Blob
1 /* Mostly copied from Plan 9's libc. */3 #include <u.h>4 #include <libc.h>5 #include <fcall.h>6 #include <fs.h>8 static9 long10 dirpackage(uchar *buf, long ts, Dir **d)11 {12 char *s;13 long ss, i, n, nn, m;15 *d = nil;16 if(ts <= 0)17 return 0;19 /*20 * first find number of all stats, check they look like stats, & size all associated strings21 */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 }32 if(i != ts)33 return -1;35 *d = malloc(n * sizeof(Dir) + ss);36 if(*d == nil)37 return -1;39 /*40 * then convert all buffers41 */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 }55 return nn;56 }58 long59 fsdirread(Fid *fid, Dir **d)60 {61 uchar *buf;62 long ts;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 }74 long75 fsdirreadall(Fid *fid, Dir **d)76 {77 uchar *buf, *nbuf;78 long n, ts;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 free(buf);97 if(ts == 0 && n < 0)98 return -1;99 return ts;100 }