summaryrefslogtreecommitdiff
path: root/usr/src/cmd/syslogd/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/syslogd/conf.c')
-rw-r--r--usr/src/cmd/syslogd/conf.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/usr/src/cmd/syslogd/conf.c b/usr/src/cmd/syslogd/conf.c
new file mode 100644
index 0000000000..2e60db8529
--- /dev/null
+++ b/usr/src/cmd/syslogd/conf.c
@@ -0,0 +1,219 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1997-2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "conf.h"
+
+#define CF_DEFSIZE 32 /* Starting table size */
+#define CF_GROW 2 /* Table size multiplier on grow */
+
+extern void logerror(char *);
+
+static FILE *
+open_conf_pipe(const char *cmd, char *argv[], pid_t *pidp)
+{
+ int pfds[2];
+ pid_t pid;
+ struct sigaction act;
+
+ /* Create a pipe and fork a child process to run the command */
+
+ if (pipe(pfds) == -1) {
+ logerror("failed to create pipe");
+ return (NULL);
+ }
+
+ if ((pid = fork1()) == -1) {
+ logerror("failed to fork1");
+ goto err;
+ }
+
+ /* If we're in the child, run the command and output to the pipe */
+
+ if (pid == 0) {
+ /*
+ * We must set up to ignore these signals, which may be
+ * propogated from the calling process.
+ */
+
+ act.sa_handler = SIG_IGN;
+
+ (void) sigaction(SIGHUP, &act, NULL);
+ (void) sigaction(SIGALRM, &act, NULL);
+ (void) sigaction(SIGUSR1, &act, NULL);
+
+ (void) close(pfds[0]);
+ (void) close(STDOUT_FILENO);
+
+ if (dup2(pfds[1], STDOUT_FILENO) == -1) {
+ logerror("failed to dup to stdout");
+ (void) close(pfds[1]);
+ _exit(127);
+ }
+
+ (void) execvp(cmd, argv);
+ logerror("failed to parse configuration file");
+ _exit(127);
+ /*NOTREACHED*/
+ }
+
+ /* If we're in the parent, open the read end of the pipe and return */
+
+ *pidp = pid;
+ (void) close(pfds[1]);
+ return (fdopen(pfds[0], "r"));
+
+err:
+ (void) close(pfds[0]);
+ (void) close(pfds[1]);
+ return (NULL);
+}
+
+static void
+close_conf_pipe(FILE *fp, pid_t pid)
+{
+ int status;
+
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR)
+ break;
+ }
+
+ (void) fclose(fp);
+}
+
+static int
+grow_conf_file(conf_t *cf)
+{
+ int ndsize = cf->cf_dsize ? cf->cf_dsize * CF_GROW : CF_DEFSIZE;
+ void *ndtab = realloc(cf->cf_dtab, sizeof (char *) * ndsize);
+
+ register char *p;
+ int odsize, lines, i;
+
+ if (ndtab == NULL) {
+ logerror("failed to allocate config file table");
+ return (-1);
+ }
+
+ lines = ndsize - cf->cf_dsize;
+ odsize = cf->cf_dsize;
+
+ cf->cf_dtab = (char **)ndtab;
+ cf->cf_dsize = ndsize;
+
+ for (i = 0; i < lines; i++) {
+ if ((p = (char *)malloc(BUFSIZ)) == NULL) {
+ logerror("failed to allocate config file buffer");
+ return (-1);
+ }
+
+ cf->cf_dtab[odsize + i] = p;
+ }
+
+ return (0);
+}
+
+int
+conf_open(conf_t *cf, const char *cmd, char *argv[])
+{
+ char *line, *p;
+ pid_t pid;
+ FILE *fp;
+
+ (void) memset(cf, 0, sizeof (conf_t));
+
+ if ((fp = open_conf_pipe(cmd, argv, &pid)) == NULL)
+ return (-1);
+
+ for (;;) {
+ /* If we need to grow the table, do so now */
+
+ if (cf->cf_lines >= cf->cf_dsize) {
+ if (grow_conf_file(cf) == -1)
+ goto err;
+ }
+
+ line = cf->cf_dtab[cf->cf_lines];
+
+ /* Read the next line, and break out if we're done */
+
+ if (fgets(line, BUFSIZ, fp) == NULL)
+ break;
+
+ /* Strip newline and bump line counter */
+
+ if ((p = strchr(line, '\n')) != NULL)
+ *p = '\0';
+
+ cf->cf_lines++;
+ }
+
+ close_conf_pipe(fp, pid);
+ return (0);
+
+err:
+ close_conf_pipe(fp, pid);
+ return (-1);
+}
+
+void
+conf_rewind(conf_t *cf)
+{
+ cf->cf_ptr = 0;
+}
+
+char *
+conf_read(conf_t *cf)
+{
+ if (cf->cf_ptr < cf->cf_lines)
+ return (cf->cf_dtab[cf->cf_ptr++]);
+
+ return (NULL);
+}
+
+void
+conf_close(conf_t *cf)
+{
+ int i;
+
+ if (cf->cf_dtab != NULL) {
+ for (i = 0; i < cf->cf_dsize; i++)
+ free(cf->cf_dtab[i]);
+ free(cf->cf_dtab);
+ }
+}