summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Morin <chris.morin2@gmail.com>2019-07-15 12:36:50 +0000
committerSimon McVittie <smcv@collabora.com>2019-07-15 12:36:50 +0000
commit9842689a29f9a3ca57a15b5a201a030688a831bf (patch)
tree8ad5105cf54d574779071e2163f12a293b7635ba
parent1823c8e14a6424f9853ed687a83cdb9c34c9da50 (diff)
dbus-send: add --sender option
Clients listening for a signal can match against the 'sender', expecting it to come from a connection with a specific name. With this change, dbus-send can send signals to them.
-rw-r--r--doc/dbus-send.1.xml.in7
-rw-r--r--tools/dbus-send.c52
2 files changed, 57 insertions, 2 deletions
diff --git a/doc/dbus-send.1.xml.in b/doc/dbus-send.1.xml.in
index 34c4b99e..981c786d 100644
--- a/doc/dbus-send.1.xml.in
+++ b/doc/dbus-send.1.xml.in
@@ -22,6 +22,7 @@
<cmdsynopsis>
<command>dbus-send</command>
<group choice='opt'><arg choice='plain'>--system </arg><arg choice='plain'>--session </arg><arg choice='plain'>--bus=<replaceable>ADDRESS</replaceable></arg><arg choice='plain'>--peer=<replaceable>ADDRESS</replaceable></arg></group>
+ <arg choice='opt'>--sender=<replaceable>NAME</replaceable></arg>
<arg choice='opt'>--dest=<replaceable>NAME</replaceable></arg>
<arg choice='opt'><arg choice='plain'>--print-reply </arg><arg choice='opt'><replaceable>=literal</replaceable></arg></arg>
<arg choice='opt'>--reply-timeout=<replaceable>MSEC</replaceable></arg>
@@ -149,6 +150,12 @@ The default is implementation&hyphen;defined, typically 25 seconds.</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--sender=</option><replaceable>NAME</replaceable></term>
+ <listitem>
+<para>Request ownership of name <replaceable>NAME</replaceable> before sending the message. The name will be released when <command>dbus-send</command> exits.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>--type=</option><replaceable>TYPE</replaceable></term>
<listitem>
<para>Specify <emphasis remap='B'>method_call</emphasis> or <emphasis remap='B'>signal</emphasis> (defaults to "<emphasis remap='B'>signal</emphasis>").</para>
diff --git a/tools/dbus-send.c b/tools/dbus-send.c
index efeb76e0..343fd75a 100644
--- a/tools/dbus-send.c
+++ b/tools/dbus-send.c
@@ -54,7 +54,7 @@ static void usage (int ecode) _DBUS_GNUC_NORETURN;
static void
usage (int ecode)
{
- fprintf (stderr, "Usage: %s [--help] [--system | --session | --bus=ADDRESS | --peer=ADDRESS] [--dest=NAME] [--type=TYPE] [--print-reply[=literal]] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
+ fprintf (stderr, "Usage: %s [--help] [--system | --session | --bus=ADDRESS | --peer=ADDRESS] [--sender=NAME] [--dest=NAME] [--type=TYPE] [--print-reply[=literal]] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
exit (ecode);
}
@@ -261,6 +261,7 @@ main (int argc, char *argv[])
int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
const char *type_str = NULL;
const char *address = NULL;
+ const char *sender = NULL;
int is_bus = FALSE;
int session_or_system = FALSE;
@@ -313,6 +314,16 @@ main (int argc, char *argv[])
usage (1);
}
}
+ else if (strstr (arg, "--sender=") == arg)
+ {
+ sender = strchr (arg, '=') + 1;
+
+ if (sender[0] == '\0')
+ {
+ fprintf (stderr, "\"--sender=\" requires a NAME\n");
+ usage (1);
+ }
+ }
else if (strncmp (arg, "--print-reply", 13) == 0)
{
print_reply = TRUE;
@@ -372,6 +383,12 @@ main (int argc, char *argv[])
usage (1);
}
+ if (sender != NULL && address != NULL && !is_bus)
+ {
+ fprintf (stderr, "\"--peer\" may not be used with \"--sender\"\n");
+ exit (1);
+ }
+
if (type_str != NULL)
{
message_type = dbus_message_type_from_string (type_str);
@@ -383,12 +400,20 @@ main (int argc, char *argv[])
exit (1);
}
}
-
+
dbus_error_init (&error);
if (dest && !dbus_validate_bus_name (dest, &error))
{
fprintf (stderr, "invalid value (%s) of \"--dest\"\n", dest);
+ dbus_error_free (&error);
+ usage (1);
+ }
+
+ if (sender && !dbus_validate_bus_name (sender, &error))
+ {
+ fprintf (stderr, "invalid value (%s) of \"--sender\"\n", sender);
+ dbus_error_free (&error);
usage (1);
}
@@ -421,6 +446,29 @@ main (int argc, char *argv[])
}
}
+ if (sender != NULL)
+ {
+ int ret = dbus_bus_request_name (connection, sender, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
+ switch (ret)
+ {
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ /* success */
+ break;
+ case DBUS_REQUEST_NAME_REPLY_EXISTS:
+ fprintf (stderr, "Requested name \"%s\" already has owner\n", sender);
+ exit (1);
+ case -1:
+ fprintf (stderr, "Failed to request sender name \"%s\": %s\n", sender, error.message);
+ dbus_error_free (&error);
+ exit (1);
+ default:
+ /* This should be unreachable if the bus is compliant */
+ fprintf (stderr, "Failed to request sender name \"%s\": unexpected result code %d\n",
+ sender, ret);
+ exit (1);
+ }
+ }
+
if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL)
{
char *last_dot;