]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/webfs/plumb.c
cwfs: back to previous version
[plan9front.git] / sys / src / cmd / webfs / plumb.c
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 }