# popt/poptconfig.c

Go to the documentation of this file.

    00001
    00005 /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
    00006    file accompanying popt source distributions, available from
    00007    ftp://ftp.rpm.org/pub/rpm/dist. */
    00008
    00009 #include "system.h"
    00010 #include "poptint.h"
    00011
    00012 /*@-compmempass@*/      /* FIX: item->option.longName kept, not dependent. */
    00013 static void configLine(poptContext con, char * line)
    00014         /*@modifies con @*/
    00015 {
    00016     /*@-type@*/
    00017     int nameLength = strlen(con->appName);
    00018     /*@=type@*/
    00019     const char * entryType;
    00020     const char * opt;
    00021     poptItem item = alloca(sizeof(*item));
    00022     int i, j;
    00023
    00024     memset(item, 0, sizeof(*item));
    00025
    00026     /*@-type@*/
    00027     if (strncmp(line, con->appName, nameLength)) return;
    00028     /*@=type@*/
    00029
    00030     line += nameLength;
    00031     if (*line == '\0' || !isspace(*line)) return;
    00032
    00033     while (*line != '\0' && isspace(*line)) line++;
    00034     entryType = line;
    00035     while (*line == '\0' || !isspace(*line)) line++;
    00036     *line++ = '\0';
    00037
    00038     while (*line != '\0' && isspace(*line)) line++;
    00039     if (*line == '\0') return;
    00040     opt = line;
    00041     while (*line == '\0' || !isspace(*line)) line++;
    00042     *line++ = '\0';
    00043
    00044     while (*line != '\0' && isspace(*line)) line++;
    00045     if (*line == '\0') return;
    00046
    00047     /*@-temptrans@*/ /* FIX: line alias is saved */
    00048     if (opt[0] == '-' && opt[1] == '-')
    00049         item->option.longName = opt + 2;
    00050     else if (opt[0] == '-' && opt[2] == '\0')
    00051         item->option.shortName = opt[1];
    00052     /*@=temptrans@*/
    00053
    00054     if (poptParseArgvString(line, &item->argc, &item->argv)) return;
    00055
    00056     /*@-modobserver@*/
    00057     item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
    00058     for (i = 0, j = 0; i < item->argc; i++, j++) {
    00059         const char * f;
    00060         if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
    00061             f = item->argv[i] + sizeof("--POPTdesc=");
    00062             if (f[0] == '$' && f[1] == '"') f++;
    00063             item->option.descrip = f;
    00064             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
    00065             j--;
    00066         } else
    00067         if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
    00068             f = item->argv[i] + sizeof("--POPTargs=");
    00069             if (f[0] == '$' && f[1] == '"') f++;
    00070             item->option.argDescrip = f;
    00071             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
    00072             item->option.argInfo |= POPT_ARG_STRING;
    00073             j--;
    00074         } else
    00075         if (j != i)
    00076             item->argv[j] = item->argv[i];
    00077     }
    00078     if (j != i) {
    00079         item->argv[j] = NULL;
    00080         item->argc = j;
    00081     }
    00082     /*@=modobserver@*/
    00083
    00084     /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
    00085     if (!strcmp(entryType, "alias"))
    00086         (void) poptAddItem(con, item, 0);
    00087     else if (!strcmp(entryType, "exec"))
    00088         (void) poptAddItem(con, item, 1);
    00089     /*@=nullstate@*/
    00090 }
    00091 /*@=compmempass@*/
    00092
    00093 int poptReadConfigFile(poptContext con, const char * fn)
    00094 {
    00095     const char * file, * chptr, * end;
    00096     char * buf;
    00097 /*@dependent@*/ char * dst;
    00098     int fd, rc;
    00099     off_t fileLength;
    00100
    00101     fd = open(fn, O_RDONLY);
    00102     if (fd < 0)
    00103         return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
    00104
    00105     fileLength = lseek(fd, 0, SEEK_END);
    00106     if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
    00107         rc = errno;
    00108         (void) close(fd);
    00109         /*@-mods@*/
    00110         errno = rc;
    00111         /*@=mods@*/
    00112         return POPT_ERROR_ERRNO;
    00113     }
    00114
    00115     file = alloca(fileLength + 1);
    00116     if (read(fd, (char *)file, fileLength) != fileLength) {
    00117         rc = errno;
    00118         (void) close(fd);
    00119         /*@-mods@*/
    00120         errno = rc;
    00121         /*@=mods@*/
    00122         return POPT_ERROR_ERRNO;
    00123     }
    00124     if (close(fd) == -1)
    00125         return POPT_ERROR_ERRNO;
    00126
    00127     dst = buf = alloca(fileLength + 1);
    00128
    00129     chptr = file;
    00130     end = (file + fileLength);
    00131     /*@-infloops@*/     /* LCL: can't detect chptr++ */
    00132     while (chptr < end) {
    00133         switch (*chptr) {
    00134           case '\n':
    00135             *dst = '\0';
    00136             dst = buf;
    00137             while (*dst && isspace(*dst)) dst++;
    00138             if (*dst && *dst != '#')
    00139                 configLine(con, dst);
    00140             chptr++;
    00141             /*@switchbreak@*/ break;
    00142           case '\\':
    00143             *dst++ = *chptr++;
    00144             if (chptr < end) {
    00145                 if (*chptr == '\n')
    00146                     dst--, chptr++;
    00147                     /* \ at the end of a line does not insert a \n */
    00148                 else
    00149                     *dst++ = *chptr++;
    00150             }
    00151             /*@switchbreak@*/ break;
    00152           default:
    00153             *dst++ = *chptr++;
    00154             /*@switchbreak@*/ break;
    00155         }
    00156     }
    00157     /*@=infloops@*/
    00158
    00159     return 0;
    00160 }
    00161
    00162 int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
    00163     char * fn, * home;
    00164     int rc;
    00165
    00166     /*@-type@*/
    00167     if (!con->appName) return 0;
    00168     /*@=type@*/
    00169
    00170     rc = poptReadConfigFile(con, "/etc/popt");
    00171     if (rc) return rc;
    00172     if (getuid() != geteuid()) return 0;
    00173
    00174     if ((home = getenv("HOME"))) {
    00175         fn = alloca(strlen(home) + 20);
    00176         strcpy(fn, home);
    00177         strcat(fn, "/.popt");
    00178         rc = poptReadConfigFile(con, fn);
    00179         if (rc) return rc;
    00180     }
    00181
    00182     return 0;
    00183 }