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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20