diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dbus-common.c | 59 | ||||
-rw-r--r-- | src/dbus-common.h | 3 | ||||
-rw-r--r-- | src/dbus-manager.c | 56 | ||||
-rw-r--r-- | src/dbus.c | 49 | ||||
-rw-r--r-- | src/dbus.h | 2 | ||||
-rw-r--r-- | src/service.c | 8 | ||||
-rw-r--r-- | src/util.c | 1 |
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); |