aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-06-14 10:57:45 -0400
committerRuss Cox <rsc@swtch.com>2008-06-14 10:57:45 -0400
commit01cea2ecb8c0b101a22e7883d87fbf1d28a03043 (patch)
tree5b29a080c9f0ede95edba0c012b9d8216bb56061
parentef6606c7a7f22ae6cca150c6433748102640e130 (diff)
downloadplan9port-01cea2ecb8c0b101a22e7883d87fbf1d28a03043.tar.gz
plan9port-01cea2ecb8c0b101a22e7883d87fbf1d28a03043.tar.bz2
plan9port-01cea2ecb8c0b101a22e7883d87fbf1d28a03043.zip
venti: add demo programs readfile.c and writefile.c
-rw-r--r--src/cmd/venti/readfile.c108
-rw-r--r--src/cmd/venti/writefile.c106
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);
+}
+