/* env-update Create /etc/profile.env (sh), /etc/csh.env from /etc/env.d Run ldconfig as required Copyright 2007 Gentoo Foundation Released under the GPLv2 */ #include #include #include #include #include #include #include #include "einfo.h" #include "rc.h" #include "rc-misc.h" #include "strlist.h" #define ENVDIR "/etc/env.d" #define PROFILE_ENV "/etc/profile.env" #define CSH_ENV "/etc/csh.env" #define LDSOCONF "/etc/ld.so.conf" #define NOTICE "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n" \ "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n" \ "# GO INTO %s NOT %s\n\n" #define LDNOTICE "# ld.so.conf autogenerated by env-update; make all\n" \ "# changes to contents of /etc/env.d directory\n" static const char *specials[] = { "ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH", "CLASSPATH", "INFOPATH", "KDEDIRS", "LDPATH", "MANPATH", "PATH", "PKG_CONFIG_PATH", "PRELINK_PATH", "PRELINK_PATH_MASK", "PYTHONPATH", "ROOTPATH", NULL }; static const char *special_spaces[] = { "CONFIG_PROTECT", "CONFIG_PROTECT_MASK", NULL, }; static char *applet = NULL; int main (int argc, char **argv) { char **files = rc_ls_dir (NULL, ENVDIR, 0); char *file; char **envs = NULL; char *env; int i = 0; FILE *fp; bool ld = true; char *ldent; char **ldents = NULL; int nents = 0; applet = argv[0]; if (! files) eerrorx ("%s: no files in " ENVDIR " to process", applet); STRLIST_FOREACH (files, file, i) { char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL); char **entries = NULL; char *entry; int j; if (! rc_is_dir (path)) entries = rc_get_config (NULL, path); free (path); STRLIST_FOREACH (entries, entry, j) { char *tmpent = rc_xstrdup (entry); char *value = tmpent; char *var = strsep (&value, "="); int k; bool isspecial = false; bool isspecial_spaced = false; bool replaced = false; for (k = 0; special_spaces[k]; k++) if (strcmp (special_spaces[k], var) == 0) { isspecial = true; isspecial_spaced = true; break; } if (! isspecial) { for (k = 0; specials[k]; k++) if (strcmp (specials[k], var) == 0) { isspecial = true; break; } } /* Skip blank vars */ if (isspecial && (! value || strlen (value)) == 0) { free (tmpent); continue; } STRLIST_FOREACH (envs, env, k) { char *tmpenv = rc_xstrdup (env); char *tmpvalue = tmpenv; char *tmpentry = strsep (&tmpvalue, "="); if (strcmp (tmpentry, var) == 0) { if (isspecial) { envs[k - 1] = rc_xrealloc (envs[k - 1], strlen (envs[k - 1]) + strlen (entry) + 1); sprintf (envs[k - 1] + strlen (envs[k - 1]), "%s%s", isspecial_spaced ? " " : ":", value); } else { free (envs[k - 1]); envs[k - 1] = strdup (entry); } replaced = true; } free (tmpenv); if (replaced) break; } if (! replaced) envs = rc_strlist_addsort (envs, entry); free (tmpent); } } if ((fp = fopen (PROFILE_ENV, "w")) == NULL) eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno)); fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV); STRLIST_FOREACH (envs, env, i) { char *tmpent = rc_xstrdup (env); char *value = tmpent; char *var = strsep (&value, "="); if (strcmp (var, "LDPATH") != 0) fprintf (fp, "export %s='%s'\n", var, value); free (tmpent); } fclose (fp); if ((fp = fopen (CSH_ENV, "w")) == NULL) eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno)); fprintf (fp, NOTICE, "/etc/csh.cshrc", PROFILE_ENV); STRLIST_FOREACH (envs, env, i) { char *tmpent = rc_xstrdup (env); char *value = tmpent; char *var = strsep (&value, "="); if (strcmp (var, "LDPATH") != 0) fprintf (fp, "setenv %s '%s'\n", var, value); free (tmpent); } fclose (fp); ldent = rc_get_config_entry (envs, "LDPATH"); if (! ldent || (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0)) { free (envs); return (EXIT_SUCCESS); } while ((file = strsep (&ldent, ":"))) { if (strlen (file) == 0) continue; ldents = rc_strlist_add (ldents, file); nents++; } /* Update ld.so.conf only if different */ if (rc_exists (LDSOCONF)) { char **lines = rc_get_list (NULL, LDSOCONF); char *line; ld = false; STRLIST_FOREACH (lines, line, i) if (i > nents || strcmp (line, ldents[i - 1]) != 0) { ld = true; break; } if (i - 1 != nents) ld = true; } if (ld) { int retval = 0; if ((fp = fopen (LDSOCONF, "w")) == NULL) eerrorx ("%s: fopen `%s': %s", applet, LDSOCONF, strerror (errno)); fprintf (fp, LDNOTICE); STRLIST_FOREACH (ldents, ldent, i) fprintf (fp, "%s\n", ldent); fclose (fp); #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ebegin ("Regenerating /var/run/ld-elf.so.hints"); retval = system ("/sbin/ldconfig -elf -i '" LDSOCONF "'"); #else ebegin ("Regenerating /etc/ld.so.cache"); retval = system ("/sbin/ldconfig"); #endif eend (retval, NULL); } return(EXIT_SUCCESS); }