packvfs

annotate src/pvfs.c @ 0:df5e9ee65a50

packvfs initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 02 Aug 2013 06:03:38 +0300
parents
children a0b3b6682d92
rev   line source
nuclear@0 1 #include <string.h>
nuclear@0 2 #include <alloca.h>
nuclear@0 3 #include <assert.h>
nuclear@0 4 #include "pvfs.h"
nuclear@0 5 #include "vnode.h"
nuclear@0 6
nuclear@0 7 int pvfs_errno;
nuclear@0 8
nuclear@0 9 int pvfs_mount(const char *mntpoint, const char *target)
nuclear@0 10 {
nuclear@0 11 struct vnode *srcnode, *destnode;
nuclear@0 12
nuclear@0 13 /* first locate the mount point vnode */
nuclear@0 14 if(!(srcnode = vnode_lookup(mntpoint))) {
nuclear@0 15 pvfs_errno = ENOENT;
nuclear@0 16 return -1;
nuclear@0 17 }
nuclear@0 18 /* and make sure it's a directory */
nuclear@0 19 if(srcnode->type != VNODE_DIR) {
nuclear@0 20 pvfs_errno = ENOTDIR;
nuclear@0 21 return -1;
nuclear@0 22 }
nuclear@0 23
nuclear@0 24 /* then locate the target vnode (if it exists) */
nuclear@0 25 if(!(destnode = vnode_lookup(target))) {
nuclear@0 26 /* it's some error other than that target doesn't exist, fail... */
nuclear@0 27 if(pvfs_errno != ENOENT) {
nuclear@0 28 return -1;
nuclear@0 29 }
nuclear@0 30 /* if it doesn't exist, it might be the case we're trying
nuclear@0 31 * to mount a package file or a real directory here. let's
nuclear@0 32 * try them in turn...
nuclear@0 33 */
nuclear@0 34 PVFS_DIR *dir;
nuclear@0 35 PVFS_FILE *fp;
nuclear@0 36
nuclear@0 37 if((dir = pvfs_opendir(target))) {
nuclear@0 38 /* it's obviously a real dir as vnode_lookup failed before... */
nuclear@0 39 assert(dir->real);
nuclear@0 40 if(!(destnode = vnode_create_dir(target, dir))) {
nuclear@0 41 return -1;
nuclear@0 42 }
nuclear@0 43
nuclear@0 44 } else if((fp = pvfs_fopen(target, "rb"))) {
nuclear@0 45 /* again, obviously real... */
nuclear@0 46 assert(fp->real);
nuclear@0 47 if(!(destnode = vnode_create_file(target, fp))) {
nuclear@0 48 return -1;
nuclear@0 49 }
nuclear@0 50
nuclear@0 51 } else {
nuclear@0 52 /* it's neither... so let's fail */
nuclear@0 53 pvfs_errno = ENOENT;
nuclear@0 54 return -1;
nuclear@0 55 }
nuclear@0 56 }
nuclear@0 57
nuclear@0 58 /* ok so we've got the two nodes, connect them up */
nuclear@0 59 srcnode->target = destnode;
nuclear@0 60 return 0;
nuclear@0 61 }
nuclear@0 62
nuclear@0 63 int pvfs_umount(const char *mntpoint)
nuclear@0 64 {
nuclear@0 65 struct vnode *node = vnode_lookup(mntpoint);
nuclear@0 66 if(!node) {
nuclear@0 67 return -1;
nuclear@0 68 }
nuclear@0 69 if(node->type != VNODE_DIR) {
nuclear@0 70 pvfs_errno = ENOTDIR;
nuclear@0 71 return -1;
nuclear@0 72 }
nuclear@0 73 if(!node->target) {
nuclear@0 74 pvfs_errno = EINVAL;
nuclear@0 75 return -1;
nuclear@0 76 }
nuclear@0 77 node->target = 0;
nuclear@0 78 return 0;
nuclear@0 79 }
nuclear@0 80
nuclear@0 81 int pvfs_chdir(const char *path)
nuclear@0 82 {
nuclear@0 83 return vnode_chdir(path);
nuclear@0 84 }
nuclear@0 85
nuclear@0 86 int pvfs_mkdir(const char *path, unsigned int mode)
nuclear@0 87 {
nuclear@0 88 char *ppath;
nuclear@0 89 const char *dname;
nuclear@0 90 struct vnode *parent = 0;
nuclear@0 91
nuclear@0 92 ppath = alloca(strlen(path) + 1);
nuclear@0 93 strcpy(ppath, path);
nuclear@0 94
nuclear@0 95 if((dname = strrchr(path, '/'))) {
nuclear@0 96 ppath[++dname - path] = 0;
nuclear@0 97 if(!*dname) {
nuclear@0 98 pvfs_errno = ENOENT;
nuclear@0 99 return -1;
nuclear@0 100 }
nuclear@0 101 if(!(parent = vnode_lookup(ppath))) {
nuclear@0 102 return -1;
nuclear@0 103 }
nuclear@0 104 } else {
nuclear@0 105 dname = ppath;
nuclear@0 106 parent = vnode_getcwd();
nuclear@0 107 }
nuclear@0 108
nuclear@0 109 return vnode_mkdir(parent, dname);
nuclear@0 110 }
nuclear@0 111
nuclear@0 112 PVFS_FILE *pvfs_fopen(const char *fname, const char *mode)
nuclear@0 113 {
nuclear@0 114 FILE *fp;
nuclear@0 115 struct vnode *node;
nuclear@0 116
nuclear@0 117 /* if we find it in the filesystem, just use it... */
nuclear@0 118 if((fp = fopen(fname, mode))) {
nuclear@0 119 PVFS_FILE *vfp = malloc(sizeof *vfp);
nuclear@0 120 if(!vfp) {
nuclear@0 121 pvfs_errno = ENOMEM;
nuclear@0 122 return 0;
nuclear@0 123 }
nuclear@0 124 vfp->fp = fp;
nuclear@0 125 vfp->real = 1;
nuclear@0 126 return vfp;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 /* otherwise try and locate it in the virtual hierarchy */
nuclear@0 130 if(!(node = vnode_lookup(fname))) {
nuclear@0 131 return 0;
nuclear@0 132 }
nuclear@0 133 if(node->type != VNODE_FILE) {
nuclear@0 134 pvfs_errno = EISDIR;
nuclear@0 135 return 0;
nuclear@0 136 }
nuclear@0 137
nuclear@0 138 return VFILE(node);
nuclear@0 139 }
nuclear@0 140
nuclear@0 141 int pvfs_fclose(PVFS_FILE *fp)
nuclear@0 142 {
nuclear@0 143 if(fp->real) {
nuclear@0 144 /* it's real, just close it and free the struct */
nuclear@0 145 fclose(fp->fp);
nuclear@0 146 free(fp);
nuclear@0 147 return 0;
nuclear@0 148 }
nuclear@0 149
nuclear@0 150 /* TODO */
nuclear@0 151 return -1;
nuclear@0 152 }
nuclear@0 153
nuclear@0 154 int pvfs_fseek(PVFS_FILE *fp, long offset, int whence);
nuclear@0 155 long pvfs_ftell(PVFS_FILE *fp);
nuclear@0 156 void pvfs_rewind(PVFS_FILE *fp);
nuclear@0 157
nuclear@0 158 size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
nuclear@0 159 size_t pvfs_write(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
nuclear@0 160
nuclear@0 161 int pvfs_fgetc(PVFS_FILE *fp);
nuclear@0 162 int pvfs_fputc(int c, PVFS_FILE *fp);
nuclear@0 163
nuclear@0 164 char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp);
nuclear@0 165 int pvfs_fputs(char *buf, PVFS_FILE *fp);
nuclear@0 166
nuclear@0 167 int pvfs_fscanf(PVFS_FILE *fp, const char *fmt, ...);
nuclear@0 168 int pvfs_vfscanf(PVFS_FILE *fp, const char *fmt, va_list ap);
nuclear@0 169 int pvfs_fprintf(PVFS_FILE *fp, const char *fmt, ...);
nuclear@0 170 int pvfs_vfprintf(PVFS_FILE *fp, const char *fmt, va_list ap);
nuclear@0 171
nuclear@0 172 void pvfs_clearerr(PVFS_FILE *fp);
nuclear@0 173 int pvfs_feof(PVFS_FILE *fp);
nuclear@0 174 int pvfs_ferror(PVFS_FILE *fp);
nuclear@0 175
nuclear@0 176 /* POSIX stuff */
nuclear@0 177 PVFS_DIR *pvfs_opendir(const char *dirname)
nuclear@0 178 {
nuclear@0 179 DIR *dir;
nuclear@0 180 struct vnode *node;
nuclear@0 181
nuclear@0 182 if((dir = opendir(dirname))) {
nuclear@0 183 PVFS_DIR *vdir = malloc(sizeof *vdir);
nuclear@0 184 if(!vdir) {
nuclear@0 185 pvfs_errno = ENOMEM;
nuclear@0 186 return 0;
nuclear@0 187 }
nuclear@0 188
nuclear@0 189 vdir->real = 1;
nuclear@0 190 vdir->dir = dir;
nuclear@0 191 return vdir;
nuclear@0 192 }
nuclear@0 193
nuclear@0 194 if(!(node = vnode_lookup(dirname))) {
nuclear@0 195 return 0;
nuclear@0 196 }
nuclear@0 197 if(node->type != VNODE_DIR) {
nuclear@0 198 pvfs_errno = ENOTDIR;
nuclear@0 199 return 0;
nuclear@0 200 }
nuclear@0 201 return VDIR(node);
nuclear@0 202 }
nuclear@0 203
nuclear@0 204 int pvfs_closedir(PVFS_DIR *dir)
nuclear@0 205 {
nuclear@0 206 if(dir->real) {
nuclear@0 207 int res = closedir(dir->dir);
nuclear@0 208 free(dir);
nuclear@0 209 return res;
nuclear@0 210 }
nuclear@0 211
nuclear@0 212 /* TODO */
nuclear@0 213 return -1;
nuclear@0 214 }
nuclear@0 215 struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir);
nuclear@0 216 void pvfs_rewinddir(PVFS_DIR *dir);
nuclear@0 217
nuclear@0 218 int pvfs_stat(const char *path, struct pvfs_stat *buf);
nuclear@0 219