]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl-set-environment.c
Merge pull request #17395 from keszybz/hwdb-drop-quotes
[thirdparty/systemd.git] / src / systemctl / systemctl-set-environment.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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
64 static void invalid_callback(const char *p, void *userdata) {
65 _cleanup_free_ char *t = cescape(p);
66
67 log_debug("Ignoring invalid environment assignment \"%s\".", strnull(t));
68 }
69
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
121 if (argc < 2) {
122 _cleanup_strv_free_ char **copy = NULL;
123
124 copy = strv_copy(environ);
125 if (!copy)
126 return log_oom();
127
128 strv_env_clean_with_callback(copy, invalid_callback, NULL);
129
130 r = sd_bus_message_append_strv(m, copy);
131
132 } else {
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 }