]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/9sys/dirread.c
allow # netpath in dial string
[plan9front.git] / sys / src / libc / 9sys / dirread.c
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4
5 static
6 long
7 dirpackage(uchar *buf, long ts, Dir **d)
8 {
9         char *s;
10         long ss, i, n, nn, m;
11
12         *d = nil;
13         if(ts <= 0)
14                 return 0;
15
16         /*
17          * first find number of all stats, check they look like stats, & size all associated strings
18          */
19         ss = 0;
20         n = 0;
21         for(i = 0; i < ts; i += m){
22                 m = BIT16SZ + GBIT16(&buf[i]);
23                 if(statcheck(&buf[i], m) < 0)
24                         break;
25                 ss += m;
26                 n++;
27         }
28
29         if(i != ts)
30                 return -1;
31
32         *d = malloc(n * sizeof(Dir) + ss);
33         if(*d == nil)
34                 return -1;
35
36         /*
37          * then convert all buffers
38          */
39         s = (char*)*d + n * sizeof(Dir);
40         nn = 0;
41         for(i = 0; i < ts; i += m){
42                 m = BIT16SZ + GBIT16((uchar*)&buf[i]);
43                 if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
44                         free(*d);
45                         *d = nil;
46                         return -1;
47                 }
48                 nn++;
49                 s += m;
50         }
51
52         return nn;
53 }
54
55 long
56 dirread(int fd, Dir **d)
57 {
58         uchar *buf;
59         long ts;
60
61         buf = malloc(DIRMAX);
62         if(buf == nil)
63                 return -1;
64         ts = read(fd, buf, DIRMAX);
65         if(ts >= 0)
66                 ts = dirpackage(buf, ts, d);
67         free(buf);
68         return ts;
69 }
70
71 long
72 dirreadall(int fd, Dir **d)
73 {
74         uchar *buf, *nbuf;
75         long n, ts;
76
77         buf = nil;
78         ts = 0;
79         for(;;){
80                 nbuf = realloc(buf, ts+DIRMAX);
81                 if(nbuf == nil){
82                         free(buf);
83                         return -1;
84                 }
85                 buf = nbuf;
86                 n = read(fd, buf+ts, DIRMAX);
87                 if(n <= 0)
88                         break;
89                 ts += n;
90         }
91         if(ts >= 0)
92                 ts = dirpackage(buf, ts, d);
93         free(buf);
94         if(ts == 0 && n < 0)
95                 return -1;
96         return ts;
97 }