1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-monitor.c Utility program to monitor messages on the bus
4 * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "dbus-print-message.h"
33 static DBusHandlerResult
34 monitor_filter_func (DBusConnection *connection,
38 print_message (message, FALSE);
40 if (dbus_message_is_signal (message,
45 /* Conceptually we want this to be
46 * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
47 * some problems. See bug 1719.
49 return DBUS_HANDLER_RESULT_HANDLED;
52 #define PROFILE_TIMED_FORMAT "%s\t%lu\t%lu"
53 #define TRAP_NULL_STRING(str) ((str) ? (str) : "<none>")
57 PROFILE_ATTRIBUTE_FLAG_SERIAL = 1,
58 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL = 2,
59 PROFILE_ATTRIBUTE_FLAG_SENDER = 4,
60 PROFILE_ATTRIBUTE_FLAG_DESTINATION = 8,
61 PROFILE_ATTRIBUTE_FLAG_PATH = 16,
62 PROFILE_ATTRIBUTE_FLAG_INTERFACE = 32,
63 PROFILE_ATTRIBUTE_FLAG_MEMBER = 64,
64 PROFILE_ATTRIBUTE_FLAG_ERROR_NAME = 128,
65 } ProfileAttributeFlags;
68 profile_print_with_attrs (const char *type, DBusMessage *message,
69 struct timeval *t, ProfileAttributeFlags attrs)
71 printf (PROFILE_TIMED_FORMAT, type, t->tv_sec, t->tv_usec);
73 if (attrs & PROFILE_ATTRIBUTE_FLAG_SERIAL)
74 printf ("\t%u", dbus_message_get_serial (message));
76 if (attrs & PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL)
77 printf ("\t%u", dbus_message_get_reply_serial (message));
79 if (attrs & PROFILE_ATTRIBUTE_FLAG_SENDER)
80 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_sender (message)));
82 if (attrs & PROFILE_ATTRIBUTE_FLAG_DESTINATION)
83 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_destination (message)));
85 if (attrs & PROFILE_ATTRIBUTE_FLAG_PATH)
86 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_path (message)));
88 if (attrs & PROFILE_ATTRIBUTE_FLAG_INTERFACE)
89 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_interface (message)));
91 if (attrs & PROFILE_ATTRIBUTE_FLAG_MEMBER)
92 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_member (message)));
94 if (attrs & PROFILE_ATTRIBUTE_FLAG_ERROR_NAME)
95 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_error_name (message)));
101 print_message_profile (DBusMessage *message)
105 if (gettimeofday (&t, NULL) < 0)
111 switch (dbus_message_get_type (message))
113 case DBUS_MESSAGE_TYPE_METHOD_CALL:
114 profile_print_with_attrs ("mc", message, &t,
115 PROFILE_ATTRIBUTE_FLAG_SERIAL |
116 PROFILE_ATTRIBUTE_FLAG_SENDER |
117 PROFILE_ATTRIBUTE_FLAG_PATH |
118 PROFILE_ATTRIBUTE_FLAG_INTERFACE |
119 PROFILE_ATTRIBUTE_FLAG_MEMBER);
121 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
122 profile_print_with_attrs ("mr", message, &t,
123 PROFILE_ATTRIBUTE_FLAG_SERIAL |
124 PROFILE_ATTRIBUTE_FLAG_DESTINATION |
125 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
127 case DBUS_MESSAGE_TYPE_ERROR:
128 profile_print_with_attrs ("err", message, &t,
129 PROFILE_ATTRIBUTE_FLAG_SERIAL |
130 PROFILE_ATTRIBUTE_FLAG_DESTINATION |
131 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
133 case DBUS_MESSAGE_TYPE_SIGNAL:
134 profile_print_with_attrs ("sig", message, &t,
135 PROFILE_ATTRIBUTE_FLAG_SERIAL |
136 PROFILE_ATTRIBUTE_FLAG_PATH |
137 PROFILE_ATTRIBUTE_FLAG_INTERFACE |
138 PROFILE_ATTRIBUTE_FLAG_MEMBER);
141 printf (PROFILE_TIMED_FORMAT "\n", "tun", t.tv_sec, t.tv_usec);
146 static DBusHandlerResult
147 profile_filter_func (DBusConnection *connection,
148 DBusMessage *message,
151 print_message_profile (message);
153 if (dbus_message_is_signal (message,
154 DBUS_INTERFACE_LOCAL,
158 return DBUS_HANDLER_RESULT_HANDLED;
162 usage (char *name, int ecode)
164 fprintf (stderr, "Usage: %s [--system | --session] [--monitor | --profile ] [watch expressions]\n", name);
168 dbus_bool_t sigint_received = FALSE;
171 sigint_handler (int signum)
173 sigint_received = TRUE;
177 main (int argc, char *argv[])
179 DBusConnection *connection;
181 DBusBusType type = DBUS_BUS_SESSION;
182 DBusHandleMessageFunction filter_func = monitor_filter_func;
184 int i = 0, j = 0, numFilters = 0;
185 char **filters = NULL;
186 for (i = 1; i < argc; i++)
190 if (!strcmp (arg, "--system"))
191 type = DBUS_BUS_SYSTEM;
192 else if (!strcmp (arg, "--session"))
193 type = DBUS_BUS_SESSION;
194 else if (!strcmp (arg, "--help"))
196 else if (!strcmp (arg, "--monitor"))
197 filter_func = monitor_filter_func;
198 else if (!strcmp (arg, "--profile"))
199 filter_func = profile_filter_func;
200 else if (!strcmp (arg, "--"))
202 else if (arg[0] == '-')
206 filters = (char **)realloc(filters, numFilters * sizeof(char *));
207 filters[j] = (char *)malloc((strlen(arg) + 1) * sizeof(char *));
208 snprintf(filters[j], strlen(arg) + 1, "%s", arg);
213 dbus_error_init (&error);
214 connection = dbus_bus_get (type, &error);
215 if (connection == NULL)
217 fprintf (stderr, "Failed to open connection to %s message bus: %s\n",
218 (type == DBUS_BUS_SYSTEM) ? "system" : "session",
220 dbus_error_free (&error);
226 for (i = 0; i < j; i++)
228 dbus_bus_add_match (connection, filters[i], &error);
229 if (dbus_error_is_set (&error))
231 fprintf (stderr, "Failed to setup match \"%s\": %s\n",
232 filters[i], error.message);
233 dbus_error_free (&error);
241 dbus_bus_add_match (connection,
244 if (dbus_error_is_set (&error))
246 dbus_bus_add_match (connection,
247 "type='method_call'",
249 if (dbus_error_is_set (&error))
251 dbus_bus_add_match (connection,
252 "type='method_return'",
254 if (dbus_error_is_set (&error))
256 dbus_bus_add_match (connection,
259 if (dbus_error_is_set (&error))
263 if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
264 fprintf (stderr, "Couldn't add filter!\n");
268 /* we handle SIGINT so exit() is reached and flushes stdout */
269 signal (SIGINT, sigint_handler);
270 while (dbus_connection_read_write_dispatch(connection, -1)
275 fprintf (stderr, "Error: %s\n", error.message);