#include #include #include #include #include #include #include #include #define SYSLOG_NAMES #include #include #include #define _(String) gettext((String)) #include #include "initlog.h" #include "process.h" static int logfacility=LOG_LOCAL7; static int logpriority=LOG_NOTICE; static int reexec=0; static int quiet=0; int debug=0; static int logEntries = 0; struct logInfo *logData = NULL; char *getLine(char **data) { /* Get one line from data */ char *x, *y; if (!*data) return NULL; for (x = *data; *x && (*x != '\n'); x++); if (*x) { x++; } else { if (x-*data) { y=malloc(x-*data+1); y[x-*data] = 0; y[x-*data-1] = '\n'; memcpy(y,*data,x-*data); } else { y=NULL; } *data = NULL; return y; } y = malloc(x-*data); y[x-*data-1] = 0; memcpy(y,*data,x-*data-1); *data = x; return y; } char **toArray(char *line, int *num) { /* Converts a long string into an array of lines. */ char **lines; char *tmpline; *num = 0; lines = NULL; while ((tmpline=getLine(&line))) { if (!*num) lines = (char **) malloc(sizeof(char *)); else lines = (char **) realloc(lines, (*num+1)*sizeof(char *)); lines[*num] = tmpline; (*num)++; } return lines; } int startDaemon() { int pid; int rc; if ( (pid = fork()) == -1 ) { perror("fork"); return -1; } if ( pid ) { /* parent */ waitpid(pid,&rc,0); if (WIFEXITED(rc)) { DDEBUG("minilogd returned %d!\n",WEXITSTATUS(rc)); return WEXITSTATUS(rc); } else return -1; } else { int fd; fd=open("/dev/null",O_RDWR); dup2(fd,0); dup2(fd,1); dup2(fd,2); /* kid */ execlp("minilogd","minilogd",NULL); perror("exec"); exit(-1); } } int logLine(struct logInfo *logEnt) { /* Logs a line... somewhere. */ int x=0,y=0,z=0; struct stat statbuf; /* Don't log empty or null lines */ if (!logEnt->line || !strcmp(logEnt->line,"\n")) return 0; if ( ((stat(_PATH_LOG,&statbuf)==-1) ||(access("/",W_OK)==-1)) && startDaemon() ) { DDEBUG("starting daemon failed, pooling entry %d\n",logEntries); logData=realloc(logData,(logEntries+1)*sizeof(struct logInfo)); logData[logEntries]= (*logEnt); logEntries++; } else { if (logEntries>0) { for (x=0;xline); openlog(logEnt->cmd,0,logEnt->fac); syslog(logEnt->pri,"%s",logEnt->line); closelog(); } return 0; } int logEvent(char *cmd, int eventtype,char *string) { char *eventtable [] = { _("%s babbles incoherently"), _("%s succeeded"), _("%s failed"), _("%s cancelled at user request"), _("%s failed due to a failed dependency"), /* insert more here */ NULL }; int x=0,len; struct logInfo logentry; if (cmd) { logentry.cmd = strdup(basename(cmd)); if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 ) && ( 30 <= logentry.cmd[2] <= 39 ) ) logentry.cmd+=3; } else logentry.cmd = strdup(_("(none)")); if (!string) string = strdup(cmd); while (eventtable[x] && x 0) { switch (rc) { case 1: logfacility=atoi(fac); if ((logfacility == 0) && strcmp(fac,"0")) { int x =0; logfacility = LOG_DAEMON; for (x=0;facilitynames[x].c_name;x++) { if (!strcmp(fac,facilitynames[x].c_name)) { logfacility = facilitynames[x].c_val; break; } } } break; case 2: logpriority = atoi(pri); if ((logpriority == 0) && strcmp(pri,"0")) { int x=0; logpriority = LOG_NOTICE; for (x=0;prioritynames[x].c_name;x++) { if (!strcmp(pri,prioritynames[x].c_name)) { logpriority = prioritynames[x].c_val; break; } } } break; case 3: reexec = 1; break; default: break; } } if ((rc < -1)) { if (!silent) fprintf(stderr, "%s: %s\n", poptBadOption(context, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); return -1; } if ( (cmd && logstring) || (cmd && cmdname) ) { if (!silent) fprintf(stderr, _("--cmd and --run are incompatible with --string or --name\n")); return -1; } if ( cmdname && (!logstring && !cmdevent)) { if (!silent) fprintf(stderr, _("--name requires one of --event or --string\n")); return -1; } if (cmdevent) { logEvent(cmdname,cmdevent,logstring); } else if (logstring) { logString(cmdname,logstring); } else if ( cmd ) { return(runCommand(cmd,reexec,quiet,debug)); } else { if (!silent) fprintf(stderr,"nothing to do!\n"); return -1; } return 0; } int main(int argc, char **argv) { setlocale(LC_ALL,""); bindtextdomain("initlog","/etc/locale"); textdomain("initlog"); exit(processArgs(argc,argv,0)); }