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); }
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; }
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; }
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); }
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; }