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