xref: /titanic_50/usr/src/cmd/syslogd/conf.c (revision 0ea5e3a571e3da934507bdd32924d11659c70704)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0ea5e3a5Sjjj  * Common Development and Distribution License (the "License").
6*0ea5e3a5Sjjj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*0ea5e3a5Sjjj  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*0ea5e3a5Sjjj  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/types.h>
297c478bd9Sstevel@tonic-gate #include <sys/wait.h>
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <signal.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <stdio.h>
367c478bd9Sstevel@tonic-gate #include <errno.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include "conf.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #define	CF_DEFSIZE	32	/* Starting table size */
417c478bd9Sstevel@tonic-gate #define	CF_GROW		2	/* Table size multiplier on grow */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate static FILE *
open_conf_pipe(const char * cmd,char * argv[],pid_t * pidp)447c478bd9Sstevel@tonic-gate open_conf_pipe(const char *cmd, char *argv[], pid_t *pidp)
457c478bd9Sstevel@tonic-gate {
467c478bd9Sstevel@tonic-gate 	int pfds[2];
477c478bd9Sstevel@tonic-gate 	pid_t pid;
487c478bd9Sstevel@tonic-gate 	struct sigaction act;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	/* Create a pipe and fork a child process to run the command */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	if (pipe(pfds) == -1) {
537c478bd9Sstevel@tonic-gate 		logerror("failed to create pipe");
547c478bd9Sstevel@tonic-gate 		return (NULL);
557c478bd9Sstevel@tonic-gate 	}
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	if ((pid = fork1()) == -1) {
587c478bd9Sstevel@tonic-gate 		logerror("failed to fork1");
597c478bd9Sstevel@tonic-gate 		goto err;
607c478bd9Sstevel@tonic-gate 	}
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	/* If we're in the child, run the command and output to the pipe */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	if (pid == 0) {
657c478bd9Sstevel@tonic-gate 		/*
667c478bd9Sstevel@tonic-gate 		 * We must set up to ignore these signals, which may be
677c478bd9Sstevel@tonic-gate 		 * propogated from the calling process.
687c478bd9Sstevel@tonic-gate 		 */
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 		act.sa_handler = SIG_IGN;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 		(void) sigaction(SIGHUP, &act, NULL);
737c478bd9Sstevel@tonic-gate 		(void) sigaction(SIGALRM, &act, NULL);
747c478bd9Sstevel@tonic-gate 		(void) sigaction(SIGUSR1, &act, NULL);
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 		(void) close(pfds[0]);
777c478bd9Sstevel@tonic-gate 		(void) close(STDOUT_FILENO);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 		if (dup2(pfds[1], STDOUT_FILENO) == -1) {
807c478bd9Sstevel@tonic-gate 			logerror("failed to dup to stdout");
817c478bd9Sstevel@tonic-gate 			(void) close(pfds[1]);
827c478bd9Sstevel@tonic-gate 			_exit(127);
837c478bd9Sstevel@tonic-gate 		}
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 		(void) execvp(cmd, argv);
867c478bd9Sstevel@tonic-gate 		logerror("failed to parse configuration file");
877c478bd9Sstevel@tonic-gate 		_exit(127);
887c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
897c478bd9Sstevel@tonic-gate 	}
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	/* If we're in the parent, open the read end of the pipe and return */
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	*pidp = pid;
947c478bd9Sstevel@tonic-gate 	(void) close(pfds[1]);
957c478bd9Sstevel@tonic-gate 	return (fdopen(pfds[0], "r"));
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate err:
987c478bd9Sstevel@tonic-gate 	(void) close(pfds[0]);
997c478bd9Sstevel@tonic-gate 	(void) close(pfds[1]);
1007c478bd9Sstevel@tonic-gate 	return (NULL);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate static void
close_conf_pipe(FILE * fp,pid_t pid)1047c478bd9Sstevel@tonic-gate close_conf_pipe(FILE *fp, pid_t pid)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate 	int status;
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	while (waitpid(pid, &status, 0) == -1) {
1097c478bd9Sstevel@tonic-gate 		if (errno != EINTR)
1107c478bd9Sstevel@tonic-gate 			break;
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate static int
grow_conf_file(conf_t * cf)1177c478bd9Sstevel@tonic-gate grow_conf_file(conf_t *cf)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate 	int ndsize = cf->cf_dsize ? cf->cf_dsize * CF_GROW : CF_DEFSIZE;
1207c478bd9Sstevel@tonic-gate 	void *ndtab = realloc(cf->cf_dtab, sizeof (char *) * ndsize);
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	register char *p;
1237c478bd9Sstevel@tonic-gate 	int odsize, lines, i;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	if (ndtab == NULL) {
1267c478bd9Sstevel@tonic-gate 		logerror("failed to allocate config file table");
1277c478bd9Sstevel@tonic-gate 		return (-1);
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	lines = ndsize - cf->cf_dsize;
1317c478bd9Sstevel@tonic-gate 	odsize = cf->cf_dsize;
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	cf->cf_dtab = (char **)ndtab;
1347c478bd9Sstevel@tonic-gate 	cf->cf_dsize = ndsize;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	for (i = 0; i < lines; i++) {
1377c478bd9Sstevel@tonic-gate 		if ((p = (char *)malloc(BUFSIZ)) == NULL) {
1387c478bd9Sstevel@tonic-gate 			logerror("failed to allocate config file buffer");
1397c478bd9Sstevel@tonic-gate 			return (-1);
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 		cf->cf_dtab[odsize + i] = p;
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	return (0);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate int
conf_open(conf_t * cf,const char * cmd,char * argv[])1497c478bd9Sstevel@tonic-gate conf_open(conf_t *cf, const char *cmd, char *argv[])
1507c478bd9Sstevel@tonic-gate {
1517c478bd9Sstevel@tonic-gate 	char *line, *p;
1527c478bd9Sstevel@tonic-gate 	pid_t pid;
1537c478bd9Sstevel@tonic-gate 	FILE *fp;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 	(void) memset(cf, 0, sizeof (conf_t));
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	if ((fp = open_conf_pipe(cmd, argv, &pid)) == NULL)
1587c478bd9Sstevel@tonic-gate 		return (-1);
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	for (;;) {
1617c478bd9Sstevel@tonic-gate 		/* If we need to grow the table, do so now */
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 		if (cf->cf_lines >= cf->cf_dsize) {
1647c478bd9Sstevel@tonic-gate 			if (grow_conf_file(cf) == -1)
1657c478bd9Sstevel@tonic-gate 				goto err;
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 		line = cf->cf_dtab[cf->cf_lines];
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 		/* Read the next line, and break out if we're done */
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		if (fgets(line, BUFSIZ, fp) == NULL)
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 		/* Strip newline and bump line counter */
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 		if ((p = strchr(line, '\n')) != NULL)
1787c478bd9Sstevel@tonic-gate 			*p = '\0';
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 		cf->cf_lines++;
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	close_conf_pipe(fp, pid);
1847c478bd9Sstevel@tonic-gate 	return (0);
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate err:
1877c478bd9Sstevel@tonic-gate 	close_conf_pipe(fp, pid);
1887c478bd9Sstevel@tonic-gate 	return (-1);
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate void
conf_rewind(conf_t * cf)1927c478bd9Sstevel@tonic-gate conf_rewind(conf_t *cf)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	cf->cf_ptr = 0;
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate char *
conf_read(conf_t * cf)1987c478bd9Sstevel@tonic-gate conf_read(conf_t *cf)
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate 	if (cf->cf_ptr < cf->cf_lines)
2017c478bd9Sstevel@tonic-gate 		return (cf->cf_dtab[cf->cf_ptr++]);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	return (NULL);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate void
conf_close(conf_t * cf)2077c478bd9Sstevel@tonic-gate conf_close(conf_t *cf)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	int i;
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (cf->cf_dtab != NULL) {
2127c478bd9Sstevel@tonic-gate 		for (i = 0; i < cf->cf_dsize; i++)
2137c478bd9Sstevel@tonic-gate 			free(cf->cf_dtab[i]);
2147c478bd9Sstevel@tonic-gate 		free(cf->cf_dtab);
2157c478bd9Sstevel@tonic-gate 	}
2167c478bd9Sstevel@tonic-gate }
217