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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2980 - (show annotations) (download) (as text)
Wed Oct 3 14:43:05 2007 UTC (6 years, 9 months ago) by uberlord
File MIME type: text/x-csrc
File size: 7952 byte(s)
Rename config funcs
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 static const char * const longopts_help[] = {
85 "Fork ldconfig into the background",
86 "Skip execution of ldconfig",
87 longopts_help_COMMON
88 };
89 #include "_usage.c"
90
91 int env_update (int argc, char **argv)
92 {
93 char **files = rc_ls_dir (ENVDIR, 0);
94 char *file;
95 char **envs = NULL;
96 char *env;
97 int i = 0;
98 int j;
99 FILE *fp;
100 bool ld = true;
101 char *ldent;
102 char **ldents = NULL;
103 char **config = NULL;
104 char *entry;
105 char **mycolons = NULL;
106 char **myspaces = NULL;
107 int opt;
108 bool ldconfig = true;
109 bool fork_ldconfig = false;
110 int nents = 0;
111
112 applet = argv[0];
113
114 while ((opt = getopt_long (argc, argv, getoptstring,
115 longopts, (int *) 0)) != -1)
116 {
117 switch (opt) {
118 case 'l':
119 fork_ldconfig = true;
120 break;
121 case 'L':
122 ldconfig = false;
123 break;
124
125 case_RC_COMMON_GETOPT
126 }
127 }
128
129 if (! files)
130 eerrorx ("%s: no files in " ENVDIR " to process", applet);
131
132 STRLIST_FOREACH (files, file, i) {
133 char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL);
134 char **entries = NULL;
135
136 j = strlen (file);
137 if (! rc_is_dir (path) &&
138 j > 2 &&
139 *file >= '0' &&
140 *file <= '9' &&
141 *(file + 1) >= '0' &&
142 *(file + 1) <= '9' &&
143 *(file + j - 1) != '~' &&
144 (j < 4 || strcmp (file + j - 4, ".bak") != 0) &&
145 (j < 5 || strcmp (file + j - 5, ".core") != 0))
146 entries = rc_config_load (path);
147 free (path);
148
149 STRLIST_FOREACH (entries, entry, j) {
150 char *tmpent = rc_xstrdup (entry);
151 char *value = tmpent;
152 char *var = strsep (&value, "=");
153
154 if (strcmp (var, "COLON_SEPARATED") == 0)
155 while ((var = strsep (&value, " ")))
156 rc_strlist_addu (&mycolons, var);
157 else if (strcmp (var, "SPACE_SEPARATED") == 0)
158 while ((var = strsep (&value, " ")))
159 rc_strlist_addu (&myspaces, var);
160 else
161 rc_strlist_add (&config, entry);
162 free (tmpent);
163 }
164
165 rc_strlist_free (entries);
166 }
167
168 STRLIST_FOREACH (config, entry, i) {
169 char *tmpent = rc_xstrdup (entry);
170 char *value = tmpent;
171 char *var = strsep (&value, "=");
172 char *match;
173 bool colon = false;
174 bool space = false;
175 bool replaced = false;
176
177 for (j = 0; colon_separated[j]; j++)
178 if (strcmp (colon_separated[j], var) == 0) {
179 colon = true;
180 break;
181 }
182
183 if (! colon)
184 STRLIST_FOREACH (mycolons, match, j) {
185 if (strcmp (match, var) == 0) {
186 colon = true;
187 break;
188 } }
189
190 if (! colon)
191 for (j = 0; space_separated[j]; j++)
192 if (strcmp (space_separated[j], var) == 0) {
193 space = true;
194 break;
195 }
196
197 if (! colon && ! space)
198 STRLIST_FOREACH (myspaces, match, j)
199 if (strcmp (match, var) == 0) {
200 space = true;
201 break;
202 }
203
204 /* Skip blank vars */
205 if ((colon || space) &&
206 (! value || strlen (value)) == 0)
207 {
208 free (tmpent);
209 continue;
210 }
211
212 STRLIST_FOREACH (envs, env, j) {
213 char *tmpenv = rc_xstrdup (env);
214 char *tmpvalue = tmpenv;
215 char *tmpentry = strsep (&tmpvalue, "=");
216
217 if (strcmp (tmpentry, var) == 0) {
218 if (colon || space) {
219 int len = strlen (envs[j - 1]) + strlen (entry) + 1;
220 envs[j - 1] = rc_xrealloc (envs[j - 1], len);
221 snprintf (envs[j - 1] + strlen (envs[j - 1]), len,
222 "%s%s", colon ? ":" : " ", value);
223 } else {
224 free (envs[j - 1]);
225 envs[j - 1] = rc_xstrdup (entry);
226 }
227 replaced = true;
228 }
229 free (tmpenv);
230
231 if (replaced)
232 break;
233 }
234
235 if (! replaced)
236 rc_strlist_addsort (&envs, entry);
237
238 free (tmpent);
239 }
240 rc_strlist_free (mycolons);
241 rc_strlist_free (myspaces);
242 rc_strlist_free (config);
243 rc_strlist_free (files);
244
245 if ((fp = fopen (PROFILE_ENV, "w")) == NULL)
246 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
247 fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV);
248
249 STRLIST_FOREACH (envs, env, i) {
250 char *tmpent = rc_xstrdup (env);
251 char *value = tmpent;
252 char *var = strsep (&value, "=");
253 if (strcmp (var, "LDPATH") != 0) {
254 if (*value == '$')
255 fprintf (fp, "export %s=%s\n", var, value);
256 else
257 fprintf (fp, "export %s='%s'\n", var, value);
258 }
259 free (tmpent);
260 }
261 fclose (fp);
262
263 if ((fp = fopen (CSH_ENV, "w")) == NULL)
264 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
265 fprintf (fp, NOTICE, "/etc/csh.cshrc", PROFILE_ENV);
266
267 STRLIST_FOREACH (envs, env, i) {
268 char *tmpent = rc_xstrdup (env);
269 char *value = tmpent;
270 char *var = strsep (&value, "=");
271 if (strcmp (var, "LDPATH") != 0) {
272 if (*value == '$')
273 fprintf (fp, "setenv %s %s\n", var, value);
274 else
275 fprintf (fp, "setenv %s '%s'\n", var, value);
276 }
277 free (tmpent);
278 }
279 fclose (fp);
280
281 ldent = rc_config_value (envs, "LDPATH");
282
283 if (! ldent ||
284 (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0))
285 {
286 rc_strlist_free (envs);
287 return (EXIT_SUCCESS);
288 }
289
290 while ((file = strsep (&ldent, ":"))) {
291 if (strlen (file) == 0)
292 continue;
293
294 if (rc_strlist_addu (&ldents, file))
295 nents++;
296 }
297
298 if (ldconfig) {
299 /* Update ld.so.conf only if different */
300 if (rc_exists (LDSOCONF)) {
301 char **lines = rc_config_list (LDSOCONF);
302 char *line;
303 ld = false;
304
305 STRLIST_FOREACH (lines, line, i)
306 if (i > nents || strcmp (line, ldents[i - 1]) != 0)
307 {
308 ld = true;
309 break;
310 }
311 rc_strlist_free (lines);
312 if (i - 1 != nents)
313 ld = true;
314 }
315
316 if (ld) {
317 int retval = 0;
318 pid_t pid = 0;
319
320 if ((fp = fopen (LDSOCONF, "w")) == NULL)
321 eerrorx ("%s: fopen `%s': %s", applet, LDSOCONF,
322 strerror (errno));
323 fprintf (fp, LDNOTICE);
324 STRLIST_FOREACH (ldents, ldent, i)
325 fprintf (fp, "%s\n", ldent);
326 fclose (fp);
327
328 ebegin (LD_MESSAGE);
329 if (fork_ldconfig) {
330 if ((pid = fork ()) == -1)
331 eerror ("%s: failed to fork: %s", applet,
332 strerror (errno));
333 else if (pid == 0) {
334 /* Become a proper daemon for a little bit */
335 int fd = open ("/dev/null", O_RDWR);
336 setsid ();
337 dup2 (fd, fileno (stdin));
338 dup2 (fd, fileno (stdout));
339 dup2 (fd, fileno (stderr));
340 }
341 }
342
343 if (pid == 0)
344 retval = system (LD_SYSTEM);
345 eend (retval, NULL);
346 }
347 }
348
349 rc_strlist_free (ldents);
350 rc_strlist_free (envs);
351 return(EXIT_SUCCESS);
352 }

  ViewVC Help
Powered by ViewVC 1.1.20