Blame


1 2277c5d7 2004-03-21 devnull #include <u.h>
2 2277c5d7 2004-03-21 devnull #include <libc.h>
3 2277c5d7 2004-03-21 devnull #include <auth.h>
4 2277c5d7 2004-03-21 devnull #include <fcall.h>
5 2277c5d7 2004-03-21 devnull #include <thread.h>
6 2277c5d7 2004-03-21 devnull #include <9p.h>
7 2277c5d7 2004-03-21 devnull
8 2277c5d7 2004-03-21 devnull /*
9 2277c5d7 2004-03-21 devnull * To avoid deadlock, the following rules must be followed.
10 2277c5d7 2004-03-21 devnull * Always lock child then parent, never parent then child.
11 2277c5d7 2004-03-21 devnull * If holding the free file lock, do not lock any Files.
12 2277c5d7 2004-03-21 devnull */
13 2277c5d7 2004-03-21 devnull struct Filelist {
14 2277c5d7 2004-03-21 devnull File *f;
15 2277c5d7 2004-03-21 devnull Filelist *link;
16 2277c5d7 2004-03-21 devnull };
17 2277c5d7 2004-03-21 devnull
18 2277c5d7 2004-03-21 devnull static QLock filelk;
19 2277c5d7 2004-03-21 devnull static File *freefilelist;
20 2277c5d7 2004-03-21 devnull
21 2277c5d7 2004-03-21 devnull static File*
22 2277c5d7 2004-03-21 devnull allocfile(void)
23 2277c5d7 2004-03-21 devnull {
24 2277c5d7 2004-03-21 devnull int i, a;
25 2277c5d7 2004-03-21 devnull File *f;
26 2277c5d7 2004-03-21 devnull enum { N = 16 };
27 2277c5d7 2004-03-21 devnull
28 2277c5d7 2004-03-21 devnull qlock(&filelk);
29 2277c5d7 2004-03-21 devnull if(freefilelist == nil){
30 2277c5d7 2004-03-21 devnull f = emalloc9p(N*sizeof(*f));
31 2277c5d7 2004-03-21 devnull for(i=0; i<N-1; i++)
32 2277c5d7 2004-03-21 devnull f[i].aux = &f[i+1];
33 2277c5d7 2004-03-21 devnull f[N-1].aux = nil;
34 2277c5d7 2004-03-21 devnull f[0].allocd = 1;
35 2277c5d7 2004-03-21 devnull freefilelist = f;
36 2277c5d7 2004-03-21 devnull }
37 2277c5d7 2004-03-21 devnull
38 2277c5d7 2004-03-21 devnull f = freefilelist;
39 2277c5d7 2004-03-21 devnull freefilelist = f->aux;
40 2277c5d7 2004-03-21 devnull qunlock(&filelk);
41 2277c5d7 2004-03-21 devnull
42 2277c5d7 2004-03-21 devnull a = f->allocd;
43 2277c5d7 2004-03-21 devnull memset(f, 0, sizeof *f);
44 2277c5d7 2004-03-21 devnull f->allocd = a;
45 2277c5d7 2004-03-21 devnull return f;
46 2277c5d7 2004-03-21 devnull }
47 2277c5d7 2004-03-21 devnull
48 2277c5d7 2004-03-21 devnull static void
49 2277c5d7 2004-03-21 devnull freefile(File *f)
50 2277c5d7 2004-03-21 devnull {
51 2277c5d7 2004-03-21 devnull Filelist *fl, *flnext;
52 2277c5d7 2004-03-21 devnull
53 2277c5d7 2004-03-21 devnull for(fl=f->filelist; fl; fl=flnext){
54 2277c5d7 2004-03-21 devnull flnext = fl->link;
55 2277c5d7 2004-03-21 devnull assert(fl->f == nil);
56 2277c5d7 2004-03-21 devnull free(fl);
57 2277c5d7 2004-03-21 devnull }
58 2277c5d7 2004-03-21 devnull
59 2277c5d7 2004-03-21 devnull free(f->dir.name);
60 2277c5d7 2004-03-21 devnull free(f->dir.uid);
61 2277c5d7 2004-03-21 devnull free(f->dir.gid);
62 2277c5d7 2004-03-21 devnull free(f->dir.muid);
63 2277c5d7 2004-03-21 devnull qlock(&filelk);
64 2277c5d7 2004-03-21 devnull assert(f->ref.ref == 0);
65 2277c5d7 2004-03-21 devnull f->aux = freefilelist;
66 2277c5d7 2004-03-21 devnull freefilelist = f;
67 2277c5d7 2004-03-21 devnull qunlock(&filelk);
68 2277c5d7 2004-03-21 devnull }
69 2277c5d7 2004-03-21 devnull
70 2277c5d7 2004-03-21 devnull void
71 2277c5d7 2004-03-21 devnull closefile(File *f)
72 2277c5d7 2004-03-21 devnull {
73 2277c5d7 2004-03-21 devnull if(decref(&f->ref) == 0){
74 2277c5d7 2004-03-21 devnull f->tree->destroy(f);
75 2277c5d7 2004-03-21 devnull freefile(f);
76 2277c5d7 2004-03-21 devnull }
77 2277c5d7 2004-03-21 devnull }
78 2277c5d7 2004-03-21 devnull
79 2277c5d7 2004-03-21 devnull static void
80 2277c5d7 2004-03-21 devnull nop(File *f)
81 2277c5d7 2004-03-21 devnull {
82 2277c5d7 2004-03-21 devnull USED(f);
83 2277c5d7 2004-03-21 devnull }
84 2277c5d7 2004-03-21 devnull
85 2277c5d7 2004-03-21 devnull int
86 2277c5d7 2004-03-21 devnull removefile(File *f)
87 2277c5d7 2004-03-21 devnull {
88 2277c5d7 2004-03-21 devnull File *fp;
89 2277c5d7 2004-03-21 devnull Filelist *fl;
90 2277c5d7 2004-03-21 devnull
91 2277c5d7 2004-03-21 devnull fp = f->parent;
92 2277c5d7 2004-03-21 devnull if(fp == nil){
93 2277c5d7 2004-03-21 devnull werrstr("no parent");
94 2277c5d7 2004-03-21 devnull closefile(f);
95 2277c5d7 2004-03-21 devnull return -1;
96 2277c5d7 2004-03-21 devnull }
97 2277c5d7 2004-03-21 devnull
98 2277c5d7 2004-03-21 devnull if(fp == f){
99 2277c5d7 2004-03-21 devnull werrstr("cannot remove root");
100 2277c5d7 2004-03-21 devnull closefile(f);
101 2277c5d7 2004-03-21 devnull return -1;
102 2277c5d7 2004-03-21 devnull }
103 2277c5d7 2004-03-21 devnull
104 2277c5d7 2004-03-21 devnull wlock(&fp->rwlock);
105 2277c5d7 2004-03-21 devnull wlock(&f->rwlock);
106 2277c5d7 2004-03-21 devnull if(f->nchild != 0){
107 2277c5d7 2004-03-21 devnull werrstr("has children");
108 2277c5d7 2004-03-21 devnull wunlock(&f->rwlock);
109 2277c5d7 2004-03-21 devnull wunlock(&fp->rwlock);
110 2277c5d7 2004-03-21 devnull closefile(f);
111 2277c5d7 2004-03-21 devnull return -1;
112 2277c5d7 2004-03-21 devnull }
113 2277c5d7 2004-03-21 devnull
114 2277c5d7 2004-03-21 devnull if(f->parent != fp){
115 2277c5d7 2004-03-21 devnull werrstr("parent changed underfoot");
116 2277c5d7 2004-03-21 devnull wunlock(&f->rwlock);
117 2277c5d7 2004-03-21 devnull wunlock(&fp->rwlock);
118 2277c5d7 2004-03-21 devnull closefile(f);
119 2277c5d7 2004-03-21 devnull return -1;
120 2277c5d7 2004-03-21 devnull }
121 2277c5d7 2004-03-21 devnull
122 2277c5d7 2004-03-21 devnull for(fl=fp->filelist; fl; fl=fl->link)
123 2277c5d7 2004-03-21 devnull if(fl->f == f)
124 2277c5d7 2004-03-21 devnull break;
125 2277c5d7 2004-03-21 devnull assert(fl != nil && fl->f == f);
126 2277c5d7 2004-03-21 devnull
127 2277c5d7 2004-03-21 devnull fl->f = nil;
128 2277c5d7 2004-03-21 devnull fp->nchild--;
129 2277c5d7 2004-03-21 devnull f->parent = nil;
130 2277c5d7 2004-03-21 devnull wunlock(&fp->rwlock);
131 2277c5d7 2004-03-21 devnull wunlock(&f->rwlock);
132 2277c5d7 2004-03-21 devnull
133 2277c5d7 2004-03-21 devnull closefile(fp); /* reference from child */
134 2277c5d7 2004-03-21 devnull closefile(f); /* reference from tree */
135 2277c5d7 2004-03-21 devnull closefile(f);
136 2277c5d7 2004-03-21 devnull return 0;
137 2277c5d7 2004-03-21 devnull }
138 2277c5d7 2004-03-21 devnull
139 2277c5d7 2004-03-21 devnull File*
140 2277c5d7 2004-03-21 devnull createfile(File *fp, char *name, char *uid, ulong perm, void *aux)
141 2277c5d7 2004-03-21 devnull {
142 2277c5d7 2004-03-21 devnull File *f;
143 2277c5d7 2004-03-21 devnull Filelist *fl, *freel;
144 2277c5d7 2004-03-21 devnull Tree *t;
145 2277c5d7 2004-03-21 devnull
146 2277c5d7 2004-03-21 devnull if((fp->dir.qid.type&QTDIR) == 0){
147 2277c5d7 2004-03-21 devnull werrstr("create in non-directory");
148 2277c5d7 2004-03-21 devnull return nil;
149 2277c5d7 2004-03-21 devnull }
150 2277c5d7 2004-03-21 devnull
151 2277c5d7 2004-03-21 devnull freel = nil;
152 2277c5d7 2004-03-21 devnull wlock(&fp->rwlock);
153 2277c5d7 2004-03-21 devnull for(fl=fp->filelist; fl; fl=fl->link){
154 2277c5d7 2004-03-21 devnull if(fl->f == nil)
155 2277c5d7 2004-03-21 devnull freel = fl;
156 2277c5d7 2004-03-21 devnull else if(strcmp(fl->f->dir.name, name) == 0){
157 2277c5d7 2004-03-21 devnull wunlock(&fp->rwlock);
158 2277c5d7 2004-03-21 devnull werrstr("file already exists");
159 2277c5d7 2004-03-21 devnull return nil;
160 2277c5d7 2004-03-21 devnull }
161 2277c5d7 2004-03-21 devnull }
162 2277c5d7 2004-03-21 devnull
163 2277c5d7 2004-03-21 devnull if(freel == nil){
164 2277c5d7 2004-03-21 devnull freel = emalloc9p(sizeof *freel);
165 2277c5d7 2004-03-21 devnull freel->link = fp->filelist;
166 2277c5d7 2004-03-21 devnull fp->filelist = freel;
167 2277c5d7 2004-03-21 devnull }
168 2277c5d7 2004-03-21 devnull
169 2277c5d7 2004-03-21 devnull f = allocfile();
170 2277c5d7 2004-03-21 devnull f->dir.name = estrdup9p(name);
171 2277c5d7 2004-03-21 devnull f->dir.uid = estrdup9p(uid ? uid : fp->dir.uid);
172 2277c5d7 2004-03-21 devnull f->dir.gid = estrdup9p(fp->dir.gid);
173 2277c5d7 2004-03-21 devnull f->dir.muid = estrdup9p(uid ? uid : "unknown");
174 2277c5d7 2004-03-21 devnull f->aux = aux;
175 2277c5d7 2004-03-21 devnull f->dir.mode = perm;
176 2277c5d7 2004-03-21 devnull
177 2277c5d7 2004-03-21 devnull t = fp->tree;
178 2277c5d7 2004-03-21 devnull lock(&t->genlock);
179 2277c5d7 2004-03-21 devnull f->dir.qid.path = t->qidgen++;
180 2277c5d7 2004-03-21 devnull unlock(&t->genlock);
181 2277c5d7 2004-03-21 devnull if(perm & DMDIR)
182 2277c5d7 2004-03-21 devnull f->dir.qid.type |= QTDIR;
183 2277c5d7 2004-03-21 devnull if(perm & DMAPPEND)
184 2277c5d7 2004-03-21 devnull f->dir.qid.type |= QTAPPEND;
185 2277c5d7 2004-03-21 devnull if(perm & DMEXCL)
186 2277c5d7 2004-03-21 devnull f->dir.qid.type |= QTEXCL;
187 2277c5d7 2004-03-21 devnull
188 2277c5d7 2004-03-21 devnull f->dir.mode = perm;
189 2277c5d7 2004-03-21 devnull f->dir.atime = f->dir.mtime = time(0);
190 2277c5d7 2004-03-21 devnull f->dir.length = 0;
191 2277c5d7 2004-03-21 devnull f->parent = fp;
192 2277c5d7 2004-03-21 devnull incref(&fp->ref);
193 2277c5d7 2004-03-21 devnull f->tree = fp->tree;
194 2277c5d7 2004-03-21 devnull
195 2277c5d7 2004-03-21 devnull incref(&f->ref); /* being returned */
196 2277c5d7 2004-03-21 devnull incref(&f->ref); /* for the tree */
197 2277c5d7 2004-03-21 devnull freel->f = f;
198 2277c5d7 2004-03-21 devnull fp->nchild++;
199 2277c5d7 2004-03-21 devnull wunlock(&fp->rwlock);
200 2277c5d7 2004-03-21 devnull
201 2277c5d7 2004-03-21 devnull return f;
202 2277c5d7 2004-03-21 devnull }
203 2277c5d7 2004-03-21 devnull
204 2277c5d7 2004-03-21 devnull static File*
205 2277c5d7 2004-03-21 devnull walkfile1(File *dir, char *elem)
206 2277c5d7 2004-03-21 devnull {
207 2277c5d7 2004-03-21 devnull File *fp;
208 2277c5d7 2004-03-21 devnull Filelist *fl;
209 2277c5d7 2004-03-21 devnull
210 2277c5d7 2004-03-21 devnull rlock(&dir->rwlock);
211 2277c5d7 2004-03-21 devnull if(strcmp(elem, "..") == 0){
212 2277c5d7 2004-03-21 devnull fp = dir->parent;
213 2277c5d7 2004-03-21 devnull incref(&fp->ref);
214 2277c5d7 2004-03-21 devnull runlock(&dir->rwlock);
215 2277c5d7 2004-03-21 devnull closefile(dir);
216 2277c5d7 2004-03-21 devnull return fp;
217 2277c5d7 2004-03-21 devnull }
218 2277c5d7 2004-03-21 devnull
219 2277c5d7 2004-03-21 devnull fp = nil;
220 2277c5d7 2004-03-21 devnull for(fl=dir->filelist; fl; fl=fl->link)
221 2277c5d7 2004-03-21 devnull if(fl->f && strcmp(fl->f->dir.name, elem)==0){
222 2277c5d7 2004-03-21 devnull fp = fl->f;
223 2277c5d7 2004-03-21 devnull incref(&fp->ref);
224 2277c5d7 2004-03-21 devnull break;
225 2277c5d7 2004-03-21 devnull }
226 2277c5d7 2004-03-21 devnull
227 2277c5d7 2004-03-21 devnull runlock(&dir->rwlock);
228 2277c5d7 2004-03-21 devnull closefile(dir);
229 2277c5d7 2004-03-21 devnull return fp;
230 2277c5d7 2004-03-21 devnull }
231 2277c5d7 2004-03-21 devnull
232 2277c5d7 2004-03-21 devnull File*
233 2277c5d7 2004-03-21 devnull walkfile(File *f, char *path)
234 2277c5d7 2004-03-21 devnull {
235 2277c5d7 2004-03-21 devnull char *os, *s, *nexts;
236 2277c5d7 2004-03-21 devnull File *nf;
237 2277c5d7 2004-03-21 devnull
238 2277c5d7 2004-03-21 devnull if(strchr(path, '/') == nil)
239 2277c5d7 2004-03-21 devnull return walkfile1(f, path); /* avoid malloc */
240 2277c5d7 2004-03-21 devnull
241 2277c5d7 2004-03-21 devnull os = s = estrdup9p(path);
242 2277c5d7 2004-03-21 devnull incref(&f->ref);
243 2277c5d7 2004-03-21 devnull for(; *s; s=nexts){
244 2277c5d7 2004-03-21 devnull if(nexts = strchr(s, '/'))
245 2277c5d7 2004-03-21 devnull *nexts++ = '\0';
246 2277c5d7 2004-03-21 devnull else
247 2277c5d7 2004-03-21 devnull nexts = s+strlen(s);
248 2277c5d7 2004-03-21 devnull nf = walkfile1(f, s);
249 2277c5d7 2004-03-21 devnull decref(&f->ref);
250 2277c5d7 2004-03-21 devnull f = nf;
251 2277c5d7 2004-03-21 devnull if(f == nil)
252 2277c5d7 2004-03-21 devnull break;
253 2277c5d7 2004-03-21 devnull }
254 2277c5d7 2004-03-21 devnull free(os);
255 2277c5d7 2004-03-21 devnull return f;
256 a0f1e21f 2004-04-20 devnull }
257 a0f1e21f 2004-04-20 devnull
258 a0f1e21f 2004-04-20 devnull static Qid
259 a0f1e21f 2004-04-20 devnull mkqid(vlong path, long vers, int type)
260 a0f1e21f 2004-04-20 devnull {
261 a0f1e21f 2004-04-20 devnull Qid q;
262 a0f1e21f 2004-04-20 devnull
263 a0f1e21f 2004-04-20 devnull q.path = path;
264 a0f1e21f 2004-04-20 devnull q.vers = vers;
265 a0f1e21f 2004-04-20 devnull q.type = type;
266 a0f1e21f 2004-04-20 devnull return q;
267 2277c5d7 2004-03-21 devnull }
268 a0f1e21f 2004-04-20 devnull
269 2277c5d7 2004-03-21 devnull
270 2277c5d7 2004-03-21 devnull Tree*
271 2277c5d7 2004-03-21 devnull alloctree(char *uid, char *gid, ulong mode, void (*destroy)(File*))
272 2277c5d7 2004-03-21 devnull {
273 2277c5d7 2004-03-21 devnull char *muid;
274 2277c5d7 2004-03-21 devnull Tree *t;
275 2277c5d7 2004-03-21 devnull File *f;
276 2277c5d7 2004-03-21 devnull
277 2277c5d7 2004-03-21 devnull t = emalloc9p(sizeof *t);
278 2277c5d7 2004-03-21 devnull f = allocfile();
279 2277c5d7 2004-03-21 devnull f->dir.name = estrdup9p("/");
280 2277c5d7 2004-03-21 devnull if(uid == nil){
281 2277c5d7 2004-03-21 devnull if(uid = getuser())
282 2277c5d7 2004-03-21 devnull uid = estrdup9p(uid);
283 2277c5d7 2004-03-21 devnull }
284 2277c5d7 2004-03-21 devnull if(uid == nil)
285 2277c5d7 2004-03-21 devnull uid = estrdup9p("none");
286 2277c5d7 2004-03-21 devnull else
287 2277c5d7 2004-03-21 devnull uid = estrdup9p(uid);
288 2277c5d7 2004-03-21 devnull
289 2277c5d7 2004-03-21 devnull if(gid == nil)
290 2277c5d7 2004-03-21 devnull gid = estrdup9p(uid);
291 2277c5d7 2004-03-21 devnull else
292 2277c5d7 2004-03-21 devnull gid = estrdup9p(gid);
293 2277c5d7 2004-03-21 devnull
294 2277c5d7 2004-03-21 devnull muid = estrdup9p(uid);
295 2277c5d7 2004-03-21 devnull
296 a0f1e21f 2004-04-20 devnull f->dir.qid = mkqid(0, 0, QTDIR);
297 2277c5d7 2004-03-21 devnull f->dir.length = 0;
298 2277c5d7 2004-03-21 devnull f->dir.atime = f->dir.mtime = time(0);
299 2277c5d7 2004-03-21 devnull f->dir.mode = DMDIR | mode;
300 2277c5d7 2004-03-21 devnull f->tree = t;
301 2277c5d7 2004-03-21 devnull f->parent = f;
302 2277c5d7 2004-03-21 devnull f->dir.uid = uid;
303 2277c5d7 2004-03-21 devnull f->dir.gid = gid;
304 2277c5d7 2004-03-21 devnull f->dir.muid = muid;
305 2277c5d7 2004-03-21 devnull
306 2277c5d7 2004-03-21 devnull incref(&f->ref);
307 2277c5d7 2004-03-21 devnull t->root = f;
308 2277c5d7 2004-03-21 devnull t->qidgen = 0;
309 2277c5d7 2004-03-21 devnull t->dirqidgen = 1;
310 2277c5d7 2004-03-21 devnull if(destroy == nil)
311 2277c5d7 2004-03-21 devnull destroy = nop;
312 2277c5d7 2004-03-21 devnull t->destroy = destroy;
313 2277c5d7 2004-03-21 devnull
314 2277c5d7 2004-03-21 devnull return t;
315 2277c5d7 2004-03-21 devnull }
316 2277c5d7 2004-03-21 devnull
317 2277c5d7 2004-03-21 devnull static void
318 2277c5d7 2004-03-21 devnull _freefiles(File *f)
319 2277c5d7 2004-03-21 devnull {
320 2277c5d7 2004-03-21 devnull Filelist *fl, *flnext;
321 2277c5d7 2004-03-21 devnull
322 2277c5d7 2004-03-21 devnull for(fl=f->filelist; fl; fl=flnext){
323 2277c5d7 2004-03-21 devnull flnext = fl->link;
324 2277c5d7 2004-03-21 devnull _freefiles(fl->f);
325 2277c5d7 2004-03-21 devnull free(fl);
326 2277c5d7 2004-03-21 devnull }
327 2277c5d7 2004-03-21 devnull
328 2277c5d7 2004-03-21 devnull f->tree->destroy(f);
329 2277c5d7 2004-03-21 devnull freefile(f);
330 2277c5d7 2004-03-21 devnull }
331 2277c5d7 2004-03-21 devnull
332 2277c5d7 2004-03-21 devnull void
333 2277c5d7 2004-03-21 devnull freetree(Tree *t)
334 2277c5d7 2004-03-21 devnull {
335 2277c5d7 2004-03-21 devnull _freefiles(t->root);
336 2277c5d7 2004-03-21 devnull free(t);
337 2277c5d7 2004-03-21 devnull }
338 2277c5d7 2004-03-21 devnull
339 2277c5d7 2004-03-21 devnull struct Readdir {
340 2277c5d7 2004-03-21 devnull Filelist *fl;
341 2277c5d7 2004-03-21 devnull };
342 2277c5d7 2004-03-21 devnull
343 2277c5d7 2004-03-21 devnull Readdir*
344 2277c5d7 2004-03-21 devnull opendirfile(File *dir)
345 2277c5d7 2004-03-21 devnull {
346 2277c5d7 2004-03-21 devnull Readdir *r;
347 2277c5d7 2004-03-21 devnull
348 2277c5d7 2004-03-21 devnull rlock(&dir->rwlock);
349 2277c5d7 2004-03-21 devnull if((dir->dir.mode & DMDIR)==0){
350 2277c5d7 2004-03-21 devnull runlock(&dir->rwlock);
351 2277c5d7 2004-03-21 devnull return nil;
352 2277c5d7 2004-03-21 devnull }
353 2277c5d7 2004-03-21 devnull r = emalloc9p(sizeof(*r));
354 2277c5d7 2004-03-21 devnull
355 2277c5d7 2004-03-21 devnull /*
356 2277c5d7 2004-03-21 devnull * This reference won't go away while we're using it
357 2277c5d7 2004-03-21 devnull * since we are dir->rdir.
358 2277c5d7 2004-03-21 devnull */
359 2277c5d7 2004-03-21 devnull r->fl = dir->filelist;
360 2277c5d7 2004-03-21 devnull runlock(&dir->rwlock);
361 2277c5d7 2004-03-21 devnull return r;
362 2277c5d7 2004-03-21 devnull }
363 2277c5d7 2004-03-21 devnull
364 2277c5d7 2004-03-21 devnull long
365 2277c5d7 2004-03-21 devnull readdirfile(Readdir *r, uchar *buf, long n)
366 2277c5d7 2004-03-21 devnull {
367 2277c5d7 2004-03-21 devnull long x, m;
368 2277c5d7 2004-03-21 devnull Filelist *fl;
369 2277c5d7 2004-03-21 devnull
370 2277c5d7 2004-03-21 devnull for(fl=r->fl, m=0; fl && m+2<=n; fl=fl->link, m+=x){
371 2277c5d7 2004-03-21 devnull if(fl->f == nil)
372 2277c5d7 2004-03-21 devnull x = 0;
373 2277c5d7 2004-03-21 devnull else if((x=convD2M(&fl->f->dir, buf+m, n-m)) <= BIT16SZ)
374 2277c5d7 2004-03-21 devnull break;
375 2277c5d7 2004-03-21 devnull }
376 2277c5d7 2004-03-21 devnull r->fl = fl;
377 2277c5d7 2004-03-21 devnull return m;
378 2277c5d7 2004-03-21 devnull }
379 2277c5d7 2004-03-21 devnull
380 2277c5d7 2004-03-21 devnull void
381 2277c5d7 2004-03-21 devnull closedirfile(Readdir *r)
382 2277c5d7 2004-03-21 devnull {
383 2277c5d7 2004-03-21 devnull free(r);
384 2277c5d7 2004-03-21 devnull }