From abfd181ddecbe1ecc67acbcd36a885cc6bd2a06d Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Fri, 27 Apr 2007 11:24:05 +0000 Subject: [PATCH] env-update now respects COLON_SEPARATED and SPACE_SEPARATED env.d values, #176198. --- ChangeLog | 5 ++ src/env-update.c | 156 ++++++++++++++++++++++++++++---------------- src/librc-strlist.c | 51 ++++++++++++++- src/librc.h | 2 + src/rc.h | 2 + 5 files changed, 156 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ee3f997..b0446d61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ # ChangeLog for Gentoo System Intialization ("rc") scripts # Copyright 1999-2007 Gentoo Foundation; Distributed under the GPLv2 + 27 Apr 2007; Roy Marples : + + env-update now respects COLON_SEPARATED and SPACE_SEPARATED env.d + values, #176198. + 26 Apr 2007; Roy Marples : checkroot and checkfs now use more friendly generic options, #116016. diff --git a/src/env-update.c b/src/env-update.c index e0aa63f9..c73671ca 100644 --- a/src/env-update.c +++ b/src/env-update.c @@ -33,7 +33,7 @@ #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[] = { +static const char *colon_separated[] = { "ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH", "CLASSPATH", @@ -50,7 +50,7 @@ static const char *specials[] = { NULL }; -static const char *special_spaces[] = { +static const char *space_separated[] = { "CONFIG_PROTECT", "CONFIG_PROTECT_MASK", NULL, @@ -65,11 +65,16 @@ int main (int argc, char **argv) char **envs = NULL; char *env; int i = 0; + int j; FILE *fp; bool ld = true; char *ldent; char **ldents = NULL; int nents = 0; + char **config = NULL; + char *entry; + char **mycolons = NULL; + char **myspaces = NULL; applet = argv[0]; @@ -79,8 +84,6 @@ int main (int argc, char **argv) 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); @@ -90,64 +93,98 @@ int main (int argc, char **argv) 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) { - int len = strlen (envs[k - 1]) + strlen (entry) + 1; - envs[k - 1] = rc_xrealloc (envs[k - 1], len); - snprintf (envs[k - 1] + strlen (envs[k - 1]), len, - "%s%s", isspecial_spaced ? " " : ":", value); - } else { - free (envs[k - 1]); - envs[k - 1] = rc_xstrdup (entry); - } - replaced = true; - } - free (tmpenv); - - if (replaced) - break; - } - - if (! replaced) - envs = rc_strlist_addsort (envs, entry); + if (strcmp (var, "COLON_SEPARATED") == 0) + while ((var = strsep (&value, " "))) + mycolons = rc_strlist_addu (mycolons, var); + else if (strcmp (var, "SPACE_SEPARATED") == 0) + while ((var = strsep (&value, " "))) + myspaces = rc_strlist_addu (myspaces, var); + else + config = rc_strlist_add (config, entry); free (tmpent); } + + rc_strlist_free (entries); } + STRLIST_FOREACH (config, entry, i) { + char *tmpent = rc_xstrdup (entry); + char *value = tmpent; + char *var = strsep (&value, "="); + char *match; + bool colon = false; + bool space = false; + bool replaced = false; + + for (j = 0; colon_separated[j]; j++) + if (strcmp (colon_separated[j], var) == 0) { + colon = true; + break; + } + + if (! colon) + STRLIST_FOREACH (mycolons, match, j) { + if (strcmp (match, var) == 0) { + colon = true; + break; + } } + + if (! colon) + for (j = 0; space_separated[j]; j++) + if (strcmp (space_separated[j], var) == 0) { + space = true; + break; + } + + if (! colon && ! space) + STRLIST_FOREACH (myspaces, match, j) + if (strcmp (match, var) == 0) { + space = true; + break; + } + + /* Skip blank vars */ + if ((colon || space) && + (! value || strlen (value)) == 0) + { + free (tmpent); + continue; + } + + STRLIST_FOREACH (envs, env, j) { + char *tmpenv = rc_xstrdup (env); + char *tmpvalue = tmpenv; + char *tmpentry = strsep (&tmpvalue, "="); + + if (strcmp (tmpentry, var) == 0) { + if (colon || space) { + int len = strlen (envs[j - 1]) + strlen (entry) + 1; + envs[j - 1] = rc_xrealloc (envs[j - 1], len); + snprintf (envs[j - 1] + strlen (envs[j - 1]), len, + "%s%s", colon ? ":" : " ", value); + } else { + free (envs[j - 1]); + envs[j - 1] = rc_xstrdup (entry); + } + replaced = true; + } + free (tmpenv); + + if (replaced) + break; + } + + if (! replaced) + envs = rc_strlist_addsort (envs, entry); + + free (tmpent); + } + rc_strlist_free (mycolons); + rc_strlist_free (myspaces); + rc_strlist_free (config); + rc_strlist_free (files); + if ((fp = fopen (PROFILE_ENV, "w")) == NULL) eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno)); fprintf (fp, NOTICE, "/etc/profile", PROFILE_ENV); @@ -181,7 +218,7 @@ int main (int argc, char **argv) if (! ldent || (argc > 1 && argv[1] && strcmp (argv[1], "--no-ldconfig") == 0)) { - free (envs); + rc_strlist_free (envs); return (EXIT_SUCCESS); } @@ -204,6 +241,7 @@ int main (int argc, char **argv) ld = true; break; } + rc_strlist_free (lines); if (i - 1 != nents) ld = true; } @@ -228,5 +266,7 @@ int main (int argc, char **argv) eend (retval, NULL); } + rc_strlist_free (ldents); + rc_strlist_free (envs); return(EXIT_SUCCESS); } diff --git a/src/librc-strlist.c b/src/librc-strlist.c index 68491816..4c72cf45 100644 --- a/src/librc-strlist.c +++ b/src/librc-strlist.c @@ -9,7 +9,7 @@ #include "librc.h" -char **rc_strlist_add (char **list, const char *item) +static char **_rc_strlist_add (char **list, const char *item, bool uniq) { char **newlist; int i = 0; @@ -17,8 +17,11 @@ char **rc_strlist_add (char **list, const char *item) if (! item) return (list); - while (list && list[i]) + while (list && list[i]) { + if (uniq && strcmp (list[i], item) == 0) + return (list); i++; + } newlist = rc_xrealloc (list, sizeof (char *) * (i + 2)); newlist[i] = rc_xstrdup (item); @@ -26,8 +29,19 @@ char **rc_strlist_add (char **list, const char *item) return (newlist); } + +char **rc_strlist_add (char **list, const char *item) +{ + return (_rc_strlist_add (list, item, false)); +} librc_hidden_def(rc_strlist_add) +char **rc_strlist_addu (char **list, const char *item) +{ + return (_rc_strlist_add (list, item, true)); +} +librc_hidden_def(rc_strlist_addu) + static char **_rc_strlist_addsort (char **list, const char *item, int (*sortfunc) (const char *s1, const char *s2), @@ -107,6 +121,39 @@ char **rc_strlist_delete (char **list, const char *item) } librc_hidden_def(rc_strlist_delete) +char **rc_strlist_join (char **this, char **that) +{ + char **newlist; + int i = 0; + int j = 0; + + if (! this && that) + return (that); + if (! that && this) + return (this); + if (! that && ! this) + return (NULL); + + while (this[i]) + i++; + + while (that[j]) + j++; + + newlist = rc_xrealloc (this, sizeof (char *) * (i + j + 1)); + + j = 0; + while (that[j]) { + newlist[i] = that[j]; + i++; + j++; + } + newlist[i] = NULL; + + return (newlist); +} +librc_hidden_def(rc_strlist_join) + void rc_strlist_reverse (char **list) { char *item; diff --git a/src/librc.h b/src/librc.h index 5791fed4..1661cea3 100644 --- a/src/librc.h +++ b/src/librc.h @@ -94,11 +94,13 @@ librc_hidden_proto(rc_start_service) librc_hidden_proto(rc_stop_service) librc_hidden_proto(rc_strcatpaths) librc_hidden_proto(rc_strlist_add) +librc_hidden_proto(rc_strlist_addu) librc_hidden_proto(rc_strlist_addsort) librc_hidden_proto(rc_strlist_addsortc) librc_hidden_proto(rc_strlist_addsortu) librc_hidden_proto(rc_strlist_delete) librc_hidden_proto(rc_strlist_free) +librc_hidden_proto(rc_strlist_join) librc_hidden_proto(rc_strlist_reverse) librc_hidden_proto(rc_update_deptree) librc_hidden_proto(rc_wait_service) diff --git a/src/rc.h b/src/rc.h index c4b651be..9d9b4866 100644 --- a/src/rc.h +++ b/src/rc.h @@ -192,10 +192,12 @@ char **rc_config_env (char **env); /* Handy functions for dealing with string arrays of char ** */ char **rc_strlist_add (char **list, const char *item); +char **rc_strlist_addu (char **list, const char *item); char **rc_strlist_addsort (char **list, const char *item); char **rc_strlist_addsortc (char **list, const char *item); char **rc_strlist_addsortu (char **list, const char *item); char **rc_strlist_delete (char **list, const char *item); +char **rc_strlist_join (char **this, char **that); void rc_strlist_reverse (char **list); void rc_strlist_free (char **list);