123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "httpd.h"
- #include "httpsrv.h"
- typedef struct Suffix Suffix;
- struct Suffix
- {
- Suffix *next;
- char *suffix;
- char *generic;
- char *specific;
- char *encoding;
- };
- Suffix *suffixes = nil;
- static Suffix* parsesuffix(char*, Suffix*);
- static char* skipwhite(char*);
- static HContents suffixclass(char*);
- static char* towhite(char*);
- int
- updateQid(int fd, Qid *q)
- {
- Dir *dir;
- Qid dq;
- dir = dirfstat(fd);
- if(dir == nil)
- sysfatal("can't dirfstat");
- dq = dir->qid;
- free(dir);
- if(q->path == dq.path && q->vers == dq.vers && q->type == dq.type)
- return 0;
- *q = dq;
- return 1;
- }
- void
- contentinit(void)
- {
- static Biobuf *b = nil;
- static Qid qid;
- char *file, *s;
- Suffix *this;
- file = "/sys/lib/mimetype";
- if(b == nil){ /* first time */
- b = Bopen(file, OREAD);
- if(b == nil)
- sysfatal("can't read from %s", file);
- }
- if(updateQid(Bfildes(b), &qid) == 0)
- return;
- Bseek(b, 0, 0);
- while(suffixes!=nil){
- this = suffixes;
- suffixes = suffixes->next;
- free(this->suffix);
- free(this->generic);
- free(this->specific);
- free(this->encoding);
- free(this);
- }
- while((s = Brdline(b, '\n')) != nil){
- s[Blinelen(b) - 1] = 0;
- suffixes = parsesuffix(s, suffixes);
- }
- }
- static Suffix*
- parsesuffix(char *line, Suffix *suffix)
- {
- Suffix *s;
- char *p, *fields[5];
- int i, nf;
- p = strchr(line, '#');
- if(p != nil)
- *p = '\0';
- nf = tokenize(line, fields, 5);
- for(i = 0; i < 4; i++)
- if(i >= nf || fields[i][0] == '-')
- fields[i] = nil;
- if(fields[2] == nil)
- fields[1] = nil;
- if(fields[1] == nil && fields[3] == nil)
- return suffix;
- if(fields[0] == nil)
- return suffix;
- s = ezalloc(sizeof *s);
- s->next = suffix;
- s->suffix = estrdup(fields[0]);
- if(fields[1] != nil){
- s->generic = estrdup(fields[1]);
- s->specific = estrdup(fields[2]);
- }
- if(fields[3] != nil)
- s->encoding = estrdup(fields[3]);
- return s;
- }
- /*
- * classify by file name extensions
- */
- HContents
- uriclass(HConnect *hc, char *name)
- {
- HContents conts;
- Suffix *s;
- HContent *type, *enc;
- char *buf, *p;
- type = nil;
- enc = nil;
- if((p = strrchr(name, '/')) != nil)
- name = p + 1;
- buf = hstrdup(hc, name);
- while((p = strrchr(buf, '.')) != nil){
- for(s = suffixes; s; s = s->next){
- if(strcmp(p, s->suffix) == 0){
- if(s->generic != nil && type == nil)
- type = hmkcontent(hc, s->generic, s->specific, nil);
- if(s->encoding != nil && enc == nil)
- enc = hmkcontent(hc, s->encoding, nil, nil);
- }
- }
- *p = 0;
- }
- conts.type = type;
- conts.encoding = enc;
- return conts;
- }
- /*
- * classify by initial contents of file
- */
- HContents
- dataclass(HConnect *hc, char *buf, int n)
- {
- HContents conts;
- Rune r;
- int c, m;
- for(; n > 0; n -= m){
- c = *buf;
- if(c < Runeself){
- if(c < 32 && c != '\n' && c != '\r' && c != '\t' && c != '\v'){
- conts.type = nil;
- conts.encoding = nil;
- return conts;
- }
- m = 1;
- }else{
- m = chartorune(&r, buf);
- if(r == Runeerror){
- conts.type = nil;
- conts.encoding = nil;
- return conts;
- }
- }
- buf += m;
- }
- conts.type = hmkcontent(hc, "text", "plain", nil);
- conts.encoding = nil;
- return conts;
- }
|