Annotation of embedaddon/rsync/popt/poptconfig.c, revision 1.1.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>