Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-projects commit in portage-utils: main.c
Date: Sat, 04 Dec 2010 12:20:54
Message-Id: 20101204122043.4CFD520054@flycatcher.gentoo.org
1 vapier 10/12/04 12:20:43
2
3 Modified: main.c
4 Log:
5 refactor portage env parsing code so we support "source" keyword in files and we handle multiple stacked parents
6
7 Revision Changes Path
8 1.176 portage-utils/main.c
9
10 file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?rev=1.176&view=markup
11 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?rev=1.176&content-type=text/plain
12 diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?r1=1.175&r2=1.176
13
14 Index: main.c
15 ===================================================================
16 RCS file: /var/cvsroot/gentoo-projects/portage-utils/main.c,v
17 retrieving revision 1.175
18 retrieving revision 1.176
19 diff -u -r1.175 -r1.176
20 --- main.c 4 Dec 2010 11:15:56 -0000 1.175
21 +++ main.c 4 Dec 2010 12:20:43 -0000 1.176
22 @@ -1,7 +1,7 @@
23 /*
24 * Copyright 2005-2008 Gentoo Foundation
25 * Distributed under the terms of the GNU General Public License v2
26 - * $Header: /var/cvsroot/gentoo-projects/portage-utils/main.c,v 1.175 2010/12/04 11:15:56 vapier Exp $
27 + * $Header: /var/cvsroot/gentoo-projects/portage-utils/main.c,v 1.176 2010/12/04 12:20:43 vapier Exp $
28 *
29 * Copyright 2005-2008 Ned Ludd - <solar@g.o>
30 * Copyright 2005-2008 Mike Frysinger - <vapier@g.o>
31 @@ -425,8 +425,7 @@
32 return &e;
33 }
34
35 -char *strincr_var(const char *, char *, char *, const size_t);
36 -char *strincr_var(const char *name, char *s, char *value, const size_t value_len)
37 +static char *strincr_var(const char *name, const char *s, char *value, const size_t value_len)
38 {
39 char buf[BUFSIZ];
40 char *p;
41 @@ -464,34 +463,122 @@
42 remove_extra_space(value);
43 /* we should sort here */
44
45 - return (char *) value;
46 + return value;
47 }
48
49 -void initialize_portage_env(void)
50 +typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types;
51 +typedef struct {
52 + const char *name;
53 + const size_t name_len;
54 + const var_types type;
55 + char *value;
56 + const size_t value_len;
57 +} env_vars;
58 +
59 +static void set_portage_env_var(const env_vars var, const char *value)
60 {
61 - char nocolor = 0;
62 - int i, f;
63 - ssize_t profilelen;
64 - struct stat st;
65 + switch (var.type) {
66 + case _Q_BOOL: *var.value = 1; break;
67 + case _Q_STR: strncpy(var.value, value, var.value_len); break;
68 + case _Q_ISTR: strincr_var(var.name, value, var.value, var.value_len); break;
69 + }
70 +}
71 +
72 +/* Helper to read a portage env file (e.g. make.conf) */
73 +static void read_portage_env_file(const char *file, const env_vars vars[])
74 +{
75 + size_t i;
76 FILE *fp;
77 char buf[BUFSIZE], *s, *p;
78 - char *e = (char *) EPREFIX;
79
80 - char profile[_Q_PATH_MAX], portage_file[_Q_PATH_MAX];
81 - const char *files[] = {
82 - portage_file,
83 + IF_DEBUG(fprintf(stderr, "profile %s\n", file));
84 +
85 + fp = fopen(file, "r");
86 + if (fp == NULL)
87 + return;
88 +
89 + while (fgets(buf, sizeof(buf), fp) != NULL) {
90 + rmspace(buf);
91 + if (*buf == '#' || *buf == '\0')
92 + continue;
93 +
94 + /* Handle "source" keyword */
95 + if (!strncmp(buf, "source ", 7))
96 + read_portage_env_file(buf + 7, vars);
97 +
98 + /* look for our desired variables and grab their value */
99 + for (i = 0; vars[i].name; ++i) {
100 + if (buf[vars[i].name_len] != '=' && buf[vars[i].name_len] != ' ')
101 + continue;
102 + if (strncmp(buf, vars[i].name, vars[i].name_len))
103 + continue;
104 +
105 + /* make sure we handle spaces between the varname, the =, and the value:
106 + * VAR=val VAR = val VAR="val"
107 + */
108 + s = buf + vars[i].name_len;
109 + if ((p = strchr(s, '=')) != NULL)
110 + s = p + 1;
111 + while (isspace(*s))
112 + ++s;
113 + if (*s == '"' || *s == '\'') {
114 + ++s;
115 + s[strlen(s)-1] = '\0';
116 + }
117 +
118 + set_portage_env_var(vars[i], s);
119 + }
120 + }
121 +
122 + fclose(fp);
123 +}
124 +
125 +/* Helper to recursively read stacked make.defaults in profiles */
126 +static void read_portage_profile(const char *profile, const env_vars vars[])
127 +{
128 + size_t profile_len, sub_len;
129 + char profile_file[_Q_PATH_MAX], *sub_file;
130 + char buf[BUFSIZE], *s;
131 +
132 + /* initialize the base profile path */
133 + profile_len = strlen(profile);
134 + if (profile_len > sizeof(profile_file) - 20)
135 + return;
136 + strncpy(profile_file, profile, sizeof(profile_file));
137 + profile_file[profile_len] = '/';
138 + sub_file = profile_file + profile_len + 1;
139 + sub_len = sizeof(profile_file) - profile_len - 1;
140 +
141 + /* first consume the profile's make.defaults */
142 + strncpy(sub_file, "make.defaults", sub_len);
143 + read_portage_env_file(profile_file, vars);
144 +
145 + /* now walk all the parents */
146 + strncpy(sub_file, "parent", sub_len);
147 + if (eat_file(profile_file, buf, sizeof(buf)) == 0)
148 + return;
149 + rmspace(buf);
150 +
151 + s = strtok(buf, "\n");
152 + while (s) {
153 + strncpy(sub_file, s, sub_len);
154 + read_portage_profile(profile_file, vars);
155 + s = strtok(NULL, "\n");
156 + }
157 +}
158 +
159 +void initialize_portage_env(void)
160 +{
161 + size_t i;
162 + char *s;
163 +
164 + static const char * const files[] = {
165 EPREFIX "/etc/make.globals",
166 EPREFIX "/etc/make.conf",
167 EPREFIX "/etc/portage/make.conf",
168 };
169 - typedef enum { _Q_BOOL, _Q_STR, _Q_ISTR } var_types;
170 - struct {
171 - const char *name;
172 - const size_t name_len;
173 - const var_types type;
174 - char *value;
175 - const size_t value_len;
176 - } vars_to_read[] = {
177 + char nocolor = 0;
178 + const env_vars vars_to_read[] = {
179 {"ACCEPT_LICENSE", 14, _Q_STR, accept_license, sizeof(accept_license)},
180 {"INSTALL_MASK", 12, _Q_ISTR, install_mask, sizeof(install_mask)},
181 {"ARCH", 4, _Q_STR, portarch, sizeof(portarch)},
182 @@ -502,102 +589,36 @@
183 {"PORTAGE_BINHOST", 15, _Q_STR, binhost, sizeof(binhost)},
184 {"PORTAGE_TMPDIR", 14, _Q_STR, port_tmpdir, sizeof(port_tmpdir)},
185 {"PKGDIR", 6, _Q_STR, pkgdir, sizeof(pkgdir)},
186 - {"ROOT", 4, _Q_STR, portroot, sizeof(portroot)}
187 + {"ROOT", 4, _Q_STR, portroot, sizeof(portroot)},
188 + { },
189 };
190
191 s = getenv("Q_VDB"); /* #257251 */
192 if (s) {
193 strncpy(portvdb, s, sizeof(portvdb));
194 portvdb[sizeof(portvdb) - 1] = '\0';
195 - } else if ((i = strlen(e)) > 1) {
196 + } else if ((i = strlen(EPREFIX)) > 1) {
197 memmove(portvdb + i, portvdb, strlen(portvdb));
198 - memcpy(portvdb, e + 1, i - 1);
199 + memcpy(portvdb, EPREFIX + 1, i - 1);
200 portvdb[i - 1] = '/';
201 }
202
203 - if ((p = strchr(portroot, '/')) != NULL)
204 - if (strlen(p) != 1)
205 + if ((s = strchr(portroot, '/')) != NULL)
206 + if (strlen(s) != 1)
207 strncat(portroot, "/", sizeof(portroot));
208
209 - f = 0;
210 - profilelen = readlink(EPREFIX "/etc/make.profile", profile, sizeof(profile) - 1);
211 - if (profilelen == -1)
212 - strcpy(profile, EPREFIX "/etc/make.profile");
213 - else
214 - profile[profilelen]='\0';
215 -
216 - if (profile[0] != '/') {
217 - memmove(profile+5+strlen(EPREFIX), profile, strlen(profile)+1);
218 - memcpy(profile, EPREFIX "/etc/", strlen(EPREFIX) + 5);
219 - }
220 - do {
221 - if (f == 0)
222 - snprintf(portage_file, sizeof(portage_file), "%s/make.defaults", profile);
223 - IF_DEBUG(fprintf(stderr, "profile %s\n", files[f]));
224 + /* walk all the stacked profiles */
225 + read_portage_profile(EPREFIX "/etc/make.profile", vars_to_read);
226
227 - if ((fp=fopen(files[f], "r")) != NULL) {
228 - while (fgets(buf, sizeof(buf), fp) != NULL) {
229 - rmspace(buf);
230 - if (*buf == '#' || *buf == '\0')
231 - continue;
232 - for (i=0; i < ARR_SIZE(vars_to_read); ++i) {
233 - if (buf[vars_to_read[i].name_len] != '=' && buf[vars_to_read[i].name_len] != ' ')
234 - continue;
235 - if (strncmp(buf, vars_to_read[i].name, vars_to_read[i].name_len))
236 - continue;
237 -
238 - /* make sure we handle spaces between the varname, the =, and the value:
239 - * VAR=val VAR = val VAR="val"
240 - */
241 - s = buf + vars_to_read[i].name_len;
242 - if ((p = strchr(s, '=')) != NULL)
243 - s = p + 1;
244 - while (isspace(*s))
245 - ++s;
246 - if (*s == '"' || *s == '\'') {
247 - ++s;
248 - s[strlen(s)-1] = '\0';
249 - }
250 -
251 - switch (vars_to_read[i].type) {
252 - case _Q_BOOL: *vars_to_read[i].value = 1; break;
253 - case _Q_STR: strncpy(vars_to_read[i].value, s, vars_to_read[i].value_len); break;
254 - case _Q_ISTR: strincr_var(vars_to_read[i].name, s, vars_to_read[i].value, vars_to_read[i].value_len); break;
255 - }
256 - }
257 - }
258 - fclose(fp);
259 - }
260 -
261 - if (f > 0) {
262 - if (++f < ARR_SIZE(files))
263 - continue;
264 - else
265 - break;
266 - }
267 -
268 - /* everything below here is to figure out what the next parent is */
269 - snprintf(portage_file, sizeof(portage_file), "%s/parent", profile);
270 - if (stat(portage_file, &st) == 0) {
271 - eat_file(portage_file, buf, sizeof(buf));
272 - rmspace(buf);
273 - portage_file[strlen(portage_file)-7] = '\0';
274 - snprintf(profile, sizeof(profile), "%s/%s", portage_file, buf);
275 - } else {
276 - f = 1;
277 - }
278 - } while (1);
279 + /* now read all the config files */
280 + for (i = 0; i < ARR_SIZE(files); ++i)
281 + read_portage_env_file(files[i], vars_to_read);
282
283 /* finally, check the env */
284 - for (i=0; i < ARR_SIZE(vars_to_read); ++i) {
285 + for (i = 0; vars_to_read[i].name; ++i) {
286 s = getenv(vars_to_read[i].name);
287 - if (s != NULL) {
288 - switch (vars_to_read[i].type) {
289 - case _Q_BOOL: *vars_to_read[i].value = 1; break;
290 - case _Q_STR: strncpy(vars_to_read[i].value, s, vars_to_read[i].value_len); break;
291 - case _Q_ISTR: strincr_var(vars_to_read[i].name, s, vars_to_read[i].value, vars_to_read[i].value_len); break;
292 - }
293 - }
294 + if (s != NULL)
295 + set_portage_env_var(vars_to_read[i], s);
296 if (getenv("DEBUG") IF_DEBUG(|| 1)) {
297 fprintf(stderr, "%s = ", vars_to_read[i].name);
298 switch (vars_to_read[i].type) {
299 @@ -607,8 +628,8 @@
300 }
301 }
302 }
303 - if ((p = strchr(portroot, '/')) != NULL)
304 - if (strlen(p) != 1)
305 + if ((s = strchr(portroot, '/')) != NULL)
306 + if (strlen(s) != 1)
307 strncat(portroot, "/", sizeof(portroot));
308
309 if (getenv("PORTAGE_QUIET") != NULL)