plan9port

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

ro.c (1882B)


      1 /* Copyright (c) 2004 Russ Cox */
      2 #include <u.h>
      3 #include <libc.h>
      4 #include <venti.h>
      5 #include <thread.h>
      6 #include <libsec.h>
      7 
      8 #ifndef _UNISTD_H_
      9 #pragma varargck type "F" VtFcall*
     10 #pragma varargck type "T" void
     11 #endif
     12 
     13 VtConn *z;
     14 int verbose;
     15 
     16 enum
     17 {
     18 	STACK = 8192
     19 };
     20 
     21 void
     22 usage(void)
     23 {
     24 	fprint(2, "usage: venti/ro [-v] [-a address] [-h address]\n");
     25 	threadexitsall("usage");
     26 }
     27 
     28 void
     29 readthread(void *v)
     30 {
     31 	char err[ERRMAX];
     32 	VtReq *r;
     33 	uchar *buf;
     34 	int n;
     35 
     36 	r = v;
     37 	buf = vtmalloc(r->tx.count);
     38 	if((n=vtread(z, r->tx.score, r->tx.blocktype, buf, r->tx.count)) < 0){
     39 		r->rx.msgtype = VtRerror;
     40 		rerrstr(err, sizeof err);
     41 		r->rx.error = vtstrdup(err);
     42 		free(buf);
     43 	}else{
     44 		r->rx.data = packetforeign(buf, n, free, buf);
     45 	}
     46 	if(verbose)
     47 		fprint(2, "-> %F\n", &r->rx);
     48 	vtrespond(r);
     49 }
     50 
     51 void
     52 threadmain(int argc, char **argv)
     53 {
     54 	VtReq *r;
     55 	VtSrv *srv;
     56 	char *address, *ventiaddress;
     57 
     58 	fmtinstall('F', vtfcallfmt);
     59 	fmtinstall('V', vtscorefmt);
     60 
     61 	address = "tcp!*!venti";
     62 	ventiaddress = nil;
     63 
     64 	ARGBEGIN{
     65 	case 'v':
     66 		verbose++;
     67 		break;
     68 	case 'a':
     69 		address = EARGF(usage());
     70 		break;
     71 	case 'h':
     72 		ventiaddress = EARGF(usage());
     73 		break;
     74 	default:
     75 		usage();
     76 	}ARGEND
     77 
     78 	if((z = vtdial(ventiaddress)) == nil)
     79 		sysfatal("vtdial %s: %r", ventiaddress);
     80 	if(vtconnect(z) < 0)
     81 		sysfatal("vtconnect: %r");
     82 
     83 	srv = vtlisten(address);
     84 	if(srv == nil)
     85 		sysfatal("vtlisten %s: %r", address);
     86 
     87 	while((r = vtgetreq(srv)) != nil){
     88 		r->rx.msgtype = r->tx.msgtype+1;
     89 		if(verbose)
     90 			fprint(2, "<- %F\n", &r->tx);
     91 		switch(r->tx.msgtype){
     92 		case VtTping:
     93 			break;
     94 		case VtTgoodbye:
     95 			break;
     96 		case VtTread:
     97 			threadcreate(readthread, r, 16384);
     98 			continue;
     99 		case VtTwrite:
    100 			r->rx.error = vtstrdup("read-only server");
    101 			r->rx.msgtype = VtRerror;
    102 			break;
    103 		case VtTsync:
    104 			break;
    105 		}
    106 		if(verbose)
    107 			fprint(2, "-> %F\n", &r->rx);
    108 		vtrespond(r);
    109 	}
    110 	threadexitsall(nil);
    111 }