]> git.pld-linux.org Git - projects/rc-scripts.git/blame - src/initlog.c
added abilities for setup static RARP table by
[projects/rc-scripts.git] / src / initlog.c
CommitLineData
458f14b7 1/* $Id: initlog.c,v 1.3 1999/12/15 18:41:08 misiek Exp $ */
cee18a41
AM
2
3#include <errno.h>
4#include <fcntl.h>
5#include <libintl.h>
6#include <locale.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12#define SYSLOG_NAMES
13#include <syslog.h>
14
15#include <sys/stat.h>
16#include <sys/wait.h>
17
18#define _(String) gettext((String))
19
20#include <popt.h>
21
458f14b7
AM
22#include <regex.h>
23
cee18a41
AM
24#include "initlog.h"
25#include "process.h"
26
458f14b7 27static int logfacility=LOG_DAEMON;
cee18a41
AM
28static int logpriority=LOG_NOTICE;
29static int reexec=0;
30static int quiet=0;
31int debug=0;
32
458f14b7
AM
33regex_t **regList = NULL;
34
cee18a41
AM
35static int logEntries = 0;
36struct logInfo *logData = NULL;
37
458f14b7
AM
38void readConfiguration(char *fname) {
39 int fd,num=0;
40 struct stat sbuf;
41 char *data,*line;
42 regex_t *regexp;
43 int lfac=-1,lpri=-1;
44
45 if ((fd=open(fname,O_RDONLY))==-1) return;
46 if (fstat(fd,&sbuf)) {
47 close(fd);
48 return;
49 }
50 data=malloc(sbuf.st_size+1);
51 if (read(fd,data,sbuf.st_size)!=sbuf.st_size) {
52 close(fd);
53 return;
54 }
55 close(fd);
56 data[sbuf.st_size] = '\0';
57 while ((line=getLine(&data))) {
58 if (line[0]=='#') continue;
59 if (!strncmp(line,"ignore ",7)) {
60 regexp = malloc(sizeof(regex_t));
61 if (!regcomp(regexp,line+7,REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) {
62 regList = realloc(regList,(num+2) * sizeof(regex_t *));
63 regList[num] = regexp;
64 regList[num+1] = NULL;
65 num++;
66 }
67 }
68 if (!strncmp(line,"facility ",9)) {
69 lfac=atoi(line+9);
70 if ((lfac == 0) && strcmp(line+9,"0")) {
71 int x =0;
72
73 lfac = LOG_DAEMON;
74 for (x=0;facilitynames[x].c_name;x++) {
75 if (!strcmp(line+9,facilitynames[x].c_name)) {
76 lfac = facilitynames[x].c_val;
77 break;
78 }
79 }
80 }
81 }
82 if (!strncmp(line,"priority ",9)) {
83 lpri = atoi(line+9);
84 if ((lpri == 0) && strcmp(line+9,"0")) {
85 int x=0;
86
87 lpri = LOG_NOTICE;
88 for (x=0;prioritynames[x].c_name;x++) {
89 if (!strcmp(line+9,prioritynames[x].c_name)) {
90 lpri = prioritynames[x].c_val;
91 break;
92 }
93 }
94 }
95 }
96 }
97 if (lfac!=-1) logfacility=lfac;
98 if (lpri!=-1) logpriority=lpri;
99}
100
cee18a41
AM
101char *getLine(char **data) {
102 /* Get one line from data */
458f14b7
AM
103 /* Anything up to a carraige return (\r) or a backspace (\b) is discarded. */
104 /* If this really bothers you, mail me and I might make it configurable. */
105 /* It's here to avoid confilcts with fsck's progress bar. */
cee18a41
AM
106 char *x, *y;
107
108 if (!*data) return NULL;
458f14b7
AM
109 x=*data;
110 while (*x && (*x != '\n')) {
111 while (*x && (*x != '\n') && (*x != '\r') && (*x != '\b')) x++;
112 if (*x && (*x=='\r' || *x =='\b')) {
113 *data = x+1;
114 x++;
115 }
116 }
cee18a41
AM
117 if (*x) {
118 x++;
119 } else {
120 if (x-*data) {
121 y=malloc(x-*data+1);
122 y[x-*data] = 0;
123 y[x-*data-1] = '\n';
124 memcpy(y,*data,x-*data);
125 } else {
126 y=NULL;
127 }
128 *data = NULL;
129 return y;
130 }
131 y = malloc(x-*data);
132 y[x-*data-1] = 0;
133 memcpy(y,*data,x-*data-1);
134 *data = x;
135 return y;
136}
137
138char **toArray(char *line, int *num) {
139 /* Converts a long string into an array of lines. */
140 char **lines;
141 char *tmpline;
142
143 *num = 0;
144 lines = NULL;
145
146 while ((tmpline=getLine(&line))) {
147 if (!*num)
148 lines = (char **) malloc(sizeof(char *));
149 else
150 lines = (char **) realloc(lines, (*num+1)*sizeof(char *));
151 lines[*num] = tmpline;
152 (*num)++;
153 }
154 return lines;
155}
156
157int startDaemon() {
158 int pid;
159 int rc;
160
161 if ( (pid = fork()) == -1 ) {
162 perror("fork");
163 return -1;
164 }
165 if ( pid ) {
166 /* parent */
167 waitpid(pid,&rc,0);
168 if (WIFEXITED(rc)) {
169 DDEBUG("minilogd returned %d!\n",WEXITSTATUS(rc));
170 return WEXITSTATUS(rc);
171 }
172 else
173 return -1;
174 } else {
175 int fd;
176
177 fd=open("/dev/null",O_RDWR);
178 dup2(fd,0);
179 dup2(fd,1);
180 dup2(fd,2);
181 /* kid */
182 execlp("minilogd","minilogd",NULL);
183 perror("exec");
184 exit(-1);
185 }
186}
187
188int logLine(struct logInfo *logEnt) {
189 /* Logs a line... somewhere. */
458f14b7 190 int x;
cee18a41
AM
191 struct stat statbuf;
192
193 /* Don't log empty or null lines */
194 if (!logEnt->line || !strcmp(logEnt->line,"\n")) return 0;
195
196 if ( ((stat(_PATH_LOG,&statbuf)==-1) ||(access("/",W_OK)==-1))
197 && startDaemon()
198 ) {
199 DDEBUG("starting daemon failed, pooling entry %d\n",logEntries);
200 logData=realloc(logData,(logEntries+1)*sizeof(struct logInfo));
201 logData[logEntries]= (*logEnt);
202 logEntries++;
203 } else {
204 if (logEntries>0) {
205 for (x=0;x<logEntries;x++) {
206 DDEBUG("flushing log entry %d =%s=\n",x,logData[x].line);
207 openlog(logData[x].cmd,0,logData[x].fac);
208 syslog(logData[x].pri,"%s",logData[x].line);
209 closelog();
210 }
211 free(logData);
212 logEntries = 0;
213 }
214 DDEBUG("logging =%s= via syslog\n",logEnt->line);
215 openlog(logEnt->cmd,0,logEnt->fac);
216 syslog(logEnt->pri,"%s",logEnt->line);
217 closelog();
218 }
219 return 0;
220}
221
222int logEvent(char *cmd, int eventtype,char *string) {
223 char *eventtable [] = {
224 _("%s babbles incoherently"),
225 _("%s succeeded"),
226 _("%s failed"),
227 _("%s cancelled at user request"),
228 _("%s failed due to a failed dependency"),
229 /* insert more here */
230 NULL
231 };
232 int x=0,len;
233 struct logInfo logentry;
234
235 if (cmd) {
7743173d 236 logentry.cmd = strdup((char *)basename(cmd));
cee18a41
AM
237 if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
238 && ( 30 <= logentry.cmd[2] <= 39 ) )
239 logentry.cmd+=3;
240 } else
241 logentry.cmd = strdup(_("(none)"));
242 if (!string)
243 string = strdup(cmd);
244
245 while (eventtable[x] && x<eventtype) x++;
246 if (!(eventtable[x])) x=0;
247
248 len=strlen(eventtable[x])+strlen(string);
249 logentry.line=malloc(len);
250 snprintf(logentry.line,len,eventtable[x],string);
251
252 logentry.pri = logpriority;
253 logentry.fac = logfacility;
254
255 return logLine(&logentry);
256}
257
258int logString(char *cmd, char *string) {
259 struct logInfo logentry;
260
261 if (cmd) {
7743173d 262 logentry.cmd = strdup((char *)basename(cmd));
cee18a41
AM
263 if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
264 && ( 30 <= logentry.cmd[2] <= 39 ) )
265 logentry.cmd+=3;
266 } else
267 logentry.cmd = strdup(_(""));
268 logentry.line = strdup(string);
269 logentry.pri = logpriority;
270 logentry.fac = logfacility;
271
272 return logLine(&logentry);
273}
274
275int processArgs(int argc, char **argv, int silent) {
276 char *cmdname=NULL;
458f14b7 277 char *conffile=NULL;
cee18a41
AM
278 int cmdevent=0;
279 char *cmd=NULL;
280 char *logstring=NULL;
281 char *fac=NULL,*pri=NULL;
458f14b7 282 int lfac=-1, lpri=-1;
cee18a41
AM
283 poptContext context;
284 int rc;
285 struct poptOption optTable[] = {
286 POPT_AUTOHELP
458f14b7
AM
287 { "conf", 0, POPT_ARG_STRING, &conffile, 0,
288 "configuration file (default: /etc/initlog.conf)", NULL
289 },
cee18a41
AM
290 { "name", 'n', POPT_ARG_STRING, &cmdname, 0,
291 "name of service being logged", NULL
292 },
293 { "event", 'e', POPT_ARG_INT, &cmdevent, 0,
294 "event being logged (see man page)", NULL
295 },
296 { "cmd", 'c', POPT_ARG_STRING, &cmd, 0,
297 "command to run, logging output", NULL
298 },
299 { "debug", 'd', POPT_ARG_NONE, &debug, 0,
300 "print lots of verbose debugging info", NULL
301 },
302 { "run", 'r', POPT_ARG_STRING, &cmd, 3,
303 "command to run, accepting input on open fd", NULL
304 },
305 { "string", 's', POPT_ARG_STRING, &logstring, 0,
306 "string to log", NULL
307 },
308 { "facility", 'f', POPT_ARG_STRING, &fac, 1,
458f14b7 309 "facility to log at (default: 'local7')", NULL
cee18a41
AM
310 },
311 { "priority", 'p', POPT_ARG_STRING, &pri, 2,
312 "priority to log at (default: 'notice')", NULL
313 },
314 { "quiet", 'q', POPT_ARG_NONE, &quiet, 0,
315 "suppress stdout/stderr", NULL
316 },
317 { 0, 0, 0, 0, 0, 0 }
318 };
319
320 context = poptGetContext("initlog", argc, argv, optTable, 0);
321
322 while ((rc = poptGetNextOpt(context)) > 0) {
323 switch (rc) {
324 case 1:
458f14b7
AM
325 lfac=atoi(fac);
326 if ((lfac == 0) && strcmp(fac,"0")) {
cee18a41
AM
327 int x =0;
328
458f14b7 329 lfac = LOG_DAEMON;
cee18a41
AM
330 for (x=0;facilitynames[x].c_name;x++) {
331 if (!strcmp(fac,facilitynames[x].c_name)) {
458f14b7 332 lfac = facilitynames[x].c_val;
cee18a41
AM
333 break;
334 }
335 }
336 }
337 break;
338 case 2:
458f14b7
AM
339 lpri = atoi(pri);
340 if ((lpri == 0) && strcmp(pri,"0")) {
cee18a41
AM
341 int x=0;
342
458f14b7 343 lpri = LOG_NOTICE;
cee18a41
AM
344 for (x=0;prioritynames[x].c_name;x++) {
345 if (!strcmp(pri,prioritynames[x].c_name)) {
458f14b7 346 lpri = prioritynames[x].c_val;
cee18a41
AM
347 break;
348 }
349 }
350 }
351 break;
352 case 3:
353 reexec = 1;
354 break;
355 default:
356 break;
357 }
358 }
359
360 if ((rc < -1)) {
361 if (!silent)
362 fprintf(stderr, "%s: %s\n",
363 poptBadOption(context, POPT_BADOPTION_NOALIAS),
364 poptStrerror(rc));
365
366 return -1;
367 }
368 if ( (cmd && logstring) || (cmd && cmdname) ) {
369 if (!silent)
370 fprintf(stderr, _("--cmd and --run are incompatible with --string or --name\n"));
371 return -1;
372 }
373 if ( cmdname && (!logstring && !cmdevent)) {
374 if (!silent)
375 fprintf(stderr, _("--name requires one of --event or --string\n"));
376 return -1;
377 }
458f14b7
AM
378 if (conffile) {
379 readConfiguration(conffile);
380 } else {
381 readConfiguration("/etc/initlog.conf");
382 }
383 if (lpri!=-1) logpriority=lpri;
384 if (lfac!=-1) logfacility=lfac;
cee18a41
AM
385 if (cmdevent) {
386 logEvent(cmdname,cmdevent,logstring);
387 } else if (logstring) {
388 logString(cmdname,logstring);
389 } else if ( cmd ) {
390 return(runCommand(cmd,reexec,quiet,debug));
391 } else {
392 if (!silent)
393 fprintf(stderr,"nothing to do!\n");
394 return -1;
395 }
396 return 0;
397}
398
399int main(int argc, char **argv) {
400
401 setlocale(LC_ALL,"");
402 bindtextdomain("initlog","/etc/locale");
403 textdomain("initlog");
404 exit(processArgs(argc,argv,0));
405}
This page took 0.089874 seconds and 4 git commands to generate.