X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fdirplex.c;h=60f0859ddcb86d41560fcd4b75fdbb9d54472e45;hb=13975be5892675874bea8c86d7d8140f5790e7e6;hp=01d87157319005e62bf3a75682995eb2ba4e9b80;hpb=6373daf9d9fdd9e24d2c657abf0625337f9b3a24;p=ashd.git diff --git a/src/dirplex.c b/src/dirplex.c index 01d8715..60f0859 100644 --- a/src/dirplex.c +++ b/src/dirplex.c @@ -43,6 +43,9 @@ #define PAT_ALL 2 #define PAT_DEFAULT 3 +#define PT_FILE 0 +#define PT_DIR 1 + struct config { struct config *next, *prev; char *path; @@ -59,6 +62,7 @@ struct rule { struct pattern { struct pattern *next; + int type; char *childnm; char **fchild; struct rule **rules; @@ -169,6 +173,8 @@ static struct pattern *parsepattern(struct cfstate *s) return(NULL); } + if((s->argc > 1) && !strcmp(s->argv[1], "directory")) + pat->type = PT_DIR; sl = s->lno; while(1) { getcfline(s); @@ -302,6 +308,9 @@ static struct config *getconfig(char *path) cf->mtime = mtime; cf->lastck = now; cf->next = cflist; + cf->prev = NULL; + if(cflist != NULL) + cflist->prev = cf; cflist = cf; return(cf); } @@ -352,7 +361,7 @@ static struct child *findchild(char *file, char *name) return(ch); } -static struct pattern *findmatch(char *file, int trydefault) +static struct pattern *findmatch(char *file, int trydefault, int dir) { int i, o, c; char *bn; @@ -367,6 +376,10 @@ static struct pattern *findmatch(char *file, int trydefault) cfs = getconfigs(file); for(c = 0; cfs[c] != NULL; c++) { for(pat = cfs[c]->patterns; pat != NULL; pat = pat->next) { + if(!dir && (pat->type == PT_DIR)) + continue; + if(dir && (pat->type != PT_DIR)) + continue; for(i = 0; (rule = pat->rules[i]) != NULL; i++) { if(rule->type == PAT_BASENAME) { for(o = 0; rule->patterns[o] != NULL; o++) { @@ -392,19 +405,16 @@ static struct pattern *findmatch(char *file, int trydefault) return(pat); } } + if(!trydefault) + return(findmatch(file, 1, dir)); return(NULL); } -static void handlefile(struct hthead *req, int fd, char *path) +static void handle(struct hthead *req, int fd, char *path, struct pattern *pat) { - struct pattern *pat; struct child *ch; headappheader(req, "X-Ash-File", path); - if(((pat = findmatch(path, 0)) == NULL) && ((pat = findmatch(path, 1)) == NULL)) { - simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); - return; - } if(pat->fchild) { stdforkserve(pat->fchild, req, fd); } else { @@ -418,6 +428,17 @@ static void handlefile(struct hthead *req, int fd, char *path) } } +static void handlefile(struct hthead *req, int fd, char *path) +{ + struct pattern *pat; + + if((pat = findmatch(path, 0, 0)) == NULL) { + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); + return; + } + handle(req, fd, path, pat); +} + static void handledir(struct hthead *req, int fd, char *path) { struct config **cfs; @@ -426,8 +447,10 @@ static void handledir(struct hthead *req, int fd, char *path) char *inm, *ipath, *p; DIR *dir; struct dirent *dent; + struct pattern *pat; - cfs = getconfigs(sprintf3("%s/", path)); + path = sprintf2("%s/", path); + cfs = getconfigs(path); for(i = 0; cfs[i] != NULL; i++) { if(cfs[i]->index != NULL) { for(o = 0; cfs[i]->index[o] != NULL; o++) { @@ -436,7 +459,7 @@ static void handledir(struct hthead *req, int fd, char *path) if(!stat(ipath, &sb) && S_ISREG(sb.st_mode)) { handlefile(req, fd, ipath); free(ipath); - return; + goto out; } free(ipath); @@ -445,7 +468,7 @@ static void handledir(struct hthead *req, int fd, char *path) while((dent = readdir(dir)) != NULL) { if((p = strchr(dent->d_name, '.')) == NULL) continue; - if(strncmp(dent->d_name, inm, p - dent->d_name)) + if(strncmp(dent->d_name, inm, strlen(inm))) continue; ipath = sprintf2("%s/%s", path, dent->d_name); if(stat(ipath, &sb) || !S_ISREG(sb.st_mode)) { @@ -460,14 +483,20 @@ static void handledir(struct hthead *req, int fd, char *path) if(ipath != NULL) { handlefile(req, fd, ipath); free(ipath); - return; + goto out; } } break; } } - /* XXX: Directory listings */ + if((pat = findmatch(path, 0, 1)) != NULL) { + handle(req, fd, path, pat); + goto out; + } simpleerror(fd, 403, "Not Authorized", "Will not send listings for this directory."); + +out: + free(path); } static int checkdir(struct hthead *req, int fd, char *path) @@ -491,6 +520,12 @@ static void serve(struct hthead *req, int fd) } else { *(p2++) = 0; } + if((tmp = unquoteurl(p)) == NULL) { + simpleerror(fd, 400, "Bad Request", "The requested URL contains an invalid escape sequence."); + goto fail; + } + strcpy(p, tmp); + free(tmp); if(!*p) { if(p2 == NULL) { @@ -605,7 +640,7 @@ int main(int argc, char **argv) { int c; int nodef; - char *gcf, *lcf; + char *gcf, *lcf, *clcf; struct hthead *req; int fd; @@ -638,8 +673,18 @@ int main(int argc, char **argv) } } if(lcf != NULL) { - if((lconfig = readconfig(lcf)) == NULL) - exit(1); + if(strchr(lcf, '/') == NULL) { + if((clcf = findstdconf(sprintf3("ashd/%s", lcf))) == NULL) { + flog(LOG_ERR, "could not find requested configuration `%s'", lcf); + exit(1); + } + if((lconfig = readconfig(clcf)) == NULL) + exit(1); + free(clcf); + } else { + if((lconfig = readconfig(lcf)) == NULL) + exit(1); + } } if(chdir(argv[optind])) { flog(LOG_ERR, "could not change directory to %s: %s", argv[optind], strerror(errno));