Commit a3a31df1 a3a31df1d1c1606c5e20409289d1161bdcc5dfd9 by Sergey Poznyakoff

* include/mailutils/cfg.h, mailbox/cfg_lexer.c,

mailbox/cfg_parser.y (mu_cfg_tree_t):
New data type.
(mu_cfg_perror_t): Remove
(mu_cfg_parse): Change prototype.
(mu_cfg_perror): Change type.
(mu_cfg_format_error): New function.
(mu_cfg_destroy_tree): Change signature.
(mu_cfg_callback_t): Take mu_debug_t as its first argument,
instead of mu_cfg_locus_t. The mu_debug_t is to be used for error
reporting and debugging diagnostics. The cfg_lexer is responsible
for storing the necessary locus data into it before calling
callbacks.
(mu_cfg_section_fp): Take an additional argument.
(mu_cfg_scan_tree): Simplified prototype. The mu_cfg_tree_t passed
as its first argument already contains all necessary data that
were passed as arguments previously.
(mu_parse_config): First two args are consts.

* include/mailutils/libcfg.h, imap4d/imap4d.c, libcfg/auth.c,
libcfg/common.c, libcfg/ldap.c, libcfg/sieve.c, libcfg/sql.c,
maidag/maidag.c, mail.local/main.c, mimeview/mimeview.c,
pop3d/pop3d.c, sieve/sieve.c: Reflect changes to the cfg
framework.

* mailbox/debug.c (mu_debug_vprintf): Make sure the locus info is
formatted on the first call.
1 parent 0c81afb7
2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
Further improvement of mu_debug_t.
III. Use mu_debug_t for diagnostics in cfg framework.
* include/mailutils/cfg.h, mailbox/cfg_lexer.c,
mailbox/cfg_parser.y (mu_cfg_tree_t):
New data type.
(mu_cfg_perror_t): Remove
(mu_cfg_parse): Change prototype.
(mu_cfg_perror): Change type.
(mu_cfg_format_error): New function.
(mu_cfg_destroy_tree): Change signature.
(mu_cfg_callback_t): Take mu_debug_t as its first argument,
instead of mu_cfg_locus_t. The mu_debug_t is to be used for error
reporting and debugging diagnostics. The cfg_lexer is responsible
for storing the necessary locus data into it before calling
callbacks.
(mu_cfg_section_fp): Take an additional argument.
(mu_cfg_scan_tree): Simplified prototype. The mu_cfg_tree_t passed
as its first argument already contains all necessary data that
were passed as arguments previously.
(mu_parse_config): First two args are consts.
* include/mailutils/libcfg.h, imap4d/imap4d.c, libcfg/auth.c,
libcfg/common.c, libcfg/ldap.c, libcfg/sieve.c, libcfg/sql.c,
maidag/maidag.c, mail.local/main.c, mimeview/mimeview.c,
pop3d/pop3d.c, sieve/sieve.c: Reflect changes to the cfg
framework.
* mailbox/debug.c (mu_debug_vprintf): Make sure the locus info is
formatted on the first call.
II. Further improvement of mu_debug_t.
* include/mailutils/debug.hm4 (struct mu_debug_locus): New data
type.
......@@ -32,9 +62,7 @@
mu_debug_set_function to print source locations. This allows for
easy i18n of the MU_DEBUG[0-9]* format strings.
2007-11-28 Sergey Poznyakoff <gray@gnu.org.ua>
Introduce "global debug settings". Mailutils objects are supposed
I. Introduce "global debug settings". Mailutils objects are supposed
to set their default mu_debug_t objects basing on these settings.
* include/mailutils/Makefile.am: Add debug.hm4. Build debug.h from
......
......@@ -146,27 +146,27 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
}
static int
cb_other (mu_cfg_locus_t *locus, void *data, char *arg)
cb_other (mu_debug_t debug, void *data, char *arg)
{
set_namespace (NS_OTHER, arg);
return 0;
}
static int
cb_shared (mu_cfg_locus_t *locus, void *data, char *arg)
cb_shared (mu_debug_t debug, void *data, char *arg)
{
set_namespace (NS_SHARED, arg);
return 0;
}
static int
cb_mode (mu_cfg_locus_t *locus, void *data, char *arg)
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))
mu_error (_("%s:%d: Invalid mode specification: %s"),
locus->file, locus->line, arg);
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("Invalid mode specification: %s"), arg);
return 0;
}
......
......@@ -19,17 +19,21 @@
#define _MAILUTILS_CFG_H
#include <mailutils/list.h>
#include <mailutils/debug.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum mu_cfg_node_type mu_cfg_node_type_t;
typedef struct mu_cfg_node mu_cfg_node_t;
typedef struct mu_cfg_locus mu_cfg_locus_t;
typedef struct mu_cfg_tree mu_cfg_tree_t;
typedef int (*mu_cfg_lexer_t) (void *ptr);
typedef void (*mu_cfg_perror_t) (void *ptr, const mu_cfg_locus_t *loc,
const char *fmt, ...);
typedef void *(*mu_cfg_alloc_t) (size_t size);
typedef void (*mu_cfg_free_t) (void *ptr);
......@@ -56,16 +60,26 @@ struct mu_cfg_node
mu_cfg_node_t *node;
};
int mu_cfg_parse (mu_cfg_node_t **ptree,
struct mu_cfg_tree
{
mu_cfg_node_t *node;
mu_debug_t debug;
mu_cfg_alloc_t alloc;
mu_cfg_free_t free;
};
int mu_cfg_parse (mu_cfg_tree_t **ptree,
void *data,
mu_cfg_lexer_t lexer,
mu_cfg_perror_t perror,
mu_debug_t debug,
mu_cfg_alloc_t alloc,
mu_cfg_free_t free);
extern mu_cfg_locus_t mu_cfg_locus;
extern int mu_cfg_tie_in;
extern mu_cfg_perror_t mu_cfg_perror;
void mu_cfg_perror (const mu_cfg_locus_t *, const char *, ...);
void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...);
#define MU_CFG_ITER_OK 0
#define MU_CFG_ITER_SKIP 1
......@@ -73,7 +87,7 @@ extern mu_cfg_perror_t mu_cfg_perror;
typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data);
void mu_cfg_destroy_tree (mu_cfg_node_t **tree);
void mu_cfg_destroy_tree (mu_cfg_tree_t **tree);
int mu_cfg_preorder (mu_cfg_node_t *node,
mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
......@@ -107,7 +121,7 @@ enum mu_cfg_param_data_type
mu_cfg_callback
};
typedef int (*mu_cfg_callback_t) (mu_cfg_locus_t *, void *, char *);
typedef int (*mu_cfg_callback_t) (mu_debug_t, void *, char *);
struct mu_cfg_param
{
......@@ -125,7 +139,9 @@ enum mu_cfg_section_stage
typedef int (*mu_cfg_section_fp) (enum mu_cfg_section_stage stage,
const mu_cfg_node_t *node,
void *section_data, void *call_data);
void *section_data,
void *call_data,
mu_cfg_tree_t *tree);
struct mu_cfg_section
{
......@@ -167,10 +183,8 @@ int mu_config_create_container (struct mu_cfg_cont **pcont,
int mu_config_clone_container (struct mu_cfg_cont *cont);
void mu_config_destroy_container (struct mu_cfg_cont **pcont);
int mu_cfg_scan_tree (mu_cfg_node_t *node,
struct mu_cfg_section *sections,
void *data, mu_cfg_perror_t perror,
mu_cfg_alloc_t palloc, mu_cfg_free_t pfree);
int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
void *call_data);
int mu_cfg_find_section (struct mu_cfg_section *root_sec,
const char *path, struct mu_cfg_section **retval);
......@@ -184,10 +198,15 @@ int mu_config_register_plain_section (const char *parent_path,
const char *ident,
struct mu_cfg_param *params);
int mu_parse_config (char *file, char *progname,
int mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global);
int mu_cfg_parse_boolean (const char *str, int *res);
extern int mu_cfg_parser_verbose;
#ifdef __cplusplus
}
#endif
#endif
......
......@@ -57,7 +57,7 @@ extern int mu_parse_config_files (struct mu_cfg_param *param);
int \
__mu_common_cat3__(mu_,capa,_section_parser) \
(enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, \
void *section_data, void *call_data) \
void *section_data, void *call_data, mu_cfg_tree_t *tree) \
{ \
switch (stage) \
{ \
......
......@@ -29,22 +29,23 @@
/* Resource-style configuration */
/* ************************************************************************* */
static int
cb_authentication (mu_cfg_locus_t *locus, void *data, char *arg)
cb_authentication (mu_debug_t err, void *data, char *arg)
{
if (strcmp (arg, "clear") == 0)
mu_authentication_clear_list ();
else
mu_authentication_add_module_list (arg);/*FIXME: error reporting*/
mu_authentication_add_module_list (arg);/*FIXME: use err for error
reporting*/
return 0;
}
static int
cb_authorization (mu_cfg_locus_t *locus, void *data, char *arg)
cb_authorization (mu_debug_t err, void *data, char *arg)
{
if (strcmp (arg, "clear") == 0)
mu_authorization_clear_list ();
else
mu_authorization_add_module_list (arg);
mu_authorization_add_module_list (arg);/* FIXME: see above */
return 0;
}
......@@ -57,7 +58,7 @@ static struct mu_cfg_param mu_auth_param[] = {
int
mu_auth_section_parser
(enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
void *section_data, void *call_data)
void *section_data, void *call_data, mu_cfg_tree_t *tree)
{
switch (stage)
{
......
......@@ -94,12 +94,13 @@ DCL_CFG_CAPA (mailer);
/* ************************************************************************* */
int
cb_facility (mu_cfg_locus_t *locus, void *data, char *arg)
cb_facility (mu_debug_t debug, void *data, char *arg)
{
if (mu_string_to_syslog_facility (arg, &logging_settings.facility))
{
mu_error (_("%s:%d: Unknown syslog facility `%s'"),
locus->file, locus->line, arg);
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("Unknown syslog facility `%s'"),
arg);
return 1;
}
return 0;
......@@ -118,7 +119,7 @@ DCL_CFG_CAPA (logging);
/* ************************************************************************* */
static int
_cb_daemon_mode (mu_cfg_locus_t *locus, void *data, char *arg)
_cb_daemon_mode (mu_debug_t debug, void *data, char *arg)
{
if (strcmp (arg, "inetd") == 0
|| strcmp (arg, "interactive") == 0)
......@@ -127,7 +128,7 @@ _cb_daemon_mode (mu_cfg_locus_t *locus, void *data, char *arg)
daemon_settings.mode = MODE_DAEMON;
else
{
mu_error ("%s:%d: unknown daemon mode", locus->file, locus->line);
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unknown daemon mode"));
return 1;
}
return 0;
......@@ -146,7 +147,7 @@ static struct mu_cfg_param mu_daemon_param[] = {
int
mu_daemon_section_parser
(enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
void *section_data, void *call_data)
void *section_data, void *call_data, mu_cfg_tree_t *tree)
{
switch (stage)
{
......@@ -170,23 +171,25 @@ struct mu_cfg_capa mu_daemon_cfg_capa = {
/* ************************************************************************* */
static int
cb_debug_level (mu_cfg_locus_t *locus, void *data, char *arg)
cb_debug_level (mu_debug_t debug, void *data, char *arg)
{
char buf[UINTMAX_STRSIZE_BOUND];
char *p;
size_t size;
char *pfx;
struct mu_debug_locus locus;
debug_settings.string = arg;
p = umaxtostr (locus->line, buf);
size = strlen (locus->file) + 1 + strlen (p) + 1;
mu_debug_get_locus (debug, &locus);
p = umaxtostr (locus.line, buf);
size = strlen (locus.file) + 1 + strlen (p) + 1;
pfx = malloc (size);
if (!pfx)
{
mu_error ("%s", mu_strerror (errno));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, "%s", mu_strerror (errno));
return 1;
}
strcpy (pfx, locus->file);
strcpy (pfx, locus.file);
strcat (pfx, ":");
strcat (pfx, p);
debug_settings.errpfx = pfx;
......
......@@ -26,13 +26,13 @@
static struct mu_ldap_module_config ldap_settings;
static int
cb_field_map (mu_cfg_locus_t *locus, void *data, char *arg)
cb_field_map (mu_debug_t debug, void *data, char *arg)
{
int err;
int rc = mutil_parse_field_map (arg, &ldap_settings.field_map, &err);
if (rc)
mu_error (_("%s:%d: Error near element %d: %s"),
locus->file, locus->line, err, mu_strerror (rc));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"),
err, mu_strerror (rc));
return 0;
}
......@@ -53,7 +53,7 @@ static struct mu_cfg_param mu_ldap_param[] = {
int
mu_ldap_section_parser
(enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
void *section_data, void *call_data)
void *section_data, void *call_data, mu_cfg_tree_t *tree)
{
switch (stage)
{
......
......@@ -25,12 +25,12 @@
static struct mu_gocs_sieve sieve_settings;
static int
cb_clear_library_path (mu_cfg_locus_t *locus, void *data, char *arg)
cb_clear_library_path (mu_debug_t debug, void *data, char *arg)
{
int flag;
if (mu_cfg_parse_boolean (arg, &flag))
{
mu_error ("%s:%u: %s", locus->file, locus->line, _("not a boolean"));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean"));
return 1;
}
if (flag)
......@@ -39,12 +39,12 @@ cb_clear_library_path (mu_cfg_locus_t *locus, void *data, char *arg)
}
static int
cb_clear_include_path (mu_cfg_locus_t *locus, void *data, char *arg)
cb_clear_include_path (mu_debug_t debug, void *data, char *arg)
{
int flag;
if (mu_cfg_parse_boolean (arg, &flag))
{
mu_error ("%s:%u: %s", locus->file, locus->line, _("not a boolean"));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("not a boolean"));
return 1;
}
if (flag)
......@@ -59,7 +59,7 @@ destroy_string (void *str)
}
static int
_add_path (mu_list_t *plist, mu_cfg_locus_t *locus, void *data, char *arg)
_add_path (mu_list_t *plist, mu_debug_t debug, void *data, char *arg)
{
char *p;
......@@ -68,7 +68,8 @@ _add_path (mu_list_t *plist, mu_cfg_locus_t *locus, void *data, char *arg)
int rc = mu_list_create (plist);
if (rc)
{
mu_error (_("cannot create list: %s"), mu_strerror (rc));
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("cannot create list: %s"), mu_strerror (rc));
exit (1);
}
mu_list_set_destroy_item (*plist, destroy_string);
......@@ -79,15 +80,15 @@ _add_path (mu_list_t *plist, mu_cfg_locus_t *locus, void *data, char *arg)
}
static int
cb_include_path (mu_cfg_locus_t *locus, void *data, char *arg)
cb_include_path (mu_debug_t debug, void *data, char *arg)
{
return _add_path (&sieve_settings.include_path, locus, data, arg);
return _add_path (&sieve_settings.include_path, debug, data, arg);
}
static int
cb_library_path (mu_cfg_locus_t *locus, void *data, char *arg)
cb_library_path (mu_debug_t debug, void *data, char *arg)
{
return _add_path (&sieve_settings.library_path, locus, data, arg);
return _add_path (&sieve_settings.library_path, debug, data, arg);
}
static struct mu_cfg_param mu_sieve_param[] = {
......
......@@ -29,22 +29,23 @@ static struct mu_sql_module_config sql_settings;
/* Resource file configuration */
static int
cb_password_type (mu_cfg_locus_t *locus, void *data, char *arg)
cb_password_type (mu_debug_t debug, void *data, char *arg)
{
if (mu_sql_decode_password_type (arg, &sql_settings.password_type))
mu_error (_("%s:%d: Unknown password type `%s'"),
locus->file, locus->line, arg);
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("Unknown password type `%s'"),
arg);
return 0;
}
static int
cb_field_map (mu_cfg_locus_t *locus, void *data, char *arg)
cb_field_map (mu_debug_t debug, void *data, char *arg)
{
int err;
int rc = mutil_parse_field_map (arg, &sql_settings.field_map, &err);
if (rc)
mu_error (_("%s:%d: Error near element %d: %s"),
locus->file, locus->line, err, mu_strerror (rc));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Error near element %d: %s"),
err, mu_strerror (rc));
return 0;
}
......
......@@ -123,7 +123,7 @@ static const char *maidag_argp_capa[] = {
#define D_DEFAULT "9,s"
static void
set_debug_flags (const mu_cfg_locus_t *locus, const char *arg)
set_debug_flags (mu_debug_t debug, const char *arg)
{
while (*arg)
{
......@@ -153,21 +153,16 @@ set_debug_flags (const mu_cfg_locus_t *locus, const char *arg)
break;
default:
if (locus)
mu_error (_("%s:%d: %c is not a valid debug flag"),
locus->file, locus->line, *arg);
else
mu_error (_("%c is not a valid debug flag"), *arg);
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("%c is not a valid debug flag"), *arg);
break;
}
}
if (*arg == ',')
arg++;
else if (locus)
mu_error (_("%s:%d: expected comma, but found %c"),
locus->file, locus->line, *arg);
else
mu_error (_("expected comma, but found %c"), *arg);
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("expected comma, but found %c"), *arg);
}
}
......@@ -229,9 +224,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
static int
cb_debug (mu_cfg_locus_t *locus, void *data, char *arg)
cb_debug (mu_debug_t debug, void *data, char *arg)
{
set_debug_flags (locus, arg);
set_debug_flags (debug, arg);
return 0;
}
......
......@@ -130,7 +130,7 @@ char *saved_envelope; /* A hack to spare mu_envelope_ calls */
#define D_DEFAULT "9s"
static void
set_debug_flags (const mu_cfg_locus_t *locus, const char *arg)
set_debug_flags (mu_debug_t debug, const char *arg)
{
for (; *arg; arg++)
{
......@@ -165,9 +165,10 @@ set_debug_flags (const mu_cfg_locus_t *locus, const char *arg)
default:
if (isdigit (*arg))
debug_level = *arg - '0';
else if (locus)
mu_error (_("%s:%d: %c is not a valid debug flag"),
locus->file, locus->line, *arg);
else if (debug)
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("%c is not a valid debug flag"),
*arg);
else
mu_error (_("%c is not a valid debug flag"), *arg);
break;
......@@ -239,9 +240,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
static int
cb_debug (mu_cfg_locus_t *locus, void *data, char *arg)
cb_debug (mu_debug_t debug, void *data, char *arg)
{
set_debug_flags (locus, arg);
set_debug_flags (debug, arg);
return 0;
}
......
......@@ -225,8 +225,7 @@ again:
{
if (*p->curp == 0)
{
mu_cfg_perror (p,
&mu_cfg_locus,
mu_cfg_perror (&mu_cfg_locus,
_("unexpected EOF in comment started at line %d"),
keep_line);
return 0;
......@@ -605,7 +604,8 @@ mu_config_register_plain_section (const char *parent_path, const char *ident,
static int
prog_parser (enum mu_cfg_section_stage stage,
const mu_cfg_node_t *node,
void *section_data, void *call_data)
void *section_data, void *call_data,
mu_cfg_tree_t *tree)
{
if (stage == mu_cfg_section_start)
{
......@@ -638,11 +638,11 @@ struct include_data
int global;
};
static int _mu_parse_config (char *file, char *progname,
static int _mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global);
static int
_cb_include (mu_cfg_locus_t *locus, void *data, char *arg)
_cb_include (mu_debug_t debug, void *data, char *arg)
{
int ret = 0;
struct stat sb;
......@@ -666,15 +666,15 @@ _cb_include (mu_cfg_locus_t *locus, void *data, char *arg)
}
else if (errno == ENOENT)
{
mu_cfg_perror (NULL, locus,
_("include directory does not exist"));
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("include file or directory does not exist"));
ret = 1;
}
else
{
mu_cfg_perror (NULL, locus,
_("cannot stat include directory: %s"),
mu_strerror (errno));
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("cannot stat include file or directory: %s"),
mu_strerror (errno));
ret = 1;
}
free (tmp);
......@@ -682,7 +682,7 @@ _cb_include (mu_cfg_locus_t *locus, void *data, char *arg)
}
static int
_mu_parse_config (char *file, char *progname,
_mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global)
{
struct lexer_data data;
......@@ -690,7 +690,7 @@ _mu_parse_config (char *file, char *progname,
int fd;
extern int mu_cfg_yydebug;
int rc;
mu_cfg_node_t *parse_tree;
mu_cfg_tree_t *parse_tree;
if (stat (file, &st))
{
......@@ -723,7 +723,7 @@ _mu_parse_config (char *file, char *progname,
mu_cfg_yydebug = 0;
/* Parse configuration */
mu_cfg_locus.file = file;
mu_cfg_locus.file = (char*) file;
mu_cfg_locus.line = 1;
rc = mu_cfg_parse (&parse_tree,
&data,
......@@ -746,7 +746,7 @@ _mu_parse_config (char *file, char *progname,
idata.progparam = progparam;
idata.global = global;
_mu_config_register_section (&cont, NULL, NULL, NULL,
progname, mu_include_param, NULL);
(void*) progname, mu_include_param, NULL);
if (global)
{
mu_iterator_t iter;
......@@ -757,7 +757,7 @@ _mu_parse_config (char *file, char *progname,
progparam = &empty_param;
_mu_config_register_section (&cont, NULL, "program", prog_parser,
progname,
(void*) progname,
progparam, &prog_sect);
if (old_root->v.section.subsec)
......@@ -794,8 +794,7 @@ _mu_parse_config (char *file, char *progname,
_mu_config_register_section (&cont, NULL, NULL, NULL, NULL,
progparam, NULL);
rc = mu_cfg_scan_tree (parse_tree, &cont->v.section,
progname, NULL, NULL, NULL);
rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, (void*) progname);
mu_config_destroy_container (&cont);
}
......@@ -811,7 +810,7 @@ _mu_parse_config (char *file, char *progname,
}
int
mu_parse_config (char *file, char *progname,
mu_parse_config (const char *file, const char *progname,
struct mu_cfg_param *progparam, int global)
{
int rc;
......
......@@ -28,7 +28,8 @@
#include <mailutils/error.h>
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#include <mailutils/debug.h>
int mu_cfg_parser_verbose;
static mu_cfg_node_t *parse_tree;
mu_cfg_locus_t mu_cfg_locus;
......@@ -36,15 +37,15 @@ int mu_cfg_tie_in;
static int _mu_cfg_errcnt;
static mu_cfg_lexer_t _mu_cfg_lexer;
mu_cfg_perror_t mu_cfg_perror;
static void *_mu_cfg_lexer_data;
mu_cfg_alloc_t _mu_cfg_alloc;
mu_cfg_free_t _mu_cfg_free;
static mu_debug_t _mu_cfg_debug;
static int
yyerror (char *s)
{
mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus, "%s", s);
mu_cfg_perror (&mu_cfg_locus, "%s", s);
return 0;
}
......@@ -65,8 +66,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
np = _mu_cfg_alloc (size);
if (!np)
{
mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus,
_("Not enough memory"));
mu_cfg_perror (&mu_cfg_locus, _("Not enough memory"));
abort();
}
np->type = type;
......@@ -87,24 +87,49 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
return np;
}
void
mu_cfg_format_error (mu_debug_t debug, size_t level, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
mu_debug_vprintf (debug, 0, fmt, ap);
mu_debug_printf (debug, 0, "\n");
va_end (ap);
}
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,
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");
}
static void
_mu_cfg_default_perror (void *ptr, const mu_cfg_locus_t *loc,
const char *fmt, ...)
_mu_cfg_perror (mu_debug_t debug, const mu_cfg_locus_t *loc,
const char *fmt, ...)
{
va_list ap;
fprintf (stderr, "%s:", loc->file ? loc->file : _("unknown file"));
if (loc->line > 0)
fprintf (stderr, "%lu", (unsigned long) loc->line);
else
fprintf (stderr, "%s", _("unknown line"));
fprintf (stderr, ": ");
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
_mu_cfg_vperror (debug, loc, fmt, ap);
va_end (ap);
fprintf (stderr, "\n");
}
void
mu_cfg_perror (const mu_cfg_locus_t *loc, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
_mu_cfg_vperror (_mu_cfg_debug, loc, fmt, ap);
va_end (ap);
}
%}
%token MU_CFG_EOL_TOKEN
......@@ -157,12 +182,10 @@ tag : MU_CFG_START_TOKEN opt_eol taglist MU_CFG_END_TOKEN MU_CFG_EOL_TOKEN
{
if ($4.tag_name && strcmp ($4.tag_name, $1.tag_name))
{
mu_cfg_perror (_mu_cfg_lexer_data,
&$1.locus,
mu_cfg_perror (&$1.locus,
_("Tag %s not closed"),
$1.tag_name);
mu_cfg_perror (_mu_cfg_lexer_data,
&$4.locus,
mu_cfg_perror (&$4.locus,
_("Found closing %s tag instead"),
$4.tag_name);
_mu_cfg_errcnt++;
......@@ -180,17 +203,31 @@ tag : MU_CFG_START_TOKEN opt_eol taglist MU_CFG_END_TOKEN MU_CFG_EOL_TOKEN
%%
static int
_cfg_default_printer (void *unused, size_t level, const char *str)
{
fprintf (stderr, "%s", str);
return 0;
}
int
mu_cfg_parse (mu_cfg_node_t **ptree,
mu_cfg_parse (mu_cfg_tree_t **ptree,
void *data, mu_cfg_lexer_t lexer,
mu_cfg_perror_t perror,
mu_debug_t debug,
mu_cfg_alloc_t palloc, mu_cfg_free_t pfree)
{
int rc;
mu_cfg_tree_t *tree;
_mu_cfg_lexer = lexer;
_mu_cfg_lexer_data = data;
mu_cfg_perror = perror ? perror : _mu_cfg_default_perror;
if (debug)
_mu_cfg_debug = debug;
else
{
mu_debug_create (&_mu_cfg_debug, NULL);
mu_debug_set_print (_mu_cfg_debug, _cfg_default_printer, NULL);
}
_mu_cfg_alloc = palloc ? palloc : malloc;
_mu_cfg_free = pfree ? pfree : free;
_mu_cfg_errcnt = 0;
......@@ -199,8 +236,14 @@ mu_cfg_parse (mu_cfg_node_t **ptree,
if (rc == 0 && _mu_cfg_errcnt)
rc = 1;
/* FIXME if (rc) free_memory; else */
*ptree = parse_tree;
tree = _mu_cfg_alloc (sizeof (*tree));
tree->debug = _mu_cfg_debug;
tree->alloc = _mu_cfg_alloc;
tree->free = _mu_cfg_free;
tree->node = parse_tree;
parse_tree = NULL;
*ptree = tree;
return rc;
}
......@@ -382,12 +425,14 @@ free_param (const mu_cfg_node_t *node, void *data)
}
void
mu_cfg_destroy_tree (mu_cfg_node_t **tree)
mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
{
if (tree && *tree)
if (ptree && *ptree)
{
mu_cfg_postorder (*tree, free_param, free_section, _mu_cfg_free);
*tree = NULL;
mu_cfg_tree_t *tree = *ptree;
mu_cfg_postorder (tree->node, free_param, free_section, tree->free);
mu_debug_destroy (&tree->debug, NULL);
*ptree = NULL;
}
}
......@@ -488,6 +533,7 @@ struct scan_tree_data
{
struct mu_cfg_section_list *list;
void *call_data;
mu_cfg_tree_t *tree;
int error;
};
......@@ -551,10 +597,10 @@ find_param (struct mu_cfg_section *sec, const char *ident, size_t len)
static int
push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec)
{
struct mu_cfg_section_list *p = _mu_cfg_alloc (sizeof *p);
struct mu_cfg_section_list *p = dat->tree->alloc (sizeof *p);
if (!p)
{
mu_cfg_perror (dat->call_data, NULL, _("not enough memory"));
_mu_cfg_perror (dat->tree->debug, NULL, _("not enough memory"));
return 1;
}
p->sec = sec;
......@@ -569,11 +615,11 @@ pop_section (struct scan_tree_data *dat)
struct mu_cfg_section_list *p = dat->list;
struct mu_cfg_section *sec = p->sec;
dat->list = p->next;
_mu_cfg_free (p);
dat->tree->free (p);
return sec;
}
#define STRTONUM(s, type, base, res, limit) \
#define STRTONUM(s, type, base, res, limit, d) \
{ \
type sum = 0; \
\
......@@ -591,16 +637,14 @@ pop_section (struct scan_tree_data *dat)
break; \
if (x <= sum) \
{ \
mu_cfg_perror (sdata->call_data, \
&node->locus, \
_("numeric overflow")); \
_mu_cfg_perror (d, &node->locus, \
_("numeric overflow")); \
return 1; \
} \
else if (limit && x > limit) \
{ \
mu_cfg_perror (sdata->call_data, \
&node->locus, \
_("value out of allowed range")); \
_mu_cfg_perror (d, &node->locus, \
_("value out of allowed range")); \
return 1; \
} \
sum = x; \
......@@ -609,7 +653,7 @@ pop_section (struct scan_tree_data *dat)
res = sum; \
}
#define STRxTONUM(s, type, res, limit) \
#define STRxTONUM(s, type, res, limit, d) \
{ \
int base; \
if (*s == '0') \
......@@ -626,26 +670,25 @@ pop_section (struct scan_tree_data *dat)
base = 8; \
} else \
base = 10; \
STRTONUM (s, type, base, res, limit); \
STRTONUM (s, type, base, res, limit, d); \
}
#define GETUNUM(str, type, res) \
#define GETUNUM(str, type, res, d) \
{ \
type tmpres; \
const char *s = str; \
STRxTONUM (s, type, tmpres, 0); \
STRxTONUM (s, type, tmpres, 0, d); \
if (*s) \
{ \
mu_cfg_perror (sdata->call_data, \
&node->locus, \
_("not a number (stopped near `%s')"), \
s); \
_mu_cfg_perror (d, &node->locus, \
_("not a number (stopped near `%s')"), \
s); \
return 1; \
} \
res = tmpres; \
}
#define GETSNUM(str, type, res) \
#define GETSNUM(str, type, res, d) \
{ \
unsigned type tmpres; \
const char *s = str; \
......@@ -665,13 +708,12 @@ pop_section (struct scan_tree_data *dat)
limit = TYPE_MAXIMUM (type); \
} \
\
STRxTONUM (s, unsigned type, tmpres, limit); \
STRxTONUM (s, unsigned type, tmpres, limit, d); \
if (*s) \
{ \
mu_cfg_perror (sdata->call_data, \
&node->locus, \
_("not a number (stopped near `%s')"), \
s); \
_mu_cfg_perror (d, &node->locus, \
_("not a number (stopped near `%s')"), \
s); \
return 1; \
} \
res = sign ? - tmpres : tmpres; \
......@@ -684,9 +726,7 @@ parse_ipv4 (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
struct in_addr addr;
if (inet_aton (node->tag_label, &addr) == 0)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not an IPv4"));
_mu_cfg_perror (sdata->tree->debug, &node->locus, _("not an IPv4"));
return 1;
}
addr.s_addr = ntohl (addr.s_addr);
......@@ -704,12 +744,11 @@ parse_host (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
{
addr.s_addr = *(unsigned long *)hp->h_addr;
}
else if (inet_aton(node->tag_label, &addr) == 0)
else if (inet_aton (node->tag_label, &addr) == 0)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("cannot resolve hostname `%s'"),
node->tag_label);
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("cannot resolve hostname `%s'"),
node->tag_label);
return 1;
}
addr.s_addr = ntohl (addr.s_addr);
......@@ -730,33 +769,30 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
{
int len = p - node->tag_label;
if (len > sizeof astr - 1) {
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not a valid IPv4 address in CIDR"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not a valid IPv4 address in CIDR"));
return 1;
}
memcpy (astr, node->tag_label, len);
astr[len] = 0;
if (inet_aton (astr, &addr) == 0)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not a valid IPv4 address in CIDR"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not a valid IPv4 address in CIDR"));
return 1;
}
addr.s_addr = ntohl (addr.s_addr);
p++;
s = p;
STRxTONUM (s, unsigned long, mask, 0);
STRxTONUM (s, unsigned long, mask, 0, sdata->tree->debug);
if (*s == '.')
{
struct in_addr a;
if (inet_aton (p, &a) == 0)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not a valid network in CIDR"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not a valid network in CIDR"));
return 1;
}
a.s_addr = ntohl (a.s_addr);
......@@ -769,9 +805,8 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
}
else if (mask > 32)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not a valid network mask in CIDR"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not a valid network mask in CIDR"));
return 1;
}
}
......@@ -783,7 +818,7 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
for (i = 0; i < 3; i++)
{
STRxTONUM(p, unsigned short, x, 255);
STRxTONUM(p, unsigned short, x, 255, sdata->tree->debug);
if (*p != '.')
break;
addr.s_addr = (addr.s_addr << 8) + x;
......@@ -791,10 +826,9 @@ parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node,
if (*p)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not a CIDR (stopped near `%s')"),
p);
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not a CIDR (stopped near `%s')"),
p);
return 1;
}
......@@ -833,7 +867,7 @@ parse_bool (struct scan_tree_data *sdata, const mu_cfg_node_t *node, int *res)
{
if (mu_cfg_parse_boolean (node->tag_label, res))
{
mu_cfg_perror (sdata->call_data, &node->locus, _("not a boolean"));
_mu_cfg_perror (sdata->tree->debug, &node->locus, _("not a boolean"));
return 1;
}
return 0;
......@@ -846,10 +880,9 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
0);
if (!param)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("unknown keyword `%s'"),
node->tag_name);
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("unknown keyword `%s'"),
node->tag_name);
return 1;
}
......@@ -858,12 +891,11 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
case mu_cfg_string:
{
size_t len = strlen (node->tag_label);
char *s = _mu_cfg_alloc (len + 1);
char *s = sdata->tree->alloc (len + 1);
if (!s)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("not enough memory"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not enough memory"));
return 1;
}
strcpy (s, node->tag_label);
......@@ -873,40 +905,48 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
}
case mu_cfg_short:
GETSNUM (node->tag_label, short, *(short*)param->data);
GETSNUM (node->tag_label, short, *(short*)param->data,
sdata->tree->debug);
break;
case mu_cfg_ushort:
GETUNUM (node->tag_label, unsigned short, *(unsigned short*)param->data);
GETUNUM (node->tag_label, unsigned short, *(unsigned short*)param->data,
sdata->tree->debug);
break;
case mu_cfg_int:
GETSNUM (node->tag_label, int, *(int*)param->data);
GETSNUM (node->tag_label, int, *(int*)param->data, sdata->tree->debug);
break;
case mu_cfg_uint:
GETUNUM (node->tag_label, unsigned int, *(unsigned int*)param->data);
GETUNUM (node->tag_label, unsigned int, *(unsigned int*)param->data,
sdata->tree->debug);
break;
case mu_cfg_long:
GETSNUM (node->tag_label, long, *(long*)param->data);
GETSNUM (node->tag_label, long, *(long*)param->data,
sdata->tree->debug);
break;
case mu_cfg_ulong:
GETUNUM (node->tag_label, unsigned long, *(unsigned long*)param->data);
GETUNUM (node->tag_label, unsigned long, *(unsigned long*)param->data,
sdata->tree->debug);
break;
case mu_cfg_size:
GETUNUM (node->tag_label, size_t, *(size_t*)param->data);
GETUNUM (node->tag_label, size_t, *(size_t*)param->data,
sdata->tree->debug);
break;
case mu_cfg_off:
mu_cfg_perror (sdata->call_data, &node->locus, _("not implemented yet"));
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("not implemented yet"));
/* GETSNUM(node->tag_label, off_t, *(off_t*)param->data); */
return 1;
case mu_cfg_time:
GETUNUM (node->tag_label, time_t, *(time_t*)param->data);
GETUNUM (node->tag_label, time_t, *(time_t*)param->data,
sdata->tree->debug);
break;
case mu_cfg_bool:
......@@ -930,7 +970,9 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
break;
case mu_cfg_callback:
if (param->callback (&node->locus, param->data, node->tag_label))
mu_debug_set_locus (sdata->tree->debug, node->locus.file,
node->locus.line);
if (param->callback (sdata->tree->debug, param->data, node->tag_label))
return 1;
break;
......@@ -958,10 +1000,9 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
{
if (mu_cfg_parser_verbose)
{
mu_cfg_perror (sdata->call_data,
&node->locus,
_("unknown section `%s'"),
node->tag_name);
_mu_cfg_perror (sdata->tree->debug, &node->locus,
_("unknown section `%s'"),
node->tag_name);
}
return MU_CFG_ITER_SKIP;
}
......@@ -969,7 +1010,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
return MU_CFG_ITER_SKIP;
if (sec->parser &&
sec->parser (mu_cfg_section_start, node,
sec->data, sdata->call_data))
sec->data, sdata->call_data, sdata->tree))
{
sdata->error++;
return MU_CFG_ITER_SKIP;
......@@ -1004,7 +1045,7 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data)
if (sec && sec->parser)
{
if (sec->parser (mu_cfg_section_end, node, sec->data,
sdata->call_data))
sdata->call_data, sdata->tree))
{
sdata->error++;
return MU_CFG_ITER_SKIP;
......@@ -1015,21 +1056,17 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data)
}
int
mu_cfg_scan_tree (mu_cfg_node_t *node,
struct mu_cfg_section *sections,
void *data, mu_cfg_perror_t perror,
mu_cfg_alloc_t palloc, mu_cfg_free_t pfree)
mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
void *data)
{
struct scan_tree_data dat;
dat.tree = tree;
dat.list = NULL;
mu_cfg_perror = perror ? perror : _mu_cfg_default_perror;
_mu_cfg_alloc = palloc ? palloc : malloc;
_mu_cfg_free = pfree ? pfree : free;
dat.call_data = data;
dat.error = 0;
dat.call_data = data;
if (push_section (&dat, sections))
return 1;
mu_cfg_preorder (node, _scan_tree_helper, _scan_tree_end_helper, &dat);
mu_cfg_preorder (tree->node, _scan_tree_helper, _scan_tree_end_helper, &dat);
pop_section (&dat);
return dat.error;
}
......
......@@ -120,6 +120,28 @@ mu_debug_set_data (mu_debug_t debug, void *data, void (*destroy) (void*),
return 0;
}
static void
debug_format_prefix (mu_debug_t debug)
{
int need_space = 0;
if (debug->locus.file)
{
mu_stream_sequential_printf (debug->stream, "%s:%d:",
debug->locus.file, debug->locus.line);
need_space = 1;
}
if (debug->function)
{
mu_stream_sequential_printf (debug->stream, "%s:",
debug->function);
need_space = 1;
}
if (need_space)
mu_stream_sequential_write (debug->stream, " ", 1);
}
int
mu_debug_vprintf (mu_debug_t debug, size_t level,
const char *format, va_list ap)
......@@ -133,7 +155,6 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
mu_transport_t tbuf;
char *ptr, *start, *p;
size_t nseg;
int need_space = 0;
if (debug->stream == NULL)
{
......@@ -149,7 +170,11 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
}
}
if (mu_stream_size (debug->stream, &len) == 0 && len == 0)
debug_format_prefix (debug);
mu_stream_sequential_vprintf (debug->stream, format, ap);
mu_stream_get_transport (debug->stream, &tbuf);
start = (char*) tbuf;
mu_stream_size (debug->stream, &len);
......@@ -180,26 +205,7 @@ mu_debug_vprintf (mu_debug_t debug, size_t level,
mu_stream_truncate (debug->stream, len);
mu_stream_seek (debug->stream, len, SEEK_SET);
if (len)
return 0;
}
if (debug->locus.file)
{
mu_stream_sequential_printf (debug->stream, "%s:%d:",
debug->locus.file, debug->locus.line);
need_space = 1;
}
if (debug->function)
{
mu_stream_sequential_printf (debug->stream, "%s:",
debug->function);
need_space = 1;
}
if (need_space)
mu_stream_sequential_write (debug->stream, " ", 1);
}
else
vfprintf (stderr, format, ap);
......
......@@ -66,7 +66,7 @@ char *mimeview_file; /* Name of the file to view */
FILE *mimeview_fp; /* Its descriptor */
static void
set_debug_flags (mu_cfg_locus_t *locus, char *arg)
set_debug_flags (mu_debug_t debug, char *arg)
{
for (; *arg; arg++)
{
......@@ -147,9 +147,9 @@ static struct argp argp = {
static int
cb_debug (mu_cfg_locus_t *locus, void *data, char *arg)
cb_debug (mu_debug_t debug, void *data, char *arg)
{
set_debug_flags (locus, arg);
set_debug_flags (debug, arg);
return 0;
}
......
......@@ -112,7 +112,7 @@ static struct argp_option options[] = {
#ifdef WITH_TLS
static int
cb_tls_expired (mu_cfg_locus_t *locus, void *data, char *arg)
cb_tls_required (mu_debug_t debug, void *data, char *arg)
{
initial_state = INITIAL;
return 0;
......@@ -120,16 +120,16 @@ cb_tls_expired (mu_cfg_locus_t *locus, void *data, char *arg)
#endif
static int
cb_bulletin_source (mu_cfg_locus_t *locus, void *data, char *arg)
cb_bulletin_source (mu_debug_t debug, void *data, char *arg)
{
set_bulletin_source (arg);
set_bulletin_source (arg); /* FIXME: Error reporting? */
return 0;
}
static int
cb_bulletin_db (mu_cfg_locus_t *locus, void *data, char *arg)
cb_bulletin_db (mu_debug_t debug, void *data, char *arg)
{
set_bulletin_db (arg);
set_bulletin_db (arg); /* FIXME: Error reporting? */
return 0;
}
......@@ -138,7 +138,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
{ "expire", mu_cfg_time, &expire },
{ "delete-expired", mu_cfg_int, &expire_on_exit },
#ifdef WITH_TLS
{ "tls-required", mu_cfg_callback, NULL, cb_tls_expired },
{ "tls-required", mu_cfg_callback, NULL, cb_tls_required },
#endif
#ifdef ENABLE_LOGIN_DELAY
{ "login-delay", mu_cfg_time, &login_delay },
......
......@@ -123,7 +123,7 @@ is_true_p (char *p)
}
static void
set_debug_level (mu_cfg_locus_t *locus, const char *arg)
set_debug_level (mu_debug_t debug, const char *arg)
{
for (; *arg; arg++)
{
......@@ -150,9 +150,9 @@ set_debug_level (mu_cfg_locus_t *locus, const char *arg)
break;
default:
if (locus)
mu_error (_("%s:%d: %c is not a valid debug flag"),
locus->file, locus->line, *arg);
if (debug)
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("%c is not a valid debug flag"), *arg);
else
mu_error (_("%c is not a valid debug flag"), *arg);
}
......@@ -240,24 +240,24 @@ static struct argp argp =
static int
cb_debug (mu_cfg_locus_t *locus, void *data, char *arg)
cb_debug (mu_debug_t debug, void *data, char *arg)
{
set_debug_level (locus, arg);
set_debug_level (debug, arg);
return 0;
}
static int
cb_email (mu_cfg_locus_t *locus, void *data, char *arg)
cb_email (mu_debug_t debug, void *data, char *arg)
{
int rc = mu_set_user_email (arg);
if (rc)
mu_error (_("%s:%d: Invalid email: %s"),
locus->file, locus->line, mu_strerror (rc));
mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("Invalid email: %s"),
mu_strerror (rc));
return rc;
}
static int
cb_ticket (mu_cfg_locus_t *locus, void *data, char *arg)
cb_ticket (mu_debug_t debug, void *data, char *arg)
{
free (tickets);
tickets = mu_tilde_expansion (arg, "/", NULL);
......