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/png", "png" }, 105 { "image/ppm", "ppm" }, 106 { "image/tiff", "tiff" }, 107 { "text/html", "html" }, 108 { "text/plain", "txt" }, 109 { "text/xml", "xml" }, 110 }; 111 112 void 113 replumb(Client *c) 114 { 115 int i; 116 Plumbmsg *m; 117 char name[128], *ctype, *ext, *p; 118 119 if(!c->plumbed) 120 return; 121 m = emalloc(sizeof(Plumbmsg)); 122 m->src = "webfs"; 123 m->dst = nil; 124 m->wdir = "/"; 125 m->type = "text"; 126 m->attr = nil; 127 addattr(m, "url", c->url->url); 128 ctype = c->contenttype; 129 ext = nil; 130 if(ctype != nil) { 131 addattr(m, "content-type", ctype); 132 for(i = 0; i < nelem(ctypes); i++) { 133 if(strcmp(ctype, ctypes[i].ctype) == 0) { 134 ext = ctypes[i].ext; 135 break; 136 } 137 } 138 } 139 if(ext == nil) { 140 p = strrchr(c->url->url, '/'); 141 if(p != nil) 142 p = strrchr(p+1, '.'); 143 if(p != nil && strlen(p) <= 5) 144 ext = p+1; 145 else 146 ext = "txt"; /* punt */ 147 } 148 c->ext = ext; 149 if(0)fprint(2, "content type %s -> extension .%s\n", ctype, ext); 150 m->ndata = snprint(name, sizeof name, "/mnt/web/%d/body.%s", c->num, ext); 151 m->data = estrdup(name); 152 proccreate(plumbsendproc, m, STACK); /* separate proc to avoid a deadlock */ 153 } 154 155 static void 156 plumbsendproc(void *x) 157 { 158 Plumbmsg *m; 159 160 m = x; 161 plumbsend(plumbsendfd, m); 162 freeattrs(m); 163 free(m->data); 164 free(m); 165 } 166