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