free(s);
}
+char *findstdconf(char *name)
+{
+ char *path, *p, *p2, *t;
+
+ if((path = getenv("PATH")) == NULL)
+ return(NULL);
+ path = sstrdup(path);
+ for(p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
+ if((p2 = strrchr(p, '/')) == NULL)
+ continue;
+ *p2 = 0;
+ if(!access(t = sprintf3("%s/etc/%s", p, name), R_OK)) {
+ free(path);
+ return(sstrdup(t));
+ }
+ }
+ free(path);
+ return(NULL);
+}
+
static struct child *newchild(char *name, int type)
{
struct child *ch;
struct rule **rules;
};
-struct config *cflist;
+static struct config *cflist;
+static struct config *gconfig, *lconfig;
static time_t now;
static void freepattern(struct pattern *pat)
cf->next->prev = cf->prev;
if(cf == cflist)
cflist = cf->next;
- free(cf->path);
+ if(cf->path != NULL)
+ free(cf->path);
for(ch = cf->children; ch != NULL; ch = nch) {
nch = ch->next;
freechild(ch);
free(tmp);
if((cf = getconfig(".")) != NULL)
bufadd(buf, cf);
+ if(lconfig != NULL)
+ bufadd(buf, lconfig);
+ if(gconfig != NULL)
+ bufadd(buf, gconfig);
bufadd(buf, NULL);
return(ret = buf.b);
}
free(path);
}
+static void usage(FILE *out)
+{
+ fprintf(out, "usage: dirplex [-hN] [-c CONFIG] DIR\n");
+}
+
int main(int argc, char **argv)
{
+ int c;
+ int nodef;
+ char *gcf, *lcf;
struct hthead *req;
int fd;
- if(argc < 2) {
- flog(LOG_ERR, "usage: dirplex DIR");
+ nodef = 0;
+ lcf = NULL;
+ while((c = getopt(argc, argv, "hNc:")) >= 0) {
+ switch(c) {
+ case 'h':
+ usage(stdout);
+ exit(0);
+ case 'N':
+ nodef = 1;
+ break;
+ case 'c':
+ lcf = optarg;
+ break;
+ default:
+ usage(stderr);
+ exit(1);
+ }
+ }
+ if(argc - optind < 1) {
+ usage(stderr);
exit(1);
}
- if(chdir(argv[1])) {
- flog(LOG_ERR, "could not change directory to %s: %s", argv[1], strerror(errno));
+ if(!nodef) {
+ if((gcf = findstdconf("ashd/dirplex.rc")) != NULL) {
+ gconfig = readconfig(gcf);
+ free(gcf);
+ }
+ }
+ if(lcf != NULL) {
+ 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));
exit(1);
}
signal(SIGCHLD, SIG_IGN);
char *restpat;
};
-static struct config *config;
+static struct config *gconfig, *lconfig;
static void freepattern(struct pattern *pat)
{
char *chnm;
struct child *ch;
- if(((chnm = findmatch(config, req, 0)) == NULL) && ((chnm = findmatch(config, req, 1)) == NULL)) {
+ chnm = NULL;
+ if(chnm == NULL)
+ chnm = findmatch(lconfig, req, 0);
+ if(chnm == NULL)
+ chnm = findmatch(lconfig, req, 1);
+ if(gconfig != NULL) {
+ if(chnm == NULL)
+ chnm = findmatch(gconfig, req, 0);
+ if(chnm == NULL)
+ chnm = findmatch(gconfig, req, 1);
+ }
+ if(chnm == NULL) {
simpleerror(fd, 404, "Not Found", "The requested resource could not be found on this server.");
return;
}
- if((ch = getchild(config, chnm)) == NULL) {
+ ch = NULL;
+ if(ch == NULL)
+ ch = getchild(lconfig, chnm);
+ if(gconfig != NULL) {
+ if(ch == NULL)
+ ch = getchild(gconfig, chnm);
+ }
+ if(ch == NULL) {
flog(LOG_ERR, "child %s requested, but was not declared", chnm);
simpleerror(fd, 500, "Configuration Error", "The server is erroneously configured. Handler %s was requested, but not declared.", chnm);
return;
simpleerror(fd, 500, "Server Error", "The request handler crashed.");
}
+static void usage(FILE *out)
+{
+ fprintf(out, "usage: patplex [-hN] CONFIGFILE\n");
+}
+
int main(int argc, char **argv)
{
+ int c;
+ int nodef;
+ char *gcf;
struct hthead *req;
int fd;
-
- if(argc < 2) {
- flog(LOG_ERR, "usage: patplex CONFIGFILE");
+
+ nodef = 0;
+ while((c = getopt(argc, argv, "hN")) >= 0) {
+ switch(c) {
+ case 'h':
+ usage(stdout);
+ exit(0);
+ case 'N':
+ nodef = 1;
+ break;
+ default:
+ usage(stderr);
+ exit(1);
+ }
+ }
+ if(argc - optind < 1) {
+ usage(stderr);
exit(1);
}
- config = readconfig(argv[1]);
+ if(!nodef) {
+ if((gcf = findstdconf("ashd/patplex.rc")) != NULL) {
+ gconfig = readconfig(gcf);
+ free(gcf);
+ }
+ }
+ lconfig = readconfig(argv[optind]);
signal(SIGCHLD, SIG_IGN);
while(1) {
if((fd = recvreq(0, &req)) < 0) {