packvfs

annotate src/pvfs.c @ 1:a0b3b6682d92

*slowly* filling in some unimplemented functions
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 04 Nov 2013 01:01:22 +0200
parents df5e9ee65a50
children dc23ab0545a6
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@0 156 int pvfs_fseek(PVFS_FILE *fp, long offset, int whence);
nuclear@0 157 long pvfs_ftell(PVFS_FILE *fp);
nuclear@0 158 void pvfs_rewind(PVFS_FILE *fp);
nuclear@0 159
nuclear@0 160 size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
nuclear@1 161 size_t pvfs_fwrite(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
nuclear@0 162
nuclear@1 163 int pvfs_fgetc(PVFS_FILE *fp)
nuclear@1 164 {
nuclear@1 165 char c;
nuclear@1 166 if(pvfs_fread(&c, 1, 1, fp) != 1) {
nuclear@1 167 return -1;
nuclear@1 168 }
nuclear@1 169 return c;
nuclear@1 170 }
nuclear@0 171
nuclear@1 172 int pvfs_fputc(int c, PVFS_FILE *fp)
nuclear@1 173 {
nuclear@1 174 return pvfs_fwrite(&c, 1, 1, fp) == 1 ? 0 : -1;
nuclear@1 175 }
nuclear@0 176
nuclear@1 177 char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp)
nuclear@1 178 {
nuclear@1 179 int i;
nuclear@1 180 char *res = buf;
nuclear@1 181
nuclear@1 182 for(i=0; i<size - 1; i++) {
nuclear@1 183 int c = pvfs_fgetc(fp);
nuclear@1 184 if(!c) break;
nuclear@1 185
nuclear@1 186 *buf++ = c;
nuclear@1 187 if(c == '\n') break;
nuclear@1 188 }
nuclear@1 189
nuclear@1 190 *buf = 0;
nuclear@1 191 return res;
nuclear@1 192 }
nuclear@1 193
nuclear@1 194 int pvfs_fputs(char *buf, PVFS_FILE *fp)
nuclear@1 195 {
nuclear@1 196 int len = strlen(buf);
nuclear@1 197
nuclear@1 198 return pvfs_fwrite(buf, 1, len, fp) == 1 ? 0 : -1;
nuclear@1 199 }
nuclear@1 200
nuclear@1 201 int pvfs_fscanf(PVFS_FILE *fp, const char *fmt, ...)
nuclear@1 202 {
nuclear@1 203 va_list ap;
nuclear@1 204 int res;
nuclear@1 205
nuclear@1 206 va_start(ap, fmt);
nuclear@1 207 res = pvfs_vfscanf(fp, fmt, ap);
nuclear@1 208 va_end(ap);
nuclear@1 209 return res;
nuclear@1 210 }
nuclear@1 211
nuclear@1 212 int pvfs_vfscanf(PVFS_FILE *fp, const char *fmt, va_list ap)
nuclear@1 213 {
nuclear@1 214 return 0; /* TODO */
nuclear@1 215 }
nuclear@1 216
nuclear@1 217 int pvfs_fprintf(PVFS_FILE *fp, const char *fmt, ...)
nuclear@1 218 {
nuclear@1 219 va_list ap;
nuclear@1 220 int res;
nuclear@1 221
nuclear@1 222 va_start(ap, fmt);
nuclear@1 223 res = pvfs_vfprintf(fp, fmt, ap);
nuclear@1 224 va_end(ap);
nuclear@1 225 return res;
nuclear@1 226 }
nuclear@1 227
nuclear@1 228 int pvfs_vfprintf(PVFS_FILE *fp, const char *fmt, va_list ap)
nuclear@1 229 {
nuclear@1 230 return 0; /* TODO */
nuclear@1 231 }
nuclear@0 232
nuclear@0 233 void pvfs_clearerr(PVFS_FILE *fp);
nuclear@0 234 int pvfs_feof(PVFS_FILE *fp);
nuclear@0 235 int pvfs_ferror(PVFS_FILE *fp);
nuclear@0 236
nuclear@0 237 /* POSIX stuff */
nuclear@0 238 PVFS_DIR *pvfs_opendir(const char *dirname)
nuclear@0 239 {
nuclear@0 240 DIR *dir;
nuclear@0 241 struct vnode *node;
nuclear@0 242
nuclear@0 243 if((dir = opendir(dirname))) {
nuclear@0 244 PVFS_DIR *vdir = malloc(sizeof *vdir);
nuclear@0 245 if(!vdir) {
nuclear@0 246 pvfs_errno = ENOMEM;
nuclear@0 247 return 0;
nuclear@0 248 }
nuclear@0 249
nuclear@0 250 vdir->real = 1;
nuclear@0 251 vdir->dir = dir;
nuclear@0 252 return vdir;
nuclear@0 253 }
nuclear@0 254
nuclear@0 255 if(!(node = vnode_lookup(dirname))) {
nuclear@0 256 return 0;
nuclear@0 257 }
nuclear@0 258 if(node->type != VNODE_DIR) {
nuclear@0 259 pvfs_errno = ENOTDIR;
nuclear@0 260 return 0;
nuclear@0 261 }
nuclear@0 262 return VDIR(node);
nuclear@0 263 }
nuclear@0 264
nuclear@0 265 int pvfs_closedir(PVFS_DIR *dir)
nuclear@0 266 {
nuclear@0 267 if(dir->real) {
nuclear@0 268 int res = closedir(dir->dir);
nuclear@0 269 free(dir);
nuclear@0 270 return res;
nuclear@0 271 }
nuclear@0 272
nuclear@0 273 /* TODO */
nuclear@0 274 return -1;
nuclear@0 275 }
nuclear@1 276
nuclear@0 277 struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir);
nuclear@0 278 void pvfs_rewinddir(PVFS_DIR *dir);
nuclear@0 279
nuclear@0 280 int pvfs_stat(const char *path, struct pvfs_stat *buf);
nuclear@0 281