Extract usage information into a separate file.
[oweals/busybox.git] / sysklogd / logger.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini logger implementation for busybox
4  *
5  * Copyright (C) 1999,2000 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 #include "internal.h"
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31
32 #if !defined BB_SYSLOGD
33
34 #define SYSLOG_NAMES
35 #include <sys/syslog.h>
36
37 #else
38 /* We have to do this since the header file defines static
39  * structues.  Argh.... bad libc, bad, bad...
40  */
41 #include <sys/syslog.h>
42 typedef struct _code {
43         char *c_name;
44         int c_val;
45 } CODE;
46 extern CODE prioritynames[];
47 extern CODE facilitynames[];
48 #endif
49
50 /* Decode a symbolic name to a numeric value 
51  * this function is based on code
52  * Copyright (c) 1983, 1993
53  * The Regents of the University of California.  All rights reserved.
54  */
55 static int decode(char *name, CODE * codetab)
56 {
57         CODE *c;
58
59         if (isdigit(*name))
60                 return (atoi(name));
61         for (c = codetab; c->c_name; c++) {
62                 if (!strcasecmp(name, c->c_name)) {
63                         return (c->c_val);
64                 }
65         }
66
67         return (-1);
68 }
69
70 /* Decode a symbolic name to a numeric value 
71  * this function is based on code
72  * Copyright (c) 1983, 1993
73  * The Regents of the University of California.  All rights reserved.
74  */
75 static int pencode(char *s)
76 {
77         char *save;
78         int lev, fac = LOG_USER;
79
80         for (save = s; *s && *s != '.'; ++s);
81         if (*s) {
82                 *s = '\0';
83                 fac = decode(save, facilitynames);
84                 if (fac < 0) {
85                         errorMsg("unknown facility name: %s\n", save);
86                         exit(FALSE);
87                 }
88                 *s++ = '.';
89         } else {
90                 s = save;
91         }
92         lev = decode(s, prioritynames);
93         if (lev < 0) {
94                 errorMsg("unknown priority name: %s\n", save);
95                 exit(FALSE);
96         }
97         return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
98 }
99
100
101 extern int logger_main(int argc, char **argv)
102 {
103         int pri = LOG_USER | LOG_NOTICE;
104         int option = 0;
105         int fromStdinFlag = FALSE;
106         int stopLookingAtMeLikeThat = FALSE;
107         char *message=NULL, buf[1024], name[128];
108
109         /* Fill out the name string early (may be overwritten later */
110         my_getpwuid(name, geteuid());
111
112         /* Parse any options */
113         while (--argc > 0 && **(++argv) == '-') {
114                 if (*((*argv) + 1) == '\0') {
115                         fromStdinFlag = TRUE;
116                 }
117                 stopLookingAtMeLikeThat = FALSE;
118                 while (*(++(*argv)) && stopLookingAtMeLikeThat == FALSE) {
119                         switch (**argv) {
120                         case 's':
121                                 option |= LOG_PERROR;
122                                 break;
123                         case 'p':
124                                 if (--argc == 0) {
125                                         usage(logger_usage);
126                                 }
127                                 pri = pencode(*(++argv));
128                                 stopLookingAtMeLikeThat = TRUE;
129                                 break;
130                         case 't':
131                                 if (--argc == 0) {
132                                         usage(logger_usage);
133                                 }
134                                 strncpy(name, *(++argv), sizeof(name));
135                                 stopLookingAtMeLikeThat = TRUE;
136                                 break;
137                         default:
138                                 usage(logger_usage);
139                         }
140                 }
141         }
142
143         if (fromStdinFlag == TRUE) {
144                 /* read from stdin */
145                 int c;
146                 unsigned int i = 0;
147
148                 while ((c = getc(stdin)) != EOF && i < sizeof(buf)) {
149                         buf[i++] = c;
150                 }
151                 message = buf;
152         } else {
153                 if (argc >= 1) {
154                         message = *argv;
155                 } else {
156                         errorMsg("No message\n");
157                         exit(FALSE);
158                 }
159         }
160
161         openlog(name, option, (pri | LOG_FACMASK));
162         syslog(pri, message);
163         closelog();
164
165         return(TRUE);
166 }