tdirread.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tdirread.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 }