dbus daemon - creating a logfile of all messages

Ralf Habacker ralf.habacker at freenet.de
Thu May 11 03:30:32 PDT 2006


Kai Teuber schrieb:
> Hi,
>
> I'm trying to monitor all messages on dbus, because the dbus-monitor didn't 
> makes it.
> So I tried to patch the daemon.
> Within the file dbus_connection.c in the function dbus_connection_dispatch I 
> added some code to write the needed informations into a logfile.
>
> But some needed informations are missing. I get the member name, the 
> destination name but not the sender name. It always is '(null)'.
>
> Can someone tell me where a better place is to make a logfile from all 
> messages on the bus?
>
>   
May be the appended dbus-monitor.c file may help you. I have patched it 
to get rid of glib requirements and it uses internal main loop, which 
works good for me.  Sender is shown if set.

Regards
Ralf


-------------- next part --------------
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-monitor.c  Utility program to monitor messages on the bus
 *
 * Copyright (C) 2003 Philip Blundell <philb at gnu.org>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#undef HAVE_GLIB
#ifdef HAVE_GLIB
#include <glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#else
#include <dbus/dbus-mainloop.h>
#include <dbus/dbus-list.h>

struct DBusLoop
{
  int refcount;
  DBusList *callbacks;
  int callback_list_serial;
  int watch_count;
  int timeout_count;
  int depth; /**< number of recursive runs */
  DBusList *need_dispatch;
};
#endif

#include "dbus-print-message.h"

#ifdef _WIN32
#include <windows.h>
#define sleep Sleep
#endif

void _____dbus_loop_run(DBusLoop * loop)
{
   DBusMessage* msg;
	 DBusConnection *conn = _dbus_list_pop_first (&loop->need_dispatch);

  _dbus_verbose ("  %d connections to dispatch\n", _dbus_list_get_length (&loop->need_dispatch));
  _dbus_loop_ref (loop);

   // loop listening for signals being emmitted
   while (1) {

      // non blocking read of the next available message
      dbus_connection_read_write(conn, 0);
      msg = dbus_connection_pop_message(conn);

      // loop again if we haven't read a message
      if (NULL == msg) { 
         sleep(1);
         continue;
      }
      printf("message :sender %s\n type %d\n dest %s\n path %s\n interface %s\n member %s\n signature %s\n",
      	dbus_message_get_sender(msg),
      	dbus_message_get_type(msg),
      	dbus_message_get_destination(msg),
      	dbus_message_get_path(msg),
      	dbus_message_get_interface(msg),
      	dbus_message_get_member(msg),
      	dbus_message_get_signature(msg)
      	);

      // free the message
      dbus_message_unref(msg);
	}
}


void _dbus_loop_run(DBusLoop * loop)
{
   DBusMessage* msg;
	 DBusConnection *conn = _dbus_list_pop_first (&loop->need_dispatch);

  _dbus_verbose ("  %d connections to dispatch\n", _dbus_list_get_length (&loop->need_dispatch));
  _dbus_loop_ref (loop);


   // loop listening for signals being emmitted
   while (1) {

      // non blocking read of the next available message
    dbus_connection_read_write(conn, 0);
		while(dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS)
			;
		sleep(1);
   }
}

static DBusHandlerResult
filter_func (DBusConnection     *connection,
             DBusMessage        *message,
             void               *user_data)
{
  print_message (message, FALSE);
  
  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);
  
  /* Conceptually we want this to be
   * DBUS_HANDLER_RESULT_NOT_YET_HANDLED, but this raises
   * some problems.  See bug 1719.
   */
  return DBUS_HANDLER_RESULT_HANDLED;
}

static void
usage (char *name, int ecode)
{
  fprintf (stderr, "Usage: %s [--system | --session] [watch expressions]\n", name);
  exit (ecode);
}

int
main (int argc, char *argv[])
{
  DBusConnection *connection;
  DBusError error;
  DBusBusType type = DBUS_BUS_SESSION;
#ifdef HAVE_GLIB
  GMainLoop *loop;
#else
	DBusLoop *loop;
#endif
  int i = 0, j = 0, numFilters = 0;
  char **filters = NULL;
  for (i = 1; i < argc; i++)
    {
      char *arg = argv[i];

      if (!strcmp (arg, "--system"))
	type = DBUS_BUS_SYSTEM;
      else if (!strcmp (arg, "--session"))
	type = DBUS_BUS_SESSION;
      else if (!strcmp (arg, "--help"))
	usage (argv[0], 0);
      else if (!strcmp (arg, "--"))
	continue;
      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++;
      }
    }

#ifdef HAVE_GLIB
  loop = g_main_loop_new (NULL, FALSE);
#else
  loop = _dbus_loop_new();
#endif
  dbus_error_init (&error);
  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",
               error.message);
      dbus_error_free (&error);
      exit (1);
    }

#ifdef HAVE_GLIB
  dbus_connection_setup_with_g_main (connection, NULL);
#else
	_dbus_loop_queue_dispatch(loop,connection);
#endif
  if (numFilters)
    {
      for (i = 0; i < j; i++)
        {
          dbus_bus_add_match (connection, filters[i], &error);
          if (dbus_error_is_set (&error))
            {
              fprintf (stderr, "Failed to setup match \"%s\": %s\n",
                       filters[i], error.message);
              dbus_error_free (&error);
              exit (1);
            }
	  free(filters[i]);
        }
    }
  else
    {
      dbus_bus_add_match (connection,
		          "type='signal'",
		          &error);
      if (dbus_error_is_set (&error))
        goto lose;
      dbus_bus_add_match (connection,
		          "type='method_call'",
		          &error);
      if (dbus_error_is_set (&error))
        goto lose;
      dbus_bus_add_match (connection,
		          "type='method_return'",
		          &error);
      if (dbus_error_is_set (&error))
        goto lose;
      dbus_bus_add_match (connection,
		          "type='error'",
		          &error);
      if (dbus_error_is_set (&error))
        goto lose;
    }

  if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
    fprintf (stderr, "Couldn't add filter!\n");
    exit (1);
  }
#ifdef HAVE_GLIB
  g_main_loop_run (loop);
#else
	_dbus_loop_run (loop);
  _dbus_loop_unref (loop);
  loop = NULL;
#endif

  exit (0);
 lose:
  fprintf (stderr, "Error: %s\n", error.message);
  exit (1);
}


More information about the dbus mailing list