]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-bus/busctl.c
tree-wide: expose "p"-suffix unref calls in public APIs to make gcc cleanup easy
[thirdparty/systemd.git] / src / libsystemd / sd-bus / busctl.c
index 39caa4e7d6f95a144fe9c6e8577bdf49ae121b6f..3e665894890cb49aacb692adeeefc76d505c0a82 100644 (file)
 
 #include <getopt.h>
 
-#include "strv.h"
-#include "util.h"
-#include "log.h"
-#include "build.h"
-#include "pager.h"
-#include "path-util.h"
-#include "set.h"
-
 #include "sd-bus.h"
-#include "bus-internal.h"
-#include "bus-util.h"
+
+#include "alloc-util.h"
 #include "bus-dump.h"
+#include "bus-internal.h"
 #include "bus-signature.h"
 #include "bus-type.h"
+#include "bus-util.h"
 #include "busctl-introspect.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "locale-util.h"
+#include "log.h"
+#include "pager.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "set.h"
+#include "strv.h"
 #include "terminal-util.h"
+#include "user-util.h"
+#include "util.h"
 
 static bool arg_no_pager = false;
 static bool arg_legend = true;
@@ -132,7 +137,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
         }
 
         STRV_FOREACH(i, merged) {
-                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 sd_id128_t mid;
 
                 if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) {
@@ -329,8 +334,8 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p
                 .on_path = on_path,
         };
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         const char *xml;
         int r;
 
@@ -449,7 +454,7 @@ static int tree(sd_bus *bus, char **argv) {
                         if (not_first)
                                 printf("\n");
 
-                        printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
+                        printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
 
                         q = tree_one(bus, *i, NULL, true);
                         if (q < 0 && r >= 0)
@@ -466,7 +471,7 @@ static int tree(sd_bus *bus, char **argv) {
 
                         if (argv[2]) {
                                 pager_open_if_enabled();
-                                printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
+                                printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
                         }
 
                         q = tree_one(bus, *i, NULL, !!argv[2]);
@@ -629,22 +634,24 @@ typedef struct Member {
         uint64_t flags;
 } Member;
 
-static unsigned long member_hash_func(const void *p, const uint8_t hash_key[]) {
+static void member_hash_func(const void *p, struct siphash *state) {
         const Member *m = p;
-        unsigned long ul;
+        uint64_t arity = 1;
 
         assert(m);
         assert(m->type);
 
-        ul = string_hash_func(m->type, hash_key);
+        string_hash_func(m->type, state);
+
+        arity += !!m->name + !!m->interface;
+
+        uint64_hash_func(&arity, state);
 
         if (m->name)
-                ul ^= string_hash_func(m->name, hash_key);
+                string_hash_func(m->name, state);
 
         if (m->interface)
-                ul ^= string_hash_func(m->interface, hash_key);
-
-        return ul;
+                string_hash_func(m->interface, state);
 }
 
 static int member_compare_func(const void *a, const void *b) {
@@ -656,28 +663,15 @@ static int member_compare_func(const void *a, const void *b) {
         assert(x->type);
         assert(y->type);
 
-        if (!x->interface && y->interface)
-                return -1;
-        if (x->interface && !y->interface)
-                return 1;
-        if (x->interface && y->interface) {
-                d = strcmp(x->interface, y->interface);
-                if (d != 0)
-                        return d;
-        }
+        d = strcmp_ptr(x->interface, y->interface);
+        if (d != 0)
+                return d;
 
         d = strcmp(x->type, y->type);
         if (d != 0)
                 return d;
 
-        if (!x->name && y->name)
-                return -1;
-        if (x->name && !y->name)
-                return 1;
-        if (x->name && y->name)
-                return strcmp(x->name, y->name);
-
-        return 0;
+        return strcmp_ptr(x->name, y->name);
 }
 
 static int member_compare_funcp(const void *a, const void *b) {
@@ -873,8 +867,8 @@ static int introspect(sd_bus *bus, char **argv) {
                 .on_property = on_property,
         };
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(member_set_freep) Set *members = NULL;
         Iterator i;
         Member *m;
@@ -1065,7 +1059,7 @@ static int introspect(sd_bus *bus, char **argv) {
                        is_interface ? ansi_highlight() : "",
                        is_interface ? "" : ".",
                        - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
-                       is_interface ? ansi_highlight_off() : "",
+                       is_interface ? ansi_normal() : "",
                        (int) type_width, strdash(m->type),
                        (int) signature_width, strdash(m->signature),
                        (int) result_width, rv,
@@ -1109,6 +1103,15 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
                 if (r < 0)
                         return log_error_errno(r, "Failed to add match: %m");
 
+                free(m);
+                m = strjoin("destination='", *i, "'", NULL);
+                if (!m)
+                        return log_oom();
+
+                r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to add match: %m");
+
                 added_something = true;
         }
 
@@ -1129,7 +1132,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
         log_info("Monitoring bus message stream.");
 
         for (;;) {
-                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
 
                 r = sd_bus_process(bus, &m);
                 if (r < 0)
@@ -1137,6 +1140,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
 
                 if (m) {
                         dump(m, stdout);
+                        fflush(stdout);
 
                         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
                                 log_info("Connection terminated, exiting.");
@@ -1178,7 +1182,7 @@ static int capture(sd_bus *bus, char *argv[]) {
 }
 
 static int status(sd_bus *bus, char *argv[]) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
         pid_t pid;
         int r;
 
@@ -1208,15 +1212,15 @@ static int status(sd_bus *bus, char *argv[]) {
 
                 r = sd_bus_get_address(bus, &address);
                 if (r >= 0)
-                        printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_highlight_off());
+                        printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_normal());
 
                 r = sd_bus_get_scope(bus, &scope);
                 if (r >= 0)
-                        printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_highlight_off());
+                        printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_normal());
 
                 r = sd_bus_get_bus_id(bus, &bus_id);
                 if (r >= 0)
-                        printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_highlight_off());
+                        printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_normal());
 
                 r = sd_bus_get_owner_creds(
                                 bus,
@@ -1485,8 +1489,8 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char
 }
 
 static int call(sd_bus *bus, char *argv[]) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
         int r;
 
         assert(bus);
@@ -1572,7 +1576,7 @@ static int call(sd_bus *bus, char *argv[]) {
 }
 
 static int get_property(sd_bus *bus, char *argv[]) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         unsigned n;
         char **i;
         int r;
@@ -1586,7 +1590,7 @@ static int get_property(sd_bus *bus, char *argv[]) {
         }
 
         STRV_FOREACH(i, argv + 4) {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
                 const char *contents = NULL;
                 char type;
 
@@ -1630,8 +1634,8 @@ static int get_property(sd_bus *bus, char *argv[]) {
 }
 
 static int set_property(sd_bus *bus, char *argv[]) {
-        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         unsigned n;
         char **p;
         int r;
@@ -1696,6 +1700,7 @@ static int help(void) {
                "     --acquired           Only show acquired names\n"
                "     --activatable        Only show activatable names\n"
                "     --match=MATCH        Only show matching messages\n"
+               "     --size=SIZE          Maximum length of captured packet\n"
                "     --list               Don't show tree, but simple object path list\n"
                "     --quiet              Don't show method call reply\n"
                "     --verbose            Show result values in long format\n"
@@ -1788,9 +1793,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return help();
 
                 case ARG_VERSION:
-                        puts(PACKAGE_STRING);
-                        puts(SYSTEMD_FEATURES);
-                        return 0;
+                        return version();
 
                 case ARG_NO_PAGER:
                         arg_no_pager = true;
@@ -1834,20 +1837,20 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_SIZE: {
-                        off_t o;
+                        uint64_t sz;
 
-                        r = parse_size(optarg, 0, &o);
+                        r = parse_size(optarg, 1024, &sz);
                         if (r < 0) {
                                 log_error("Failed to parse size: %s", optarg);
                                 return r;
                         }
 
-                        if ((off_t) (size_t) o !=  o) {
+                        if ((uint64_t) (size_t) sz !=  sz) {
                                 log_error("Size out of range.");
                                 return -E2BIG;
                         }
 
-                        arg_snaplen = (size_t) o;
+                        arg_snaplen = (size_t) sz;
                         break;
                 }
 
@@ -1973,7 +1976,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         log_parse_environment();
@@ -2017,15 +2020,15 @@ int main(int argc, char *argv[]) {
                 }
         }
 
+        r = sd_bus_set_bus_client(bus, true);
+        if (r < 0) {
+                log_error_errno(r, "Failed to set bus client: %m");
+                goto finish;
+        }
+
         if (arg_address)
                 r = sd_bus_set_address(bus, arg_address);
         else {
-                r = sd_bus_set_bus_client(bus, true);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to set bus client: %m");
-                        goto finish;
-                }
-
                 switch (arg_transport) {
 
                 case BUS_TRANSPORT_LOCAL: