mirror of https://github.com/ArduPilot/ardupilot
AP_Filesystem: list virtual @SYS, @MISSION etc directories in /
Adds virtual directory entries for these virtual filesystems in / RTL> ftp list RTL> Listing / D @MISSION D @PARAM D @ROMFS D @SYS D APM D log V5_BT.dfu 10541 bootlog.txt 297 dataman 350216 message-intervals-chan0.txt 7 Total size 352.60 kByte ftp list @MISSION RTL> Listing @MISSION LIST: OP seq:7 sess:2 opcode:129 req_opcode:3 size:2 bc:0 ofs:0 plen=2 [2] ftp list @ROMFS RTL> Listing @ROMFS bootloader.bin 16448 hwdef.dat 5743 io_firmware.bin 40880 Total size 61.59 kByte This PR also makes us *much* more lenient in what we accept for looking at virtual filesystems, so ftp list @SYS ftp list /@SYS ftp list @SYS/ ftp list /@SYS/ should all work
This commit is contained in:
parent
e9d065c1cc
commit
ac769014c4
|
@ -63,18 +63,16 @@ static AP_Filesystem_Mission fs_mission;
|
|||
const AP_Filesystem::Backend AP_Filesystem::backends[] = {
|
||||
{ nullptr, fs_local },
|
||||
#if AP_FILESYSTEM_ROMFS_ENABLED
|
||||
{ "@ROMFS/", fs_romfs },
|
||||
{ "@ROMFS", fs_romfs },
|
||||
#endif
|
||||
#if AP_FILESYSTEM_PARAM_ENABLED
|
||||
{ "@PARAM/", fs_param },
|
||||
{ "@PARAM", fs_param },
|
||||
#endif
|
||||
#if AP_FILESYSTEM_SYS_ENABLED
|
||||
{ "@SYS/", fs_sys },
|
||||
{ "@SYS", fs_sys },
|
||||
#endif
|
||||
#if AP_FILESYSTEM_MISSION_ENABLED
|
||||
{ "@MISSION/", fs_mission },
|
||||
{ "@MISSION", fs_mission },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -90,10 +88,19 @@ extern const AP_HAL::HAL& hal;
|
|||
*/
|
||||
const AP_Filesystem::Backend &AP_Filesystem::backend_by_path(const char *&path) const
|
||||
{
|
||||
// ignore leading slashes:
|
||||
const char *path_with_no_leading_slash = path;
|
||||
if (path_with_no_leading_slash[0] == '/') {
|
||||
path_with_no_leading_slash = &path_with_no_leading_slash[1];
|
||||
}
|
||||
for (uint8_t i=1; i<NUM_BACKENDS; i++) {
|
||||
const uint8_t plen = strlen(backends[i].prefix);
|
||||
if (strncmp(path, backends[i].prefix, plen) == 0) {
|
||||
if (strncmp(path_with_no_leading_slash, backends[i].prefix, plen) == 0) {
|
||||
path = path_with_no_leading_slash;
|
||||
path += plen;
|
||||
if (strlen(path) > 0 && path[0] == '/') {
|
||||
path++;
|
||||
}
|
||||
return backends[i];
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +195,18 @@ int AP_Filesystem::rename(const char *oldpath, const char *newpath)
|
|||
|
||||
AP_Filesystem::DirHandle *AP_Filesystem::opendir(const char *pathname)
|
||||
{
|
||||
// support reading a list of "@" filesystems (e.g. @SYS) in
|
||||
// listing of root directory. Note that backend_by_path modifies
|
||||
// its parameter.
|
||||
if (strlen(pathname) == 0 ||
|
||||
(strlen(pathname) == 1 && pathname[0] == '/')) {
|
||||
virtual_dirent.backend_ofs = 0;
|
||||
virtual_dirent.d_off = 0;
|
||||
virtual_dirent.de.d_type = DT_DIR;
|
||||
} else {
|
||||
virtual_dirent.backend_ofs = 255;
|
||||
}
|
||||
|
||||
const Backend &backend = backend_by_path(pathname);
|
||||
DirHandle *h = new DirHandle;
|
||||
if (!h) {
|
||||
|
@ -199,6 +218,7 @@ AP_Filesystem::DirHandle *AP_Filesystem::opendir(const char *pathname)
|
|||
return nullptr;
|
||||
}
|
||||
h->fs_index = BACKEND_IDX(backend);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -208,7 +228,26 @@ struct dirent *AP_Filesystem::readdir(DirHandle *dirp)
|
|||
return nullptr;
|
||||
}
|
||||
const Backend &backend = backends[dirp->fs_index];
|
||||
return backend.fs.readdir(dirp->dir);
|
||||
struct dirent * ret = backend.fs.readdir(dirp->dir);
|
||||
if (ret != nullptr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// virtual directory entries in the root directory (e.g. @SYS, @MISSION)
|
||||
for (; ret == nullptr && virtual_dirent.backend_ofs < ARRAY_SIZE(AP_Filesystem::backends); virtual_dirent.backend_ofs++) {
|
||||
const char *prefix = backends[virtual_dirent.backend_ofs].prefix;
|
||||
if (prefix == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (prefix[0] != '@') {
|
||||
continue;
|
||||
}
|
||||
// found a virtual directory we haven't returned yet
|
||||
strncpy_noterm(virtual_dirent.de.d_name, prefix, sizeof(virtual_dirent.de.d_name));
|
||||
virtual_dirent.d_off++;
|
||||
ret = &virtual_dirent.de;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int AP_Filesystem::closedir(DirHandle *dirp)
|
||||
|
|
|
@ -155,6 +155,14 @@ private:
|
|||
find backend by open fd
|
||||
*/
|
||||
const Backend &backend_by_fd(int &fd) const;
|
||||
|
||||
// support for listing out virtual directory entries (e.g. @SYS
|
||||
// then @MISSION)
|
||||
struct {
|
||||
uint8_t backend_ofs;
|
||||
struct dirent de;
|
||||
uint8_t d_off;
|
||||
} virtual_dirent;
|
||||
};
|
||||
|
||||
namespace AP {
|
||||
|
|
Loading…
Reference in New Issue