/[mailutils]/mailutils/lib/mu_argp.c
ViewVC logotype

Diff of /mailutils/lib/mu_argp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by gray, Fri Mar 8 22:39:49 2002 UTC revision 1.8 by gray, Sat Mar 9 14:29:29 2002 UTC
# Line 25  Line 25 
25  #ifdef HAVE_STRINGS_H  #ifdef HAVE_STRINGS_H
26  # include <strings.h>  # include <strings.h>
27  #endif  #endif
28    #include <sys/types.h>
29    #include <sys/stat.h>
30    #include <unistd.h>
31    #include <pwd.h>
32    #include <xalloc.h>
33    #include <getline.h>
34    #include <mailutils/mutil.h>
35    #include <mailutils/error.h>
36  #include <argcv.h>  #include <argcv.h>
37  #include <mu_argp.h>  #include <mu_argp.h>
38  #ifdef HAVE_MYSQL  #ifdef HAVE_MYSQL
# Line 42  Line 50 
50  #define ARG_SQL_PORT 9  #define ARG_SQL_PORT 9
51  #define ARG_PAM_SERVICE 10  #define ARG_PAM_SERVICE 10
52    
53  static struct argp_option mu_common_argp_option[] =  static struct argp_option mu_common_argp_option[] = {
 {  
54    {"maildir", 'm', "URL", 0,    {"maildir", 'm', "URL", 0,
55     "use specified URL as a mailspool directory", 0},     "use specified URL as a mailspool directory", 0},
56    { "license", 'L', NULL, 0, "print license and exit", 0 },    { "license", 'L', NULL, 0, "print license and exit", 0 },
57    { NULL,      0, NULL, 0, NULL, 0 }    { NULL,      0, NULL, 0, NULL, 0 }
58  };  };
59    
60  static struct argp_option mu_logging_argp_option[] =  static struct argp_option mu_logging_argp_option[] = {
 {  
61    {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0,    {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0,
62     "output logs to syslog FACILITY", 0},     "output logs to syslog FACILITY", 0},
63    { NULL,      0, NULL, 0, NULL, 0 }    { NULL,      0, NULL, 0, NULL, 0 }
64  };  };
65    
66    
67  static struct argp_option mu_auth_argp_option[] =  static struct argp_option mu_auth_argp_option[] = {
 {  
68  #ifdef USE_LIBPAM  #ifdef USE_LIBPAM
69    { "pam-service", ARG_PAM_SERVICE, "STRING", 0,    { "pam-service", ARG_PAM_SERVICE, "STRING", 0,
70      "Use STRING as PAM service name", 0},      "Use STRING as PAM service name", 0},
# Line 85  static struct argp_option mu_auth_argp_o Line 90  static struct argp_option mu_auth_argp_o
90    { NULL,      0, NULL, 0, NULL, 0 }    { NULL,      0, NULL, 0, NULL, 0 }
91  };  };
92    
93  static struct argp_option mu_daemon_argp_option[] =  static struct argp_option mu_daemon_argp_option[] = {
 {  
94    {"daemon", 'd', "NUMBER", OPTION_ARG_OPTIONAL,    {"daemon", 'd', "NUMBER", OPTION_ARG_OPTIONAL,
95     "runs in daemon mode with a maximum of NUMBER children"},     "runs in daemon mode with a maximum of NUMBER children"},
96    {"inetd",  'i', 0, 0,    {"inetd",  'i', 0, 0,
# Line 103  static error_t mu_common_argp_parser __P Line 107  static error_t mu_common_argp_parser __P
107  static error_t mu_daemon_argp_parser __P((int key, char *arg,  static error_t mu_daemon_argp_parser __P((int key, char *arg,
108                                            struct argp_state *state));                                            struct argp_state *state));
109    
110  struct argp mu_common_argp =  struct argp mu_common_argp = {
 {  
111    mu_common_argp_option,    mu_common_argp_option,
112    mu_common_argp_parser,    mu_common_argp_parser,
113    "",    "",
# Line 121  struct argp_child mu_common_argp_child = Line 124  struct argp_child mu_common_argp_child =
124    1    1
125  };  };
126    
127  struct argp mu_auth_argp =  struct argp mu_auth_argp = {
 {  
128    mu_auth_argp_option,    mu_auth_argp_option,
129    mu_common_argp_parser,    mu_common_argp_parser,
130    "",    "",
# Line 139  struct argp_child mu_auth_argp_child = { Line 141  struct argp_child mu_auth_argp_child = {
141    1    1
142  };  };
143    
144  struct argp mu_logging_argp =  struct argp mu_logging_argp = {
 {  
145    mu_logging_argp_option,    mu_logging_argp_option,
146    mu_common_argp_parser,    mu_common_argp_parser,
147    "",    "",
# Line 157  struct argp_child mu_logging_argp_child Line 158  struct argp_child mu_logging_argp_child
158    1    1
159  };  };
160    
161  struct argp mu_daemon_argp =  struct argp mu_daemon_argp = {
 {  
162    mu_daemon_argp_option,    mu_daemon_argp_option,
163    mu_daemon_argp_parser,    mu_daemon_argp_parser,
164    "",    "",
# Line 361  mu_daemon_argp_parser (int key, char *ar Line 361  mu_daemon_argp_parser (int key, char *ar
361  # define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc"  # define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc"
362  #endif  #endif
363    
364    #ifndef MU_USER_CONFIG_FILE
365    # define MU_USER_CONFIG_FILE ".mailutils"
366    #endif
367    
368  static int  static int
369  member (const char *array[], const char *text, size_t len)  member (const char *array[], const char *text, size_t len)
370  {  {
# Line 372  member (const char *array[], const char Line 376  member (const char *array[], const char
376  }  }
377    
378  void  void
379    read_rc (const char *progname, const char *name, const char *capa[],
380             int *argc, char ***argv)
381    {
382      FILE *fp;
383      char *linebuf = NULL;
384      char *buf = NULL;
385      size_t n = 0;
386      int x_argc = *argc;
387      char **x_argv = *argv;
388    
389      fp = fopen (name, "r");
390      if (!fp)
391        return;
392      
393      while (getline (&buf, &n, fp) > 0)
394        {
395          char *kwp, *p;
396          int len;
397          
398          for (kwp = buf; *kwp && isspace (*kwp); kwp++)
399            ;
400    
401          if (*kwp == '#' || *kwp == 0)
402            continue;
403    
404          len = strlen (kwp);
405          if (kwp[len-1] == '\n')
406            kwp[--len] = 0;
407    
408          if (kwp[len-1] == '\\' || linebuf)
409            {
410              int cont;
411              
412              if (kwp[len-1] == '\\')
413                {
414                  kwp[--len] = 0;
415                  cont = 1;
416                }
417              else
418                cont = 0;
419              
420              if (!linebuf)
421                linebuf = calloc (len + 1, 1);
422              else
423                linebuf = realloc (linebuf, strlen (linebuf) + len + 1);
424              
425              if (!linebuf)
426                {
427                  fprintf (stderr, "%s: not enough memory\n", progname);
428                  exit (1);
429                }
430              
431              strcpy (linebuf + strlen (linebuf), kwp);
432              if (cont)
433                continue;
434              kwp = linebuf;
435            }
436    
437          len = 0;
438          for (p = kwp; *p && !isspace (*p); p++)
439            len++;
440    
441          if ((kwp[0] == ':'
442               && member (capa, kwp+1, len-1))
443              || strncmp (progname, kwp, len) == 0)
444            {
445              int i, n_argc = 0;
446              char **n_argv;
447                  
448              if (argcv_get (p, "", NULL, &n_argc, &n_argv))
449                {
450                  argcv_free (n_argc, n_argv);
451                  if (linebuf)
452                    free (linebuf);
453                  linebuf = NULL;
454                  continue;
455                }
456              x_argv = realloc (x_argv,
457                                (x_argc + n_argc) * sizeof (x_argv[0]));
458              if (!x_argv)
459                {
460                  fprintf (stderr, "%s: not enough memory\n", progname);
461                  exit (1);
462                }
463              
464              for (i = 0; i < n_argc; i++)
465                x_argv[x_argc++] = n_argv[i];
466              
467              free (n_argv);
468              if (linebuf)
469                free (linebuf);
470              linebuf = NULL;
471            }
472        }
473      fclose (fp);
474    
475      *argc = x_argc;
476      *argv = x_argv;
477    }
478    
479    
480    void
481  mu_create_argcv (const char *capa[],  mu_create_argcv (const char *capa[],
482                   int argc, char **argv, int *p_argc, char ***p_argv)                   int argc, char **argv, int *p_argc, char ***p_argv)
483  {  {
   FILE *fp;  
484    char *progname;    char *progname;
485    int x_argc;    int x_argc;
486    char **x_argv;    char **x_argv;
487    int i;    int i;
488      struct passwd *pw;
489        
490    progname = strrchr (argv[0], '/');    progname = strrchr (argv[0], '/');
491    if (progname)    if (progname)
# Line 399  mu_create_argcv (const char *capa[], Line 505  mu_create_argcv (const char *capa[],
505    x_argv[x_argc] = argv[x_argc];    x_argv[x_argc] = argv[x_argc];
506    x_argc++;    x_argc++;
507    
508    /* Process the mailutils.rc file */    read_rc (progname, MU_CONFIG_FILE, capa, &x_argc, &x_argv);
509    fp = fopen (MU_CONFIG_FILE, "r");    pw = getpwuid (getuid ());
510    if (fp)    if (pw)
511      {      {
512        char *linebuf = NULL;        struct stat sb;
513        char *buf = NULL;  
514        size_t n = 0;        if (stat (pw->pw_dir, &sb) == 0 && S_ISDIR (sb.st_mode))
515                  {
516        while (getline (&buf, &n, fp) > 0)            /* note: sizeof return value counts terminating zero */
517          {            char *name = xmalloc (strlen (pw->pw_dir) + 1
518            char *kwp, *p;                                          + sizeof (MU_USER_CONFIG_FILE));
519            int len;            sprintf (name, "%s/%s", pw->pw_dir, MU_USER_CONFIG_FILE);
520                        read_rc (progname, name, capa, &x_argc, &x_argv);
521            for (kwp = buf; *kwp && isspace (*kwp); kwp++)            free (name);
522              ;          }
   
           if (*kwp == '#' || *kwp == 0)  
             continue;  
   
           len = strlen (kwp);  
           if (kwp[len-1] == '\n')  
             kwp[--len] = 0;  
   
           if (kwp[len-1] == '\\' || linebuf)  
             {  
               int cont;  
                 
               if (kwp[len-1] == '\\')  
                 {  
                   kwp[--len] = 0;  
                   cont = 1;  
                 }  
               else  
                 cont = 0;  
                 
               if (!linebuf)  
                 linebuf = calloc (len + 1, 1);  
               else  
                 linebuf = realloc (linebuf, strlen (linebuf) + len + 1);  
   
               if (!linebuf)  
                 {  
                   fprintf (stderr, "%s: not enough memory\n", progname);  
                   exit (1);  
                 }  
   
               strcpy (linebuf + strlen (linebuf), kwp);  
               if (cont)  
                 continue;  
               kwp = linebuf;  
             }  
   
           len = 0;  
           for (p = kwp; *p && !isspace (*p); p++)  
             len++;  
   
           if ((kwp[0] == ':'  
                && member (capa, kwp+1, len-1))  
               || strncmp (progname, kwp, len) == 0)  
             {  
               int n_argc = 0;  
               char **n_argv;  
                 
               if (argcv_get (p, "", NULL, &n_argc, &n_argv))  
                 {  
                   argcv_free (n_argc, n_argv);  
                   if (linebuf)  
                     free (linebuf);  
                   linebuf = NULL;  
                   continue;  
                 }  
               x_argv = realloc (x_argv,  
                                 (x_argc + n_argc + 1) * sizeof (x_argv[0]));  
               if (!x_argv)  
                 {  
                   fprintf (stderr, "%s: not enough memory\n", progname);  
                   exit (1);  
                 }  
   
               for (i = 0; i < n_argc; i++)  
                 x_argv[x_argc++] = n_argv[i];  
   
               free (n_argv);  
               if (linebuf)  
                 free (linebuf);  
               linebuf = NULL;  
             }  
         }  
       fclose (fp);  
523      }      }
524    
525    /* Finally, add the command line options */    /* Finally, add the command line options */
526    x_argv = realloc (x_argv, (x_argc + argc + 1) * sizeof (x_argv[0]));    x_argv = realloc (x_argv, (x_argc + argc) * sizeof (x_argv[0]));
527    for (i = 1; i < argc; i++)    for (i = 1; i < argc; i++)
528      x_argv[x_argc++] = argv[i];      x_argv[x_argc++] = argv[i];
529        
# Line 555  mu_build_argp (const struct argp *templa Line 587  mu_build_argp (const struct argp *templa
587          {          {
588            mu_error ("INTERNAL ERROR: requested unknown argp capability %s",            mu_error ("INTERNAL ERROR: requested unknown argp capability %s",
589                      capa[n]);                      capa[n]);
590            continue;            abort ();
591          }          }
592        ap[n] = *tmp;        ap[n] = *tmp;
593        ap[n].group = n;        ap[n].group = n;

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26