int _ls_handler(int argc, char **argv) { if (argc < 2) { _ls_usage(argv); return 1; } char *path = argv[1]; uint8_t buf[16]; int res; int ret = 0; res = vfs_normalize_path(path, path, strlen(path) + 1); if (res < 0) { _errno_string(res, (char *)buf, sizeof(buf)); printf("Invalid path \"%s\": %s\n", path, buf); return 5; } vfs_DIR dir; res = vfs_opendir(&dir, path); if (res < 0) { _errno_string(res, (char *)buf, sizeof(buf)); printf("vfs_opendir error: %s\n", buf); return 1; } unsigned int nfiles = 0; while (1) { vfs_dirent_t entry; res = vfs_readdir(&dir, &entry); if (res < 0) { _errno_string(res, (char *)buf, sizeof(buf)); printf("vfs_readdir error: %s\n", buf); if (res == -EAGAIN) { /* try again */ continue; } ret = 2; break; } if (res == 0) { /* end of stream */ break; } printf("%s\n", entry.d_name); ++nfiles; } if (ret == 0) { printf("total %u files\n", nfiles); } res = vfs_closedir(&dir); if (res < 0) { _errno_string(res, (char *)buf, sizeof(buf)); printf("vfs_closedir error: %s\n", buf); return 2; } return ret; }
struct vnode *vfs_lookup(struct vnode *parent, char *name) { parent = get_real_node(parent); DIR *dh = vfs_opendir(parent); struct vnode *node = 0; while ((node = vfs_readdir(dh)) != NULL) { if (!strcmp(node->v_name, name)) { vfs_closedir(dh); return node; } } vfs_closedir(dh); return NULL; }
static int cmd_vfs_mount(struct vmm_chardev *cdev, const char *dev, const char *path) { int rc; bool found; int fd, num, count; struct vmm_blockdev *bdev; struct filesystem *fs; bdev = vmm_blockdev_find(dev); if (!bdev) { vmm_cprintf(cdev, "Block device %s not found\n", dev); return VMM_ENODEV; } if (strcmp(path, "/") != 0) { fd = vfs_opendir(path); if (fd < 0) { vmm_cprintf(cdev, "Directory %s not found\n", path); return fd; } else { vfs_closedir(fd); } } found = FALSE; count = vfs_filesystem_count(); vmm_cprintf(cdev, "Trying:"); for (num = 0; num < count; num++) { fs = vfs_filesystem_get(num); vmm_cprintf(cdev, " %s", fs->name); rc = vfs_mount(path, fs->name, dev, MOUNT_RW); if (!rc) { found = TRUE; vmm_cprintf(cdev, "\n"); break; } } if (!found) { vmm_cprintf(cdev, "\nMount failed\n"); return VMM_ENOSYS; } vmm_cprintf(cdev, "Mounted %s using %s at %s\n", dev, fs->name, path); return VMM_OK; }
static int ls(int argc, char *argv[]) { errval_t err; int ret = 0; // XXX: cheat and assume we have some extra space wherever argv lives if (argc <= 1) { argv[1] = cwd; argc = 2; } for (int i = 1; i < argc; i++) { vfs_handle_t vh; char *path = vfs_path_mkabsolute(cwd, argv[i]); err = vfs_opendir(path, &vh); free(path); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_opendir %s", argv[i]); printf("%s: not found\n", argv[i]); ret = 1; continue; } if (i > 1) { printf("\n"); } printf("%s:\n", argv[i]); do { struct vfs_fileinfo info; char *name; err = vfs_dir_read_next(vh, &name, &info); if (err_is_ok(err)) { printf("%8zu %c %s\n", info.size, vfs_type_char(info.type), name); free(name); } } while(err_is_ok(err)); err = vfs_closedir(vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_closedir"); } } return ret; }
static void walk_dir(char* path) { printf("%s:%d: path=%s\n", __FUNCTION__, __LINE__, path); vfs_handle_t dhandle; struct vfs_fileinfo info; errval_t err = vfs_opendir(path, &dhandle); assert(err_is_ok(err)); char* name; while(err_is_ok(vfs_dir_read_next(dhandle, &name, &info))) { if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; char* newpath = malloc(snprintf(NULL, 0, "%s/%s", path, name) + 1); sprintf(newpath, "%s/%s", path, name); switch (info.type) { case VFS_DIRECTORY: printf("%s:%d: Found directory %s\n", __FUNCTION__, __LINE__, newpath); walk_dir(newpath); break; case VFS_FILE: printf("%s:%d: Found file %s\n", __FUNCTION__, __LINE__, newpath); vfs_handle_t fhandle; err = vfs_open(newpath, &fhandle); char* buf = malloc(info.size); size_t bytes_read = 0; err = vfs_read(fhandle, buf, info.size, &bytes_read); assert(err_is_ok(err)); assert(bytes_read == info.size); printf("%s:%d: File content is (bytes=%d):\n%s\n", __FUNCTION__, __LINE__, bytes_read, buf); free(buf); break; } free(name); free(newpath); } err = vfs_closedir(dhandle); assert(err_is_ok(err)); }
static u32 flist_reload_dir(flist_dir_priv_t *p_flist_dir) { media_file_t *p_file = NULL; file_list_priv_t *p_priv = NULL; p_priv = class_get_handle_by_id(FILE_LIST_CLASS_ID); if (p_flist_dir->vfs_dir) { vfs_closedir(p_flist_dir->vfs_dir); p_flist_dir->vfs_dir = NULL; } p_flist_dir->vfs_dir = vfs_opendir (p_flist_dir->cur_path, p_priv->max_support_cnt); p_flist_dir->total_cnt = 0; if (p_flist_dir->vfs_dir == NULL) { return 0; } while (p_flist_dir->total_cnt < p_priv->max_support_cnt) { p_file = get_file_by_index(p_flist_dir, p_flist_dir->total_cnt); if (p_file == NULL) { break; } if (flist_read_dir_one(p_flist_dir, p_file)) { p_file->default_order = p_flist_dir->total_cnt; p_flist_dir->total_cnt ++; } else { break; } } return p_flist_dir->total_cnt; }
static int cmd_vfs_ls(struct vmm_chardev *cdev, const char *path) { char type[11]; char dpath[VFS_MAX_PATH]; int fd, rc, plen, total_ent; struct vmm_timeinfo ti; struct stat st; struct dirent d; fd = vfs_opendir(path); if (fd < 0) { vmm_cprintf(cdev, "Failed to opendir %s\n", path); return fd; } if ((plen = strlcpy(dpath, path, sizeof(dpath))) >= sizeof(dpath)) { rc = VMM_EOVERFLOW; goto closedir_fail; } if (path[plen-1] != '/') { if ((plen = strlcat(dpath, "/", sizeof(dpath))) >= sizeof(dpath)) { rc = VMM_EOVERFLOW; goto closedir_fail; } } total_ent = 0; while (!vfs_readdir(fd, &d)) { dpath[plen] = '\0'; if (strlcat(dpath, d.d_name, sizeof(dpath)) >= sizeof(dpath)) { rc = VMM_EOVERFLOW; goto closedir_fail; } rc = vfs_stat(dpath, &st); if (rc) { vmm_cprintf(cdev, "Failed to get %s stat\n", dpath); goto closedir_fail; } strcpy(type, "----------"); if (st.st_mode & S_IFDIR) { type[0]= 'd'; } else if (st.st_mode & S_IFCHR) { type[0]= 'c'; } else if (st.st_mode & S_IFBLK) { type[0]= 'b'; } else if (st.st_mode & S_IFLNK) { type[0]= 'l'; } if (st.st_mode & S_IRUSR) { type[1] = 'r'; } if (st.st_mode & S_IWUSR) { type[2] = 'w'; } if (st.st_mode & S_IXUSR) { type[3] = 'x'; } if (st.st_mode & S_IRGRP) { type[4] = 'r'; } if (st.st_mode & S_IWGRP) { type[5] = 'w'; } if (st.st_mode & S_IXGRP) { type[6] = 'x'; } if (st.st_mode & S_IROTH) { type[7] = 'r'; } if (st.st_mode & S_IWOTH) { type[8] = 'w'; } if (st.st_mode & S_IXOTH) { type[9] = 'x'; } vmm_cprintf(cdev, "%10s ", type); vmm_cprintf(cdev, "%10ll ", st.st_size); vmm_wallclock_mkinfo(st.st_mtime, 0, &ti); switch (ti.tm_mon) { case 0: vmm_cprintf(cdev, "%s ", "Jan"); break; case 1: vmm_cprintf(cdev, "%s ", "Feb"); break; case 2: vmm_cprintf(cdev, "%s ", "Mar"); break; case 3: vmm_cprintf(cdev, "%s ", "Apr"); break; case 4: vmm_cprintf(cdev, "%s ", "May"); break; case 5: vmm_cprintf(cdev, "%s ", "Jun"); break; case 6: vmm_cprintf(cdev, "%s ", "Jul"); break; case 7: vmm_cprintf(cdev, "%s ", "Aug"); break; case 8: vmm_cprintf(cdev, "%s ", "Sep"); break; case 9: vmm_cprintf(cdev, "%s ", "Oct"); break; case 10: vmm_cprintf(cdev, "%s ", "Nov"); break; case 11: vmm_cprintf(cdev, "%s ", "Dec"); break; default: break; }; vmm_cprintf(cdev, "%02d %d %02d:%02d:%02d ", ti.tm_mday, ti.tm_year + 1900, ti.tm_hour, ti.tm_min, ti.tm_sec); if (type[0] == 'd') vmm_cprintf(cdev, "%s/\n", d.d_name); else vmm_cprintf(cdev, "%s\n", d.d_name); total_ent++; } vmm_cprintf(cdev, "total %d\n", total_ent); rc = vfs_closedir(fd); if (rc) { vmm_cprintf(cdev, "Failed to closedir %s\n", path); return rc; } return VMM_OK; closedir_fail: vfs_closedir(fd); return rc; }
static int fuse_releasedir(const char *path, struct fuse_file_info *fi) { vfs_closedir(fi->fh); return 0; }
/** * \brief Mount a filesystem into the local VFS * * \param mountpoint Fully-qualified absolute path to the mount-point * Must be a directory in the existing VFS which is not already a mount-point * * \param uri URI of source file system to mount. * Currently-supported are: * ramfs://[servicename] where servicename is registered in the name service * nfs://hostip/path */ errval_t vfs_mount(const char *mountpoint, const char *uri) { errval_t err; // copy mountpoint and normalise it assert(mountpoint != NULL); char *mp = strdup(mountpoint); assert(mp != NULL); vfs_path_normalise(mp); // sanity-check mountpoint: must start at root and not have .. in it if (mp[0] != VFS_PATH_SEP || strncmp(mp, "/../", 4) == 0) { free(mp); return VFS_ERR_BAD_MOUNTPOINT; } // sanity-check mountpoint // if this is the first mount, it must be for the root, otherwise it must // not duplicate an existing mount, and the mount-point must exist if (mounts == NULL) { if (strcmp(mp, VFS_PATH_SEP_STR) != 0) { free(mp); return VFS_ERR_BAD_MOUNTPOINT; } } else { struct vfs_mount *parent = find_mount(mp, NULL); assert(parent != NULL); // root should always have matched if (strcmp(parent->mountpoint, mp) == 0) { free(mp); return VFS_ERR_MOUNTPOINT_IN_USE; } // check for existence of mountpoint by attempting to open it vfs_handle_t tmp; err = vfs_opendir(mp, &tmp); if (err_is_fail(err)) { free(mp); return err_push(err, VFS_ERR_MOUNTPOINT_NOTFOUND); } vfs_closedir(tmp); } // parse protocol part of URI char *pos = strstr(uri, "://"); if (pos == NULL) { free(mp); return VFS_ERR_BAD_URI; } struct vfs_mount *m = malloc(sizeof(struct vfs_mount)); assert(m != NULL); m->mountpoint = mp; size_t len = pos - uri; if (strncmp(uri, "nfs", len) == 0) { #ifndef DISABLE_NFS err = vfs_nfs_mount(uri, &m->st, &m->ops); #else err = VFS_ERR_UNKNOWN_FILESYSTEM; #endif } else if (strncmp(uri, "ramfs", len) == 0) { err = vfs_ramfs_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "blockdevfs", len) == 0) { err = vfs_blockdevfs_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "fat16", len) == 0) { err = vfs_fat_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "fat32", len) == 0) { err = vfs_fat_mount(uri, &m->st, &m->ops); } else { debug_printf("VFS: unknown file system %.*s\n", (int)len, uri); err = VFS_ERR_UNKNOWN_FILESYSTEM; } if (err_is_fail(err)) { free(m); free(mp); return err; } // add to list of mounts m->next = mounts; mounts = m; return SYS_ERR_OK; }
static void send_next_directory(struct ftpd_datastate *fsd, struct tcp_pcb *pcb, int shortlist) { char buffer[1024]; int len; while (1) { if (fsd->vfs_dirent == NULL) fsd->vfs_dirent = vfs_readdir(fsd->vfs_dir); if (fsd->vfs_dirent) { if (shortlist) { len = sprintf(buffer, "%s\r\n", fsd->vfs_dirent->name); if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } else { vfs_stat_t st; time_t current_time; int current_year; struct tm *s_time; time(¤t_time); s_time = gmtime(¤t_time); current_year = s_time->tm_year; vfs_stat(fsd->msgfs->vfs, fsd->vfs_dirent->name, &st); s_time = gmtime(&st.st_mtime); if (s_time->tm_year == current_year) len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %02i:%02i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_hour, s_time->tm_min, fsd->vfs_dirent->name); else len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %5i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_year + 1900, fsd->vfs_dirent->name); if (VFS_ISDIR(st.st_mode)) buffer[0] = 'd'; if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_closedir(fsd->vfs_dir); fsd->vfs_dir = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } } }