xref: /plan9/sys/src/cmd/webfs/plumb.c (revision 314a20f0e09eab47511b995e9c2c3983f0567584)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier #include <fcall.h>
59a747e4fSDavid du Colombier #include <thread.h>
69a747e4fSDavid du Colombier #include <plumb.h>
79a747e4fSDavid du Colombier #include <9p.h>
89a747e4fSDavid du Colombier 
99a747e4fSDavid du Colombier #include "dat.h"
109a747e4fSDavid du Colombier #include "fns.h"
119a747e4fSDavid du Colombier 
129a747e4fSDavid du Colombier static int		plumbsendfd;
139a747e4fSDavid du Colombier static int		plumbwebfd;
149a747e4fSDavid du Colombier static Channel	*plumbchan;
159a747e4fSDavid du Colombier 
169a747e4fSDavid du Colombier static void	plumbwebproc(void*);
179a747e4fSDavid du Colombier static void	plumbwebthread(void*);
189a747e4fSDavid du Colombier static void plumbsendproc(void*);
199a747e4fSDavid du Colombier 
209a747e4fSDavid du Colombier void
plumbinit(void)219a747e4fSDavid du Colombier plumbinit(void)
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier 	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
249a747e4fSDavid du Colombier 	plumbwebfd = plumbopen("web", OREAD|OCEXEC);
259a747e4fSDavid du Colombier }
269a747e4fSDavid du Colombier 
279a747e4fSDavid du Colombier void
plumbstart(void)289a747e4fSDavid du Colombier plumbstart(void)
299a747e4fSDavid du Colombier {
309a747e4fSDavid du Colombier 	plumbchan = chancreate(sizeof(Plumbmsg*), 0);
319a747e4fSDavid du Colombier 	proccreate(plumbwebproc, nil, STACK);
329a747e4fSDavid du Colombier 	threadcreate(plumbwebthread, nil, STACK);
339a747e4fSDavid du Colombier }
349a747e4fSDavid du Colombier 
359a747e4fSDavid du Colombier static void
plumbwebthread(void *)369a747e4fSDavid du Colombier plumbwebthread(void*)
379a747e4fSDavid du Colombier {
389a747e4fSDavid du Colombier 	char *base;
399a747e4fSDavid du Colombier 	Plumbmsg *m;
409a747e4fSDavid du Colombier 
419a747e4fSDavid du Colombier 	for(;;){
429a747e4fSDavid du Colombier 		m = recvp(plumbchan);
439a747e4fSDavid du Colombier 		if(m == nil)
449a747e4fSDavid du Colombier 			threadexits(nil);
459a747e4fSDavid du Colombier 		base = plumblookup(m->attr, "baseurl");
469a747e4fSDavid du Colombier 		if(base == nil)
479a747e4fSDavid du Colombier 			base = m->wdir;
489a747e4fSDavid du Colombier 		plumburl(m->data, base);
499a747e4fSDavid du Colombier 		plumbfree(m);
509a747e4fSDavid du Colombier 	}
519a747e4fSDavid du Colombier }
529a747e4fSDavid du Colombier 
539a747e4fSDavid du Colombier static void
plumbwebproc(void *)549a747e4fSDavid du Colombier plumbwebproc(void*)
559a747e4fSDavid du Colombier {
569a747e4fSDavid du Colombier 	Plumbmsg *m;
579a747e4fSDavid du Colombier 
589a747e4fSDavid du Colombier 	for(;;){
599a747e4fSDavid du Colombier 		m = plumbrecv(plumbwebfd);
609a747e4fSDavid du Colombier 		sendp(plumbchan, m);
619a747e4fSDavid du Colombier 		if(m == nil)
629a747e4fSDavid du Colombier 			threadexits(nil);
639a747e4fSDavid du Colombier 	}
649a747e4fSDavid du Colombier }
659a747e4fSDavid du Colombier 
669a747e4fSDavid du Colombier static void
addattr(Plumbmsg * m,char * name,char * value)679a747e4fSDavid du Colombier addattr(Plumbmsg *m, char *name, char *value)
689a747e4fSDavid du Colombier {
699a747e4fSDavid du Colombier 	Plumbattr *a;
709a747e4fSDavid du Colombier 
719a747e4fSDavid du Colombier 	a = malloc(sizeof(Plumbattr));
729a747e4fSDavid du Colombier 	a->name = name;
739a747e4fSDavid du Colombier 	a->value = value;
749a747e4fSDavid du Colombier 	a->next = m->attr;
759a747e4fSDavid du Colombier 	m->attr = a;
769a747e4fSDavid du Colombier }
779a747e4fSDavid du Colombier 
789a747e4fSDavid du Colombier static void
freeattrs(Plumbmsg * m)799a747e4fSDavid du Colombier freeattrs(Plumbmsg *m)
809a747e4fSDavid du Colombier {
819a747e4fSDavid du Colombier 	Plumbattr *a, *next;
829a747e4fSDavid du Colombier 
839a747e4fSDavid du Colombier 	a = m->attr;
849a747e4fSDavid du Colombier 	while(a != nil) {
859a747e4fSDavid du Colombier 		next = a->next;
869a747e4fSDavid du Colombier 		free(a);
879a747e4fSDavid du Colombier 		a = next;
889a747e4fSDavid du Colombier 	}
899a747e4fSDavid du Colombier }
909a747e4fSDavid du Colombier 
919a747e4fSDavid du Colombier static struct
929a747e4fSDavid du Colombier {
939a747e4fSDavid du Colombier 	char	*ctype;
949a747e4fSDavid du Colombier 	char	*ext;
959a747e4fSDavid du Colombier }
969a747e4fSDavid du Colombier ctypes[] =
979a747e4fSDavid du Colombier {
989a747e4fSDavid du Colombier 	{ "application/msword", "doc" },
999a747e4fSDavid du Colombier 	{ "application/pdf", "pdf" },
1009a747e4fSDavid du Colombier 	{ "application/postscript", "ps" },
1019a747e4fSDavid du Colombier 	{ "application/rtf", "rtf" },
1029a747e4fSDavid du Colombier 	{ "image/gif", "gif" },
1039a747e4fSDavid du Colombier 	{ "image/jpeg", "jpg" },
104*314a20f0SDavid du Colombier 	{ "image/png", "png" },
105*314a20f0SDavid du Colombier 	{ "image/ppm", "ppm" },
1069a747e4fSDavid du Colombier 	{ "image/tiff", "tiff" },
1079a747e4fSDavid du Colombier 	{ "text/html", "html" },
1089a747e4fSDavid du Colombier 	{ "text/plain", "txt" },
1099a747e4fSDavid du Colombier 	{ "text/xml", "xml" },
1109a747e4fSDavid du Colombier };
1119a747e4fSDavid du Colombier 
1129a747e4fSDavid du Colombier void
replumb(Client * c)1139a747e4fSDavid du Colombier replumb(Client *c)
1149a747e4fSDavid du Colombier {
1159a747e4fSDavid du Colombier 	int i;
1169a747e4fSDavid du Colombier 	Plumbmsg *m;
1179a747e4fSDavid du Colombier 	char name[128], *ctype, *ext, *p;
1189a747e4fSDavid du Colombier 
1199a747e4fSDavid du Colombier 	if(!c->plumbed)
1209a747e4fSDavid du Colombier 		return;
1219a747e4fSDavid du Colombier 	m = emalloc(sizeof(Plumbmsg));
1229a747e4fSDavid du Colombier 	m->src = "webfs";
1239a747e4fSDavid du Colombier 	m->dst = nil;
1249a747e4fSDavid du Colombier 	m->wdir = "/";
1259a747e4fSDavid du Colombier 	m->type = "text";
1269a747e4fSDavid du Colombier 	m->attr = nil;
1279a747e4fSDavid du Colombier 	addattr(m, "url", c->url->url);
1289a747e4fSDavid du Colombier 	ctype = c->contenttype;
1299a747e4fSDavid du Colombier 	ext = nil;
1309a747e4fSDavid du Colombier 	if(ctype != nil) {
1319a747e4fSDavid du Colombier 		addattr(m, "content-type", ctype);
1329a747e4fSDavid du Colombier 		for(i = 0; i < nelem(ctypes); i++) {
1339a747e4fSDavid du Colombier 			if(strcmp(ctype, ctypes[i].ctype) == 0) {
1349a747e4fSDavid du Colombier 				ext = ctypes[i].ext;
1359a747e4fSDavid du Colombier 				break;
1369a747e4fSDavid du Colombier 			}
1379a747e4fSDavid du Colombier 		}
1389a747e4fSDavid du Colombier 	}
1399a747e4fSDavid du Colombier 	if(ext == nil) {
1409a747e4fSDavid du Colombier 		p = strrchr(c->url->url, '/');
1419a747e4fSDavid du Colombier 		if(p != nil)
1429a747e4fSDavid du Colombier 			p = strrchr(p+1, '.');
1439a747e4fSDavid du Colombier 		if(p != nil && strlen(p) <= 5)
1449a747e4fSDavid du Colombier 			ext = p+1;
1459a747e4fSDavid du Colombier 		else
1469a747e4fSDavid du Colombier 			ext = "txt";		/* punt */
1479a747e4fSDavid du Colombier 	}
1489a747e4fSDavid du Colombier 	c->ext = ext;
1499a747e4fSDavid du Colombier if(0)fprint(2, "content type %s -> extension .%s\n", ctype, ext);
1509a747e4fSDavid du Colombier 	m->ndata = snprint(name, sizeof name, "/mnt/web/%d/body.%s", c->num, ext);
1519a747e4fSDavid du Colombier 	m->data = estrdup(name);
1529a747e4fSDavid du Colombier 	proccreate(plumbsendproc, m, STACK);	/* separate proc to avoid a deadlock */
1539a747e4fSDavid du Colombier }
1549a747e4fSDavid du Colombier 
1559a747e4fSDavid du Colombier static void
plumbsendproc(void * x)1569a747e4fSDavid du Colombier plumbsendproc(void *x)
1579a747e4fSDavid du Colombier {
1589a747e4fSDavid du Colombier 	Plumbmsg *m;
1599a747e4fSDavid du Colombier 
1609a747e4fSDavid du Colombier 	m = x;
1619a747e4fSDavid du Colombier 	plumbsend(plumbsendfd, m);
1629a747e4fSDavid du Colombier 	freeattrs(m);
1639a747e4fSDavid du Colombier 	free(m->data);
1649a747e4fSDavid du Colombier 	free(m);
1659a747e4fSDavid du Colombier }
166