plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

readfile.c (2394B)


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