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 }
|