From owner-freebsd-current@FreeBSD.ORG Wed Nov 9 15:27:46 2011 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1432C1065670 for ; Wed, 9 Nov 2011 15:27:46 +0000 (UTC) (envelope-from rysto32@gmail.com) Received: from mail-ww0-f50.google.com (mail-ww0-f50.google.com [74.125.82.50]) by mx1.freebsd.org (Postfix) with ESMTP id 8B53C8FC18 for ; Wed, 9 Nov 2011 15:27:45 +0000 (UTC) Received: by wwg14 with SMTP id 14so336547wwg.31 for ; Wed, 09 Nov 2011 07:27:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; bh=ArpLI749/wOAl8cBgrUtwawlTavGVajAGQcCZcSOj3A=; b=sLpbJGwa+hXNQICunfk12ceVsdtd2uF/I417kaxA/I8Kq5qIRu6mf+w304hQymKaqf 6YgLoSDTufTJ0FpZGZTb1TUmcc+BRY0AePGd3u2pnhi2MKE3JE8CJkZdsd5fPsMGvInz TI8ZM5QpzY7hDctCIS8X+/kYdiU90MlhJxboM= MIME-Version: 1.0 Received: by 10.180.3.227 with SMTP id f3mr3417948wif.5.1320852464333; Wed, 09 Nov 2011 07:27:44 -0800 (PST) Received: by 10.180.8.34 with HTTP; Wed, 9 Nov 2011 07:27:44 -0800 (PST) Date: Wed, 9 Nov 2011 10:27:44 -0500 Message-ID: From: Ryan Stone To: FreeBSD Current Content-Type: text/plain; charset=ISO-8859-1 Subject: [PATCH] Allow syslogd to accept multiple configuration files X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Nov 2011 15:27:46 -0000 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 -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,