Blob


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