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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20