X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fdbus-send.c;h=e5df15cf6b7333760e0421f64107a5a5559d2e4f;hb=0611a71c67b39d90565144de20c946447e2bbea6;hp=12ad5c8c549b0c3aa0e7ba15b23f1308e63d5d7f;hpb=e94493fc116955bbf72a8896c48f2c119efacf7f;p=platform%2Fupstream%2Fdbus.git diff --git a/tools/dbus-send.c b/tools/dbus-send.c index 12ad5c8..e5df15c 100644 --- a/tools/dbus-send.c +++ b/tools/dbus-send.c @@ -1,4 +1,4 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-send.c Utility program to send messages from the command line * * Copyright (C) 2003 Philip Blundell @@ -15,25 +15,214 @@ * * 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 #include #include #include #include +#ifndef HAVE_STRTOLL +#undef strtoll +#define strtoll mystrtoll +#include "strtoll.c" +#endif + +#ifndef HAVE_STRTOULL +#undef strtoull +#define strtoull mystrtoull +#include "strtoull.c" +#endif + +#ifdef DBUS_WINCE +#ifndef strdup +#define strdup _strdup +#endif +#endif + #include "dbus-print-message.h" +static const char *appname; + static void -usage (char *name, int ecode) +usage (int ecode) { - fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=SERVICE] [--print-reply] [contents ...]\n", name); + fprintf (stderr, "Usage: %s [--help] [--system | --session | --address=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] [contents ...]\n", appname); exit (ecode); } +static void +append_arg (DBusMessageIter *iter, int type, const char *value) +{ + dbus_uint16_t uint16; + dbus_int16_t int16; + dbus_uint32_t uint32; + dbus_int32_t int32; + dbus_uint64_t uint64; + dbus_int64_t int64; + double d; + unsigned char byte; + dbus_bool_t v_BOOLEAN; + + /* FIXME - we are ignoring OOM returns on all these functions */ + switch (type) + { + case DBUS_TYPE_BYTE: + byte = strtoul (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &byte); + break; + + case DBUS_TYPE_DOUBLE: + d = strtod (value, NULL); + dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &d); + break; + + case DBUS_TYPE_INT16: + int16 = strtol (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT16, &int16); + break; + + case DBUS_TYPE_UINT16: + uint16 = strtoul (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT16, &uint16); + break; + + case DBUS_TYPE_INT32: + int32 = strtol (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &int32); + break; + + case DBUS_TYPE_UINT32: + uint32 = strtoul (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &uint32); + break; + + case DBUS_TYPE_INT64: + int64 = strtoll (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &int64); + break; + + case DBUS_TYPE_UINT64: + uint64 = strtoull (value, NULL, 0); + dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &uint64); + break; + + case DBUS_TYPE_STRING: + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value); + break; + + case DBUS_TYPE_OBJECT_PATH: + dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &value); + break; + + case DBUS_TYPE_BOOLEAN: + if (strcmp (value, "true") == 0) + { + v_BOOLEAN = TRUE; + dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN); + } + else if (strcmp (value, "false") == 0) + { + v_BOOLEAN = FALSE; + dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &v_BOOLEAN); + } + else + { + fprintf (stderr, "%s: Expected \"true\" or \"false\" instead of \"%s\"\n", appname, value); + exit (1); + } + break; + + default: + fprintf (stderr, "%s: Unsupported data type %c\n", appname, (char) type); + exit (1); + } +} + +static void +append_array (DBusMessageIter *iter, int type, const char *value) +{ + const char *val; + char *dupval = strdup (value); + + val = strtok (dupval, ","); + while (val != NULL) + { + append_arg (iter, type, val); + val = strtok (NULL, ","); + } + free (dupval); +} + +static void +append_dict (DBusMessageIter *iter, int keytype, int valtype, const char *value) +{ + const char *val; + char *dupval = strdup (value); + + val = strtok (dupval, ","); + while (val != NULL) + { + DBusMessageIter subiter; + + dbus_message_iter_open_container (iter, + DBUS_TYPE_DICT_ENTRY, + NULL, + &subiter); + + append_arg (&subiter, keytype, val); + val = strtok (NULL, ","); + if (val == NULL) + { + fprintf (stderr, "%s: Malformed dictionary\n", appname); + exit (1); + } + append_arg (&subiter, valtype, val); + + dbus_message_iter_close_container (iter, &subiter); + val = strtok (NULL, ","); + } + free (dupval); +} + +static int +type_from_name (const char *arg) +{ + int type; + if (!strcmp (arg, "string")) + type = DBUS_TYPE_STRING; + else if (!strcmp (arg, "int16")) + type = DBUS_TYPE_INT16; + else if (!strcmp (arg, "uint16")) + type = DBUS_TYPE_UINT16; + else if (!strcmp (arg, "int32")) + type = DBUS_TYPE_INT32; + else if (!strcmp (arg, "uint32")) + type = DBUS_TYPE_UINT32; + else if (!strcmp (arg, "int64")) + type = DBUS_TYPE_INT64; + else if (!strcmp (arg, "uint64")) + type = DBUS_TYPE_UINT64; + else if (!strcmp (arg, "double")) + type = DBUS_TYPE_DOUBLE; + else if (!strcmp (arg, "byte")) + type = DBUS_TYPE_BYTE; + else if (!strcmp (arg, "boolean")) + type = DBUS_TYPE_BOOLEAN; + else if (!strcmp (arg, "objpath")) + type = DBUS_TYPE_OBJECT_PATH; + else + { + fprintf (stderr, "%s: Unknown type \"%s\"\n", appname, arg); + exit (1); + } + return type; +} + int main (int argc, char *argv[]) { @@ -41,69 +230,188 @@ main (int argc, char *argv[]) DBusError error; DBusMessage *message; int print_reply; + int print_reply_literal; + int reply_timeout; DBusMessageIter iter; int i; DBusBusType type = DBUS_BUS_SESSION; - char *dest = DBUS_SERVICE_BROADCAST; - char *name = NULL; + 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 session_or_system = FALSE; - if (argc < 2) - usage (argv[0], 1); + 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; + { + type = DBUS_BUS_SYSTEM; + session_or_system = TRUE; + } else if (strcmp (arg, "--session") == 0) - type = DBUS_BUS_SESSION; - else if (strcmp (arg, "--print-reply") == 0) - print_reply = TRUE; + { + type = DBUS_BUS_SESSION; + session_or_system = TRUE; + } + else if (strstr (arg, "--address") == arg) + { + address = strchr (arg, '='); + + if (address == NULL) + { + fprintf (stderr, "\"--address=\" requires an ADDRESS\n"); + usage (1); + } + else + { + address = address + 1; + } + } + else if (strncmp (arg, "--print-reply", 13) == 0) + { + print_reply = TRUE; + message_type = DBUS_MESSAGE_TYPE_METHOD_CALL; + if (*(arg + 13) != '\0') + print_reply_literal = TRUE; + } + else if (strstr (arg, "--reply-timeout=") == arg) + { + reply_timeout = strtol (strchr (arg, '=') + 1, + NULL, 10); + } else if (strstr (arg, "--dest=") == arg) dest = strchr (arg, '=') + 1; + else if (strstr (arg, "--type=") == arg) + type_str = strchr (arg, '=') + 1; else if (!strcmp(arg, "--help")) - usage (argv[0], 0); + usage (0); else if (arg[0] == '-') - usage (argv[0], 1); - else - name = arg; + usage (1); + else if (path == NULL) + path = arg; + else /* name == NULL guaranteed by the 'while' loop */ + name = arg; } if (name == NULL) - usage (argv[0], 1); + usage (1); + + if (session_or_system && + (address != NULL)) + { + fprintf (stderr, "\"--address\" 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); - connection = dbus_bus_get (type, &error); + + 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", - (type == DBUS_BUS_SYSTEM) ? "system" : "session", + 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); } - message = dbus_message_new (name, dest); + 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"); + fprintf (stderr, "Couldn't allocate D-Bus message\n"); exit (1); } - dbus_message_append_iter_init (message, &iter); + 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; - dbus_uint32_t uint32; - dbus_int32_t int32; - double d; - unsigned char byte; + int secondary_type; + int container_type; + DBusMessageIter *target_iter; + DBusMessageIter container_iter; type = DBUS_TYPE_INVALID; arg = argv[i++]; @@ -117,53 +425,84 @@ main (int argc, char *argv[]) *(c++) = 0; - if (arg[0] == 0 || !strcmp (arg, "string")) + 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 if (!strcmp (arg, "int32")) - type = DBUS_TYPE_INT32; - else if (!strcmp (arg, "uint32")) - type = DBUS_TYPE_UINT32; - else if (!strcmp (arg, "double")) - type = DBUS_TYPE_DOUBLE; - else if (!strcmp (arg, "byte")) - type = DBUS_TYPE_BYTE; - else if (!strcmp (arg, "boolean")) - type = DBUS_TYPE_BOOLEAN; else + type = type_from_name (arg); + + if (container_type == DBUS_TYPE_DICT_ENTRY) { - fprintf (stderr, "%s: Unknown type \"%s\"\n", argv[0], arg); - exit (1); + 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; - switch (type) + if (container_type == DBUS_TYPE_ARRAY) { - case DBUS_TYPE_BYTE: - byte = strtoul (c, NULL, 0); - dbus_message_iter_append_byte (&iter, byte); - break; - - case DBUS_TYPE_DOUBLE: - d = strtod (c, NULL); - dbus_message_iter_append_double (&iter, d); - break; - - case DBUS_TYPE_INT32: - int32 = strtol (c, NULL, 0); - dbus_message_iter_append_int32 (&iter, int32); - break; - - case DBUS_TYPE_UINT32: - uint32 = strtoul (c, NULL, 0); - dbus_message_iter_append_uint32 (&iter, uint32); - break; - - case DBUS_TYPE_STRING: - dbus_message_iter_append_string (&iter, c); - break; - - default: - fprintf (stderr, "%s: Unsupported data type\n", argv[0]); - exit (1); + 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); } } @@ -173,18 +512,19 @@ main (int argc, char *argv[]) dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (connection, - message, -1, + message, reply_timeout, &error); if (dbus_error_is_set (&error)) { - fprintf (stderr, "Error: %s\n", + fprintf (stderr, "Error %s: %s\n", + error.name, error.message); exit (1); } if (reply) { - print_message (reply); + print_message (reply, print_reply_literal); dbus_message_unref (reply); } } @@ -196,7 +536,7 @@ main (int argc, char *argv[]) dbus_message_unref (message); - dbus_connection_disconnect (connection); + dbus_connection_unref (connection); exit (0); }