6 #include <sys/socket.h>
11 #include <ashd/mtio.h>
13 #include "statserve.h"
15 static struct source *sources = NULL;
17 static struct source *parsesource(char *arg)
19 if(arg[strlen(arg) - 1] == '/') {
22 return(mkdbsrc(arg, NULL));
26 static int cached(struct hthead *req, struct fileinfo f)
31 if((hdr = getheader(req, "If-Modified-Since")) != NULL) {
32 cdate = parsehttpdate(hdr);
33 return((cdate > 0) && !(cdate < f.mtime));
38 static void serve(struct muth *muth, va_list args)
40 vavar(struct hthead *, req);
47 for(src = sources; src != NULL; src = src->next) {
48 f = src->serve(src, req->rest);
53 simpleerror(fd, 404, "Resource not found", "The resource %s was not found", htmlquote(req->rest));
56 out = mtstdopen(fd, 1, 60, "r+");
58 fprintf(out, "HTTP/1.1 304 Not Modified\n");
59 fprintf(out, "Content-Length: 0\n");
62 fprintf(out, "HTTP/1.1 200 OK\n");
63 fprintf(out, "Content-Type: %s\n", f.ctype);
64 fprintf(out, "Content-Length: %zi\n", f.sz);
65 fprintf(out, "Last-Modified: %s\n", fmthttpdate(f.mtime));
67 fwrite(f.data, 1, f.sz, out);
79 static void usage(FILE *out)
81 fprintf(out, "usage: statserve [-h] [-P PAGESIZE] SOURCE...\n");
84 static void listenloop(struct muth *muth, va_list args)
93 if((fd = recvreq(lfd, &req)) < 0) {
95 flog(LOG_ERR, "recvreq: %s", strerror(errno));
98 mustart(serve, req, fd);
99 for(src = sources; src != NULL; src = src->next) {
106 static void sigterm(int sig)
108 shutdown(0, SHUT_RDWR);
111 static void closeall(void)
115 for(src = sources; src != NULL; src = src->next) {
121 int main(int argc, char **argv)
124 struct source *last, *src;
126 while((c = getopt(argc, argv, "+hP:")) >= 0) {
129 dbpagesize = atoi(optarg);
140 while(optind < argc) {
141 if((src = parsesource(argv[optind++])) == NULL) {
156 mustart(listenloop, 0);
157 signal(SIGINT, sigterm);
158 signal(SIGTERM, sigterm);