Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}