]> git.pld-linux.org Git - projects/rc-scripts.git/blame - src/initlog.c
pare zmian
[projects/rc-scripts.git] / src / initlog.c
CommitLineData
cee18a41
AM
1
2#include <errno.h>
3#include <fcntl.h>
4#include <libintl.h>
5#include <locale.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10
11#define SYSLOG_NAMES
12#include <syslog.h>
13
14#include <sys/stat.h>
15#include <sys/wait.h>
16
17#define _(String) gettext((String))
18
19#include <popt.h>
20
21#include "initlog.h"
22#include "process.h"
23
24static int logfacility=LOG_LOCAL7;
25static int logpriority=LOG_NOTICE;
26static int reexec=0;
27static int quiet=0;
28int debug=0;
29
30static int logEntries = 0;
31struct logInfo *logData = NULL;
32
33char *getLine(char **data) {
34 /* Get one line from data */
35 char *x, *y;
36
37 if (!*data) return NULL;
38
39 for (x = *data; *x && (*x != '\n'); x++);
40 if (*x) {
41 x++;
42 } else {
43 if (x-*data) {
44 y=malloc(x-*data+1);
45 y[x-*data] = 0;
46 y[x-*data-1] = '\n';
47 memcpy(y,*data,x-*data);
48 } else {
49 y=NULL;
50 }
51 *data = NULL;
52 return y;
53 }
54 y = malloc(x-*data);
55 y[x-*data-1] = 0;
56 memcpy(y,*data,x-*data-1);
57 *data = x;
58 return y;
59}
60
61char **toArray(char *line, int *num) {
62 /* Converts a long string into an array of lines. */
63 char **lines;
64 char *tmpline;
65
66 *num = 0;
67 lines = NULL;
68
69 while ((tmpline=getLine(&line))) {
70 if (!*num)
71 lines = (char **) malloc(sizeof(char *));
72 else
73 lines = (char **) realloc(lines, (*num+1)*sizeof(char *));
74 lines[*num] = tmpline;
75 (*num)++;
76 }
77 return lines;
78}
79
80int startDaemon() {
81 int pid;
82 int rc;
83
84 if ( (pid = fork()) == -1 ) {
85 perror("fork");
86 return -1;
87 }
88 if ( pid ) {
89 /* parent */
90 waitpid(pid,&rc,0);
91 if (WIFEXITED(rc)) {
92 DDEBUG("minilogd returned %d!\n",WEXITSTATUS(rc));
93 return WEXITSTATUS(rc);
94 }
95 else
96 return -1;
97 } else {
98 int fd;
99
100 fd=open("/dev/null",O_RDWR);
101 dup2(fd,0);
102 dup2(fd,1);
103 dup2(fd,2);
104 /* kid */
105 execlp("minilogd","minilogd",NULL);
106 perror("exec");
107 exit(-1);
108 }
109}
110
111int logLine(struct logInfo *logEnt) {
112 /* Logs a line... somewhere. */
113 int x=0,y=0,z=0;
114 struct stat statbuf;
115
116 /* Don't log empty or null lines */
117 if (!logEnt->line || !strcmp(logEnt->line,"\n")) return 0;
118
119 if ( ((stat(_PATH_LOG,&statbuf)==-1) ||(access("/",W_OK)==-1))
120 && startDaemon()
121 ) {
122 DDEBUG("starting daemon failed, pooling entry %d\n",logEntries);
123 logData=realloc(logData,(logEntries+1)*sizeof(struct logInfo));
124 logData[logEntries]= (*logEnt);
125 logEntries++;
126 } else {
127 if (logEntries>0) {
128 for (x=0;x<logEntries;x++) {
129 DDEBUG("flushing log entry %d =%s=\n",x,logData[x].line);
130 openlog(logData[x].cmd,0,logData[x].fac);
131 syslog(logData[x].pri,"%s",logData[x].line);
132 closelog();
133 }
134 free(logData);
135 logEntries = 0;
136 }
137 DDEBUG("logging =%s= via syslog\n",logEnt->line);
138 openlog(logEnt->cmd,0,logEnt->fac);
139 syslog(logEnt->pri,"%s",logEnt->line);
140 closelog();
141 }
142 return 0;
143}
144
145int logEvent(char *cmd, int eventtype,char *string) {
146 char *eventtable [] = {
147 _("%s babbles incoherently"),
148 _("%s succeeded"),
149 _("%s failed"),
150 _("%s cancelled at user request"),
151 _("%s failed due to a failed dependency"),
152 /* insert more here */
153 NULL
154 };
155 int x=0,len;
156 struct logInfo logentry;
157
158 if (cmd) {
159 logentry.cmd = strdup(basename(cmd));
160 if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
161 && ( 30 <= logentry.cmd[2] <= 39 ) )
162 logentry.cmd+=3;
163 } else
164 logentry.cmd = strdup(_("(none)"));
165 if (!string)
166 string = strdup(cmd);
167
168 while (eventtable[x] && x<eventtype) x++;
169 if (!(eventtable[x])) x=0;
170
171 len=strlen(eventtable[x])+strlen(string);
172 logentry.line=malloc(len);
173 snprintf(logentry.line,len,eventtable[x],string);
174
175 logentry.pri = logpriority;
176 logentry.fac = logfacility;
177
178 return logLine(&logentry);
179}
180
181int logString(char *cmd, char *string) {
182 struct logInfo logentry;
183
184 if (cmd) {
185 logentry.cmd = strdup(basename(cmd));
186 if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
187 && ( 30 <= logentry.cmd[2] <= 39 ) )
188 logentry.cmd+=3;
189 } else
190 logentry.cmd = strdup(_(""));
191 logentry.line = strdup(string);
192 logentry.pri = logpriority;
193 logentry.fac = logfacility;
194
195 return logLine(&logentry);
196}
197
198int processArgs(int argc, char **argv, int silent) {
199 char *cmdname=NULL;
200 int cmdevent=0;
201 char *cmd=NULL;
202 char *logstring=NULL;
203 char *fac=NULL,*pri=NULL;
204 poptContext context;
205 int rc;
206 struct poptOption optTable[] = {
207 POPT_AUTOHELP
208 { "name", 'n', POPT_ARG_STRING, &cmdname, 0,
209 "name of service being logged", NULL
210 },
211 { "event", 'e', POPT_ARG_INT, &cmdevent, 0,
212 "event being logged (see man page)", NULL
213 },
214 { "cmd", 'c', POPT_ARG_STRING, &cmd, 0,
215 "command to run, logging output", NULL
216 },
217 { "debug", 'd', POPT_ARG_NONE, &debug, 0,
218 "print lots of verbose debugging info", NULL
219 },
220 { "run", 'r', POPT_ARG_STRING, &cmd, 3,
221 "command to run, accepting input on open fd", NULL
222 },
223 { "string", 's', POPT_ARG_STRING, &logstring, 0,
224 "string to log", NULL
225 },
226 { "facility", 'f', POPT_ARG_STRING, &fac, 1,
227 "facility to log at (default: 'daemon')", NULL
228 },
229 { "priority", 'p', POPT_ARG_STRING, &pri, 2,
230 "priority to log at (default: 'notice')", NULL
231 },
232 { "quiet", 'q', POPT_ARG_NONE, &quiet, 0,
233 "suppress stdout/stderr", NULL
234 },
235 { 0, 0, 0, 0, 0, 0 }
236 };
237
238 context = poptGetContext("initlog", argc, argv, optTable, 0);
239
240 while ((rc = poptGetNextOpt(context)) > 0) {
241 switch (rc) {
242 case 1:
243 logfacility=atoi(fac);
244 if ((logfacility == 0) && strcmp(fac,"0")) {
245 int x =0;
246
247 logfacility = LOG_DAEMON;
248 for (x=0;facilitynames[x].c_name;x++) {
249 if (!strcmp(fac,facilitynames[x].c_name)) {
250 logfacility = facilitynames[x].c_val;
251 break;
252 }
253 }
254 }
255 break;
256 case 2:
257 logpriority = atoi(pri);
258 if ((logpriority == 0) && strcmp(pri,"0")) {
259 int x=0;
260
261 logpriority = LOG_NOTICE;
262 for (x=0;prioritynames[x].c_name;x++) {
263 if (!strcmp(pri,prioritynames[x].c_name)) {
264 logpriority = prioritynames[x].c_val;
265 break;
266 }
267 }
268 }
269 break;
270 case 3:
271 reexec = 1;
272 break;
273 default:
274 break;
275 }
276 }
277
278 if ((rc < -1)) {
279 if (!silent)
280 fprintf(stderr, "%s: %s\n",
281 poptBadOption(context, POPT_BADOPTION_NOALIAS),
282 poptStrerror(rc));
283
284 return -1;
285 }
286 if ( (cmd && logstring) || (cmd && cmdname) ) {
287 if (!silent)
288 fprintf(stderr, _("--cmd and --run are incompatible with --string or --name\n"));
289 return -1;
290 }
291 if ( cmdname && (!logstring && !cmdevent)) {
292 if (!silent)
293 fprintf(stderr, _("--name requires one of --event or --string\n"));
294 return -1;
295 }
296 if (cmdevent) {
297 logEvent(cmdname,cmdevent,logstring);
298 } else if (logstring) {
299 logString(cmdname,logstring);
300 } else if ( cmd ) {
301 return(runCommand(cmd,reexec,quiet,debug));
302 } else {
303 if (!silent)
304 fprintf(stderr,"nothing to do!\n");
305 return -1;
306 }
307 return 0;
308}
309
310int main(int argc, char **argv) {
311
312 setlocale(LC_ALL,"");
313 bindtextdomain("initlog","/etc/locale");
314 textdomain("initlog");
315 exit(processArgs(argc,argv,0));
316}
This page took 0.054796 seconds and 4 git commands to generate.