/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #define PORTABLE_SYSCALLS #include #include #include <9P2000.h> static int32_t dirpackage(uint8_t *buf, int32_t ts, Dir **d) { char *s; int32_t 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 = jehanne_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((uint8_t*)&buf[i]); if(nn >= n || jehanne_convM2D(&buf[i], m, *d + nn, s) != m){ jehanne_free(*d); *d = nil; return -1; } nn++; s += m; } return nn; } int32_t jehanne_dirread(int fd, Dir **d) { uint8_t *buf; int32_t ts; buf = jehanne_malloc(DIRMAX); if(buf == nil) return -1; ts = jehanne_read(fd, buf, DIRMAX); if(ts >= 0) ts = dirpackage(buf, ts, d); jehanne_free(buf); return ts; } int32_t jehanne_dirreadall(int fd, Dir **d) { uint8_t *buf, *nbuf; int32_t n, ts; buf = nil; ts = 0; for(;;){ nbuf = jehanne_realloc(buf, ts+DIRMAX); if(nbuf == nil){ jehanne_free(buf); return -1; } buf = nbuf; n = jehanne_read(fd, buf+ts, DIRMAX); if(n <= 0) break; ts += n; } if(ts >= 0) ts = dirpackage(buf, ts, d); jehanne_free(buf); if(ts == 0 && n < 0) return -1; return ts; }