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>7 #include "fsimpl.h"9 static long10 dirpackage(uchar *buf, long ts, Dir **d, int dotu)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(statchecku(&buf[i], m, dotu) < 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 || convM2Du(&buf[i], m, *d + nn, s, dotu) != m){47 free(*d);48 *d = nil;49 return -1;50 }51 nn++;52 s += m;53 }55 return nn;56 }58 long59 fsdirread(CFid *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, fid->fs->dotu);70 free(buf);71 return ts;72 }74 long75 fsdirreadall(CFid *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, fid->fs->dotu);96 if(ts < 0)97 werrstr("malformed directory contents [dotu=%d]", fid->fs->dotu);98 }99 free(buf);100 if(ts == 0 && n < 0)101 return -1;102 return ts;103 }