nuclear@0: #include nuclear@1: #include nuclear@1: #include nuclear@0: #include nuclear@0: #include "pvfs.h" nuclear@0: #include "vnode.h" nuclear@0: nuclear@0: int pvfs_errno; nuclear@0: nuclear@0: int pvfs_mount(const char *mntpoint, const char *target) nuclear@0: { nuclear@0: struct vnode *srcnode, *destnode; nuclear@0: nuclear@0: /* first locate the mount point vnode */ nuclear@0: if(!(srcnode = vnode_lookup(mntpoint))) { nuclear@0: pvfs_errno = ENOENT; nuclear@0: return -1; nuclear@0: } nuclear@0: /* and make sure it's a directory */ nuclear@0: if(srcnode->type != VNODE_DIR) { nuclear@0: pvfs_errno = ENOTDIR; nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@0: /* then locate the target vnode (if it exists) */ nuclear@0: if(!(destnode = vnode_lookup(target))) { nuclear@1: PVFS_DIR *dir; nuclear@1: PVFS_FILE *fp; nuclear@1: nuclear@0: /* it's some error other than that target doesn't exist, fail... */ nuclear@0: if(pvfs_errno != ENOENT) { nuclear@0: return -1; nuclear@0: } nuclear@1: nuclear@0: /* if it doesn't exist, it might be the case we're trying nuclear@0: * to mount a package file or a real directory here. let's nuclear@0: * try them in turn... nuclear@0: */ nuclear@0: if((dir = pvfs_opendir(target))) { nuclear@0: /* it's obviously a real dir as vnode_lookup failed before... */ nuclear@0: assert(dir->real); nuclear@0: if(!(destnode = vnode_create_dir(target, dir))) { nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@0: } else if((fp = pvfs_fopen(target, "rb"))) { nuclear@0: /* again, obviously real... */ nuclear@0: assert(fp->real); nuclear@0: if(!(destnode = vnode_create_file(target, fp))) { nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@0: } else { nuclear@0: /* it's neither... so let's fail */ nuclear@0: pvfs_errno = ENOENT; nuclear@0: return -1; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: /* ok so we've got the two nodes, connect them up */ nuclear@0: srcnode->target = destnode; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int pvfs_umount(const char *mntpoint) nuclear@0: { nuclear@0: struct vnode *node = vnode_lookup(mntpoint); nuclear@0: if(!node) { nuclear@0: return -1; nuclear@0: } nuclear@0: if(node->type != VNODE_DIR) { nuclear@0: pvfs_errno = ENOTDIR; nuclear@0: return -1; nuclear@0: } nuclear@0: if(!node->target) { nuclear@0: pvfs_errno = EINVAL; nuclear@0: return -1; nuclear@0: } nuclear@0: node->target = 0; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int pvfs_chdir(const char *path) nuclear@0: { nuclear@0: return vnode_chdir(path); nuclear@0: } nuclear@0: nuclear@0: int pvfs_mkdir(const char *path, unsigned int mode) nuclear@0: { nuclear@0: char *ppath; nuclear@0: const char *dname; nuclear@0: struct vnode *parent = 0; nuclear@0: nuclear@0: ppath = alloca(strlen(path) + 1); nuclear@0: strcpy(ppath, path); nuclear@0: nuclear@0: if((dname = strrchr(path, '/'))) { nuclear@0: ppath[++dname - path] = 0; nuclear@0: if(!*dname) { nuclear@0: pvfs_errno = ENOENT; nuclear@0: return -1; nuclear@0: } nuclear@0: if(!(parent = vnode_lookup(ppath))) { nuclear@0: return -1; nuclear@0: } nuclear@0: } else { nuclear@0: dname = ppath; nuclear@0: parent = vnode_getcwd(); nuclear@0: } nuclear@0: nuclear@0: return vnode_mkdir(parent, dname); nuclear@0: } nuclear@0: nuclear@0: PVFS_FILE *pvfs_fopen(const char *fname, const char *mode) nuclear@0: { nuclear@0: FILE *fp; nuclear@0: struct vnode *node; nuclear@0: nuclear@0: /* if we find it in the filesystem, just use it... */ nuclear@0: if((fp = fopen(fname, mode))) { nuclear@0: PVFS_FILE *vfp = malloc(sizeof *vfp); nuclear@0: if(!vfp) { nuclear@0: pvfs_errno = ENOMEM; nuclear@0: return 0; nuclear@0: } nuclear@0: vfp->fp = fp; nuclear@0: vfp->real = 1; nuclear@0: return vfp; nuclear@0: } nuclear@0: nuclear@0: /* otherwise try and locate it in the virtual hierarchy */ nuclear@0: if(!(node = vnode_lookup(fname))) { nuclear@0: return 0; nuclear@0: } nuclear@0: if(node->type != VNODE_FILE) { nuclear@0: pvfs_errno = EISDIR; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: return VFILE(node); nuclear@0: } nuclear@0: nuclear@0: int pvfs_fclose(PVFS_FILE *fp) nuclear@0: { nuclear@0: if(fp->real) { nuclear@0: /* it's real, just close it and free the struct */ nuclear@0: fclose(fp->fp); nuclear@0: free(fp); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: /* TODO */ nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@2: int pvfs_fseek(PVFS_FILE *fp, long offset, int whence) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return fseek(fp->fp, offset, whence); nuclear@2: } nuclear@0: nuclear@2: return -1; /* TODO */ nuclear@2: } nuclear@2: nuclear@2: long pvfs_ftell(PVFS_FILE *fp) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return ftell(fp->fp); nuclear@2: } nuclear@2: return -1; /* TODO */ nuclear@2: } nuclear@2: nuclear@2: void pvfs_rewind(PVFS_FILE *fp) nuclear@2: { nuclear@2: pvfs_fseek(fp, 0, SEEK_SET); nuclear@2: } nuclear@2: nuclear@2: size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return fread(buf, size, nitems, fp->fp); nuclear@2: } nuclear@2: return 0; /* TODO */ nuclear@2: } nuclear@2: nuclear@2: size_t pvfs_fwrite(void *buf, size_t size, size_t nitems, PVFS_FILE *fp) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return fwrite(buf, size, nitems, fp->fp); nuclear@2: } nuclear@2: return 0; /* TODO */ nuclear@2: } nuclear@0: nuclear@1: int pvfs_fgetc(PVFS_FILE *fp) nuclear@1: { nuclear@1: char c; nuclear@1: if(pvfs_fread(&c, 1, 1, fp) != 1) { nuclear@1: return -1; nuclear@1: } nuclear@1: return c; nuclear@1: } nuclear@0: nuclear@1: int pvfs_fputc(int c, PVFS_FILE *fp) nuclear@1: { nuclear@1: return pvfs_fwrite(&c, 1, 1, fp) == 1 ? 0 : -1; nuclear@1: } nuclear@0: nuclear@1: char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp) nuclear@1: { nuclear@1: int i; nuclear@1: char *res = buf; nuclear@1: nuclear@1: for(i=0; ireal) { nuclear@2: clearerr(fp->fp); nuclear@2: return; nuclear@2: } nuclear@2: /* TODO */ nuclear@2: } nuclear@2: nuclear@2: int pvfs_feof(PVFS_FILE *fp) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return feof(fp->fp); nuclear@2: } nuclear@2: return 0; /* TODO */ nuclear@2: } nuclear@2: nuclear@2: int pvfs_ferror(PVFS_FILE *fp) nuclear@2: { nuclear@2: if(fp->real) { nuclear@2: return ferror(fp->fp); nuclear@2: } nuclear@2: return -1; /* TODO */ nuclear@2: } nuclear@0: nuclear@0: /* POSIX stuff */ nuclear@0: PVFS_DIR *pvfs_opendir(const char *dirname) nuclear@0: { nuclear@0: DIR *dir; nuclear@0: struct vnode *node; nuclear@0: nuclear@0: if((dir = opendir(dirname))) { nuclear@0: PVFS_DIR *vdir = malloc(sizeof *vdir); nuclear@0: if(!vdir) { nuclear@0: pvfs_errno = ENOMEM; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: vdir->real = 1; nuclear@0: vdir->dir = dir; nuclear@0: return vdir; nuclear@0: } nuclear@0: nuclear@0: if(!(node = vnode_lookup(dirname))) { nuclear@0: return 0; nuclear@0: } nuclear@0: if(node->type != VNODE_DIR) { nuclear@0: pvfs_errno = ENOTDIR; nuclear@0: return 0; nuclear@0: } nuclear@0: return VDIR(node); nuclear@0: } nuclear@0: nuclear@0: int pvfs_closedir(PVFS_DIR *dir) nuclear@0: { nuclear@0: if(dir->real) { nuclear@0: int res = closedir(dir->dir); nuclear@0: free(dir); nuclear@0: return res; nuclear@0: } nuclear@0: nuclear@0: /* TODO */ nuclear@0: return -1; nuclear@0: } nuclear@1: nuclear@2: struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir) nuclear@2: { nuclear@2: static struct pvfs_dirent dent; nuclear@0: nuclear@2: if(dir->real) { nuclear@2: struct dirent *real_dent = readdir(dir->dir); nuclear@2: if(!real_dent) { nuclear@2: pvfs_errno = errno; nuclear@2: return 0; nuclear@2: } nuclear@0: nuclear@2: strncpy(dent.d_name, real_dent->d_name, sizeof dent.d_name - 1); nuclear@2: dent.d_name[sizeof dent.d_name - 1] = 0; nuclear@2: nuclear@2: return &dent; nuclear@2: } nuclear@2: return 0; /* TODO */ nuclear@2: } nuclear@2: nuclear@2: void pvfs_rewinddir(PVFS_DIR *dir) nuclear@2: { nuclear@2: if(dir->real) { nuclear@2: rewinddir(dir->dir); nuclear@2: return; nuclear@2: } nuclear@2: /* TODO */ nuclear@2: } nuclear@2: nuclear@2: int pvfs_stat(const char *path, struct pvfs_stat *buf) nuclear@2: { nuclear@2: return -1; /* TODO */ nuclear@2: }