root/lib/popt/poptconfig.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. configLine
  2. poptReadConfigFile
  3. poptReadDefaultConfig

   1 /** \ingroup popt
   2  * \file popt/poptconfig.c
   3  */
   4 
   5 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
   6    file accompanying popt source distributions, available from 
   7    ftp://ftp.rpm.org/pub/rpm/dist. */
   8 
   9 #include "system.h"
  10 #include "poptint.h"
  11 
  12 /*@-compmempass@*/      /* FIX: item->option.longName kept, not dependent. */
  13 static void configLine(poptContext con, char * line)
     /* [<][>][^][v][top][bottom][index][help] */
  14         /*@modifies con @*/
  15 {
  16     /*@-type@*/
  17     int nameLength = strlen(con->appName);
  18     /*@=type@*/
  19     const char * entryType;
  20     const char * opt;
  21     poptItem item = (poptItem)alloca(sizeof(*item));
  22     int i, j;
  23     
  24 /*@-boundswrite@*/
  25     memset(item, 0, sizeof(*item));
  26 
  27     /*@-type@*/
  28     if (strncmp(line, con->appName, nameLength)) return;
  29     /*@=type@*/
  30 
  31     line += nameLength;
  32     if (*line == '\0' || !isspace(*line)) return;
  33 
  34     while (*line != '\0' && isspace(*line)) line++;
  35     entryType = line;
  36     while (*line == '\0' || !isspace(*line)) line++;
  37     *line++ = '\0';
  38 
  39     while (*line != '\0' && isspace(*line)) line++;
  40     if (*line == '\0') return;
  41     opt = line;
  42     while (*line == '\0' || !isspace(*line)) line++;
  43     *line++ = '\0';
  44 
  45     while (*line != '\0' && isspace(*line)) line++;
  46     if (*line == '\0') return;
  47 
  48     /*@-temptrans@*/ /* FIX: line alias is saved */
  49     if (opt[0] == '-' && opt[1] == '-')
  50         item->option.longName = opt + 2;
  51     else if (opt[0] == '-' && opt[2] == '\0')
  52         item->option.shortName = opt[1];
  53     /*@=temptrans@*/
  54 
  55     if (poptParseArgvString(line, &item->argc, &item->argv)) return;
  56 
  57     /*@-modobserver@*/
  58     item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
  59     for (i = 0, j = 0; i < item->argc; i++, j++) {
  60         const char * f;
  61         if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
  62             f = item->argv[i] + sizeof("--POPTdesc=");
  63             if (f[0] == '$' && f[1] == '"') f++;
  64             item->option.descrip = f;
  65             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
  66             j--;
  67         } else
  68         if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
  69             f = item->argv[i] + sizeof("--POPTargs=");
  70             if (f[0] == '$' && f[1] == '"') f++;
  71             item->option.argDescrip = f;
  72             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
  73             item->option.argInfo |= POPT_ARG_STRING;
  74             j--;
  75         } else
  76         if (j != i)
  77             item->argv[j] = item->argv[i];
  78     }
  79     if (j != i) {
  80         item->argv[j] = NULL;
  81         item->argc = j;
  82     }
  83     /*@=modobserver@*/
  84 /*@=boundswrite@*/
  85 
  86     /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
  87     if (!strcmp(entryType, "alias"))
  88         (void) poptAddItem(con, item, 0);
  89     else if (!strcmp(entryType, "exec"))
  90         (void) poptAddItem(con, item, 1);
  91     /*@=nullstate@*/
  92 }
  93 /*@=compmempass@*/
  94 
  95 int poptReadConfigFile(poptContext con, const char * fn)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97     const char * file, * chptr, * end;
  98     char * buf;
  99 /*@dependent@*/ char * dst;
 100     int fd, rc;
 101     off_t fileLength;
 102 
 103     fd = open(fn, O_RDONLY);
 104     if (fd < 0)
 105         return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
 106 
 107     fileLength = lseek(fd, 0, SEEK_END);
 108     if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
 109         rc = errno;
 110         (void) close(fd);
 111         /*@-mods@*/
 112         errno = rc;
 113         /*@=mods@*/
 114         return POPT_ERROR_ERRNO;
 115     }
 116 
 117     file = (const char *)alloca(fileLength + 1);
 118     if (read(fd, (char *)file, fileLength) != fileLength) {
 119         rc = errno;
 120         (void) close(fd);
 121         /*@-mods@*/
 122         errno = rc;
 123         /*@=mods@*/
 124         return POPT_ERROR_ERRNO;
 125     }
 126     if (close(fd) == -1)
 127         return POPT_ERROR_ERRNO;
 128 
 129 /*@-boundswrite@*/
 130     dst = buf = (char *)alloca(fileLength + 1);
 131 
 132     chptr = file;
 133     end = (file + fileLength);
 134     /*@-infloops@*/     /* LCL: can't detect chptr++ */
 135     while (chptr < end) {
 136         switch (*chptr) {
 137           case '\n':
 138             *dst = '\0';
 139             dst = buf;
 140             while (*dst && isspace(*dst)) dst++;
 141             if (*dst && *dst != '#')
 142                 configLine(con, dst);
 143             chptr++;
 144             /*@switchbreak@*/ break;
 145           case '\\':
 146             *dst++ = *chptr++;
 147             if (chptr < end) {
 148                 if (*chptr == '\n') 
 149                     dst--, chptr++;     
 150                     /* \ at the end of a line does not insert a \n */
 151                 else
 152                     *dst++ = *chptr++;
 153             }
 154             /*@switchbreak@*/ break;
 155           default:
 156             *dst++ = *chptr++;
 157             /*@switchbreak@*/ break;
 158         }
 159     }
 160     /*@=infloops@*/
 161 /*@=boundswrite@*/
 162 
 163     return 0;
 164 }
 165 
 166 int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
     /* [<][>][^][v][top][bottom][index][help] */
 167 {
 168     char * fn, * home;
 169     int rc;
 170 
 171     /*@-type@*/
 172     if (!con->appName) return 0;
 173     /*@=type@*/
 174 
 175     rc = poptReadConfigFile(con, "/etc/popt");
 176     if (rc) return rc;
 177 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
 178     if (getuid() != geteuid()) return 0;
 179 #endif
 180 
 181     if ((home = getenv("HOME"))) {
 182         fn = (char *)alloca(strlen(home) + 20);
 183         strcpy(fn, home);
 184         strcat(fn, "/.popt");
 185         rc = poptReadConfigFile(con, fn);
 186         if (rc) return rc;
 187     }
 188 
 189     return 0;
 190 }

/* [<][>][^][v][top][bottom][index][help] */