-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-monitor.c Utility program to monitor messages on the bus
*
* Copyright (C) 2003 Philip Blundell <philb@gnu.org>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <time.h>
-#include <signal.h>
-
#include "dbus-print-message.h"
+#define EAVESDROPPING_RULE "eavesdrop=true"
+
#ifdef DBUS_WIN
/* gettimeofday is not defined on windows */
#define DBUS_SECONDS_SINCE_1601 11644473600LL
#define DBUS_USEC_IN_SEC 1000000LL
+#ifdef DBUS_WINCE
+
+#ifndef _IOLBF
+#define _IOLBF 0x40
+#endif
+#ifndef _IONBF
+#define _IONBF 0x04
+#endif
+
+void
+GetSystemTimeAsFileTime (LPFILETIME ftp)
+{
+ SYSTEMTIME st;
+ GetSystemTime (&st);
+ SystemTimeToFileTime (&st, ftp);
+}
+#endif
+
static int
gettimeofday (struct timeval *__p,
void *__t)
}
#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,
return DBUS_HANDLER_RESULT_HANDLED;
}
+#ifdef __APPLE__
+#define PROFILE_TIMED_FORMAT "%s\t%lu\t%d"
+#else
#define PROFILE_TIMED_FORMAT "%s\t%lu\t%lu"
+#endif
#define TRAP_NULL_STRING(str) ((str) ? (str) : "<none>")
typedef enum
PROFILE_ATTRIBUTE_FLAG_PATH = 16,
PROFILE_ATTRIBUTE_FLAG_INTERFACE = 32,
PROFILE_ATTRIBUTE_FLAG_MEMBER = 64,
- PROFILE_ATTRIBUTE_FLAG_ERROR_NAME = 128,
+ PROFILE_ATTRIBUTE_FLAG_ERROR_NAME = 128
} ProfileAttributeFlags;
static void
static void
usage (char *name, int ecode)
{
- fprintf (stderr, "Usage: %s [--system | --session] [--monitor | --profile ] [watch expressions]\n", name);
+ fprintf (stderr, "Usage: %s [--system | --session | --address ADDRESS] [--monitor | --profile ] [watch expressions]\n", name);
exit (ecode);
}
-dbus_bool_t sigint_received = FALSE;
+static void
+only_one_type (dbus_bool_t *seen_bus_type,
+ char *name)
+{
+ if (*seen_bus_type)
+ {
+ fprintf (stderr, "I only support monitoring one bus at a time!\n");
+ usage (name, 1);
+ }
+ else
+ {
+ *seen_bus_type = TRUE;
+ }
+}
+
+static dbus_bool_t sigint_received = FALSE;
static void
sigint_handler (int signum)
DBusError error;
DBusBusType type = DBUS_BUS_SESSION;
DBusHandleMessageFunction filter_func = monitor_filter_func;
-
+ char *address = NULL;
+ dbus_bool_t seen_bus_type = FALSE;
+
int i = 0, j = 0, numFilters = 0;
char **filters = NULL;
+
+ /* Set stdout to be unbuffered; this is basically so that if people
+ * do dbus-monitor > file, then send SIGINT via Control-C, they
+ * don't lose the last chunk of messages.
+ */
+
+#ifdef DBUS_WIN
+ setvbuf (stdout, NULL, _IONBF, 0);
+#else
+ setvbuf (stdout, NULL, _IOLBF, 0);
+#endif
+
for (i = 1; i < argc; i++)
{
char *arg = argv[i];
if (!strcmp (arg, "--system"))
- type = DBUS_BUS_SYSTEM;
+ {
+ only_one_type (&seen_bus_type, argv[0]);
+ type = DBUS_BUS_SYSTEM;
+ }
else if (!strcmp (arg, "--session"))
- type = DBUS_BUS_SESSION;
+ {
+ only_one_type (&seen_bus_type, argv[0]);
+ type = DBUS_BUS_SESSION;
+ }
+ else if (!strcmp (arg, "--address"))
+ {
+ only_one_type (&seen_bus_type, argv[0]);
+
+ if (i+1 < argc)
+ {
+ address = argv[i+1];
+ i++;
+ }
+ else
+ usage (argv[0], 1);
+ }
else if (!strcmp (arg, "--help"))
usage (argv[0], 0);
else if (!strcmp (arg, "--monitor"))
else if (arg[0] == '-')
usage (argv[0], 1);
else {
- 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++;
+ 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++;
}
}
dbus_error_init (&error);
- connection = dbus_bus_get (type, &error);
+
+ if (address != NULL)
+ {
+ connection = dbus_connection_open (address, &error);
+ if (connection)
+ {
+ if (!dbus_bus_register (connection, &error))
+ {
+ fprintf (stderr, "Failed to register connection to bus at %s: %s\n",
+ address, error.message);
+ dbus_error_free (&error);
+ exit (1);
+ }
+ }
+ }
+ else
+ connection = dbus_bus_get (type, &error);
if (connection == NULL)
{
- fprintf (stderr, "Failed to open connection to %s message bus: %s\n",
- (type == DBUS_BUS_SYSTEM) ? "system" : "session",
+ const char *where;
+ if (address != NULL)
+ where = address;
+ else
+ {
+ switch (type)
+ {
+ case DBUS_BUS_SYSTEM:
+ where = "system bus";
+ break;
+ case DBUS_BUS_SESSION:
+ where = "session bus";
+ break;
+ default:
+ where = "";
+ }
+ }
+ fprintf (stderr, "Failed to open connection to %s: %s\n",
+ where,
error.message);
dbus_error_free (&error);
exit (1);
else
{
dbus_bus_add_match (connection,
- "type='signal'",
+ EAVESDROPPING_RULE ",type='signal'",
&error);
if (dbus_error_is_set (&error))
goto lose;
dbus_bus_add_match (connection,
- "type='method_call'",
+ EAVESDROPPING_RULE ",type='method_call'",
&error);
if (dbus_error_is_set (&error))
goto lose;
dbus_bus_add_match (connection,
- "type='method_return'",
+ EAVESDROPPING_RULE ",type='method_return'",
&error);
if (dbus_error_is_set (&error))
goto lose;
dbus_bus_add_match (connection,
- "type='error'",
+ EAVESDROPPING_RULE ",type='error'",
&error);
if (dbus_error_is_set (&error))
goto lose;
exit (1);
}
- /* we handle SIGINT so exit() is reached and flushes stdout */
- signal (SIGINT, sigint_handler);
- while (dbus_connection_read_write_dispatch(connection, -1)
- && !sigint_received)
+ while (dbus_connection_read_write_dispatch(connection, -1))
;
exit (0);
lose: