/*
* 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