1 46f79934 2005-01-04 devnull /* Mostly copied from Plan 9's libc. */
3 46f79934 2005-01-04 devnull #include <u.h>
4 46f79934 2005-01-04 devnull #include <libc.h>
5 46f79934 2005-01-04 devnull #include <fcall.h>
6 46f79934 2005-01-04 devnull #include <9pclient.h>
7 382ae73f 2008-07-04 rsc #include "fsimpl.h"
9 46f79934 2005-01-04 devnull static long
10 382ae73f 2008-07-04 rsc dirpackage(uchar *buf, long ts, Dir **d, int dotu)
13 46f79934 2005-01-04 devnull long ss, i, n, nn, m;
15 46f79934 2005-01-04 devnull *d = nil;
16 46f79934 2005-01-04 devnull if(ts <= 0)
17 46f79934 2005-01-04 devnull return 0;
20 46f79934 2005-01-04 devnull * first find number of all stats, check they look like stats, & size all associated strings
24 46f79934 2005-01-04 devnull for(i = 0; i < ts; i += m){
25 46f79934 2005-01-04 devnull m = BIT16SZ + GBIT16(&buf[i]);
26 382ae73f 2008-07-04 rsc if(statchecku(&buf[i], m, dotu) < 0)
32 46f79934 2005-01-04 devnull if(i != ts)
33 46f79934 2005-01-04 devnull return -1;
35 46f79934 2005-01-04 devnull *d = malloc(n * sizeof(Dir) + ss);
36 46f79934 2005-01-04 devnull if(*d == nil)
37 46f79934 2005-01-04 devnull return -1;
40 46f79934 2005-01-04 devnull * then convert all buffers
42 46f79934 2005-01-04 devnull s = (char*)*d + n * sizeof(Dir);
44 46f79934 2005-01-04 devnull for(i = 0; i < ts; i += m){
45 46f79934 2005-01-04 devnull m = BIT16SZ + GBIT16((uchar*)&buf[i]);
46 382ae73f 2008-07-04 rsc if(nn >= n || convM2Du(&buf[i], m, *d + nn, s, dotu) != m){
47 46f79934 2005-01-04 devnull free(*d);
48 46f79934 2005-01-04 devnull *d = nil;
49 46f79934 2005-01-04 devnull return -1;
55 46f79934 2005-01-04 devnull return nn;
59 46f79934 2005-01-04 devnull fsdirread(CFid *fid, Dir **d)
61 46f79934 2005-01-04 devnull uchar *buf;
64 46f79934 2005-01-04 devnull buf = malloc(DIRMAX);
65 46f79934 2005-01-04 devnull if(buf == nil)
66 46f79934 2005-01-04 devnull return -1;
67 46f79934 2005-01-04 devnull ts = fsread(fid, buf, DIRMAX);
68 46f79934 2005-01-04 devnull if(ts >= 0)
69 382ae73f 2008-07-04 rsc ts = dirpackage(buf, ts, d, fid->fs->dotu);
70 46f79934 2005-01-04 devnull free(buf);
71 46f79934 2005-01-04 devnull return ts;
75 46f79934 2005-01-04 devnull fsdirreadall(CFid *fid, Dir **d)
77 46f79934 2005-01-04 devnull uchar *buf, *nbuf;
78 46f79934 2005-01-04 devnull long n, ts;
80 46f79934 2005-01-04 devnull buf = nil;
83 46f79934 2005-01-04 devnull nbuf = realloc(buf, ts+DIRMAX);
84 46f79934 2005-01-04 devnull if(nbuf == nil){
85 46f79934 2005-01-04 devnull free(buf);
86 46f79934 2005-01-04 devnull return -1;
88 46f79934 2005-01-04 devnull buf = nbuf;
89 46f79934 2005-01-04 devnull n = fsread(fid, buf+ts, DIRMAX);
90 46f79934 2005-01-04 devnull if(n <= 0)
94 f53117fb 2006-06-26 devnull if(ts >= 0){
95 382ae73f 2008-07-04 rsc ts = dirpackage(buf, ts, d, fid->fs->dotu);
96 f53117fb 2006-06-26 devnull if(ts < 0)
97 382ae73f 2008-07-04 rsc werrstr("malformed directory contents [dotu=%d]", fid->fs->dotu);
99 46f79934 2005-01-04 devnull free(buf);
100 46f79934 2005-01-04 devnull if(ts == 0 && n < 0)
101 46f79934 2005-01-04 devnull return -1;
102 46f79934 2005-01-04 devnull return ts;