Example #1
0
static void
print_message_profile (DBusMessage *message)
{
  static dbus_bool_t first = TRUE;
  long sec = 0, usec = 0;

  if (first)
    {
      profile_print_headers ();
      first = FALSE;
    }

  _dbus_get_real_time (&sec, &usec);

  switch (dbus_message_get_type (message))
    {
      case DBUS_MESSAGE_TYPE_METHOD_CALL:
        profile_print_with_attrs ("mc", message, sec, usec,
          PROFILE_ATTRIBUTE_FLAG_SERIAL |
          PROFILE_ATTRIBUTE_FLAG_SENDER |
          PROFILE_ATTRIBUTE_FLAG_DESTINATION |
          PROFILE_ATTRIBUTE_FLAG_PATH |
          PROFILE_ATTRIBUTE_FLAG_INTERFACE |
          PROFILE_ATTRIBUTE_FLAG_MEMBER);
        break;
      case DBUS_MESSAGE_TYPE_METHOD_RETURN:
        profile_print_with_attrs ("mr", message, sec, usec,
          PROFILE_ATTRIBUTE_FLAG_SERIAL |
          PROFILE_ATTRIBUTE_FLAG_SENDER |
          PROFILE_ATTRIBUTE_FLAG_DESTINATION |
          PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
        break;
      case DBUS_MESSAGE_TYPE_ERROR:
        profile_print_with_attrs ("err", message, sec, usec,
          PROFILE_ATTRIBUTE_FLAG_SERIAL |
          PROFILE_ATTRIBUTE_FLAG_SENDER |
          PROFILE_ATTRIBUTE_FLAG_DESTINATION |
          PROFILE_ATTRIBUTE_FLAG_REPLY_SERIAL);
        break;
      case DBUS_MESSAGE_TYPE_SIGNAL:
        profile_print_with_attrs ("sig", message, sec, usec,
          PROFILE_ATTRIBUTE_FLAG_SERIAL |
          PROFILE_ATTRIBUTE_FLAG_SENDER |
          PROFILE_ATTRIBUTE_FLAG_DESTINATION |
          PROFILE_ATTRIBUTE_FLAG_PATH |
          PROFILE_ATTRIBUTE_FLAG_INTERFACE |
          PROFILE_ATTRIBUTE_FLAG_MEMBER);
        break;
      default:
        printf ("%s\t%ld.%06ld", "tun", sec, usec);
        break;
    }
}
/**
 * Generates a new UUID. If you change how this is done,
 * there's some text about it in the spec that should also change.
 *
 * @param uuid the uuid to initialize
 */
void
_dbus_generate_uuid (DBusGUID *uuid)
{
  long now;

  /* don't use monotonic time because the UUID may be saved to disk, e.g.
   * it may persist across reboots
   */
  _dbus_get_real_time (&now, NULL);

  uuid->as_uint32s[DBUS_UUID_LENGTH_WORDS - 1] = DBUS_UINT32_TO_BE (now);
  
  _dbus_generate_random_bytes_buffer (uuid->as_bytes, DBUS_UUID_LENGTH_BYTES - 4);
}
Example #3
0
static DBusHandlerResult
monitor_filter_func (DBusConnection     *connection,
                     DBusMessage        *message,
                     void               *user_data)
{
  long sec = 0, usec = 0;

  _dbus_get_real_time (&sec, &usec);

  print_message (message, FALSE, sec, usec);
  
  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);

  /* Monitors must not allow libdbus to reply to messages, so we eat
   * the message. See bug 1719.
   */
  return DBUS_HANDLER_RESULT_HANDLED;
}
Example #4
0
static int
run_session (const char *dbus_daemon,
             const char *config_file,
             char       *bus_address,
             char      **argv,
             int         prog_arg)
{
  char *dbus_daemon_argv[3];
  int ret = 127;
  HANDLE server_handle = NULL;
  HANDLE app_handle = NULL;
  DWORD exit_code;
  DBusString argv_strings[4];
  DBusString address;
  char **env = NULL;
  DBusHashTable *env_table = NULL;
  long sec,usec;
  dbus_bool_t result = TRUE;
  char *key = NULL;
  char *value = NULL;

  if (!_dbus_string_init (&argv_strings[0]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[1]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[2]))
    result = FALSE;
  if (!_dbus_string_init (&address))
    result = FALSE;
  if (!result)
    goto out;

  /* run dbus daemon */
  _dbus_get_real_time (&sec, &usec);
  /* On Windows it's difficult to make use of --print-address to
   * convert a listenable address into a connectable address, so instead
   * we tell the temporary dbus-daemon to use the Windows autolaunch
   * mechanism, with a unique scope that is shared by this dbus-daemon,
   * the app process that defines its lifetime, and any other child
   * processes they might have. */
  _dbus_string_append_printf (&address, "autolaunch:scope=dbus-tmp-session-%ld%ld-" DBUS_PID_FORMAT, sec, usec, _dbus_getpid ());
  _dbus_string_append_printf (&argv_strings[0], "%s", dbus_daemon);
  if (config_file != NULL)
    _dbus_string_append_printf (&argv_strings[1], "--config-file=%s", config_file);
  else
    _dbus_string_append_printf (&argv_strings[1], "--session");
  _dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address));
  dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]);
  dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]);
  dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]);
  dbus_daemon_argv[3] = NULL;

  server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL);
  if (!server_handle)
    {
      _dbus_win_stderr_win_error (me, "Could not start dbus daemon", GetLastError ());
      goto out;
    }

  /* run app */
  env = _dbus_get_environment ();
  env_table = _dbus_hash_table_new (DBUS_HASH_STRING,
                                    dbus_free,
                                    dbus_free);
  if (!_dbus_hash_table_from_array (env_table, env, '='))
    {
      goto out;
    }

  /* replace DBUS_SESSION_BUS_ADDRESS in environment */
  if (!_dbus_string_steal_data (&address, &value))
    goto out;

  key = _dbus_strdup ("DBUS_SESSION_BUS_ADDRESS");

  if (key == NULL)
    goto out;

  if (_dbus_hash_table_insert_string (env_table, key, value))
    {
      /* env_table took ownership, do not free separately */
      key = NULL;
      value = NULL;
    }
  else
    {
      /* we still own key and value, the cleanup code will free them */
      goto out;
    }

  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_ADDRESS");
  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_BUS_TYPE");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_PID");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_WINDOWID");

  dbus_free_string_array (env);
  env = _dbus_hash_table_to_array (env_table, '=');
  if (!env)
    goto out;

  app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env);
  if (!app_handle)
    {
      _dbus_win_stderr_win_error (me, "unable to start child process", GetLastError ());
      goto out;
    }

  WaitForSingleObject (app_handle, INFINITE);
  if (!GetExitCodeProcess (app_handle, &exit_code))
    {
      _dbus_win_stderr_win_error (me, "could not fetch exit code", GetLastError ());
      goto out;
    }
  ret = exit_code;

out:
  TerminateProcess (server_handle, 0);
  if (server_handle != NULL)
    CloseHandle (server_handle);
  if (app_handle != NULL)
    CloseHandle (app_handle);
  _dbus_string_free (&argv_strings[0]);
  _dbus_string_free (&argv_strings[1]);
  _dbus_string_free (&argv_strings[2]);
  _dbus_string_free (&address);
  dbus_free_string_array (env);
  if (env_table != NULL)
    _dbus_hash_table_unref (env_table);
  dbus_free (key);
  dbus_free (value);
  return ret;
}
Example #5
0
int
main (int argc, char *argv[])
{
  DBusConnection *connection;
  DBusError error;
  DBusMessage *message;
  dbus_bool_t print_reply;
  dbus_bool_t print_reply_literal;
  int reply_timeout;
  DBusMessageIter iter;
  int i;
  DBusBusType type = DBUS_BUS_SESSION;
  const char *dest = NULL;
  const char *name = NULL;
  const char *path = NULL;
  int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
  const char *type_str = NULL;
  const char *address = NULL;
  int is_bus = FALSE;
  int session_or_system = FALSE;

  appname = argv[0];
  
  if (argc < 3)
    usage (1);

  print_reply = FALSE;
  print_reply_literal = FALSE;
  reply_timeout = -1;
  
  for (i = 1; i < argc && name == NULL; i++)
    {
      char *arg = argv[i];

      if (strcmp (arg, "--system") == 0)
        {
	  type = DBUS_BUS_SYSTEM;
          session_or_system = TRUE;
        }
      else if (strcmp (arg, "--session") == 0)
        {
	  type = DBUS_BUS_SESSION;
          session_or_system = TRUE;
        }
      else if ((strstr (arg, "--bus=") == arg) || (strstr (arg, "--peer=") == arg) || (strstr (arg, "--address=") == arg))
        {
          if (arg[2] == 'b') /* bus */
            {
              is_bus = TRUE;
            }
          else if (arg[2] == 'p') /* peer */
            {
              is_bus = FALSE;
            }
          else /* address; keeping backwards compatibility */
            {
              is_bus = FALSE;
            }

          address = strchr (arg, '=') + 1;

          if (address[0] == '\0')
            {
              fprintf (stderr, "\"--peer=\" and \"--bus=\" require an ADDRESS\n");
              usage (1);
            }
        }
      else if (strncmp (arg, "--print-reply", 13) == 0)
	{
	  print_reply = TRUE;
	  message_type = DBUS_MESSAGE_TYPE_METHOD_CALL;
	  if (strcmp (arg + 13, "=literal") == 0)
	    print_reply_literal = TRUE;
	  else if (*(arg + 13) != '\0')
	    {
	      fprintf (stderr, "invalid value (%s) of \"--print-reply\"\n", arg + 13);
	      usage (1);
	    }
	}
      else if (strstr (arg, "--reply-timeout=") == arg)
	{
	  if (*(strchr (arg, '=') + 1) == '\0')
	    {
	      fprintf (stderr, "\"--reply-timeout=\" requires an MSEC\n");
	      usage (1);
	    }
	  reply_timeout = strtol (strchr (arg, '=') + 1,
				  NULL, 10);
	  if (reply_timeout <= 0)
	    {
	      fprintf (stderr, "invalid value (%s) of \"--reply-timeout\"\n",
	               strchr (arg, '=') + 1);
	      usage (1);
	    }
	}
      else if (strstr (arg, "--dest=") == arg)
	{
	  if (*(strchr (arg, '=') + 1) == '\0')
	    {
	      fprintf (stderr, "\"--dest=\" requires an NAME\n");
	      usage (1);
	    }
	  dest = strchr (arg, '=') + 1;
	}
      else if (strstr (arg, "--type=") == arg)
	type_str = strchr (arg, '=') + 1;
      else if (!strcmp(arg, "--help"))
	usage (0);
      else if (arg[0] == '-')
	usage (1);
      else if (path == NULL)
        path = arg;
      else /* name == NULL guaranteed by the 'while' loop */
        name = arg;
    }

  if (name == NULL)
    usage (1);

  if (session_or_system &&
      (address != NULL))
    {
      fprintf (stderr, "\"--peer\" and \"--bus\" may not be used with \"--system\" or \"--session\"\n");
      usage (1);
    }

  if (type_str != NULL)
    {
      message_type = dbus_message_type_from_string (type_str);
      if (!(message_type == DBUS_MESSAGE_TYPE_METHOD_CALL ||
            message_type == DBUS_MESSAGE_TYPE_SIGNAL))
        {
          fprintf (stderr, "Message type \"%s\" is not supported\n",
                   type_str);
          exit (1);
        }
    }
  
  dbus_error_init (&error);

  if (dest && !dbus_validate_bus_name (dest, &error))
    {
      fprintf (stderr, "invalid value (%s) of \"--dest\"\n", dest);
      usage (1);
    }

  if (address != NULL)
    {
      connection = dbus_connection_open (address, &error);
    }
  else
    {
      connection = dbus_bus_get (type, &error);
    }

  if (connection == NULL)
    {
      fprintf (stderr, "Failed to open connection to \"%s\" message bus: %s\n",
               (address != NULL) ? address :
                 ((type == DBUS_BUS_SYSTEM) ? "system" : "session"),
               error.message);
      dbus_error_free (&error);
      exit (1);
    }
  else if ((address != NULL) && is_bus)
    {
      if (!dbus_bus_register (connection, &error))
        {
          fprintf (stderr, "Failed to register on connection to \"%s\" message bus: %s\n",
                   address, error.message);
          dbus_error_free (&error);
          exit (1);
        }
    }

  if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL)
    {
      char *last_dot;

      last_dot = strrchr (name, '.');
      if (last_dot == NULL)
        {
          fprintf (stderr, "Must use org.mydomain.Interface.Method notation, no dot in \"%s\"\n",
                   name);
          exit (1);
        }
      *last_dot = '\0';
      
      message = dbus_message_new_method_call (NULL,
                                              path,
                                              name,
                                              last_dot + 1);
      dbus_message_set_auto_start (message, TRUE);
    }
  else if (message_type == DBUS_MESSAGE_TYPE_SIGNAL)
    {
      char *last_dot;

      last_dot = strrchr (name, '.');
      if (last_dot == NULL)
        {
          fprintf (stderr, "Must use org.mydomain.Interface.Signal notation, no dot in \"%s\"\n",
                   name);
          exit (1);
        }
      *last_dot = '\0';
      
      message = dbus_message_new_signal (path, name, last_dot + 1);
    }
  else
    {
      fprintf (stderr, "Internal error, unknown message type\n");
      exit (1);
    }

  if (message == NULL)
    {
      fprintf (stderr, "Couldn't allocate D-Bus message\n");
      exit (1);
    }

  if (dest && !dbus_message_set_destination (message, dest))
    {
      fprintf (stderr, "Not enough memory\n");
      exit (1);
    }
  
  dbus_message_iter_init_append (message, &iter);

  while (i < argc)
    {
      char *arg;
      char *c;
      int type;
      int secondary_type;
      int container_type;
      DBusMessageIter *target_iter;
      DBusMessageIter container_iter;

      type = DBUS_TYPE_INVALID;
      arg = argv[i++];
      c = strchr (arg, ':');

      if (c == NULL)
	{
	  fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
	  exit (1);
	}

      *(c++) = 0;

      container_type = DBUS_TYPE_INVALID;

      if (strcmp (arg, "variant") == 0)
	container_type = DBUS_TYPE_VARIANT;
      else if (strcmp (arg, "array") == 0)
	container_type = DBUS_TYPE_ARRAY;
      else if (strcmp (arg, "dict") == 0)
	container_type = DBUS_TYPE_DICT_ENTRY;

      if (container_type != DBUS_TYPE_INVALID)
	{
	  arg = c;
	  c = strchr (arg, ':');
	  if (c == NULL)
	    {
	      fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
	      exit (1);
	    }
	  *(c++) = 0;
	}

      if (arg[0] == 0)
	type = DBUS_TYPE_STRING;
      else
	type = type_from_name (arg);

      if (container_type == DBUS_TYPE_DICT_ENTRY)
	{
	  char sig[5];
	  arg = c;
	  c = strchr (c, ':');
	  if (c == NULL)
	    {
	      fprintf (stderr, "%s: Data item \"%s\" is badly formed\n", argv[0], arg);
	      exit (1);
	    }
	  *(c++) = 0;
	  secondary_type = type_from_name (arg);
	  sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
	  sig[1] = type;
	  sig[2] = secondary_type;
	  sig[3] = DBUS_DICT_ENTRY_END_CHAR;
	  sig[4] = '\0';
	  dbus_message_iter_open_container (&iter,
					    DBUS_TYPE_ARRAY,
					    sig,
					    &container_iter);
	  target_iter = &container_iter;
	}
      else if (container_type != DBUS_TYPE_INVALID)
	{
	  char sig[2];
	  sig[0] = type;
	  sig[1] = '\0';
	  dbus_message_iter_open_container (&iter,
					    container_type,
					    sig,
					    &container_iter);
	  target_iter = &container_iter;
	}
      else
	target_iter = &iter;

      if (container_type == DBUS_TYPE_ARRAY)
	{
	  append_array (target_iter, type, c);
	}
      else if (container_type == DBUS_TYPE_DICT_ENTRY)
	{
	  append_dict (target_iter, type, secondary_type, c);
	}
      else
	append_arg (target_iter, type, c);

      if (container_type != DBUS_TYPE_INVALID)
	{
	  dbus_message_iter_close_container (&iter,
					     &container_iter);
	}
    }

  if (print_reply)
    {
      DBusMessage *reply;

      dbus_error_init (&error);
      reply = dbus_connection_send_with_reply_and_block (connection,
                                                         message, reply_timeout,
                                                         &error);
      if (dbus_error_is_set (&error))
        {
          fprintf (stderr, "Error %s: %s\n",
		   error.name,
                   error.message);
          exit (1);
        }

      if (reply)
        {
          long sec, usec;

          _dbus_get_real_time (&sec, &usec);
          print_message (reply, print_reply_literal, sec, usec);
          dbus_message_unref (reply);
        }
    }
  else
    {
      dbus_connection_send (connection, message, NULL);
      dbus_connection_flush (connection);
    }

  dbus_message_unref (message);

  dbus_connection_unref (connection);

  exit (0);
}
Example #6
0
static DBusHandlerResult
binary_filter_func (DBusConnection *connection,
                    DBusMessage    *message,
                    void           *user_data)
{
  BinaryMode mode = _DBUS_POINTER_TO_INT (user_data);
  char *blob;
  int len;

  /* It would be nice if we could do a zero-copy "peek" one day, but libdbus
   * is so copy-happy that this isn't really a big deal.
   */
  if (!dbus_message_marshal (message, &blob, &len))
    tool_oom ("retrieving message");

  switch (mode)
    {
      case BINARY_MODE_PCAP:
          {
            long tv_sec, tv_usec;
            /* seconds, microseconds, bytes captured (possibly truncated),
             * original length.
             * http://wiki.wireshark.org/Development/LibpcapFileFormat
             */
            dbus_uint32_t header[4] = { 0, 0, len, len };

            /* If this gets padded then we'd need to write it out in pieces */
            _DBUS_STATIC_ASSERT (sizeof (header) == 16);

            _dbus_get_real_time (&tv_sec, &tv_usec);
            header[0] = tv_sec;
            header[1] = tv_usec;

            if (!tool_write_all (STDOUT_FILENO, header, sizeof (header)))
              {
                perror ("dbus-monitor: write");
                exit (1);
              }
          }
        break;

      case BINARY_MODE_RAW:
      default:
        /* nothing special, just the raw message stream */
        break;
    }

  if (!tool_write_all (STDOUT_FILENO, blob, len))
    {
      perror ("dbus-monitor: write");
      exit (1);
    }

  dbus_free (blob);

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);

  return DBUS_HANDLER_RESULT_HANDLED;
}