diff options
Diffstat (limited to 'src/cmd')
-rw-r--r-- | src/cmd/venti/readfile.c | 108 | ||||
-rw-r--r-- | src/cmd/venti/writefile.c | 106 |
2 files changed, 214 insertions, 0 deletions
diff --git a/src/cmd/venti/readfile.c b/src/cmd/venti/readfile.c new file mode 100644 index 00000000..2883350a --- /dev/null +++ b/src/cmd/venti/readfile.c @@ -0,0 +1,108 @@ +#include <u.h> +#include <libc.h> +#include <venti.h> +#include <libsec.h> +#include <thread.h> + +int chatty; + +void +usage(void) +{ + fprint(2, "usage: readfile [-v] [-h host] score\n"); + threadexitsall("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + int n; + uchar score[VtScoreSize]; + uchar *buf; + char *host, *type; + vlong off; + VtEntry e; + VtRoot root; + VtCache *c; + VtConn *z; + VtFile *f; + + quotefmtinstall(); + fmtinstall('F', vtfcallfmt); + fmtinstall('V', vtscorefmt); + + host = nil; + ARGBEGIN{ + case 'V': + chattyventi++; + break; + case 'h': + host = EARGF(usage()); + break; + case 'v': + chatty++; + break; + default: + usage(); + break; + }ARGEND + + if(argc != 1) + usage(); + + type = nil; + if(vtparsescore(argv[0], &type, score) < 0) + sysfatal("could not parse score '%s': %r", argv[0]); + if(type == nil || strcmp(type, "file") != 0) + sysfatal("bad score - not file:..."); + + buf = vtmallocz(VtMaxLumpSize); + + z = vtdial(host); + if(z == nil) + sysfatal("could not connect to server: %r"); + + if(vtconnect(z) < 0) + sysfatal("vtconnect: %r"); + + // root block ... + n = vtread(z, score, VtRootType, buf, VtMaxLumpSize); + if(n < 0) + sysfatal("could not read root %V: %r", score); + if(n != VtRootSize) + sysfatal("root block %V is wrong size %d != %d", score, n, VtRootSize); + if(vtrootunpack(&root, buf) < 0) + sysfatal("unpacking root block %V: %r", score); + if(strcmp(root.type, "file") != 0) + sysfatal("bad root type %q (not 'file')", root.type); + if(chatty) + fprint(2, "%V: %q %q %V %d %V\n", + score, root.name, root.type, + root.score, root.blocksize, root.prev); + + // ... points at entry block + n = vtread(z, root.score, VtDirType, buf, VtMaxLumpSize); + if(n < 0) + sysfatal("could not read entry %V: %r", root.score); + if(n != VtEntrySize) + sysfatal("dir block %V is wrong size %d != %d", root.score, n, VtEntrySize); + if(vtentryunpack(&e, buf, 0) < 0) + sysfatal("unpacking dir block %V: %r", root.score); + if((e.type&VtTypeBaseMask) != VtDataType) + sysfatal("not a single file"); + + // open and read file + c = vtcachealloc(z, root.blocksize, 32); + if(c == nil) + sysfatal("vtcachealloc: %r"); + f = vtfileopenroot(c, &e); + if(f == nil) + sysfatal("vtfileopenroot: %r"); + off = 0; + vtfilelock(f, VtOREAD); + while((n = vtfileread(f, buf, VtMaxLumpSize, off)) > 0){ + write(1, buf, n); + off += n; + } + threadexitsall(0); +} diff --git a/src/cmd/venti/writefile.c b/src/cmd/venti/writefile.c new file mode 100644 index 00000000..19a26fa6 --- /dev/null +++ b/src/cmd/venti/writefile.c @@ -0,0 +1,106 @@ +#include <u.h> +#include <libc.h> +#include <venti.h> +#include <libsec.h> +#include <thread.h> + +enum +{ + Blocksize = 8192 +}; + +int chatty; + +void +usage(void) +{ + fprint(2, "usage: writefile [-v] [-h host] < data\n"); + threadexitsall("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + int n; + uchar score[VtScoreSize]; + uchar *buf; + char *host; + vlong off; + VtEntry e; + VtRoot root; + VtCache *c; + VtConn *z; + VtFile *f; + + quotefmtinstall(); + fmtinstall('F', vtfcallfmt); + fmtinstall('V', vtscorefmt); + + host = nil; + ARGBEGIN{ + case 'V': + chattyventi++; + break; + case 'h': + host = EARGF(usage()); + break; + case 'v': + chatty++; + break; + default: + usage(); + break; + }ARGEND + + if(argc != 0) + usage(); + + buf = vtmallocz(Blocksize); + + z = vtdial(host); + if(z == nil) + sysfatal("could not connect to server: %r"); + + if(vtconnect(z) < 0) + sysfatal("vtconnect: %r"); + + // write file + c = vtcachealloc(z, Blocksize, 32); + if(c == nil) + sysfatal("vtcachealloc: %r"); + f = vtfilecreateroot(c, Blocksize, Blocksize, VtDataType); + if(f == nil) + sysfatal("vtfilecreateroot: %r"); + off = 0; + vtfilelock(f, VtOWRITE); + while((n = read(0, buf, Blocksize)) > 0){ + if(vtfilewrite(f, buf, n, off) != n) + sysfatal("vtfilewrite: %r"); + off += n; + if(vtfileflushbefore(f, off) < 0) + sysfatal("vtfileflushbefore: %r"); + } + if(vtfileflush(f) < 0) + sysfatal("vtfileflush: %r"); + if(vtfilegetentry(f, &e) < 0) + sysfatal("vtfilegetentry: %r"); + vtfileunlock(f); + + // write directory entry + memset(&root, 0, sizeof root); + vtentrypack(&e, buf, 0); + if(vtwrite(z, root.score, VtDirType, buf, VtEntrySize) < 0) + sysfatal("vtwrite dir: %r"); + + // write root + strcpy(root.name, "data"); + strcpy(root.type, "file"); + root.blocksize = Blocksize; + vtrootpack(&root, buf); + if(vtwrite(z, score, VtRootType, buf, VtRootSize) < 0) + sysfatal("vtwrite root: %r"); + + print("file:%V\n", score); + threadexitsall(0); +} + |