170 lines
5.2 KiB
C
170 lines
5.2 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "bus-error.h"
|
|
#include "bus-locator.h"
|
|
#include "env-util.h"
|
|
#include "escape.h"
|
|
#include "systemctl-set-environment.h"
|
|
#include "systemctl-util.h"
|
|
#include "systemctl.h"
|
|
|
|
static int print_variable(const char *s) {
|
|
const char *sep;
|
|
_cleanup_free_ char *esc = NULL;
|
|
|
|
sep = strchr(s, '=');
|
|
if (!sep)
|
|
return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN),
|
|
"Invalid environment block");
|
|
|
|
esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX);
|
|
if (!esc)
|
|
return log_oom();
|
|
|
|
printf("%.*s=%s\n", (int)(sep-s), s, esc);
|
|
return 0;
|
|
}
|
|
|
|
int show_environment(int argc, char *argv[], void *userdata) {
|
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
|
const char *text;
|
|
sd_bus *bus;
|
|
int r;
|
|
|
|
r = acquire_bus(BUS_MANAGER, &bus);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
(void) pager_open(arg_pager_flags);
|
|
|
|
r = bus_get_property(bus, bus_systemd_mgr, "Environment", &error, &reply, "as");
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
|
|
|
|
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
|
|
if (r < 0)
|
|
return bus_log_parse_error(r);
|
|
|
|
while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) {
|
|
r = print_variable(text);
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
if (r < 0)
|
|
return bus_log_parse_error(r);
|
|
|
|
r = sd_bus_message_exit_container(reply);
|
|
if (r < 0)
|
|
return bus_log_parse_error(r);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void invalid_callback(const char *p, void *userdata) {
|
|
_cleanup_free_ char *t = cescape(p);
|
|
|
|
log_debug("Ignoring invalid environment assignment \"%s\".", strnull(t));
|
|
}
|
|
|
|
int set_environment(int argc, char *argv[], void *userdata) {
|
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
|
const char *method;
|
|
sd_bus *bus;
|
|
int r;
|
|
|
|
assert(argc > 1);
|
|
assert(argv);
|
|
|
|
r = acquire_bus(BUS_MANAGER, &bus);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
polkit_agent_open_maybe();
|
|
|
|
method = streq(argv[0], "set-environment")
|
|
? "SetEnvironment"
|
|
: "UnsetEnvironment";
|
|
|
|
r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method);
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
r = sd_bus_call(bus, m, 0, &error, NULL);
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int import_environment(int argc, char *argv[], void *userdata) {
|
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
|
sd_bus *bus;
|
|
int r;
|
|
|
|
r = acquire_bus(BUS_MANAGER, &bus);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
polkit_agent_open_maybe();
|
|
|
|
r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "SetEnvironment");
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
if (argc < 2) {
|
|
_cleanup_strv_free_ char **copy = NULL;
|
|
|
|
copy = strv_copy(environ);
|
|
if (!copy)
|
|
return log_oom();
|
|
|
|
strv_env_clean_with_callback(copy, invalid_callback, NULL);
|
|
|
|
r = sd_bus_message_append_strv(m, copy);
|
|
|
|
} else {
|
|
char **a, **b;
|
|
|
|
r = sd_bus_message_open_container(m, 'a', "s");
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
STRV_FOREACH(a, strv_skip(argv, 1)) {
|
|
|
|
if (!env_name_is_valid(*a))
|
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid environment variable name: %s", *a);
|
|
|
|
STRV_FOREACH(b, environ) {
|
|
const char *eq;
|
|
|
|
eq = startswith(*b, *a);
|
|
if (eq && *eq == '=') {
|
|
|
|
r = sd_bus_message_append(m, "s", *b);
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
r = sd_bus_message_close_container(m);
|
|
}
|
|
if (r < 0)
|
|
return bus_log_create_error(r);
|
|
|
|
r = sd_bus_call(bus, m, 0, &error, NULL);
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
|
|
|
|
return 0;
|
|
}
|