URI:
       treadfile.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       treadfile.c (2394B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <venti.h>
            4 #include <libsec.h>
            5 #include <thread.h>
            6 
            7 enum
            8 {
            9         // XXX What to do here?
           10         VtMaxLumpSize = 65535,
           11 };
           12 
           13 int chatty;
           14 
           15 void
           16 usage(void)
           17 {
           18         fprint(2, "usage: readfile [-v] [-h host] score\n");
           19         threadexitsall("usage");
           20 }
           21 
           22 void
           23 threadmain(int argc, char *argv[])
           24 {
           25         int n;
           26         uchar score[VtScoreSize];
           27         uchar *buf;
           28         char *host, *type;
           29         vlong off;
           30         VtEntry e;
           31         VtRoot root;
           32         VtCache *c;
           33         VtConn *z;
           34         VtFile *f;
           35 
           36         quotefmtinstall();
           37         fmtinstall('F', vtfcallfmt);
           38         fmtinstall('V', vtscorefmt);
           39 
           40         host = nil;
           41         ARGBEGIN{
           42         case 'V':
           43                 chattyventi++;
           44                 break;
           45         case 'h':
           46                 host = EARGF(usage());
           47                 break;
           48         case 'v':
           49                 chatty++;
           50                 break;
           51         default:
           52                 usage();
           53                 break;
           54         }ARGEND
           55 
           56         if(argc != 1)
           57                 usage();
           58 
           59         type = nil;
           60         if(vtparsescore(argv[0], &type, score) < 0)
           61                 sysfatal("could not parse score '%s': %r", argv[0]);
           62         if(type == nil || strcmp(type, "file") != 0)
           63                 sysfatal("bad score - not file:...");
           64 
           65         buf = vtmallocz(VtMaxLumpSize);
           66 
           67         z = vtdial(host);
           68         if(z == nil)
           69                 sysfatal("could not connect to server: %r");
           70 
           71         if(vtconnect(z) < 0)
           72                 sysfatal("vtconnect: %r");
           73 
           74         // root block ...
           75         n = vtread(z, score, VtRootType, buf, VtMaxLumpSize);
           76         if(n < 0)
           77                 sysfatal("could not read root %V: %r", score);
           78         if(n != VtRootSize)
           79                 sysfatal("root block %V is wrong size %d != %d", score, n, VtRootSize);
           80         if(vtrootunpack(&root, buf) < 0)
           81                 sysfatal("unpacking root block %V: %r", score);
           82         if(strcmp(root.type, "file") != 0)
           83                 sysfatal("bad root type %q (not 'file')", root.type);
           84         if(chatty)
           85                 fprint(2, "%V: %q %q %V %d %V\n",
           86                         score, root.name, root.type,
           87                         root.score, root.blocksize, root.prev);
           88 
           89         // ... points at entry block
           90         n = vtread(z, root.score, VtDirType, buf, VtMaxLumpSize);
           91         if(n < 0)
           92                 sysfatal("could not read entry %V: %r", root.score);
           93         if(n != VtEntrySize)
           94                 sysfatal("dir block %V is wrong size %d != %d", root.score, n, VtEntrySize);
           95         if(vtentryunpack(&e, buf, 0) < 0)
           96                 sysfatal("unpacking dir block %V: %r", root.score);
           97         if((e.type&VtTypeBaseMask) != VtDataType)
           98                 sysfatal("not a single file");
           99 
          100         // open and read file
          101         c = vtcachealloc(z, root.blocksize*32);
          102         if(c == nil)
          103                 sysfatal("vtcachealloc: %r");
          104         f = vtfileopenroot(c, &e);
          105         if(f == nil)
          106                 sysfatal("vtfileopenroot: %r");
          107         off = 0;
          108         vtfilelock(f, VtOREAD);
          109         while((n = vtfileread(f, buf, VtMaxLumpSize, off)) > 0){
          110                 write(1, buf, n);
          111                 off += n;
          112         }
          113         threadexitsall(0);
          114 }