henesyinit from p9fd787fda5 years agoHistory
203 lines · 3.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <ip.h>#include <plumb.h>#include <thread.h>#include <fcall.h>#include <9p.h>#include <mp.h>#include <libsec.h>#include "dat.h"#include "fns.h" static int tlsdial(char*, char*, char*, int*, int); static longt(Ioproc *io, void (*op)(Ioproc*), int n, ...){	int i, ret;	va_list arg; 	assert(!io->inuse);	io->inuse = 1;	io->op = op;	va_start(arg, n);	for(i=0; i<n; i++)		io->arg[i] = va_arg(arg, long);	sendp(io->c, io);	recvp(io->c);	ret = io->ret;	if(ret < 0)		errstr(io->err, sizeof io->err);	io->inuse = 0;	return ret;} static voidt2(Ioproc *io, int ret){	io->ret = ret;	if(ret < 0)		rerrstr(io->err, sizeof io->err);	sendp(io->c, io);} static void ioread2(Ioproc*);static longioread(Ioproc *io, int fd, void *a, long n){	return t(io, ioread2, 3, fd, a, n);}static voidioread2(Ioproc *io){	t2(io, read(io->arg[0], (void*)io->arg[1], io->arg[2]));} static void iowrite2(Ioproc*);static longiowrite(Ioproc *io, int fd, void *a, long n){	return t(io, iowrite2, 3, fd, a, n);}static voidiowrite2(Ioproc *io){	t2(io, write(io->arg[0], (void*)io->arg[1], io->arg[2]));} static void ioclose2(Ioproc*);static intioclose(Ioproc *io, int fd){	return t(io, ioclose2, 1, fd);}static voidioclose2(Ioproc *io){	t2(io, close(io->arg[0]));} static void iodial2(Ioproc*);static intiodial(Ioproc *io, char *a, char *b, char *c, int *d, int e){	return t(io, iodial2, 5, a, b, c, d, e);}static voidiodial2(Ioproc *io){	t2(io, tlsdial((char*)io->arg[0], (char*)io->arg[1], (char*)io->arg[2], (int*)io->arg[3], io->arg[4]));} static void ioopen2(Ioproc*);static intioopen(Ioproc *io, char *path, int mode){	return t(io, ioopen2, 2, path, mode);}static voidioopen2(Ioproc *io){	t2(io, open((char*)io->arg[0], io->arg[1]));} static intioprint(Ioproc *io, int fd, char *fmt, ...){	char buf[1024];	va_list arg; 	va_start(arg, fmt);	vseprint(buf, buf+sizeof buf, fmt, arg);	va_end(arg);	return iowrite(io, fd, buf, strlen(buf));} static voidiointerrupt(Ioproc *io){	if(!io->inuse)		return;	postnote(PNPROC, io->pid, "interrupt");} static voidxioproc(void *a){	Ioproc *io; 	io = a;	io->pid = getpid();	sendp(io->c, nil);	while(recvp(io->c) == io)		io->op(io);	chanfree(io->c);	free(io);} static inttlsdial(char *a, char *b, char *c, int *d, int usetls){	int fd, tfd;	TLSconn conn; 	fd = dial(a, b, c, d);	if(fd < 0)		return -1;	if(usetls == 0)		return fd;		memset(&conn, 0, sizeof conn);	tfd = tlsClient(fd, &conn);	if(tfd < 0){		print("tls %r\n");		close(fd);		return -1;	}	/* BUG: check cert here? */	if(conn.cert)		free(conn.cert);	close(fd);	return tfd;} Ioproc iofns ={	ioread,	iowrite,	iodial,	ioclose,	ioopen,	ioprint,	iointerrupt,}; Ioproc *iofree; Ioproc*ioproc(void){	Ioproc *io; 	if((io = iofree) != nil){		iofree = io->next;		return io;	}	io = emalloc(sizeof(*io));	*io = iofns;	io->c = chancreate(sizeof(void*), 0);	if(proccreate(xioproc, io, STACK) < 0)		sysfatal("proccreate: %r");	recvp(io->c);	return io;} voidcloseioproc(Ioproc *io){	io->next = iofree;	iofree = io;}