+static char *bt_secure_getenv(const char *name)
+{
+ if (is_setuid_setgid()) {
+ printf_err("Disregarding %s environment variable for setuid/setgid binary", name);
+ return NULL;
+ }
+ return getenv(name);
+}
+
+static const char *get_home_dir(void)
+{
+ char *val = NULL;
+ struct passwd *pwd;
+
+ val = bt_secure_getenv(HOME_ENV_VAR);
+ if (val) {
+ goto end;
+ }
+ /* Fallback on password file. */
+ pwd = getpwuid(getuid());
+ if (!pwd) {
+ goto end;
+ }
+ val = pwd->pw_dir;
+end:
+ return val;
+}
+
+static int add_internal_plugin_paths(struct bt_config *cfg)
+{
+ if (!cfg->omit_home_plugin_path) {
+ char path[PATH_MAX];
+ const char *home_dir;
+
+ if (is_setuid_setgid()) {
+ printf_debug("Skipping non-system plugin paths for setuid/setgid binary.");
+ } else {
+ home_dir = get_home_dir();
+ if (home_dir) {
+ if (strlen(home_dir) + strlen(HOME_SUBPATH) + 1
+ >= PATH_MAX) {
+ printf_err("Home directory path too long\n");
+ goto error;
+ }
+ strcpy(path, home_dir);
+ strcat(path, HOME_SUBPATH);
+ if (plugin_paths_from_arg(cfg->plugin_paths, path)) {
+ printf_err("Invalid home plugin path\n");
+ goto error;
+ }
+ }
+ }
+ }
+
+ if (!cfg->omit_system_plugin_path) {
+ if (plugin_paths_from_arg(cfg->plugin_paths,
+ SYSTEM_PLUGIN_PATH)) {
+ printf_err("Invalid system plugin path\n");
+ goto error;
+ }
+ }
+ return 0;
+error:
+ return -1;
+}
+
+static int append_sources_from_implicit_params(GPtrArray *sources,
+ struct bt_config_component *implicit_source_comp)
+{
+ size_t i;
+ size_t len = sources->len;
+
+ for (i = 0; i < len; i++) {
+ struct bt_config_component *comp;
+ struct bt_value *params_to_set;
+
+ comp = g_ptr_array_index(sources, i);
+ params_to_set = bt_value_map_extend(comp->params,
+ implicit_source_comp->params);
+ if (!params_to_set) {
+ printf_err("Cannot extend legacy component parameters with non-legacy parameters\n");
+ goto error;
+ }
+ BT_MOVE(comp->params, params_to_set);
+ }
+ return 0;
+error:
+ return -1;
+}
+
+struct bt_config *bt_config_create(void)
+{
+ struct bt_config *cfg;
+
+ /* Create config */
+ cfg = g_new0(struct bt_config, 1);
+ if (!cfg) {
+ print_err_oom();
+ goto error;
+ }
+
+ bt_object_init(cfg, bt_config_destroy);
+ cfg->sources = g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
+ if (!cfg->sources) {
+ print_err_oom();
+ goto error;
+ }
+
+ cfg->sinks = g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
+ if (!cfg->sinks) {
+ print_err_oom();
+ goto error;
+ }
+
+ cfg->plugin_paths = bt_value_array_create();
+ if (!cfg->plugin_paths) {
+ print_err_oom();
+ goto error;
+ }
+end:
+ return cfg;
+error:
+ BT_PUT(cfg);
+ goto end;
+}
+