]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
daf71ef6 LP |
2 | |
3 | #include "bus-error.h" | |
4 | #include "bus-locator.h" | |
5 | #include "env-util.h" | |
6 | #include "escape.h" | |
7 | #include "systemctl-set-environment.h" | |
8 | #include "systemctl-util.h" | |
9 | #include "systemctl.h" | |
10 | ||
11 | static int print_variable(const char *s) { | |
12 | const char *sep; | |
13 | _cleanup_free_ char *esc = NULL; | |
14 | ||
15 | sep = strchr(s, '='); | |
16 | if (!sep) | |
17 | return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN), | |
18 | "Invalid environment block"); | |
19 | ||
20 | esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX); | |
21 | if (!esc) | |
22 | return log_oom(); | |
23 | ||
24 | printf("%.*s=%s\n", (int)(sep-s), s, esc); | |
25 | return 0; | |
26 | } | |
27 | ||
28 | int show_environment(int argc, char *argv[], void *userdata) { | |
29 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; | |
30 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
31 | const char *text; | |
32 | sd_bus *bus; | |
33 | int r; | |
34 | ||
35 | r = acquire_bus(BUS_MANAGER, &bus); | |
36 | if (r < 0) | |
37 | return r; | |
38 | ||
39 | (void) pager_open(arg_pager_flags); | |
40 | ||
41 | r = bus_get_property(bus, bus_systemd_mgr, "Environment", &error, &reply, "as"); | |
42 | if (r < 0) | |
43 | return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r)); | |
44 | ||
45 | r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s"); | |
46 | if (r < 0) | |
47 | return bus_log_parse_error(r); | |
48 | ||
49 | while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) { | |
50 | r = print_variable(text); | |
51 | if (r < 0) | |
52 | return r; | |
53 | } | |
54 | if (r < 0) | |
55 | return bus_log_parse_error(r); | |
56 | ||
57 | r = sd_bus_message_exit_container(reply); | |
58 | if (r < 0) | |
59 | return bus_log_parse_error(r); | |
60 | ||
61 | return 0; | |
62 | } | |
63 | ||
a4ccce22 ZJS |
64 | static void invalid_callback(const char *p, void *userdata) { |
65 | _cleanup_free_ char *t = cescape(p); | |
edfa5517 | 66 | |
a4ccce22 ZJS |
67 | log_debug("Ignoring invalid environment assignment \"%s\".", strnull(t)); |
68 | } | |
69 | ||
daf71ef6 LP |
70 | int set_environment(int argc, char *argv[], void *userdata) { |
71 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; | |
72 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; | |
73 | const char *method; | |
74 | sd_bus *bus; | |
75 | int r; | |
76 | ||
77 | assert(argc > 1); | |
78 | assert(argv); | |
79 | ||
80 | r = acquire_bus(BUS_MANAGER, &bus); | |
81 | if (r < 0) | |
82 | return r; | |
83 | ||
84 | polkit_agent_open_maybe(); | |
85 | ||
86 | method = streq(argv[0], "set-environment") | |
87 | ? "SetEnvironment" | |
88 | : "UnsetEnvironment"; | |
89 | ||
90 | r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method); | |
91 | if (r < 0) | |
92 | return bus_log_create_error(r); | |
93 | ||
94 | r = sd_bus_message_append_strv(m, strv_skip(argv, 1)); | |
95 | if (r < 0) | |
96 | return bus_log_create_error(r); | |
97 | ||
98 | r = sd_bus_call(bus, m, 0, &error, NULL); | |
99 | if (r < 0) | |
100 | return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r)); | |
101 | ||
102 | return 0; | |
103 | } | |
104 | ||
105 | int import_environment(int argc, char *argv[], void *userdata) { | |
106 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; | |
107 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; | |
108 | sd_bus *bus; | |
109 | int r; | |
110 | ||
111 | r = acquire_bus(BUS_MANAGER, &bus); | |
112 | if (r < 0) | |
113 | return r; | |
114 | ||
115 | polkit_agent_open_maybe(); | |
116 | ||
117 | r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "SetEnvironment"); | |
118 | if (r < 0) | |
119 | return bus_log_create_error(r); | |
120 | ||
a4ccce22 ZJS |
121 | if (argc < 2) { |
122 | _cleanup_strv_free_ char **copy = NULL; | |
edfa5517 | 123 | |
a4ccce22 ZJS |
124 | copy = strv_copy(environ); |
125 | if (!copy) | |
126 | return log_oom(); | |
edfa5517 | 127 | |
a4ccce22 | 128 | strv_env_clean_with_callback(copy, invalid_callback, NULL); |
edfa5517 | 129 | |
a4ccce22 ZJS |
130 | r = sd_bus_message_append_strv(m, copy); |
131 | ||
132 | } else { | |
daf71ef6 LP |
133 | char **a, **b; |
134 | ||
135 | r = sd_bus_message_open_container(m, 'a', "s"); | |
136 | if (r < 0) | |
137 | return bus_log_create_error(r); | |
138 | ||
139 | STRV_FOREACH(a, strv_skip(argv, 1)) { | |
140 | ||
141 | if (!env_name_is_valid(*a)) | |
142 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid environment variable name: %s", *a); | |
143 | ||
144 | STRV_FOREACH(b, environ) { | |
145 | const char *eq; | |
146 | ||
147 | eq = startswith(*b, *a); | |
148 | if (eq && *eq == '=') { | |
149 | ||
150 | r = sd_bus_message_append(m, "s", *b); | |
151 | if (r < 0) | |
152 | return bus_log_create_error(r); | |
153 | ||
154 | break; | |
155 | } | |
156 | } | |
157 | } | |
158 | ||
159 | r = sd_bus_message_close_container(m); | |
160 | } | |
161 | if (r < 0) | |
162 | return bus_log_create_error(r); | |
163 | ||
164 | r = sd_bus_call(bus, m, 0, &error, NULL); | |
165 | if (r < 0) | |
166 | return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r)); | |
167 | ||
168 | return 0; | |
169 | } |