tdirread.c - plan9port - [fork] Plan 9 from user space
(HTM) git clone git://src.adamsgaard.dk/plan9port
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
tdirread.c (1545B)
---
1 /* Mostly copied from Plan 9's libc. */
2
3 #include <u.h>
4 #include <libc.h>
5 #include <fcall.h>
6 #include <9pclient.h>
7 #include "fsimpl.h"
8
9 static long
10 dirpackage(uchar *buf, long ts, Dir **d)
11 {
12 char *s;
13 long ss, i, n, nn, m;
14
15 *d = nil;
16 if(ts <= 0)
17 return 0;
18
19 /*
20 * first find number of all stats, check they look like stats, & size all associated strings
21 */
22 ss = 0;
23 n = 0;
24 for(i = 0; i < ts; i += m){
25 m = BIT16SZ + GBIT16(&buf[i]);
26 if(statcheck(&buf[i], m) < 0)
27 break;
28 ss += m;
29 n++;
30 }
31
32 if(i != ts)
33 return -1;
34
35 *d = malloc(n * sizeof(Dir) + ss);
36 if(*d == nil)
37 return -1;
38
39 /*
40 * then convert all buffers
41 */
42 s = (char*)*d + n * sizeof(Dir);
43 nn = 0;
44 for(i = 0; i < ts; i += m){
45 m = BIT16SZ + GBIT16((uchar*)&buf[i]);
46 if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
47 free(*d);
48 *d = nil;
49 return -1;
50 }
51 nn++;
52 s += m;
53 }
54
55 return nn;
56 }
57
58 long
59 fsdirread(CFid *fid, Dir **d)
60 {
61 uchar *buf;
62 long ts;
63
64 buf = malloc(DIRMAX);
65 if(buf == nil)
66 return -1;
67 ts = fsread(fid, buf, DIRMAX);
68 if(ts >= 0)
69 ts = dirpackage(buf, ts, d);
70 free(buf);
71 return ts;
72 }
73
74 long
75 fsdirreadall(CFid *fid, Dir **d)
76 {
77 uchar *buf, *nbuf;
78 long n, ts;
79
80 buf = nil;
81 ts = 0;
82 for(;;){
83 nbuf = realloc(buf, ts+DIRMAX);
84 if(nbuf == nil){
85 free(buf);
86 return -1;
87 }
88 buf = nbuf;
89 n = fsread(fid, buf+ts, DIRMAX);
90 if(n <= 0)
91 break;
92 ts += n;
93 }
94 if(ts >= 0){
95 ts = dirpackage(buf, ts, d);
96 if(ts < 0)
97 werrstr("malformed directory contents");
98 }
99 free(buf);
100 if(ts == 0 && n < 0)
101 return -1;
102 return ts;
103 }