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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations) (download) (as text)
Thu Jun 28 15:44:14 2007 UTC (7 years, 10 months ago) by uberlord
File MIME type: text/x-csrc
File size: 6762 byte(s)
Add --nocolor to more programs
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 { "no-ldconfig", 0, NULL, 'L'},
68 longopts_COMMON
69 { NULL, 0, NULL, 0}
70 };
71 #include "_usage.c"
72
73 int main (int argc, char **argv)
74 {
75 char **files = rc_ls_dir (NULL, ENVDIR, 0);
76 char *file;
77 char **envs = NULL;
78 char *env;
79 int i = 0;
80 int j;
81 FILE *fp;
82 bool ld = true;
83 char *ldent;
84 char **ldents = NULL;
85 int nents = 0;
86 char **config = NULL;
87 char *entry;
88 char **mycolons = NULL;
89 char **myspaces = NULL;
90 int opt;
91 bool ldconfig = true;
92
93 applet = argv[0];
94
95 while ((opt = getopt_long (argc, argv, getoptstring,
96 longopts, (int *) 0)) != -1)
97 {
98 switch (opt) {
99 case 'L':
100 ldconfig = false;
101 break;
102
103 case_RC_COMMON_GETOPT
104 }
105 }
106
107 if (! files)
108 eerrorx ("%s: no files in " ENVDIR " to process", applet);
109
110 STRLIST_FOREACH (files, file, i) {
111 char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL);
112 char **entries = NULL;
113
114 if (! rc_is_dir (path))
115 entries = rc_get_config (NULL, path);
116 free (path);
117
118 STRLIST_FOREACH (entries, entry, j) {
119 char *tmpent = rc_xstrdup (entry);
120 char *value = tmpent;
121 char *var = strsep (&value, "=");
122
123 if (strcmp (var, "COLON_SEPARATED") == 0)
124 while ((var = strsep (&value, " ")))
125 mycolons = rc_strlist_addu (mycolons, var);
126 else if (strcmp (var, "SPACE_SEPARATED") == 0)
127 while ((var = strsep (&value, " ")))
128 myspaces = rc_strlist_addu (myspaces, var);
129 else
130 config = rc_strlist_add (config, entry);
131 free (tmpent);
132 }
133
134 rc_strlist_free (entries);
135 }
136
137 STRLIST_FOREACH (config, entry, i) {
138 char *tmpent = rc_xstrdup (entry);
139 char *value = tmpent;
140 char *var = strsep (&value, "=");
141 char *match;
142 bool colon = false;
143 bool space = false;
144 bool replaced = false;
145
146 for (j = 0; colon_separated[j]; j++)
147 if (strcmp (colon_separated[j], var) == 0) {
148 colon = true;
149 break;
150 }
151
152 if (! colon)
153 STRLIST_FOREACH (mycolons, match, j) {
154 if (strcmp (match, var) == 0) {
155 colon = true;
156 break;
157 } }
158
159 if (! colon)
160 for (j = 0; space_separated[j]; j++)
161 if (strcmp (space_separated[j], var) == 0) {
162 space = true;
163 break;
164 }
165
166 if (! colon && ! space)
167 STRLIST_FOREACH (myspaces, match, j)
168 if (strcmp (match, var) == 0) {
169 space = true;
170 break;
171 }
172
173 /* Skip blank vars */
174 if ((colon || space) &&
175 (! value || strlen (value)) == 0)
176 {
177 free (tmpent);
178 continue;
179 }
180
181 STRLIST_FOREACH (envs, env, j) {
182 char *tmpenv = rc_xstrdup (env);
183 char *tmpvalue = tmpenv;
184 char *tmpentry = strsep (&tmpvalue, "=");
185
186 if (strcmp (tmpentry, var) == 0) {
187 if (colon || space) {
188 int len = strlen (envs[j - 1]) + strlen (entry) + 1;
189 envs[j - 1] = rc_xrealloc (envs[j - 1], len);
190 snprintf (envs[j - 1] + strlen (envs[j - 1]), len,
191 "%s%s", colon ? ":" : " ", value);
192 } else {
193 free (envs[j - 1]);
194 envs[j - 1] = rc_xstrdup (entry);
195 }
196 replaced = true;
197 }
198 free (tmpenv);
199
200 if (replaced)
201 break;
202 }
203
204 if (! replaced)
205 envs = rc_strlist_addsort (envs, entry);
206
207 free (tmpent);
208 }
209 rc_strlist_free (mycolons);
210 rc_strlist_free (myspaces);
211 rc_strlist_free (config);
212 rc_strlist_free (files);
213
214 if ((fp = fopen (PROFILE_ENV, "w")) == NULL)
215 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
216 fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV);
217
218 STRLIST_FOREACH (envs, env, i) {
219 char *tmpent = rc_xstrdup (env);
220 char *value = tmpent;
221 char *var = strsep (&value, "=");
222 if (strcmp (var, "LDPATH") != 0)
223 fprintf (fp, "export %s='%s'\n", var, value);
224 free (tmpent);
225 }
226 fclose (fp);
227
228 if ((fp = fopen (CSH_ENV, "w")) == NULL)
229 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
230 fprintf (fp, NOTICE, "/etc/csh.cshrc", PROFILE_ENV);
231
232 STRLIST_FOREACH (envs, env, i) {
233 char *tmpent = rc_xstrdup (env);
234 char *value = tmpent;
235 char *var = strsep (&value, "=");
236 if (strcmp (var, "LDPATH") != 0)
237 fprintf (fp, "setenv %s '%s'\n", var, value);
238 free (tmpent);
239 }
240 fclose (fp);
241
242 ldent = rc_get_config_entry (envs, "LDPATH");
243
244 if (! ldent ||
245 (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0))
246 {
247 rc_strlist_free (envs);
248 return (EXIT_SUCCESS);
249 }
250
251 while ((file = strsep (&ldent, ":"))) {
252 if (strlen (file) == 0)
253 continue;
254
255 ldents = rc_strlist_add (ldents, file);
256 nents++;
257 }
258
259 if (ldconfig) {
260 /* Update ld.so.conf only if different */
261 if (rc_exists (LDSOCONF)) {
262 char **lines = rc_get_list (NULL, LDSOCONF);
263 char *line;
264 ld = false;
265 STRLIST_FOREACH (lines, line, i)
266 if (i > nents || strcmp (line, ldents[i - 1]) != 0)
267 {
268 ld = true;
269 break;
270 }
271 rc_strlist_free (lines);
272 if (i - 1 != nents)
273 ld = true;
274 }
275
276 if (ld) {
277 int retval = 0;
278
279 if ((fp = fopen (LDSOCONF, "w")) == NULL)
280 eerrorx ("%s: fopen `%s': %s", applet, LDSOCONF,
281 strerror (errno));
282 fprintf (fp, LDNOTICE);
283 STRLIST_FOREACH (ldents, ldent, i)
284 fprintf (fp, "%s\n", ldent);
285 fclose (fp);
286
287 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
288 ebegin ("Regenerating /var/run/ld-elf.so.hints");
289 retval = system ("/sbin/ldconfig -elf -i '" LDSOCONF "'");
290 #else
291 ebegin ("Regenerating /etc/ld.so.cache");
292 retval = system ("/sbin/ldconfig");
293 #endif
294 eend (retval, NULL);
295 }
296 }
297
298 rc_strlist_free (ldents);
299 rc_strlist_free (envs);
300 return(EXIT_SUCCESS);
301 }

  ViewVC Help
Powered by ViewVC 1.1.20