1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 * Author: David Zeuthen <davidz@redhat.com>
33 #include "glib/glib-private.h"
36 /* ---------------------------------------------------------------------------------------------------- */
38 G_GNUC_UNUSED
static void completion_debug (const gchar
*format
, ...);
40 /* Uncomment to get debug traces in /tmp/gdbus-completion-debug.txt (nice
41 * to not have it interfere with stdout/stderr)
44 G_GNUC_UNUSED
static void
45 completion_debug (const gchar
*format
, ...)
49 static FILE *f
= NULL
;
51 va_start (var_args
, format
);
52 s
= g_strdup_vprintf (format
, var_args
);
55 f
= fopen ("/tmp/gdbus-completion-debug.txt", "a+");
57 fprintf (f
, "%s\n", s
);
62 completion_debug (const gchar
*format
, ...)
67 /* ---------------------------------------------------------------------------------------------------- */
71 remove_arg (gint num
, gint
*argc
, gchar
**argv
[])
75 g_assert (num
<= (*argc
));
77 for (n
= num
; (*argv
)[n
] != NULL
; n
++)
78 (*argv
)[n
] = (*argv
)[n
+1];
80 (*argc
) = (*argc
) - 1;
84 usage (gint
*argc
, gchar
**argv
[], gboolean use_stdout
)
90 o
= g_option_context_new (_("COMMAND"));
91 g_option_context_set_help_enabled (o
, FALSE
);
92 /* Ignore parsing result */
93 g_option_context_parse (o
, argc
, argv
, NULL
);
94 program_name
= g_path_get_basename ((*argv
)[0]);
95 s
= g_strdup_printf (_("Commands:\n"
96 " help Shows this information\n"
97 " introspect Introspect a remote object\n"
98 " monitor Monitor a remote object\n"
99 " call Invoke a method on a remote object\n"
100 " emit Emit a signal\n"
101 " wait Wait for a bus name to appear\n"
103 "Use “%s COMMAND --help” to get help on each command.\n"),
105 g_free (program_name
);
106 g_option_context_set_description (o
, s
);
108 s
= g_option_context_get_help (o
, FALSE
, NULL
);
112 g_printerr ("%s", s
);
114 g_option_context_free (o
);
118 modify_argv0_for_command (gint
*argc
, gchar
**argv
[], const gchar
*command
)
124 * 1. get a g_set_prgname() ?; or
125 * 2. save old argv[0] and restore later
128 g_assert (g_strcmp0 ((*argv
)[1], command
) == 0);
129 remove_arg (1, argc
, argv
);
131 program_name
= g_path_get_basename ((*argv
)[0]);
132 s
= g_strdup_printf ("%s %s", (*argv
)[0], command
);
134 g_free (program_name
);
137 /* ---------------------------------------------------------------------------------------------------- */
140 print_methods_and_signals (GDBusConnection
*c
,
143 gboolean print_methods
,
144 gboolean print_signals
)
148 const gchar
*xml_data
;
154 result
= g_dbus_connection_call_sync (c
,
157 "org.freedesktop.DBus.Introspectable",
160 G_VARIANT_TYPE ("(s)"),
161 G_DBUS_CALL_FLAGS_NONE
,
167 g_printerr (_("Error: %s\n"), error
->message
);
168 g_error_free (error
);
171 g_variant_get (result
, "(&s)", &xml_data
);
174 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
175 g_variant_unref (result
);
178 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
179 g_error_free (error
);
183 for (n
= 0; node
->interfaces
!= NULL
&& node
->interfaces
[n
] != NULL
; n
++)
185 const GDBusInterfaceInfo
*iface
= node
->interfaces
[n
];
186 for (m
= 0; print_methods
&& iface
->methods
!= NULL
&& iface
->methods
[m
] != NULL
; m
++)
188 const GDBusMethodInfo
*method
= iface
->methods
[m
];
189 g_print ("%s.%s \n", iface
->name
, method
->name
);
191 for (m
= 0; print_signals
&& iface
->signals
!= NULL
&& iface
->signals
[m
] != NULL
; m
++)
193 const GDBusSignalInfo
*signal
= iface
->signals
[m
];
194 g_print ("%s.%s \n", iface
->name
, signal
->name
);
197 g_dbus_node_info_unref (node
);
204 print_paths (GDBusConnection
*c
,
210 const gchar
*xml_data
;
214 if (!g_dbus_is_name (name
))
216 g_printerr (_("Error: %s is not a valid name\n"), name
);
221 result
= g_dbus_connection_call_sync (c
,
224 "org.freedesktop.DBus.Introspectable",
227 G_VARIANT_TYPE ("(s)"),
228 G_DBUS_CALL_FLAGS_NONE
,
234 g_printerr (_("Error: %s\n"), error
->message
);
235 g_error_free (error
);
238 g_variant_get (result
, "(&s)", &xml_data
);
240 //g_printerr ("xml='%s'", xml_data);
243 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
244 g_variant_unref (result
);
247 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
248 g_error_free (error
);
252 //g_printerr ("bar '%s'\n", path);
254 if (node
->interfaces
!= NULL
)
255 g_print ("%s \n", path
);
257 for (n
= 0; node
->nodes
!= NULL
&& node
->nodes
[n
] != NULL
; n
++)
261 //g_printerr ("foo '%s'\n", node->nodes[n].path);
263 if (g_strcmp0 (path
, "/") == 0)
264 s
= g_strdup_printf ("/%s", node
->nodes
[n
]->path
);
266 s
= g_strdup_printf ("%s/%s", path
, node
->nodes
[n
]->path
);
268 print_paths (c
, name
, s
);
272 g_dbus_node_info_unref (node
);
279 print_names (GDBusConnection
*c
,
280 gboolean include_unique_names
)
286 GHashTable
*name_set
;
290 name_set
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
293 result
= g_dbus_connection_call_sync (c
,
294 "org.freedesktop.DBus",
295 "/org/freedesktop/DBus",
296 "org.freedesktop.DBus",
299 G_VARIANT_TYPE ("(as)"),
300 G_DBUS_CALL_FLAGS_NONE
,
306 g_printerr (_("Error: %s\n"), error
->message
);
307 g_error_free (error
);
310 g_variant_get (result
, "(as)", &iter
);
311 while (g_variant_iter_loop (iter
, "s", &str
))
312 g_hash_table_add (name_set
, g_strdup (str
));
313 g_variant_iter_free (iter
);
314 g_variant_unref (result
);
317 result
= g_dbus_connection_call_sync (c
,
318 "org.freedesktop.DBus",
319 "/org/freedesktop/DBus",
320 "org.freedesktop.DBus",
321 "ListActivatableNames",
323 G_VARIANT_TYPE ("(as)"),
324 G_DBUS_CALL_FLAGS_NONE
,
330 g_printerr (_("Error: %s\n"), error
->message
);
331 g_error_free (error
);
334 g_variant_get (result
, "(as)", &iter
);
335 while (g_variant_iter_loop (iter
, "s", &str
))
336 g_hash_table_add (name_set
, g_strdup (str
));
337 g_variant_iter_free (iter
);
338 g_variant_unref (result
);
340 keys
= g_hash_table_get_keys (name_set
);
341 keys
= g_list_sort (keys
, (GCompareFunc
) g_strcmp0
);
342 for (l
= keys
; l
!= NULL
; l
= l
->next
)
344 const gchar
*name
= l
->data
;
345 if (!include_unique_names
&& g_str_has_prefix (name
, ":"))
348 g_print ("%s \n", name
);
353 g_hash_table_unref (name_set
);
356 /* ---------------------------------------------------------------------------------------------------- */
358 static gboolean opt_connection_system
= FALSE
;
359 static gboolean opt_connection_session
= FALSE
;
360 static gchar
*opt_connection_address
= NULL
;
362 static const GOptionEntry connection_entries
[] =
364 { "system", 'y', 0, G_OPTION_ARG_NONE
, &opt_connection_system
, N_("Connect to the system bus"), NULL
},
365 { "session", 'e', 0, G_OPTION_ARG_NONE
, &opt_connection_session
, N_("Connect to the session bus"), NULL
},
366 { "address", 'a', 0, G_OPTION_ARG_STRING
, &opt_connection_address
, N_("Connect to given D-Bus address"), NULL
},
370 static GOptionGroup
*
371 connection_get_group (void)
373 static GOptionGroup
*g
;
375 g
= g_option_group_new ("connection",
376 N_("Connection Endpoint Options:"),
377 N_("Options specifying the connection endpoint"),
380 g_option_group_set_translation_domain (g
, GETTEXT_PACKAGE
);
381 g_option_group_add_entries (g
, connection_entries
);
386 static GDBusConnection
*
387 connection_get_dbus_connection (GError
**error
)
393 /* First, ensure we have exactly one connect */
394 if (!opt_connection_system
&& !opt_connection_session
&& opt_connection_address
== NULL
)
399 _("No connection endpoint specified"));
402 else if ((opt_connection_system
&& (opt_connection_session
|| opt_connection_address
!= NULL
)) ||
403 (opt_connection_session
&& (opt_connection_system
|| opt_connection_address
!= NULL
)) ||
404 (opt_connection_address
!= NULL
&& (opt_connection_system
|| opt_connection_session
)))
409 _("Multiple connection endpoints specified"));
413 if (opt_connection_system
)
415 c
= g_bus_get_sync (G_BUS_TYPE_SYSTEM
, NULL
, error
);
417 else if (opt_connection_session
)
419 c
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, error
);
421 else if (opt_connection_address
!= NULL
)
423 c
= g_dbus_connection_new_for_address_sync (opt_connection_address
,
424 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
,
425 NULL
, /* GDBusAuthObserver */
426 NULL
, /* GCancellable */
434 /* ---------------------------------------------------------------------------------------------------- */
437 call_helper_get_method_in_signature (GDBusConnection
*c
,
440 const gchar
*interface_name
,
441 const gchar
*method_name
,
446 GDBusNodeInfo
*node_info
;
447 const gchar
*xml_data
;
448 GDBusInterfaceInfo
*interface_info
;
449 GDBusMethodInfo
*method_info
;
456 result
= g_dbus_connection_call_sync (c
,
459 "org.freedesktop.DBus.Introspectable",
462 G_VARIANT_TYPE ("(s)"),
463 G_DBUS_CALL_FLAGS_NONE
,
470 g_variant_get (result
, "(&s)", &xml_data
);
471 node_info
= g_dbus_node_info_new_for_xml (xml_data
, error
);
472 if (node_info
== NULL
)
475 interface_info
= g_dbus_node_info_lookup_interface (node_info
, interface_name
);
476 if (interface_info
== NULL
)
478 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
479 _("Warning: According to introspection data, interface “%s” does not exist\n"),
484 method_info
= g_dbus_interface_info_lookup_method (interface_info
, method_name
);
485 if (method_info
== NULL
)
487 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
488 _("Warning: According to introspection data, method “%s” does not exist on interface “%s”\n"),
494 ret
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_variant_type_free
);
495 for (n
= 0; method_info
->in_args
!= NULL
&& method_info
->in_args
[n
] != NULL
; n
++)
497 g_ptr_array_add (ret
, g_variant_type_new (method_info
->in_args
[n
]->signature
));
501 if (node_info
!= NULL
)
502 g_dbus_node_info_unref (node_info
);
504 g_variant_unref (result
);
509 /* ---------------------------------------------------------------------------------------------------- */
512 _g_variant_parse_me_harder (GVariantType
*type
,
513 const gchar
*given_str
,
521 str
= g_string_new ("\"");
522 for (n
= 0; given_str
[n
] != '\0'; n
++)
524 if (G_UNLIKELY (given_str
[n
] == '\"'))
525 g_string_append (str
, "\\\"");
527 g_string_append_c (str
, given_str
[n
]);
529 g_string_append_c (str
, '"');
530 s
= g_string_free (str
, FALSE
);
532 value
= g_variant_parse (type
,
542 /* ---------------------------------------------------------------------------------------------------- */
544 static gchar
*opt_emit_dest
= NULL
;
545 static gchar
*opt_emit_object_path
= NULL
;
546 static gchar
*opt_emit_signal
= NULL
;
548 static const GOptionEntry emit_entries
[] =
550 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_emit_dest
, N_("Optional destination for signal (unique name)"), NULL
},
551 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_emit_object_path
, N_("Object path to emit signal on"), NULL
},
552 { "signal", 's', 0, G_OPTION_ARG_STRING
, &opt_emit_signal
, N_("Signal and interface name"), NULL
},
557 handle_emit (gint
*argc
,
559 gboolean request_completion
,
560 const gchar
*completion_cur
,
561 const gchar
*completion_prev
)
568 GVariant
*parameters
;
569 gchar
*interface_name
;
571 GVariantBuilder builder
;
572 gboolean skip_dashes
;
575 gboolean complete_names
, complete_paths
, complete_signals
;
580 interface_name
= NULL
;
583 modify_argv0_for_command (argc
, argv
, "emit");
585 o
= g_option_context_new (NULL
);
586 g_option_context_set_help_enabled (o
, FALSE
);
587 g_option_context_set_summary (o
, _("Emit a signal."));
588 g_option_context_add_main_entries (o
, emit_entries
, GETTEXT_PACKAGE
);
589 g_option_context_add_group (o
, connection_get_group ());
591 complete_names
= FALSE
;
592 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
594 complete_names
= TRUE
;
595 remove_arg ((*argc
) - 1, argc
, argv
);
598 complete_paths
= FALSE
;
599 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
601 complete_paths
= TRUE
;
602 remove_arg ((*argc
) - 1, argc
, argv
);
605 complete_signals
= FALSE
;
606 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--signal") == 0)
608 complete_signals
= TRUE
;
609 remove_arg ((*argc
) - 1, argc
, argv
);
612 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
614 if (!request_completion
)
616 s
= g_option_context_get_help (o
, FALSE
, NULL
);
617 g_printerr ("%s", s
);
624 c
= connection_get_dbus_connection (&error
);
627 if (request_completion
)
629 if (g_strcmp0 (completion_prev
, "--address") == 0)
637 g_print ("--system \n--session \n--address \n");
642 g_printerr (_("Error connecting: %s\n"), error
->message
);
643 g_error_free (error
);
648 /* validate and complete destination (bus name) */
651 print_names (c
, FALSE
);
654 if (opt_emit_dest
== NULL
)
656 if (request_completion
)
657 g_print ("--dest \n");
659 g_printerr (_("Error: Destination is not specified\n"));
662 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
664 print_names (c
, g_str_has_prefix (opt_emit_dest
, ":"));
668 if (!request_completion
&& !g_dbus_is_unique_name (opt_emit_dest
))
670 g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest
);
674 /* validate and complete object path */
677 print_paths (c
, opt_emit_dest
, "/");
680 if (opt_emit_object_path
== NULL
)
682 if (request_completion
)
683 g_print ("--object-path \n");
685 g_printerr (_("Error: Object path is not specified\n"));
688 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
691 s
= g_strdup (opt_emit_object_path
);
692 p
= strrchr (s
, '/');
699 print_paths (c
, opt_emit_dest
, s
);
703 if (!request_completion
&& !g_variant_is_object_path (opt_emit_object_path
))
705 g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path
);
709 /* validate and complete signal (interface + signal name) */
710 if (complete_signals
)
712 print_methods_and_signals (c
, opt_emit_dest
, opt_emit_object_path
, FALSE
, TRUE
);
715 if (opt_emit_signal
== NULL
)
717 if (request_completion
)
718 g_print ("--signal \n");
720 g_printerr (_("Error: Signal name is not specified\n"));
723 if (request_completion
&& g_strcmp0 ("--signal", completion_prev
) == 0)
725 print_methods_and_signals (c
, opt_emit_dest
, opt_emit_object_path
, FALSE
, TRUE
);
728 s
= strrchr (opt_emit_signal
, '.');
729 if (!request_completion
&& s
== NULL
)
731 g_printerr (_("Error: Signal name “%s” is invalid\n"), opt_emit_signal
);
734 signal_name
= g_strdup (s
+ 1);
735 interface_name
= g_strndup (opt_emit_signal
, s
- opt_emit_signal
);
737 /* All done with completion now */
738 if (request_completion
)
741 if (!g_dbus_is_interface_name (interface_name
))
743 g_printerr (_("Error: %s is not a valid interface name\n"), interface_name
);
747 if (!g_dbus_is_member_name (signal_name
))
749 g_printerr (_("Error: %s is not a valid member name\n"), signal_name
);
753 /* Read parameters */
754 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
757 for (n
= 1; n
< (guint
) *argc
; n
++)
761 /* Under certain conditions, g_option_context_parse returns the "--"
762 itself (setting off unparsed arguments), too: */
763 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
770 value
= g_variant_parse (NULL
,
779 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
780 g_error_free (error
);
782 value
= _g_variant_parse_me_harder (NULL
, (*argv
)[n
], &error
);
785 /* Use the original non-"parse-me-harder" error */
786 g_printerr (_("Error parsing parameter %d: %s\n"),
789 g_error_free (error
);
791 g_variant_builder_clear (&builder
);
796 g_variant_builder_add_value (&builder
, value
);
799 parameters
= g_variant_builder_end (&builder
);
801 if (parameters
!= NULL
)
802 parameters
= g_variant_ref_sink (parameters
);
803 if (!g_dbus_connection_emit_signal (c
,
805 opt_emit_object_path
,
811 g_printerr (_("Error: %s\n"), error
->message
);
812 g_error_free (error
);
816 if (!g_dbus_connection_flush_sync (c
, NULL
, &error
))
818 g_printerr (_("Error flushing connection: %s\n"), error
->message
);
819 g_error_free (error
);
828 if (parameters
!= NULL
)
829 g_variant_unref (parameters
);
830 g_free (interface_name
);
831 g_free (signal_name
);
832 g_option_context_free (o
);
836 /* ---------------------------------------------------------------------------------------------------- */
838 static gchar
*opt_call_dest
= NULL
;
839 static gchar
*opt_call_object_path
= NULL
;
840 static gchar
*opt_call_method
= NULL
;
841 static gint opt_call_timeout
= -1;
843 static const GOptionEntry call_entries
[] =
845 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_call_dest
, N_("Destination name to invoke method on"), NULL
},
846 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_call_object_path
, N_("Object path to invoke method on"), NULL
},
847 { "method", 'm', 0, G_OPTION_ARG_STRING
, &opt_call_method
, N_("Method and interface name"), NULL
},
848 { "timeout", 't', 0, G_OPTION_ARG_INT
, &opt_call_timeout
, N_("Timeout in seconds"), NULL
},
853 handle_call (gint
*argc
,
855 gboolean request_completion
,
856 const gchar
*completion_cur
,
857 const gchar
*completion_prev
)
864 GVariant
*parameters
;
865 gchar
*interface_name
;
868 GPtrArray
*in_signature_types
;
869 gboolean complete_names
;
870 gboolean complete_paths
;
871 gboolean complete_methods
;
872 GVariantBuilder builder
;
873 gboolean skip_dashes
;
880 interface_name
= NULL
;
883 in_signature_types
= NULL
;
885 modify_argv0_for_command (argc
, argv
, "call");
887 o
= g_option_context_new (NULL
);
888 g_option_context_set_help_enabled (o
, FALSE
);
889 g_option_context_set_summary (o
, _("Invoke a method on a remote object."));
890 g_option_context_add_main_entries (o
, call_entries
, GETTEXT_PACKAGE
);
891 g_option_context_add_group (o
, connection_get_group ());
893 complete_names
= FALSE
;
894 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
896 complete_names
= TRUE
;
897 remove_arg ((*argc
) - 1, argc
, argv
);
900 complete_paths
= FALSE
;
901 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
903 complete_paths
= TRUE
;
904 remove_arg ((*argc
) - 1, argc
, argv
);
907 complete_methods
= FALSE
;
908 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--method") == 0)
910 complete_methods
= TRUE
;
911 remove_arg ((*argc
) - 1, argc
, argv
);
914 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
916 if (!request_completion
)
918 s
= g_option_context_get_help (o
, FALSE
, NULL
);
919 g_printerr ("%s", s
);
926 c
= connection_get_dbus_connection (&error
);
929 if (request_completion
)
931 if (g_strcmp0 (completion_prev
, "--address") == 0)
939 g_print ("--system \n--session \n--address \n");
944 g_printerr (_("Error connecting: %s\n"), error
->message
);
945 g_error_free (error
);
950 /* validate and complete destination (bus name) */
953 print_names (c
, FALSE
);
956 if (opt_call_dest
== NULL
)
958 if (request_completion
)
959 g_print ("--dest \n");
961 g_printerr (_("Error: Destination is not specified\n"));
964 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
966 print_names (c
, g_str_has_prefix (opt_call_dest
, ":"));
970 if (!request_completion
&& !g_dbus_is_name (opt_call_dest
))
972 g_printerr (_("Error: %s is not a valid bus name\n"), opt_call_dest
);
976 /* validate and complete object path */
979 print_paths (c
, opt_call_dest
, "/");
982 if (opt_call_object_path
== NULL
)
984 if (request_completion
)
985 g_print ("--object-path \n");
987 g_printerr (_("Error: Object path is not specified\n"));
990 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
993 s
= g_strdup (opt_call_object_path
);
994 p
= strrchr (s
, '/');
1001 print_paths (c
, opt_call_dest
, s
);
1005 if (!request_completion
&& !g_variant_is_object_path (opt_call_object_path
))
1007 g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path
);
1011 /* validate and complete method (interface + method name) */
1012 if (complete_methods
)
1014 print_methods_and_signals (c
, opt_call_dest
, opt_call_object_path
, TRUE
, FALSE
);
1017 if (opt_call_method
== NULL
)
1019 if (request_completion
)
1020 g_print ("--method \n");
1022 g_printerr (_("Error: Method name is not specified\n"));
1025 if (request_completion
&& g_strcmp0 ("--method", completion_prev
) == 0)
1027 print_methods_and_signals (c
, opt_call_dest
, opt_call_object_path
, TRUE
, FALSE
);
1030 s
= strrchr (opt_call_method
, '.');
1031 if (!request_completion
&& s
== NULL
)
1033 g_printerr (_("Error: Method name “%s” is invalid\n"), opt_call_method
);
1036 method_name
= g_strdup (s
+ 1);
1037 interface_name
= g_strndup (opt_call_method
, s
- opt_call_method
);
1039 /* All done with completion now */
1040 if (request_completion
)
1043 /* Introspect, for easy conversion - it's not fatal if we can't do this */
1044 in_signature_types
= call_helper_get_method_in_signature (c
,
1046 opt_call_object_path
,
1050 if (in_signature_types
== NULL
)
1052 //g_printerr ("Error getting introspection data: %s\n", error->message);
1053 g_error_free (error
);
1057 /* Read parameters */
1058 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
1061 for (n
= 1; n
< (guint
) *argc
; n
++)
1066 /* Under certain conditions, g_option_context_parse returns the "--"
1067 itself (setting off unparsed arguments), too: */
1068 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
1070 skip_dashes
= FALSE
;
1075 if (in_signature_types
!= NULL
)
1077 if (parm
>= in_signature_types
->len
)
1079 /* Only warn for the first param */
1080 if (parm
== in_signature_types
->len
)
1082 g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n",
1083 in_signature_types
->len
);
1088 type
= in_signature_types
->pdata
[parm
];
1093 value
= g_variant_parse (type
,
1102 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
1103 g_error_free (error
);
1105 value
= _g_variant_parse_me_harder (type
, (*argv
)[n
], &error
);
1110 s
= g_variant_type_dup_string (type
);
1111 g_printerr (_("Error parsing parameter %d of type “%s”: %s\n"),
1119 g_printerr (_("Error parsing parameter %d: %s\n"),
1123 g_error_free (error
);
1124 g_variant_builder_clear (&builder
);
1130 g_variant_builder_add_value (&builder
, value
);
1133 parameters
= g_variant_builder_end (&builder
);
1135 if (parameters
!= NULL
)
1136 parameters
= g_variant_ref_sink (parameters
);
1137 result
= g_dbus_connection_call_sync (c
,
1139 opt_call_object_path
,
1144 G_DBUS_CALL_FLAGS_NONE
,
1145 opt_call_timeout
> 0 ? opt_call_timeout
* 1000 : opt_call_timeout
,
1150 g_printerr (_("Error: %s\n"), error
->message
);
1152 if (g_error_matches (error
, G_DBUS_ERROR
, G_DBUS_ERROR_INVALID_ARGS
) && in_signature_types
!= NULL
)
1154 if (in_signature_types
->len
> 0)
1157 s
= g_string_new (NULL
);
1159 for (n
= 0; n
< in_signature_types
->len
; n
++)
1161 GVariantType
*type
= in_signature_types
->pdata
[n
];
1162 g_string_append_len (s
,
1163 g_variant_type_peek_string (type
),
1164 g_variant_type_get_string_length (type
));
1167 g_printerr ("(According to introspection data, you need to pass '%s')\n", s
->str
);
1168 g_string_free (s
, TRUE
);
1171 g_printerr ("(According to introspection data, you need to pass no arguments)\n");
1174 g_error_free (error
);
1178 s
= g_variant_print (result
, TRUE
);
1179 g_print ("%s\n", s
);
1185 if (in_signature_types
!= NULL
)
1186 g_ptr_array_unref (in_signature_types
);
1188 g_variant_unref (result
);
1191 if (parameters
!= NULL
)
1192 g_variant_unref (parameters
);
1193 g_free (interface_name
);
1194 g_free (method_name
);
1195 g_option_context_free (o
);
1199 /* ---------------------------------------------------------------------------------------------------- */
1201 static gchar
*opt_introspect_dest
= NULL
;
1202 static gchar
*opt_introspect_object_path
= NULL
;
1203 static gboolean opt_introspect_xml
= FALSE
;
1204 static gboolean opt_introspect_recurse
= FALSE
;
1205 static gboolean opt_introspect_only_properties
= FALSE
;
1208 dump_annotation (const GDBusAnnotationInfo
*o
,
1210 gboolean ignore_indent
)
1213 g_print ("%*s@%s(\"%s\")\n",
1214 ignore_indent
? 0 : indent
, "",
1217 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1218 dump_annotation (o
->annotations
[n
], indent
+ 2, FALSE
);
1222 dump_arg (const GDBusArgInfo
*o
,
1224 const gchar
*direction
,
1225 gboolean ignore_indent
,
1226 gboolean include_newline
)
1230 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1232 dump_annotation (o
->annotations
[n
], indent
, ignore_indent
);
1233 ignore_indent
= FALSE
;
1236 g_print ("%*s%s%s %s%s",
1237 ignore_indent
? 0 : indent
, "",
1241 include_newline
? ",\n" : "");
1245 count_args (GDBusArgInfo
**args
)
1251 while (args
[n
] != NULL
)
1258 dump_method (const GDBusMethodInfo
*o
,
1264 guint total_num_args
;
1266 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1267 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1269 g_print ("%*s%s(", indent
, "", o
->name
);
1270 name_len
= strlen (o
->name
);
1271 total_num_args
= count_args (o
->in_args
) + count_args (o
->out_args
);
1272 for (n
= 0, m
= 0; o
->in_args
!= NULL
&& o
->in_args
[n
] != NULL
; n
++, m
++)
1274 gboolean ignore_indent
= (m
== 0);
1275 gboolean include_newline
= (m
!= total_num_args
- 1);
1277 dump_arg (o
->in_args
[n
],
1278 indent
+ name_len
+ 1,
1283 for (n
= 0; o
->out_args
!= NULL
&& o
->out_args
[n
] != NULL
; n
++, m
++)
1285 gboolean ignore_indent
= (m
== 0);
1286 gboolean include_newline
= (m
!= total_num_args
- 1);
1287 dump_arg (o
->out_args
[n
],
1288 indent
+ name_len
+ 1,
1297 dump_signal (const GDBusSignalInfo
*o
,
1302 guint total_num_args
;
1304 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1305 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1307 g_print ("%*s%s(", indent
, "", o
->name
);
1308 name_len
= strlen (o
->name
);
1309 total_num_args
= count_args (o
->args
);
1310 for (n
= 0; o
->args
!= NULL
&& o
->args
[n
] != NULL
; n
++)
1312 gboolean ignore_indent
= (n
== 0);
1313 gboolean include_newline
= (n
!= total_num_args
- 1);
1314 dump_arg (o
->args
[n
],
1315 indent
+ name_len
+ 1,
1324 dump_property (const GDBusPropertyInfo
*o
,
1328 const gchar
*access
;
1331 if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
1332 access
= "readonly";
1333 else if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
)
1334 access
= "writeonly";
1335 else if (o
->flags
== (G_DBUS_PROPERTY_INFO_FLAGS_READABLE
| G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
))
1336 access
= "readwrite";
1338 g_assert_not_reached ();
1340 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1341 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1345 gchar
*s
= g_variant_print (value
, FALSE
);
1346 g_print ("%*s%s %s %s = %s;\n", indent
, "", access
, o
->signature
, o
->name
, s
);
1351 g_print ("%*s%s %s %s;\n", indent
, "", access
, o
->signature
, o
->name
);
1356 dump_interface (GDBusConnection
*c
,
1358 const GDBusInterfaceInfo
*o
,
1360 const gchar
*object_path
)
1363 GHashTable
*properties
;
1365 properties
= g_hash_table_new_full (g_str_hash
,
1368 (GDestroyNotify
) g_variant_unref
);
1370 /* Try to get properties */
1371 if (c
!= NULL
&& name
!= NULL
&& object_path
!= NULL
&& o
->properties
!= NULL
)
1374 result
= g_dbus_connection_call_sync (c
,
1377 "org.freedesktop.DBus.Properties",
1379 g_variant_new ("(s)", o
->name
),
1381 G_DBUS_CALL_FLAGS_NONE
,
1387 if (g_variant_is_of_type (result
, G_VARIANT_TYPE ("(a{sv})")))
1391 g_variant_get (result
,
1394 while ((item
= g_variant_iter_next_value (iter
)))
1398 g_variant_get (item
,
1403 g_hash_table_insert (properties
, key
, g_variant_ref (value
));
1406 g_variant_unref (result
);
1411 for (n
= 0; o
->properties
!= NULL
&& o
->properties
[n
] != NULL
; n
++)
1413 result
= g_dbus_connection_call_sync (c
,
1416 "org.freedesktop.DBus.Properties",
1418 g_variant_new ("(ss)", o
->name
, o
->properties
[n
]->name
),
1419 G_VARIANT_TYPE ("(v)"),
1420 G_DBUS_CALL_FLAGS_NONE
,
1426 GVariant
*property_value
;
1427 g_variant_get (result
,
1430 g_hash_table_insert (properties
,
1431 g_strdup (o
->properties
[n
]->name
),
1432 g_variant_ref (property_value
));
1433 g_variant_unref (result
);
1439 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1440 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1442 g_print ("%*sinterface %s {\n", indent
, "", o
->name
);
1443 if (o
->methods
!= NULL
&& !opt_introspect_only_properties
)
1445 g_print ("%*s methods:\n", indent
, "");
1446 for (n
= 0; o
->methods
[n
] != NULL
; n
++)
1447 dump_method (o
->methods
[n
], indent
+ 4);
1449 if (o
->signals
!= NULL
&& !opt_introspect_only_properties
)
1451 g_print ("%*s signals:\n", indent
, "");
1452 for (n
= 0; o
->signals
[n
] != NULL
; n
++)
1453 dump_signal (o
->signals
[n
], indent
+ 4);
1455 if (o
->properties
!= NULL
)
1457 g_print ("%*s properties:\n", indent
, "");
1458 for (n
= 0; o
->properties
[n
] != NULL
; n
++)
1460 dump_property (o
->properties
[n
],
1462 g_hash_table_lookup (properties
, (o
->properties
[n
])->name
));
1468 g_hash_table_unref (properties
);
1472 introspect_do (GDBusConnection
*c
,
1473 const gchar
*object_path
,
1477 dump_node (GDBusConnection
*c
,
1479 const GDBusNodeInfo
*o
,
1481 const gchar
*object_path
,
1485 const gchar
*object_path_to_print
;
1487 object_path_to_print
= object_path
;
1488 if (o
->path
!= NULL
)
1489 object_path_to_print
= o
->path
;
1491 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1492 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1494 g_print ("%*snode %s", indent
, "", object_path_to_print
!= NULL
? object_path_to_print
: "(not set)");
1495 if (o
->interfaces
!= NULL
|| o
->nodes
!= NULL
)
1498 for (n
= 0; o
->interfaces
!= NULL
&& o
->interfaces
[n
] != NULL
; n
++)
1500 if (opt_introspect_only_properties
)
1502 if (o
->interfaces
[n
]->properties
!= NULL
&& o
->interfaces
[n
]->properties
[0] != NULL
)
1503 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1507 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1510 for (n
= 0; o
->nodes
!= NULL
&& o
->nodes
[n
] != NULL
; n
++)
1515 if (g_variant_is_object_path (o
->nodes
[n
]->path
))
1517 child_path
= g_strdup (o
->nodes
[n
]->path
);
1518 /* avoid infinite loops */
1519 if (g_str_has_prefix (child_path
, object_path
))
1521 introspect_do (c
, child_path
, indent
+ 2);
1525 g_print ("Skipping path %s that is not enclosed by parent %s\n",
1526 child_path
, object_path
);
1531 if (g_strcmp0 (object_path
, "/") == 0)
1532 child_path
= g_strdup_printf ("/%s", o
->nodes
[n
]->path
);
1534 child_path
= g_strdup_printf ("%s/%s", object_path
, o
->nodes
[n
]->path
);
1535 introspect_do (c
, child_path
, indent
+ 2);
1537 g_free (child_path
);
1541 dump_node (NULL
, NULL
, o
->nodes
[n
], indent
+ 2, NULL
, recurse
);
1553 static const GOptionEntry introspect_entries
[] =
1555 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_introspect_dest
, N_("Destination name to introspect"), NULL
},
1556 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_introspect_object_path
, N_("Object path to introspect"), NULL
},
1557 { "xml", 'x', 0, G_OPTION_ARG_NONE
, &opt_introspect_xml
, N_("Print XML"), NULL
},
1558 { "recurse", 'r', 0, G_OPTION_ARG_NONE
, &opt_introspect_recurse
, N_("Introspect children"), NULL
},
1559 { "only-properties", 'p', 0, G_OPTION_ARG_NONE
, &opt_introspect_only_properties
, N_("Only print properties"), NULL
},
1564 introspect_do (GDBusConnection
*c
,
1565 const gchar
*object_path
,
1570 GDBusNodeInfo
*node
;
1572 const gchar
*xml_data
;
1579 result
= g_dbus_connection_call_sync (c
,
1580 opt_introspect_dest
,
1582 "org.freedesktop.DBus.Introspectable",
1585 G_VARIANT_TYPE ("(s)"),
1586 G_DBUS_CALL_FLAGS_NONE
,
1592 g_printerr (_("Error: %s\n"), error
->message
);
1593 g_error_free (error
);
1596 g_variant_get (result
, "(&s)", &xml_data
);
1598 if (opt_introspect_xml
)
1600 g_print ("%s", xml_data
);
1605 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
1608 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
1609 g_error_free (error
);
1613 dump_node (c
, opt_introspect_dest
, node
, indent
, object_path
, opt_introspect_recurse
);
1620 g_dbus_node_info_unref (node
);
1622 g_variant_unref (result
);
1627 handle_introspect (gint
*argc
,
1629 gboolean request_completion
,
1630 const gchar
*completion_cur
,
1631 const gchar
*completion_prev
)
1638 gboolean complete_names
;
1639 gboolean complete_paths
;
1644 modify_argv0_for_command (argc
, argv
, "introspect");
1646 o
= g_option_context_new (NULL
);
1647 if (request_completion
)
1648 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1649 g_option_context_set_help_enabled (o
, FALSE
);
1650 g_option_context_set_summary (o
, _("Introspect a remote object."));
1651 g_option_context_add_main_entries (o
, introspect_entries
, GETTEXT_PACKAGE
);
1652 g_option_context_add_group (o
, connection_get_group ());
1654 complete_names
= FALSE
;
1655 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1657 complete_names
= TRUE
;
1658 remove_arg ((*argc
) - 1, argc
, argv
);
1661 complete_paths
= FALSE
;
1662 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1664 complete_paths
= TRUE
;
1665 remove_arg ((*argc
) - 1, argc
, argv
);
1668 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1670 if (!request_completion
)
1672 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1673 g_printerr ("%s", s
);
1680 c
= connection_get_dbus_connection (&error
);
1683 if (request_completion
)
1685 if (g_strcmp0 (completion_prev
, "--address") == 0)
1693 g_print ("--system \n--session \n--address \n");
1698 g_printerr (_("Error connecting: %s\n"), error
->message
);
1699 g_error_free (error
);
1706 print_names (c
, FALSE
);
1709 /* this only makes sense on message bus connections */
1710 if (opt_introspect_dest
== NULL
)
1712 if (request_completion
)
1713 g_print ("--dest \n");
1715 g_printerr (_("Error: Destination is not specified\n"));
1718 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1720 print_names (c
, g_str_has_prefix (opt_introspect_dest
, ":"));
1726 print_paths (c
, opt_introspect_dest
, "/");
1730 if (!request_completion
&& !g_dbus_is_name (opt_introspect_dest
))
1732 g_printerr (_("Error: %s is not a valid bus name\n"), opt_introspect_dest
);
1736 if (opt_introspect_object_path
== NULL
)
1738 if (request_completion
)
1739 g_print ("--object-path \n");
1741 g_printerr (_("Error: Object path is not specified\n"));
1744 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1747 s
= g_strdup (opt_introspect_object_path
);
1748 p
= strrchr (s
, '/');
1755 print_paths (c
, opt_introspect_dest
, s
);
1759 if (!request_completion
&& !g_variant_is_object_path (opt_introspect_object_path
))
1761 g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path
);
1765 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_recurse
)
1767 g_print ("--recurse \n");
1770 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_only_properties
)
1772 g_print ("--only-properties \n");
1775 /* All done with completion now */
1776 if (request_completion
)
1779 if (!introspect_do (c
, opt_introspect_object_path
, 0))
1787 g_option_context_free (o
);
1791 /* ---------------------------------------------------------------------------------------------------- */
1793 static gchar
*opt_monitor_dest
= NULL
;
1794 static gchar
*opt_monitor_object_path
= NULL
;
1796 static guint monitor_filter_id
= 0;
1799 monitor_signal_cb (GDBusConnection
*connection
,
1800 const gchar
*sender_name
,
1801 const gchar
*object_path
,
1802 const gchar
*interface_name
,
1803 const gchar
*signal_name
,
1804 GVariant
*parameters
,
1808 s
= g_variant_print (parameters
, TRUE
);
1809 g_print ("%s: %s.%s %s\n",
1818 monitor_on_name_appeared (GDBusConnection
*connection
,
1820 const gchar
*name_owner
,
1823 g_print ("The name %s is owned by %s\n", name
, name_owner
);
1824 g_assert (monitor_filter_id
== 0);
1825 monitor_filter_id
= g_dbus_connection_signal_subscribe (connection
,
1827 NULL
, /* any interface */
1828 NULL
, /* any member */
1829 opt_monitor_object_path
,
1831 G_DBUS_SIGNAL_FLAGS_NONE
,
1833 NULL
, /* user_data */
1834 NULL
); /* user_data destroy notify */
1838 monitor_on_name_vanished (GDBusConnection
*connection
,
1842 g_print ("The name %s does not have an owner\n", name
);
1844 if (monitor_filter_id
!= 0)
1846 g_dbus_connection_signal_unsubscribe (connection
, monitor_filter_id
);
1847 monitor_filter_id
= 0;
1851 static const GOptionEntry monitor_entries
[] =
1853 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_monitor_dest
, N_("Destination name to monitor"), NULL
},
1854 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_monitor_object_path
, N_("Object path to monitor"), NULL
},
1859 handle_monitor (gint
*argc
,
1861 gboolean request_completion
,
1862 const gchar
*completion_cur
,
1863 const gchar
*completion_prev
)
1870 gboolean complete_names
;
1871 gboolean complete_paths
;
1877 modify_argv0_for_command (argc
, argv
, "monitor");
1879 o
= g_option_context_new (NULL
);
1880 if (request_completion
)
1881 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1882 g_option_context_set_help_enabled (o
, FALSE
);
1883 g_option_context_set_summary (o
, _("Monitor a remote object."));
1884 g_option_context_add_main_entries (o
, monitor_entries
, GETTEXT_PACKAGE
);
1885 g_option_context_add_group (o
, connection_get_group ());
1887 complete_names
= FALSE
;
1888 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1890 complete_names
= TRUE
;
1891 remove_arg ((*argc
) - 1, argc
, argv
);
1894 complete_paths
= FALSE
;
1895 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1897 complete_paths
= TRUE
;
1898 remove_arg ((*argc
) - 1, argc
, argv
);
1901 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1903 if (!request_completion
)
1905 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1906 g_printerr ("%s", s
);
1913 c
= connection_get_dbus_connection (&error
);
1916 if (request_completion
)
1918 if (g_strcmp0 (completion_prev
, "--address") == 0)
1926 g_print ("--system \n--session \n--address \n");
1931 g_printerr (_("Error connecting: %s\n"), error
->message
);
1932 g_error_free (error
);
1937 /* Monitoring doesn’t make sense on a non-message-bus connection. */
1938 if (g_dbus_connection_get_unique_name (c
) == NULL
)
1940 if (!request_completion
)
1941 g_printerr (_("Error: can’t monitor a non-message-bus connection\n"));
1947 print_names (c
, FALSE
);
1950 /* this only makes sense on message bus connections */
1951 if (opt_monitor_dest
== NULL
)
1953 if (request_completion
)
1954 g_print ("--dest \n");
1956 g_printerr (_("Error: Destination is not specified\n"));
1959 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1961 print_names (c
, g_str_has_prefix (opt_monitor_dest
, ":"));
1965 if (!request_completion
&& !g_dbus_is_name (opt_monitor_dest
))
1967 g_printerr (_("Error: %s is not a valid bus name\n"), opt_monitor_dest
);
1973 print_paths (c
, opt_monitor_dest
, "/");
1976 if (opt_monitor_object_path
== NULL
)
1978 if (request_completion
)
1980 g_print ("--object-path \n");
1983 /* it's fine to not have an object path */
1985 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1988 s
= g_strdup (opt_monitor_object_path
);
1989 p
= strrchr (s
, '/');
1996 print_paths (c
, opt_monitor_dest
, s
);
2000 if (!request_completion
&& (opt_monitor_object_path
!= NULL
&& !g_variant_is_object_path (opt_monitor_object_path
)))
2002 g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path
);
2006 /* All done with completion now */
2007 if (request_completion
)
2010 if (opt_monitor_object_path
!= NULL
)
2011 g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path
, opt_monitor_dest
);
2013 g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest
);
2015 loop
= g_main_loop_new (NULL
, FALSE
);
2016 g_bus_watch_name_on_connection (c
,
2018 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
2019 monitor_on_name_appeared
,
2020 monitor_on_name_vanished
,
2024 g_main_loop_run (loop
);
2025 g_main_loop_unref (loop
);
2032 g_option_context_free (o
);
2036 /* ---------------------------------------------------------------------------------------------------- */
2038 static gboolean opt_wait_activate_set
= FALSE
;
2039 static gchar
*opt_wait_activate_name
= NULL
;
2040 static gint64 opt_wait_timeout
= 0; /* no timeout */
2043 WAIT_STATE_RUNNING
, /* waiting to see the service */
2044 WAIT_STATE_SUCCESS
, /* seen it successfully */
2045 WAIT_STATE_TIMEOUT
, /* timed out before seeing it */
2049 opt_wait_activate_cb (const gchar
*option_name
,
2054 /* @value may be NULL */
2055 opt_wait_activate_set
= TRUE
;
2056 opt_wait_activate_name
= g_strdup (value
);
2061 static const GOptionEntry wait_entries
[] =
2063 { "activate", 'a', G_OPTION_FLAG_OPTIONAL_ARG
, G_OPTION_ARG_CALLBACK
,
2064 opt_wait_activate_cb
,
2065 N_("Service to activate before waiting for the other one (well-known name)"),
2067 { "timeout", 't', 0, G_OPTION_ARG_INT64
, &opt_wait_timeout
,
2068 N_("Timeout to wait for before exiting with an error (seconds); 0 for "
2069 "no timeout (default)"), "SECS" },
2074 wait_name_appeared_cb (GDBusConnection
*connection
,
2076 const gchar
*name_owner
,
2079 WaitState
*wait_state
= user_data
;
2081 *wait_state
= WAIT_STATE_SUCCESS
;
2085 wait_timeout_cb (gpointer user_data
)
2087 WaitState
*wait_state
= user_data
;
2089 *wait_state
= WAIT_STATE_TIMEOUT
;
2091 /* Removed in handle_wait(). */
2092 return G_SOURCE_CONTINUE
;
2096 handle_wait (gint
*argc
,
2098 gboolean request_completion
,
2099 const gchar
*completion_cur
,
2100 const gchar
*completion_prev
)
2107 guint watch_id
, timer_id
= 0, activate_watch_id
;
2108 const gchar
*activate_service
, *wait_service
;
2109 WaitState wait_state
= WAIT_STATE_RUNNING
;
2114 modify_argv0_for_command (argc
, argv
, "wait");
2116 o
= g_option_context_new (_("[OPTION…] BUS-NAME"));
2117 g_option_context_set_help_enabled (o
, FALSE
);
2118 g_option_context_set_summary (o
, _("Wait for a bus name to appear."));
2119 g_option_context_add_main_entries (o
, wait_entries
, GETTEXT_PACKAGE
);
2120 g_option_context_add_group (o
, connection_get_group ());
2122 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
2124 if (!request_completion
)
2126 s
= g_option_context_get_help (o
, FALSE
, NULL
);
2127 g_printerr ("%s", s
);
2134 c
= connection_get_dbus_connection (&error
);
2137 if (request_completion
)
2139 if (g_strcmp0 (completion_prev
, "--address") == 0)
2147 g_print ("--system \n--session \n--address \n");
2152 g_printerr (_("Error connecting: %s\n"), error
->message
);
2153 g_error_free (error
);
2158 /* All done with completion now */
2159 if (request_completion
)
2163 * Try and disentangle the command line arguments, with the aim of supporting:
2164 * gdbus wait --session --activate ActivateName WaitName
2165 * gdbus wait --session --activate ActivateAndWaitName
2166 * gdbus wait --activate --session ActivateAndWaitName
2167 * gdbus wait --session WaitName
2169 if (*argc
== 2 && opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2171 activate_service
= opt_wait_activate_name
;
2172 wait_service
= (*argv
)[1];
2174 else if (*argc
== 2 &&
2175 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2177 activate_service
= (*argv
)[1];
2178 wait_service
= (*argv
)[1];
2180 else if (*argc
== 2 && !opt_wait_activate_set
)
2182 activate_service
= NULL
; /* disabled */
2183 wait_service
= (*argv
)[1];
2185 else if (*argc
== 1 &&
2186 opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2188 activate_service
= opt_wait_activate_name
;
2189 wait_service
= opt_wait_activate_name
;
2191 else if (*argc
== 1 &&
2192 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2194 g_printerr (_("Error: A service to activate for must be specified.\n"));
2197 else if (*argc
== 1 && !opt_wait_activate_set
)
2199 g_printerr (_("Error: A service to wait for must be specified.\n"));
2202 else /* if (*argc > 2) */
2204 g_printerr (_("Error: Too many arguments.\n"));
2208 if (activate_service
!= NULL
&&
2209 (!g_dbus_is_name (activate_service
) ||
2210 g_dbus_is_unique_name (activate_service
)))
2212 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2217 if (!g_dbus_is_name (wait_service
) || g_dbus_is_unique_name (wait_service
))
2219 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2224 /* Start the prerequisite service if needed. */
2225 if (activate_service
!= NULL
)
2227 activate_watch_id
= g_bus_watch_name_on_connection (c
, activate_service
,
2228 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
2234 activate_watch_id
= 0;
2237 /* Wait for the expected name to appear. */
2238 watch_id
= g_bus_watch_name_on_connection (c
,
2240 G_BUS_NAME_WATCHER_FLAGS_NONE
,
2241 wait_name_appeared_cb
,
2242 NULL
, &wait_state
, NULL
);
2244 /* Safety timeout. */
2245 if (opt_wait_timeout
> 0)
2246 timer_id
= g_timeout_add (opt_wait_timeout
, wait_timeout_cb
, &wait_state
);
2248 while (wait_state
== WAIT_STATE_RUNNING
)
2249 g_main_context_iteration (NULL
, TRUE
);
2251 g_bus_unwatch_name (watch_id
);
2253 g_source_remove (timer_id
);
2254 if (activate_watch_id
!= 0)
2255 g_bus_unwatch_name (activate_watch_id
);
2257 ret
= (wait_state
== WAIT_STATE_SUCCESS
);
2260 g_clear_object (&c
);
2261 g_option_context_free (o
);
2262 g_free (opt_wait_activate_name
);
2263 opt_wait_activate_name
= NULL
;
2268 /* ---------------------------------------------------------------------------------------------------- */
2271 pick_word_at (const gchar
*s
,
2273 gint
*out_word_begins_at
)
2280 if (out_word_begins_at
!= NULL
)
2281 *out_word_begins_at
= -1;
2285 if (g_ascii_isspace (s
[cursor
]) && ((cursor
> 0 && g_ascii_isspace(s
[cursor
-1])) || cursor
== 0))
2287 if (out_word_begins_at
!= NULL
)
2288 *out_word_begins_at
= cursor
;
2289 return g_strdup ("");
2292 while (!g_ascii_isspace (s
[cursor
- 1]) && cursor
> 0)
2297 while (!g_ascii_isspace (s
[end
]) && s
[end
] != '\0')
2300 if (out_word_begins_at
!= NULL
)
2301 *out_word_begins_at
= begin
;
2303 return g_strndup (s
+ begin
, end
- begin
);
2307 main (gint argc
, gchar
*argv
[])
2310 const gchar
*command
;
2311 gboolean request_completion
;
2312 gchar
*completion_cur
;
2313 gchar
*completion_prev
;
2318 setlocale (LC_ALL
, "");
2319 textdomain (GETTEXT_PACKAGE
);
2322 tmp
= _glib_get_locale_dir ();
2323 bindtextdomain (GETTEXT_PACKAGE
, tmp
);
2326 bindtextdomain (GETTEXT_PACKAGE
, GLIB_LOCALE_DIR
);
2329 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2330 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
2334 completion_cur
= NULL
;
2335 completion_prev
= NULL
;
2339 usage (&argc
, &argv
, FALSE
);
2343 request_completion
= FALSE
;
2345 //completion_debug ("---- argc=%d --------------------------------------------------------", argc);
2349 if (g_strcmp0 (command
, "help") == 0)
2351 if (request_completion
)
2357 usage (&argc
, &argv
, TRUE
);
2362 else if (g_strcmp0 (command
, "emit") == 0)
2364 if (handle_emit (&argc
,
2372 else if (g_strcmp0 (command
, "call") == 0)
2374 if (handle_call (&argc
,
2382 else if (g_strcmp0 (command
, "introspect") == 0)
2384 if (handle_introspect (&argc
,
2392 else if (g_strcmp0 (command
, "monitor") == 0)
2394 if (handle_monitor (&argc
,
2402 else if (g_strcmp0 (command
, "wait") == 0)
2404 if (handle_wait (&argc
,
2412 else if (g_strcmp0 (command
, "complete") == 0 && argc
== 4 && !request_completion
)
2414 const gchar
*completion_line
;
2415 gchar
**completion_argv
;
2416 gint completion_argc
;
2417 gint completion_point
;
2421 request_completion
= TRUE
;
2423 completion_line
= argv
[2];
2424 completion_point
= strtol (argv
[3], &endp
, 10);
2425 if (endp
== argv
[3] || *endp
!= '\0')
2429 completion_debug ("completion_point=%d", completion_point
);
2430 completion_debug ("----");
2431 completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
2432 completion_debug ("'%s'", completion_line
);
2433 completion_debug (" %*s^",
2434 completion_point
, "");
2435 completion_debug ("----");
2438 if (!g_shell_parse_argv (completion_line
,
2443 /* it's very possible the command line can't be parsed (for
2444 * example, missing quotes etc) - in that case, we just
2445 * don't autocomplete at all
2450 /* compute cur and prev */
2451 completion_prev
= NULL
;
2452 completion_cur
= pick_word_at (completion_line
, completion_point
, &cur_begin
);
2456 for (prev_end
= cur_begin
- 1; prev_end
>= 0; prev_end
--)
2458 if (!g_ascii_isspace (completion_line
[prev_end
]))
2460 completion_prev
= pick_word_at (completion_line
, prev_end
, NULL
);
2466 completion_debug (" cur='%s'", completion_cur
);
2467 completion_debug ("prev='%s'", completion_prev
);
2470 argc
= completion_argc
;
2471 argv
= completion_argv
;
2479 if (request_completion
)
2481 g_print ("help \nemit \ncall \nintrospect \nmonitor \nwait \n");
2487 g_printerr ("Unknown command '%s'\n", command
);
2488 usage (&argc
, &argv
, FALSE
);
2494 g_free (completion_cur
);
2495 g_free (completion_prev
);