diff options
author | rsc <devnull@localhost> | 2005-01-04 21:22:40 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-01-04 21:22:40 +0000 |
commit | 46f79934b79ef526ed42bbe5a565e6b5d884d24a (patch) | |
tree | d1e663f7d3b2b328f03aeb34fdb3f4006aa97ec0 /src/lib9pclient/dirread.c | |
parent | 5ba841dffa1f6cda712ebcff27c55c9d0a672c67 (diff) | |
download | plan9port-46f79934b79ef526ed42bbe5a565e6b5d884d24a.tar.gz plan9port-46f79934b79ef526ed42bbe5a565e6b5d884d24a.tar.bz2 plan9port-46f79934b79ef526ed42bbe5a565e6b5d884d24a.zip |
lib9pclient is the new libfs
Diffstat (limited to 'src/lib9pclient/dirread.c')
-rw-r--r-- | src/lib9pclient/dirread.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/lib9pclient/dirread.c b/src/lib9pclient/dirread.c new file mode 100644 index 00000000..540cfc6b --- /dev/null +++ b/src/lib9pclient/dirread.c @@ -0,0 +1,99 @@ +/* Mostly copied from Plan 9's libc. */ + +#include <u.h> +#include <libc.h> +#include <fcall.h> +#include <9pclient.h> + +static long +dirpackage(uchar *buf, long ts, Dir **d) +{ + char *s; + long ss, i, n, nn, m; + + *d = nil; + if(ts <= 0) + return 0; + + /* + * first find number of all stats, check they look like stats, & size all associated strings + */ + ss = 0; + n = 0; + for(i = 0; i < ts; i += m){ + m = BIT16SZ + GBIT16(&buf[i]); + if(statcheck(&buf[i], m) < 0) + break; + ss += m; + n++; + } + + if(i != ts) + return -1; + + *d = malloc(n * sizeof(Dir) + ss); + if(*d == nil) + return -1; + + /* + * then convert all buffers + */ + s = (char*)*d + n * sizeof(Dir); + nn = 0; + for(i = 0; i < ts; i += m){ + m = BIT16SZ + GBIT16((uchar*)&buf[i]); + if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){ + free(*d); + *d = nil; + return -1; + } + nn++; + s += m; + } + + return nn; +} + +long +fsdirread(CFid *fid, Dir **d) +{ + uchar *buf; + long ts; + + buf = malloc(DIRMAX); + if(buf == nil) + return -1; + ts = fsread(fid, buf, DIRMAX); + if(ts >= 0) + ts = dirpackage(buf, ts, d); + free(buf); + return ts; +} + +long +fsdirreadall(CFid *fid, Dir **d) +{ + uchar *buf, *nbuf; + long n, ts; + + buf = nil; + ts = 0; + for(;;){ + nbuf = realloc(buf, ts+DIRMAX); + if(nbuf == nil){ + free(buf); + return -1; + } + buf = nbuf; + n = fsread(fid, buf+ts, DIRMAX); + if(n <= 0) + break; + ts += n; + } + if(ts >= 0) + ts = dirpackage(buf, ts, d); + free(buf); + if(ts == 0 && n < 0) + return -1; + return ts; +} |