aboutsummaryrefslogtreecommitdiff
path: root/logger.c
diff options
context:
space:
mode:
Diffstat (limited to 'logger.c')
-rw-r--r--logger.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/logger.c b/logger.c
new file mode 100644
index 000000000..0683838cc
--- /dev/null
+++ b/logger.c
@@ -0,0 +1,186 @@
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 <sys/socket.h>
26#include <sys/un.h>
27#include <unistd.h>
28#include <time.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <signal.h>
33#include <ctype.h>
34#include <netdb.h>
35
36#if !defined BB_SYSLOGD
37
38#define SYSLOG_NAMES
39#include <sys/syslog.h>
40
41#else
42/* We have to do this since the header file defines static
43 * structues. Argh.... bad libc, bad, bad...
44 */
45#include <sys/syslog.h>
46typedef struct _code {
47 char *c_name;
48 int c_val;
49} CODE;
50extern CODE prioritynames[];
51extern CODE facilitynames[];
52#endif
53
54static const char logger_usage[] =
55 "logger [OPTION]... [MESSAGE]\n\n"
56 "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n"
57 "Options:\n"
58 "\t-s\tLog to stderr as well as the system log.\n"
59 "\t-p\tEnter the message with the specified priority.\n"
60 "\t\tThis may be numerical or a ``facility.level'' pair.\n";
61
62
63/* Decode a symbolic name to a numeric value
64 * this function is based on code
65 * Copyright (c) 1983, 1993
66 * The Regents of the University of California. All rights reserved.
67 */
68static int
69decode(char* name, CODE* codetab)
70{
71 CODE *c;
72
73 if (isdigit(*name))
74 return (atoi(name));
75 for (c = codetab; c->c_name; c++) {
76 if (!strcasecmp(name, c->c_name)) {
77 return (c->c_val);
78 }
79 }
80
81 return (-1);
82}
83
84/* Decode a symbolic name to a numeric value
85 * this function is based on code
86 * Copyright (c) 1983, 1993
87 * The Regents of the University of California. All rights reserved.
88 */
89static int
90pencode(char* s)
91{
92 char *save;
93 int lev, fac=LOG_USER;
94
95 for (save = s; *s && *s != '.'; ++s);
96 if (*s) {
97 *s = '\0';
98 fac = decode(save, facilitynames);
99 if (fac < 0) {
100 fprintf(stderr, "unknown facility name: %s\n", save);
101 exit( FALSE);
102 }
103 *s++ = '.';
104 }
105 else {
106 s = save;
107 }
108 lev = decode(s, prioritynames);
109 if (lev < 0) {
110 fprintf(stderr, "unknown priority name: %s\n", save);
111 exit( FALSE);
112 }
113 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
114}
115
116
117extern int logger_main(int argc, char **argv)
118{
119 struct sockaddr_un sunx;
120 int fd, pri = LOG_USER|LOG_NOTICE;
121 int toStdErrFlag=FALSE;
122 char *message, buf[1024];
123 time_t now;
124 size_t addrLength;
125
126 /* Parse any options */
127 while (--argc > 0 && **(++argv) == '-') {
128 while (*(++(*argv))) {
129 switch (**argv) {
130 case 's':
131 toStdErrFlag = TRUE;
132 break;
133 case 'p':
134 if (--argc == 0) {
135 usage(logger_usage);
136 }
137 pri = pencode(*(++argv));
138 if (--argc == 0) {
139 usage(logger_usage);
140 }
141 ++argv;
142 break;
143 default:
144 usage(logger_usage);
145 }
146 }
147 }
148
149 if (argc>=1)
150 if (**argv=='-') {
151 /* read from stdin */
152 } else {
153 message=*argv;
154 }
155 else {
156 fprintf(stderr, "No message\n");
157 exit( FALSE);
158 }
159
160 memset(&sunx, 0, sizeof(sunx));
161 sunx.sun_family = AF_UNIX; /* Unix domain socket */
162 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
163 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
164 perror("Couldn't obtain descriptor for socket " _PATH_LOG);
165 exit( FALSE);
166 }
167
168 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
169
170 if (connect(fd, (struct sockaddr *) &sunx, addrLength)) {
171 perror("Could not connect to socket " _PATH_LOG);
172 exit( FALSE);
173 }
174
175 time(&now);
176 snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message);
177
178 if (toStdErrFlag==TRUE)
179 fprintf(stderr, "%s\n", buf);
180
181 write( fd, buf, sizeof(buf));
182
183 close(fd);
184 exit( TRUE);
185}
186