doc: Documented htpipe.
[ashd.git] / src / errlogger.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 <stdio.h>
20 #include <stdlib.h>
21 #include <syslog.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <signal.h>
26
27 static int prio;
28
29 static void logloop(int fd)
30 {
31     FILE *in;
32     char buf[1024];
33     size_t len;
34     
35     in = fdopen(fd, "r");
36     while(fgets(buf, sizeof(buf), in) != NULL) {
37         len = strlen(buf);
38         if(buf[len - 1] == '\n')
39             buf[len - 1] = 0;
40         syslog(prio, "%s", buf);
41     }
42     fclose(in);
43 }
44
45 static void usage(FILE *out)
46 {
47     fprintf(out, "usage: errlogger [-h] [-n NAME] [-f FACILITY] [-p PRIO] PROGRAM [ARGS...]\n");
48 }
49
50 int main(int argc, char **argv)
51 {
52     int c;
53     int pfd[2];
54     pid_t ch;
55     char *name;
56     int fac;
57     
58     name = NULL;
59     prio = LOG_WARNING;
60     fac = LOG_DAEMON;
61     while((c = getopt(argc, argv, "+hn:p:f:")) >= 0) {
62         switch(c) {
63         case 'n':
64             name = optarg;
65             break;
66         case 'f':
67             if(!strcmp(optarg, "auth")) {
68                 fac = LOG_AUTH;
69             } else if(!strcmp(optarg, "authpriv")) {
70                 fac = LOG_AUTHPRIV;
71             } else if(!strcmp(optarg, "cron")) {
72                 fac = LOG_CRON;
73             } else if(!strcmp(optarg, "daemon")) {
74                 fac = LOG_DAEMON;
75             } else if(!strcmp(optarg, "ftp")) {
76                 fac = LOG_FTP;
77             } else if(!strcmp(optarg, "kern")) {
78                 fac = LOG_KERN;
79             } else if(!strcmp(optarg, "lpr")) {
80                 fac = LOG_LPR;
81             } else if(!strcmp(optarg, "mail")) {
82                 fac = LOG_MAIL;
83             } else if(!strcmp(optarg, "news")) {
84                 fac = LOG_NEWS;
85             } else if(!strcmp(optarg, "user")) {
86                 fac = LOG_USER;
87             } else if(!strcmp(optarg, "uucp")) {
88                 fac = LOG_UUCP;
89             } else if(!strncmp(optarg, "local", 5) && (optarg[5] >= '0') && (optarg[5] <= '7') && !optarg[6]) {
90                 fac = LOG_LOCAL0 + (optarg[5] - '0');
91             } else {
92                 fprintf(stderr, "errlogger: unknown facility %s\n", optarg);
93                 exit(1);
94             }
95             break;
96         case 'p':
97             if(!strcmp(optarg, "emerg")) {
98                 fac = LOG_EMERG;
99             } else if(!strcmp(optarg, "alert")) {
100                 fac = LOG_ALERT;
101             } else if(!strcmp(optarg, "crit")) {
102                 fac = LOG_CRIT;
103             } else if(!strcmp(optarg, "err")) {
104                 fac = LOG_ERR;
105             } else if(!strcmp(optarg, "warning")) {
106                 fac = LOG_WARNING;
107             } else if(!strcmp(optarg, "notice")) {
108                 fac = LOG_NOTICE;
109             } else if(!strcmp(optarg, "info")) {
110                 fac = LOG_INFO;
111             } else if(!strcmp(optarg, "debug")) {
112                 fac = LOG_DEBUG;
113             } else {
114                 fprintf(stderr, "errlogger: unknown priorty %s\n", optarg);
115                 exit(1);
116             }
117             break;
118         case 'h':
119             usage(stdout);
120             exit(0);
121         default:
122             usage(stderr);
123             exit(1);
124         }
125     }
126     if(argc - optind < 1) {
127         usage(stderr);
128         exit(1);
129     }
130     if(name == NULL)
131         name = argv[optind];
132     openlog(name, 0, fac);
133     pipe(pfd);
134     if((ch = fork()) == 0) {
135         close(pfd[0]);
136         if(pfd[1] != 2) {
137             dup2(pfd[1], 2);
138             close(pfd[1]);
139         }
140         execvp(argv[optind], argv + optind);
141         fprintf(stderr, "errlogger: %s: %s", argv[optind], strerror(errno));
142         exit(127);
143     }
144     close(pfd[1]);
145     signal(SIGCHLD, SIG_IGN);
146     logloop(pfd[0]);
147     return(0);
148 }