diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2012-01-04 17:44:23 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2012-01-04 17:44:23 +0000 |
commit | 5df8c3db12590edd68e968975a335da9d0415e5a (patch) | |
tree | df1452c78f549722ccc8d8c3b1b7ac047a494681 /tools | |
parent | 5ec835dac93a084ff5f697a9b83b640689462e00 (diff) | |
download | dbus-5df8c3db12590edd68e968975a335da9d0415e5a.tar.gz |
Revert all changes since a36d4918a6f646e085
Someone seems to have merged part of master into 1.4. Again. Let's go
back to the "last known good" point (the branch-point of some 1.4
branches I had locally), then we can cherry-pick the changes that
should have gone in.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile.am | 45 | ||||
-rw-r--r-- | tools/dbus-monitor.c | 45 | ||||
-rw-r--r-- | tools/dbus-viewer.c | 617 |
3 files changed, 647 insertions, 60 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am index 08b90234..ce88c85f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,28 +1,14 @@ configdir=$(sysconfdir)/dbus-1 -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(DBUS_X_CFLAGS) \ - -DDBUS_COMPILATION \ - -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" \ - $(NULL) - -# if assertions are enabled, improve backtraces -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ - -bin_PROGRAMS = \ - dbus-launch \ - dbus-monitor \ - dbus-send \ - $(NULL) +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" +extra_bin_programs= if DBUS_UNIX -bin_PROGRAMS += \ - dbus-cleanup-sockets \ - dbus-uuidgen \ - $(NULL) +extra_bin_programs += dbus-cleanup-sockets dbus-uuidgen endif +bin_PROGRAMS=dbus-launch dbus-send dbus-monitor $(extra_bin_programs) + dbus_send_SOURCES= \ dbus-print-message.c \ dbus-print-message.h \ @@ -50,22 +36,17 @@ dbus_cleanup_sockets_SOURCES= \ dbus_uuidgen_SOURCES= \ dbus-uuidgen.c -dbus_send_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NULL) +dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_send_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_monitor_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NETWORK_libs) \ - $(NULL) +dbus_monitor_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_monitor_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_uuidgen_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NULL) +dbus_uuidgen_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_uuidgen_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_launch_LDADD = \ - $(DBUS_X_LIBS) \ - $(NULL) +dbus_launch_LDADD= $(DBUS_X_LIBS) $(DBUS_CLIENT_LIBS) +dbus_launch_LDFLAGS=@R_DYNAMIC_LDFLAG@ EXTRA_DIST = run-with-tmp-session-bus.sh strtoll.c strtoull.c CLEANFILES = \ diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c index a4b54782..5edb5c0b 100644 --- a/tools/dbus-monitor.c +++ b/tools/dbus-monitor.c @@ -35,8 +35,6 @@ #include "dbus-print-message.h" -#define EAVESDROPPING_RULE "eavesdrop=true" - #ifdef DBUS_WIN /* gettimeofday is not defined on windows */ @@ -78,13 +76,6 @@ gettimeofday (struct timeval *__p, } #endif -inline static void -oom (const char *doing) -{ - fprintf (stderr, "OOM while %s\n", doing); - exit (1); -} - static DBusHandlerResult monitor_filter_func (DBusConnection *connection, DBusMessage *message, @@ -239,6 +230,14 @@ only_one_type (dbus_bool_t *seen_bus_type, } } +static dbus_bool_t sigint_received = FALSE; + +static void +sigint_handler (int signum) +{ + sigint_received = TRUE; +} + int main (int argc, char *argv[]) { @@ -300,21 +299,11 @@ main (int argc, char *argv[]) else if (arg[0] == '-') usage (argv[0], 1); else { - unsigned int filter_len; - numFilters++; - /* Prepend a rule (and a comma) to enable the monitor to eavesdrop. - * Prepending allows the user to add eavesdrop=false at command line - * in order to disable eavesdropping when needed */ - filter_len = strlen (EAVESDROPPING_RULE) + 1 + strlen (arg) + 1; - - filters = (char **) realloc (filters, numFilters * sizeof (char *)); - if (filters == NULL) - oom ("adding a new filter slot"); - filters[j] = (char *) malloc (filter_len * sizeof (char *)); - if (filters[j] == NULL) - oom ("adding a new filter"); - snprintf (filters[j], filter_len, "%s,%s", EAVESDROPPING_RULE, arg); - j++; + numFilters++; + filters = (char **)realloc(filters, numFilters * sizeof(char *)); + filters[j] = (char *)malloc((strlen(arg) + 1) * sizeof(char *)); + snprintf(filters[j], strlen(arg) + 1, "%s", arg); + j++; } } @@ -380,22 +369,22 @@ main (int argc, char *argv[]) else { dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='signal'", + "type='signal'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='method_call'", + "type='method_call'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='method_return'", + "type='method_return'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='error'", + "type='error'", &error); if (dbus_error_is_set (&error)) goto lose; diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c new file mode 100644 index 00000000..2fd28474 --- /dev/null +++ b/tools/dbus-viewer.c @@ -0,0 +1,617 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-viewer.c Graphical D-Bus frontend utility + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include <config.h> +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <gtk/gtk.h> +#include "dbus-tree-view.h" +#include "dbus-names-model.h" +#include <glib/dbus-gparser.h> +#include <glib/dbus-gutils.h> +#include <dbus/dbus-glib.h> +#include <glib/gi18n.h> + +static void +show_error_dialog (GtkWindow *transient_parent, + GtkWidget **weak_ptr, + const char *message_format, + ...) +{ + char *message; + va_list args; + + if (message_format) + { + va_start (args, message_format); + message = g_strdup_vprintf (message_format, args); + va_end (args); + } + else + message = NULL; + + if (weak_ptr == NULL || *weak_ptr == NULL) + { + GtkWidget *dialog; + dialog = gtk_message_dialog_new (transient_parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + message); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); + + if (weak_ptr != NULL) + { + *weak_ptr = dialog; + g_object_add_weak_pointer (G_OBJECT (dialog), (void**)weak_ptr); + } + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + gtk_widget_show_all (dialog); + } + else + { + g_return_if_fail (GTK_IS_MESSAGE_DIALOG (*weak_ptr)); + + gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (*weak_ptr)->label), message); + + gtk_window_present (GTK_WINDOW (*weak_ptr)); + } +} + +typedef struct +{ + DBusGConnection *connection; + + GtkWidget *window; + GtkWidget *treeview; + GtkWidget *name_menu; + + GtkTreeModel *names_model; + + GtkWidget *error_dialog; + +} TreeWindow; + + +static void +tree_window_set_node (TreeWindow *w, + NodeInfo *node) +{ + char **path; + const char *name; + + name = node_info_get_name (node); + if (name == NULL || + name[0] != '/') + { + g_printerr (_("Assuming root node is at path /, since no absolute path is specified")); + name = "/"; + } + + path = _dbus_gutils_split_path (name); + + dbus_tree_view_update (GTK_TREE_VIEW (w->treeview), + (const char**) path, + node); + + g_strfreev (path); +} + +typedef struct +{ + DBusGConnection *connection; + char *service_name; + GError *error; + NodeInfo *node; + TreeWindow *window; /* Not touched from child thread */ +} LoadFromServiceData; + +static gboolean +load_child_nodes (const char *service_name, + NodeInfo *parent, + GString *path, + GError **error) +{ + DBusGConnection *connection; + GSList *tmp; + + connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); + if (connection == NULL) + return FALSE; + + tmp = node_info_get_nodes (parent); + while (tmp != NULL) + { + DBusGProxy *proxy; + char *data; + NodeInfo *child; + NodeInfo *complete_child; + int save_len; + + complete_child = NULL; + + child = tmp->data; + + save_len = path->len; + + if (save_len > 1) + g_string_append (path, "/"); + g_string_append (path, base_info_get_name ((BaseInfo*)child)); + + if (*service_name == ':') + { + proxy = dbus_g_proxy_new_for_name (connection, + service_name, + path->str, + DBUS_INTERFACE_INTROSPECTABLE); + g_assert (proxy != NULL); + } + else + { + proxy = dbus_g_proxy_new_for_name_owner (connection, + service_name, + path->str, + DBUS_INTERFACE_INTROSPECTABLE, + error); + if (proxy == NULL) + goto done; + } + + if (!dbus_g_proxy_call (proxy, "Introspect", error, + G_TYPE_INVALID, + G_TYPE_STRING, &data, + G_TYPE_INVALID)) + goto done; + + complete_child = description_load_from_string (data, -1, error); + g_free (data); + if (complete_child == NULL) + { + g_printerr ("%s\n", data); + goto done; + } + + done: + g_object_unref (proxy); + + if (complete_child == NULL) + return FALSE; + + /* change complete_child's name to relative */ + base_info_set_name ((BaseInfo*)complete_child, + base_info_get_name ((BaseInfo*)child)); + + /* Stitch in complete_child rather than child */ + node_info_replace_node (parent, child, complete_child); + node_info_unref (complete_child); /* ref still held by parent */ + + /* Now recurse */ + if (!load_child_nodes (service_name, complete_child, path, error)) + return FALSE; + + /* restore path */ + g_string_set_size (path, save_len); + + tmp = tmp->next; + } + + return TRUE; +} + +static gboolean +load_from_service_complete_idle (void *data) +{ + /* Called in main thread */ + GThread *thread = data; + LoadFromServiceData *d; + NodeInfo *node; + + d = g_thread_join (thread); + + node = d->node; + + if (d->error) + { + g_assert (d->node == NULL); + show_error_dialog (GTK_WINDOW (d->window->window), &d->window->error_dialog, + _("Unable to load \"%s\": %s\n"), + d->service_name, d->error->message); + g_error_free (d->error); + } + else + { + g_assert (d->error == NULL); + + tree_window_set_node (d->window, node); + node_info_unref (node); + } + + g_free (d->service_name); + dbus_g_connection_unref (d->connection); + g_free (d); + + return FALSE; +} + +static void* +load_from_service_thread_func (void *thread_data) +{ + DBusGProxy *root_proxy; + const char *data; + NodeInfo *node; + GString *path; + LoadFromServiceData *lfsd; + + lfsd = thread_data; + + node = NULL; + path = NULL; + +#if 1 + /* this will end up autolaunching the service when we introspect it */ + root_proxy = dbus_g_proxy_new_for_name (lfsd->connection, + lfsd->service_name, + "/", + DBUS_INTERFACE_INTROSPECTABLE); + g_assert (root_proxy != NULL); +#else + /* this will be an error if the service doesn't exist */ + root_proxy = dbus_g_proxy_new_for_name_owner (lfsd->connection, + lfsd->service_name, + "/", + DBUS_INTERFACE_INTROSPECTABLE, + &lfsd->error); + if (root_proxy == NULL) + { + g_printerr ("Failed to get owner of '%s'\n", lfsd->service_name); + return lfsd->data; + } +#endif + + if (!dbus_g_proxy_call (root_proxy, "Introspect", &lfsd->error, + G_TYPE_INVALID, + G_TYPE_STRING, &data, + G_TYPE_INVALID)) + { + g_printerr ("Failed to Introspect() %s\n", + dbus_g_proxy_get_bus_name (root_proxy)); + goto out; + } + + node = description_load_from_string (data, -1, &lfsd->error); + + /* g_print ("%s\n", data); */ + + if (node == NULL) + goto out; + + base_info_set_name ((BaseInfo*)node, "/"); + + path = g_string_new ("/"); + + if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy), + node, path, &lfsd->error)) + { + node_info_unref (node); + node = NULL; + goto out; + } + + out: + g_object_unref (root_proxy); + + if (path) + g_string_free (path, TRUE); + + lfsd->node = node; + g_assert (lfsd->node || lfsd->error); + g_assert (lfsd->node == NULL || lfsd->error == NULL); + + /* Add idle to main thread that will join us back */ + g_idle_add (load_from_service_complete_idle, g_thread_self ()); + + return lfsd; +} + +static void +start_load_from_service (TreeWindow *w, + DBusGConnection *connection, + const char *service_name) +{ + LoadFromServiceData *d; + + d = g_new0 (LoadFromServiceData, 1); + + d->connection = dbus_g_connection_ref (connection); + d->service_name = g_strdup (service_name); + d->error = NULL; + d->node = NULL; + d->window = w; + + g_thread_create (load_from_service_thread_func, d, TRUE, NULL); +} + +static void +tree_window_set_service (TreeWindow *w, + const char *service_name) +{ + start_load_from_service (w, w->connection, service_name); +} + +static void +name_combo_changed_callback (GtkComboBox *combo, + TreeWindow *w) +{ + GtkTreeIter iter; + + if (gtk_combo_box_get_active_iter (combo, &iter)) + { + GtkTreeModel *model; + char *text; + + model = gtk_combo_box_get_model (combo); + gtk_tree_model_get (model, &iter, 0, &text, -1); + + if (text) + { + tree_window_set_service (w, text); + g_free (text); + } + } +} + +static void +window_closed_callback (GtkWidget *window, + TreeWindow *w) +{ + g_assert (window == w->window); + w->window = NULL; + gtk_main_quit (); +} + +static TreeWindow* +tree_window_new (DBusGConnection *connection, + GtkTreeModel *names_model) +{ + TreeWindow *w; + GtkWidget *sw; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *combo; + + /* Should use glade, blah */ + + w = g_new0 (TreeWindow, 1); + w->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title (GTK_WINDOW (w->window), "D-Bus Viewer"); + gtk_window_set_default_size (GTK_WINDOW (w->window), 400, 500); + + g_signal_connect (w->window, "destroy", G_CALLBACK (window_closed_callback), + w); + gtk_container_set_border_width (GTK_CONTAINER (w->window), 6); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (w->window), vbox); + + /* Create names option menu */ + if (connection) + { + GtkCellRenderer *cell; + + w->connection = connection; + + w->names_model = names_model; + + combo = gtk_combo_box_new_with_model (w->names_model); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, + "text", 0, + NULL); + + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); + + g_signal_connect (combo, "changed", + G_CALLBACK (name_combo_changed_callback), + w); + } + + /* Create tree view */ + hbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0); + + w->treeview = dbus_tree_view_new (); + + gtk_container_add (GTK_CONTAINER (sw), w->treeview); + + /* Show everything */ + gtk_widget_show_all (w->window); + + return w; +} + +static void +usage (int ecode) +{ + fprintf (stderr, "dbus-viewer [--version] [--help]\n"); + exit (ecode); +} + +static void +version (void) +{ + printf ("D-Bus Message Bus Viewer %s\n" + "Copyright (C) 2003 Red Hat, Inc.\n" + "This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", + VERSION); + exit (0); +} + +int +main (int argc, char **argv) +{ + int i; + GSList *files; + gboolean end_of_args; + GSList *tmp; + gboolean services; + DBusGConnection *connection; + GError *error; + GtkTreeModel *names_model; + + g_thread_init (NULL); + dbus_g_thread_init (); + + bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + gtk_init (&argc, &argv); + + services = FALSE; + end_of_args = FALSE; + files = NULL; + i = 1; + while (i < argc) + { + const char *arg = argv[i]; + + if (!end_of_args) + { + if (strcmp (arg, "--help") == 0 || + strcmp (arg, "-h") == 0 || + strcmp (arg, "-?") == 0) + usage (0); + else if (strcmp (arg, "--version") == 0) + version (); + else if (strcmp (arg, "--services") == 0) + services = TRUE; + else if (arg[0] == '-' && + arg[1] == '-' && + arg[2] == '\0') + end_of_args = TRUE; + else if (arg[0] == '-') + { + usage (1); + } + else + { + files = g_slist_prepend (files, (char*) arg); + } + } + else + files = g_slist_prepend (files, (char*) arg); + + ++i; + } + + if (services || files == NULL) + { + error = NULL; + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (connection == NULL) + { + g_printerr ("Could not open bus connection: %s\n", + error->message); + g_error_free (error); + exit (1); + } + + g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL)); + + names_model = names_model_new (connection); + } + else + { + connection = NULL; + names_model = NULL; + } + + if (files == NULL) + { + TreeWindow *w; + + w = tree_window_new (connection, names_model); + } + + files = g_slist_reverse (files); + + tmp = files; + while (tmp != NULL) + { + const char *filename; + TreeWindow *w; + + filename = tmp->data; + + if (services) + { + w = tree_window_new (connection, names_model); + tree_window_set_service (w, filename); + } + else + { + NodeInfo *node; + + error = NULL; + node = description_load_from_file (filename, + &error); + + if (node == NULL) + { + g_assert (error != NULL); + show_error_dialog (NULL, NULL, + _("Unable to load \"%s\": %s\n"), + filename, error->message); + g_error_free (error); + } + else + { + w = tree_window_new (connection, names_model); + tree_window_set_node (w, node); + node_info_unref (node); + } + } + + tmp = tmp->next; + } + + gtk_main (); + + return 0; +} + |