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>