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
|