+++ /dev/null
-From 92c63984fc28ea1bb0939acfcb551f65d7bfddf7 Mon Sep 17 00:00:00 2001
-From: Dennis Groenen <tj.groenen@gmail.com>
-Date: Fri, 23 Dec 2011 20:34:22 +0100
-Subject: [PATCH] appletlib: parse /etc/environment prior to applet launch
-
----
- libbb/appletlib.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 files changed, 117 insertions(+), 0 deletions(-)
-
-diff --git a/libbb/appletlib.c b/libbb/appletlib.c
-index 8157b4f..d13aee5 100644
---- a/libbb/appletlib.c
-+++ b/libbb/appletlib.c
-@@ -474,6 +474,121 @@ static inline void parse_config_file(void)
- }
- # endif /* FEATURE_SUID_CONFIG */
-
-+/* We do not want to allow all characters in environment variables.
-+ * Function based on patch by Tito.
-+ * http://lists.busybox.net/pipermail/busybox/2011-August/076364.html */
-+static bool bad_env_var(const char *name)
-+{
-+ const char *s = name;
-+
-+ do {
-+ /* We don't use isalnum as it will allow locale-specific non-ASCII */
-+ /* letters in legacy 8-bit locales. */
-+ if (((*name >= 48 && *name <= 57) && name != s) /* no numeric values as first char */
-+ || *name == '_' /* allow underscores */
-+ || (*name >= 65 && *name <= 90) /* allow A-Z */
-+ || (*name >= 97 && *name <= 122) /* allow a-z */
-+ ) {
-+ continue;
-+ }
-+ return true;
-+ } while (*++name);
-+ return false;
-+}
-+
-+static void load_env_vars(void)
-+{
-+ /* Don't depend on the tools to combine strings. */
-+ static const char config_file[] ALIGN1 = "/etc/environment";
-+
-+ FILE *f;
-+ const char *errmsg;
-+ unsigned lc;
-+ struct stat st;
-+
-+ if ((stat(config_file, &st) != 0) /* No config file? */
-+ || !S_ISREG(st.st_mode) /* Not a regular file? */
-+ || (st.st_uid != 0) /* Not owned by root? */
-+ || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */
-+ || !(f = fopen_for_read(config_file)) /* Cannot open? */
-+ ) {
-+ return;
-+ }
-+
-+ lc = 0;
-+
-+ while (1) {
-+ char buffer[256];
-+ char *key;
-+ char *val;
-+ char *e;
-+
-+ if (!fgets(buffer, sizeof(buffer), f)) { /* Are we done? */
-+ fclose(f);
-+ return;
-+ }
-+
-+ key = buffer;
-+ lc++; /* Got a (partial) line. */
-+
-+ /* If a line is too long for our buffer, we consider it an error.
-+ * The following test does mistreat one corner case though.
-+ * If the final line of the file does not end with a newline and
-+ * yet exactly fills the buffer, it will be treated as too long
-+ * even though there isn't really a problem. But it isn't really
-+ * worth adding code to deal with such an unlikely situation, and
-+ * we do err on the side of caution. Besides, the line would be
-+ * too long if it did end with a newline. */
-+ if (!strchr(key, '\n') && !feof(f)) {
-+ errmsg = "line too long";
-+ goto pe_label;
-+ }
-+
-+ /* Trim leading and trailing whitespace, ignoring comments, and
-+ * check if the resulting string is empty. */
-+ key = get_trimmed_slice(key, strchrnul(key, '#'));
-+ if (!*key) {
-+ continue;
-+ }
-+
-+ /* Get the key */
-+ e = strchr(key, '=');
-+
-+ if (e) {
-+ key = get_trimmed_slice(key, e);
-+ }
-+
-+ if (!e || !*key) { /* Missing '=' or empty key. */
-+ errmsg = "keyword";
-+ goto pe_label;
-+ }
-+ if (bad_env_var(key)) { /* Check for illegal characters */
-+ errmsg = "illegal character";
-+ goto pe_label;
-+ }
-+
-+ /* Get the value */
-+ val = skip_whitespace(e+1); /* What's after the equal sign? */
-+
-+ if (!*val) { /* Empty value */
-+ errmsg = "value";
-+ goto pe_label;
-+ }
-+ if (*val == '"' && val[(strlen(val)-1)] == '"') {
-+ /* We do not want to pass quoted strings to setenv. */
-+ val++;
-+ val[strlen(val)-1] = 0;
-+ }
-+
-+ if (!getenv(key)) /* User vars > config vars */
-+ xsetenv(key, val);
-+ continue;
-+ } /* while (1) */
-+
-+ pe_label:
-+ fclose(f);
-+ bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg);
-+}
-
- # if ENABLE_FEATURE_SUID
- static void check_suid(int applet_no)
-@@ -802,9 +917,11 @@ int main(int argc UNUSED_PARAM, char **argv)
- }
- /* applet_names in this case is just "applet\0\0" */
- lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv));
-+ load_env_vars();
- return SINGLE_APPLET_MAIN(argc, argv);
- #else
- lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
-+ load_env_vars();
-
- applet_name = argv[0];
- if (applet_name[0] == '-')
---
-1.7.8
-