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 long9 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 strings20 */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 buffers40 */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 long58 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 long74 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 }