/*
 * Copyright (c) 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.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: demo-syslog.c,v 1.3 2005/09/26 23:26:41 ca Exp $")

#if SM_LIBCONF_ALONE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include "sm-conf.h"
#else /* SM_LIBCONF_ALONE */
#include "sm/string.h"
#include "sm/sm-conf.h"
#include "sm/net.h"
#include <stdio.h>
#endif /* SM_LIBCONF_ALONE */

#include <syslog.h>

/* DEMO-SYSLOG.C -- small demo of sm_conf_scan() */

#ifndef offsetof
#define offsetof(type, member)	((char *)&((type *)0)->member - (char *)0)
#endif

typedef struct
{
	unsigned int	facility;
	char const	*ident;

} my_syslog_T;

sm_conf_definition_T const facility_names[] =
{
#ifdef LOG_AUTH
	{ SM_CONF_DEF_MAGIC, "auth",	sm_conf_type_choice_value, LOG_AUTH},
#endif
#ifdef LOG_AUTHPRIV
	{ SM_CONF_DEF_MAGIC, "authpriv",sm_conf_type_choice_value,LOG_AUTHPRIV},
#endif
#ifdef LOG_CRON
	{ SM_CONF_DEF_MAGIC, "cron",    sm_conf_type_choice_value, LOG_CRON},
#endif
#ifdef LOG_DAEMON
	{ SM_CONF_DEF_MAGIC, "daemon",  sm_conf_type_choice_value, LOG_DAEMON},
#endif
#ifdef LOG_FTP
	{ SM_CONF_DEF_MAGIC, "ftp",	sm_conf_type_choice_value, LOG_FTP},
#endif
#ifdef LOG_KERN
	{ SM_CONF_DEF_MAGIC, "kern",	sm_conf_type_choice_value, LOG_KERN},
#endif
#ifdef LOG_LOCAL0
	{ SM_CONF_DEF_MAGIC, "local0",  sm_conf_type_choice_value, LOG_LOCAL0},
#endif
#ifdef LOG_LOCAL1
	{ SM_CONF_DEF_MAGIC, "local1",  sm_conf_type_choice_value, LOG_LOCAL1},
#endif
#ifdef LOG_LOCAL2
	{ SM_CONF_DEF_MAGIC, "local2",  sm_conf_type_choice_value, LOG_LOCAL2},
#endif
#ifdef LOG_LOCAL3
	{ SM_CONF_DEF_MAGIC, "local3",  sm_conf_type_choice_value, LOG_LOCAL3},
#endif
#ifdef LOG_LOCAL4
	{ SM_CONF_DEF_MAGIC, "local4",  sm_conf_type_choice_value, LOG_LOCAL4},
#endif
#ifdef LOG_LOCAL5
	{ SM_CONF_DEF_MAGIC, "local5",  sm_conf_type_choice_value, LOG_LOCAL5},
#endif
#ifdef LOG_LOCAL6
	{ SM_CONF_DEF_MAGIC, "local6",  sm_conf_type_choice_value, LOG_LOCAL6},
#endif
#ifdef LOG_LOCAL7
	{ SM_CONF_DEF_MAGIC, "local7",  sm_conf_type_choice_value, LOG_LOCAL7},
#endif
#ifdef LOG_LPR
	{ SM_CONF_DEF_MAGIC, "lpr",	sm_conf_type_choice_value, LOG_LPR},
#endif
#ifdef LOG_MAIL
	{ SM_CONF_DEF_MAGIC, "mail",	sm_conf_type_choice_value, LOG_MAIL},
#endif
#ifdef LOG_NEWS
	{ SM_CONF_DEF_MAGIC, "news",	sm_conf_type_choice_value, LOG_NEWS},
#endif
#ifdef LOG_SYSLOG
	{ SM_CONF_DEF_MAGIC, "syslog",  sm_conf_type_choice_value, LOG_SYSLOG},
#endif
#ifdef LOG_USER
	{ SM_CONF_DEF_MAGIC, "user",	sm_conf_type_choice_value, LOG_USER},
#endif
#ifdef LOG_UUCP
	{ SM_CONF_DEF_MAGIC, "uucp",	sm_conf_type_choice_value, LOG_UUCP},
#endif

	/* Sentinel */
	{ SM_CONF_DEF_MAGIC, NULL }
};

sm_conf_definition_T log_definitions[] =
{
	{ SM_CONF_DEF_MAGIC,
		"ident", sm_conf_type_string, offsetof(my_syslog_T, ident),
	},

	{ SM_CONF_DEF_MAGIC,
		"facility", sm_conf_type_choice, offsetof(my_syslog_T, facility),
		sizeof(unsigned int), "mail", 0, facility_names
	},

	/* sentinel */
	{ SM_CONF_DEF_MAGIC, NULL }
};

sm_conf_definition_T definitions[] =
{
	{ SM_CONF_DEF_MAGIC,
		"log", sm_conf_type_section, 0, sizeof(my_syslog_T), NULL, 0,
		log_definitions
	},

	/* sentinel */
	{ SM_CONF_DEF_MAGIC, NULL }
};

static void
print_structure(my_syslog_T *s)
{
	printf("facility: %u\n", s->facility);
	printf("ident: '%s'\n",	s->ident);
	putchar('\n');
}

static int
process(char const *name, FILE *fp)
{
	sm_conf_T		*stream;
	int			err;
	my_syslog_T		s;

	if (((stream = sm_conf_new(name ? name : "*stdin*"))) == NULL)
	{
		fprintf(stderr, "error -- sm_conf_new() returns NULL!\n");
		return 1;
	}
	if ((err = sm_conf_read_FILE(stream, name, fp)) != 0)
	{
		char buf[SM_CONF_ERROR_BUFFER_SIZE];
		char const *e = NULL;

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

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

		sm_conf_destroy(stream);
		return 2;
	}

	memset(&s, 0, sizeof(s));
	err = sm_conf_scan(stream, definitions, 0, &s);
	if (err != 0)
	{
		char buf[SM_CONF_ERROR_BUFFER_SIZE];
		char const *e = NULL;

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

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

		sm_conf_destroy(stream);
		return 3;
	}

	print_structure(&s);
	sm_conf_destroy(stream);

	return 0;
}

int
main(int ac, char **av)
{
	int	ai;

	if (ac == 1)
		return process("*stdin*", stdin);

	for (ai = 1; ai < ac; ai++)
	{
		int ret = process(av[ai], NULL);
		if (ret != 0)
			return ret;
	}
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1