I've written the following patch to allow syslogd to accept multiple
configuration files by passing multiple -f options.  One use case for
this is to specify a common configuration file that applies across
multiple machines along with a second config file specific to the
local machine.

The patch can also be found at
http://people.freebsd.org/~rstone/patches/syslogd-multiconf.diff

(Oh, and before somebody asks, the reason that I converted struct
filed to use a TAILQ was that at one point I found myself typing
struct filed ***, then hit myself and refactored the code instead).

Index: syslogd.c
===================================================================
--- syslogd.c   (revision 227341)
+++ syslogd.c   (working copy)
@@ -114,7 +114,6 @@
 #define SYSLOG_NAMES
 #include <sys/syslog.h>

-const char     *ConfFile = _PATH_LOGCONF;
 const char     *PidFile = _PATH_LOGPID;
 const char     ctty[] = _PATH_CONSOLE;

@@ -141,6 +140,13 @@
 STAILQ_HEAD(, funix) funixes = { &funix_default,
                                &(funix_secure.next.stqe_next) };

+struct conf_file {
+       const char *name;
+       TAILQ_ENTRY(conf_file) next;
+};
+
+TAILQ_HEAD(, conf_file) conf_list = TAILQ_HEAD_INITIALIZER(conf_list);
+
 /*
  * Flags to logmsg().
  */
@@ -159,7 +165,7 @@
  */

 struct filed {
-       struct  filed *f_next;          /* next in linked list */
+       TAILQ_ENTRY(filed) f_next;      /* next in linked list */
        short   f_type;                 /* entry type, see below */
        short   f_file;                 /* file descriptor */
        time_t  f_time;                 /* time this was last written */
@@ -266,7 +272,7 @@
        "FORW",         "USERS",        "WALL",         "PIPE"
 };

-static struct filed *Files;    /* Log files that we write to */
+static TAILQ_HEAD(, filed) Files = TAILQ_HEAD_INITIALIZER(Files);
 static struct filed consfile;  /* Console */

 static int     Debug;          /* debug flag */
@@ -351,6 +357,7 @@
        struct timeval tv, *tvp;
        struct sigaction sact;
        struct funix *fx, *fx1;
+       struct conf_file *conf;
        sigset_t mask;
        pid_t ppid = 1, spid;
        socklen_t len;
@@ -393,7 +400,11 @@
                        Debug++;
                        break;
                case 'f':               /* configuration file */
-                       ConfFile = optarg;
+                       conf = malloc(sizeof(*conf));
+                       if (conf == NULL)
+                               errx(1, "Could not alloc memory, exiting");
+                       conf->name = optarg;
+                       TAILQ_INSERT_TAIL(&conf_list, conf, next);
                        break;
                case 'k':               /* keep remote kern fac */
                        KeepKernFac = 1;
@@ -497,6 +508,14 @@
                setlinebuf(stdout);
        }

+       if (TAILQ_EMPTY(&conf_list)) {
+               conf = malloc(sizeof(*conf));
+               if (conf == NULL)
+                       errx(1, "Could not alloc memory, exiting");
+               conf->name = _PATH_LOGCONF;
+               TAILQ_INSERT_TAIL(&conf_list, conf, next);
+       }
+
        if (NumAllowed)
                endservent();

@@ -989,7 +1008,7 @@
                (void)sigsetmask(omask);
                return;
        }
-       for (f = Files; f; f = f->f_next) {
+       TAILQ_FOREACH(f, &Files, f_next) {
                /* skip messages that are incorrect priority */
                if (!(((f->f_pcmp[fac] & PRI_EQ) && (f->f_pmask[fac] == prilev))
                     ||((f->f_pcmp[fac] & PRI_LT) && (f->f_pmask[fac] < prilev))
@@ -1066,7 +1085,7 @@
 {
        struct filed *f;

-       for (f = Files; f; f = f->f_next) {
+       TAILQ_FOREACH(f, &Files, f_next) {
                if ((f->f_type == F_FILE) &&
                    (f->f_flags & FFLAG_NEEDSYNC)) {
                        f->f_flags &= ~FFLAG_NEEDSYNC;
@@ -1403,7 +1422,7 @@
                        goto oncemore;

                /* Now, look in list of active processes. */
-               for (f = Files; f; f = f->f_next)
+               TAILQ_FOREACH(f, &Files, f_next)
                        if (f->f_type == F_PIPE &&
                            f->f_un.f_pipe.f_pid == pid) {
                                (void)close(f->f_file);
@@ -1505,7 +1524,7 @@

        was_initialized = Initialized;
        Initialized = 0;        /* Don't log SIGCHLDs. */
-       for (f = Files; f != NULL; f = f->f_next) {
+       TAILQ_FOREACH(f, &Files, f_next) {
                /* flush any pending output */
                if (f->f_prevcount)
                        fprintlog(f, 0, (char *)NULL);
@@ -1528,90 +1547,37 @@
        exit(1);
 }

-/*
- *  INIT -- Initialize syslogd from configuration table
- */
-static void
-init(int signo)
+static int
+parse_conf(const char *conf)
 {
        int i;
        FILE *cf;
-       struct filed *f, *next, **nextp;
+       struct filed *f;
        char *p;
        char cline[LINE_MAX];
        char prog[NAME_MAX+1];
        char host[MAXHOSTNAMELEN];
-       char oldLocalHostName[MAXHOSTNAMELEN];
-       char hostMsg[2*MAXHOSTNAMELEN+40];
-       char bootfileMsg[LINE_MAX];

-       dprintf("init\n");
-
-       /*
-        * Load hostname (may have changed).
-        */
-       if (signo != 0)
-               (void)strlcpy(oldLocalHostName, LocalHostName,
-                   sizeof(oldLocalHostName));
-       if (gethostname(LocalHostName, sizeof(LocalHostName)))
-               err(EX_OSERR, "gethostname() failed");
-       if ((p = strchr(LocalHostName, '.')) != NULL) {
-               *p++ = '\0';
-               LocalDomain = p;
-       } else {
-               LocalDomain = "";
-       }
-
-       /*
-        *  Close all open log files.
-        */
-       Initialized = 0;
-       for (f = Files; f != NULL; f = next) {
-               /* flush any pending output */
-               if (f->f_prevcount)
-                       fprintlog(f, 0, (char *)NULL);
-
-               switch (f->f_type) {
-               case F_FILE:
-               case F_FORW:
-               case F_CONSOLE:
-               case F_TTY:
-                       (void)close(f->f_file);
-                       break;
-               case F_PIPE:
-                       if (f->f_un.f_pipe.f_pid > 0) {
-                               (void)close(f->f_file);
-                               deadq_enter(f->f_un.f_pipe.f_pid,
-                                           f->f_un.f_pipe.f_pname);
-                       }
-                       f->f_un.f_pipe.f_pid = 0;
-                       break;
-               }
-               next = f->f_next;
-               if (f->f_program) free(f->f_program);
-               if (f->f_host) free(f->f_host);
-               free((char *)f);
-       }
-       Files = NULL;
-       nextp = &Files;
-
        /* open the configuration file */
-       if ((cf = fopen(ConfFile, "r")) == NULL) {
-               dprintf("cannot open %s\n", ConfFile);
-               *nextp = (struct filed *)calloc(1, sizeof(*f));
-               if (*nextp == NULL) {
+       if ((cf = fopen(conf, "r")) == NULL) {
+               dprintf("cannot open %s\n", conf);
+               f = (struct filed *)calloc(1, sizeof(*f));
+               if (f == NULL) {
                        logerror("calloc");
                        exit(1);
                }
-               cfline("*.ERR\t/dev/console", *nextp, "*", "*");
-               (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
-               if ((*nextp)->f_next == NULL) {
+               cfline("*.ERR\t/dev/console", f, "*", "*");
+               TAILQ_INSERT_TAIL(&Files, f, f_next);
+               
+               f = (struct filed *)calloc(1, sizeof(*f));
+               if (f == NULL) {
                        logerror("calloc");
                        exit(1);
                }
-               cfline("*.PANIC\t*", (*nextp)->f_next, "*", "*");
+               cfline("*.PANIC\t*", f, "*", "*");
+               TAILQ_INSERT_TAIL(&Files, f, f_next);
                Initialized = 1;
-               return;
+               return (ENOENT);
        }

        /*
@@ -1687,19 +1653,91 @@
                        logerror("calloc");
                        exit(1);
                }
-               *nextp = f;
-               nextp = &f->f_next;
                cfline(cline, f, prog, host);
+               TAILQ_INSERT_TAIL(&Files, f, f_next);
        }

        /* close the configuration file */
        (void)fclose(cf);

+       return (0);
+}
+
+/*
+ *  INIT -- Initialize syslogd from configuration table
+ */
+static void
+init(int signo)
+{
+       int i;
+       char *p;
+       struct filed *f, *next;
+       char oldLocalHostName[MAXHOSTNAMELEN];
+       char hostMsg[2*MAXHOSTNAMELEN+40];
+       char bootfileMsg[LINE_MAX];
+       struct conf_file *conf;
+       int error;
+
+       dprintf("init\n");
+
+       /*
+        * Load hostname (may have changed).
+        */
+       if (signo != 0)
+               (void)strlcpy(oldLocalHostName, LocalHostName,
+                   sizeof(oldLocalHostName));
+       if (gethostname(LocalHostName, sizeof(LocalHostName)))
+               err(EX_OSERR, "gethostname() failed");
+       if ((p = strchr(LocalHostName, '.')) != NULL) {
+               *p++ = '\0';
+               LocalDomain = p;
+       } else {
+               LocalDomain = "";
+       }
+
+       /*
+        *  Close all open log files.
+        */
+       Initialized = 0;
+       TAILQ_FOREACH_SAFE(f, &Files, f_next, next) {
+               /* flush any pending output */
+               if (f->f_prevcount)
+                       fprintlog(f, 0, (char *)NULL);
+
+               switch (f->f_type) {
+               case F_FILE:
+               case F_FORW:
+               case F_CONSOLE:
+               case F_TTY:
+                       (void)close(f->f_file);
+                       break;
+               case F_PIPE:
+                       if (f->f_un.f_pipe.f_pid > 0) {
+                               (void)close(f->f_file);
+                               deadq_enter(f->f_un.f_pipe.f_pid,
+                                           f->f_un.f_pipe.f_pname);
+                       }
+                       f->f_un.f_pipe.f_pid = 0;
+                       break;
+               }
+               if (f->f_program) free(f->f_program);
+               if (f->f_host) free(f->f_host);
+               TAILQ_REMOVE(&Files, f, f_next);
+               free((char *)f);
+       }
+
+       TAILQ_FOREACH(conf, &conf_list, next) {
+               error = parse_conf(conf->name);
+
+               if (error)
+                       return;
+       }
+
        Initialized = 1;

        if (Debug) {
                int port;
-               for (f = Files; f; f = f->f_next) {
+               TAILQ_FOREACH(f, &Files, f_next) {
                        for (i = 0; i <= LOG_NFACILITIES; i++)
                                if (f->f_pmask[i] == INTERNAL_NOPRI)
                                        printf("X ");
@@ -2054,7 +2092,7 @@
                MarkSeq = 0;
        }

-       for (f = Files; f; f = f->f_next) {
+       TAILQ_FOREACH(f, &Files, f_next) {
                if (f->f_prevcount && now >= REPEATTIME(f)) {
                        dprintf("flush %s: repeated %d times, %d sec.\n",
                            TypeNames[f->f_type], f->f_prevcount,
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to