popt/poptconfig.c

説明を見る。
00001 /** \ingroup popt
00002  * \file popt/poptconfig.c
00003  */
00004 
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 }

Sambaに対してSat Aug 29 21:23:13 2009に生成されました。  doxygen 1.4.7