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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2665 - (show annotations) (download) (as text)
Fri Apr 27 11:24:05 2007 UTC (7 years, 8 months ago) by uberlord
File MIME type: text/x-csrc
File size: 6219 byte(s)
env-update now respects COLON_SEPARATED and SPACE_SEPARATED env.d values, #176198.
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 #include <errno.h>
12 #include <limits.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include "einfo.h"
20 #include "rc.h"
21 #include "rc-misc.h"
22 #include "strlist.h"
23
24 #define ENVDIR "/etc/env.d"
25 #define PROFILE_ENV "/etc/profile.env"
26 #define CSH_ENV "/etc/csh.env"
27 #define LDSOCONF "/etc/ld.so.conf"
28
29 #define NOTICE "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n" \
30 "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n" \
31 "# GO INTO %s NOT %s\n\n"
32
33 #define LDNOTICE "# ld.so.conf autogenerated by env-update; make all\n" \
34 "# changes to contents of /etc/env.d directory\n"
35
36 static const char *colon_separated[] = {
37 "ADA_INCLUDE_PATH",
38 "ADA_OBJECTS_PATH",
39 "CLASSPATH",
40 "INFOPATH",
41 "KDEDIRS",
42 "LDPATH",
43 "MANPATH",
44 "PATH",
45 "PKG_CONFIG_PATH",
46 "PRELINK_PATH",
47 "PRELINK_PATH_MASK",
48 "PYTHONPATH",
49 "ROOTPATH",
50 NULL
51 };
52
53 static const char *space_separated[] = {
54 "CONFIG_PROTECT",
55 "CONFIG_PROTECT_MASK",
56 NULL,
57 };
58
59 static char *applet = NULL;
60
61 int main (int argc, char **argv)
62 {
63 char **files = rc_ls_dir (NULL, ENVDIR, 0);
64 char *file;
65 char **envs = NULL;
66 char *env;
67 int i = 0;
68 int j;
69 FILE *fp;
70 bool ld = true;
71 char *ldent;
72 char **ldents = NULL;
73 int nents = 0;
74 char **config = NULL;
75 char *entry;
76 char **mycolons = NULL;
77 char **myspaces = NULL;
78
79 applet = argv[0];
80
81 if (! files)
82 eerrorx ("%s: no files in " ENVDIR " to process", applet);
83
84 STRLIST_FOREACH (files, file, i) {
85 char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL);
86 char **entries = NULL;
87
88 if (! rc_is_dir (path))
89 entries = rc_get_config (NULL, path);
90 free (path);
91
92 STRLIST_FOREACH (entries, entry, j) {
93 char *tmpent = rc_xstrdup (entry);
94 char *value = tmpent;
95 char *var = strsep (&value, "=");
96
97 if (strcmp (var, "COLON_SEPARATED") == 0)
98 while ((var = strsep (&value, " ")))
99 mycolons = rc_strlist_addu (mycolons, var);
100 else if (strcmp (var, "SPACE_SEPARATED") == 0)
101 while ((var = strsep (&value, " ")))
102 myspaces = rc_strlist_addu (myspaces, var);
103 else
104 config = rc_strlist_add (config, entry);
105 free (tmpent);
106 }
107
108 rc_strlist_free (entries);
109 }
110
111 STRLIST_FOREACH (config, entry, i) {
112 char *tmpent = rc_xstrdup (entry);
113 char *value = tmpent;
114 char *var = strsep (&value, "=");
115 char *match;
116 bool colon = false;
117 bool space = false;
118 bool replaced = false;
119
120 for (j = 0; colon_separated[j]; j++)
121 if (strcmp (colon_separated[j], var) == 0) {
122 colon = true;
123 break;
124 }
125
126 if (! colon)
127 STRLIST_FOREACH (mycolons, match, j) {
128 if (strcmp (match, var) == 0) {
129 colon = true;
130 break;
131 } }
132
133 if (! colon)
134 for (j = 0; space_separated[j]; j++)
135 if (strcmp (space_separated[j], var) == 0) {
136 space = true;
137 break;
138 }
139
140 if (! colon && ! space)
141 STRLIST_FOREACH (myspaces, match, j)
142 if (strcmp (match, var) == 0) {
143 space = true;
144 break;
145 }
146
147 /* Skip blank vars */
148 if ((colon || space) &&
149 (! value || strlen (value)) == 0)
150 {
151 free (tmpent);
152 continue;
153 }
154
155 STRLIST_FOREACH (envs, env, j) {
156 char *tmpenv = rc_xstrdup (env);
157 char *tmpvalue = tmpenv;
158 char *tmpentry = strsep (&tmpvalue, "=");
159
160 if (strcmp (tmpentry, var) == 0) {
161 if (colon || space) {
162 int len = strlen (envs[j - 1]) + strlen (entry) + 1;
163 envs[j - 1] = rc_xrealloc (envs[j - 1], len);
164 snprintf (envs[j - 1] + strlen (envs[j - 1]), len,
165 "%s%s", colon ? ":" : " ", value);
166 } else {
167 free (envs[j - 1]);
168 envs[j - 1] = rc_xstrdup (entry);
169 }
170 replaced = true;
171 }
172 free (tmpenv);
173
174 if (replaced)
175 break;
176 }
177
178 if (! replaced)
179 envs = rc_strlist_addsort (envs, entry);
180
181 free (tmpent);
182 }
183 rc_strlist_free (mycolons);
184 rc_strlist_free (myspaces);
185 rc_strlist_free (config);
186 rc_strlist_free (files);
187
188 if ((fp = fopen (PROFILE_ENV, "w")) == NULL)
189 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
190 fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV);
191
192 STRLIST_FOREACH (envs, env, i) {
193 char *tmpent = rc_xstrdup (env);
194 char *value = tmpent;
195 char *var = strsep (&value, "=");
196 if (strcmp (var, "LDPATH") != 0)
197 fprintf (fp, "export %s='%s'\n", var, value);
198 free (tmpent);
199 }
200 fclose (fp);
201
202 if ((fp = fopen (CSH_ENV, "w")) == NULL)
203 eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
204 fprintf (fp, NOTICE, "/etc/csh.cshrc", PROFILE_ENV);
205
206 STRLIST_FOREACH (envs, env, i) {
207 char *tmpent = rc_xstrdup (env);
208 char *value = tmpent;
209 char *var = strsep (&value, "=");
210 if (strcmp (var, "LDPATH") != 0)
211 fprintf (fp, "setenv %s '%s'\n", var, value);
212 free (tmpent);
213 }
214 fclose (fp);
215
216 ldent = rc_get_config_entry (envs, "LDPATH");
217
218 if (! ldent ||
219 (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0))
220 {
221 rc_strlist_free (envs);
222 return (EXIT_SUCCESS);
223 }
224
225 while ((file = strsep (&ldent, ":"))) {
226 if (strlen (file) == 0)
227 continue;
228
229 ldents = rc_strlist_add (ldents, file);
230 nents++;
231 }
232
233 /* Update ld.so.conf only if different */
234 if (rc_exists (LDSOCONF)) {
235 char **lines = rc_get_list (NULL, LDSOCONF);
236 char *line;
237 ld = false;
238 STRLIST_FOREACH (lines, line, i)
239 if (i > nents || strcmp (line, ldents[i - 1]) != 0)
240 {
241 ld = true;
242 break;
243 }
244 rc_strlist_free (lines);
245 if (i - 1 != nents)
246 ld = true;
247 }
248
249 if (ld) {
250 int retval = 0;
251
252 if ((fp = fopen (LDSOCONF, "w")) == NULL)
253 eerrorx ("%s: fopen `%s': %s", applet, LDSOCONF, strerror (errno));
254 fprintf (fp, LDNOTICE);
255 STRLIST_FOREACH (ldents, ldent, i)
256 fprintf (fp, "%s\n", ldent);
257 fclose (fp);
258
259 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
260 ebegin ("Regenerating /var/run/ld-elf.so.hints");
261 retval = system ("/sbin/ldconfig -elf -i '" LDSOCONF "'");
262 #else
263 ebegin ("Regenerating /etc/ld.so.cache");
264 retval = system ("/sbin/ldconfig");
265 #endif
266 eend (retval, NULL);
267 }
268
269 rc_strlist_free (ldents);
270 rc_strlist_free (envs);
271 return(EXIT_SUCCESS);
272 }

  ViewVC Help
Powered by ViewVC 1.1.20