dbus: introduce UnsetAndSetEnvironment()

This commit is contained in:
Lennart Poettering 2011-06-15 15:31:54 +02:00
parent 48f82119ce
commit 8d0e38a2b9
8 changed files with 127 additions and 59 deletions

8
TODO
View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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);