Commit a8d00fd7 a8d00fd7f100b4a2111e18b773e2a5734cb94319 by Sam Roberts

Added ~/.<progname>rc to be last config file.

Fixed segv for NULL capa and added header file blurb.
1 parent 5f9936f7
...@@ -362,7 +362,7 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -362,7 +362,7 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state)
362 #endif 362 #endif
363 363
364 #ifndef MU_USER_CONFIG_FILE 364 #ifndef MU_USER_CONFIG_FILE
365 # define MU_USER_CONFIG_FILE ".mailutils" 365 # define MU_USER_CONFIG_FILE "~/.mailutils"
366 #endif 366 #endif
367 367
368 static int 368 static int
...@@ -375,6 +375,12 @@ member (const char *array[], const char *text, size_t len) ...@@ -375,6 +375,12 @@ member (const char *array[], const char *text, size_t len)
375 return 0; 375 return 0;
376 } 376 }
377 377
378 /*
379 Appends applicable options found in file NAME to argv. If progname
380 is NULL, all the options found are assumed to apply. Otherwise they
381 apply only if the line starts with ":something", and something is
382 found in the CAPA array, or the line starts with PROGNAME.
383 */
378 void 384 void
379 read_rc (const char *progname, const char *name, const char *capa[], 385 read_rc (const char *progname, const char *name, const char *capa[],
380 int *argc, char ***argv) 386 int *argc, char ***argv)
...@@ -385,10 +391,20 @@ read_rc (const char *progname, const char *name, const char *capa[], ...@@ -385,10 +391,20 @@ read_rc (const char *progname, const char *name, const char *capa[],
385 size_t n = 0; 391 size_t n = 0;
386 int x_argc = *argc; 392 int x_argc = *argc;
387 char **x_argv = *argv; 393 char **x_argv = *argv;
394 char* rcfile = mu_tilde_expansion (name, "/", NULL);
388 395
389 fp = fopen (name, "r"); 396 if (!rcfile)
397 {
398 fprintf (stderr, "%s: not enough memory\n", progname);
399 exit (1);
400 }
401
402 fp = fopen (rcfile, "r");
390 if (!fp) 403 if (!fp)
404 {
405 free(rcfile);
391 return; 406 return;
407 }
392 408
393 while (getline (&buf, &n, fp) > 0) 409 while (getline (&buf, &n, fp) > 0)
394 { 410 {
...@@ -435,12 +451,19 @@ read_rc (const char *progname, const char *name, const char *capa[], ...@@ -435,12 +451,19 @@ read_rc (const char *progname, const char *name, const char *capa[],
435 } 451 }
436 452
437 len = 0; 453 len = 0;
454 if(progname)
455 {
438 for (p = kwp; *p && !isspace (*p); p++) 456 for (p = kwp; *p && !isspace (*p); p++)
439 len++; 457 len++;
440 458 }
441 if ((kwp[0] == ':' 459 else
442 && member (capa, kwp+1, len-1)) 460 p = kwp; /* Use the whole line. */
443 || strncmp (progname, kwp, len) == 0) 461
462 if (
463 progname == NULL
464 || (kwp[0] == ':' && member (capa, kwp+1, len-1))
465 || strncmp (progname, kwp, len) == 0
466 )
444 { 467 {
445 int i, n_argc = 0; 468 int i, n_argc = 0;
446 char **n_argv; 469 char **n_argv;
...@@ -471,6 +494,7 @@ read_rc (const char *progname, const char *name, const char *capa[], ...@@ -471,6 +494,7 @@ read_rc (const char *progname, const char *name, const char *capa[],
471 } 494 }
472 } 495 }
473 fclose (fp); 496 fclose (fp);
497 free(rcfile);
474 498
475 *argc = x_argc; 499 *argc = x_argc;
476 *argv = x_argv; 500 *argv = x_argv;
...@@ -485,8 +509,7 @@ mu_create_argcv (const char *capa[], ...@@ -485,8 +509,7 @@ mu_create_argcv (const char *capa[],
485 int x_argc; 509 int x_argc;
486 char **x_argv; 510 char **x_argv;
487 int i; 511 int i;
488 struct passwd *pw; 512
489
490 progname = strrchr (argv[0], '/'); 513 progname = strrchr (argv[0], '/');
491 if (progname) 514 if (progname)
492 progname++; 515 progname++;
...@@ -505,28 +528,30 @@ mu_create_argcv (const char *capa[], ...@@ -505,28 +528,30 @@ mu_create_argcv (const char *capa[],
505 x_argv[x_argc] = argv[x_argc]; 528 x_argv[x_argc] = argv[x_argc];
506 x_argc++; 529 x_argc++;
507 530
531 /* Add global config file. */
508 read_rc (progname, MU_CONFIG_FILE, capa, &x_argc, &x_argv); 532 read_rc (progname, MU_CONFIG_FILE, capa, &x_argc, &x_argv);
509 pw = getpwuid (getuid ());
510 if (pw)
511 {
512 struct stat sb;
513 533
514 if (stat (pw->pw_dir, &sb) == 0 && S_ISDIR (sb.st_mode)) 534 /* Add per-user config file. */
515 { 535 read_rc (progname, MU_USER_CONFIG_FILE, capa, &x_argc, &x_argv);
516 /* note: sizeof return value counts terminating zero */ 536
517 char *name = xmalloc (strlen (pw->pw_dir) + 1 537 /* Add per-program (and per-user) config file. */
518 + sizeof (MU_USER_CONFIG_FILE)); 538 {
519 sprintf (name, "%s/%s", pw->pw_dir, MU_USER_CONFIG_FILE); 539 char* progrc = malloc (strlen (progname) + 3 /* ~/ */ + 3 /* rc */ + 1);
520 read_rc (progname, name, capa, &x_argc, &x_argv); 540 if (!progrc)
521 free (name); 541 {
522 } 542 fprintf (stderr, "%s: not enough memory\n", progname);
523 } 543 exit (1);
544 }
545 sprintf (progrc, "~/.%src", progname);
546 read_rc (NULL, progrc, capa, &x_argc, &x_argv);
547 free (progrc);
548 }
524 549
525 /* Finally, add the command line options */ 550 /* Finally, add the command line options */
526 x_argv = realloc (x_argv, (x_argc + argc) * sizeof (x_argv[0])); 551 x_argv = realloc (x_argv, (x_argc + argc) * sizeof (x_argv[0]));
527 for (i = 1; i < argc; i++) 552 for (i = 1; i < argc; i++)
528 x_argv[x_argc++] = argv[i]; 553 x_argv[x_argc++] = argv[i];
529 554
530 x_argv[x_argc] = NULL; 555 x_argv[x_argc] = NULL;
531 556
532 *p_argc = x_argc; 557 *p_argc = x_argc;
...@@ -562,9 +587,9 @@ mu_build_argp (const struct argp *template, const char *capa[]) ...@@ -562,9 +587,9 @@ mu_build_argp (const struct argp *template, const char *capa[])
562 struct argp *argp; 587 struct argp *argp;
563 588
564 /* Count the capabilities */ 589 /* Count the capabilities */
565 for (n = 0; capa[n]; n++) 590 for (n = 0; capa && capa[n]; n++)
566 ; 591 ;
567 if (template->children) 592 if (template && template->children)
568 for (; template->children[n].argp; n++) 593 for (; template->children[n].argp; n++)
569 ; 594 ;
570 595
...@@ -576,11 +601,11 @@ mu_build_argp (const struct argp *template, const char *capa[]) ...@@ -576,11 +601,11 @@ mu_build_argp (const struct argp *template, const char *capa[])
576 } 601 }
577 602
578 n = 0; 603 n = 0;
579 if (template->children) 604 if (template && template->children)
580 for (; template->children[n].argp; n++) 605 for (; template->children[n].argp; n++)
581 ap[n] = template->children[n]; 606 ap[n] = template->children[n];
582 607
583 for (; capa[n]; n++) 608 for (; capa && capa[n]; n++)
584 { 609 {
585 struct argp_child *tmp = find_argp_child (capa[n]); 610 struct argp_child *tmp = find_argp_child (capa[n]);
586 if (!tmp) 611 if (!tmp)
...@@ -621,3 +646,4 @@ mu_argp_parse(const struct argp *argp, ...@@ -621,3 +646,4 @@ mu_argp_parse(const struct argp *argp,
621 free ((void*) argp); 646 free ((void*) argp);
622 return ret; 647 return ret;
623 } 648 }
649
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef MU_ARGP_H
19 #define MU_ARGP_H 1
20
1 #include <mailutils/mailbox.h> 21 #include <mailutils/mailbox.h>
2 #include <argp.h> 22 #include <argp.h>
3 23
...@@ -27,3 +47,5 @@ extern error_t mu_argp_parse __P((const struct argp *argp, ...@@ -27,3 +47,5 @@ extern error_t mu_argp_parse __P((const struct argp *argp,
27 int *arg_index, 47 int *arg_index,
28 void *input)); 48 void *input));
29 49
50 #endif
51
......