Blob


1 /* Mostly copied from Plan 9's libc. */
3 #include <u.h>
4 #include <libc.h>
5 #include <fcall.h>
6 #include <9pclient.h>
8 static long
9 dirpackage(uchar *buf, long ts, Dir **d)
10 {
11 char *s;
12 long ss, i, n, nn, m;
14 *d = nil;
15 if(ts <= 0)
16 return 0;
18 /*
19 * first find number of all stats, check they look like stats, & size all associated strings
20 */
21 ss = 0;
22 n = 0;
23 for(i = 0; i < ts; i += m){
24 m = BIT16SZ + GBIT16(&buf[i]);
25 if(statcheck(&buf[i], m) < 0)
26 break;
27 ss += m;
28 n++;
29 }
31 if(i != ts)
32 return -1;
34 *d = malloc(n * sizeof(Dir) + ss);
35 if(*d == nil)
36 return -1;
38 /*
39 * then convert all buffers
40 */
41 s = (char*)*d + n * sizeof(Dir);
42 nn = 0;
43 for(i = 0; i < ts; i += m){
44 m = BIT16SZ + GBIT16((uchar*)&buf[i]);
45 if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
46 free(*d);
47 *d = nil;
48 return -1;
49 }
50 nn++;
51 s += m;
52 }
54 return nn;
55 }
57 long
58 fsdirread(CFid *fid, Dir **d)
59 {
60 uchar *buf;
61 long ts;
63 buf = malloc(DIRMAX);
64 if(buf == nil)
65 return -1;
66 ts = fsread(fid, buf, DIRMAX);
67 if(ts >= 0)
68 ts = dirpackage(buf, ts, d);
69 free(buf);
70 return ts;
71 }
73 long
74 fsdirreadall(CFid *fid, Dir **d)
75 {
76 uchar *buf, *nbuf;
77 long n, ts;
79 buf = nil;
80 ts = 0;
81 for(;;){
82 nbuf = realloc(buf, ts+DIRMAX);
83 if(nbuf == nil){
84 free(buf);
85 return -1;
86 }
87 buf = nbuf;
88 n = fsread(fid, buf+ts, DIRMAX);
89 if(n <= 0)
90 break;
91 ts += n;
92 }
93 if(ts >= 0)
94 ts = dirpackage(buf, ts, d);
95 free(buf);
96 if(ts == 0 && n < 0)
97 return -1;
98 return ts;
99 }