Commit | Line | Data |
---|---|---|
cc248aae WD |
1 | /** \ingroup popt |
2 | * \file popt/poptconfig.c | |
3 | */ | |
4 | ||
5 | /* (C) 1998-2000 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 MP |
10 | #include "poptint.h" |
11 | ||
cc248aae | 12 | /*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ |
37101856 | 13 | static void configLine(poptContext con, unsigned char * line) |
cc248aae WD |
14 | /*@modifies con @*/ |
15 | { | |
16 | /*@-type@*/ | |
62402cb1 | 17 | int nameLength = strlen(con->appName); |
cc248aae WD |
18 | /*@=type@*/ |
19 | const char * entryType; | |
20 | const char * opt; | |
b17f1d76 | 21 | poptItem item = (poptItem) alloca(sizeof(*item)); |
cc248aae | 22 | int i, j; |
62402cb1 | 23 | |
cc248aae WD |
24 | memset(item, 0, sizeof(*item)); |
25 | ||
26 | /*@-type@*/ | |
62402cb1 | 27 | if (strncmp(line, con->appName, nameLength)) return; |
cc248aae WD |
28 | /*@=type@*/ |
29 | ||
62402cb1 | 30 | line += nameLength; |
cc248aae | 31 | if (*line == '\0' || !isspace(*line)) return; |
62402cb1 | 32 | |
cc248aae WD |
33 | while (*line != '\0' && isspace(*line)) line++; |
34 | entryType = line; | |
35 | while (*line == '\0' || !isspace(*line)) line++; | |
62402cb1 | 36 | *line++ = '\0'; |
62402cb1 | 37 | |
cc248aae WD |
38 | while (*line != '\0' && isspace(*line)) line++; |
39 | if (*line == '\0') return; | |
40 | opt = line; | |
41 | while (*line == '\0' || !isspace(*line)) line++; | |
62402cb1 | 42 | *line++ = '\0'; |
62402cb1 | 43 | |
cc248aae WD |
44 | while (*line != '\0' && isspace(*line)) line++; |
45 | if (*line == '\0') return; | |
46 | ||
47 | /*@-temptrans@*/ /* FIX: line alias is saved */ | |
62402cb1 | 48 | if (opt[0] == '-' && opt[1] == '-') |
cc248aae WD |
49 | item->option.longName = opt + 2; |
50 | else if (opt[0] == '-' && opt[2] == '\0') | |
51 | item->option.shortName = opt[1]; | |
52 | /*@=temptrans@*/ | |
53 | ||
54 | if (poptParseArgvString(line, &item->argc, &item->argv)) return; | |
55 | ||
56 | /*@-modobserver@*/ | |
57 | item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; | |
58 | for (i = 0, j = 0; i < item->argc; i++, j++) { | |
59 | const char * f; | |
60 | if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { | |
61 | f = item->argv[i] + sizeof("--POPTdesc="); | |
62 | if (f[0] == '$' && f[1] == '"') f++; | |
63 | item->option.descrip = f; | |
64 | item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; | |
65 | j--; | |
66 | } else | |
67 | if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { | |
68 | f = item->argv[i] + sizeof("--POPTargs="); | |
69 | if (f[0] == '$' && f[1] == '"') f++; | |
70 | item->option.argDescrip = f; | |
71 | item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; | |
72 | item->option.argInfo |= POPT_ARG_STRING; | |
73 | j--; | |
74 | } else | |
75 | if (j != i) | |
76 | item->argv[j] = item->argv[i]; | |
77 | } | |
78 | if (j != i) { | |
79 | item->argv[j] = NULL; | |
80 | item->argc = j; | |
62402cb1 | 81 | } |
cc248aae WD |
82 | /*@=modobserver@*/ |
83 | ||
84 | /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ | |
85 | if (!strcmp(entryType, "alias")) | |
86 | (void) poptAddItem(con, item, 0); | |
87 | else if (!strcmp(entryType, "exec")) | |
88 | (void) poptAddItem(con, item, 1); | |
89 | /*@=nullstate@*/ | |
62402cb1 | 90 | } |
cc248aae | 91 | /*@=compmempass@*/ |
62402cb1 | 92 | |
cc248aae WD |
93 | int poptReadConfigFile(poptContext con, const char * fn) |
94 | { | |
ff3184ca WD |
95 | const unsigned char * file, * chptr, * end; |
96 | unsigned char * buf; | |
97 | /*@dependent@*/ unsigned char * dst; | |
62402cb1 | 98 | int fd, rc; |
cc248aae | 99 | off_t fileLength; |
62402cb1 MP |
100 | |
101 | fd = open(fn, O_RDONLY); | |
cc248aae WD |
102 | if (fd < 0) |
103 | return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); | |
62402cb1 MP |
104 | |
105 | fileLength = lseek(fd, 0, SEEK_END); | |
cc248aae WD |
106 | if (fileLength == -1 || lseek(fd, 0, 0) == -1) { |
107 | rc = errno; | |
108 | (void) close(fd); | |
109 | /*@-mods@*/ | |
110 | errno = rc; | |
111 | /*@=mods@*/ | |
112 | return POPT_ERROR_ERRNO; | |
113 | } | |
62402cb1 | 114 | |
cc248aae WD |
115 | file = alloca(fileLength + 1); |
116 | if (read(fd, (char *)file, fileLength) != fileLength) { | |
62402cb1 | 117 | rc = errno; |
cc248aae WD |
118 | (void) close(fd); |
119 | /*@-mods@*/ | |
62402cb1 | 120 | errno = rc; |
cc248aae | 121 | /*@=mods@*/ |
62402cb1 MP |
122 | return POPT_ERROR_ERRNO; |
123 | } | |
cc248aae WD |
124 | if (close(fd) == -1) |
125 | return POPT_ERROR_ERRNO; | |
62402cb1 | 126 | |
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; | |
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@*/ |
6afe7f23 | 158 | |
62402cb1 MP |
159 | return 0; |
160 | } | |
161 | ||
37101856 WD |
162 | int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) |
163 | { | |
62402cb1 MP |
164 | char * fn, * home; |
165 | int rc; | |
166 | ||
cc248aae | 167 | /*@-type@*/ |
62402cb1 | 168 | if (!con->appName) return 0; |
cc248aae | 169 | /*@=type@*/ |
62402cb1 MP |
170 | |
171 | rc = poptReadConfigFile(con, "/etc/popt"); | |
172 | if (rc) return rc; | |
173 | if (getuid() != geteuid()) return 0; | |
174 | ||
175 | if ((home = getenv("HOME"))) { | |
cc248aae | 176 | fn = alloca(strlen(home) + 20); |
62402cb1 MP |
177 | strcpy(fn, home); |
178 | strcat(fn, "/.popt"); | |
179 | rc = poptReadConfigFile(con, fn); | |
180 | if (rc) return rc; | |
181 | } | |
182 | ||
183 | return 0; | |
184 | } |