17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include "httpd.h"
580ee5cbfSDavid du Colombier #include "httpsrv.h"
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier typedef struct Suffix Suffix;
87dd7cddfSDavid du Colombier struct Suffix
97dd7cddfSDavid du Colombier {
107dd7cddfSDavid du Colombier Suffix *next;
117dd7cddfSDavid du Colombier char *suffix;
127dd7cddfSDavid du Colombier char *generic;
137dd7cddfSDavid du Colombier char *specific;
147dd7cddfSDavid du Colombier char *encoding;
157dd7cddfSDavid du Colombier };
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier Suffix *suffixes = nil;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier static Suffix* parsesuffix(char*, Suffix*);
207dd7cddfSDavid du Colombier static char* skipwhite(char*);
2180ee5cbfSDavid du Colombier static HContents suffixclass(char*);
227dd7cddfSDavid du Colombier static char* towhite(char*);
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier int
updateQid(int fd,Qid * q)257dd7cddfSDavid du Colombier updateQid(int fd, Qid *q)
267dd7cddfSDavid du Colombier {
27*9a747e4fSDavid du Colombier Dir *dir;
28*9a747e4fSDavid du Colombier Qid dq;
297dd7cddfSDavid du Colombier
30*9a747e4fSDavid du Colombier dir = dirfstat(fd);
31*9a747e4fSDavid du Colombier if(dir == nil)
327dd7cddfSDavid du Colombier sysfatal("can't dirfstat");
33*9a747e4fSDavid du Colombier dq = dir->qid;
34*9a747e4fSDavid du Colombier free(dir);
35*9a747e4fSDavid du Colombier if(q->path == dq.path && q->vers == dq.vers && q->type == dq.type)
367dd7cddfSDavid du Colombier return 0;
37*9a747e4fSDavid du Colombier *q = dq;
387dd7cddfSDavid du Colombier return 1;
397dd7cddfSDavid du Colombier }
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier void
contentinit(void)427dd7cddfSDavid du Colombier contentinit(void)
437dd7cddfSDavid du Colombier {
447dd7cddfSDavid du Colombier static Biobuf *b = nil;
457dd7cddfSDavid du Colombier static Qid qid;
467dd7cddfSDavid du Colombier char *file, *s;
477dd7cddfSDavid du Colombier Suffix *this;
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier file = "/sys/lib/mimetype";
507dd7cddfSDavid du Colombier if(b == nil){ /* first time */
517dd7cddfSDavid du Colombier b = Bopen(file, OREAD);
527dd7cddfSDavid du Colombier if(b == nil)
537dd7cddfSDavid du Colombier sysfatal("can't read from %s", file);
547dd7cddfSDavid du Colombier }
557dd7cddfSDavid du Colombier if(updateQid(Bfildes(b), &qid) == 0)
567dd7cddfSDavid du Colombier return;
577dd7cddfSDavid du Colombier Bseek(b, 0, 0);
587dd7cddfSDavid du Colombier while(suffixes!=nil){
597dd7cddfSDavid du Colombier this = suffixes;
607dd7cddfSDavid du Colombier suffixes = suffixes->next;
617dd7cddfSDavid du Colombier free(this->suffix);
627dd7cddfSDavid du Colombier free(this->generic);
637dd7cddfSDavid du Colombier free(this->specific);
647dd7cddfSDavid du Colombier free(this->encoding);
657dd7cddfSDavid du Colombier free(this);
667dd7cddfSDavid du Colombier }
677dd7cddfSDavid du Colombier
687dd7cddfSDavid du Colombier while((s = Brdline(b, '\n')) != nil){
697dd7cddfSDavid du Colombier s[Blinelen(b) - 1] = 0;
707dd7cddfSDavid du Colombier suffixes = parsesuffix(s, suffixes);
717dd7cddfSDavid du Colombier }
727dd7cddfSDavid du Colombier }
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier static Suffix*
parsesuffix(char * line,Suffix * suffix)757dd7cddfSDavid du Colombier parsesuffix(char *line, Suffix *suffix)
767dd7cddfSDavid du Colombier {
777dd7cddfSDavid du Colombier Suffix *s;
787dd7cddfSDavid du Colombier char *p, *fields[5];
797dd7cddfSDavid du Colombier int i, nf;
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier p = strchr(line, '#');
827dd7cddfSDavid du Colombier if(p != nil)
837dd7cddfSDavid du Colombier *p = '\0';
847dd7cddfSDavid du Colombier nf = tokenize(line, fields, 5);
857dd7cddfSDavid du Colombier for(i = 0; i < 4; i++)
8659cc4ca5SDavid du Colombier if(i >= nf || fields[i][0] == '-')
877dd7cddfSDavid du Colombier fields[i] = nil;
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier if(fields[2] == nil)
907dd7cddfSDavid du Colombier fields[1] = nil;
917dd7cddfSDavid du Colombier if(fields[1] == nil && fields[3] == nil)
927dd7cddfSDavid du Colombier return suffix;
93*9a747e4fSDavid du Colombier if(fields[0] == nil)
94*9a747e4fSDavid du Colombier return suffix;
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier s = ezalloc(sizeof *s);
977dd7cddfSDavid du Colombier s->next = suffix;
987dd7cddfSDavid du Colombier s->suffix = estrdup(fields[0]);
997dd7cddfSDavid du Colombier if(fields[1] != nil){
1007dd7cddfSDavid du Colombier s->generic = estrdup(fields[1]);
1017dd7cddfSDavid du Colombier s->specific = estrdup(fields[2]);
1027dd7cddfSDavid du Colombier }
1037dd7cddfSDavid du Colombier if(fields[3] != nil)
1047dd7cddfSDavid du Colombier s->encoding = estrdup(fields[3]);
1057dd7cddfSDavid du Colombier return s;
1067dd7cddfSDavid du Colombier }
1077dd7cddfSDavid du Colombier
1087dd7cddfSDavid du Colombier /*
1097dd7cddfSDavid du Colombier * classify by file name extensions
1107dd7cddfSDavid du Colombier */
11180ee5cbfSDavid du Colombier HContents
uriclass(HConnect * hc,char * name)11280ee5cbfSDavid du Colombier uriclass(HConnect *hc, char *name)
1137dd7cddfSDavid du Colombier {
11480ee5cbfSDavid du Colombier HContents conts;
1157dd7cddfSDavid du Colombier Suffix *s;
11680ee5cbfSDavid du Colombier HContent *type, *enc;
117*9a747e4fSDavid du Colombier char *buf, *p;
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier type = nil;
1207dd7cddfSDavid du Colombier enc = nil;
1217dd7cddfSDavid du Colombier if((p = strrchr(name, '/')) != nil)
1227dd7cddfSDavid du Colombier name = p + 1;
123*9a747e4fSDavid du Colombier buf = hstrdup(hc, name);
1247dd7cddfSDavid du Colombier while((p = strrchr(buf, '.')) != nil){
1257dd7cddfSDavid du Colombier for(s = suffixes; s; s = s->next){
1267dd7cddfSDavid du Colombier if(strcmp(p, s->suffix) == 0){
1277dd7cddfSDavid du Colombier if(s->generic != nil && type == nil)
12880ee5cbfSDavid du Colombier type = hmkcontent(hc, s->generic, s->specific, nil);
1297dd7cddfSDavid du Colombier if(s->encoding != nil && enc == nil)
13080ee5cbfSDavid du Colombier enc = hmkcontent(hc, s->encoding, nil, nil);
1317dd7cddfSDavid du Colombier }
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier *p = 0;
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier conts.type = type;
1367dd7cddfSDavid du Colombier conts.encoding = enc;
1377dd7cddfSDavid du Colombier return conts;
1387dd7cddfSDavid du Colombier }
1397dd7cddfSDavid du Colombier
1407dd7cddfSDavid du Colombier /*
1417dd7cddfSDavid du Colombier * classify by initial contents of file
1427dd7cddfSDavid du Colombier */
14380ee5cbfSDavid du Colombier HContents
dataclass(HConnect * hc,char * buf,int n)14480ee5cbfSDavid du Colombier dataclass(HConnect *hc, char *buf, int n)
1457dd7cddfSDavid du Colombier {
14680ee5cbfSDavid du Colombier HContents conts;
1477dd7cddfSDavid du Colombier Rune r;
1487dd7cddfSDavid du Colombier int c, m;
1497dd7cddfSDavid du Colombier
1507dd7cddfSDavid du Colombier for(; n > 0; n -= m){
1517dd7cddfSDavid du Colombier c = *buf;
1527dd7cddfSDavid du Colombier if(c < Runeself){
1537dd7cddfSDavid du Colombier if(c < 32 && c != '\n' && c != '\r' && c != '\t' && c != '\v'){
1547dd7cddfSDavid du Colombier conts.type = nil;
1557dd7cddfSDavid du Colombier conts.encoding = nil;
1567dd7cddfSDavid du Colombier return conts;
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier m = 1;
1597dd7cddfSDavid du Colombier }else{
1607dd7cddfSDavid du Colombier m = chartorune(&r, buf);
1617dd7cddfSDavid du Colombier if(r == Runeerror){
1627dd7cddfSDavid du Colombier conts.type = nil;
1637dd7cddfSDavid du Colombier conts.encoding = nil;
1647dd7cddfSDavid du Colombier return conts;
1657dd7cddfSDavid du Colombier }
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier buf += m;
1687dd7cddfSDavid du Colombier }
16980ee5cbfSDavid du Colombier conts.type = hmkcontent(hc, "text", "plain", nil);
1707dd7cddfSDavid du Colombier conts.encoding = nil;
1717dd7cddfSDavid du Colombier return conts;
1727dd7cddfSDavid du Colombier }
173