X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fdirplex%2Fconf.c;h=03d5477383e5a53b6a493625fbfca8f0e79a80c6;hb=b70b2d4f237082541d01b4b33abc86ef2b7b2223;hp=96a7704b6fc11516ec5c0387229fd0f3019fda02;hpb=600a1ce79471493f8cad5fcf118dc9797331d5aa;p=ashd.git diff --git a/src/dirplex/conf.c b/src/dirplex/conf.c index 96a7704..03d5477 100644 --- a/src/dirplex/conf.c +++ b/src/dirplex/conf.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "dirplex.h" @@ -76,6 +77,8 @@ static void freeconfig(struct config *cf) freepattern(pat); } freeca(cf->index); + if(cf->capture != NULL) + free(cf->capture); free(cf); } @@ -162,6 +165,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); @@ -228,6 +233,14 @@ 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]); } else if(!strcmp(s->argv[0], "eof")) { break; } else { @@ -242,7 +255,7 @@ struct config *readconfig(char *file) struct config *getconfig(char *path) { - struct config *cf; + struct config *cf, *ocf; struct stat sb; char *fn; time_t mtime; @@ -251,15 +264,14 @@ struct config *getconfig(char *path) for(cf = cflist; cf != NULL; cf = cf->next) { if(!strcmp(cf->path, path)) { if(now - cf->lastck > 5) { - if(stat(fn, &sb) || (sb.st_mtime != cf->mtime)) { - freeconfig(cf); + if(stat(fn, &sb) || (sb.st_mtime != cf->mtime)) break; - } } cf->lastck = now; return(cf); } } + ocf = cf; if(access(fn, R_OK) || stat(fn, &sb)) { cf = emptyconfig(); mtime = 0; @@ -268,6 +280,10 @@ struct config *getconfig(char *path) return(NULL); mtime = sb.st_mtime; } + if(ocf != NULL) { + mergechildren(cf->children, ocf->children); + freeconfig(ocf); + } cf->path = sstrdup(path); cf->mtime = mtime; cf->lastck = now; @@ -311,18 +327,25 @@ struct config **getconfigs(char *file) return(ret = buf.b); } -struct child *findchild(char *file, char *name) +struct child *findchild(char *file, char *name, struct config **cf) { int i; 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) - break; + if((ch = getchild(cfs[i], name)) != NULL) { + if(cf != NULL) + *cf = cfs[i]; + return(ch); + } } - return(ch); + if(!strcmp(name, ".notfound")) + return(notfound); + return(NULL); } struct pattern *findmatch(char *file, int trydefault, int dir) @@ -332,6 +355,7 @@ struct pattern *findmatch(char *file, int trydefault, int dir) struct config **cfs; struct pattern *pat; struct rule *rule; + size_t pl; if((bn = strrchr(file, '/')) != NULL) bn++; @@ -363,6 +387,12 @@ 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(cfs[c]->path == NULL) + break; + pl = strlen(cfs[c]->path); + if(!((strlen(file) > pl) && !strncmp(file, cfs[c]->path, pl) && (file[pl] == '/') && !strchr(file + pl + 1, '/'))) + break; } } if(!rule) @@ -373,3 +403,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;