Commit c3378d59 c3378d59ccc7cf6d57d6b07ed8923a169c7923cd by Sergey Poznyakoff

Fix parsing of per-user configuration files.

The mu_cfg_parse_file function ignored special meaning of the
initial "~/" in file names. This led to user configuration files
not being read (mu_libcfg_parse_config creates such names if
mu_load_user_rcfile is set).

* mailbox/cfg_lexer.l (mu_cfg_parse_file): Expand initial tilde
in the file name. Store expanded file name in the opool.
(mu_get_config): Destroy tree only if it has actually been
created.
* mailbox/cfg_parser.y (mu_cfg_parse): Free allocated memory in
case of error.
(do_include): Fix memory leak.
1 parent aa3531ff
......@@ -323,34 +323,47 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
struct stat st;
FILE *fp;
int rc;
if (stat (file, &st))
char *full_name = mu_tilde_expansion (file, "/", NULL);
if (stat (full_name, &st))
{
if (errno != ENOENT)
mu_error (_("cannot stat `%s': %s"), file, mu_strerror (errno));
mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno));
free (full_name);
return ENOENT;
}
fp = fopen (file, "r");
fp = fopen (full_name, "r");
if (!fp)
{
mu_error (_("cannot open config file `%s': %s"), file,
mu_error (_("cannot open config file `%s': %s"), full_name,
mu_strerror (errno));
free (full_name);
return errno;
}
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), file);
mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), full_name);
mu_cfg_set_lex_debug ();
/* Initialize locus: */
/* 1. Save file name in the lexer object pool and point `file' member
to this copy. Free full_name: it is not used after that. */
_mu_line_begin ();
_mu_line_add (full_name, strlen (full_name));
mu_cfg_locus.file = _mu_line_finish ();
free (full_name);
/* 2. Initialize line number */
mu_cfg_locus.line = 1;
/* Parse configuration */
mu_cfg_locus.file = (char*) file;
mu_cfg_locus.line = 1;
yyrestart (fp);
rc = mu_cfg_parse (return_tree);
fclose (fp);
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), file);
mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"),
mu_cfg_locus.file);
return rc == 0 ? 0 : MU_ERR_FAILURE;
}
......@@ -367,10 +380,9 @@ mu_get_config (const char *file, const char *progname,
if (rc == 0)
rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags,
target_ptr);
mu_cfg_destroy_tree (&parse_tree);
}
mu_cfg_destroy_tree (&parse_tree);
return rc == 0 ? 0 : MU_ERR_FAILURE;
}
......
......@@ -459,22 +459,28 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
{
int rc;
mu_cfg_tree_t *tree;
mu_opool_t pool;
mu_cfg_set_debug ();
_mu_cfg_errcnt = 0;
rc = yyparse ();
pool = mu_cfg_lexer_pool ();
if (rc == 0 && _mu_cfg_errcnt)
rc = 1;
/* FIXME if (rc) free_memory; else */
tree = mu_alloc (sizeof (*tree));
tree->debug = _mu_cfg_debug;
_mu_cfg_debug = NULL;
tree->nodes = parse_node_list;
tree->pool = mu_cfg_lexer_pool ();
parse_node_list = NULL;
*ptree = tree;
{
mu_opool_destroy (&pool);
rc = 1;
}
else
{
tree = mu_alloc (sizeof (*tree));
tree->debug = _mu_cfg_debug;
_mu_cfg_debug = NULL;
tree->nodes = parse_node_list;
tree->pool = pool;
parse_node_list = NULL;
*ptree = tree;
}
return rc;
}
......@@ -544,6 +550,7 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc)
{
char *file = mu_make_file_name (name, mu_program_name);
rc = mu_cfg_parse_file (&tree, file, flags);
free (file);
}
}
else
......