]> git.pld-linux.org Git - projects/rc-scripts.git/blobdiff - src/initlog.c
netfs: respect VSERVER_ISOLATION_NET here as well
[projects/rc-scripts.git] / src / initlog.c
index d3fe00c2a3b8cfa174fce807a8974c665f5f9985..3b1cded633749466474784beab38cf2da6c0e29e 100644 (file)
@@ -1,5 +1,16 @@
-/* $Id: initlog.c,v 1.2 1999/09/02 12:11:06 misiek Exp $ */
+/*
+ * Copyright (c) 1999-2003 Red Hat, Inc. All rights reserved.
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <libintl.h>
 #define SYSLOG_NAMES
 #include <syslog.h>
 
+#include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/un.h>
 #include <sys/wait.h>
 
 #define _(String) gettext((String))
 
 #include <popt.h>
 
+#include <regex.h>
+
 #include "initlog.h"
 #include "process.h"
 
-static int logfacility=LOG_LOCAL7;
+static int logfacility=LOG_DAEMON;
 static int logpriority=LOG_NOTICE;
 static int reexec=0;
 static int quiet=0;
 int debug=0;
 
+regex_t  **regList = NULL;
+
 static int logEntries = 0;
 struct logInfo *logData = NULL;
 
+void readConfiguration(char *fname) {
+    int fd,num=0;
+    struct stat sbuf;
+    char *data,*line;
+    regex_t *regexp;
+    int lfac=-1,lpri=-1;
+    
+    if ((fd=open(fname,O_RDONLY))==-1) return;
+    if (fstat(fd,&sbuf)) {
+           close(fd);
+           return;
+    }
+    data=malloc(sbuf.st_size+1);
+    if (read(fd,data,sbuf.st_size)!=sbuf.st_size) {
+           close(fd);
+           free(data);
+           return;
+    }
+    close(fd);
+    data[sbuf.st_size] = '\0';
+    while ((line=getLine(&data))) {
+       if (line[0]=='#') continue;
+       if (!strncmp(line,"ignore ",7)) {
+           regexp = malloc(sizeof(regex_t));
+           if (!regcomp(regexp,line+7,REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) {
+               regList = realloc(regList,(num+2) * sizeof(regex_t *));
+               regList[num] = regexp;
+               regList[num+1] = NULL;
+               num++;
+           }
+       }
+       if (!strncmp(line,"facility ",9)) {
+           lfac=atoi(line+9);
+           if ((lfac == 0) && strcmp(line+9,"0")) {
+               int x =0;
+               
+               lfac = LOG_DAEMON;
+               for (x=0;facilitynames[x].c_name;x++) {
+                   if (!strcmp(line+9,facilitynames[x].c_name)) {
+                       lfac = facilitynames[x].c_val;
+                       break;
+                   }
+               }
+           }
+       }
+       if (!strncmp(line,"priority ",9)) {
+           lpri = atoi(line+9);
+           if ((lpri == 0) && strcmp(line+9,"0")) {
+               int x=0;
+               
+               lpri = LOG_NOTICE;
+               for (x=0;prioritynames[x].c_name;x++) {
+                   if (!strcmp(line+9,prioritynames[x].c_name)) {
+                       lpri = prioritynames[x].c_val;
+                       break;
+                   }
+               }
+           }
+       }
+    }
+    if (lfac!=-1) logfacility=lfac;
+    if (lpri!=-1) logpriority=lpri;
+}
+    
 char *getLine(char **data) {
     /* Get one line from data */
+    /* Anything up to a carraige return (\r) or a backspace (\b) is discarded. */
+    /* If this really bothers you, mail me and I might make it configurable. */
+    /* It's here to avoid confilcts with fsck's progress bar. */
     char *x, *y;
     
     if (!*data) return NULL;
-    
-    for (x = *data; *x && (*x != '\n'); x++);
+    x=*data;
+    while (*x && (*x != '\n')) {
+       while (*x && (*x != '\n') && (*x != '\r') && (*x != '\b')) x++;
+       if (*x && (*x=='\r' || *x =='\b')) {
+               *data = x+1;
+               x++;
+       }
+    }
     if (*x) {
        x++;
     } else {
@@ -102,6 +192,7 @@ int startDaemon() {
        dup2(fd,0);
        dup2(fd,1);
        dup2(fd,2);
+        close(fd);
        /* kid */
        execlp("minilogd","minilogd",NULL);
        perror("exec");
@@ -109,15 +200,50 @@ int startDaemon() {
     }
 }
 
+int trySocket() {
+       int s;
+       struct sockaddr_un addr;
+       
+       s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+       if (s<0)
+         return 1;
+   
+       bzero(&addr,sizeof(addr));
+       addr.sun_family = AF_LOCAL;
+       strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
+
+       if (connect(s,(struct sockaddr *) &addr,sizeof(addr))<0) {
+               if (errno == EPROTOTYPE || errno == ECONNREFUSED) {
+                       DDEBUG("connect failed (EPROTOTYPE), trying stream\n");
+                       close(s);
+                       s = socket(AF_LOCAL, SOCK_STREAM, 0);
+                       if (connect(s,(struct sockaddr *) &addr, sizeof(addr)) < 0) {
+                               DDEBUG("connect failed: %s\n",strerror(errno));
+                               close(s);
+                               return 1;
+                       } 
+                       close(s);
+                       return 0;
+               }
+               close(s);
+               DDEBUG("connect failed: %s\n",strerror(errno));
+               return 1;
+       } else {
+               close(s);
+               return 0;
+       }
+}
+
 int logLine(struct logInfo *logEnt) {
     /* Logs a line... somewhere. */
-    int x=0,y=0,z=0;
+    int x;
     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))
+       
+    if  ( ((stat(_PATH_LOG,&statbuf)==-1) || trySocket())
          && startDaemon()
        ) {
        DDEBUG("starting daemon failed, pooling entry %d\n",logEntries);
@@ -157,9 +283,10 @@ int logEvent(char *cmd, int eventtype,char *string) {
     struct logInfo logentry;
     
     if (cmd) {
-       logentry.cmd = strdup((char *)basename(cmd));
-       if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
-           && ( 30 <= logentry.cmd[2] <= 39 ) )
+       logentry.cmd = strdup(basename(cmd));
+       if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') &&
+           ( logentry.cmd[1] >= '0' && logentry.cmd[1] <= '9' ) &&
+           ( logentry.cmd[2] >= '0' && logentry.cmd[2] <= '9' ) )
          logentry.cmd+=3;
     } else
       logentry.cmd = strdup(_("(none)"));
@@ -183,9 +310,10 @@ int logString(char *cmd, char *string) {
     struct logInfo logentry;
     
     if (cmd) {
-       logentry.cmd = strdup((char *)basename(cmd));
-       if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && ( 30 <= logentry.cmd[1] <= 39 )
-           && ( 30 <= logentry.cmd[2] <= 39 ) )
+       logentry.cmd = strdup(basename(cmd));
+       if ((logentry.cmd[0] =='K' || logentry.cmd[0] == 'S') && 
+           ( logentry.cmd[1] >= '0' && logentry.cmd[1] <= 0x39 ) &&
+           ( logentry.cmd[2] >= '0' && logentry.cmd[2] <= 0x39 ) )
          logentry.cmd+=3;
     } else
       logentry.cmd = strdup(_(""));
@@ -198,14 +326,19 @@ int logString(char *cmd, char *string) {
 
 int processArgs(int argc, char **argv, int silent) {
     char *cmdname=NULL;
+    char *conffile=NULL;
     int cmdevent=0;
     char *cmd=NULL;
     char *logstring=NULL;
     char *fac=NULL,*pri=NULL;
+    int lfac=-1, lpri=-1;
     poptContext context;
     int rc;
     struct poptOption optTable[] = {
        POPT_AUTOHELP
+       { "conf", 0, POPT_ARG_STRING, &conffile, 0,
+         "configuration file (default: /etc/initlog.conf)", NULL
+       },
        { "name", 'n', POPT_ARG_STRING, &cmdname, 0,
          "name of service being logged", NULL 
        },
@@ -225,7 +358,7 @@ int processArgs(int argc, char **argv, int silent) {
          "string to log", NULL
        },
        { "facility", 'f', POPT_ARG_STRING, &fac, 1,
-         "facility to log at (default: 'daemon')", NULL
+         "facility to log at (default: 'local7')", NULL
        },
        { "priority", 'p', POPT_ARG_STRING, &pri, 2,
          "priority to log at (default: 'notice')", NULL
@@ -241,28 +374,28 @@ int processArgs(int argc, char **argv, int silent) {
     while ((rc = poptGetNextOpt(context)) > 0) {
        switch (rc) {
         case 1:
-           logfacility=atoi(fac);
-           if ((logfacility == 0) && strcmp(fac,"0")) {
+           lfac=atoi(fac);
+           if ((lfac == 0) && strcmp(fac,"0")) {
                int x =0;
                
-               logfacility = LOG_DAEMON;
+               lfac = LOG_DAEMON;
                for (x=0;facilitynames[x].c_name;x++) {
                    if (!strcmp(fac,facilitynames[x].c_name)) {
-                       logfacility = facilitynames[x].c_val;
+                       lfac = facilitynames[x].c_val;
                        break;
                    }
                }
            }
            break;
         case 2:
-           logpriority = atoi(pri);
-           if ((logpriority == 0) && strcmp(pri,"0")) {
+           lpri = atoi(pri);
+           if ((lpri == 0) && strcmp(pri,"0")) {
                int x=0;
                
-               logpriority = LOG_NOTICE;
+               lpri = LOG_NOTICE;
                for (x=0;prioritynames[x].c_name;x++) {
                    if (!strcmp(pri,prioritynames[x].c_name)) {
-                       logpriority = prioritynames[x].c_val;
+                       lpri = prioritynames[x].c_val;
                        break;
                    }
                }
@@ -294,11 +427,26 @@ int processArgs(int argc, char **argv, int silent) {
         fprintf(stderr, _("--name requires one of --event or --string\n"));
        return -1;
     }
+    if (cmdevent && cmd) {
+           if (!silent)
+             fprintf(stderr, _("--cmd and --run are incompatible with --event\n"));
+           return -1;
+    }
+    if (conffile) {
+       readConfiguration(conffile);
+    } else {
+       readConfiguration("/etc/initlog.conf");
+    }
+    if (cmd) {
+           while (isspace(*cmd)) cmd++;
+    }
+    if (lpri!=-1) logpriority=lpri;
+    if (lfac!=-1) logfacility=lfac;
     if (cmdevent) {
        logEvent(cmdname,cmdevent,logstring);
     } else if (logstring) {
        logString(cmdname,logstring);
-    } else if ( cmd ) {
+    } else if ( cmd && *cmd) {
        return(runCommand(cmd,reexec,quiet,debug));
     } else {
         if (!silent)
This page took 0.095618 seconds and 4 git commands to generate.