dbus: introduce UnsetAndSetEnvironment()
This commit is contained in:
parent
48f82119ce
commit
8d0e38a2b9
8
TODO
8
TODO
|
@ -27,6 +27,10 @@ Features:
|
|||
|
||||
* kernel: add device_type = "fb", "fbcon" to class "graphics"
|
||||
|
||||
* hostnamed: make file updates atomic
|
||||
|
||||
* support sd_notify() style notificatio when reload is finished (RELOADED=1)
|
||||
|
||||
* verify that the AF_UNIX sockets of a service in the fs still exist
|
||||
when we start a service in order to avoid confusion when a user
|
||||
assumes starting a service is enough to make it accessible
|
||||
|
@ -46,8 +50,6 @@ Features:
|
|||
|
||||
* move /selinux to /sys/fs/selinux
|
||||
|
||||
* unset cgroup agents on shutdown
|
||||
|
||||
* add prefix match to sysctl, tmpfiles, ...
|
||||
|
||||
* send out "finished" signal when we are finished booting
|
||||
|
@ -154,8 +156,6 @@ Features:
|
|||
|
||||
* Support --test based on current system state
|
||||
|
||||
* systemctl enable as D-Bus call
|
||||
|
||||
* consider services with any kind of link in /etc/systemd/system enabled
|
||||
|
||||
* show failure error string in "systemctl status"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
49
src/dbus.c
49
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue