bus: update bus_map_all_properties()
This commit is contained in:
parent
9b07511d65
commit
9f6eb1cd58
|
@ -142,12 +142,12 @@ static int show_one_name(sd_bus *bus, const char* attr) {
|
|||
|
||||
static int show_all_names(sd_bus *bus) {
|
||||
StatusInfo info = {};
|
||||
const struct bus_properties_map map[] = {
|
||||
{ "s", "Hostname", &info.hostname },
|
||||
{ "s", "StaticHostname", &info.static_hostname },
|
||||
{ "s", "PrettyHostname", &info.pretty_hostname },
|
||||
{ "s", "IconName", &info.icon_name },
|
||||
{ "s", "Chassis", &info.chassis },
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Hostname", "s", NULL, offsetof(StatusInfo, hostname) },
|
||||
{ "StaticHostname", "s", NULL, offsetof(StatusInfo, static_hostname) },
|
||||
{ "PrettyHostname", "s", NULL, offsetof(StatusInfo, pretty_hostname) },
|
||||
{ "IconName", "s", NULL, offsetof(StatusInfo, icon_name) },
|
||||
{ "Chassis", "s", NULL, offsetof(StatusInfo, chassis) },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
@ -155,7 +155,8 @@ static int show_all_names(sd_bus *bus) {
|
|||
r = bus_map_all_properties(bus,
|
||||
"org.freedesktop.hostname1",
|
||||
"/org/freedesktop/hostname1",
|
||||
map);
|
||||
map,
|
||||
&info);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -440,20 +440,26 @@ int bus_open_system_systemd(sd_bus **_bus) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bus_generic_print_property(const char *name, sd_bus_message *property, bool all) {
|
||||
int bus_print_property(const char *name, sd_bus_message *property, bool all) {
|
||||
char type;
|
||||
const char *contents;
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(property);
|
||||
|
||||
sd_bus_message_peek_type(property, &type, &contents);
|
||||
r = sd_bus_message_peek_type(property, &type, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SD_BUS_TYPE_STRING: {
|
||||
const char *s;
|
||||
sd_bus_message_read_basic(property, type, &s);
|
||||
|
||||
r = sd_bus_message_read_basic(property, type, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (all || !isempty(s))
|
||||
printf("%s=%s\n", name, s);
|
||||
|
@ -464,7 +470,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
case SD_BUS_TYPE_BOOLEAN: {
|
||||
bool b;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &b);
|
||||
r = sd_bus_message_read_basic(property, type, &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s=%s\n", name, yes_no(b));
|
||||
|
||||
return 1;
|
||||
|
@ -473,7 +482,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
case SD_BUS_TYPE_UINT64: {
|
||||
uint64_t u;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &u);
|
||||
r = sd_bus_message_read_basic(property, type, &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Yes, heuristics! But we can change this check
|
||||
* should it turn out to not be sufficient */
|
||||
|
@ -498,7 +509,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
case SD_BUS_TYPE_UINT32: {
|
||||
uint32_t u;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &u);
|
||||
r = sd_bus_message_read_basic(property, type, &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (strstr(name, "UMask") || strstr(name, "Mode"))
|
||||
printf("%s=%04o\n", name, u);
|
||||
|
@ -511,7 +524,9 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
case SD_BUS_TYPE_INT32: {
|
||||
int32_t i;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &i);
|
||||
r = sd_bus_message_read_basic(property, type, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s=%i\n", name, (int) i);
|
||||
return 1;
|
||||
|
@ -520,38 +535,47 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
case SD_BUS_TYPE_DOUBLE: {
|
||||
double d;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &d);
|
||||
r = sd_bus_message_read_basic(property, type, &d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s=%g\n", name, d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_ARRAY:
|
||||
|
||||
if (streq(contents, "s")) {
|
||||
bool space = false;
|
||||
char tp;
|
||||
const char *cnt;
|
||||
|
||||
sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
|
||||
r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_peek_type(property, &tp, &cnt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sd_bus_message_peek_type(property, &tp, &cnt);
|
||||
if (all || cnt) {
|
||||
const char *str;
|
||||
|
||||
printf("%s=", name);
|
||||
|
||||
|
||||
while(sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str) > 0) {
|
||||
while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) >= 0) {
|
||||
printf("%s%s", space ? " " : "", str);
|
||||
|
||||
space = true;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
puts("");
|
||||
}
|
||||
|
||||
sd_bus_message_exit_container(property);
|
||||
r = sd_bus_message_exit_container(property);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1;
|
||||
|
||||
|
@ -559,7 +583,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
const uint8_t *u;
|
||||
size_t n;
|
||||
|
||||
sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
|
||||
r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (all || n > 0) {
|
||||
unsigned int i;
|
||||
|
||||
|
@ -577,7 +604,10 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
uint32_t *u;
|
||||
size_t n;
|
||||
|
||||
sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
|
||||
r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (all || n > 0) {
|
||||
unsigned int i;
|
||||
|
||||
|
@ -598,14 +628,202 @@ int bus_generic_print_property(const char *name, sd_bus_message *property, bool
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bus_print_all_properties(sd_bus *bus, const char *path, char **filter, bool all) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
|
||||
r = sd_bus_call_method(bus,
|
||||
"org.freedesktop.machine1",
|
||||
path,
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"GetAll",
|
||||
&error,
|
||||
&reply,
|
||||
"s", "");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
|
||||
const char *name;
|
||||
const char *contents;
|
||||
|
||||
r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!filter || strv_find(filter, name)) {
|
||||
r = sd_bus_message_peek_type(reply, NULL, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_print_property(name, reply, all);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0 && all)
|
||||
printf("%s=[unprintable]\n", name);
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
r = sd_bus_message_skip(reply, "v");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
sd_id128_t *p = userdata;
|
||||
const void *v;
|
||||
size_t n;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (n == 0)
|
||||
*p = SD_ID128_NULL;
|
||||
else if (n == 16)
|
||||
memcpy((*p).bytes, v, n);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
|
||||
char type;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_peek_type(m, &type, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
switch (type) {
|
||||
case SD_BUS_TYPE_STRING: {
|
||||
const char *s;
|
||||
char *str;
|
||||
char **p = userdata;
|
||||
|
||||
r = sd_bus_message_read_basic(m, type, &s);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
if (isempty(s))
|
||||
break;
|
||||
|
||||
str = strdup(s);
|
||||
if (!str) {
|
||||
r = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
free(*p);
|
||||
*p = str;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_ARRAY: {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char ***p = userdata;
|
||||
|
||||
r = bus_message_read_strv_extend(m, &l);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
strv_free(*p);
|
||||
*p = l;
|
||||
l = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_BOOLEAN: {
|
||||
unsigned b;
|
||||
bool *p = userdata;
|
||||
|
||||
r = sd_bus_message_read_basic(m, type, &b);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
*p = b;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_UINT32: {
|
||||
uint64_t u;
|
||||
uint32_t *p = userdata;
|
||||
|
||||
r = sd_bus_message_read_basic(m, type, &u);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
*p = u;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_UINT64: {
|
||||
uint64_t t;
|
||||
uint64_t *p = userdata;
|
||||
|
||||
r = sd_bus_message_read_basic(m, type, &t);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
*p = t;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int bus_map_all_properties(sd_bus *bus,
|
||||
const char *destination,
|
||||
const char *path,
|
||||
const struct bus_properties_map *map) {
|
||||
const struct bus_properties_map *map,
|
||||
void *userdata) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(destination);
|
||||
assert(path);
|
||||
assert(map);
|
||||
|
||||
r = sd_bus_call_method( bus,
|
||||
destination,
|
||||
path,
|
||||
|
@ -614,144 +832,59 @@ int bus_map_all_properties(sd_bus *bus,
|
|||
&error,
|
||||
&m,
|
||||
"s", "");
|
||||
if (r < 0) {
|
||||
log_error("Could not get properties: %s", bus_error_message(&error, -r));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
|
||||
const char *name;
|
||||
char type;
|
||||
const struct bus_properties_map *prop;
|
||||
const char *member;
|
||||
const char *contents;
|
||||
void *v;
|
||||
unsigned i;
|
||||
|
||||
r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
|
||||
r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_peek_type(m, NULL, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_peek_type(m, &type, &contents);
|
||||
if (r < 0) {
|
||||
log_error("Could not determine type of message: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SD_BUS_TYPE_STRING: {
|
||||
const char *s;
|
||||
|
||||
sd_bus_message_read_basic(m, type, &s);
|
||||
if (isempty(s))
|
||||
for (i = 0, prop = NULL; map[i].member; i++)
|
||||
if (streq(map[i].member, member)) {
|
||||
prop = &map[i];
|
||||
break;
|
||||
|
||||
for (i = 0; map[i].type; i++) {
|
||||
char **p;
|
||||
|
||||
if (!streq(map[i].type, "s"))
|
||||
continue;
|
||||
if (!streq(map[i].name, name))
|
||||
continue;
|
||||
|
||||
p = map[i].ptr;
|
||||
free(*p);
|
||||
*p = strdup(s);
|
||||
if (!*p) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (prop) {
|
||||
r = sd_bus_message_peek_type(m, NULL, &contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
v = (uint8_t *)userdata + prop->offset;
|
||||
if (map[i].set)
|
||||
r = prop->set(bus, member, m, &error, v);
|
||||
else
|
||||
r = map_basic(bus, member, m, &error, v);
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return -r;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_ARRAY: {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
if (!streq(contents, "s"))
|
||||
break;
|
||||
|
||||
for (i = 0; map[i].type; i++) {
|
||||
char ***p;
|
||||
|
||||
if (!streq(map[i].type, "as"))
|
||||
continue;
|
||||
if (!streq(map[i].name, name))
|
||||
continue;
|
||||
|
||||
r = bus_message_read_strv_extend(m, &l);
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
p = map[i].ptr;
|
||||
strv_free(*p);
|
||||
*p = l;
|
||||
l = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_BOOLEAN: {
|
||||
unsigned b;
|
||||
|
||||
sd_bus_message_read_basic(m, type, &b);
|
||||
|
||||
for (i = 0; map[i].type; i++) {
|
||||
bool *p;
|
||||
|
||||
if (!streq(map[i].type, "b"))
|
||||
continue;
|
||||
if (!streq(map[i].name, name))
|
||||
continue;
|
||||
|
||||
p = map[i].ptr;
|
||||
*p = b;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_UINT64: {
|
||||
uint64_t t;
|
||||
|
||||
sd_bus_message_read_basic(m, type, &t);
|
||||
|
||||
for (i = 0; map[i].type; i++) {
|
||||
uint64_t *p;
|
||||
|
||||
if (!streq(map[i].type, "t"))
|
||||
continue;
|
||||
if (!streq(map[i].name, name))
|
||||
continue;
|
||||
|
||||
p = map[i].ptr;
|
||||
*p = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,16 +35,22 @@ typedef enum BusTransport {
|
|||
_BUS_TRANSPORT_INVALID = -1
|
||||
} BusTransport;
|
||||
|
||||
typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
|
||||
|
||||
struct bus_properties_map {
|
||||
const char *type;
|
||||
const char *name;
|
||||
void *ptr;
|
||||
const char *member;
|
||||
const char *signature;
|
||||
bus_property_set_t set;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
|
||||
|
||||
int bus_map_all_properties(sd_bus *bus,
|
||||
const char *destination,
|
||||
const char *path,
|
||||
const struct bus_properties_map *map);
|
||||
const struct bus_properties_map *map,
|
||||
void *userdata);
|
||||
|
||||
int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name);
|
||||
|
||||
|
@ -60,7 +66,8 @@ int bus_open_system_systemd(sd_bus **_bus);
|
|||
|
||||
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
|
||||
|
||||
int bus_generic_print_property(const char *name, sd_bus_message *property, bool all);
|
||||
int bus_print_property(const char *name, sd_bus_message *property, bool all);
|
||||
int bus_print_all_properties(sd_bus *bus, const char *path, char **filter, bool all);
|
||||
|
||||
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
|
||||
int bus_property_get_uid(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
|
||||
|
|
|
@ -104,15 +104,15 @@ static void print_status_info(StatusInfo *i) {
|
|||
|
||||
static int show_status(sd_bus *bus, char **args, unsigned n) {
|
||||
StatusInfo info = {};
|
||||
const struct bus_properties_map map[] = {
|
||||
{ "s", "VConsoleKeymap", &info.vconsole_keymap },
|
||||
{ "s", "VConsoleKeymap", &info.vconsole_keymap },
|
||||
{ "s", "VConsoleKeymapToggle", &info.vconsole_keymap_toggle},
|
||||
{ "s", "X11Layout", &info.x11_layout },
|
||||
{ "s", "X11Model", &info.x11_model },
|
||||
{ "s", "X11Variant", &info.x11_variant },
|
||||
{ "s", "X11Options", &info.x11_options },
|
||||
{ "as", "Locale", &info.locale },
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "VConsoleKeymap", "s", NULL, offsetof(StatusInfo, vconsole_keymap) },
|
||||
{ "VConsoleKeymap", "s", NULL, offsetof(StatusInfo, vconsole_keymap) },
|
||||
{ "VConsoleKeymapToggle", "s", NULL, offsetof(StatusInfo, vconsole_keymap_toggle) },
|
||||
{ "X11Layout", "s", NULL, offsetof(StatusInfo, x11_layout) },
|
||||
{ "X11Model", "s", NULL, offsetof(StatusInfo, x11_model) },
|
||||
{ "X11Variant", "s", NULL, offsetof(StatusInfo, x11_variant) },
|
||||
{ "X11Options", "s", NULL, offsetof(StatusInfo, x11_options) },
|
||||
{ "Locale", "as", NULL, offsetof(StatusInfo, locale) },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
@ -122,7 +122,8 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
|
|||
r = bus_map_all_properties(bus,
|
||||
"org.freedesktop.locale1",
|
||||
"/org/freedesktop/locale1",
|
||||
map);
|
||||
map,
|
||||
&info);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -172,12 +172,12 @@ static int show_scope_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
|
|||
}
|
||||
|
||||
typedef struct MachineStatusInfo {
|
||||
const char *name;
|
||||
char *name;
|
||||
sd_id128_t id;
|
||||
const char *class;
|
||||
const char *service;
|
||||
const char *scope;
|
||||
const char *root_directory;
|
||||
char *class;
|
||||
char *service;
|
||||
char *scope;
|
||||
char *root_directory;
|
||||
pid_t leader;
|
||||
usec_t timestamp;
|
||||
} MachineStatusInfo;
|
||||
|
@ -233,201 +233,87 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
|
|||
}
|
||||
}
|
||||
|
||||
static int status_property_machine(const char *name, sd_bus_message *property, MachineStatusInfo *i) {
|
||||
char type;
|
||||
const char *contents;
|
||||
static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
|
||||
MachineStatusInfo info = {};
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
|
||||
{ "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
|
||||
{ "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
|
||||
{ "Scope", "s", NULL, offsetof(MachineStatusInfo, scope) },
|
||||
{ "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
|
||||
{ "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
|
||||
{ "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
|
||||
{ "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(property);
|
||||
assert(i);
|
||||
|
||||
r = sd_bus_message_peek_type(property, &type, &contents);
|
||||
if (r < 0) {
|
||||
log_error("Could not determine type of message: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SD_BUS_TYPE_STRING: {
|
||||
const char *s;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &s);
|
||||
|
||||
if (!isempty(s)) {
|
||||
if (streq(name, "Name"))
|
||||
i->name = s;
|
||||
else if (streq(name, "Class"))
|
||||
i->class = s;
|
||||
else if (streq(name, "Service"))
|
||||
i->service = s;
|
||||
else if (streq(name, "Scope"))
|
||||
i->scope = s;
|
||||
else if (streq(name, "RootDirectory"))
|
||||
i->root_directory = s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_UINT32: {
|
||||
uint32_t u;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &u);
|
||||
|
||||
if (streq(name, "Leader"))
|
||||
i->leader = (pid_t) u;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_UINT64: {
|
||||
uint64_t u;
|
||||
|
||||
sd_bus_message_read_basic(property, type, &u);
|
||||
|
||||
if (streq(name, "Timestamp"))
|
||||
i->timestamp = (usec_t) u;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SD_BUS_TYPE_ARRAY: {
|
||||
if (streq(contents, "y") && streq(name, "Id")) {
|
||||
const void *v;
|
||||
size_t n;
|
||||
|
||||
sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, &v, &n);
|
||||
if (n == 0)
|
||||
i->id = SD_ID128_NULL;
|
||||
else if (n == 16)
|
||||
memcpy(&i->id, v, n);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_property(const char *name, sd_bus_message *reply) {
|
||||
assert(name);
|
||||
assert(reply);
|
||||
|
||||
if (arg_property && !strv_find(arg_property, name))
|
||||
return 0;
|
||||
|
||||
if (bus_generic_print_property(name, reply, arg_all) > 0)
|
||||
return 0;
|
||||
|
||||
if (arg_all)
|
||||
printf("%s=[unprintable]\n", name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_one(const char *verb, sd_bus *bus, const char *path, bool show_properties, bool *new_line) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
MachineStatusInfo machine_info = {};
|
||||
|
||||
assert(path);
|
||||
assert(new_line);
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.machine1",
|
||||
path,
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"GetAll",
|
||||
&error,
|
||||
&reply,
|
||||
"s", "");
|
||||
r = bus_map_all_properties(bus,
|
||||
"org.freedesktop.machine1",
|
||||
path,
|
||||
map,
|
||||
&info);
|
||||
if (r < 0) {
|
||||
log_error("Could not get properties: %s", bus_error_message(&error, -r));
|
||||
log_error("Could not get properties: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (*new_line)
|
||||
printf("\n");
|
||||
*new_line = true;
|
||||
|
||||
print_machine_status_info(bus, &info);
|
||||
|
||||
free(info.name);
|
||||
free(info.class);
|
||||
free(info.service);
|
||||
free(info.scope);
|
||||
free(info.root_directory);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
|
||||
int r;
|
||||
|
||||
if (*new_line)
|
||||
printf("\n");
|
||||
|
||||
*new_line = true;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
|
||||
r = bus_print_all_properties(bus, path, arg_property, arg_all);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
log_error("Could not get properties: %s", strerror(-r));
|
||||
|
||||
while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
|
||||
const char *name;
|
||||
const char *contents;
|
||||
|
||||
r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_bus_message_peek_type(reply, NULL, &contents);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (show_properties)
|
||||
r = print_property(name, reply);
|
||||
else
|
||||
r = status_property_machine(name, reply, &machine_info);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!show_properties)
|
||||
print_machine_status_info(bus, &machine_info);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
log_error("Failed to parse reply: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int show(sd_bus *bus, char **args, unsigned n) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r, ret = 0;
|
||||
int r = 0;
|
||||
unsigned i;
|
||||
bool show_properties, new_line = false;
|
||||
bool properties, new_line = false;
|
||||
|
||||
assert(bus);
|
||||
assert(args);
|
||||
|
||||
show_properties = !strstr(args[0], "status");
|
||||
properties = !strstr(args[0], "status");
|
||||
|
||||
pager_open_if_enabled();
|
||||
|
||||
if (show_properties && n <= 1) {
|
||||
if (properties && n <= 1) {
|
||||
|
||||
/* If no argument is specified inspect the manager
|
||||
/* If no argument is specified, inspect the manager
|
||||
* itself */
|
||||
|
||||
return show_one(args[0], bus, "/org/freedesktop/machine1", show_properties, &new_line);
|
||||
r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
|
||||
if (r < 0) {
|
||||
log_error("Failed to query properties: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
|
@ -450,15 +336,16 @@ static int show(sd_bus *bus, char **args, unsigned n) {
|
|||
r = sd_bus_message_read(reply, "o", &path);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse reply: %s", strerror(-r));
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
|
||||
r = show_one(args[0], bus, path, show_properties, &new_line);
|
||||
if (r != 0)
|
||||
ret = r;
|
||||
if (properties)
|
||||
r = show_properties(bus, path, &new_line);
|
||||
else
|
||||
r = show_info(args[0], bus, path, &new_line);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kill_machine(sd_bus *bus, char **args, unsigned n) {
|
||||
|
|
|
@ -193,14 +193,14 @@ static void print_status_info(const StatusInfo *i) {
|
|||
static int show_status(sd_bus *bus, char **args, unsigned n) {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
StatusInfo info = {};
|
||||
const struct bus_properties_map map[] = {
|
||||
{ "s", "Timezone", &info.timezone },
|
||||
{ "b", "LocalRTC", &info.rtc_local },
|
||||
{ "b", "NTP", &info.ntp_enabled },
|
||||
{ "b", "CanNTP", &info.ntp_capable },
|
||||
{ "b", "NTPSynchronized", &info.ntp_synced},
|
||||
{ "t", "TimeUSec", &info.time },
|
||||
{ "t", "RTCTimeUSec", &info.rtc_time },
|
||||
static const struct bus_properties_map map[] = {
|
||||
{ "Timezone", "s", NULL, offsetof(StatusInfo, timezone) },
|
||||
{ "LocalRTC", "b", NULL, offsetof(StatusInfo, rtc_local) },
|
||||
{ "NTP", "b", NULL, offsetof(StatusInfo, ntp_enabled) },
|
||||
{ "CanNTP", "b", NULL, offsetof(StatusInfo, ntp_capable) },
|
||||
{ "NTPSynchronized", "b", NULL, offsetof(StatusInfo, ntp_synced) },
|
||||
{ "TimeUSec", "t", NULL, offsetof(StatusInfo, time) },
|
||||
{ "RTCTimeUSec", "t", NULL, offsetof(StatusInfo, rtc_time) },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
@ -210,7 +210,8 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
|
|||
r = bus_map_all_properties(bus,
|
||||
"org.freedesktop.timedate1",
|
||||
"/org/freedesktop/timedate1",
|
||||
map);
|
||||
map,
|
||||
&info);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
|
Loading…
Reference in a new issue