X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=blobdiff_plain;f=src%2Fdirplex%2Fconf.c;h=dec84b57287dba25f267c7d740864e1b303f8e87;hp=e40a44542043648f1919904049022d28c674f3c1;hb=54490135194e0474e753ce7d4cb60f935dad1dd4;hpb=da75c835b71b9ed9cf1d2c8fcbcfb7631dd24a05 diff --git a/src/dirplex/conf.c b/src/dirplex/conf.c index e40a445..dec84b5 100644 --- a/src/dirplex/conf.c +++ b/src/dirplex/conf.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "dirplex.h" @@ -45,9 +46,16 @@ static void freerule(struct rule *rule) static void freepattern(struct pattern *pat) { struct rule **rule; + struct headmod *head; for(rule = pat->rules; *rule; rule++) freerule(*rule); + while((head = pat->headers) != NULL) { + pat->headers = head->next; + free(head->name); + free(head->value); + free(head); + } if(pat->childnm != NULL) free(pat->childnm); freeca(pat->fchild); @@ -76,6 +84,8 @@ static void freeconfig(struct config *cf) freepattern(pat); } freeca(cf->index); + if(cf->capture != NULL) + free(cf->capture); free(cf); } @@ -128,6 +138,7 @@ static struct pattern *parsepattern(struct cfstate *s) { struct pattern *pat; struct rule *rule; + struct headmod *head; int sl; if(!strcmp(s->argv[0], "match")) { @@ -162,6 +173,8 @@ static struct pattern *parsepattern(struct cfstate *s) newrule(pat)->type = PAT_ALL; } else if(!strcmp(s->argv[0], "default")) { newrule(pat)->type = PAT_DEFAULT; + } else if(!strcmp(s->argv[0], "local")) { + newrule(pat)->type = PAT_LOCAL; } else if(!strcmp(s->argv[0], "handler")) { if(s->argc < 2) { flog(LOG_WARNING, "%s:%i: missing child name for `handler' directive", s->file, s->lno); @@ -172,6 +185,19 @@ static struct pattern *parsepattern(struct cfstate *s) pat->childnm = sstrdup(s->argv[1]); } else if(!strcmp(s->argv[0], "fork")) { pat->fchild = cadup(s->argv + 1); + } else if(!strcmp(s->argv[0], "set") || !strcmp(s->argv[0], "xset")) { + if(s->argc < 3) { + flog(LOG_WARNING, "%s:%i: missing header name or pattern for `%s' directive", s->file, s->lno, s->argv[0]); + continue; + } + omalloc(head); + if(!strcmp(s->argv[0], "xset")) + head->name = sprintf2("X-Ash-%s", s->argv[1]); + else + head->name = sstrdup(s->argv[1]); + head->value = sstrdup(s->argv[2]); + head->next = pat->headers; + pat->headers = head; } else if(!strcmp(s->argv[0], "end") || !strcmp(s->argv[0], "eof")) { break; } else { @@ -228,6 +254,17 @@ struct config *readconfig(char *file) cf->index = NULL; if(s->argc > 1) cf->index = cadup(s->argv + 1); + } else if(!strcmp(s->argv[0], "capture")) { + if(s->argc < 2) { + flog(LOG_WARNING, "%s:%i: missing argument to capture declaration", s->file, s->lno); + continue; + } + if(cf->capture != NULL) + free(cf->capture); + cf->capture = sstrdup(s->argv[1]); + cf->caproot = 1; + if((s->argc > 2) && strchr(s->argv[2], 'R')) + cf->caproot = 0; } else if(!strcmp(s->argv[0], "eof")) { break; } else { @@ -240,21 +277,6 @@ struct config *readconfig(char *file) return(cf); } -static void mergechildren(struct config *dst, struct config *src) -{ - struct child *ch1, *ch2; - - for(ch1 = dst->children; ch1 != NULL; ch1 = ch1->next) { - for(ch2 = src->children; ch2 != NULL; ch2 = ch2->next) { - if(!strcmp(ch1->name, ch2->name)) { - ch1->fd = ch2->fd; - ch2->fd = -1; - break; - } - } - } -} - struct config *getconfig(char *path) { struct config *cf, *ocf; @@ -266,10 +288,10 @@ struct config *getconfig(char *path) for(cf = cflist; cf != NULL; cf = cf->next) { if(!strcmp(cf->path, path)) { if(now - cf->lastck > 5) { + cf->lastck = now; if(stat(fn, &sb) || (sb.st_mtime != cf->mtime)) break; } - cf->lastck = now; return(cf); } } @@ -283,7 +305,7 @@ struct config *getconfig(char *path) mtime = sb.st_mtime; } if(ocf != NULL) { - mergechildren(cf, ocf); + mergechildren(cf->children, ocf->children); freeconfig(ocf); } cf->path = sstrdup(path); @@ -310,6 +332,8 @@ struct config **getconfigs(char *file) if(ret != NULL) free(ret); bufinit(buf); + if(!strncmp(file, "./", 2)) + file += 2; tmp = sstrdup(file); while(1) { if((p = strrchr(tmp, '/')) == NULL) @@ -335,6 +359,8 @@ struct child *findchild(char *file, char *name, struct config **cf) struct config **cfs; struct child *ch; + if(cf != NULL) + *cf = NULL; cfs = getconfigs(file); for(i = 0; cfs[i] != NULL; i++) { if((ch = getchild(cfs[i], name)) != NULL) { @@ -343,16 +369,19 @@ struct child *findchild(char *file, char *name, struct config **cf) return(ch); } } + if(!strcmp(name, ".notfound")) + return(notfound); return(NULL); } struct pattern *findmatch(char *file, int trydefault, int dir) { int i, o, c; - char *bn; + char *bn, *ln; struct config **cfs; struct pattern *pat; struct rule *rule; + size_t pl; if((bn = strrchr(file, '/')) != NULL) bn++; @@ -360,6 +389,15 @@ struct pattern *findmatch(char *file, int trydefault, int dir) bn = file; cfs = getconfigs(file); for(c = 0; cfs[c] != NULL; c++) { + if(cfs[c]->path == NULL) { + ln = file; + } else { + pl = strlen(cfs[c]->path); + if((strlen(file) > pl) && !strncmp(file, cfs[c]->path, pl) && (file[pl] == '/')) + ln = file + pl + 1; + else + ln = file; /* This should only happen in the base directory. */ + } for(pat = cfs[c]->patterns; pat != NULL; pat = pat->next) { if(!dir && (pat->type == PT_DIR)) continue; @@ -375,7 +413,7 @@ struct pattern *findmatch(char *file, int trydefault, int dir) break; } else if(rule->type == PAT_PATHNAME) { for(o = 0; rule->patterns[o] != NULL; o++) { - if(!fnmatch(rule->patterns[o], file, FNM_PATHNAME)) + if(!fnmatch(rule->patterns[o], ln, FNM_PATHNAME)) break; } if(rule->patterns[o] == NULL) @@ -384,6 +422,9 @@ struct pattern *findmatch(char *file, int trydefault, int dir) } else if(rule->type == PAT_DEFAULT) { if(!trydefault) break; + } else if(rule->type == PAT_LOCAL) { + if(strchr(ln, '/')) + break; } } if(!rule) @@ -394,3 +435,19 @@ struct pattern *findmatch(char *file, int trydefault, int dir) return(findmatch(file, 1, dir)); return(NULL); } + +static int donotfound(struct child *ch, struct hthead *req, int fd, void (*chinit)(void *), void *idata) +{ + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); + return(0); +} + +static struct chandler i_notfound = { + .handle = donotfound, +}; + +static struct child s_notfound = { + .name = ".notfound", + .iface = &i_notfound, +}; +struct child *notfound = &s_notfound;