int access(const char *pathname, int mode) { vfs_handle_t vh; errval_t err; int ret; char *path = vfs_path_mkabs(pathname); assert(path != NULL); err = vfs_open(path, &vh); if (err_is_fail(err)) { if(err_no(err) == FS_ERR_NOTFILE) { // Is it a directory? err = vfs_opendir(path, &vh); if(err_is_ok(err)) { vfs_closedir(vh); ret = 0; goto out; } } POSIXCOMPAT_DEBUG("access(%s) failed\n", pathname); ret = -1; } else { POSIXCOMPAT_DEBUG("access(%s): OK\n", pathname); vfs_close(vh); ret = 0; } out: free(path); return ret; }
static int cd(int argc, char *argv[]) { errval_t err; if (argc != 2) { printf("Usage: %s DIR\n", argv[0]); return 1; } char *newcwd = vfs_path_mkabsolute(cwd, argv[1]); // ensure directory exists, by attempting to open it vfs_handle_t dh; err = vfs_opendir(newcwd, &dh); if (err_is_fail(err)) { printf("cd to %s (-> %s) failed: %s\n", argv[1], newcwd, err_getstring(err)); free(newcwd); return 1; } vfs_closedir(dh); // ok! free(cwd); cwd = newcwd; return 0; }
static void cmd_list_common(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate *fsm, int shortlist) { vfs_dir_t *vfs_dir; char *cwd; cwd = vfs_getcwd(fsm->vfs, NULL, 0); if ((!cwd)) { send_msg(pcb, fsm, msg451); return; } vfs_dir = vfs_opendir(fsm->vfs, cwd); free(cwd); if (!vfs_dir) { send_msg(pcb, fsm, msg451); return; } if (open_dataconnection(pcb, fsm) != 0) { vfs_closedir(vfs_dir); return; } fsm->datafs->vfs_dir = vfs_dir; fsm->datafs->vfs_dirent = NULL; if (shortlist != 0) fsm->state = FTPD_NLST; else fsm->state = FTPD_LIST; send_msg(pcb, fsm, msg150); }
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; }
static int fuse_opendir(const char *path, struct fuse_file_info *fi) { int fd; if ((fd = vfs_opendir(path)) < 0) { MESSAGE_DEBUG("return:%d\n", fd); return fd; } fi->fh = fd; return 0; }
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)); }
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 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; }
flist_dir_t flist_open_dir(u16 *p_filter, u16 *p_path, u32 *p_total_cnt) { file_list_priv_t *p_priv = NULL; flist_dir_priv_t *p_dir_priv = NULL; u16 *p_temp = NULL; u16 parent[4] = {0}; u16 curn[4] = {0}; CHECK_FAIL_RET_NULL(p_path != NULL); p_priv = class_get_handle_by_id(FILE_LIST_CLASS_ID); if (p_priv->p_opened_dir) { OS_PRINTF("\n\n\n##waring:please close/leave dir[0x%x] first!\n", p_priv->p_opened_dir); } p_dir_priv = mtos_malloc(sizeof(flist_dir_priv_t)); CHECK_FAIL_RET_NULL(p_dir_priv != NULL); memset(p_dir_priv, 0, sizeof(flist_dir_priv_t)); p_dir_priv->p_flist = NULL; p_dir_priv->start_idx = 0; p_dir_priv->total_cnt = 0; uni_strcpy(p_dir_priv->cur_path, p_path); if (p_filter != NULL) { uni_strncpy(p_dir_priv->filter, p_filter, MAX_FILE_PATH); } p_temp = uni_strrchr(p_dir_priv->cur_path, 0x5c/*'\\'*/); if (p_temp != NULL) { //parent dir str_asc2uni("..", parent); str_asc2uni(".", curn); if (uni_strlen(p_temp) >= 3 && uni_strcmp(p_temp + 1, parent/*".."*/) == 0) { p_temp[0] = 0/*'\0'*/; p_temp = uni_strrchr(p_dir_priv->cur_path, 0x5c/*'\\'*/); if (p_temp != NULL) { p_temp[0] = 0/*'\0'*/; } } //cur dir else if (uni_strlen(p_temp) >= 2 && uni_strcmp(p_temp + 1, curn/*"."*/) == 0) { p_temp[0] = 0/*'\0'*/; } } p_dir_priv->vfs_dir = vfs_opendir (p_dir_priv->cur_path, p_priv->max_support_cnt); if (p_dir_priv->vfs_dir == NULL) { mtos_free(p_dir_priv); p_dir_priv = NULL; return NULL; } OS_PRINTF("\n##flist read dir please wait...\n"); flist_reload_dir(p_dir_priv); if (p_total_cnt) { *p_total_cnt = p_dir_priv->total_cnt; } p_priv->p_opened_dir = p_dir_priv; return (flist_dir_t)p_dir_priv; }
flist_dir_t file_list_enter_dir(u16 *p_filter, u16 unit_cnt, u16 *p_path) { file_list_priv_t *p_priv = NULL; file_list_dir_t *p_flist_dir = NULL; u16 *p_temp = NULL; u16 parent[4] = {0}; u16 curn[4] = {0}; CHECK_FAIL_RET_NULL(p_path != NULL); if (unit_cnt == 0) { return NULL; } p_priv = class_get_handle_by_id(FILE_LIST_CLASS_ID); if (p_priv->p_opened_dir) { OS_PRINTF("\n\n\n##waring:please close/leave dir[0x%x] first!\n", p_priv->p_opened_dir); } p_flist_dir = mtos_malloc(sizeof(file_list_dir_t)); CHECK_FAIL_RET_NULL(p_flist_dir != NULL); memset(p_flist_dir, 0, sizeof(file_list_dir_t)); uni_strcpy(p_flist_dir->cur_path, p_path); if (p_filter != NULL) { uni_strncpy(p_flist_dir->filter, p_filter, MAX_FILE_PATH); } p_flist_dir->unit_cnt = unit_cnt; p_temp = uni_strrchr(p_flist_dir->cur_path, 0x5c/*'\\'*/); if (p_temp != NULL) { //parent dir str_asc2uni("..", parent); str_asc2uni(".", curn); if (uni_strlen(p_temp) >= 3 && uni_strcmp(p_temp + 1, parent/*".."*/) == 0) { p_temp[0] = 0/*'\0'*/; p_temp = uni_strrchr(p_flist_dir->cur_path, 0x5c/*'\\'*/); if (p_temp != NULL) { p_temp[0] = 0/*'\0'*/; } } //cur dir else if (uni_strlen(p_temp) >= 2 && uni_strcmp(p_temp + 1, curn/*"."*/) == 0) { p_temp[0] = 0/*'\0'*/; } } p_flist_dir->cur_dir = vfs_opendir (p_flist_dir->cur_path, unit_cnt); if (p_flist_dir->cur_dir == NULL) { mtos_free(p_flist_dir); p_flist_dir = NULL; } p_priv->p_opened_dir = p_flist_dir; return (flist_dir_t)p_flist_dir; }
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; }
/** * \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; }