123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- #include "orconfig.h"
- #include "lib/process/env.h"
- #include "lib/malloc/util_malloc.h"
- #include "lib/ctime/di_ops.h"
- #include "lib/container/smartlist.h"
- #include "lib/log/util_bug.h"
- #include "lib/log/torlog.h"
- #include "lib/malloc/util_malloc.h"
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <stdlib.h>
- #include <string.h>
- #ifdef HAVE_CRT_EXTERNS_H
- #include <crt_externs.h>
- #endif
- #ifndef HAVE__NSGETENVIRON
- #ifndef HAVE_EXTERN_ENVIRON_DECLARED
- #ifndef RUNNING_DOXYGEN
- extern char **environ;
- #endif
- #endif
- #endif
- char **
- get_environment(void)
- {
- #ifdef HAVE__NSGETENVIRON
-
- return *_NSGetEnviron();
- #else
- return environ;
- #endif
- }
- static inline size_t
- str_num_before(const char *s, char ch)
- {
- const char *cp = strchr(s, ch);
- if (cp)
- return cp - s;
- else
- return strlen(s);
- }
- int
- environment_variable_names_equal(const char *s1, const char *s2)
- {
- size_t s1_name_len = str_num_before(s1, '=');
- size_t s2_name_len = str_num_before(s2, '=');
- return (s1_name_len == s2_name_len &&
- tor_memeq(s1, s2, s1_name_len));
- }
- void
- process_environment_free_(process_environment_t *env)
- {
- if (env == NULL) return;
-
- tor_free(env->unixoid_environment_block);
- tor_free(env->windows_environment_block);
- tor_free(env);
- }
- process_environment_t *
- process_environment_make(struct smartlist_t *env_vars)
- {
- process_environment_t *env = tor_malloc_zero(sizeof(process_environment_t));
- int n_env_vars = smartlist_len(env_vars);
- int i;
- size_t total_env_length;
- smartlist_t *env_vars_sorted;
- tor_assert(n_env_vars + 1 != 0);
- env->unixoid_environment_block = tor_calloc(n_env_vars + 1, sizeof(char *));
-
- total_env_length = 1;
- for (i = 0; i < n_env_vars; ++i) {
- const char *s = smartlist_get(env_vars, (int)i);
- size_t slen = strlen(s);
- tor_assert(slen + 1 != 0);
- tor_assert(slen + 1 < SIZE_MAX - total_env_length);
- total_env_length += slen + 1;
- }
- env->windows_environment_block = tor_malloc_zero(total_env_length);
-
-
- env_vars_sorted = smartlist_new();
- smartlist_add_all(env_vars_sorted, env_vars);
- smartlist_sort_strings(env_vars_sorted);
-
- {
- char *cp = env->windows_environment_block;
- const char *prev_env_var = NULL;
- for (i = 0; i < n_env_vars; ++i) {
- const char *s = smartlist_get(env_vars_sorted, (int)i);
- size_t slen = strlen(s);
- size_t s_name_len = str_num_before(s, '=');
- if (s_name_len == slen) {
- log_warn(LD_GENERAL,
- "Preparing an environment containing a variable "
- "without a value: %s",
- s);
- }
- if (prev_env_var != NULL &&
- environment_variable_names_equal(s, prev_env_var)) {
- log_warn(LD_GENERAL,
- "Preparing an environment containing two variables "
- "with the same name: %s and %s",
- prev_env_var, s);
- }
- prev_env_var = s;
-
- memcpy(cp, s, slen+1);
- env->unixoid_environment_block[i] = cp;
- cp += slen+1;
- }
- tor_assert(cp == env->windows_environment_block + total_env_length - 1);
- }
- smartlist_free(env_vars_sorted);
- return env;
- }
- struct smartlist_t *
- get_current_process_environment_variables(void)
- {
- smartlist_t *sl = smartlist_new();
- char **environ_tmp;
- for (environ_tmp = get_environment(); *environ_tmp; ++environ_tmp) {
- smartlist_add_strdup(sl, *environ_tmp);
- }
- return sl;
- }
- void
- set_environment_variable_in_smartlist(struct smartlist_t *env_vars,
- const char *new_var,
- void (*free_old)(void*),
- int free_p)
- {
- SMARTLIST_FOREACH_BEGIN(env_vars, const char *, s) {
- if (environment_variable_names_equal(s, new_var)) {
- SMARTLIST_DEL_CURRENT(env_vars, s);
- if (free_p) {
- free_old((void *)s);
- }
- }
- } SMARTLIST_FOREACH_END(s);
- if (strchr(new_var, '=') != NULL) {
- smartlist_add(env_vars, (void *)new_var);
- }
- }
|