#define PAT_ALL 2
#define PAT_DEFAULT 3
+#define PT_FILE 0
+#define PT_DIR 1
+
struct config {
struct config *next, *prev;
char *path;
struct pattern {
struct pattern *next;
+ int type;
char *childnm;
char **fchild;
struct rule **rules;
return(NULL);
}
+ if((s->argc > 1) && !strcmp(s->argv[1], "directory"))
+ pat->type = PT_DIR;
sl = s->lno;
while(1) {
getcfline(s);
cf->mtime = mtime;
cf->lastck = now;
cf->next = cflist;
+ cf->prev = NULL;
+ if(cflist != NULL)
+ cflist->prev = cf;
cflist = cf;
return(cf);
}
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;
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++) {
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 {
}
}
+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;
int i, o;
struct stat sb;
- char *inm, *ipath, *p;
+ char *inm, *ipath, *p, *cpath;
DIR *dir;
struct dirent *dent;
+ struct pattern *pat;
- cfs = getconfigs(sprintf3("%s/", path));
+ cpath = sprintf2("%s/", path);
+ cfs = getconfigs(cpath);
for(i = 0; cfs[i] != NULL; i++) {
if(cfs[i]->index != NULL) {
for(o = 0; cfs[i]->index[o] != NULL; o++) {
if(!stat(ipath, &sb) && S_ISREG(sb.st_mode)) {
handlefile(req, fd, ipath);
free(ipath);
- return;
+ goto out;
}
free(ipath);
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)) {
if(ipath != NULL) {
handlefile(req, fd, ipath);
free(ipath);
- return;
+ goto out;
}
}
break;
}
}
- /* XXX: Directory listings */
+ if((pat = findmatch(cpath, 0, 1)) != NULL) {
+ handle(req, fd, cpath, pat);
+ goto out;
+ }
simpleerror(fd, 403, "Not Authorized", "Will not send listings for this directory.");
+
+out:
+ free(cpath);
}
static int checkdir(struct hthead *req, int fd, char *path)
} 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) {
{
int c;
int nodef;
- char *gcf, *lcf;
+ char *gcf, *lcf, *clcf;
struct hthead *req;
int fd;
}
}
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));