packvfs

annotate src/pvfs.c @ 2:dc23ab0545a6

- fleshed out some more fucntions with the code for the case where file/dir are real - added install/uninstall targets to the makefile - added pvfsh (packvfs shell) test program
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 04 Nov 2013 03:50:55 +0200
parents a0b3b6682d92
children
rev   line source
nuclear@0 1 #include <string.h>
nuclear@1 2 #include <stdarg.h>
nuclear@1 3 #include <assert.h>
nuclear@0 4 #include <alloca.h>
nuclear@0 5 #include "pvfs.h"
nuclear@0 6 #include "vnode.h"
nuclear@0 7
nuclear@0 8 int pvfs_errno;
nuclear@0 9
nuclear@0 10 int pvfs_mount(const char *mntpoint, const char *target)
nuclear@0 11 {
nuclear@0 12 struct vnode *srcnode, *destnode;
nuclear@0 13
nuclear@0 14 /* first locate the mount point vnode */
nuclear@0 15 if(!(srcnode = vnode_lookup(mntpoint))) {
nuclear@0 16 pvfs_errno = ENOENT;
nuclear@0 17 return -1;
nuclear@0 18 }
nuclear@0 19 /* and make sure it's a directory */
nuclear@0 20 if(srcnode->type != VNODE_DIR) {
nuclear@0 21 pvfs_errno = ENOTDIR;
nuclear@0 22 return -1;
nuclear@0 23 }
nuclear@0 24
nuclear@0 25 /* then locate the target vnode (if it exists) */
nuclear@0 26 if(!(destnode = vnode_lookup(target))) {
nuclear@1 27 PVFS_DIR *dir;
nuclear@1 28 PVFS_FILE *fp;
nuclear@1 29
nuclear@0 30 /* it's some error other than that target doesn't exist, fail... */
nuclear@0 31 if(pvfs_errno != ENOENT) {
nuclear@0 32 return -1;
nuclear@0 33 }
nuclear@1 34
nuclear@0 35 /* if it doesn't exist, it might be the case we're trying
nuclear@0 36 * to mount a package file or a real directory here. let's
nuclear@0 37 * try them in turn...
nuclear@0 38 */
nuclear@0 39 if((dir = pvfs_opendir(target))) {
nuclear@0 40 /* it's obviously a real dir as vnode_lookup failed before... */
nuclear@0 41 assert(dir->real);
nuclear@0 42 if(!(destnode = vnode_create_dir(target, dir))) {
nuclear@0 43 return -1;
nuclear@0 44 }
nuclear@0 45
nuclear@0 46 } else if((fp = pvfs_fopen(target, "rb"))) {
nuclear@0 47 /* again, obviously real... */
nuclear@0 48 assert(fp->real);
nuclear@0 49 if(!(destnode = vnode_create_file(target, fp))) {
nuclear@0 50 return -1;
nuclear@0 51 }
nuclear@0 52
nuclear@0 53 } else {
nuclear@0 54 /* it's neither... so let's fail */
nuclear@0 55 pvfs_errno = ENOENT;
nuclear@0 56 return -1;
nuclear@0 57 }
nuclear@0 58 }
nuclear@0 59
nuclear@0 60 /* ok so we've got the two nodes, connect them up */
nuclear@0 61 srcnode->target = destnode;
nuclear@0 62 return 0;
nuclear@0 63 }
nuclear@0 64
nuclear@0 65 int pvfs_umount(const char *mntpoint)
nuclear@0 66 {
nuclear@0 67 struct vnode *node = vnode_lookup(mntpoint);
nuclear@0 68 if(!node) {
nuclear@0 69 return -1;
nuclear@0 70 }
nuclear@0 71 if(node->type != VNODE_DIR) {
nuclear@0 72 pvfs_errno = ENOTDIR;
nuclear@0 73 return -1;
nuclear@0 74 }
nuclear@0 75 if(!node->target) {
nuclear@0 76 pvfs_errno = EINVAL;
nuclear@0 77 return -1;
nuclear@0 78 }
nuclear@0 79 node->target = 0;
nuclear@0 80 return 0;
nuclear@0 81 }
nuclear@0 82
nuclear@0 83 int pvfs_chdir(const char *path)
nuclear@0 84 {
nuclear@0 85 return vnode_chdir(path);
nuclear@0 86 }
nuclear@0 87
nuclear@0 88 int pvfs_mkdir(const char *path, unsigned int mode)
nuclear@0 89 {
nuclear@0 90 char *ppath;
nuclear@0 91 const char *dname;
nuclear@0 92 struct vnode *parent = 0;
nuclear@0 93
nuclear@0 94 ppath = alloca(strlen(path) + 1);
nuclear@0 95 strcpy(ppath, path);
nuclear@0 96
nuclear@0 97 if((dname = strrchr(path, '/'))) {
nuclear@0 98 ppath[++dname - path] = 0;
nuclear@0 99 if(!*dname) {
nuclear@0 100 pvfs_errno = ENOENT;
nuclear@0 101 return -1;
nuclear@0 102 }
nuclear@0 103 if(!(parent = vnode_lookup(ppath))) {
nuclear@0 104 return -1;
nuclear@0 105 }
nuclear@0 106 } else {
nuclear@0 107 dname = ppath;
nuclear@0 108 parent = vnode_getcwd();
nuclear@0 109 }
nuclear@0 110
nuclear@0 111 return vnode_mkdir(parent, dname);
nuclear@0 112 }
nuclear@0 113
nuclear@0 114 PVFS_FILE *pvfs_fopen(const char *fname, const char *mode)
nuclear@0 115 {
nuclear@0 116 FILE *fp;
nuclear@0 117 struct vnode *node;
nuclear@0 118
nuclear@0 119 /* if we find it in the filesystem, just use it... */
nuclear@0 120 if((fp = fopen(fname, mode))) {
nuclear@0 121 PVFS_FILE *vfp = malloc(sizeof *vfp);
nuclear@0 122 if(!vfp) {
nuclear@0 123 pvfs_errno = ENOMEM;
nuclear@0 124 return 0;
nuclear@0 125 }
nuclear@0 126 vfp->fp = fp;
nuclear@0 127 vfp->real = 1;
nuclear@0 128 return vfp;
nuclear@0 129 }
nuclear@0 130
nuclear@0 131 /* otherwise try and locate it in the virtual hierarchy */
nuclear@0 132 if(!(node = vnode_lookup(fname))) {
nuclear@0 133 return 0;
nuclear@0 134 }
nuclear@0 135 if(node->type != VNODE_FILE) {
nuclear@0 136 pvfs_errno = EISDIR;
nuclear@0 137 return 0;
nuclear@0 138 }
nuclear@0 139
nuclear@0 140 return VFILE(node);
nuclear@0 141 }
nuclear@0 142
nuclear@0 143 int pvfs_fclose(PVFS_FILE *fp)
nuclear@0 144 {
nuclear@0 145 if(fp->real) {
nuclear@0 146 /* it's real, just close it and free the struct */
nuclear@0 147 fclose(fp->fp);
nuclear@0 148 free(fp);
nuclear@0 149 return 0;
nuclear@0 150 }
nuclear@0 151
nuclear@0 152 /* TODO */
nuclear@0 153 return -1;
nuclear@0 154 }
nuclear@0 155
nuclear@2 156 int pvfs_fseek(PVFS_FILE *fp, long offset, int whence)
nuclear@2 157 {
nuclear@2 158 if(fp->real) {
nuclear@2 159 return fseek(fp->fp, offset, whence);
nuclear@2 160 }
nuclear@0 161
nuclear@2 162 return -1; /* TODO */
nuclear@2 163 }
nuclear@2 164
nuclear@2 165 long pvfs_ftell(PVFS_FILE *fp)
nuclear@2 166 {
nuclear@2 167 if(fp->real) {
nuclear@2 168 return ftell(fp->fp);
nuclear@2 169 }
nuclear@2 170 return -1; /* TODO */
nuclear@2 171 }
nuclear@2 172
nuclear@2 173 void pvfs_rewind(PVFS_FILE *fp)
nuclear@2 174 {
nuclear@2 175 pvfs_fseek(fp, 0, SEEK_SET);
nuclear@2 176 }
nuclear@2 177
nuclear@2 178 size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp)
nuclear@2 179 {
nuclear@2 180 if(fp->real) {
nuclear@2 181 return fread(buf, size, nitems, fp->fp);
nuclear@2 182 }
nuclear@2 183 return 0; /* TODO */
nuclear@2 184 }
nuclear@2 185
nuclear@2 186 size_t pvfs_fwrite(void *buf, size_t size, size_t nitems, PVFS_FILE *fp)
nuclear@2 187 {
nuclear@2 188 if(fp->real) {
nuclear@2 189 return fwrite(buf, size, nitems, fp->fp);
nuclear@2 190 }
nuclear@2 191 return 0; /* TODO */
nuclear@2 192 }
nuclear@0 193
nuclear@1 194 int pvfs_fgetc(PVFS_FILE *fp)
nuclear@1 195 {
nuclear@1 196 char c;
nuclear@1 197 if(pvfs_fread(&c, 1, 1, fp) != 1) {
nuclear@1 198 return -1;
nuclear@1 199 }
nuclear@1 200 return c;
nuclear@1 201 }
nuclear@0 202
nuclear@1 203 int pvfs_fputc(int c, PVFS_FILE *fp)
nuclear@1 204 {
nuclear@1 205 return pvfs_fwrite(&c, 1, 1, fp) == 1 ? 0 : -1;
nuclear@1 206 }
nuclear@0 207
nuclear@1 208 char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp)
nuclear@1 209 {
nuclear@1 210 int i;
nuclear@1 211 char *res = buf;
nuclear@1 212
nuclear@1 213 for(i=0; i<size - 1; i++) {
nuclear@1 214 int c = pvfs_fgetc(fp);
nuclear@1 215 if(!c) break;
nuclear@1 216
nuclear@1 217 *buf++ = c;
nuclear@1 218 if(c == '\n') break;
nuclear@1 219 }
nuclear@1 220
nuclear@1 221 *buf = 0;
nuclear@1 222 return res;
nuclear@1 223 }
nuclear@1 224
nuclear@1 225 int pvfs_fputs(char *buf, PVFS_FILE *fp)
nuclear@1 226 {
nuclear@1 227 int len = strlen(buf);
nuclear@1 228
nuclear@1 229 return pvfs_fwrite(buf, 1, len, fp) == 1 ? 0 : -1;
nuclear@1 230 }
nuclear@1 231
nuclear@1 232 int pvfs_fscanf(PVFS_FILE *fp, const char *fmt, ...)
nuclear@1 233 {
nuclear@1 234 va_list ap;
nuclear@1 235 int res;
nuclear@1 236
nuclear@1 237 va_start(ap, fmt);
nuclear@1 238 res = pvfs_vfscanf(fp, fmt, ap);
nuclear@1 239 va_end(ap);
nuclear@1 240 return res;
nuclear@1 241 }
nuclear@1 242
nuclear@1 243 int pvfs_vfscanf(PVFS_FILE *fp, const char *fmt, va_list ap)
nuclear@1 244 {
nuclear@1 245 return 0; /* TODO */
nuclear@1 246 }
nuclear@1 247
nuclear@1 248 int pvfs_fprintf(PVFS_FILE *fp, const char *fmt, ...)
nuclear@1 249 {
nuclear@1 250 va_list ap;
nuclear@1 251 int res;
nuclear@1 252
nuclear@1 253 va_start(ap, fmt);
nuclear@1 254 res = pvfs_vfprintf(fp, fmt, ap);
nuclear@2 255
nuclear@1 256 va_end(ap);
nuclear@1 257 return res;
nuclear@1 258 }
nuclear@1 259
nuclear@1 260 int pvfs_vfprintf(PVFS_FILE *fp, const char *fmt, va_list ap)
nuclear@1 261 {
nuclear@1 262 return 0; /* TODO */
nuclear@1 263 }
nuclear@0 264
nuclear@2 265 void pvfs_clearerr(PVFS_FILE *fp)
nuclear@2 266 {
nuclear@2 267 if(fp->real) {
nuclear@2 268 clearerr(fp->fp);
nuclear@2 269 return;
nuclear@2 270 }
nuclear@2 271 /* TODO */
nuclear@2 272 }
nuclear@2 273
nuclear@2 274 int pvfs_feof(PVFS_FILE *fp)
nuclear@2 275 {
nuclear@2 276 if(fp->real) {
nuclear@2 277 return feof(fp->fp);
nuclear@2 278 }
nuclear@2 279 return 0; /* TODO */
nuclear@2 280 }
nuclear@2 281
nuclear@2 282 int pvfs_ferror(PVFS_FILE *fp)
nuclear@2 283 {
nuclear@2 284 if(fp->real) {
nuclear@2 285 return ferror(fp->fp);
nuclear@2 286 }
nuclear@2 287 return -1; /* TODO */
nuclear@2 288 }
nuclear@0 289
nuclear@0 290 /* POSIX stuff */
nuclear@0 291 PVFS_DIR *pvfs_opendir(const char *dirname)
nuclear@0 292 {
nuclear@0 293 DIR *dir;
nuclear@0 294 struct vnode *node;
nuclear@0 295
nuclear@0 296 if((dir = opendir(dirname))) {
nuclear@0 297 PVFS_DIR *vdir = malloc(sizeof *vdir);
nuclear@0 298 if(!vdir) {
nuclear@0 299 pvfs_errno = ENOMEM;
nuclear@0 300 return 0;
nuclear@0 301 }
nuclear@0 302
nuclear@0 303 vdir->real = 1;
nuclear@0 304 vdir->dir = dir;
nuclear@0 305 return vdir;
nuclear@0 306 }
nuclear@0 307
nuclear@0 308 if(!(node = vnode_lookup(dirname))) {
nuclear@0 309 return 0;
nuclear@0 310 }
nuclear@0 311 if(node->type != VNODE_DIR) {
nuclear@0 312 pvfs_errno = ENOTDIR;
nuclear@0 313 return 0;
nuclear@0 314 }
nuclear@0 315 return VDIR(node);
nuclear@0 316 }
nuclear@0 317
nuclear@0 318 int pvfs_closedir(PVFS_DIR *dir)
nuclear@0 319 {
nuclear@0 320 if(dir->real) {
nuclear@0 321 int res = closedir(dir->dir);
nuclear@0 322 free(dir);
nuclear@0 323 return res;
nuclear@0 324 }
nuclear@0 325
nuclear@0 326 /* TODO */
nuclear@0 327 return -1;
nuclear@0 328 }
nuclear@1 329
nuclear@2 330 struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir)
nuclear@2 331 {
nuclear@2 332 static struct pvfs_dirent dent;
nuclear@0 333
nuclear@2 334 if(dir->real) {
nuclear@2 335 struct dirent *real_dent = readdir(dir->dir);
nuclear@2 336 if(!real_dent) {
nuclear@2 337 pvfs_errno = errno;
nuclear@2 338 return 0;
nuclear@2 339 }
nuclear@0 340
nuclear@2 341 strncpy(dent.d_name, real_dent->d_name, sizeof dent.d_name - 1);
nuclear@2 342 dent.d_name[sizeof dent.d_name - 1] = 0;
nuclear@2 343
nuclear@2 344 return &dent;
nuclear@2 345 }
nuclear@2 346 return 0; /* TODO */
nuclear@2 347 }
nuclear@2 348
nuclear@2 349 void pvfs_rewinddir(PVFS_DIR *dir)
nuclear@2 350 {
nuclear@2 351 if(dir->real) {
nuclear@2 352 rewinddir(dir->dir);
nuclear@2 353 return;
nuclear@2 354 }
nuclear@2 355 /* TODO */
nuclear@2 356 }
nuclear@2 357
nuclear@2 358 int pvfs_stat(const char *path, struct pvfs_stat *buf)
nuclear@2 359 {
nuclear@2 360 return -1; /* TODO */
nuclear@2 361 }