Commit c57171ac c57171ac85329c8baad86a7e4221ebeef2df0804 by Sergey Poznyakoff

* auth/virtual.c (site_virtual_pwddir): Replace with global

struct mu_gocs_virtual mu_virtual_module_config

* include/mailutils/cfg.h (MU_PARSE_CONFIG_GLOBAL)
(MU_PARSE_CONFIG_VERBOSE, MU_PARSE_CONFIG_DUMP): New defines.
(mu_cfg_tree_create,mu_cfg_tree_set_debug,mu_cfg_tree_set_alloc)
(mu_cfg_tree_alloc,mu_cfg_tree_free)
(mu_cfg_tree_create_node,mu_cfg_tree_add_node): New functions.
* include/mailutils/gocs.h (struct mu_gocs_virtual): New data
type.
* include/mailutils/libargp.h (struct mu_argp_node_list): New data
type.
(mu_argp_node_list_init, mu_argp_node_list_add)
(mu_argp_node_list_new, mu_argp_node_list_finish): New functions.
* libargp/cmdline.h: New header.
* libargp/Makefile.am (libmuargp_a_SOURCES): Add cmdline.h.

* dotlock/dotlock.c, imap4d/imap4d.c, libargp/auth.c,
libargp/cmdline.c, libargp/common.c, libargp/compat.c,
libargp/gsasl.c, libargp/mu_argp.c, libargp/muinit.c,
libargp/pam.c, libargp/radius.c, libargp/sieve.c, libargp/sql.c,
libargp/tls.c, libargp/virtdomain.c, libcfg/common.c,
libcfg/init.c, libcfg/virtdomain.c, maidag/maidag.c,
mail.local/main.c, mail.remote/mail.remote.c, mimeview/mimeview.c,
movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
sieve/sieve.c: Change option parsing, usig mu_cfg_tree_ functions.

* mailbox/argcv.c: Fix a typo in comment.
* mailbox/cfg_lexer.c (mu_parse_config_tree): New function.
(_mu_parse_config): Rewrite using mu_parse_config_tree.
* mailbox/cfg_parser.y (mu_cfg_format_error,_mu_cfg_vperror)
(debug_print_node): Use default diag debug_t object, if the passed
one is NULL. Reset locus after formatting.
(mu_cfg_postorder): Return immediately if node == NULL.
(mu_cfg_tree_create,mu_cfg_tree_set_debug,mu_cfg_tree_set_alloc)
(mu_cfg_tree_alloc,mu_cfg_tree_free,mu_cfg_tree_create_node)
(mu_cfg_tree_add_node): New functions.
* mailbox/gocs.c (mu_gocs_store): Make sure no capa/data tuple
gets registered twice.
1 parent 0112e3c0
2007-12-03 Sergey Poznyakoff <gray@gnu.org.ua>
* auth/virtual.c (site_virtual_pwddir): Replace with global
struct mu_gocs_virtual mu_virtual_module_config
* include/mailutils/cfg.h (MU_PARSE_CONFIG_GLOBAL)
(MU_PARSE_CONFIG_VERBOSE, MU_PARSE_CONFIG_DUMP): New defines.
(mu_cfg_tree_create,mu_cfg_tree_set_debug,mu_cfg_tree_set_alloc)
(mu_cfg_tree_alloc,mu_cfg_tree_free)
(mu_cfg_tree_create_node,mu_cfg_tree_add_node): New functions.
* include/mailutils/gocs.h (struct mu_gocs_virtual): New data
type.
* include/mailutils/libargp.h (struct mu_argp_node_list): New data
type.
(mu_argp_node_list_init, mu_argp_node_list_add)
(mu_argp_node_list_new, mu_argp_node_list_finish): New functions.
* libargp/cmdline.h: New header.
* libargp/Makefile.am (libmuargp_a_SOURCES): Add cmdline.h.
* dotlock/dotlock.c, imap4d/imap4d.c, libargp/auth.c,
libargp/cmdline.c, libargp/common.c, libargp/compat.c,
libargp/gsasl.c, libargp/mu_argp.c, libargp/muinit.c,
libargp/pam.c, libargp/radius.c, libargp/sieve.c, libargp/sql.c,
libargp/tls.c, libargp/virtdomain.c, libcfg/common.c,
libcfg/init.c, libcfg/virtdomain.c, maidag/maidag.c,
mail.local/main.c, mail.remote/mail.remote.c, mimeview/mimeview.c,
movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
sieve/sieve.c: Change option parsing, usig mu_cfg_tree_ functions.
* mailbox/argcv.c: Fix a typo in comment.
* mailbox/cfg_lexer.c (mu_parse_config_tree): New function.
(_mu_parse_config): Rewrite using mu_parse_config_tree.
* mailbox/cfg_parser.y (mu_cfg_format_error,_mu_cfg_vperror)
(debug_print_node): Use default diag debug_t object, if the passed
one is NULL. Reset locus after formatting.
(mu_cfg_postorder): Return immediately if node == NULL.
(mu_cfg_tree_create,mu_cfg_tree_set_debug,mu_cfg_tree_set_alloc)
(mu_cfg_tree_alloc,mu_cfg_tree_free,mu_cfg_tree_create_node)
(mu_cfg_tree_add_node): New functions.
* mailbox/gocs.c (mu_gocs_store): Make sure no capa/data tuple
gets registered twice.
* NEWS: Update.
* gnulib.modules: Add des. Sort lines.
* imap4d/Makefile.am (imap4d_SOURCES): Add preauth.c
......@@ -7,13 +47,13 @@
* imap4d/authenticate.c (imap4d_authenticate): Use
imap4d_session_setup.
* imap4d/imap4d.c (imap4d_session_setup)
(imap4d_session_setup.0): New functions.
(imap4d_session_setup0): New functions.
(imap4d_mainloop): Implement PREAUTH mode.
* imap4d/imap4d.h (RESP_PREAUTH): New define.
(enum imap4d_preauth): New data type.
(preauth_mode,preauth_program,preauth_only,ident_port): New
globals.
(imap4d_session_setup,imap4d_session_setup.0): New functions.
(imap4d_session_setup,imap4d_session_setup0): New functions.
* imap4d/login.c (imap4d_login): Use imap4d_session_setup0.
* imap4d/util.c (sc2string): Handle RESP_PREAUTH
......
......@@ -55,17 +55,15 @@
#ifdef ENABLE_VIRTUAL_DOMAINS
/* FIXME: Make global, prefix with mu_ */
static char *site_virtual_pwddir = SITE_VIRTUAL_PWDDIR;
struct mu_gocs_virtual mu_virtual_module_config = { SITE_VIRTUAL_PWDDIR };
int
mu_virtual_module_init (void *data)
{
if (data)
{
site_virtual_pwddir = strdup (data);
if (!site_virtual_pwddir)
return 1;
struct mu_gocs_virtual *p = data;
mu_virtual_module_config = *p;
}
return 0;
}
......@@ -91,12 +89,12 @@ getpwnam_virtual (const char *u)
if (delim == 0)
return NULL;
filename = malloc (strlen (site_virtual_pwddir) +
filename = malloc (strlen (mu_virtual_module_config.pwddir) +
strlen (&u[delim + 1]) + 2 /* slash and null byte */);
if (filename == NULL)
return NULL;
sprintf (filename, "%s/%s", site_virtual_pwddir, &u[delim + 1]);
sprintf (filename, "%s/%s", mu_virtual_module_config.pwddir, &u[delim + 1]);
pfile = fopen (filename, "r");
free (filename);
......
......@@ -77,10 +77,12 @@ static int debug;
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case 'd':
debug = 1;
mu_argp_node_list_new (&lst, "debug", "yes");
break;
case 'u':
......@@ -89,21 +91,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'r':
if (arg)
{
retries = atoi (arg);
if (retries <= 0)
argp_error (state, _("RETRIES must be greater than 0"));
}
flags |= MU_LOCKER_RETRY;
mu_argp_node_list_new (&lst, "retry", arg);
break;
case 'f':
if (arg)
{
force = atoi (arg);
if (force <= 0)
argp_error (state, _("MINUTES must be greater than 0"));
}
mu_argp_node_list_new (&lst, "force", arg ? arg : "0");
break;
case ARGP_KEY_ARG:
......@@ -115,6 +107,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
case ARGP_KEY_NO_ARGS:
argp_error (state, _("FILE must be specified"));
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
......@@ -166,6 +166,9 @@ main (int argc, char *argv[])
force *= 60;
flags |= MU_LOCKER_TIME;
}
if (retries != 0)
flags |= MU_LOCKER_RETRY;
if ((err = mu_locker_create (&locker, file, flags)))
{
......
......@@ -110,40 +110,41 @@ static int imap4d_mainloop (int, FILE *, FILE *);
static error_t
imap4d_parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case ARGP_KEY_INIT:
state->child_inputs[0] = state->input;
break;
case 'O':
set_namespace (NS_OTHER, arg);
mu_argp_node_list_new (&lst, "other-namespace", arg);
break;
case 'S':
set_namespace (NS_SHARED, arg);
mu_argp_node_list_new (&lst, "shared-namespace", arg);
break;
case ARG_LOGIN_DISABLED:
login_disabled = 1;
mu_argp_node_list_new (&lst, "login-disabled", "yes");
break;
case ARG_CREATE_HOME_DIR:
create_home_dir = 1;
mu_argp_node_list_new (&lst, "create-home-dir", "yes");
if (arg)
{
char *p;
home_dir_mode = strtoul (arg, &p, 8);
if (p || (home_dir_mode & 0777))
argp_error (state, _("Invalid mode specification: %s"), arg);
}
mu_argp_node_list_new (&lst, "home-dir-mode", arg);
break;
#ifdef WITH_TLS
case ARG_TLS_REQUIRED:
tls_required = 1;
mu_argp_node_list_new (&lst, "tls-required", "yes");
break;
#endif
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
......@@ -170,7 +171,7 @@ cb_mode (mu_debug_t debug, void *data, char *arg)
{
char *p;
home_dir_mode = strtoul (arg, &p, 8);
if (p || (home_dir_mode & 0777))
if (p[0] || (home_dir_mode & ~0777))
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("Invalid mode specification: %s"), arg);
return 0;
......
......@@ -198,14 +198,30 @@ int mu_config_register_plain_section (const char *parent_path,
const char *ident,
struct mu_cfg_param *params);
#define MU_PARSE_CONFIG_GLOBAL 0x1
#define MU_PARSE_CONFIG_VERBOSE 0x2
#define MU_PARSE_CONFIG_DUMP 0x4
int mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global);
struct mu_cfg_param *progparam, int flags);
int mu_cfg_parse_boolean (const char *str, int *res);
extern int mu_cfg_parser_verbose;
void mu_cfg_format_tree (mu_stream_t stream, mu_cfg_tree_t *tree);
void mu_cfg_format_tree (mu_stream_t stream, struct mu_cfg_tree *tree);
int mu_cfg_tree_create (struct mu_cfg_tree **ptree);
void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug);
void mu_cfg_tree_set_alloc (struct mu_cfg_tree *tree,
mu_cfg_alloc_t alloc, mu_cfg_free_t free);
void *mu_cfg_tree_alloc (struct mu_cfg_tree *tree, size_t size);
void mu_cfg_tree_free (struct mu_cfg_tree *tree, void *mem);
mu_cfg_node_t *mu_cfg_tree_create_node
(struct mu_cfg_tree *tree, enum mu_cfg_node_type type,
mu_cfg_locus_t *loc, char *tag, char *label,
mu_cfg_node_t *node);
void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node);
#ifdef __cplusplus
}
......
......@@ -80,6 +80,11 @@ struct mu_gocs_pam
char *service;
};
struct mu_gocs_virtual
{
char *pwddir;
};
/* Auxiliary variables for use by libargp/libcfg */
extern int mu_load_user_rcfile;
extern int mu_load_site_rcfile;
......
......@@ -79,6 +79,18 @@ error_t mu_argp_parse (const struct argp *myargp,
const char *capa[],
int *arg_index,
void *input) __attribute__ ((deprecated));
struct mu_argp_node_list
{
int count;
mu_cfg_node_t *head, *tail;
};
void mu_argp_node_list_init (struct mu_argp_node_list *);
void mu_argp_node_list_add (struct mu_argp_node_list *, mu_cfg_node_t *);
void mu_argp_node_list_new (struct mu_argp_node_list *,
char *, char *);
void mu_argp_node_list_finish (struct mu_argp_node_list *, char *, char *);
#ifdef __cplusplus
}
......
......@@ -27,6 +27,7 @@ lib_LIBRARIES = libmuargp.a
libmuargp_a_SOURCES =\
auth.c\
cmdline.c\
cmdline.h\
common.c\
compat.c\
gsasl.c\
......
......@@ -19,7 +19,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include "mailutils/mu_auth.h"
......@@ -80,27 +80,32 @@ auth_set_debug ()
static error_t
mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_auth_finish_setup ();
mu_argp_node_list_finish (&lst, "auth", NULL);
break;
/* authentication */
case OPT_AUTHORIZATION:
mu_authorization_add_module_list (arg);
mu_argp_node_list_new (&lst, "authorization", arg);
break;
case OPT_AUTHENTICATION:
mu_authentication_add_module_list (arg);
mu_argp_node_list_new (&lst, "authentication", arg);
break;
case OPT_CLEAR_AUTHENTICATION:
mu_authentication_clear_list ();
mu_argp_node_list_new (&lst, "authentication", "clear");
break;
case OPT_CLEAR_AUTHORIZATION:
mu_authorization_clear_list ();
mu_argp_node_list_new (&lst, "authorization", "clear");
break;
case OPT_DEBUG_AUTH:
......
......@@ -19,7 +19,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
static struct mu_cmdline_capa *all_cmdline_capa[] = {
&mu_common_cmdline,
......@@ -63,5 +63,53 @@ mu_libargp_init ()
}
}
void
mu_argp_node_list_init (struct mu_argp_node_list *lst)
{
lst->count = 0;
lst->head = lst->tail = NULL;
}
void
mu_argp_node_list_add (struct mu_argp_node_list *lst, mu_cfg_node_t *node)
{
lst->count++;
if (lst->tail)
lst->tail->next = node;
else
lst->head = node;
lst->tail = node;
}
void
mu_argp_node_list_new (struct mu_argp_node_list *lst,
char *tag, char *label)
{
mu_cfg_node_t *node;
mu_cfg_locus_t loc = { "command line", 0 };
loc.line = lst->count;
node = mu_cfg_tree_create_node (mu_argp_tree, mu_cfg_node_param,
&loc, tag, label, NULL);
mu_argp_node_list_add (lst, node);
}
void
mu_argp_node_list_finish (struct mu_argp_node_list *lst, char *tag,
char *label)
{
mu_cfg_node_t *node;
if (!lst->head)
return;
if (tag)
node = mu_cfg_tree_create_node (mu_argp_tree,
mu_cfg_node_tag,
NULL,
tag, label,
lst->head);
else
node = lst->head;
mu_cfg_tree_add_node (mu_argp_tree, node);
mu_argp_node_list_init (lst);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2007 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#include "mailutils/libcfg.h"
#include "mailutils/libargp.h"
extern struct mu_cfg_tree *mu_argp_tree;
......@@ -19,45 +19,11 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include <string.h>
#include <mailutils/syslog.h>
#include <mailutils/daemon.h>
static struct mu_gocs_daemon daemon_settings;
static struct mu_gocs_locking locking_settings;
static struct mu_gocs_logging logging_settings;
static struct mu_gocs_mailbox mailbox_settings;
static struct mu_gocs_source_email source_email_settings;
static struct mu_gocs_mailer mailer_settings;
static struct mu_gocs_debug debug_settings;
void
assign_string (char **pstr, char *val)
{
if (!val)
{
if (*pstr)
{
free (*pstr);
*pstr = NULL;
}
}
else
{
size_t size = strlen (val);
char *p = realloc (*pstr, size + 1);
if (!p)
{
mu_error ("%s", mu_strerror (ENOMEM));
exit (1);
}
strcpy (p, val);
*pstr = p;
}
}
/* ************************************************************************* */
/* Common */
......@@ -158,17 +124,21 @@ static struct argp_option mu_logging_argp_option[] = {
static error_t
mu_logging_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
/* log */
case OPT_LOG_FACILITY:
if (mu_string_to_syslog_facility (arg, &logging_settings.facility))
mu_error (_("Unknown syslog facility `%s'"), arg);
/* FIXME: error reporting */
mu_argp_node_list_new (&lst, "facility", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("logging", &logging_settings);
mu_argp_node_list_finish (&lst, "logging", NULL);
break;
default:
......@@ -253,19 +223,25 @@ static struct argp_option mu_mailbox_argp_option[] = {
static error_t
mu_mailbox_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
/* mailbox */
case 'm':
assign_string (&mailbox_settings.mail_spool, arg);
mu_argp_node_list_new (&lst, "mail-spool", arg);
break;
case OPT_MAILBOX_TYPE:
assign_string (&mailbox_settings.mailbox_type, arg);
mu_argp_node_list_new (&lst, "mailbox-type", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("mailbox", &mailbox_settings);
mu_argp_node_list_finish (&lst, "mailbox", NULL);
break;
default:
......@@ -314,30 +290,36 @@ static struct argp_option mu_locking_argp_option[] = {
static error_t
mu_locking_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_LOCK_FLAGS:
assign_string (&locking_settings.lock_flags, arg);
mu_argp_node_list_new (&lst, "flags", arg);
break;
case OPT_LOCK_RETRY_COUNT:
locking_settings.lock_retry_count = strtoul (arg, NULL, 0);
mu_argp_node_list_new (&lst, "retry-count", arg);
break;
case OPT_LOCK_RETRY_TIMEOUT:
locking_settings.lock_retry_timeout = strtoul (arg, NULL, 0);
mu_argp_node_list_new (&lst, "retry-timeout", arg);
break;
case OPT_LOCK_EXPIRE_TIMEOUT:
locking_settings.lock_expire_timeout = strtoul (arg, NULL, 0);
mu_argp_node_list_new (&lst, "expire-timeout", arg);
break;
case OPT_LOCK_EXTERNAL_PROGRAM:
assign_string (&locking_settings.external_locker, arg);
mu_argp_node_list_new (&lst, "external-locker", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("locking", &locking_settings);
mu_argp_node_list_finish (&lst, "locking", NULL);
break;
default:
......@@ -379,18 +361,24 @@ static struct argp_option mu_address_argp_option[] = {
static error_t
mu_address_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case 'E':
assign_string (&source_email_settings.address, arg);
mu_argp_node_list_new (&lst, "email-addr", arg);
break;
case 'D':
assign_string (&source_email_settings.domain, arg);
mu_argp_node_list_new (&lst, "email-domain", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("address", &source_email_settings);
mu_argp_node_list_finish (&lst, "address", NULL);
break;
default:
......@@ -430,15 +418,21 @@ static struct argp_option mu_mailer_argp_option[] = {
static error_t
mu_mailer_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
/* mailer */
case 'M':
assign_string (&mailer_settings.mailer, arg);
mu_argp_node_list_new (&lst, "url", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("mailer", &mailer_settings);
mu_argp_node_list_finish (&lst, "mailer", NULL);
break;
default:
......@@ -488,51 +482,40 @@ static struct argp_option mu_daemon_argp_option[] = {
static error_t
mu_daemon_argp_parser (int key, char *arg, struct argp_state *state)
{
static int options_given = 0;
static struct mu_argp_node_list lst;
switch (key)
{
case 'd':
options_given = 1;
daemon_settings.mode = MODE_DAEMON;
if (arg)
daemon_settings.maxchildren = strtoul (arg, NULL, 10);
mu_argp_node_list_new (&lst, "mode", arg);
break;
case 'i':
options_given = 1;
daemon_settings.mode = MODE_INTERACTIVE;
mu_argp_node_list_new (&lst, "mode", "inetd");
break;
case 'p':
options_given = 1;
daemon_settings.mode = MODE_DAEMON;
daemon_settings.port = strtoul (arg, NULL, 10); /*FIXME: overflow */
mu_argp_node_list_new (&lst, "port", arg);
break;
case 'P':
options_given = 1;
assign_string (&daemon_settings.pidfile, arg);
mu_argp_node_list_new (&lst, "pidfile", arg);
break;
case 't':
options_given = 1;
daemon_settings.timeout = strtoul (arg, NULL, 10);
mu_argp_node_list_new (&lst, "timeout", arg);
break;
case 'x':
options_given = 1;
daemon_settings.transcript = 1;
mu_argp_node_list_new (&lst, "transcript", "yes");
break;
case ARGP_KEY_INIT:
options_given = 0;
daemon_settings = mu_gocs_daemon;
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
if (options_given)
mu_gocs_store ("daemon", &daemon_settings);
mu_argp_node_list_finish (&lst, "daemon", NULL);
break;
default:
......@@ -570,23 +553,24 @@ static struct argp_option mu_debug_argp_options[] =
static error_t
mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_DEBUG_LEVEL:
debug_settings.string = arg;
debug_settings.errpfx = strdup ("command line");
mu_argp_node_list_new (&lst, "level", arg);
break;
case OPT_LINE_INFO:
debug_settings.line_info = 1;
mu_argp_node_list_new (&lst, "line-info", "yes");
break;
case ARGP_KEY_INIT:
debug_settings.line_info = -1;
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("debug", &debug_settings);
mu_argp_node_list_finish (&lst, "debug", NULL);
break;
default:
......
......@@ -19,7 +19,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include <mailutils/gsasl.h>
#define OPT_CRAM_PASSWD 256
......@@ -30,21 +30,23 @@ static struct argp_option _gsasl_argp_options[] = {
{ NULL, 0, NULL, 0, NULL, 0 }
};
static struct mu_gsasl_module_data gsasl_data = {
SITE_CRAM_MD5_PWD
};
static error_t
_gsasl_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_CRAM_PASSWD:
gsasl_data.cram_md5_pwd = arg;
mu_argp_node_list_new (&lst, "cram-passwd", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("gsasl", &gsasl_data);
mu_argp_node_list_finish (&lst, "gsasl", NULL);
break;
default:
......
......@@ -72,7 +72,7 @@ find_capa (const char *name)
}
static struct argp *
mu_build_argp (const struct argp *template, const char *capa[])
mu_build_argp (const struct argp *template, char **capa)
{
int n;
int nchild;
......@@ -159,7 +159,7 @@ cap_buf_init (struct cap_buf *bp)
}
static void
cap_buf_add (struct cap_buf *bp, const char *str)
cap_buf_add (struct cap_buf *bp, char *str)
{
if (bp->numcapa == bp->maxcapa)
{
......
......@@ -19,9 +19,10 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "cmdline.h"
#include <mailutils/stream.h>
#include "mailutils/libcfg.h"
#include "mailutils/libargp.h"
struct mu_cfg_tree *mu_argp_tree;
void
mu_argp_init (const char *vers, const char *bugaddr)
......@@ -30,6 +31,8 @@ mu_argp_init (const char *vers, const char *bugaddr)
argp_program_bug_address = bugaddr ? bugaddr : "<" PACKAGE_BUGREPORT ">";
}
extern struct mu_cfg_cont *mu_cfg_root_container; /* FIXME */
int
mu_app_init (struct argp *myargp, const char **capa,
struct mu_cfg_param *cfg_param,
......@@ -39,7 +42,8 @@ mu_app_init (struct argp *myargp, const char **capa,
struct argp *argp;
const struct argp argpnull = { 0 };
char **excapa;
int flags = 0;
mu_set_program_name (argv[0]);
mu_libargp_init ();
for (i = 0; capa[i]; i++)
......@@ -47,6 +51,8 @@ mu_app_init (struct argp *myargp, const char **capa,
if (!myargp)
myargp = &argpnull;
argp = mu_argp_build (myargp, &excapa);
mu_cfg_tree_create (&mu_argp_tree);
rc = argp_parse (argp, argc, argv, flags, pindex, data);
mu_argp_done (argp);
if (rc)
......@@ -55,8 +61,16 @@ mu_app_init (struct argp *myargp, const char **capa,
mu_libcfg_init (excapa);
free (excapa);
mu_parse_config_files (cfg_param);
if (mu_cfg_parser_verbose)
flags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
flags |= MU_PARSE_CONFIG_DUMP;
rc = mu_parse_config_tree (mu_argp_tree, mu_program_name, cfg_param, flags);
mu_gocs_flush ();
mu_cfg_destroy_tree (&mu_argp_tree);
return 0;
}
......
......@@ -20,24 +20,28 @@
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include <mailutils/pam.h>
static struct mu_gocs_pam pam_settings;
#define OPT_PAM_SERVICE 256
static error_t
mu_pam_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_PAM_SERVICE:
pam_settings.service = arg;
mu_argp_node_list_new (&lst, "service", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("pam", &pam_settings);
mu_argp_node_list_finish (&lst, "pam", NULL);
break;
default:
......
......@@ -20,7 +20,7 @@
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include <mailutils/radius.h>
enum {
......@@ -42,32 +42,35 @@ static struct argp_option mu_radius_argp_option[] = {
{ NULL }
};
static struct mu_radius_module_data radius_data;
static error_t
mu_radius_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_AUTH_REQUEST:
radius_data.auth_request = arg;
mu_argp_node_list_new (&lst, "auth-request", arg);
break;
case OPT_GETPWNAM_REQUEST:
radius_data.getpwnam_request = arg;
mu_argp_node_list_new (&lst, "getwnam-request", arg);
break;
case OPT_GETPWUID_REQUEST:
radius_data.getpwuid_request = arg;
mu_argp_node_list_new (&lst, "getwuid-request", arg);
break;
case OPT_RADIUS_DIR:
radius_data.config_dir = arg;
mu_argp_node_list_new (&lst, "directory", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("radius", &radius_data);
mu_argp_node_list_finish (&lst, "radius", NULL);
break;
default:
......
......@@ -20,7 +20,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "cmdline.h"
#include "mailutils/libsieve.h"
enum {
......@@ -44,54 +44,37 @@ static struct argp_option sieve_argp_option[] = {
static error_t
sieve_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_gocs_sieve gocs_data;
mu_list_t *plist = NULL;
static struct mu_argp_node_list lst;
switch (key)
{
case 'I':
plist = &gocs_data.include_path;
mu_argp_node_list_new (&lst, "include-path", arg);
break;
case 'L':
plist = &gocs_data.library_path;
mu_argp_node_list_new (&lst, "library-path", arg);
break;
case OPT_CLEAR_INCLUDE_PATH:
gocs_data.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
mu_argp_node_list_new (&lst, "clear-include-path", "yes");
break;
case OPT_CLEAR_LIBRARY_PATH:
gocs_data.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
mu_argp_node_list_new (&lst, "clear-library-path", "yes");
break;
case ARGP_KEY_INIT:
memset (&gocs_data, 0, sizeof gocs_data);
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("sieve", &gocs_data);
mu_argp_node_list_finish (&lst, "sieve", NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
if (plist)
{
if (!*plist)
{
int rc = mu_list_create (plist);
if (rc)
{
argp_error (state, _("cannot create list: %s"),
mu_strerror (rc));
exit (1);
}
}
mu_list_append (*plist, arg);
}
return 0;
}
......
......@@ -20,13 +20,7 @@
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include "mailutils/sql.h"
#include "mailutils/mutil.h"
static int sql_requested;
static struct mu_sql_module_config sql_config;
/* Command-line configuration */
#include "cmdline.h"
enum {
OPT_SQL_INTERFACE = 256,
......@@ -72,72 +66,60 @@ static struct argp_option mu_sql_argp_option[] = {
static error_t
mu_sql_argp_parser (int key, char *arg, struct argp_state *state)
{
int rc, err;
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_SQL_INTERFACE:
sql_config.interface = arg;
sql_requested = 1;
mu_argp_node_list_new (&lst, "interface", arg);
break;
case OPT_SQL_GETPWNAM:
sql_requested = 1;
sql_config.getpwnam_query = arg;
mu_argp_node_list_new (&lst, "getpwnam", arg);
break;
case OPT_SQL_GETPWUID:
sql_requested = 1;
sql_config.getpwuid_query = arg;
mu_argp_node_list_new (&lst, "getpwuid", arg);
break;
case OPT_SQL_GETPASS:
sql_requested = 1;
sql_config.getpass_query = arg;
mu_argp_node_list_new (&lst, "getpass", arg);
break;
case OPT_SQL_HOST:
sql_requested = 1;
sql_config.host = arg;
mu_argp_node_list_new (&lst, "host", arg);
break;
case OPT_SQL_USER:
sql_requested = 1;
sql_config.user = arg;
mu_argp_node_list_new (&lst, "user", arg);
break;
case OPT_SQL_PASSWD:
sql_requested = 1;
sql_config.passwd = arg;
mu_argp_node_list_new (&lst, "passwd", arg);
break;
case OPT_SQL_DB:
sql_requested = 1;
sql_config.db = arg;
mu_argp_node_list_new (&lst, "db", arg);
break;
case OPT_SQL_PORT:
sql_requested = 1;
sql_config.port = strtoul (arg, NULL, 0);
mu_argp_node_list_new (&lst, "port", arg);
break;
case OPT_SQL_MU_PASSWORD_TYPE:
if (mu_sql_decode_password_type (arg, &sql_config.password_type))
argp_error (state, _("Unknown password type `%s'"), arg);
sql_requested = 1;
mu_argp_node_list_new (&lst, "password-type", arg);
break;
case OPT_SQL_FIELD_MAP:
rc = mutil_parse_field_map (arg, &sql_config.field_map, &err);
if (rc)
argp_error (state, _("Error near element %d: %s"),
err, mu_strerror (rc));
sql_requested = 1;
mu_argp_node_list_new (&lst, "field-map", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
if (sql_requested)
mu_gocs_store ("sql", &sql_config);
mu_argp_node_list_finish (&lst, "sql", NULL);
break;
default:
......
......@@ -20,8 +20,7 @@
# include <config.h>
#endif
#include "mailutils/libargp.h"
#include <mailutils/tls.h>
#include "cmdline.h"
enum {
OPT_TLS = 256,
......@@ -42,34 +41,35 @@ static struct argp_option _tls_argp_options[] = {
{NULL, 0, NULL, 0, NULL, 0}
};
static struct mu_tls_module_config tls_data = { 1, };
static error_t
_tls_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_TLS:
if (!arg || strcasecmp (arg, "yes") == 0)
tls_data.client_enable = 1;
else if (strcasecmp (arg, "no") == 0)
tls_data.client_enable = 0;
mu_argp_node_list_new (&lst, "tls", arg);
break;
case OPT_SSL_CERT:
tls_data.ssl_cert = arg;
mu_argp_node_list_new (&lst, "ssl-cert", arg);
break;
case OPT_SSL_KEY:
tls_data.ssl_key = arg;
mu_argp_node_list_new (&lst, "ssl-key", arg);
break;
case OPT_SSL_CAFILE:
tls_data.ssl_cafile = arg;
mu_argp_node_list_new (&lst, "ssl-cafile", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("tls", &tls_data);
mu_argp_node_list_finish (&lst, "tls", NULL);
break;
default:
......
......@@ -20,23 +20,27 @@
# include <config.h>
#endif
#include "mailutils/libargp.h"
static char *virtdir;
#include "cmdline.h"
#define OPT_PWDDIR 256
static error_t
mu_virt_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case OPT_PWDDIR:
virtdir = arg;
mu_argp_node_list_new (&lst, "passwd-dir", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_gocs_store ("virtdomain", virtdir);
mu_argp_node_list_finish (&lst, "virtdomain", NULL);
break;
default:
......
......@@ -155,7 +155,8 @@ mu_daemon_section_parser
daemon_settings = mu_gocs_daemon;
break;
case mu_cfg_section_end:
case mu_cfg_section_end:
mu_gocs_daemon = daemon_settings;
mu_gocs_store ("daemon", &daemon_settings);
}
return 0;
......@@ -180,18 +181,23 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg)
struct mu_debug_locus locus;
debug_settings.string = arg;
mu_debug_get_locus (debug, &locus);
p = umaxtostr (locus.line, buf);
size = strlen (locus.file) + 1 + strlen (p) + 1;
pfx = malloc (size);
if (!pfx)
if (mu_debug_get_locus (debug, &locus) == 0)
{
mu_cfg_format_error (debug, MU_DEBUG_ERROR, "%s", mu_strerror (errno));
return 1;
p = umaxtostr (locus.line, buf);
size = strlen (locus.file) + 1 + strlen (p) + 1;
pfx = malloc (size);
if (!pfx)
{
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
"%s", mu_strerror (errno));
return 1;
}
strcpy (pfx, locus.file);
strcat (pfx, ":");
strcat (pfx, p);
}
strcpy (pfx, locus.file);
strcat (pfx, ":");
strcat (pfx, p);
else
pfx = strdup ("command line");/*FIXME*/
debug_settings.errpfx = pfx;
return 0;
}
......
......@@ -87,8 +87,16 @@ mu_libcfg_init (const char **cnames)
int
mu_parse_config_files (struct mu_cfg_param *param)
{
int flags = 0;
if (mu_cfg_parser_verbose)
flags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
flags |= MU_PARSE_CONFIG_DUMP;
if (mu_load_site_rcfile)
mu_parse_config (MU_CONFIG_FILE, mu_program_name, param, 1);
mu_parse_config (MU_CONFIG_FILE, mu_program_name, param,
flags | MU_PARSE_CONFIG_GLOBAL);
if (mu_load_user_rcfile && mu_program_name)
{
......@@ -99,14 +107,14 @@ mu_parse_config_files (struct mu_cfg_param *param)
strcpy (file_name, "~/.");
strcat (file_name, mu_program_name);
mu_parse_config (file_name, mu_program_name, param, 0);
mu_parse_config (file_name, mu_program_name, param, flags);
free (file_name);
}
}
if (mu_load_rcfile)
mu_parse_config (mu_load_rcfile, mu_program_name, param, 0);
mu_parse_config (mu_load_rcfile, mu_program_name, param, flags);
return 0;
}
......
......@@ -21,7 +21,7 @@
#include <stdlib.h>
#include "mailutils/libcfg.h"
static char *virtdomain_settings;
static struct mu_gocs_virtual virtdomain_settings;
static struct mu_cfg_param mu_virtdomain_param[] = {
{ "passwd-dir", mu_cfg_string, &virtdomain_settings },
......
......@@ -169,19 +169,17 @@ set_debug_flags (mu_debug_t debug, const char *arg)
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case ARGP_KEY_INIT:
state->child_inputs[0] = state->input;
break;
case MESSAGE_ID_HEADER_OPTION:
message_id_header = arg;
mu_argp_node_list_new (&lst, "message-id-header", arg);
break;
case LMTP_OPTION:
lmtp_mode = 1;
lmtp_url_string = arg;
mu_argp_node_list_new (&lst, "lmtp", "yes");
mu_argp_node_list_new (&lst, "listen", arg);
break;
case 'r':
......@@ -196,27 +194,35 @@ parse_opt (int key, char *arg, struct argp_state *state)
#ifdef WITH_GUILE
case 's':
progfile_pattern = arg;
mu_argp_node_list_new (&lst, "guile-filter", arg);
break;
#endif
case 'S':
sieve_pattern = arg;
mu_argp_node_list_new (&lst, "sieve-filter", arg);
break;
case 'x':
set_debug_flags (NULL, arg ? arg : D_DEFAULT);
mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT);
break;
case STDERR_OPTION:
log_to_stderr = 1;
mu_argp_node_list_new (&lst, "stderr", "yes");
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
case ARGP_KEY_ERROR:
exit (EX_USAGE);
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
......
......@@ -179,22 +179,24 @@ set_debug_flags (mu_debug_t debug, const char *arg)
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case ARG_MULTIPLE_DELIVERY:
multiple_delivery = 1;
mu_argp_node_list_new (&lst, "ex-multiple-delivery-success", "yes");
break;
case ARG_QUOTA_TEMPFAIL:
ex_quota_tempfail = 1;
mu_argp_node_list_new (&lst, "ex-quota-tempfail", "yes");
break;
case ARG_MESSAGE_ID_HEADER:
message_id_header = arg;
mu_argp_node_list_new (&lst, "message-id-header", arg);
break;
case ARG_QUOTA_QUERY:
quota_query = arg;
mu_argp_node_list_new (&lst, "quota-query", arg);
break;
case 'r':
......@@ -209,24 +211,30 @@ parse_opt (int key, char *arg, struct argp_state *state)
#ifdef USE_DBM
case 'q':
quotadbname = arg;
mu_argp_node_list_new (&lst, "quota-db", arg);
break;
#endif
#ifdef WITH_GUILE
case 's':
progfile_pattern = arg;
mu_argp_node_list_new (&lst, "source", arg);
break;
#endif
case 'S':
sieve_pattern = arg;
mu_argp_node_list_new (&lst, "sieve", arg);
break;
case 'x':
if (!arg)
arg = D_DEFAULT;
set_debug_flags (NULL, arg);
mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
......
......@@ -87,14 +87,17 @@ static int read_recipients; /* Read recipients from the message */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static int dbug = 0;
switch (key)
{
case 'f':
optfrom = arg;
mu_argp_node_list_new (&lst, "from", arg);
break;
case 'd':
optdebug++;
dbug++;
break;
case 'o':
......@@ -103,7 +106,17 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 't':
read_recipients = 1;
mu_argp_node_list_new (&lst, "read-recipients", "yes");
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
if (dbug)
mu_argp_node_list_new (&lst, "debug", mu_umaxtostr (0, dbug));
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
......
......@@ -395,7 +395,7 @@ argcv_free (int argc, char **argv)
return 0;
}
/* Take a argv an make string separated by ' '. */
/* Make a argv an make string separated by ' '. */
int
argcv_string (int argc, char **argv, char **pstring)
......
......@@ -14,7 +14,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
......@@ -33,6 +35,7 @@
#include <mailutils/refcount.h>
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#include <mailutils/stream.h>
#include "cfg_parser.h"
......@@ -530,7 +533,7 @@ _clone_action (void *item, void *cbdata)
int
mu_config_clone_container (struct mu_cfg_cont *cont)
{
int n = mu_refcount_inc (cont->refcount);
mu_refcount_inc (cont->refcount);
/* printf("clone %p-%s: %d\n", cont, cont->v.section.ident, n); */
switch (cont->type)
{
......@@ -681,11 +684,11 @@ struct include_data
{
const char *progname;
struct mu_cfg_param *progparam;
int global;
int flags;
};
static int _mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global);
struct mu_cfg_param *progparam, int flags);
static int
_cb_include (mu_debug_t debug, void *data, char *arg)
......@@ -708,7 +711,7 @@ _cb_include (mu_debug_t debug, void *data, char *arg)
}
else
ret = _mu_parse_config (dirname, idp->progname, idp->progparam,
idp->global);
idp->flags);
}
else if (errno == ENOENT)
{
......@@ -727,51 +730,13 @@ _cb_include (mu_debug_t debug, void *data, char *arg)
return ret;
}
static int
_mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global)
int
mu_parse_config_tree (mu_cfg_tree_t *parse_tree, const char *progname,
struct mu_cfg_param *progparam, int flags)
{
struct lexer_data data;
struct stat st;
int fd;
int rc;
mu_cfg_tree_t *parse_tree;
if (stat (file, &st))
{
if (errno != ENOENT)
mu_error (_("can't stat `%s'"), file);
return -1;
}
fd = open (file, O_RDONLY);
if (fd == -1)
{
mu_error (_("cannot open config file `%s'"), file);
return -1;
}
if (mu_cfg_parser_verbose)
mu_error (_("Info: parsing file `%s'"), file);
int rc = 1;
memset (&data, 0, sizeof data);
data.buffer = malloc (st.st_size+1);
read (fd, data.buffer, st.st_size);
data.buffer[st.st_size] = 0;
close (fd);
data.curp = data.buffer;
/* Parse configuration */
mu_cfg_locus.file = (char*) file;
mu_cfg_locus.line = 1;
rc = mu_cfg_parse (&parse_tree,
&data,
default_lexer,
NULL,
NULL,
NULL);
if (rc == 0 && root_container)
if (root_container)
{
struct mu_cfg_cont *cont = root_container;
struct include_data idata;
......@@ -779,14 +744,14 @@ _mu_parse_config (const char *file, const char *progname,
{ "include", mu_cfg_callback, &idata, _cb_include },
{ NULL }
};
mu_config_clone_container (cont);
idata.progname = progname;
idata.progparam = progparam;
idata.global = global;
idata.flags = flags & MU_PARSE_CONFIG_GLOBAL;
_mu_config_register_section (&cont, NULL, NULL, NULL,
(void*) progname, mu_include_param, NULL);
if (global)
if (flags & MU_PARSE_CONFIG_GLOBAL)
{
mu_iterator_t iter;
struct mu_cfg_section *prog_sect;
......@@ -798,7 +763,7 @@ _mu_parse_config (const char *file, const char *progname,
_mu_config_register_section (&cont, NULL, "program", prog_parser,
(void*) progname,
progparam, &prog_sect);
if (old_root->v.section.subsec)
{
if (!prog_sect->subsec)
......@@ -837,12 +802,72 @@ _mu_parse_config (const char *file, const char *progname,
mu_config_destroy_container (&cont);
}
if (flags & MU_PARSE_CONFIG_DUMP)
{
mu_stream_t stream;
mu_stdio_stream_create (&stream, stderr,
MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE);
mu_stream_open (stream);
mu_cfg_format_tree (stream, parse_tree);
mu_stream_destroy (&stream, NULL);
}
return rc;
}
static int
_mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int flags)
{
struct lexer_data data;
struct stat st;
int fd;
int rc;
mu_cfg_tree_t *parse_tree;
if (stat (file, &st))
{
if (errno != ENOENT)
mu_error (_("can't stat `%s'"), file);
return -1;
}
fd = open (file, O_RDONLY);
if (fd == -1)
{
mu_error (_("cannot open config file `%s'"), file);
return -1;
}
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_error (_("Info: parsing file `%s'"), file);
memset (&data, 0, sizeof data);
data.buffer = malloc (st.st_size+1);
read (fd, data.buffer, st.st_size);
data.buffer[st.st_size] = 0;
close (fd);
data.curp = data.buffer;
/* Parse configuration */
mu_cfg_locus.file = (char*) file;
mu_cfg_locus.line = 1;
rc = mu_cfg_parse (&parse_tree,
&data,
default_lexer,
NULL,
NULL,
NULL);
if (rc == 0)
rc = mu_parse_config_tree (parse_tree, progname, progparam, flags);
mu_cfg_destroy_tree (&parse_tree);
mu_list_destroy (&data.mpool);
free (data.cbuf);
free (data.buffer);
if (mu_cfg_parser_verbose)
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_error (_("Info: finished parsing file `%s'"), file);
return rc;
......@@ -850,7 +875,7 @@ _mu_parse_config (const char *file, const char *progname,
int
mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global)
struct mu_cfg_param *progparam, int flags)
{
int rc;
char *full_name = mu_tilde_expansion (file, "/", NULL);
......@@ -858,7 +883,7 @@ mu_parse_config (const char *file, const char *progname,
{
if (access (full_name, R_OK) == 0)
{
rc = _mu_parse_config (full_name, progname, progparam, global);
rc = _mu_parse_config (full_name, progname, progparam, flags);
free (full_name);
}
else
......
......@@ -15,7 +15,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
......@@ -92,6 +94,8 @@ mu_cfg_format_error (mu_debug_t debug, size_t level, const char *fmt, ...)
{
va_list ap;
if (!debug)
mu_diag_get_debug (&debug);
va_start (ap, fmt);
mu_debug_vprintf (debug, 0, fmt, ap);
mu_debug_printf (debug, 0, "\n");
......@@ -102,11 +106,14 @@ static void
_mu_cfg_vperror (mu_debug_t debug, const mu_cfg_locus_t *loc,
const char *fmt, va_list ap)
{
mu_debug_set_locus (_mu_cfg_debug,
if (!debug)
mu_diag_get_debug (&debug);
mu_debug_set_locus (debug,
loc->file ? loc->file : _("unknown file"),
loc->line);
mu_debug_vprintf (_mu_cfg_debug, 0, fmt, ap);
mu_debug_printf (_mu_cfg_debug, 0, "\n");
mu_debug_vprintf (debug, 0, fmt, ap);
mu_debug_printf (debug, 0, "\n");
mu_debug_set_locus (debug, NULL, 0);
}
static void
......@@ -149,6 +156,7 @@ debug_print_node (mu_cfg_node_t *node)
node_type_str (node->type),
node->tag_name ? node->tag_name : "(null)",
node->tag_label ? node->tag_label : "(null)");
mu_debug_set_locus (_mu_cfg_debug, NULL, 0);
}
}
......@@ -271,8 +279,6 @@ mu_cfg_parse (mu_cfg_tree_t **ptree,
return rc;
}
static int
_mu_cfg_preorder_recursive (mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
......@@ -355,6 +361,8 @@ int
mu_cfg_postorder (mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data)
{
if (!node)
return 1;
if (node->next
&& mu_cfg_postorder (node->next, beg, end, data) == MU_CFG_ITER_STOP)
return 1;
......@@ -1061,6 +1069,92 @@ mu_cfg_find_section (struct mu_cfg_section *root_sec,
return 0;
}
int
mu_cfg_tree_create (struct mu_cfg_tree **ptree)
{
struct mu_cfg_tree *tree = calloc (1, sizeof *tree);
if (!tree)
return errno;
tree->alloc = malloc;
tree->free = free;
*ptree = tree;
return 0;
}
void
mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug)
{
tree->debug = debug;
}
void
mu_cfg_tree_set_alloc (struct mu_cfg_tree *tree,
mu_cfg_alloc_t alloc, mu_cfg_free_t free)
{
tree->alloc = malloc;
tree->free = free;
}
void *
mu_cfg_tree_alloc (struct mu_cfg_tree *tree, size_t size)
{
return tree->alloc (size);
}
void
mu_cfg_tree_free (struct mu_cfg_tree *tree, void *mem)
{
tree->free (mem);
}
mu_cfg_node_t *
mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
char *tag, char *label, mu_cfg_node_t *node)
{
char *p;
mu_cfg_node_t *np;
size_t size = sizeof *np + strlen (tag) + 1
+ (label ? (strlen (label) + 1) : 0);
np = mu_cfg_tree_alloc (tree, size);
if (!np)
{
mu_debug_printf (tree->debug, MU_DEBUG_ERROR, "%s\n",
_("Not enough memory"));
abort ();
}
np->type = type;
if (loc)
np->locus = *loc;
else
memset (&np->locus, 0, sizeof np->locus);
p = (char*) (np + 1);
np->tag_name = p;
strcpy (p, tag);
p += strlen (p) + 1;
if (label)
{
np->tag_label = p;
strcpy (p, label);
}
else
np->tag_label = label;
np->node = node;
np->next = NULL;
return np;
}
void
mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node)
{
if (!tree->node)
tree->node = node;
else
{
mu_cfg_node_t *p;
for (p = tree->node; p->next; p = p->next)
;
p->next = node;
}
}
......
......@@ -326,6 +326,13 @@ _destroy_data (void *item)
free (item);
}
static int
_gocs_comp (const void *a, const void *b)
{
const struct mu_gocs_data *da = a, *db = b;
return !(strcmp (da->capa, db->capa) == 0 && da->data == db->data);
}
void
mu_gocs_store (char *capa, void *data)
{
......@@ -334,6 +341,7 @@ mu_gocs_store (char *capa, void *data)
{
mu_list_create (&data_list);
mu_list_set_destroy_item (data_list, _destroy_data);
mu_list_set_comparator (data_list, _gocs_comp);
}
s = malloc (sizeof *s);
if (!s)
......@@ -343,7 +351,10 @@ mu_gocs_store (char *capa, void *data)
}
s->capa = capa;
s->data = data;
mu_list_prepend (data_list, s);
if (mu_list_locate (data_list, s, NULL) == 0)
free (s);
else
mu_list_prepend (data_list, s);
}
int
......
......@@ -89,6 +89,8 @@ set_debug_flags (mu_debug_t debug, char *arg)
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case ARGP_KEY_INIT:
......@@ -96,11 +98,13 @@ parse_opt (int key, char *arg, struct argp_state *state)
mimetypes_gram_debug (0);
if (interactive == -1)
interactive = isatty (fileno (stdin));
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
if (dry_run && !debug_level)
debug_level = 1;
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
case 'a':
......@@ -109,9 +113,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'd':
if (!arg)
arg = "9";
set_debug_flags (NULL, arg);
mu_argp_node_list_new (&lst, "debug", arg ? arg : "9");
break;
case 'h':
......@@ -123,11 +125,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 't':
mimetypes_config = arg;
mu_argp_node_list_new (&lst, "mimetypes", arg);
break;
case OPT_METAMAIL:
metamail = arg ? arg : "metamail";
mu_argp_node_list_new (&lst, "metamail", arg ? arg : "metamail");
break;
default:
......
......@@ -49,18 +49,28 @@ static int emacs_mode;
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
switch (key)
{
case 'r':
reverse_order++;
mu_argp_node_list_new (&lst, "reverse", "yes");
break;
case 'p':
preserve_mail++;
mu_argp_node_list_new (&lst, "preserve", arg);
break;
case OPT_EMACS:
emacs_mode++;
mu_argp_node_list_new (&lst, "emacs", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
......@@ -82,6 +92,7 @@ static struct argp argp = {
struct mu_cfg_param movemail_cfg_param[] = {
{ "preserve", mu_cfg_bool, &preserve_mail },
{ "reverse", mu_cfg_bool, &reverse_order },
{ "emacs", mu_cfg_bool, &emacs_mode },
{ NULL }
};
......
......@@ -175,64 +175,56 @@ static const char *pop3d_argp_capa[] = {
static error_t
pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
{
char *p;
static struct mu_argp_node_list lst;
switch (key)
{
case ARGP_KEY_INIT:
astate->child_inputs[0] = astate->input;
break;
case 'u':
undelete_on_startup = 1;
mu_argp_node_list_new (&lst, "undelete", "yes");
break;
#ifdef ENABLE_LOGIN_DELAY
case OPT_LOGIN_DELAY:
login_delay = strtoul (arg, &p, 10);
if (*p)
{
argp_error (astate, _("Invalid number"));
exit (1);
}
mu_argp_node_list_new (&lst, "login-delay", arg);
break;
case OPT_STAT_FILE:
login_stat_file = arg;
mu_argp_node_list_new (&lst, "stat-file", arg);
break;
#endif
case OPT_EXPIRE:
expire = strtoul (arg, &p, 10);
if (*p)
{
argp_error (astate, _("Invalid number"));
exit (1);
}
if (expire == 0)
expire_on_exit = 1;
mu_argp_node_list_new (&lst, "expire", arg);
break;
case OPT_EXPIRE_ON_EXIT:
expire_on_exit = 1;
mu_argp_node_list_new (&lst, "delete-expired", "yes");
break;
#ifdef WITH_TLS
case OPT_TLS_REQUIRED:
initial_state = INITIAL;
mu_argp_node_list_new (&lst, "tls-required", "yes");
break;
#endif
case OPT_BULLETIN_SOURCE:
set_bulletin_source (arg);
mu_argp_node_list_new (&lst, "bulletin-source", arg);
break;
#ifdef USE_DBM
case OPT_BULLETIN_DB:
set_bulletin_db (arg);
mu_argp_node_list_new (&lst, "bulletin-db", arg);
break;
#endif
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
......
......@@ -78,6 +78,8 @@ int show_all = 0;
static error_t
readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
{
static struct mu_argp_node_list lst;
switch (key)
{
case 'd':
......@@ -85,29 +87,39 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
break;
case 'h':
all_header = 1;
mu_argp_node_list_new (&lst, "header", "yes");
break;
case 'f':
mailbox_name = arg;
mu_argp_node_list_new (&lst, "folder", arg);
break;
case 'w':
weedlist = arg;
mu_argp_node_list_new (&lst, "weedlist", arg);
break;
case 'n':
no_header = 1;
mu_argp_node_list_new (&lst, "no-header", "yes");
break;
case 'p':
form_feed = 1;
mu_argp_node_list_new (&lst, "form-feeds", arg);
break;
case 'a':
show_all = 1;
mu_argp_node_list_new (&lst, "show-all-match", arg);
break;
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
if (dbug)
mu_argp_node_list_new (&lst, "debug", mu_umaxtostr (0, dbug));
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
......
......@@ -173,14 +173,13 @@ mu_compat_printer (void *data, mu_log_level_t level, const char *buf)
static error_t
parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
int rc;
switch (key)
{
case 'e':
rc = mu_set_user_email (arg);
if (rc)
argp_error (state, _("Invalid email: %s"), mu_strerror (rc));
mu_argp_node_list_new (&lst, "email", arg);
break;
case 'n':
......@@ -188,7 +187,7 @@ parser (int key, char *arg, struct argp_state *state)
break;
case 'k':
keep_going = 1;
mu_argp_node_list_new (&lst, "keep-going", "yes");
break;
case 'c':
......@@ -200,29 +199,24 @@ parser (int key, char *arg, struct argp_state *state)
break;
case 'f':
if (mbox_url)
free (mbox_url);
mbox_url = strdup (arg);
mu_argp_node_list_new (&lst, "mbox-url", arg);
break;
case 't':
free (tickets);
tickets = mu_tilde_expansion (arg, "/", NULL);
tickets_default = 0;
mu_argp_node_list_new (&lst, "ticket", arg);
break;
case 'd':
if (!arg)
arg = D_DEFAULT;
set_debug_level (NULL, arg);
mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT);
break;
case 'v':
verbose = 1;
mu_argp_node_list_new (&lst, "verbose", "yes");
break;
case ARG_LINE_INFO:
sieve_print_locus = is_true_p (arg);
mu_argp_node_list_new (&lst, "line-info",
is_true_p (arg) ? "yes" : "no");
break;
case ARG_NO_PROGRAM_NAME:
......@@ -242,6 +236,13 @@ parser (int key, char *arg, struct argp_state *state)
case ARGP_KEY_NO_ARGS:
argp_error (state, _("SCRIPT must be specified"));
case ARGP_KEY_INIT:
mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
return ARGP_ERR_UNKNOWN;
}
......