X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/cc248aae9bff569a771210e9b63f6f4dfe83e3a6..e9ad7bb1f846834190ae8377d5e8f0ded543ff3a:/popt/poptparse.c diff --git a/popt/poptparse.c b/popt/poptparse.c index 2ffb7dd2..e003a04a 100644 --- a/popt/poptparse.c +++ b/popt/poptparse.c @@ -2,14 +2,17 @@ * \file popt/poptparse.c */ -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from ftp://ftp.rpm.org/pub/rpm/dist. */ #include "system.h" +#include "poptint.h" + #define POPT_ARGV_ARRAY_GROW_DELTA 5 +/*@-boundswrite@*/ int poptDupArgv(int argc, const char **argv, int * argcPtr, const char *** argvPtr) { @@ -35,7 +38,7 @@ int poptDupArgv(int argc, const char **argv, /*@-branchstate@*/ for (i = 0; i < argc; i++) { argv2[i] = dst; - dst += strlen(strcpy(dst, argv[i])) + 1; + dst += strlcpy(dst, argv[i], nb) + 1; } /*@=branchstate@*/ argv2[argc] = NULL; @@ -50,7 +53,9 @@ int poptDupArgv(int argc, const char **argv, *argcPtr = argc; return 0; } +/*@=boundswrite@*/ +/*@-bounds@*/ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) { const char * src; @@ -78,7 +83,7 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) if (*src != quote) *buf++ = '\\'; } *buf++ = *src; - } else if (isspace(*src)) { + } else if (isSpace(src)) { if (*argv[argc] != '\0') { buf++, argc++; if (argc == argvAlloced) { @@ -116,3 +121,111 @@ exit: if (argv) free(argv); return rc; } +/*@=bounds@*/ + +/* still in the dev stage. + * return values, perhaps 1== file erro + * 2== line to long + * 3== umm.... more? + */ +int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags)) +{ + char line[999]; + char * argstr; + char * p; + char * q; + char * x; + int t; + int argvlen = 0; + size_t maxlinelen = sizeof(line); + size_t linelen; + int maxargvlen = 480; + int linenum = 0; + + *argstrp = NULL; + + /* | this_is = our_line + * p q x + */ + + if (fp == NULL) + return POPT_ERROR_NULLARG; + + argstr = calloc(maxargvlen, sizeof(*argstr)); + if (argstr == NULL) return POPT_ERROR_MALLOC; + + while (fgets(line, (int)maxlinelen, fp) != NULL) { + linenum++; + p = line; + + /* loop until first non-space char or EOL */ + while( *p != '\0' && isSpace(p) ) + p++; + + linelen = strlen(p); + if (linelen >= maxlinelen-1) { + free(argstr); + return POPT_ERROR_OVERFLOW; /* XXX line too long */ + } + + if (*p == '\0' || *p == '\n') continue; /* line is empty */ + if (*p == '#') continue; /* comment line */ + + q = p; + + while (*q != '\0' && (!isSpace(q)) && *q != '=') + q++; + + if (isSpace(q)) { + /* a space after the name, find next non space */ + *q++='\0'; + while( *q != '\0' && isSpace(q) ) q++; + } + if (*q == '\0') { + /* single command line option (ie, no name=val, just name) */ + q[-1] = '\0'; /* kill off newline from fgets() call */ + argvlen += (t = q - p) + (sizeof(" --")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strlcat(argstr, " --", maxargvlen); + strlcat(argstr, p, maxargvlen); + continue; + } + if (*q != '=') + continue; /* XXX for now, silently ignore bogus line */ + + /* *q is an equal sign. */ + *q++ = '\0'; + + /* find next non-space letter of value */ + while (*q != '\0' && isSpace(q)) + q++; + if (*q == '\0') + continue; /* XXX silently ignore missing value */ + + /* now, loop and strip all ending whitespace */ + x = p + linelen; + while (isSpace(--x)) + *x = 0; /* null out last char if space (including fgets() NL) */ + + /* rest of line accept */ + t = x - p; + argvlen += t + (sizeof("' --='")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strlcat(argstr, " --", maxargvlen); + strlcat(argstr, p, maxargvlen); + strlcat(argstr, "=\"", maxargvlen); + strlcat(argstr, q, maxargvlen); + strlcat(argstr, "\"", maxargvlen); + } + + *argstrp = argstr; + return 0; +}