summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dbus-common.c59
-rw-r--r--src/dbus-common.h3
-rw-r--r--src/dbus-manager.c56
-rw-r--r--src/dbus.c49
-rw-r--r--src/dbus.h2
-rw-r--r--src/service.c8
-rw-r--r--src/util.c1
7 files changed, 123 insertions, 55 deletions
diff --git a/src/dbus-common.c b/src/dbus-common.c
index cb43bbdd4c..e439a42486 100644
--- a/src/dbus-common.c
+++ b/src/dbus-common.c
@@ -737,3 +737,62 @@ unsigned bus_events_to_flags(uint32_t events) {
return flags;
}
+
+int bus_parse_strv(DBusMessage *m, char ***_l) {
+ DBusMessageIter iter;
+
+ assert(m);
+ assert(_l);
+
+ if (!dbus_message_iter_init(m, &iter))
+ return -EINVAL;
+
+ return bus_parse_strv_iter(&iter, _l);
+}
+
+int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) {
+ DBusMessageIter sub;
+ unsigned n = 0, i = 0;
+ char **l;
+
+ assert(iter);
+ assert(_l);
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ n++;
+ dbus_message_iter_next(&sub);
+ }
+
+ if (!(l = new(char*, n+1)))
+ return -ENOMEM;
+
+ dbus_message_iter_recurse(iter, &sub);
+
+ while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ const char *s;
+
+ assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
+ dbus_message_iter_get_basic(&sub, &s);
+
+ if (!(l[i++] = strdup(s))) {
+ strv_free(l);
+ return -ENOMEM;
+ }
+
+ dbus_message_iter_next(&sub);
+ }
+
+ assert(i == n);
+ l[i] = NULL;
+
+ if (_l)
+ *_l = l;
+
+ return 0;
+}
diff --git a/src/dbus-common.h b/src/dbus-common.h
index e321a2c822..9368f75123 100644
--- a/src/dbus-common.h
+++ b/src/dbus-common.h
@@ -158,4 +158,7 @@ DBusMessage* bus_properties_changed_new(const char *path, const char *interface,
uint32_t bus_flags_to_events(DBusWatch *bus_watch);
unsigned bus_events_to_flags(uint32_t events);
+int bus_parse_strv(DBusMessage *m, char ***_l);
+int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l);
+
#endif
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 797e53d10f..cc2b4d0157 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -128,6 +128,10 @@
" </method>\n" \
" <method name=\"UnsetEnvironment\">\n" \
" <arg name=\"names\" type=\"as\" direction=\"in\"/>\n" \
+ " </method>\n" \
+ " <method name=\"UnsetAndSetEnvironment\">\n" \
+ " <arg name=\"unset\" type=\"as\" direction=\"in\"/>\n" \
+ " <arg name=\"set\" type=\"as\" direction=\"in\"/>\n" \
" </method>\n"
#define BUS_MANAGER_INTERFACE_SIGNALS \
@@ -1035,6 +1039,58 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
strv_free(m->environment);
m->environment = e;
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) {
+ char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL;
+ DBusMessageIter iter;
+
+ if (!dbus_message_iter_init(message, &iter))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+ r = bus_parse_strv_iter(&iter, &l_unset);
+ if (r < 0) {
+ if (r == -ENOMEM)
+ goto oom;
+
+ return bus_send_error_reply(connection, message, NULL, r);
+ }
+
+ if (!dbus_message_iter_next(&iter)) {
+ strv_free(l_unset);
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
+ }
+
+ r = bus_parse_strv_iter(&iter, &l_set);
+ if (r < 0) {
+ strv_free(l_unset);
+ if (r == -ENOMEM)
+ goto oom;
+
+ return bus_send_error_reply(connection, message, NULL, r);
+ }
+
+ e = strv_env_delete(m->environment, 1, l_unset);
+ strv_free(l_unset);
+
+ if (!e) {
+ strv_free(l_set);
+ goto oom;
+ }
+
+ f = strv_env_merge(2, e, l_set);
+ strv_free(l_set);
+ strv_free(e);
+
+ if (!f)
+ goto oom;
+
+ if (!(reply = dbus_message_new_method_return(message))) {
+ strv_free(f);
+ goto oom;
+ }
+
+ strv_free(m->environment);
+ m->environment = f;
+
} else
return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, properties);
diff --git a/src/dbus.c b/src/dbus.c
index e153c35ab3..2a379a2b3e 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -1212,55 +1212,6 @@ int bus_broadcast(Manager *m, DBusMessage *message) {
return oom ? -ENOMEM : 0;
}
-int bus_parse_strv(DBusMessage *m, char ***_l) {
- DBusMessageIter iter, sub;
- unsigned n = 0, i = 0;
- char **l;
-
- assert(m);
- assert(_l);
-
- if (!dbus_message_iter_init(m, &iter) ||
- dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
- return -EINVAL;
-
- dbus_message_iter_recurse(&iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- n++;
- dbus_message_iter_next(&sub);
- }
-
- if (!(l = new(char*, n+1)))
- return -ENOMEM;
-
- assert_se(dbus_message_iter_init(m, &iter));
- dbus_message_iter_recurse(&iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *s;
-
- assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
- dbus_message_iter_get_basic(&sub, &s);
-
- if (!(l[i++] = strdup(s))) {
- strv_free(l);
- return -ENOMEM;
- }
-
- dbus_message_iter_next(&sub);
- }
-
- assert(i == n);
- l[i] = NULL;
-
- if (_l)
- *_l = l;
-
- return 0;
-}
-
bool bus_has_subscriber(Manager *m) {
Iterator i;
DBusConnection *c;
diff --git a/src/dbus.h b/src/dbus.h
index 8387ffaa72..c47e782692 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -38,8 +38,6 @@ int bus_query_pid(Manager *m, const char *name);
int bus_broadcast(Manager *m, DBusMessage *message);
-int bus_parse_strv(DBusMessage *m, char ***_l);
-
bool bus_has_subscriber(Manager *m);
bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
diff --git a/src/service.c b/src/service.c
index 1f748688e2..62027f3a2e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -280,10 +280,10 @@ static int sysv_translate_facility(const char *name, const char *filename, char
/* LSB defined facilities */
"local_fs", SPECIAL_LOCAL_FS_TARGET,
#ifndef TARGET_MANDRIVA
- /* Due to unfortunate name selection in Mandriva,
- * $network is provided by network-up which is ordered
- * after network which actually starts interfaces.
- * To break the loop, just ignore it */
+ /* Due to unfortunate name selection in Mandriva,
+ * $network is provided by network-up which is ordered
+ * after network which actually starts interfaces.
+ * To break the loop, just ignore it */
"network", SPECIAL_NETWORK_TARGET,
#endif
"named", SPECIAL_NSS_LOOKUP_TARGET,
diff --git a/src/util.c b/src/util.c
index b291e2f729..81d247ca46 100644
--- a/src/util.c
+++ b/src/util.c
@@ -4692,6 +4692,7 @@ int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
}
qsort(files, hashmap_size(fh), sizeof(char *), base_cmp);
+
finish:
strv_free(dirs);
hashmap_free(fh);