0d7d845a21fc89c5c81bbfaf76b16a40408fb479
[ashd.git] / src / httrcall.c
1 /*
2     ashd - A Sane HTTP Daemon
3     Copyright (C) 2008  Fredrik Tolf <fredrik@dolda2000.com>
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <signal.h>
25 #include <sys/wait.h>
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #include <utils.h>
31 #include <log.h>
32 #include <req.h>
33 #include <proc.h>
34 #include <resp.h>
35
36 static char **prog;
37
38 static void serve(struct hthead *req, int fd)
39 {
40     if(stdforkserve(prog, req, fd, NULL, NULL) < 0)
41         simpleerror(fd, 500, "Server Error", "The server appears to be overloaded.");
42 }
43
44 static void chldhandler(int sig)
45 {
46     pid_t pid;
47     int st;
48     
49     while((pid = waitpid(-1, &st, WNOHANG)) > 0) {
50         if(WCOREDUMP(st))
51             flog(LOG_WARNING, "child process %i dumped core", pid);
52     }
53 }
54
55 static void usage(FILE *out)
56 {
57     fprintf(out, "usage: httrcall [-h] PROGRAM [ARGS...]\n");
58 }
59
60 int main(int argc, char **argv)
61 {
62     int c;
63     struct hthead *req;
64     int fd;
65     
66     while((c = getopt(argc, argv, "+h")) >= 0) {
67         switch(c) {
68         case 'h':
69             usage(stdout);
70             exit(0);
71         default:
72             usage(stderr);
73             exit(1);
74         }
75     }
76     if(argc < optind - 1) {
77         usage(stderr);
78         exit(1);
79     }
80     prog = argv + optind;
81     signal(SIGCHLD, chldhandler);
82     while(1) {
83         if((fd = recvreq(0, &req)) < 0) {
84             if(errno == EINTR)
85                 continue;
86             if(errno != 0)
87                 flog(LOG_ERR, "recvreq: %s", strerror(errno));
88             break;
89         }
90         serve(req, fd);
91         freehthead(req);
92         close(fd);
93     }
94     return(0);
95 }