Commit | Line | Data |
---|---|---|
cc248aae WD |
1 | /** \ingroup popt |
2 | * \file popt/poptconfig.c | |
3 | */ | |
4 | ||
bc93ee84 | 5 | /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING |
62402cb1 | 6 | file accompanying popt source distributions, available from |
cc248aae | 7 | ftp://ftp.rpm.org/pub/rpm/dist. */ |
62402cb1 | 8 | |
b348deae | 9 | #include "system.h" |
62402cb1 | 10 | #include "poptint.h" |
bc93ee84 | 11 | /*@access poptContext @*/ |
62402cb1 | 12 | |
cc248aae | 13 | /*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ |
bc93ee84 | 14 | static void configLine(poptContext con, char * line) |
cc248aae WD |
15 | /*@modifies con @*/ |
16 | { | |
bc93ee84 | 17 | size_t nameLength; |
cc248aae WD |
18 | const char * entryType; |
19 | const char * opt; | |
b17f1d76 | 20 | poptItem item = (poptItem) alloca(sizeof(*item)); |
cc248aae | 21 | int i, j; |
bc93ee84 WD |
22 | |
23 | if (con->appName == NULL) | |
24 | return; | |
25 | nameLength = strlen(con->appName); | |
62402cb1 | 26 | |
bc93ee84 | 27 | /*@-boundswrite@*/ |
cc248aae WD |
28 | memset(item, 0, sizeof(*item)); |
29 | ||
62402cb1 | 30 | if (strncmp(line, con->appName, nameLength)) return; |
cc248aae | 31 | |
62402cb1 | 32 | line += nameLength; |
a8facdc0 | 33 | if (*line == '\0' || !isSpace(line)) return; |
62402cb1 | 34 | |
a8facdc0 | 35 | while (*line != '\0' && isSpace(line)) line++; |
cc248aae | 36 | entryType = line; |
a8facdc0 | 37 | while (*line == '\0' || !isSpace(line)) line++; |
62402cb1 | 38 | *line++ = '\0'; |
62402cb1 | 39 | |
a8facdc0 | 40 | while (*line != '\0' && isSpace(line)) line++; |
cc248aae WD |
41 | if (*line == '\0') return; |
42 | opt = line; | |
a8facdc0 | 43 | while (*line == '\0' || !isSpace(line)) line++; |
62402cb1 | 44 | *line++ = '\0'; |
62402cb1 | 45 | |
a8facdc0 | 46 | while (*line != '\0' && isSpace(line)) line++; |
cc248aae WD |
47 | if (*line == '\0') return; |
48 | ||
49 | /*@-temptrans@*/ /* FIX: line alias is saved */ | |
62402cb1 | 50 | if (opt[0] == '-' && opt[1] == '-') |
cc248aae WD |
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; | |
62402cb1 | 83 | } |
cc248aae | 84 | /*@=modobserver@*/ |
bc93ee84 | 85 | /*@=boundswrite@*/ |
cc248aae WD |
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@*/ | |
62402cb1 | 93 | } |
cc248aae | 94 | /*@=compmempass@*/ |
62402cb1 | 95 | |
cc248aae WD |
96 | int poptReadConfigFile(poptContext con, const char * fn) |
97 | { | |
bc93ee84 WD |
98 | const char * file, * chptr, * end; |
99 | char * buf; | |
100 | /*@dependent@*/ char * dst; | |
62402cb1 | 101 | int fd, rc; |
cc248aae | 102 | off_t fileLength; |
62402cb1 MP |
103 | |
104 | fd = open(fn, O_RDONLY); | |
cc248aae WD |
105 | if (fd < 0) |
106 | return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); | |
62402cb1 MP |
107 | |
108 | fileLength = lseek(fd, 0, SEEK_END); | |
cc248aae WD |
109 | if (fileLength == -1 || lseek(fd, 0, 0) == -1) { |
110 | rc = errno; | |
111 | (void) close(fd); | |
cc248aae | 112 | errno = rc; |
cc248aae WD |
113 | return POPT_ERROR_ERRNO; |
114 | } | |
62402cb1 | 115 | |
cc248aae WD |
116 | file = alloca(fileLength + 1); |
117 | if (read(fd, (char *)file, fileLength) != fileLength) { | |
62402cb1 | 118 | rc = errno; |
cc248aae | 119 | (void) close(fd); |
62402cb1 MP |
120 | errno = rc; |
121 | return POPT_ERROR_ERRNO; | |
122 | } | |
cc248aae WD |
123 | if (close(fd) == -1) |
124 | return POPT_ERROR_ERRNO; | |
62402cb1 | 125 | |
bc93ee84 | 126 | /*@-boundswrite@*/ |
cc248aae | 127 | dst = buf = alloca(fileLength + 1); |
62402cb1 MP |
128 | |
129 | chptr = file; | |
130 | end = (file + fileLength); | |
cc248aae | 131 | /*@-infloops@*/ /* LCL: can't detect chptr++ */ |
62402cb1 MP |
132 | while (chptr < end) { |
133 | switch (*chptr) { | |
134 | case '\n': | |
135 | *dst = '\0'; | |
136 | dst = buf; | |
a8facdc0 | 137 | while (*dst && isSpace(dst)) dst++; |
cc248aae | 138 | if (*dst && *dst != '#') |
62402cb1 | 139 | configLine(con, dst); |
62402cb1 | 140 | chptr++; |
cc248aae | 141 | /*@switchbreak@*/ break; |
62402cb1 MP |
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 | } | |
cc248aae | 151 | /*@switchbreak@*/ break; |
62402cb1 MP |
152 | default: |
153 | *dst++ = *chptr++; | |
cc248aae | 154 | /*@switchbreak@*/ break; |
62402cb1 MP |
155 | } |
156 | } | |
cc248aae | 157 | /*@=infloops@*/ |
bc93ee84 | 158 | /*@=boundswrite@*/ |
6afe7f23 | 159 | |
62402cb1 MP |
160 | return 0; |
161 | } | |
162 | ||
73042aae | 163 | int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) |
37101856 | 164 | { |
62402cb1 MP |
165 | char * fn, * home; |
166 | int rc; | |
167 | ||
bc93ee84 | 168 | if (con->appName == NULL) return 0; |
62402cb1 MP |
169 | |
170 | rc = poptReadConfigFile(con, "/etc/popt"); | |
171 | if (rc) return rc; | |
62402cb1 MP |
172 | |
173 | if ((home = getenv("HOME"))) { | |
bc93ee84 WD |
174 | size_t bufsize = strlen(home) + 20; |
175 | fn = alloca(bufsize); | |
176 | if (fn == NULL) return 0; | |
177 | snprintf(fn, bufsize, "%s/.popt", home); | |
62402cb1 MP |
178 | rc = poptReadConfigFile(con, fn); |
179 | if (rc) return rc; | |
180 | } | |
181 | ||
182 | return 0; | |
183 | } |