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) ...@@ -323,34 +323,47 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
323 struct stat st; 323 struct stat st;
324 FILE *fp; 324 FILE *fp;
325 int rc; 325 int rc;
326 326 char *full_name = mu_tilde_expansion (file, "/", NULL);
327 if (stat (file, &st)) 327
328 if (stat (full_name, &st))
328 { 329 {
329 if (errno != ENOENT) 330 if (errno != ENOENT)
330 mu_error (_("cannot stat `%s': %s"), file, mu_strerror (errno)); 331 mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno));
332 free (full_name);
331 return ENOENT; 333 return ENOENT;
332 } 334 }
333 fp = fopen (file, "r"); 335 fp = fopen (full_name, "r");
334 if (!fp) 336 if (!fp)
335 { 337 {
336 mu_error (_("cannot open config file `%s': %s"), file, 338 mu_error (_("cannot open config file `%s': %s"), full_name,
337 mu_strerror (errno)); 339 mu_strerror (errno));
340 free (full_name);
338 return errno; 341 return errno;
339 } 342 }
340 343
341 if (flags & MU_PARSE_CONFIG_VERBOSE) 344 if (flags & MU_PARSE_CONFIG_VERBOSE)
342 mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), file); 345 mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), full_name);
343 346
344 mu_cfg_set_lex_debug (); 347 mu_cfg_set_lex_debug ();
348
349 /* Initialize locus: */
350 /* 1. Save file name in the lexer object pool and point `file' member
351 to this copy. Free full_name: it is not used after that. */
352 _mu_line_begin ();
353 _mu_line_add (full_name, strlen (full_name));
354 mu_cfg_locus.file = _mu_line_finish ();
355 free (full_name);
356 /* 2. Initialize line number */
357 mu_cfg_locus.line = 1;
345 358
346 /* Parse configuration */ 359 /* Parse configuration */
347 mu_cfg_locus.file = (char*) file;
348 mu_cfg_locus.line = 1;
349 yyrestart (fp); 360 yyrestart (fp);
350 rc = mu_cfg_parse (return_tree); 361 rc = mu_cfg_parse (return_tree);
351 fclose (fp); 362 fclose (fp);
352 if (flags & MU_PARSE_CONFIG_VERBOSE) 363 if (flags & MU_PARSE_CONFIG_VERBOSE)
353 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), file); 364 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"),
365 mu_cfg_locus.file);
366
354 return rc == 0 ? 0 : MU_ERR_FAILURE; 367 return rc == 0 ? 0 : MU_ERR_FAILURE;
355 } 368 }
356 369
...@@ -367,10 +380,9 @@ mu_get_config (const char *file, const char *progname, ...@@ -367,10 +380,9 @@ mu_get_config (const char *file, const char *progname,
367 if (rc == 0) 380 if (rc == 0)
368 rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags, 381 rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags,
369 target_ptr); 382 target_ptr);
383 mu_cfg_destroy_tree (&parse_tree);
370 } 384 }
371 385
372 mu_cfg_destroy_tree (&parse_tree);
373
374 return rc == 0 ? 0 : MU_ERR_FAILURE; 386 return rc == 0 ? 0 : MU_ERR_FAILURE;
375 } 387 }
376 388
......
...@@ -459,22 +459,28 @@ mu_cfg_parse (mu_cfg_tree_t **ptree) ...@@ -459,22 +459,28 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
459 { 459 {
460 int rc; 460 int rc;
461 mu_cfg_tree_t *tree; 461 mu_cfg_tree_t *tree;
462 462 mu_opool_t pool;
463
463 mu_cfg_set_debug (); 464 mu_cfg_set_debug ();
464
465 _mu_cfg_errcnt = 0; 465 _mu_cfg_errcnt = 0;
466
466 rc = yyparse (); 467 rc = yyparse ();
468 pool = mu_cfg_lexer_pool ();
467 if (rc == 0 && _mu_cfg_errcnt) 469 if (rc == 0 && _mu_cfg_errcnt)
468 rc = 1; 470 {
469 /* FIXME if (rc) free_memory; else */ 471 mu_opool_destroy (&pool);
470 472 rc = 1;
471 tree = mu_alloc (sizeof (*tree)); 473 }
472 tree->debug = _mu_cfg_debug; 474 else
473 _mu_cfg_debug = NULL; 475 {
474 tree->nodes = parse_node_list; 476 tree = mu_alloc (sizeof (*tree));
475 tree->pool = mu_cfg_lexer_pool (); 477 tree->debug = _mu_cfg_debug;
476 parse_node_list = NULL; 478 _mu_cfg_debug = NULL;
477 *ptree = tree; 479 tree->nodes = parse_node_list;
480 tree->pool = pool;
481 parse_node_list = NULL;
482 *ptree = tree;
483 }
478 return rc; 484 return rc;
479 } 485 }
480 486
...@@ -544,6 +550,7 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc) ...@@ -544,6 +550,7 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc)
544 { 550 {
545 char *file = mu_make_file_name (name, mu_program_name); 551 char *file = mu_make_file_name (name, mu_program_name);
546 rc = mu_cfg_parse_file (&tree, file, flags); 552 rc = mu_cfg_parse_file (&tree, file, flags);
553 free (file);
547 } 554 }
548 } 555 }
549 else 556 else
......