#include #include #include #include #include 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); }