/[baselayout]/trunk/src/env-update.c
Gentoo

Contents of /trunk/src/env-update.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2755 - (show annotations) (download) (as text)
Mon Jul 9 10:26:02 2007 UTC (7 years, 3 months ago) by uberlord
File MIME type: text/x-csrc
File size: 7231 byte(s)
Add an option to fork ldconfig in env-update, #182794. Also, preserve the entire line in /etc/env.d/foo if it begins with $
1 /*
2 env-update
3 Create /etc/profile.env (sh), /etc/csh.env from /etc/env.d
4 Run ldconfig as required
5
6 Copyright 2007 Gentoo Foundation
7 Released under the GPLv2
8
9 */
10
11 #define APPLET "env-update"
12
13 #include <errno.h>
14 #include <getopt.h>
15 #include <limits.h>
16 #include <stdbool.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "einfo.h"
23 #include "rc.h"
24 #include "rc-misc.h"
25 #include "strlist.h"
26
27 #define ENVDIR "/etc/env.d"
28 #define PROFILE_ENV "/etc/profile.env"
29 #define CSH_ENV "/etc/csh.env"
30 #define LDSOCONF "/etc/ld.so.conf"
31
32 #define NOTICE "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n" \
33 "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n" \
34 "# GO INTO %s NOT %s\n\n"
35
36 #define LDNOTICE "# ld.so.conf autogenerated by env-update; make all\n" \
37 "# changes to contents of /etc/env.d directory\n"
38
39 static const char *colon_separated[] = {
40 "ADA_INCLUDE_PATH",
41 "ADA_OBJECTS_PATH",
42 "CLASSPATH",
43 "INFOPATH",
44 "KDEDIRS",
45 "LDPATH",
46 "MANPATH",
47 "PATH",
48 "PKG_CONFIG_PATH",
49 "PRELINK_PATH",
50 "PRELINK_PATH_MASK",
51 "PYTHONPATH",
52 "ROOTPATH",
53 NULL
54 };
55
56 static const char *space_separated[] = {
57 "CONFIG_PROTECT",
58 "CONFIG_PROTECT_MASK",
59 NULL,
60 };
61
62 static char *applet = NULL;
63
64 #include "_usage.h"
65 #define getoptstring "L" getoptstring_COMMON
66 static struct option longopts[] = {
67 { "fork-ldconfig", 0, NULL, 'l'},
68 { "no-ldconfig", 0, NULL, 'L'},
69 longopts_COMMON
70 { NULL, 0, NULL, 0}
71 };
72 #include "_usage.c"
73
74 int main (int argc, char **argv)
75 {
76 char **files = rc_ls_dir (NULL, ENVDIR, 0);
77 char *file;
78 char **envs = NULL;
79 char *env;
80 int i = 0;
81 int j;
82 FILE *fp;
83 bool ld = true;
84 char *ldent;
85 char **ldents = NULL;
86 int nents = 0;
87 char **config = NULL;
88 char *entry;
89 char **mycolons = NULL;
90 char **myspaces = NULL;
91 int opt;
92 bool ldconfig = true;
93 bool fork_ldconfig = false;
94
95 applet = argv[0];
96
97 while ((opt = getopt_long (argc, argv, getoptstring,
98 longopts, (int *) 0)) != -1)
99 {
100 switch (opt) {
101 case 'l':
102 fork_ldconfig = true;
103 break;
104 case 'L':
105 ldconfig = false;
106 break;
107
108 case_RC_COMMON_GETOPT
109 }
110 }
111
112 if (! files)
113 eerrorx ("%s: no files in " ENVDIR " to process", applet);
114
115 STRLIST_FOREACH (files, file, i) {
116 char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL);
117 char **entries = NULL;
118
119 if (! rc_is_dir (path))
120 entries = rc_get_config (NULL, path);
121 free (path);
122
123 STRLIST_FOREACH (entries, entry, j) {
124 char *tmpent = rc_xstrdup (entry);
125 char *value = tmpent;
126 char *var = strsep (&value, "=");
127
128 if (strcmp (var, "COLON_SEPARATED") == 0)
129 while ((var = strsep (&value, " ")))
130 mycolons = rc_strlist_addu (mycolons, var);
131 else if (strcmp (var, "SPACE_SEPARATED") == 0)
132 while ((var = strsep (&value, " ")))
133 myspaces = rc_strlist_addu (myspaces, var);
134 else
135 config = rc_strlist_add (config, entry);
136 free (tmpent);
137 }
138
139 rc_strlist_free (entries);
140 }
141
142 STRLIST_FOREACH (config, entry, i) {
143 char *tmpent = rc_xstrdup (entry);
144 char *value = tmpent;
145 char *var = strsep (&value, "=");
146 char *match;
147 bool colon = false;
148 bool space = false;
149 bool replaced = false;
150
151 for (j = 0; colon_separated[j]; j++)
152 if (strcmp (colon_separated[j], var) == 0) {
153 colon = true;
154 break;
155 }
156
157 if (! colon)
158 STRLIST_FOREACH (mycolons, match, j) {
159 if (strcmp (match, var) == 0) {
160 colon = true;
161 break;
162 } }
163
164 if (! colon)
165 for (j = 0; space_separated[j]; j++)
166 if (strcmp (space_separated[j], var) == 0) {
167 space = true;
168 break;
169 }
170
171 if (! colon && ! space)
172 STRLIST_FOREACH (myspaces, match, j)
173 if (strcmp (match, var) == 0) {
174 space = true;
175 break;
176 }
177
178 /* Skip blank vars */
179 if ((colon || space) &&
180 (! value || strlen (value)) == 0)
181 {
182 free (tmpent);
183 continue;
184 }
185
186 STRLIST_FOREACH (envs, env, j) {
187 char *tmpenv = rc_xstrdup (env);
188 char *tmpvalue = tmpenv;
189 char *tmpentry = strsep (&tmpvalue, "=");
190
191 if (strcmp (tmpentry, var) == 0) {
192 if (colon || space) {
193 int len = strlen (envs[j - 1]) + strlen (entry) + 1;
194 envs[j - 1] = rc_xrealloc (envs[j - 1], len);
195 snprintf (envs[j - 1] + strlen (envs[j - 1]), len,
196 "%s%s", colon ? ":" : " ", value);
197 } else {
198 free (envs[j - 1]);
199 envs[j - 1] = rc_xstrdup (entry);
200 }
201 replaced = true;
202 }
203 free (tmpenv);
204
205 if (replaced)
206 break;
207 }
208
209 if (! replaced)
210 envs = rc_strlist_addsort (envs, entry);
211
212 free (tmpent);
213 }
214 rc_strlist_free (mycolons);
215 rc_strlist_free (myspaces);
216 rc_strlist_free (config);
217 rc_strlist_free (files);
218
219 if ((fp = fopen (PROFILE_ENV, "w")) == NULL)
220 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
221 fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV);
222
223 STRLIST_FOREACH (envs, env, i) {
224 char *tmpent = rc_xstrdup (env);
225 char *value = tmpent;
226 char *var = strsep (&value, "=");
227 if (strcmp (var, "LDPATH") != 0) {
228 if (*value == '$')
229 fprintf (fp, "export %s=%s\n", var, value);
230 else
231 fprintf (fp, "export %s='%s'\n", var, value);
232 }
233 free (tmpent);
234 }
235 fclose (fp);
236
237 if ((fp = fopen (CSH_ENV, "w")) == NULL)
238 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
239 fprintf (fp, NOTICE, "/etc/csh.cshrc", PROFILE_ENV);
240
241 STRLIST_FOREACH (envs, env, i) {
242 char *tmpent = rc_xstrdup (env);
243 char *value = tmpent;
244 char *var = strsep (&value, "=");
245 if (strcmp (var, "LDPATH") != 0) {
246 if (*value == '$')
247 fprintf (fp, "setenv %s %s\n", var, value);
248 else
249 fprintf (fp, "setenv %s '%s'\n", var, value);
250 }
251 free (tmpent);
252 }
253 fclose (fp);
254
255 ldent = rc_get_config_entry (envs, "LDPATH");
256
257 if (! ldent ||
258 (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0))
259 {
260 rc_strlist_free (envs);
261 return (EXIT_SUCCESS);
262 }
263
264 while ((file = strsep (&ldent, ":"))) {
265 if (strlen (file) == 0)
266 continue;
267
268 ldents = rc_strlist_add (ldents, file);
269 nents++;
270 }
271
272 if (ldconfig) {
273 /* Update ld.so.conf only if different */
274 if (rc_exists (LDSOCONF)) {
275 char **lines = rc_get_list (NULL, LDSOCONF);
276 char *line;
277 ld = false;
278 STRLIST_FOREACH (lines, line, i)
279 if (i > nents || strcmp (line, ldents[i - 1]) != 0)
280 {
281 ld = true;
282 break;
283 }
284 rc_strlist_free (lines);
285 if (i - 1 != nents)
286 ld = true;
287 }
288
289 if (ld) {
290 int retval = 0;
291 pid_t pid = getpid ();
292
293 if ((fp = fopen (LDSOCONF, "w")) == NULL)
294 eerrorx ("%s: fopen `%s': %s", applet, LDSOCONF,
295 strerror (errno));
296 fprintf (fp, LDNOTICE);
297 STRLIST_FOREACH (ldents, ldent, i)
298 fprintf (fp, "%s\n", ldent);
299 fclose (fp);
300
301 if (fork_ldconfig) {
302 if ((pid = fork ()) == -1)
303 eerror ("%s: failed to fork: %s", applet,
304 strerror (errno));
305 }
306
307 if (pid) {
308 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
309 ebegin ("Regenerating /var/run/ld-elf.so.hints");
310 retval = system ("/sbin/ldconfig -elf -i '" LDSOCONF "'");
311 #else
312 ebegin ("Regenerating /etc/ld.so.cache");
313 retval = system ("/sbin/ldconfig");
314 #endif
315 eend (retval, NULL);
316 }
317 }
318 }
319
320 rc_strlist_free (ldents);
321 rc_strlist_free (envs);
322 return(EXIT_SUCCESS);
323 }

  ViewVC Help
Powered by ViewVC 1.1.20