112 lines · 1.8 KB · C
RawDownload
/* Copyright (c) 2004 Russ Cox */#include <u.h>#include <libc.h>#include <venti.h>#include <thread.h>#include <libsec.h> #ifndef _UNISTD_H_#pragma varargck type "F" VtFcall*#pragma varargck type "T" void#endif VtConn *z;int verbose; enum{	STACK = 8192}; voidusage(void){	fprint(2, "usage: venti/ro [-v] [-a address] [-h address]\n");	threadexitsall("usage");} voidreadthread(void *v){	char err[ERRMAX];	VtReq *r;	uchar *buf;	int n;		r = v;	buf = vtmalloc(r->tx.count);	if((n=vtread(z, r->tx.score, r->tx.blocktype, buf, r->tx.count)) < 0){		r->rx.msgtype = VtRerror;		rerrstr(err, sizeof err);		r->rx.error = vtstrdup(err);		free(buf);	}else{		r->rx.data = packetforeign(buf, n, free, buf);	}	if(verbose)		fprint(2, "-> %F\n", &r->rx);	vtrespond(r);} voidthreadmain(int argc, char **argv){	VtReq *r;	VtSrv *srv;	char *address, *ventiaddress; 	fmtinstall('F', vtfcallfmt);	fmtinstall('V', vtscorefmt);		address = "tcp!*!venti";	ventiaddress = nil;		ARGBEGIN{	case 'v':		verbose++;		break;	case 'a':		address = EARGF(usage());		break;	case 'h':		ventiaddress = EARGF(usage());		break;	default:		usage();	}ARGEND 	if((z = vtdial(ventiaddress)) == nil)		sysfatal("vtdial %s: %r", ventiaddress);	if(vtconnect(z) < 0)		sysfatal("vtconnect: %r"); 	srv = vtlisten(address);	if(srv == nil)		sysfatal("vtlisten %s: %r", address); 	while((r = vtgetreq(srv)) != nil){		r->rx.msgtype = r->tx.msgtype+1;		if(verbose)			fprint(2, "<- %F\n", &r->tx);		switch(r->tx.msgtype){		case VtTping:			break;		case VtTgoodbye:			break;		case VtTread:			threadcreate(readthread, r, 16384);			continue;		case VtTwrite:			r->rx.error = vtstrdup("read-only server");			r->rx.msgtype = VtRerror;			break;		case VtTsync:			break;		}		if(verbose)			fprint(2, "-> %F\n", &r->rx);		vtrespond(r);	}	threadexitsall(nil);}