X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/6afe7f23b0440d3261fb99e3f7b4d56bd00713cc..e9ad7bb1f846834190ae8377d5e8f0ded543ff3a:/popt/poptconfig.c diff --git a/popt/poptconfig.c b/popt/poptconfig.c index eb769413..9733d152 100644 --- a/popt/poptconfig.c +++ b/popt/poptconfig.c @@ -1,101 +1,144 @@ -/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING +/** \ingroup popt + * \file popt/poptconfig.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from - ftp://ftp.redhat.com/pub/code/popt */ + ftp://ftp.rpm.org/pub/rpm/dist. */ #include "system.h" #include "poptint.h" - -static void configLine(poptContext con, char * line) { - int nameLength = strlen(con->appName); - char * opt; - struct poptAlias alias; - char * entryType; - char * longName = NULL; - char shortName = '\0'; +/*@access poptContext @*/ + +/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ +static void configLine(poptContext con, char * line) + /*@modifies con @*/ +{ + size_t nameLength; + const char * entryType; + const char * opt; + poptItem item = (poptItem) alloca(sizeof(*item)); + int i, j; + + if (con->appName == NULL) + return; + nameLength = strlen(con->appName); +/*@-boundswrite@*/ + memset(item, 0, sizeof(*item)); + if (strncmp(line, con->appName, nameLength)) return; + line += nameLength; - if (!*line || !isspace(*line)) return; - while (*line && isspace(*line)) line++; - entryType = line; + if (*line == '\0' || !isSpace(line)) return; - while (!*line || !isspace(*line)) line++; + while (*line != '\0' && isSpace(line)) line++; + entryType = line; + while (*line == '\0' || !isSpace(line)) line++; *line++ = '\0'; - while (*line && isspace(*line)) line++; - if (!*line) return; - opt = line; - while (!*line || !isspace(*line)) line++; + while (*line != '\0' && isSpace(line)) line++; + if (*line == '\0') return; + opt = line; + while (*line == '\0' || !isSpace(line)) line++; *line++ = '\0'; - while (*line && isspace(*line)) line++; - if (!*line) return; + while (*line != '\0' && isSpace(line)) line++; + if (*line == '\0') return; + + /*@-temptrans@*/ /* FIX: line alias is saved */ if (opt[0] == '-' && opt[1] == '-') - longName = opt + 2; - else if (opt[0] == '-' && !opt[2]) - shortName = opt[1]; - - if (!strcmp(entryType, "alias")) { - if (poptParseArgvString(line, &alias.argc, &alias.argv)) return; - alias.longName = longName, alias.shortName = shortName; - poptAddAlias(con, alias, 0); - } else if (!strcmp(entryType, "exec")) { - con->execs = realloc(con->execs, - sizeof(*con->execs) * (con->numExecs + 1)); - if (longName) - con->execs[con->numExecs].longName = xstrdup(longName); - else - con->execs[con->numExecs].longName = NULL; - - con->execs[con->numExecs].shortName = shortName; - con->execs[con->numExecs].script = xstrdup(line); - - con->numExecs++; + item->option.longName = opt + 2; + else if (opt[0] == '-' && opt[2] == '\0') + item->option.shortName = opt[1]; + /*@=temptrans@*/ + + if (poptParseArgvString(line, &item->argc, &item->argv)) return; + + /*@-modobserver@*/ + item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; + for (i = 0, j = 0; i < item->argc; i++, j++) { + const char * f; + if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { + f = item->argv[i] + sizeof("--POPTdesc="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.descrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + j--; + } else + if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { + f = item->argv[i] + sizeof("--POPTargs="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.argDescrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + item->option.argInfo |= POPT_ARG_STRING; + j--; + } else + if (j != i) + item->argv[j] = item->argv[i]; + } + if (j != i) { + item->argv[j] = NULL; + item->argc = j; } + /*@=modobserver@*/ +/*@=boundswrite@*/ + + /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ + if (!strcmp(entryType, "alias")) + (void) poptAddItem(con, item, 0); + else if (!strcmp(entryType, "exec")) + (void) poptAddItem(con, item, 1); + /*@=nullstate@*/ } +/*@=compmempass@*/ -int poptReadConfigFile(poptContext con, const char * fn) { - char * file=NULL, * chptr, * end; - char * buf=NULL, * dst; +int poptReadConfigFile(poptContext con, const char * fn) +{ + const char * file, * chptr, * end; + char * buf; +/*@dependent@*/ char * dst; int fd, rc; - int fileLength; + off_t fileLength; fd = open(fn, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) - return 0; - else - return POPT_ERROR_ERRNO; - } + if (fd < 0) + return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); fileLength = lseek(fd, 0, SEEK_END); - (void) lseek(fd, 0, 0); + if (fileLength == -1 || lseek(fd, 0, 0) == -1) { + rc = errno; + (void) close(fd); + errno = rc; + return POPT_ERROR_ERRNO; + } - file = malloc(fileLength + 1); - if (read(fd, file, fileLength) != fileLength) { + file = alloca(fileLength + 1); + if (read(fd, (char *)file, fileLength) != fileLength) { rc = errno; - close(fd); + (void) close(fd); errno = rc; - if (file) free(file); return POPT_ERROR_ERRNO; } - close(fd); + if (close(fd) == -1) + return POPT_ERROR_ERRNO; - dst = buf = malloc(fileLength + 1); +/*@-boundswrite@*/ + dst = buf = alloca(fileLength + 1); chptr = file; end = (file + fileLength); + /*@-infloops@*/ /* LCL: can't detect chptr++ */ while (chptr < end) { switch (*chptr) { case '\n': *dst = '\0'; dst = buf; - while (*dst && isspace(*dst)) dst++; - if (*dst && *dst != '#') { + while (*dst && isSpace(dst)) dst++; + if (*dst && *dst != '#') configLine(con, dst); - } chptr++; - break; + /*@switchbreak@*/ break; case '\\': *dst++ = *chptr++; if (chptr < end) { @@ -105,38 +148,36 @@ int poptReadConfigFile(poptContext con, const char * fn) { else *dst++ = *chptr++; } - break; + /*@switchbreak@*/ break; default: *dst++ = *chptr++; - break; + /*@switchbreak@*/ break; } } - - free(file); - free(buf); + /*@=infloops@*/ +/*@=boundswrite@*/ return 0; } -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) { +int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) +{ char * fn, * home; int rc; - if (!con->appName) return 0; + if (con->appName == NULL) return 0; rc = poptReadConfigFile(con, "/etc/popt"); if (rc) return rc; - if (getuid() != geteuid()) return 0; if ((home = getenv("HOME"))) { - fn = malloc(strlen(home) + 20); - strcpy(fn, home); - strcat(fn, "/.popt"); + size_t bufsize = strlen(home) + 20; + fn = alloca(bufsize); + if (fn == NULL) return 0; + snprintf(fn, bufsize, "%s/.popt", home); rc = poptReadConfigFile(con, fn); - free(fn); if (rc) return rc; } return 0; } -