Annotation of embedaddon/rsync/popt/poptconfig.c, revision 1.1
1.1 ! misho 1: /** \ingroup popt
! 2: * \file popt/poptconfig.c
! 3: */
! 4:
! 5: /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
! 6: file accompanying popt source distributions, available from
! 7: ftp://ftp.rpm.org/pub/rpm/dist. */
! 8:
! 9: #include "system.h"
! 10: #include "poptint.h"
! 11: /*@access poptContext @*/
! 12:
! 13: /*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
! 14: static void configLine(poptContext con, char * line)
! 15: /*@modifies con @*/
! 16: {
! 17: size_t nameLength;
! 18: const char * entryType;
! 19: const char * opt;
! 20: poptItem item = (poptItem) alloca(sizeof(*item));
! 21: int i, j;
! 22:
! 23: if (con->appName == NULL)
! 24: return;
! 25: nameLength = strlen(con->appName);
! 26:
! 27: /*@-boundswrite@*/
! 28: memset(item, 0, sizeof(*item));
! 29:
! 30: if (strncmp(line, con->appName, nameLength)) return;
! 31:
! 32: line += nameLength;
! 33: if (*line == '\0' || !isSpace(line)) return;
! 34:
! 35: while (*line != '\0' && isSpace(line)) line++;
! 36: entryType = line;
! 37: while (*line == '\0' || !isSpace(line)) line++;
! 38: *line++ = '\0';
! 39:
! 40: while (*line != '\0' && isSpace(line)) line++;
! 41: if (*line == '\0') return;
! 42: opt = line;
! 43: while (*line == '\0' || !isSpace(line)) line++;
! 44: *line++ = '\0';
! 45:
! 46: while (*line != '\0' && isSpace(line)) line++;
! 47: if (*line == '\0') return;
! 48:
! 49: /*@-temptrans@*/ /* FIX: line alias is saved */
! 50: if (opt[0] == '-' && opt[1] == '-')
! 51: item->option.longName = opt + 2;
! 52: else if (opt[0] == '-' && opt[2] == '\0')
! 53: item->option.shortName = opt[1];
! 54: /*@=temptrans@*/
! 55:
! 56: if (poptParseArgvString(line, &item->argc, &item->argv)) return;
! 57:
! 58: /*@-modobserver@*/
! 59: item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
! 60: for (i = 0, j = 0; i < item->argc; i++, j++) {
! 61: const char * f;
! 62: if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
! 63: f = item->argv[i] + sizeof("--POPTdesc=");
! 64: if (f[0] == '$' && f[1] == '"') f++;
! 65: item->option.descrip = f;
! 66: item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
! 67: j--;
! 68: } else
! 69: if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
! 70: f = item->argv[i] + sizeof("--POPTargs=");
! 71: if (f[0] == '$' && f[1] == '"') f++;
! 72: item->option.argDescrip = f;
! 73: item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
! 74: item->option.argInfo |= POPT_ARG_STRING;
! 75: j--;
! 76: } else
! 77: if (j != i)
! 78: item->argv[j] = item->argv[i];
! 79: }
! 80: if (j != i) {
! 81: item->argv[j] = NULL;
! 82: item->argc = j;
! 83: }
! 84: /*@=modobserver@*/
! 85: /*@=boundswrite@*/
! 86:
! 87: /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
! 88: if (!strcmp(entryType, "alias"))
! 89: (void) poptAddItem(con, item, 0);
! 90: else if (!strcmp(entryType, "exec"))
! 91: (void) poptAddItem(con, item, 1);
! 92: /*@=nullstate@*/
! 93: }
! 94: /*@=compmempass@*/
! 95:
! 96: int poptReadConfigFile(poptContext con, const char * fn)
! 97: {
! 98: const char * file, * chptr, * end;
! 99: char * buf;
! 100: /*@dependent@*/ char * dst;
! 101: int fd, rc;
! 102: off_t fileLength;
! 103:
! 104: fd = open(fn, O_RDONLY);
! 105: if (fd < 0)
! 106: return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
! 107:
! 108: fileLength = lseek(fd, 0, SEEK_END);
! 109: if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
! 110: rc = errno;
! 111: (void) close(fd);
! 112: errno = rc;
! 113: return POPT_ERROR_ERRNO;
! 114: }
! 115:
! 116: file = alloca(fileLength + 1);
! 117: if (read(fd, (char *)file, fileLength) != fileLength) {
! 118: rc = errno;
! 119: (void) close(fd);
! 120: errno = rc;
! 121: return POPT_ERROR_ERRNO;
! 122: }
! 123: if (close(fd) == -1)
! 124: return POPT_ERROR_ERRNO;
! 125:
! 126: /*@-boundswrite@*/
! 127: dst = buf = alloca(fileLength + 1);
! 128:
! 129: chptr = file;
! 130: end = (file + fileLength);
! 131: /*@-infloops@*/ /* LCL: can't detect chptr++ */
! 132: while (chptr < end) {
! 133: switch (*chptr) {
! 134: case '\n':
! 135: *dst = '\0';
! 136: dst = buf;
! 137: while (*dst && isSpace(dst)) dst++;
! 138: if (*dst && *dst != '#')
! 139: configLine(con, dst);
! 140: chptr++;
! 141: /*@switchbreak@*/ break;
! 142: case '\\':
! 143: *dst++ = *chptr++;
! 144: if (chptr < end) {
! 145: if (*chptr == '\n')
! 146: dst--, chptr++;
! 147: /* \ at the end of a line does not insert a \n */
! 148: else
! 149: *dst++ = *chptr++;
! 150: }
! 151: /*@switchbreak@*/ break;
! 152: default:
! 153: *dst++ = *chptr++;
! 154: /*@switchbreak@*/ break;
! 155: }
! 156: }
! 157: /*@=infloops@*/
! 158: /*@=boundswrite@*/
! 159:
! 160: return 0;
! 161: }
! 162:
! 163: int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
! 164: {
! 165: char * fn, * home;
! 166: int rc;
! 167:
! 168: if (con->appName == NULL) return 0;
! 169:
! 170: rc = poptReadConfigFile(con, "/etc/popt");
! 171: if (rc) return rc;
! 172:
! 173: if ((home = getenv("HOME"))) {
! 174: size_t bufsize = strlen(home) + 20;
! 175: fn = alloca(bufsize);
! 176: if (fn == NULL) return 0;
! 177: snprintf(fn, bufsize, "%s/.popt", home);
! 178: rc = poptReadConfigFile(con, fn);
! 179: if (rc) return rc;
! 180: }
! 181:
! 182: return 0;
! 183: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>