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