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 /*@access poptContext @*/
00012 
00013 /*@-compmempass@*/      /* FIX: item->option.longName kept, not dependent. */
00014 static void configLine(poptContext con, char * line)
00015         /*@modifies con @*/
00016 {
00017     size_t nameLength;
00018     const char * entryType;
00019     const char * opt;
00020     struct poptItem_s item_buf;
00021     poptItem item = &item_buf;
00022     int i, j;
00023 
00024     if (con->appName == NULL)
00025         return;
00026     nameLength = strlen(con->appName);
00027     
00028 /*@-boundswrite@*/
00029     memset(item, 0, sizeof(*item));
00030 
00031     if (strncmp(line, con->appName, nameLength)) return;
00032 
00033     line += nameLength;
00034     if (*line == '\0' || !isspace(*line)) return;
00035 
00036     while (*line != '\0' && isspace(*line)) line++;
00037     entryType = line;
00038     while (*line == '\0' || !isspace(*line)) line++;
00039     *line++ = '\0';
00040 
00041     while (*line != '\0' && isspace(*line)) line++;
00042     if (*line == '\0') return;
00043     opt = line;
00044     while (*line == '\0' || !isspace(*line)) line++;
00045     *line++ = '\0';
00046 
00047     while (*line != '\0' && isspace(*line)) line++;
00048     if (*line == '\0') return;
00049 
00050 /*@-temptrans@*/ /* FIX: line alias is saved */
00051     if (opt[0] == '-' && opt[1] == '-')
00052         item->option.longName = opt + 2;
00053     else if (opt[0] == '-' && opt[2] == '\0')
00054         item->option.shortName = opt[1];
00055 /*@=temptrans@*/
00056 
00057     if (poptParseArgvString(line, &item->argc, &item->argv)) return;
00058 
00059 /*@-modobserver@*/
00060     item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
00061     for (i = 0, j = 0; i < item->argc; i++, j++) {
00062         const char * f;
00063         if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
00064             f = item->argv[i] + sizeof("--POPTdesc=");
00065             if (f[0] == '$' && f[1] == '"') f++;
00066             item->option.descrip = f;
00067             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00068             j--;
00069         } else
00070         if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
00071             f = item->argv[i] + sizeof("--POPTargs=");
00072             if (f[0] == '$' && f[1] == '"') f++;
00073             item->option.argDescrip = f;
00074             item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00075             item->option.argInfo |= POPT_ARG_STRING;
00076             j--;
00077         } else
00078         if (j != i)
00079             item->argv[j] = item->argv[i];
00080     }
00081     if (j != i) {
00082         item->argv[j] = NULL;
00083         item->argc = j;
00084     }
00085 /*@=modobserver@*/
00086 /*@=boundswrite@*/
00087         
00088 /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
00089     if (!strcmp(entryType, "alias"))
00090         (void) poptAddItem(con, item, 0);
00091     else if (!strcmp(entryType, "exec"))
00092         (void) poptAddItem(con, item, 1);
00093 /*@=nullstate@*/
00094 }
00095 /*@=compmempass@*/
00096 
00097 int poptReadConfigFile(poptContext con, const char * fn)
00098 {
00099     char * file = NULL, * chptr, * end;
00100     char * buf = NULL;
00101 /*@dependent@*/ char * dst;
00102     int fd, rc;
00103     off_t fileLength;
00104 
00105     fd = open(fn, O_RDONLY);
00106     if (fd < 0)
00107         return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
00108 
00109     fileLength = lseek(fd, 0, SEEK_END);
00110     if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
00111         rc = errno;
00112         (void) close(fd);
00113         errno = rc;
00114         return POPT_ERROR_ERRNO;
00115     }
00116 
00117     file = malloc(fileLength + 1);
00118     if (read(fd, (char *)file, fileLength) != fileLength) {
00119         rc = errno;
00120         (void) close(fd);
00121         errno = rc;
00122         return POPT_ERROR_ERRNO;
00123     }
00124     if (close(fd) == -1) {
00125         free(file);
00126         return POPT_ERROR_ERRNO;
00127     }
00128 
00129 /*@-boundswrite@*/
00130     dst = buf = malloc(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     free(file);
00164     free(buf);
00165 
00166     return 0;
00167 }
00168 
00169 int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
00170 {
00171     char * fn, * home;
00172     int rc;
00173 
00174     if (con->appName == NULL) return 0;
00175 
00176     rc = poptReadConfigFile(con, POPT_SYSCONFDIR "/popt");
00177     if (rc) return rc;
00178 
00179     rc = poptReadConfigFile(con, "/etc/popt");
00180     if (rc) return rc;
00181 
00182     if ((home = getenv("HOME"))) {
00183         fn = malloc(strlen(home) + 20);
00184         strcpy(fn, home);
00185         strcat(fn, "/.popt");
00186         rc = poptReadConfigFile(con, fn);
00187         free(fn);
00188         if (rc) return rc;
00189     }
00190 
00191     return 0;
00192 }

Generated on Thu Aug 23 18:55:04 2007 for popt by  doxygen 1.5.2