rev |
line source |
nuclear@0
|
1 #include <string.h>
|
nuclear@0
|
2 #include <alloca.h>
|
nuclear@0
|
3 #include <assert.h>
|
nuclear@0
|
4 #include "pvfs.h"
|
nuclear@0
|
5 #include "vnode.h"
|
nuclear@0
|
6
|
nuclear@0
|
7 int pvfs_errno;
|
nuclear@0
|
8
|
nuclear@0
|
9 int pvfs_mount(const char *mntpoint, const char *target)
|
nuclear@0
|
10 {
|
nuclear@0
|
11 struct vnode *srcnode, *destnode;
|
nuclear@0
|
12
|
nuclear@0
|
13 /* first locate the mount point vnode */
|
nuclear@0
|
14 if(!(srcnode = vnode_lookup(mntpoint))) {
|
nuclear@0
|
15 pvfs_errno = ENOENT;
|
nuclear@0
|
16 return -1;
|
nuclear@0
|
17 }
|
nuclear@0
|
18 /* and make sure it's a directory */
|
nuclear@0
|
19 if(srcnode->type != VNODE_DIR) {
|
nuclear@0
|
20 pvfs_errno = ENOTDIR;
|
nuclear@0
|
21 return -1;
|
nuclear@0
|
22 }
|
nuclear@0
|
23
|
nuclear@0
|
24 /* then locate the target vnode (if it exists) */
|
nuclear@0
|
25 if(!(destnode = vnode_lookup(target))) {
|
nuclear@0
|
26 /* it's some error other than that target doesn't exist, fail... */
|
nuclear@0
|
27 if(pvfs_errno != ENOENT) {
|
nuclear@0
|
28 return -1;
|
nuclear@0
|
29 }
|
nuclear@0
|
30 /* if it doesn't exist, it might be the case we're trying
|
nuclear@0
|
31 * to mount a package file or a real directory here. let's
|
nuclear@0
|
32 * try them in turn...
|
nuclear@0
|
33 */
|
nuclear@0
|
34 PVFS_DIR *dir;
|
nuclear@0
|
35 PVFS_FILE *fp;
|
nuclear@0
|
36
|
nuclear@0
|
37 if((dir = pvfs_opendir(target))) {
|
nuclear@0
|
38 /* it's obviously a real dir as vnode_lookup failed before... */
|
nuclear@0
|
39 assert(dir->real);
|
nuclear@0
|
40 if(!(destnode = vnode_create_dir(target, dir))) {
|
nuclear@0
|
41 return -1;
|
nuclear@0
|
42 }
|
nuclear@0
|
43
|
nuclear@0
|
44 } else if((fp = pvfs_fopen(target, "rb"))) {
|
nuclear@0
|
45 /* again, obviously real... */
|
nuclear@0
|
46 assert(fp->real);
|
nuclear@0
|
47 if(!(destnode = vnode_create_file(target, fp))) {
|
nuclear@0
|
48 return -1;
|
nuclear@0
|
49 }
|
nuclear@0
|
50
|
nuclear@0
|
51 } else {
|
nuclear@0
|
52 /* it's neither... so let's fail */
|
nuclear@0
|
53 pvfs_errno = ENOENT;
|
nuclear@0
|
54 return -1;
|
nuclear@0
|
55 }
|
nuclear@0
|
56 }
|
nuclear@0
|
57
|
nuclear@0
|
58 /* ok so we've got the two nodes, connect them up */
|
nuclear@0
|
59 srcnode->target = destnode;
|
nuclear@0
|
60 return 0;
|
nuclear@0
|
61 }
|
nuclear@0
|
62
|
nuclear@0
|
63 int pvfs_umount(const char *mntpoint)
|
nuclear@0
|
64 {
|
nuclear@0
|
65 struct vnode *node = vnode_lookup(mntpoint);
|
nuclear@0
|
66 if(!node) {
|
nuclear@0
|
67 return -1;
|
nuclear@0
|
68 }
|
nuclear@0
|
69 if(node->type != VNODE_DIR) {
|
nuclear@0
|
70 pvfs_errno = ENOTDIR;
|
nuclear@0
|
71 return -1;
|
nuclear@0
|
72 }
|
nuclear@0
|
73 if(!node->target) {
|
nuclear@0
|
74 pvfs_errno = EINVAL;
|
nuclear@0
|
75 return -1;
|
nuclear@0
|
76 }
|
nuclear@0
|
77 node->target = 0;
|
nuclear@0
|
78 return 0;
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@0
|
81 int pvfs_chdir(const char *path)
|
nuclear@0
|
82 {
|
nuclear@0
|
83 return vnode_chdir(path);
|
nuclear@0
|
84 }
|
nuclear@0
|
85
|
nuclear@0
|
86 int pvfs_mkdir(const char *path, unsigned int mode)
|
nuclear@0
|
87 {
|
nuclear@0
|
88 char *ppath;
|
nuclear@0
|
89 const char *dname;
|
nuclear@0
|
90 struct vnode *parent = 0;
|
nuclear@0
|
91
|
nuclear@0
|
92 ppath = alloca(strlen(path) + 1);
|
nuclear@0
|
93 strcpy(ppath, path);
|
nuclear@0
|
94
|
nuclear@0
|
95 if((dname = strrchr(path, '/'))) {
|
nuclear@0
|
96 ppath[++dname - path] = 0;
|
nuclear@0
|
97 if(!*dname) {
|
nuclear@0
|
98 pvfs_errno = ENOENT;
|
nuclear@0
|
99 return -1;
|
nuclear@0
|
100 }
|
nuclear@0
|
101 if(!(parent = vnode_lookup(ppath))) {
|
nuclear@0
|
102 return -1;
|
nuclear@0
|
103 }
|
nuclear@0
|
104 } else {
|
nuclear@0
|
105 dname = ppath;
|
nuclear@0
|
106 parent = vnode_getcwd();
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 return vnode_mkdir(parent, dname);
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 PVFS_FILE *pvfs_fopen(const char *fname, const char *mode)
|
nuclear@0
|
113 {
|
nuclear@0
|
114 FILE *fp;
|
nuclear@0
|
115 struct vnode *node;
|
nuclear@0
|
116
|
nuclear@0
|
117 /* if we find it in the filesystem, just use it... */
|
nuclear@0
|
118 if((fp = fopen(fname, mode))) {
|
nuclear@0
|
119 PVFS_FILE *vfp = malloc(sizeof *vfp);
|
nuclear@0
|
120 if(!vfp) {
|
nuclear@0
|
121 pvfs_errno = ENOMEM;
|
nuclear@0
|
122 return 0;
|
nuclear@0
|
123 }
|
nuclear@0
|
124 vfp->fp = fp;
|
nuclear@0
|
125 vfp->real = 1;
|
nuclear@0
|
126 return vfp;
|
nuclear@0
|
127 }
|
nuclear@0
|
128
|
nuclear@0
|
129 /* otherwise try and locate it in the virtual hierarchy */
|
nuclear@0
|
130 if(!(node = vnode_lookup(fname))) {
|
nuclear@0
|
131 return 0;
|
nuclear@0
|
132 }
|
nuclear@0
|
133 if(node->type != VNODE_FILE) {
|
nuclear@0
|
134 pvfs_errno = EISDIR;
|
nuclear@0
|
135 return 0;
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@0
|
138 return VFILE(node);
|
nuclear@0
|
139 }
|
nuclear@0
|
140
|
nuclear@0
|
141 int pvfs_fclose(PVFS_FILE *fp)
|
nuclear@0
|
142 {
|
nuclear@0
|
143 if(fp->real) {
|
nuclear@0
|
144 /* it's real, just close it and free the struct */
|
nuclear@0
|
145 fclose(fp->fp);
|
nuclear@0
|
146 free(fp);
|
nuclear@0
|
147 return 0;
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 /* TODO */
|
nuclear@0
|
151 return -1;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 int pvfs_fseek(PVFS_FILE *fp, long offset, int whence);
|
nuclear@0
|
155 long pvfs_ftell(PVFS_FILE *fp);
|
nuclear@0
|
156 void pvfs_rewind(PVFS_FILE *fp);
|
nuclear@0
|
157
|
nuclear@0
|
158 size_t pvfs_fread(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
|
nuclear@0
|
159 size_t pvfs_write(void *buf, size_t size, size_t nitems, PVFS_FILE *fp);
|
nuclear@0
|
160
|
nuclear@0
|
161 int pvfs_fgetc(PVFS_FILE *fp);
|
nuclear@0
|
162 int pvfs_fputc(int c, PVFS_FILE *fp);
|
nuclear@0
|
163
|
nuclear@0
|
164 char *pvfs_fgets(char *buf, int size, PVFS_FILE *fp);
|
nuclear@0
|
165 int pvfs_fputs(char *buf, PVFS_FILE *fp);
|
nuclear@0
|
166
|
nuclear@0
|
167 int pvfs_fscanf(PVFS_FILE *fp, const char *fmt, ...);
|
nuclear@0
|
168 int pvfs_vfscanf(PVFS_FILE *fp, const char *fmt, va_list ap);
|
nuclear@0
|
169 int pvfs_fprintf(PVFS_FILE *fp, const char *fmt, ...);
|
nuclear@0
|
170 int pvfs_vfprintf(PVFS_FILE *fp, const char *fmt, va_list ap);
|
nuclear@0
|
171
|
nuclear@0
|
172 void pvfs_clearerr(PVFS_FILE *fp);
|
nuclear@0
|
173 int pvfs_feof(PVFS_FILE *fp);
|
nuclear@0
|
174 int pvfs_ferror(PVFS_FILE *fp);
|
nuclear@0
|
175
|
nuclear@0
|
176 /* POSIX stuff */
|
nuclear@0
|
177 PVFS_DIR *pvfs_opendir(const char *dirname)
|
nuclear@0
|
178 {
|
nuclear@0
|
179 DIR *dir;
|
nuclear@0
|
180 struct vnode *node;
|
nuclear@0
|
181
|
nuclear@0
|
182 if((dir = opendir(dirname))) {
|
nuclear@0
|
183 PVFS_DIR *vdir = malloc(sizeof *vdir);
|
nuclear@0
|
184 if(!vdir) {
|
nuclear@0
|
185 pvfs_errno = ENOMEM;
|
nuclear@0
|
186 return 0;
|
nuclear@0
|
187 }
|
nuclear@0
|
188
|
nuclear@0
|
189 vdir->real = 1;
|
nuclear@0
|
190 vdir->dir = dir;
|
nuclear@0
|
191 return vdir;
|
nuclear@0
|
192 }
|
nuclear@0
|
193
|
nuclear@0
|
194 if(!(node = vnode_lookup(dirname))) {
|
nuclear@0
|
195 return 0;
|
nuclear@0
|
196 }
|
nuclear@0
|
197 if(node->type != VNODE_DIR) {
|
nuclear@0
|
198 pvfs_errno = ENOTDIR;
|
nuclear@0
|
199 return 0;
|
nuclear@0
|
200 }
|
nuclear@0
|
201 return VDIR(node);
|
nuclear@0
|
202 }
|
nuclear@0
|
203
|
nuclear@0
|
204 int pvfs_closedir(PVFS_DIR *dir)
|
nuclear@0
|
205 {
|
nuclear@0
|
206 if(dir->real) {
|
nuclear@0
|
207 int res = closedir(dir->dir);
|
nuclear@0
|
208 free(dir);
|
nuclear@0
|
209 return res;
|
nuclear@0
|
210 }
|
nuclear@0
|
211
|
nuclear@0
|
212 /* TODO */
|
nuclear@0
|
213 return -1;
|
nuclear@0
|
214 }
|
nuclear@0
|
215 struct pvfs_dirent *pvfs_readdir(PVFS_DIR *dir);
|
nuclear@0
|
216 void pvfs_rewinddir(PVFS_DIR *dir);
|
nuclear@0
|
217
|
nuclear@0
|
218 int pvfs_stat(const char *path, struct pvfs_stat *buf);
|
nuclear@0
|
219
|