plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

dirread.c (1545B)


      1 /* Mostly copied from Plan 9's libc. */
      2 
      3 #include <u.h>
      4 #include <libc.h>
      5 #include <fcall.h>
      6 #include <9pclient.h>
      7 #include "fsimpl.h"
      8 
      9 static long
     10 dirpackage(uchar *buf, long ts, Dir **d)
     11 {
     12 	char *s;
     13 	long ss, i, n, nn, m;
     14 
     15 	*d = nil;
     16 	if(ts <= 0)
     17 		return 0;
     18 
     19 	/*
     20 	 * first find number of all stats, check they look like stats, & size all associated strings
     21 	 */
     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 	}
     31 
     32 	if(i != ts)
     33 		return -1;
     34 
     35 	*d = malloc(n * sizeof(Dir) + ss);
     36 	if(*d == nil)
     37 		return -1;
     38 
     39 	/*
     40 	 * then convert all buffers
     41 	 */
     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 	}
     54 
     55 	return nn;
     56 }
     57 
     58 long
     59 fsdirread(CFid *fid, Dir **d)
     60 {
     61 	uchar *buf;
     62 	long ts;
     63 
     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 }
     73 
     74 long
     75 fsdirreadall(CFid *fid, Dir **d)
     76 {
     77 	uchar *buf, *nbuf;
     78 	long n, ts;
     79 
     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 		if(ts < 0)
     97 			werrstr("malformed directory contents");
     98 	}
     99 	free(buf);
    100 	if(ts == 0 && n < 0)
    101 		return -1;
    102 	return ts;
    103 }