1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <fcall.h> 5 #include <thread.h> 6 #include <plumb.h> 7 #include <9p.h> 8 9 #include "dat.h" 10 #include "fns.h" 11 12 static int plumbsendfd; 13 static int plumbwebfd; 14 static Channel *plumbchan; 15 16 static void plumbwebproc(void*); 17 static void plumbwebthread(void*); 18 static void plumbsendproc(void*); 19 20 void 21 plumbinit(void) 22 { 23 plumbsendfd = plumbopen("send", OWRITE|OCEXEC); 24 plumbwebfd = plumbopen("web", OREAD|OCEXEC); 25 } 26 27 void 28 plumbstart(void) 29 { 30 plumbchan = chancreate(sizeof(Plumbmsg*), 0); 31 proccreate(plumbwebproc, nil, STACK); 32 threadcreate(plumbwebthread, nil, STACK); 33 } 34 35 static void 36 plumbwebthread(void*) 37 { 38 char *base; 39 Plumbmsg *m; 40 41 for(;;){ 42 m = recvp(plumbchan); 43 if(m == nil) 44 threadexits(nil); 45 base = plumblookup(m->attr, "baseurl"); 46 if(base == nil) 47 base = m->wdir; 48 plumburl(m->data, base); 49 plumbfree(m); 50 } 51 } 52 53 static void 54 plumbwebproc(void*) 55 { 56 Plumbmsg *m; 57 58 for(;;){ 59 m = plumbrecv(plumbwebfd); 60 sendp(plumbchan, m); 61 if(m == nil) 62 threadexits(nil); 63 } 64 } 65 66 static void 67 addattr(Plumbmsg *m, char *name, char *value) 68 { 69 Plumbattr *a; 70 71 a = malloc(sizeof(Plumbattr)); 72 a->name = name; 73 a->value = value; 74 a->next = m->attr; 75 m->attr = a; 76 } 77 78 static void 79 freeattrs(Plumbmsg *m) 80 { 81 Plumbattr *a, *next; 82 83 a = m->attr; 84 while(a != nil) { 85 next = a->next; 86 free(a); 87 a = next; 88 } 89 } 90 91 static struct 92 { 93 char *ctype; 94 char *ext; 95 } 96 ctypes[] = 97 { 98 { "application/msword", "doc" }, 99 { "application/pdf", "pdf" }, 100 { "application/postscript", "ps" }, 101 { "application/rtf", "rtf" }, 102 { "image/gif", "gif" }, 103 { "image/jpeg", "jpg" }, 104 { "image/tiff", "tiff" }, 105 { "text/html", "html" }, 106 { "text/plain", "txt" }, 107 { "text/xml", "xml" }, 108 }; 109 110 void 111 replumb(Client *c) 112 { 113 int i; 114 Plumbmsg *m; 115 char name[128], *ctype, *ext, *p; 116 117 if(!c->plumbed) 118 return; 119 m = emalloc(sizeof(Plumbmsg)); 120 m->src = "webfs"; 121 m->dst = nil; 122 m->wdir = "/"; 123 m->type = "text"; 124 m->attr = nil; 125 addattr(m, "url", c->url->url); 126 ctype = c->contenttype; 127 ext = nil; 128 if(ctype != nil) { 129 addattr(m, "content-type", ctype); 130 for(i = 0; i < nelem(ctypes); i++) { 131 if(strcmp(ctype, ctypes[i].ctype) == 0) { 132 ext = ctypes[i].ext; 133 break; 134 } 135 } 136 } 137 if(ext == nil) { 138 p = strrchr(c->url->url, '/'); 139 if(p != nil) 140 p = strrchr(p+1, '.'); 141 if(p != nil && strlen(p) <= 5) 142 ext = p+1; 143 else 144 ext = "txt"; /* punt */ 145 } 146 c->ext = ext; 147 if(0)fprint(2, "content type %s -> extension .%s\n", ctype, ext); 148 m->ndata = snprint(name, sizeof name, "/mnt/web/%d/body.%s", c->num, ext); 149 m->data = estrdup(name); 150 proccreate(plumbsendproc, m, STACK); /* separate proc to avoid a deadlock */ 151 } 152 153 static void 154 plumbsendproc(void *x) 155 { 156 Plumbmsg *m; 157 158 m = x; 159 plumbsend(plumbsendfd, m); 160 freeattrs(m); 161 free(m->data); 162 free(m); 163 } 164