xref: /plan9/sys/src/cmd/webfs/io.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include <u.h>
2*9a747e4fSDavid du Colombier #include <libc.h>
3*9a747e4fSDavid du Colombier #include <bio.h>
4*9a747e4fSDavid du Colombier #include <ip.h>
5*9a747e4fSDavid du Colombier #include <plumb.h>
6*9a747e4fSDavid du Colombier #include <thread.h>
7*9a747e4fSDavid du Colombier #include <fcall.h>
8*9a747e4fSDavid du Colombier #include <9p.h>
9*9a747e4fSDavid du Colombier #include <mp.h>
10*9a747e4fSDavid du Colombier #include <libsec.h>
11*9a747e4fSDavid du Colombier #include "dat.h"
12*9a747e4fSDavid du Colombier #include "fns.h"
13*9a747e4fSDavid du Colombier 
14*9a747e4fSDavid du Colombier static int tlsdial(char*, char*, char*, int*, int);
15*9a747e4fSDavid du Colombier 
16*9a747e4fSDavid du Colombier static long
17*9a747e4fSDavid du Colombier t(Ioproc *io, void (*op)(Ioproc*), int n, ...)
18*9a747e4fSDavid du Colombier {
19*9a747e4fSDavid du Colombier 	int i, ret;
20*9a747e4fSDavid du Colombier 	va_list arg;
21*9a747e4fSDavid du Colombier 
22*9a747e4fSDavid du Colombier 	assert(!io->inuse);
23*9a747e4fSDavid du Colombier 	io->inuse = 1;
24*9a747e4fSDavid du Colombier 	io->op = op;
25*9a747e4fSDavid du Colombier 	va_start(arg, n);
26*9a747e4fSDavid du Colombier 	for(i=0; i<n; i++)
27*9a747e4fSDavid du Colombier 		io->arg[i] = va_arg(arg, long);
28*9a747e4fSDavid du Colombier 	sendp(io->c, io);
29*9a747e4fSDavid du Colombier 	recvp(io->c);
30*9a747e4fSDavid du Colombier 	ret = io->ret;
31*9a747e4fSDavid du Colombier 	if(ret < 0)
32*9a747e4fSDavid du Colombier 		errstr(io->err, sizeof io->err);
33*9a747e4fSDavid du Colombier 	io->inuse = 0;
34*9a747e4fSDavid du Colombier 	return ret;
35*9a747e4fSDavid du Colombier }
36*9a747e4fSDavid du Colombier 
37*9a747e4fSDavid du Colombier static void
38*9a747e4fSDavid du Colombier t2(Ioproc *io, int ret)
39*9a747e4fSDavid du Colombier {
40*9a747e4fSDavid du Colombier 	io->ret = ret;
41*9a747e4fSDavid du Colombier 	if(ret < 0)
42*9a747e4fSDavid du Colombier 		rerrstr(io->err, sizeof io->err);
43*9a747e4fSDavid du Colombier 	sendp(io->c, io);
44*9a747e4fSDavid du Colombier }
45*9a747e4fSDavid du Colombier 
46*9a747e4fSDavid du Colombier static void ioread2(Ioproc*);
47*9a747e4fSDavid du Colombier static long
48*9a747e4fSDavid du Colombier ioread(Ioproc *io, int fd, void *a, long n)
49*9a747e4fSDavid du Colombier {
50*9a747e4fSDavid du Colombier 	return t(io, ioread2, 3, fd, a, n);
51*9a747e4fSDavid du Colombier }
52*9a747e4fSDavid du Colombier static void
53*9a747e4fSDavid du Colombier ioread2(Ioproc *io)
54*9a747e4fSDavid du Colombier {
55*9a747e4fSDavid du Colombier 	t2(io, read(io->arg[0], (void*)io->arg[1], io->arg[2]));
56*9a747e4fSDavid du Colombier }
57*9a747e4fSDavid du Colombier 
58*9a747e4fSDavid du Colombier static void iowrite2(Ioproc*);
59*9a747e4fSDavid du Colombier static long
60*9a747e4fSDavid du Colombier iowrite(Ioproc *io, int fd, void *a, long n)
61*9a747e4fSDavid du Colombier {
62*9a747e4fSDavid du Colombier 	return t(io, iowrite2, 3, fd, a, n);
63*9a747e4fSDavid du Colombier }
64*9a747e4fSDavid du Colombier static void
65*9a747e4fSDavid du Colombier iowrite2(Ioproc *io)
66*9a747e4fSDavid du Colombier {
67*9a747e4fSDavid du Colombier 	t2(io, write(io->arg[0], (void*)io->arg[1], io->arg[2]));
68*9a747e4fSDavid du Colombier }
69*9a747e4fSDavid du Colombier 
70*9a747e4fSDavid du Colombier static void ioclose2(Ioproc*);
71*9a747e4fSDavid du Colombier static int
72*9a747e4fSDavid du Colombier ioclose(Ioproc *io, int fd)
73*9a747e4fSDavid du Colombier {
74*9a747e4fSDavid du Colombier 	return t(io, ioclose2, 1, fd);
75*9a747e4fSDavid du Colombier }
76*9a747e4fSDavid du Colombier static void
77*9a747e4fSDavid du Colombier ioclose2(Ioproc *io)
78*9a747e4fSDavid du Colombier {
79*9a747e4fSDavid du Colombier 	t2(io, close(io->arg[0]));
80*9a747e4fSDavid du Colombier }
81*9a747e4fSDavid du Colombier 
82*9a747e4fSDavid du Colombier static void iodial2(Ioproc*);
83*9a747e4fSDavid du Colombier static int
84*9a747e4fSDavid du Colombier iodial(Ioproc *io, char *a, char *b, char *c, int *d, int e)
85*9a747e4fSDavid du Colombier {
86*9a747e4fSDavid du Colombier 	return t(io, iodial2, 5, a, b, c, d, e);
87*9a747e4fSDavid du Colombier }
88*9a747e4fSDavid du Colombier static void
89*9a747e4fSDavid du Colombier iodial2(Ioproc *io)
90*9a747e4fSDavid du Colombier {
91*9a747e4fSDavid du Colombier 	t2(io, tlsdial((char*)io->arg[0], (char*)io->arg[1], (char*)io->arg[2], (int*)io->arg[3], io->arg[4]));
92*9a747e4fSDavid du Colombier }
93*9a747e4fSDavid du Colombier 
94*9a747e4fSDavid du Colombier static void ioopen2(Ioproc*);
95*9a747e4fSDavid du Colombier static int
96*9a747e4fSDavid du Colombier ioopen(Ioproc *io, char *path, int mode)
97*9a747e4fSDavid du Colombier {
98*9a747e4fSDavid du Colombier 	return t(io, ioopen2, 2, path, mode);
99*9a747e4fSDavid du Colombier }
100*9a747e4fSDavid du Colombier static void
101*9a747e4fSDavid du Colombier ioopen2(Ioproc *io)
102*9a747e4fSDavid du Colombier {
103*9a747e4fSDavid du Colombier 	t2(io, open((char*)io->arg[0], io->arg[1]));
104*9a747e4fSDavid du Colombier }
105*9a747e4fSDavid du Colombier 
106*9a747e4fSDavid du Colombier static int
107*9a747e4fSDavid du Colombier ioprint(Ioproc *io, int fd, char *fmt, ...)
108*9a747e4fSDavid du Colombier {
109*9a747e4fSDavid du Colombier 	char buf[1024];
110*9a747e4fSDavid du Colombier 	va_list arg;
111*9a747e4fSDavid du Colombier 
112*9a747e4fSDavid du Colombier 	va_start(arg, fmt);
113*9a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof buf, fmt, arg);
114*9a747e4fSDavid du Colombier 	va_end(arg);
115*9a747e4fSDavid du Colombier 	return iowrite(io, fd, buf, strlen(buf));
116*9a747e4fSDavid du Colombier }
117*9a747e4fSDavid du Colombier 
118*9a747e4fSDavid du Colombier static void
119*9a747e4fSDavid du Colombier iointerrupt(Ioproc *io)
120*9a747e4fSDavid du Colombier {
121*9a747e4fSDavid du Colombier 	if(!io->inuse)
122*9a747e4fSDavid du Colombier 		return;
123*9a747e4fSDavid du Colombier 	postnote(PNPROC, io->pid, "interrupt");
124*9a747e4fSDavid du Colombier }
125*9a747e4fSDavid du Colombier 
126*9a747e4fSDavid du Colombier static void
127*9a747e4fSDavid du Colombier xioproc(void *a)
128*9a747e4fSDavid du Colombier {
129*9a747e4fSDavid du Colombier 	Ioproc *io;
130*9a747e4fSDavid du Colombier 
131*9a747e4fSDavid du Colombier 	io = a;
132*9a747e4fSDavid du Colombier 	io->pid = getpid();
133*9a747e4fSDavid du Colombier 	sendp(io->c, nil);
134*9a747e4fSDavid du Colombier 	while(recvp(io->c) == io)
135*9a747e4fSDavid du Colombier 		io->op(io);
136*9a747e4fSDavid du Colombier 	chanfree(io->c);
137*9a747e4fSDavid du Colombier 	free(io);
138*9a747e4fSDavid du Colombier }
139*9a747e4fSDavid du Colombier 
140*9a747e4fSDavid du Colombier static int
141*9a747e4fSDavid du Colombier tlsdial(char *a, char *b, char *c, int *d, int usetls)
142*9a747e4fSDavid du Colombier {
143*9a747e4fSDavid du Colombier 	int fd, tfd;
144*9a747e4fSDavid du Colombier 	TLSconn conn;
145*9a747e4fSDavid du Colombier 
146*9a747e4fSDavid du Colombier 	fd = dial(a, b, c, d);
147*9a747e4fSDavid du Colombier 	if(fd < 0)
148*9a747e4fSDavid du Colombier 		return -1;
149*9a747e4fSDavid du Colombier 	if(usetls == 0)
150*9a747e4fSDavid du Colombier 		return fd;
151*9a747e4fSDavid du Colombier 
152*9a747e4fSDavid du Colombier 	memset(&conn, 0, sizeof conn);
153*9a747e4fSDavid du Colombier 	tfd = tlsClient(fd, &conn);
154*9a747e4fSDavid du Colombier 	if(tfd < 0){
155*9a747e4fSDavid du Colombier 		print("tls %r\n");
156*9a747e4fSDavid du Colombier 		close(fd);
157*9a747e4fSDavid du Colombier 		return -1;
158*9a747e4fSDavid du Colombier 	}
159*9a747e4fSDavid du Colombier 	/* BUG: check cert here? */
160*9a747e4fSDavid du Colombier 	if(conn.cert)
161*9a747e4fSDavid du Colombier 		free(conn.cert);
162*9a747e4fSDavid du Colombier 	close(fd);
163*9a747e4fSDavid du Colombier 	return tfd;
164*9a747e4fSDavid du Colombier }
165*9a747e4fSDavid du Colombier 
166*9a747e4fSDavid du Colombier Ioproc iofns =
167*9a747e4fSDavid du Colombier {
168*9a747e4fSDavid du Colombier 	ioread,
169*9a747e4fSDavid du Colombier 	iowrite,
170*9a747e4fSDavid du Colombier 	iodial,
171*9a747e4fSDavid du Colombier 	ioclose,
172*9a747e4fSDavid du Colombier 	ioopen,
173*9a747e4fSDavid du Colombier 	ioprint,
174*9a747e4fSDavid du Colombier 	iointerrupt,
175*9a747e4fSDavid du Colombier };
176*9a747e4fSDavid du Colombier 
177*9a747e4fSDavid du Colombier Ioproc *iofree;
178*9a747e4fSDavid du Colombier 
179*9a747e4fSDavid du Colombier Ioproc*
180*9a747e4fSDavid du Colombier ioproc(void)
181*9a747e4fSDavid du Colombier {
182*9a747e4fSDavid du Colombier 	Ioproc *io;
183*9a747e4fSDavid du Colombier 
184*9a747e4fSDavid du Colombier 	if((io = iofree) != nil){
185*9a747e4fSDavid du Colombier 		iofree = io->next;
186*9a747e4fSDavid du Colombier 		return io;
187*9a747e4fSDavid du Colombier 	}
188*9a747e4fSDavid du Colombier 	io = emalloc(sizeof(*io));
189*9a747e4fSDavid du Colombier 	*io = iofns;
190*9a747e4fSDavid du Colombier 	io->c = chancreate(sizeof(void*), 0);
191*9a747e4fSDavid du Colombier 	if(proccreate(xioproc, io, STACK) < 0)
192*9a747e4fSDavid du Colombier 		sysfatal("proccreate: %r");
193*9a747e4fSDavid du Colombier 	recvp(io->c);
194*9a747e4fSDavid du Colombier 	return io;
195*9a747e4fSDavid du Colombier }
196*9a747e4fSDavid du Colombier 
197*9a747e4fSDavid du Colombier void
198*9a747e4fSDavid du Colombier closeioproc(Ioproc *io)
199*9a747e4fSDavid du Colombier {
200*9a747e4fSDavid du Colombier 	io->next = iofree;
201*9a747e4fSDavid du Colombier 	iofree = io;
202*9a747e4fSDavid du Colombier }
203*9a747e4fSDavid du Colombier 
204