Main Page Modules Data Structures File List Data Fields Globals Related Pages

# popt/poptconfig.c

Go to the documentation of this file.

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