Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include <libsec.h>
5 #include <thread.h>
7 enum
8 {
9 // XXX What to do here?
10 VtMaxLumpSize = 65535,
11 };
13 int chatty;
15 void
16 usage(void)
17 {
18 fprint(2, "usage: readfile [-v] [-h host] score\n");
19 threadexitsall("usage");
20 }
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;
36 quotefmtinstall();
37 fmtinstall('F', vtfcallfmt);
38 fmtinstall('V', vtscorefmt);
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
56 if(argc != 1)
57 usage();
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:...");
65 buf = vtmallocz(VtMaxLumpSize);
67 z = vtdial(host);
68 if(z == nil)
69 sysfatal("could not connect to server: %r");
71 if(vtconnect(z) < 0)
72 sysfatal("vtconnect: %r");
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);
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");
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;
113 threadexitsall(0);