#include <resp.h>
#include <cf.h>
-#define CH_SOCKET 0
-#define CH_FORK 1
-
#define PAT_BASENAME 0
#define PAT_PATHNAME 1
#define PAT_ALL 2
return(cf);
}
-static struct child *findchild(char *file, char *name)
+static struct config **getconfigs(char *file)
{
- char *buf, *p;
+ static struct config **ret = NULL;
+ struct {
+ struct config **b;
+ size_t s, d;
+ } buf;
struct config *cf;
- struct child *ch;
-
- buf = sstrdup(file);
+ char *tmp, *p;
+
+ if(ret != NULL)
+ free(ret);
+ bufinit(buf);
+ tmp = sstrdup(file);
while(1) {
- ch = NULL;
- if(!strcmp(buf, "."))
+ if((p = strrchr(tmp, '/')) == NULL)
break;
- if((p = strrchr(buf, '/')) != NULL)
- *p = 0;
- else
- strcpy(buf, ".");
- cf = getconfig(buf);
- if(cf == NULL)
- continue;
- if((ch = getchild(cf, name)) != NULL)
+ *p = 0;
+ if((cf = getconfig(tmp)) != NULL)
+ bufadd(buf, cf);
+ }
+ free(tmp);
+ if((cf = getconfig(".")) != NULL)
+ bufadd(buf, cf);
+ bufadd(buf, NULL);
+ return(ret = buf.b);
+}
+
+static struct child *findchild(char *file, char *name)
+{
+ int i;
+ struct config **cfs;
+ struct child *ch;
+
+ cfs = getconfigs(file);
+ for(i = 0; cfs[i] != NULL; i++) {
+ if((ch = getchild(cfs[i], name)) != NULL)
break;
}
- free(buf);
return(ch);
}
static struct pattern *findmatch(char *file, int trydefault)
{
- int i;
- char *buf, *p, *bn;
- struct config *cf;
+ int i, c;
+ char *bn;
+ struct config **cfs;
struct pattern *pat;
struct rule *rule;
bn++;
else
bn = file;
- buf = sstrdup(file);
- while(1) {
- pat = NULL;
- if(!strcmp(buf, "."))
- break;
- if((p = strrchr(buf, '/')) != NULL)
- *p = 0;
- else
- strcpy(buf, ".");
- cf = getconfig(buf);
- if(cf == NULL)
- continue;
- for(pat = cf->patterns; pat != NULL; pat = pat->next) {
+ cfs = getconfigs(file);
+ for(c = 0; cfs[c] != NULL; c++) {
+ for(pat = cfs[c]->patterns; pat != NULL; pat = pat->next) {
for(i = 0; (rule = pat->rules[i]) != NULL; i++) {
if(rule->type == PAT_BASENAME) {
if(fnmatch(rule->pattern, bn, 0))
}
}
if(!rule)
- goto out;
- }
- }
-
-out:
- free(buf);
- return(pat);
-}
-
-static void forkchild(struct child *ch)
-{
- ch->fd = stdmkchild(ch->argv);
-}
-
-static void passreq(struct child *ch, struct hthead *req, int fd)
-{
- if(ch->fd < 0)
- forkchild(ch);
- if(sendreq(ch->fd, req, fd)) {
- if(errno == EPIPE) {
- /* Assume that the child has crashed and restart it. */
- forkchild(ch);
- if(!sendreq(ch->fd, req, fd))
- return;
+ return(pat);
}
- flog(LOG_ERR, "could not pass on request to child %s: %s", ch->name, strerror(errno));
- close(ch->fd);
- ch->fd = -1;
- simpleerror(fd, 500, "Server Error", "The request handler crashed.");
}
+ return(NULL);
}
static void handlefile(struct hthead *req, int fd, char *path)
return;
}
- if(ch->type == CH_SOCKET) {
- passreq(ch, req, fd);
- } else if(ch->type == CH_FORK) {
- stdforkserve(ch->argv, req, fd);
- }
+ if(childhandle(ch, req, fd))
+ simpleerror(fd, 500, "Server Error", "The request handler crashed.");
}
static void handledir(struct hthead *req, int fd, char *path)
else
path = sprintf2("%s/%s", path, p);
free(tmp);
+ if(p2 == NULL) {
+ stdredir(req, fd, 301, sprintf3("%s/", p));
+ goto out;
+ }
if(checkdir(req, fd, path))
break;
goto next;