readfile.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 }