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 <bio.h>
4
#include "httpd.h"
5
#include "httpsrv.h"
6
 
7
typedef struct Suffix	Suffix;
8
struct Suffix 
9
{
10
	Suffix	*next;
11
	char	*suffix;
12
	char	*generic;
13
	char	*specific;
14
	char	*encoding;
15
};
16
 
17
Suffix	*suffixes = nil;
18
 
19
static	Suffix*			parsesuffix(char*, Suffix*);
20
static	char*			skipwhite(char*);
21
static	HContents		suffixclass(char*);
22
static	char*			towhite(char*);
23
 
24
int
25
updateQid(int fd, Qid *q)
26
{
27
	Dir *dir;
28
	Qid dq;
29
 
30
	dir = dirfstat(fd);
31
	if(dir == nil)
32
		sysfatal("can't dirfstat");
33
	dq = dir->qid;
34
	free(dir);
35
	if(q->path == dq.path && q->vers == dq.vers && q->type == dq.type)
36
		return 0;
37
	*q = dq;
38
	return 1;
39
}
40
 
41
void
42
contentinit(void)
43
{
44
	static Biobuf *b = nil;
45
	static Qid qid;
46
	char *file, *s;
47
	Suffix *this;
48
 
49
	file = "/sys/lib/mimetype";
50
	if(b == nil){ /* first time */
51
		b = Bopen(file, OREAD);
52
		if(b == nil)
53
			sysfatal("can't read from %s", file);
54
	}
55
	if(updateQid(Bfildes(b), &qid) == 0)
56
		return;
57
	Bseek(b, 0, 0);
58
	while(suffixes!=nil){
59
		this = suffixes;
60
		suffixes = suffixes->next;
61
		free(this->suffix);
62
		free(this->generic);
63
		free(this->specific);
64
		free(this->encoding);
65
		free(this);
66
	}
67
 
68
	while((s = Brdline(b, '\n')) != nil){
69
		s[Blinelen(b) - 1] = 0;
70
		suffixes = parsesuffix(s, suffixes);
71
	}
72
}
73
 
74
static Suffix*
75
parsesuffix(char *line, Suffix *suffix)
76
{
77
	Suffix *s;
78
	char *p, *fields[5];
79
	int i, nf;
80
 
81
	p = strchr(line, '#');
82
	if(p != nil)
83
		*p = '\0';
84
	nf = tokenize(line, fields, 5);
85
	for(i = 0; i < 4; i++)
86
		if(i >= nf || fields[i][0] == '-')
87
			fields[i] = nil;
88
 
89
	if(fields[2] == nil)
90
		fields[1] = nil;
91
	if(fields[1] == nil && fields[3] == nil)
92
		return suffix;
93
	if(fields[0] == nil)
94
		return suffix;
95
 
96
	s = ezalloc(sizeof *s);
97
	s->next = suffix;
98
	s->suffix = estrdup(fields[0]);
99
	if(fields[1] != nil){
100
		s->generic = estrdup(fields[1]);
101
		s->specific = estrdup(fields[2]);
102
	}
103
	if(fields[3] != nil)
104
		s->encoding = estrdup(fields[3]);
105
	return s;
106
}
107
 
108
/*
109
 * classify by file name extensions
110
 */
111
HContents
112
uriclass(HConnect *hc, char *name)
113
{
114
	HContents conts;
115
	Suffix *s;
116
	HContent *type, *enc;
117
	char *buf, *p;
118
 
119
	type = nil;
120
	enc = nil;
121
	if((p = strrchr(name, '/')) != nil)
122
		name = p + 1;
123
	buf = hstrdup(hc, name);
124
	while((p = strrchr(buf, '.')) != nil){
125
		for(s = suffixes; s; s = s->next){
126
			if(strcmp(p, s->suffix) == 0){
127
				if(s->generic != nil && type == nil)
128
					type = hmkcontent(hc, s->generic, s->specific, nil);
129
				if(s->encoding != nil && enc == nil)
130
					enc = hmkcontent(hc, s->encoding, nil, nil);
131
			}
132
		}
133
		*p = 0;
134
	}
135
	conts.type = type;
136
	conts.encoding = enc;
137
	return conts;
138
}
139
 
140
/*
141
 * classify by initial contents of file
142
 */
143
HContents
144
dataclass(HConnect *hc, char *buf, int n)
145
{
146
	HContents conts;
147
	Rune r;
148
	int c, m;
149
 
150
	for(; n > 0; n -= m){
151
		c = *buf;
152
		if(c < Runeself){
153
			if(c < 32 && c != '\n' && c != '\r' && c != '\t' && c != '\v'){
154
				conts.type = nil;
155
				conts.encoding = nil;
156
				return conts;
157
			}
158
			m = 1;
159
		}else{
160
			m = chartorune(&r, buf);
161
			if(r == Runeerror){
162
				conts.type = nil;
163
				conts.encoding = nil;
164
				return conts;
165
			}
166
		}
167
		buf += m;
168
	}
169
	conts.type = hmkcontent(hc, "text", "plain", nil);
170
	conts.encoding = nil;
171
	return conts;
172
}