/*
 * Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

/*
**  Program for reading/printing MCP configuration files.
**  Used by t-mcpconf-*.sh
*/

#include "sm/generic.h"
SM_RCSID("@(#)$Id: mcpconf.c,v 1.10 2005/09/26 23:38:35 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/sysexits.h"
#include "sm/string.h"
#include "sm/io.h"

#include "sm/sm-conf.h"

#include "sm/net.h"
#include "mcp.h"

#define SM_SOCKCNFDEF 1
#include "sm/sockcnf.h"
#include "sm/sockcnfdef.h"

#define SM_MCPCNFDEF 1
#include "sm/mcpcnfdef.h"

static int Verbose = 0;

#define IS_SET(s)	((s) != NULL && (*(s)) != '\0')

static void
prt_mcpcnf(servtab_T *s, char const *name, size_t name_n)
{
	size_t i;

	printf("%.*s {\n", (int)name_n, name);
	if (Verbose > 0 && IS_SET(s->se_prg))
		printf("prg           = \"%s\";\n", s->se_prg);
	if (s->se_port != 0)
	{
		printf("port          = %2d;\n", s->se_port);
	}
	else if (s->se_socket_name != NULL &&
		 *s->se_socket_name != '\0' &&
		 *s->se_socket_name != SM_MCP_DEFAULT_CHAR)
	{
		if (*s->se_socket_name != '\0')
			printf("socket_name   = \"%s\";\n", s->se_socket_name);
		if (s->se_socket_umask != 066)
			printf("socket_umask  = %03o;\n", s->se_socket_umask);
		if (s->se_socket_user != NULL && *s->se_socket_user != '\0')
			printf("socket_user   = \"%s\";\n", s->se_socket_user);
		if (s->se_socket_group != NULL && *s->se_socket_group != '\0')
			printf("socket_group  = \"%s\";\n", s->se_socket_group);
	}
	if (s->se_minchild != 1)
		printf("minproc       = %2d;\n", s->se_minchild);
	if (s->se_maxchild != 1)
		printf("maxproc       = %2d;\n", s->se_maxchild);
	if (*s->se_exsock != '\0')
		printf("pass_fd_socket= \"%s\";\n", s->se_exsock);
	if (*s->se_user != '\0')
		printf("user          = \"%s\";\n", s->se_user);
	if (*s->se_group != '\0')
		printf("group         = \"%s\";\n", s->se_group);

	if (s->se_restartdep[0] != NULL)
	{
		printf("restartdeps   = {");
		for (i = 0;
		     i < SM_ARRAY_SIZE(s->se_restartdep)
			&& s->se_restartdep[i] != NULL;
		     i++)
			printf(" %s,", s->se_restartdep[i]);
		printf("};\n");
	}

	if (s->se_flags != 0)
		printf("start_action  = %x;\n", s->se_flags);
	printf("path          = \"%s\";\n", s->se_server);
	printf("args          = \"%s\";\n", s->se_args);
	printf("}\n");
}

static int
process(char const *name, FILE *fp)
{
	sm_conf_T *smc;
	int err;
	servtab_T s;
#if 0
	sm_conf_iterator_T service_iter;
	char const *service_name;
	size_t service_name_n;
#endif /* 0 */
	char const *title, *kw;
	size_t title_n, kw_n;
	sm_conf_node_T *node, *root;
	char buf[200];
	char const *e = NULL;

	sm_memzero(&s, sizeof(s));
	if (((smc = sm_conf_new(name ? name : "*stdin*"))) == NULL)
	{
		fprintf(stderr, "error -- sm_conf_new() returns NULL!\n");
		return 1;
	}
	if ((err = sm_conf_read_FILE(smc, name, fp)) != 0)
	{

		fprintf(stderr, "%s: %s\n",
			name ? name : "*stdin*",
			sm_conf_strerror(err, buf, sizeof buf));

		while ((e = sm_conf_syntax_error(smc, e)) != NULL)
			fprintf(stderr, "%s\n", e);

		sm_conf_destroy(smc);
		return 2;
	}

	root = sm_conf_root(smc);
	node = NULL;
	while ((node = sm_conf_section_next_subsection(smc, root,
				NULL, 0, NULL, 0, node)) != NULL)
	{
		err = sm_conf_section_keyword(smc, node, &kw, &kw_n);
		if (Verbose > 1)
		{
			if (kw == NULL)
				printf("kw=(none)\n");
			else
				printf("kw=%*s\n", (int) kw_n, kw);
		}
		if (kw != NULL)
			s.se_prg = kw;
		err = sm_conf_section_name(smc, node, &title, &title_n);
		if (Verbose > 1)
		{
			if (title == NULL)
				printf("title=(none)\n");
			else
				printf("title=%*s\n", (int) title_n, title);
		}
		if (sm_conf_node_type(smc, node) != SM_CONF_NODE_SECTION)
			continue;
		if (title != NULL)
			s.se_prg = title;

		err = sm_conf_get_relative(smc, node, NULL,
				sm_conf_type_section, mcp_defs,
				SM_CONF_FLAG_ALLOW_ANY, &s, sizeof(s));
		if (err != 0)
		{
			fprintf(stderr, "%s: %s\n",
				name ? name : "*stdin*",
				sm_conf_strerror(err, buf, sizeof buf));

			while ((e = sm_conf_syntax_error(smc, e)) != NULL)
				fprintf(stderr, "%s\n", e);

		}
		else
			prt_mcpcnf(&s, kw, kw_n);
	}

	sm_conf_destroy(smc);

	return 0;
}

#if STANDALONE
int
main(int argc, char **argv)
{
	int ret, r, ai;

	ret = 0;	/* make compiler happy */
	while ((r = getopt(argc, argv, "V")) != -1)
	{
		switch (r)
		{
		  case 'V':
			++Verbose;
			break;
		  default:
/*
			usage(argv[0]);
*/
			return 1;
		}
	}

	argc -= optind;
	argv += optind;

	for (ai = 0; ai < argc; ai++)
	{
		ret = process(argv[ai], NULL);
		if (ret != 0)
			break;
	}

	return ret;
}
#endif /* STANDALONE */


syntax highlighted by Code2HTML, v. 0.9.1