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
32 #include "dbus-print-message.h"
34 static DBusHandlerResult
35 monitor_filter_func (DBusConnection *connection,
39 print_message (message, FALSE);
41 if (dbus_message_is_signal (message,
46 /* Conceptually we want this to be
47 * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
48 * some problems. See bug 1719.
50 return DBUS_HANDLER_RESULT_HANDLED;
53 #define PROFILE_TIMED_FORMAT "%s\t%lu\t%lu"
54 #define TRAP_NULL_STRING(str) ((str) ? (str) : "<none>")
58 PROFILE_ATTRIBUTE_FLAG_SERIAL = 1,
59 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL = 2,
60 PROFILE_ATTRIBUTE_FLAG_SENDER = 4,
61 PROFILE_ATTRIBUTE_FLAG_DESTINATION = 8,
62 PROFILE_ATTRIBUTE_FLAG_PATH = 16,
63 PROFILE_ATTRIBUTE_FLAG_INTERFACE = 32,
64 PROFILE_ATTRIBUTE_FLAG_MEMBER = 64,
65 PROFILE_ATTRIBUTE_FLAG_ERROR_NAME = 128,
66 } ProfileAttributeFlags;
69 profile_print_with_attrs (const char *type, DBusMessage *message,
70 struct timeval *t, ProfileAttributeFlags attrs)
72 printf (PROFILE_TIMED_FORMAT, type, t->tv_sec, t->tv_usec);
74 if (attrs & PROFILE_ATTRIBUTE_FLAG_SERIAL)
75 printf ("\t%u", dbus_message_get_serial (message));
77 if (attrs & PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL)
78 printf ("\t%u", dbus_message_get_reply_serial (message));
80 if (attrs & PROFILE_ATTRIBUTE_FLAG_SENDER)
81 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_sender (message)));
83 if (attrs & PROFILE_ATTRIBUTE_FLAG_DESTINATION)
84 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_destination (message)));
86 if (attrs & PROFILE_ATTRIBUTE_FLAG_PATH)
87 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_path (message)));
89 if (attrs & PROFILE_ATTRIBUTE_FLAG_INTERFACE)
90 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_interface (message)));
92 if (attrs & PROFILE_ATTRIBUTE_FLAG_MEMBER)
93 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_member (message)));
95 if (attrs & PROFILE_ATTRIBUTE_FLAG_ERROR_NAME)
96 printf ("\t%s", TRAP_NULL_STRING (dbus_message_get_error_name (message)));
102 print_message_profile (DBusMessage *message)
106 if (gettimeofday (&t, NULL) < 0)
112 switch (dbus_message_get_type (message))
114 case DBUS_MESSAGE_TYPE_METHOD_CALL:
115 profile_print_with_attrs ("mc", message, &t,
116 PROFILE_ATTRIBUTE_FLAG_SERIAL |
117 PROFILE_ATTRIBUTE_FLAG_SENDER |
118 PROFILE_ATTRIBUTE_FLAG_PATH |
119 PROFILE_ATTRIBUTE_FLAG_INTERFACE |
120 PROFILE_ATTRIBUTE_FLAG_MEMBER);
122 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
123 profile_print_with_attrs ("mr", message, &t,
124 PROFILE_ATTRIBUTE_FLAG_SERIAL |
125 PROFILE_ATTRIBUTE_FLAG_DESTINATION |
126 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
128 case DBUS_MESSAGE_TYPE_ERROR:
129 profile_print_with_attrs ("err", message, &t,
130 PROFILE_ATTRIBUTE_FLAG_SERIAL |
131 PROFILE_ATTRIBUTE_FLAG_DESTINATION |
132 PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
134 case DBUS_MESSAGE_TYPE_SIGNAL:
135 profile_print_with_attrs ("sig", message, &t,
136 PROFILE_ATTRIBUTE_FLAG_SERIAL |
137 PROFILE_ATTRIBUTE_FLAG_PATH |
138 PROFILE_ATTRIBUTE_FLAG_INTERFACE |
139 PROFILE_ATTRIBUTE_FLAG_MEMBER);
142 printf (PROFILE_TIMED_FORMAT "\n", "tun", t.tv_sec, t.tv_usec);
147 static DBusHandlerResult
148 profile_filter_func (DBusConnection *connection,
149 DBusMessage *message,
152 print_message_profile (message);
154 if (dbus_message_is_signal (message,
155 DBUS_INTERFACE_LOCAL,
159 return DBUS_HANDLER_RESULT_HANDLED;
163 usage (char *name, int ecode)
165 fprintf (stderr, "Usage: %s [--system | --session] [--monitor | --profile ] [watch expressions]\n", name);
169 dbus_bool_t sigint_received = FALSE;
172 sigint_handler (int signum)
174 sigint_received = TRUE;
178 main (int argc, char *argv[])
180 DBusConnection *connection;
182 DBusBusType type = DBUS_BUS_SESSION;
183 DBusHandleMessageFunction filter_func = monitor_filter_func;
185 int i = 0, j = 0, numFilters = 0;
186 char **filters = NULL;
187 for (i = 1; i < argc; i++)
191 if (!strcmp (arg, "--system"))
192 type = DBUS_BUS_SYSTEM;
193 else if (!strcmp (arg, "--session"))
194 type = DBUS_BUS_SESSION;
195 else if (!strcmp (arg, "--help"))
197 else if (!strcmp (arg, "--monitor"))
198 filter_func = monitor_filter_func;
199 else if (!strcmp (arg, "--profile"))
200 filter_func = profile_filter_func;
201 else if (!strcmp (arg, "--"))
203 else if (arg[0] == '-')
207 filters = (char **)realloc(filters, numFilters * sizeof(char *));
208 filters[j] = (char *)malloc((strlen(arg) + 1) * sizeof(char *));
209 snprintf(filters[j], strlen(arg) + 1, "%s", arg);
214 dbus_error_init (&error);
215 connection = dbus_bus_get (type, &error);
216 if (connection == NULL)
218 fprintf (stderr, "Failed to open connection to %s message bus: %s\n",
219 (type == DBUS_BUS_SYSTEM) ? "system" : "session",
221 dbus_error_free (&error);
227 for (i = 0; i < j; i++)
229 dbus_bus_add_match (connection, filters[i], &error);
230 if (dbus_error_is_set (&error))
232 fprintf (stderr, "Failed to setup match \"%s\": %s\n",
233 filters[i], error.message);
234 dbus_error_free (&error);
242 dbus_bus_add_match (connection,
245 if (dbus_error_is_set (&error))
247 dbus_bus_add_match (connection,
248 "type='method_call'",
250 if (dbus_error_is_set (&error))
252 dbus_bus_add_match (connection,
253 "type='method_return'",
255 if (dbus_error_is_set (&error))
257 dbus_bus_add_match (connection,
260 if (dbus_error_is_set (&error))
264 if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
265 fprintf (stderr, "Couldn't add filter!\n");
269 /* we handle SIGINT so exit() is reached and flushes stdout */
270 signal (SIGINT, sigint_handler);
271 while (dbus_connection_read_write_dispatch(connection, -1)
276 fprintf (stderr, "Error: %s\n", error.message);