packvfs

view 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
line source
1 #include <string.h>
2 #include <stdarg.h>
3 #include <assert.h>
4 #include <alloca.h>
5 #include "pvfs.h"
6 #include "vnode.h"
8 int pvfs_errno;
10 int pvfs_mount(const char *mntpoint, const char *target)
11 {
12 struct vnode *srcnode, *destnode;
14 /* first locate the mount point vnode */
15 if(!(srcnode = vnode_lookup(mntpoint))) {
16 pvfs_errno = ENOENT;
17 return -1;
18 }
19 /* and make sure it's a directory */
20 if(srcnode->type != VNODE_DIR) {
21 pvfs_errno = ENOTDIR;
22 return -1;
23 }
25 /* then locate the target vnode (if it exists) */
26 if(!(destnode = vnode_lookup(target))) {
27 PVFS_DIR *dir;
28 PVFS_FILE *fp;
30 /* it's some error other than that target doesn't exist, fail... */
31 if(pvfs_errno != ENOENT) {
32 return -1;
33 }
35 /* if it doesn't exist, it might be the case we're trying
36 * to mount a package file or a real directory here. let's
37 * try them in turn...
38 */
39 if((dir = pvfs_opendir(target))) {
40 /* it's obviously a real dir as vnode_lookup failed before... */
41 assert(dir->real);
42 if(!(destnode = vnode_create_dir(target, dir))) {
43 return -1;
44 }
46 } else if((fp = pvfs_fopen(target, "rb"))) {
47 /* again, obviously real... */
48 assert(fp->real);
49 if(!(destnode = vnode_create_file(target, fp))) {
50 return -1;
51 }
53 } else {
54 /* it's neither... so let's fail */
55 pvfs_errno = ENOENT;
56 return -1;
57 }
58 }
60 /* ok so we've got the two nodes, connect them up */
61 srcnode->target = destnode;
62 return 0;
63 }
65 int pvfs_umount(const char *mntpoint)
66 {
67 struct vnode *node = vnode_lookup(mntpoint);
68 if(!node) {
69 return -1;
70 }
71 if(node->type != VNODE_DIR) {
72 pvfs_errno = ENOTDIR;
73 return -1;
74 }
75 if(!node->target) {
76 pvfs_errno = EINVAL;
77 return -1;
78 }
79 node->target = 0;
80 return 0;
81 }
83 int pvfs_chdir(const char *path)
84 {
85 return vnode_chdir(path);
86 }
88 int pvfs_mkdir(const char *path, unsigned int mode)
89 {
90 char *ppath;
91 const char *dname;
92 struct vnode *parent = 0;
94 ppath = alloca(strlen(path) + 1);
95 strcpy(ppath, path);
97 if((dname = strrchr(path, '/'))) {
98 ppath[++dname - path] = 0;
99 if(!*dname) {
100 pvfs_errno = ENOENT;
101 return -1;
102 }
103 if(!(parent = vnode_lookup(ppath))) {
104 return -1;
105 }
106 } else {
107 dname = ppath;
108 parent = vnode_getcwd();
109 }
111 return vnode_mkdir(parent, dname);
112 }
114 PVFS_FILE *pvfs_fopen(const char *fname, const char *mode)
115 {
116 FILE *fp;
117 struct vnode *node;
119 /* if we find it in the filesystem, just use it... */
120 if((fp = fopen(fname, mode))) {
121 PVFS_FILE *vfp = malloc(sizeof *vfp);
122 if(!vfp) {
123 pvfs_errno = ENOMEM;
124 return 0;
125 }
126 vfp->fp = fp;
127 vfp->real = 1;
128 return vfp;
129 }
131 /* otherwise try and locate it in the virtual hierarchy */
132 if(!(node = vnode_lookup(fname))) {
133 return 0;
134 }
135 if(node->type != VNODE_FILE) {
136 pvfs_errno = EISDIR;
137 return 0;
138 }
140 return VFILE(node);
141 }
143 int pvfs_fclose(PVFS_FILE *fp)
144 {
145 if(fp->real) {
146 /* it's real, just close it and free the struct */
147 fclose(fp->fp);
148 free(fp);
149 return 0;
150 }
152 /* TODO */
153 return -1;
154 }
156 int pvfs_fseek(PVFS_FILE *fp, long offset, int whence);
157 long pvfs_ftell(PVFS_FILE *fp);
158 void pvfs_rewind(PVFS_FILE *fp);
160 size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
161 size_t pvfs_fwrite(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
163 int pvfs_fgetc(PVFS_FILE *fp)
164 {
165 char c;
166 if(pvfs_fread(&c, 1, 1, fp) != 1) {
167 return -1;
168 }
169 return c;
170 }
172 int pvfs_fputc(int c, PVFS_FILE *fp)
173 {
174 return pvfs_fwrite(&c, 1, 1, fp) == 1 ? 0 : -1;
175 }
177 char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp)
178 {
179 int i;
180 char *res = buf;
182 for(i=0; i<size - 1; i++) {
183 int c = pvfs_fgetc(fp);
184 if(!c) break;
186 *buf++ = c;
187 if(c == '\n') break;
188 }
190 *buf = 0;
191 return res;
192 }
194 int pvfs_fputs(char *buf, PVFS_FILE *fp)
195 {
196 int len = strlen(buf);
198 return pvfs_fwrite(buf, 1, len, fp) == 1 ? 0 : -1;
199 }
201 int pvfs_fscanf(PVFS_FILE *fp, const char *fmt, ...)
202 {
203 va_list ap;
204 int res;
206 va_start(ap, fmt);
207 res = pvfs_vfscanf(fp, fmt, ap);
208 va_end(ap);
209 return res;
210 }
212 int pvfs_vfscanf(PVFS_FILE *fp, const char *fmt, va_list ap)
213 {
214 return 0; /* TODO */
215 }
217 int pvfs_fprintf(PVFS_FILE *fp, const char *fmt, ...)
218 {
219 va_list ap;
220 int res;
222 va_start(ap, fmt);
223 res = pvfs_vfprintf(fp, fmt, ap);
224 va_end(ap);
225 return res;
226 }
228 int pvfs_vfprintf(PVFS_FILE *fp, const char *fmt, va_list ap)
229 {
230 return 0; /* TODO */
231 }
233 void pvfs_clearerr(PVFS_FILE *fp);
234 int pvfs_feof(PVFS_FILE *fp);
235 int pvfs_ferror(PVFS_FILE *fp);
237 /* POSIX stuff */
238 PVFS_DIR *pvfs_opendir(const char *dirname)
239 {
240 DIR *dir;
241 struct vnode *node;
243 if((dir = opendir(dirname))) {
244 PVFS_DIR *vdir = malloc(sizeof *vdir);
245 if(!vdir) {
246 pvfs_errno = ENOMEM;
247 return 0;
248 }
250 vdir->real = 1;
251 vdir->dir = dir;
252 return vdir;
253 }
255 if(!(node = vnode_lookup(dirname))) {
256 return 0;
257 }
258 if(node->type != VNODE_DIR) {
259 pvfs_errno = ENOTDIR;
260 return 0;
261 }
262 return VDIR(node);
263 }
265 int pvfs_closedir(PVFS_DIR *dir)
266 {
267 if(dir->real) {
268 int res = closedir(dir->dir);
269 free(dir);
270 return res;
271 }
273 /* TODO */
274 return -1;
275 }
277 struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir);
278 void pvfs_rewinddir(PVFS_DIR *dir);
280 int pvfs_stat(const char *path, struct pvfs_stat *buf);