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 static GOptionContext
*
138 command_option_context_new (const gchar
*parameter_string
,
139 const gchar
*summary
,
140 const GOptionEntry
*entries
,
141 gboolean request_completion
)
143 GOptionContext
*o
= NULL
;
145 o
= g_option_context_new (parameter_string
);
146 if (request_completion
)
147 g_option_context_set_ignore_unknown_options (o
, TRUE
);
148 g_option_context_set_help_enabled (o
, FALSE
);
149 g_option_context_set_summary (o
, summary
);
150 g_option_context_add_main_entries (o
, entries
, GETTEXT_PACKAGE
);
152 return g_steal_pointer (&o
);
155 /* ---------------------------------------------------------------------------------------------------- */
158 print_methods_and_signals (GDBusConnection
*c
,
161 gboolean print_methods
,
162 gboolean print_signals
)
166 const gchar
*xml_data
;
172 result
= g_dbus_connection_call_sync (c
,
175 "org.freedesktop.DBus.Introspectable",
178 G_VARIANT_TYPE ("(s)"),
179 G_DBUS_CALL_FLAGS_NONE
,
185 g_printerr (_("Error: %s\n"), error
->message
);
186 g_error_free (error
);
189 g_variant_get (result
, "(&s)", &xml_data
);
192 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
193 g_variant_unref (result
);
196 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
197 g_error_free (error
);
201 for (n
= 0; node
->interfaces
!= NULL
&& node
->interfaces
[n
] != NULL
; n
++)
203 const GDBusInterfaceInfo
*iface
= node
->interfaces
[n
];
204 for (m
= 0; print_methods
&& iface
->methods
!= NULL
&& iface
->methods
[m
] != NULL
; m
++)
206 const GDBusMethodInfo
*method
= iface
->methods
[m
];
207 g_print ("%s.%s \n", iface
->name
, method
->name
);
209 for (m
= 0; print_signals
&& iface
->signals
!= NULL
&& iface
->signals
[m
] != NULL
; m
++)
211 const GDBusSignalInfo
*signal
= iface
->signals
[m
];
212 g_print ("%s.%s \n", iface
->name
, signal
->name
);
215 g_dbus_node_info_unref (node
);
222 print_paths (GDBusConnection
*c
,
228 const gchar
*xml_data
;
232 if (!g_dbus_is_name (name
))
234 g_printerr (_("Error: %s is not a valid name\n"), name
);
239 result
= g_dbus_connection_call_sync (c
,
242 "org.freedesktop.DBus.Introspectable",
245 G_VARIANT_TYPE ("(s)"),
246 G_DBUS_CALL_FLAGS_NONE
,
252 g_printerr (_("Error: %s\n"), error
->message
);
253 g_error_free (error
);
256 g_variant_get (result
, "(&s)", &xml_data
);
258 //g_printerr ("xml='%s'", xml_data);
261 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
262 g_variant_unref (result
);
265 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
266 g_error_free (error
);
270 //g_printerr ("bar '%s'\n", path);
272 if (node
->interfaces
!= NULL
)
273 g_print ("%s \n", path
);
275 for (n
= 0; node
->nodes
!= NULL
&& node
->nodes
[n
] != NULL
; n
++)
279 //g_printerr ("foo '%s'\n", node->nodes[n].path);
281 if (g_strcmp0 (path
, "/") == 0)
282 s
= g_strdup_printf ("/%s", node
->nodes
[n
]->path
);
284 s
= g_strdup_printf ("%s/%s", path
, node
->nodes
[n
]->path
);
286 print_paths (c
, name
, s
);
290 g_dbus_node_info_unref (node
);
297 print_names (GDBusConnection
*c
,
298 gboolean include_unique_names
)
304 GHashTable
*name_set
;
308 name_set
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
311 result
= g_dbus_connection_call_sync (c
,
312 "org.freedesktop.DBus",
313 "/org/freedesktop/DBus",
314 "org.freedesktop.DBus",
317 G_VARIANT_TYPE ("(as)"),
318 G_DBUS_CALL_FLAGS_NONE
,
324 g_printerr (_("Error: %s\n"), error
->message
);
325 g_error_free (error
);
328 g_variant_get (result
, "(as)", &iter
);
329 while (g_variant_iter_loop (iter
, "s", &str
))
330 g_hash_table_add (name_set
, g_strdup (str
));
331 g_variant_iter_free (iter
);
332 g_variant_unref (result
);
335 result
= g_dbus_connection_call_sync (c
,
336 "org.freedesktop.DBus",
337 "/org/freedesktop/DBus",
338 "org.freedesktop.DBus",
339 "ListActivatableNames",
341 G_VARIANT_TYPE ("(as)"),
342 G_DBUS_CALL_FLAGS_NONE
,
348 g_printerr (_("Error: %s\n"), error
->message
);
349 g_error_free (error
);
352 g_variant_get (result
, "(as)", &iter
);
353 while (g_variant_iter_loop (iter
, "s", &str
))
354 g_hash_table_add (name_set
, g_strdup (str
));
355 g_variant_iter_free (iter
);
356 g_variant_unref (result
);
358 keys
= g_hash_table_get_keys (name_set
);
359 keys
= g_list_sort (keys
, (GCompareFunc
) g_strcmp0
);
360 for (l
= keys
; l
!= NULL
; l
= l
->next
)
362 const gchar
*name
= l
->data
;
363 if (!include_unique_names
&& g_str_has_prefix (name
, ":"))
366 g_print ("%s \n", name
);
371 g_hash_table_unref (name_set
);
374 /* ---------------------------------------------------------------------------------------------------- */
376 static gboolean opt_connection_system
= FALSE
;
377 static gboolean opt_connection_session
= FALSE
;
378 static gchar
*opt_connection_address
= NULL
;
380 static const GOptionEntry connection_entries
[] =
382 { "system", 'y', 0, G_OPTION_ARG_NONE
, &opt_connection_system
, N_("Connect to the system bus"), NULL
},
383 { "session", 'e', 0, G_OPTION_ARG_NONE
, &opt_connection_session
, N_("Connect to the session bus"), NULL
},
384 { "address", 'a', 0, G_OPTION_ARG_STRING
, &opt_connection_address
, N_("Connect to given D-Bus address"), NULL
},
388 static GOptionGroup
*
389 connection_get_group (void)
391 static GOptionGroup
*g
;
393 g
= g_option_group_new ("connection",
394 N_("Connection Endpoint Options:"),
395 N_("Options specifying the connection endpoint"),
398 g_option_group_set_translation_domain (g
, GETTEXT_PACKAGE
);
399 g_option_group_add_entries (g
, connection_entries
);
404 static GDBusConnection
*
405 connection_get_dbus_connection (GError
**error
)
411 /* First, ensure we have exactly one connect */
412 if (!opt_connection_system
&& !opt_connection_session
&& opt_connection_address
== NULL
)
417 _("No connection endpoint specified"));
420 else if ((opt_connection_system
&& (opt_connection_session
|| opt_connection_address
!= NULL
)) ||
421 (opt_connection_session
&& (opt_connection_system
|| opt_connection_address
!= NULL
)) ||
422 (opt_connection_address
!= NULL
&& (opt_connection_system
|| opt_connection_session
)))
427 _("Multiple connection endpoints specified"));
431 if (opt_connection_system
)
433 c
= g_bus_get_sync (G_BUS_TYPE_SYSTEM
, NULL
, error
);
435 else if (opt_connection_session
)
437 c
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, error
);
439 else if (opt_connection_address
!= NULL
)
441 c
= g_dbus_connection_new_for_address_sync (opt_connection_address
,
442 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
,
443 NULL
, /* GDBusAuthObserver */
444 NULL
, /* GCancellable */
452 /* ---------------------------------------------------------------------------------------------------- */
455 call_helper_get_method_in_signature (GDBusConnection
*c
,
458 const gchar
*interface_name
,
459 const gchar
*method_name
,
464 GDBusNodeInfo
*node_info
;
465 const gchar
*xml_data
;
466 GDBusInterfaceInfo
*interface_info
;
467 GDBusMethodInfo
*method_info
;
474 result
= g_dbus_connection_call_sync (c
,
477 "org.freedesktop.DBus.Introspectable",
480 G_VARIANT_TYPE ("(s)"),
481 G_DBUS_CALL_FLAGS_NONE
,
488 g_variant_get (result
, "(&s)", &xml_data
);
489 node_info
= g_dbus_node_info_new_for_xml (xml_data
, error
);
490 if (node_info
== NULL
)
493 interface_info
= g_dbus_node_info_lookup_interface (node_info
, interface_name
);
494 if (interface_info
== NULL
)
496 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
497 _("Warning: According to introspection data, interface “%s” does not exist\n"),
502 method_info
= g_dbus_interface_info_lookup_method (interface_info
, method_name
);
503 if (method_info
== NULL
)
505 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
506 _("Warning: According to introspection data, method “%s” does not exist on interface “%s”\n"),
512 ret
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_variant_type_free
);
513 for (n
= 0; method_info
->in_args
!= NULL
&& method_info
->in_args
[n
] != NULL
; n
++)
515 g_ptr_array_add (ret
, g_variant_type_new (method_info
->in_args
[n
]->signature
));
519 if (node_info
!= NULL
)
520 g_dbus_node_info_unref (node_info
);
522 g_variant_unref (result
);
527 /* ---------------------------------------------------------------------------------------------------- */
530 _g_variant_parse_me_harder (GVariantType
*type
,
531 const gchar
*given_str
,
539 str
= g_string_new ("\"");
540 for (n
= 0; given_str
[n
] != '\0'; n
++)
542 if (G_UNLIKELY (given_str
[n
] == '\"'))
543 g_string_append (str
, "\\\"");
545 g_string_append_c (str
, given_str
[n
]);
547 g_string_append_c (str
, '"');
548 s
= g_string_free (str
, FALSE
);
550 value
= g_variant_parse (type
,
560 /* ---------------------------------------------------------------------------------------------------- */
562 static gchar
*opt_emit_dest
= NULL
;
563 static gchar
*opt_emit_object_path
= NULL
;
564 static gchar
*opt_emit_signal
= NULL
;
566 static const GOptionEntry emit_entries
[] =
568 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_emit_dest
, N_("Optional destination for signal (unique name)"), NULL
},
569 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_emit_object_path
, N_("Object path to emit signal on"), NULL
},
570 { "signal", 's', 0, G_OPTION_ARG_STRING
, &opt_emit_signal
, N_("Signal and interface name"), NULL
},
575 handle_emit (gint
*argc
,
577 gboolean request_completion
,
578 const gchar
*completion_cur
,
579 const gchar
*completion_prev
)
586 GVariant
*parameters
;
587 gchar
*interface_name
;
589 GVariantBuilder builder
;
590 gboolean skip_dashes
;
593 gboolean complete_names
, complete_paths
, complete_signals
;
598 interface_name
= NULL
;
601 modify_argv0_for_command (argc
, argv
, "emit");
603 o
= command_option_context_new (NULL
, _("Emit a signal."),
604 emit_entries
, request_completion
);
605 g_option_context_add_group (o
, connection_get_group ());
607 complete_names
= FALSE
;
608 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
610 complete_names
= TRUE
;
611 remove_arg ((*argc
) - 1, argc
, argv
);
614 complete_paths
= FALSE
;
615 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
617 complete_paths
= TRUE
;
618 remove_arg ((*argc
) - 1, argc
, argv
);
621 complete_signals
= FALSE
;
622 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--signal") == 0)
624 complete_signals
= TRUE
;
625 remove_arg ((*argc
) - 1, argc
, argv
);
628 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
630 if (!request_completion
)
632 s
= g_option_context_get_help (o
, FALSE
, NULL
);
633 g_printerr ("%s", s
);
640 c
= connection_get_dbus_connection (&error
);
643 if (request_completion
)
645 if (g_strcmp0 (completion_prev
, "--address") == 0)
653 g_print ("--system \n--session \n--address \n");
658 g_printerr (_("Error connecting: %s\n"), error
->message
);
659 g_error_free (error
);
664 /* validate and complete destination (bus name) */
667 print_names (c
, FALSE
);
670 if (request_completion
&& opt_emit_dest
!= NULL
&& g_strcmp0 ("--dest", completion_prev
) == 0)
672 print_names (c
, g_str_has_prefix (opt_emit_dest
, ":"));
676 if (!request_completion
&& opt_emit_dest
!= NULL
&& !g_dbus_is_unique_name (opt_emit_dest
))
678 g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest
);
682 if (opt_emit_dest
== NULL
&& opt_emit_object_path
== NULL
&& request_completion
)
684 g_print ("--dest \n");
686 /* validate and complete object path */
687 if (opt_emit_dest
!= NULL
&& complete_paths
)
689 print_paths (c
, opt_emit_dest
, "/");
692 if (opt_emit_object_path
== NULL
)
694 if (request_completion
)
695 g_print ("--object-path \n");
697 g_printerr (_("Error: Object path is not specified\n"));
700 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
702 if (opt_emit_dest
!= NULL
)
705 s
= g_strdup (opt_emit_object_path
);
706 p
= strrchr (s
, '/');
713 print_paths (c
, opt_emit_dest
, s
);
718 if (!request_completion
&& !g_variant_is_object_path (opt_emit_object_path
))
720 g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path
);
724 /* validate and complete signal (interface + signal name) */
725 if (opt_emit_dest
!= NULL
&& opt_emit_object_path
!= NULL
&& complete_signals
)
727 print_methods_and_signals (c
, opt_emit_dest
, opt_emit_object_path
, FALSE
, TRUE
);
730 if (opt_emit_signal
== NULL
)
732 /* don't keep repeatedly completing --signal */
733 if (request_completion
)
735 if (g_strcmp0 ("--signal", completion_prev
) != 0)
736 g_print ("--signal \n");
740 g_printerr (_("Error: Signal name is not specified\n"));
745 if (request_completion
&& opt_emit_dest
!= NULL
&& opt_emit_object_path
!= NULL
&&
746 g_strcmp0 ("--signal", completion_prev
) == 0)
748 print_methods_and_signals (c
, opt_emit_dest
, opt_emit_object_path
, FALSE
, TRUE
);
751 s
= strrchr (opt_emit_signal
, '.');
752 if (!request_completion
&& s
== NULL
)
754 g_printerr (_("Error: Signal name “%s” is invalid\n"), opt_emit_signal
);
757 signal_name
= g_strdup (s
+ 1);
758 interface_name
= g_strndup (opt_emit_signal
, s
- opt_emit_signal
);
760 /* All done with completion now */
761 if (request_completion
)
764 if (!g_dbus_is_interface_name (interface_name
))
766 g_printerr (_("Error: %s is not a valid interface name\n"), interface_name
);
770 if (!g_dbus_is_member_name (signal_name
))
772 g_printerr (_("Error: %s is not a valid member name\n"), signal_name
);
776 /* Read parameters */
777 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
780 for (n
= 1; n
< (guint
) *argc
; n
++)
784 /* Under certain conditions, g_option_context_parse returns the "--"
785 itself (setting off unparsed arguments), too: */
786 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
793 value
= g_variant_parse (NULL
,
802 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
803 g_error_free (error
);
805 value
= _g_variant_parse_me_harder (NULL
, (*argv
)[n
], &error
);
808 /* Use the original non-"parse-me-harder" error */
809 g_printerr (_("Error parsing parameter %d: %s\n"),
812 g_error_free (error
);
814 g_variant_builder_clear (&builder
);
819 g_variant_builder_add_value (&builder
, value
);
822 parameters
= g_variant_builder_end (&builder
);
824 if (parameters
!= NULL
)
825 parameters
= g_variant_ref_sink (parameters
);
826 if (!g_dbus_connection_emit_signal (c
,
828 opt_emit_object_path
,
834 g_printerr (_("Error: %s\n"), error
->message
);
835 g_error_free (error
);
839 if (!g_dbus_connection_flush_sync (c
, NULL
, &error
))
841 g_printerr (_("Error flushing connection: %s\n"), error
->message
);
842 g_error_free (error
);
851 if (parameters
!= NULL
)
852 g_variant_unref (parameters
);
853 g_free (interface_name
);
854 g_free (signal_name
);
855 g_option_context_free (o
);
859 /* ---------------------------------------------------------------------------------------------------- */
861 static gchar
*opt_call_dest
= NULL
;
862 static gchar
*opt_call_object_path
= NULL
;
863 static gchar
*opt_call_method
= NULL
;
864 static gint opt_call_timeout
= -1;
866 static const GOptionEntry call_entries
[] =
868 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_call_dest
, N_("Destination name to invoke method on"), NULL
},
869 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_call_object_path
, N_("Object path to invoke method on"), NULL
},
870 { "method", 'm', 0, G_OPTION_ARG_STRING
, &opt_call_method
, N_("Method and interface name"), NULL
},
871 { "timeout", 't', 0, G_OPTION_ARG_INT
, &opt_call_timeout
, N_("Timeout in seconds"), NULL
},
876 handle_call (gint
*argc
,
878 gboolean request_completion
,
879 const gchar
*completion_cur
,
880 const gchar
*completion_prev
)
887 GVariant
*parameters
;
888 gchar
*interface_name
;
891 GPtrArray
*in_signature_types
;
892 gboolean complete_names
;
893 gboolean complete_paths
;
894 gboolean complete_methods
;
895 GVariantBuilder builder
;
896 gboolean skip_dashes
;
903 interface_name
= NULL
;
906 in_signature_types
= NULL
;
908 modify_argv0_for_command (argc
, argv
, "call");
910 o
= command_option_context_new (NULL
, _("Invoke a method on a remote object."),
911 call_entries
, request_completion
);
912 g_option_context_add_group (o
, connection_get_group ());
914 complete_names
= FALSE
;
915 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
917 complete_names
= TRUE
;
918 remove_arg ((*argc
) - 1, argc
, argv
);
921 complete_paths
= FALSE
;
922 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
924 complete_paths
= TRUE
;
925 remove_arg ((*argc
) - 1, argc
, argv
);
928 complete_methods
= FALSE
;
929 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--method") == 0)
931 complete_methods
= TRUE
;
932 remove_arg ((*argc
) - 1, argc
, argv
);
935 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
937 if (!request_completion
)
939 s
= g_option_context_get_help (o
, FALSE
, NULL
);
940 g_printerr ("%s", s
);
947 c
= connection_get_dbus_connection (&error
);
950 if (request_completion
)
952 if (g_strcmp0 (completion_prev
, "--address") == 0)
960 g_print ("--system \n--session \n--address \n");
965 g_printerr (_("Error connecting: %s\n"), error
->message
);
966 g_error_free (error
);
971 /* validate and complete destination (bus name) */
974 print_names (c
, FALSE
);
977 if (opt_call_dest
== NULL
)
979 if (request_completion
)
980 g_print ("--dest \n");
982 g_printerr (_("Error: Destination is not specified\n"));
985 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
987 print_names (c
, g_str_has_prefix (opt_call_dest
, ":"));
991 if (!request_completion
&& !g_dbus_is_name (opt_call_dest
))
993 g_printerr (_("Error: %s is not a valid bus name\n"), opt_call_dest
);
997 /* validate and complete object path */
1000 print_paths (c
, opt_call_dest
, "/");
1003 if (opt_call_object_path
== NULL
)
1005 if (request_completion
)
1006 g_print ("--object-path \n");
1008 g_printerr (_("Error: Object path is not specified\n"));
1011 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1014 s
= g_strdup (opt_call_object_path
);
1015 p
= strrchr (s
, '/');
1022 print_paths (c
, opt_call_dest
, s
);
1026 if (!request_completion
&& !g_variant_is_object_path (opt_call_object_path
))
1028 g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path
);
1032 /* validate and complete method (interface + method name) */
1033 if (complete_methods
)
1035 print_methods_and_signals (c
, opt_call_dest
, opt_call_object_path
, TRUE
, FALSE
);
1038 if (opt_call_method
== NULL
)
1040 if (request_completion
)
1041 g_print ("--method \n");
1043 g_printerr (_("Error: Method name is not specified\n"));
1046 if (request_completion
&& g_strcmp0 ("--method", completion_prev
) == 0)
1048 print_methods_and_signals (c
, opt_call_dest
, opt_call_object_path
, TRUE
, FALSE
);
1051 s
= strrchr (opt_call_method
, '.');
1052 if (!request_completion
&& s
== NULL
)
1054 g_printerr (_("Error: Method name “%s” is invalid\n"), opt_call_method
);
1057 method_name
= g_strdup (s
+ 1);
1058 interface_name
= g_strndup (opt_call_method
, s
- opt_call_method
);
1060 /* All done with completion now */
1061 if (request_completion
)
1064 /* Introspect, for easy conversion - it's not fatal if we can't do this */
1065 in_signature_types
= call_helper_get_method_in_signature (c
,
1067 opt_call_object_path
,
1071 if (in_signature_types
== NULL
)
1073 //g_printerr ("Error getting introspection data: %s\n", error->message);
1074 g_error_free (error
);
1078 /* Read parameters */
1079 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
1082 for (n
= 1; n
< (guint
) *argc
; n
++)
1087 /* Under certain conditions, g_option_context_parse returns the "--"
1088 itself (setting off unparsed arguments), too: */
1089 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
1091 skip_dashes
= FALSE
;
1096 if (in_signature_types
!= NULL
)
1098 if (parm
>= in_signature_types
->len
)
1100 /* Only warn for the first param */
1101 if (parm
== in_signature_types
->len
)
1103 g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n",
1104 in_signature_types
->len
);
1109 type
= in_signature_types
->pdata
[parm
];
1114 value
= g_variant_parse (type
,
1123 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
1124 g_error_free (error
);
1126 value
= _g_variant_parse_me_harder (type
, (*argv
)[n
], &error
);
1131 s
= g_variant_type_dup_string (type
);
1132 g_printerr (_("Error parsing parameter %d of type “%s”: %s\n"),
1140 g_printerr (_("Error parsing parameter %d: %s\n"),
1144 g_error_free (error
);
1145 g_variant_builder_clear (&builder
);
1151 g_variant_builder_add_value (&builder
, value
);
1154 parameters
= g_variant_builder_end (&builder
);
1156 if (parameters
!= NULL
)
1157 parameters
= g_variant_ref_sink (parameters
);
1158 result
= g_dbus_connection_call_sync (c
,
1160 opt_call_object_path
,
1165 G_DBUS_CALL_FLAGS_NONE
,
1166 opt_call_timeout
> 0 ? opt_call_timeout
* 1000 : opt_call_timeout
,
1171 g_printerr (_("Error: %s\n"), error
->message
);
1173 if (g_error_matches (error
, G_DBUS_ERROR
, G_DBUS_ERROR_INVALID_ARGS
) && in_signature_types
!= NULL
)
1175 if (in_signature_types
->len
> 0)
1178 s
= g_string_new (NULL
);
1180 for (n
= 0; n
< in_signature_types
->len
; n
++)
1182 GVariantType
*type
= in_signature_types
->pdata
[n
];
1183 g_string_append_len (s
,
1184 g_variant_type_peek_string (type
),
1185 g_variant_type_get_string_length (type
));
1188 g_printerr ("(According to introspection data, you need to pass '%s')\n", s
->str
);
1189 g_string_free (s
, TRUE
);
1192 g_printerr ("(According to introspection data, you need to pass no arguments)\n");
1195 g_error_free (error
);
1199 s
= g_variant_print (result
, TRUE
);
1200 g_print ("%s\n", s
);
1206 if (in_signature_types
!= NULL
)
1207 g_ptr_array_unref (in_signature_types
);
1209 g_variant_unref (result
);
1212 if (parameters
!= NULL
)
1213 g_variant_unref (parameters
);
1214 g_free (interface_name
);
1215 g_free (method_name
);
1216 g_option_context_free (o
);
1220 /* ---------------------------------------------------------------------------------------------------- */
1222 static gchar
*opt_introspect_dest
= NULL
;
1223 static gchar
*opt_introspect_object_path
= NULL
;
1224 static gboolean opt_introspect_xml
= FALSE
;
1225 static gboolean opt_introspect_recurse
= FALSE
;
1226 static gboolean opt_introspect_only_properties
= FALSE
;
1229 dump_annotation (const GDBusAnnotationInfo
*o
,
1231 gboolean ignore_indent
)
1234 g_print ("%*s@%s(\"%s\")\n",
1235 ignore_indent
? 0 : indent
, "",
1238 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1239 dump_annotation (o
->annotations
[n
], indent
+ 2, FALSE
);
1243 dump_arg (const GDBusArgInfo
*o
,
1245 const gchar
*direction
,
1246 gboolean ignore_indent
,
1247 gboolean include_newline
)
1251 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1253 dump_annotation (o
->annotations
[n
], indent
, ignore_indent
);
1254 ignore_indent
= FALSE
;
1257 g_print ("%*s%s%s %s%s",
1258 ignore_indent
? 0 : indent
, "",
1262 include_newline
? ",\n" : "");
1266 count_args (GDBusArgInfo
**args
)
1272 while (args
[n
] != NULL
)
1279 dump_method (const GDBusMethodInfo
*o
,
1285 guint total_num_args
;
1287 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1288 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1290 g_print ("%*s%s(", indent
, "", o
->name
);
1291 name_len
= strlen (o
->name
);
1292 total_num_args
= count_args (o
->in_args
) + count_args (o
->out_args
);
1293 for (n
= 0, m
= 0; o
->in_args
!= NULL
&& o
->in_args
[n
] != NULL
; n
++, m
++)
1295 gboolean ignore_indent
= (m
== 0);
1296 gboolean include_newline
= (m
!= total_num_args
- 1);
1298 dump_arg (o
->in_args
[n
],
1299 indent
+ name_len
+ 1,
1304 for (n
= 0; o
->out_args
!= NULL
&& o
->out_args
[n
] != NULL
; n
++, m
++)
1306 gboolean ignore_indent
= (m
== 0);
1307 gboolean include_newline
= (m
!= total_num_args
- 1);
1308 dump_arg (o
->out_args
[n
],
1309 indent
+ name_len
+ 1,
1318 dump_signal (const GDBusSignalInfo
*o
,
1323 guint total_num_args
;
1325 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1326 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1328 g_print ("%*s%s(", indent
, "", o
->name
);
1329 name_len
= strlen (o
->name
);
1330 total_num_args
= count_args (o
->args
);
1331 for (n
= 0; o
->args
!= NULL
&& o
->args
[n
] != NULL
; n
++)
1333 gboolean ignore_indent
= (n
== 0);
1334 gboolean include_newline
= (n
!= total_num_args
- 1);
1335 dump_arg (o
->args
[n
],
1336 indent
+ name_len
+ 1,
1345 dump_property (const GDBusPropertyInfo
*o
,
1349 const gchar
*access
;
1352 if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
1353 access
= "readonly";
1354 else if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
)
1355 access
= "writeonly";
1356 else if (o
->flags
== (G_DBUS_PROPERTY_INFO_FLAGS_READABLE
| G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
))
1357 access
= "readwrite";
1359 g_assert_not_reached ();
1361 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1362 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1366 gchar
*s
= g_variant_print (value
, FALSE
);
1367 g_print ("%*s%s %s %s = %s;\n", indent
, "", access
, o
->signature
, o
->name
, s
);
1372 g_print ("%*s%s %s %s;\n", indent
, "", access
, o
->signature
, o
->name
);
1377 dump_interface (GDBusConnection
*c
,
1379 const GDBusInterfaceInfo
*o
,
1381 const gchar
*object_path
)
1384 GHashTable
*properties
;
1386 properties
= g_hash_table_new_full (g_str_hash
,
1389 (GDestroyNotify
) g_variant_unref
);
1391 /* Try to get properties */
1392 if (c
!= NULL
&& name
!= NULL
&& object_path
!= NULL
&& o
->properties
!= NULL
)
1395 result
= g_dbus_connection_call_sync (c
,
1398 "org.freedesktop.DBus.Properties",
1400 g_variant_new ("(s)", o
->name
),
1402 G_DBUS_CALL_FLAGS_NONE
,
1408 if (g_variant_is_of_type (result
, G_VARIANT_TYPE ("(a{sv})")))
1412 g_variant_get (result
,
1415 while ((item
= g_variant_iter_next_value (iter
)))
1419 g_variant_get (item
,
1424 g_hash_table_insert (properties
, key
, g_variant_ref (value
));
1427 g_variant_unref (result
);
1432 for (n
= 0; o
->properties
!= NULL
&& o
->properties
[n
] != NULL
; n
++)
1434 result
= g_dbus_connection_call_sync (c
,
1437 "org.freedesktop.DBus.Properties",
1439 g_variant_new ("(ss)", o
->name
, o
->properties
[n
]->name
),
1440 G_VARIANT_TYPE ("(v)"),
1441 G_DBUS_CALL_FLAGS_NONE
,
1447 GVariant
*property_value
;
1448 g_variant_get (result
,
1451 g_hash_table_insert (properties
,
1452 g_strdup (o
->properties
[n
]->name
),
1453 g_variant_ref (property_value
));
1454 g_variant_unref (result
);
1460 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1461 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1463 g_print ("%*sinterface %s {\n", indent
, "", o
->name
);
1464 if (o
->methods
!= NULL
&& !opt_introspect_only_properties
)
1466 g_print ("%*s methods:\n", indent
, "");
1467 for (n
= 0; o
->methods
[n
] != NULL
; n
++)
1468 dump_method (o
->methods
[n
], indent
+ 4);
1470 if (o
->signals
!= NULL
&& !opt_introspect_only_properties
)
1472 g_print ("%*s signals:\n", indent
, "");
1473 for (n
= 0; o
->signals
[n
] != NULL
; n
++)
1474 dump_signal (o
->signals
[n
], indent
+ 4);
1476 if (o
->properties
!= NULL
)
1478 g_print ("%*s properties:\n", indent
, "");
1479 for (n
= 0; o
->properties
[n
] != NULL
; n
++)
1481 dump_property (o
->properties
[n
],
1483 g_hash_table_lookup (properties
, (o
->properties
[n
])->name
));
1489 g_hash_table_unref (properties
);
1493 introspect_do (GDBusConnection
*c
,
1494 const gchar
*object_path
,
1498 dump_node (GDBusConnection
*c
,
1500 const GDBusNodeInfo
*o
,
1502 const gchar
*object_path
,
1506 const gchar
*object_path_to_print
;
1508 object_path_to_print
= object_path
;
1509 if (o
->path
!= NULL
)
1510 object_path_to_print
= o
->path
;
1512 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1513 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1515 g_print ("%*snode %s", indent
, "", object_path_to_print
!= NULL
? object_path_to_print
: "(not set)");
1516 if (o
->interfaces
!= NULL
|| o
->nodes
!= NULL
)
1519 for (n
= 0; o
->interfaces
!= NULL
&& o
->interfaces
[n
] != NULL
; n
++)
1521 if (opt_introspect_only_properties
)
1523 if (o
->interfaces
[n
]->properties
!= NULL
&& o
->interfaces
[n
]->properties
[0] != NULL
)
1524 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1528 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1531 for (n
= 0; o
->nodes
!= NULL
&& o
->nodes
[n
] != NULL
; n
++)
1536 if (g_variant_is_object_path (o
->nodes
[n
]->path
))
1538 child_path
= g_strdup (o
->nodes
[n
]->path
);
1539 /* avoid infinite loops */
1540 if (g_str_has_prefix (child_path
, object_path
))
1542 introspect_do (c
, child_path
, indent
+ 2);
1546 g_print ("Skipping path %s that is not enclosed by parent %s\n",
1547 child_path
, object_path
);
1552 if (g_strcmp0 (object_path
, "/") == 0)
1553 child_path
= g_strdup_printf ("/%s", o
->nodes
[n
]->path
);
1555 child_path
= g_strdup_printf ("%s/%s", object_path
, o
->nodes
[n
]->path
);
1556 introspect_do (c
, child_path
, indent
+ 2);
1558 g_free (child_path
);
1562 dump_node (NULL
, NULL
, o
->nodes
[n
], indent
+ 2, NULL
, recurse
);
1574 static const GOptionEntry introspect_entries
[] =
1576 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_introspect_dest
, N_("Destination name to introspect"), NULL
},
1577 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_introspect_object_path
, N_("Object path to introspect"), NULL
},
1578 { "xml", 'x', 0, G_OPTION_ARG_NONE
, &opt_introspect_xml
, N_("Print XML"), NULL
},
1579 { "recurse", 'r', 0, G_OPTION_ARG_NONE
, &opt_introspect_recurse
, N_("Introspect children"), NULL
},
1580 { "only-properties", 'p', 0, G_OPTION_ARG_NONE
, &opt_introspect_only_properties
, N_("Only print properties"), NULL
},
1585 introspect_do (GDBusConnection
*c
,
1586 const gchar
*object_path
,
1591 GDBusNodeInfo
*node
;
1593 const gchar
*xml_data
;
1600 result
= g_dbus_connection_call_sync (c
,
1601 opt_introspect_dest
,
1603 "org.freedesktop.DBus.Introspectable",
1606 G_VARIANT_TYPE ("(s)"),
1607 G_DBUS_CALL_FLAGS_NONE
,
1613 g_printerr (_("Error: %s\n"), error
->message
);
1614 g_error_free (error
);
1617 g_variant_get (result
, "(&s)", &xml_data
);
1619 if (opt_introspect_xml
)
1621 g_print ("%s", xml_data
);
1626 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
1629 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
1630 g_error_free (error
);
1634 dump_node (c
, opt_introspect_dest
, node
, indent
, object_path
, opt_introspect_recurse
);
1641 g_dbus_node_info_unref (node
);
1643 g_variant_unref (result
);
1648 handle_introspect (gint
*argc
,
1650 gboolean request_completion
,
1651 const gchar
*completion_cur
,
1652 const gchar
*completion_prev
)
1659 gboolean complete_names
;
1660 gboolean complete_paths
;
1665 modify_argv0_for_command (argc
, argv
, "introspect");
1667 o
= command_option_context_new (NULL
, _("Introspect a remote object."),
1668 introspect_entries
, request_completion
);
1669 g_option_context_add_group (o
, connection_get_group ());
1671 complete_names
= FALSE
;
1672 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1674 complete_names
= TRUE
;
1675 remove_arg ((*argc
) - 1, argc
, argv
);
1678 complete_paths
= FALSE
;
1679 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1681 complete_paths
= TRUE
;
1682 remove_arg ((*argc
) - 1, argc
, argv
);
1685 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1687 if (!request_completion
)
1689 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1690 g_printerr ("%s", s
);
1697 c
= connection_get_dbus_connection (&error
);
1700 if (request_completion
)
1702 if (g_strcmp0 (completion_prev
, "--address") == 0)
1710 g_print ("--system \n--session \n--address \n");
1715 g_printerr (_("Error connecting: %s\n"), error
->message
);
1716 g_error_free (error
);
1723 print_names (c
, FALSE
);
1726 /* this only makes sense on message bus connections */
1727 if (opt_introspect_dest
== NULL
)
1729 if (request_completion
)
1730 g_print ("--dest \n");
1732 g_printerr (_("Error: Destination is not specified\n"));
1735 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1737 print_names (c
, g_str_has_prefix (opt_introspect_dest
, ":"));
1743 print_paths (c
, opt_introspect_dest
, "/");
1747 if (!request_completion
&& !g_dbus_is_name (opt_introspect_dest
))
1749 g_printerr (_("Error: %s is not a valid bus name\n"), opt_introspect_dest
);
1753 if (opt_introspect_object_path
== NULL
)
1755 if (request_completion
)
1756 g_print ("--object-path \n");
1758 g_printerr (_("Error: Object path is not specified\n"));
1761 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1764 s
= g_strdup (opt_introspect_object_path
);
1765 p
= strrchr (s
, '/');
1772 print_paths (c
, opt_introspect_dest
, s
);
1776 if (!request_completion
&& !g_variant_is_object_path (opt_introspect_object_path
))
1778 g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path
);
1782 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_recurse
)
1784 g_print ("--recurse \n");
1787 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_only_properties
)
1789 g_print ("--only-properties \n");
1792 /* All done with completion now */
1793 if (request_completion
)
1796 if (!introspect_do (c
, opt_introspect_object_path
, 0))
1804 g_option_context_free (o
);
1808 /* ---------------------------------------------------------------------------------------------------- */
1810 static gchar
*opt_monitor_dest
= NULL
;
1811 static gchar
*opt_monitor_object_path
= NULL
;
1813 static guint monitor_filter_id
= 0;
1816 monitor_signal_cb (GDBusConnection
*connection
,
1817 const gchar
*sender_name
,
1818 const gchar
*object_path
,
1819 const gchar
*interface_name
,
1820 const gchar
*signal_name
,
1821 GVariant
*parameters
,
1825 s
= g_variant_print (parameters
, TRUE
);
1826 g_print ("%s: %s.%s %s\n",
1835 monitor_on_name_appeared (GDBusConnection
*connection
,
1837 const gchar
*name_owner
,
1840 g_print ("The name %s is owned by %s\n", name
, name_owner
);
1841 g_assert (monitor_filter_id
== 0);
1842 monitor_filter_id
= g_dbus_connection_signal_subscribe (connection
,
1844 NULL
, /* any interface */
1845 NULL
, /* any member */
1846 opt_monitor_object_path
,
1848 G_DBUS_SIGNAL_FLAGS_NONE
,
1850 NULL
, /* user_data */
1851 NULL
); /* user_data destroy notify */
1855 monitor_on_name_vanished (GDBusConnection
*connection
,
1859 g_print ("The name %s does not have an owner\n", name
);
1861 if (monitor_filter_id
!= 0)
1863 g_dbus_connection_signal_unsubscribe (connection
, monitor_filter_id
);
1864 monitor_filter_id
= 0;
1868 static const GOptionEntry monitor_entries
[] =
1870 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_monitor_dest
, N_("Destination name to monitor"), NULL
},
1871 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_monitor_object_path
, N_("Object path to monitor"), NULL
},
1876 handle_monitor (gint
*argc
,
1878 gboolean request_completion
,
1879 const gchar
*completion_cur
,
1880 const gchar
*completion_prev
)
1887 gboolean complete_names
;
1888 gboolean complete_paths
;
1894 modify_argv0_for_command (argc
, argv
, "monitor");
1896 o
= command_option_context_new (NULL
, _("Monitor a remote object."),
1897 monitor_entries
, request_completion
);
1898 g_option_context_add_group (o
, connection_get_group ());
1900 complete_names
= FALSE
;
1901 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1903 complete_names
= TRUE
;
1904 remove_arg ((*argc
) - 1, argc
, argv
);
1907 complete_paths
= FALSE
;
1908 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1910 complete_paths
= TRUE
;
1911 remove_arg ((*argc
) - 1, argc
, argv
);
1914 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1916 if (!request_completion
)
1918 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1919 g_printerr ("%s", s
);
1926 c
= connection_get_dbus_connection (&error
);
1929 if (request_completion
)
1931 if (g_strcmp0 (completion_prev
, "--address") == 0)
1939 g_print ("--system \n--session \n--address \n");
1944 g_printerr (_("Error connecting: %s\n"), error
->message
);
1945 g_error_free (error
);
1950 /* Monitoring doesn’t make sense on a non-message-bus connection. */
1951 if (g_dbus_connection_get_unique_name (c
) == NULL
)
1953 if (!request_completion
)
1954 g_printerr (_("Error: can’t monitor a non-message-bus connection\n"));
1960 print_names (c
, FALSE
);
1963 /* this only makes sense on message bus connections */
1964 if (opt_monitor_dest
== NULL
)
1966 if (request_completion
)
1967 g_print ("--dest \n");
1969 g_printerr (_("Error: Destination is not specified\n"));
1972 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1974 print_names (c
, g_str_has_prefix (opt_monitor_dest
, ":"));
1978 if (!request_completion
&& !g_dbus_is_name (opt_monitor_dest
))
1980 g_printerr (_("Error: %s is not a valid bus name\n"), opt_monitor_dest
);
1986 print_paths (c
, opt_monitor_dest
, "/");
1989 if (opt_monitor_object_path
== NULL
)
1991 if (request_completion
)
1993 g_print ("--object-path \n");
1996 /* it's fine to not have an object path */
1998 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
2001 s
= g_strdup (opt_monitor_object_path
);
2002 p
= strrchr (s
, '/');
2009 print_paths (c
, opt_monitor_dest
, s
);
2013 if (!request_completion
&& (opt_monitor_object_path
!= NULL
&& !g_variant_is_object_path (opt_monitor_object_path
)))
2015 g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path
);
2019 /* All done with completion now */
2020 if (request_completion
)
2023 if (opt_monitor_object_path
!= NULL
)
2024 g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path
, opt_monitor_dest
);
2026 g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest
);
2028 loop
= g_main_loop_new (NULL
, FALSE
);
2029 g_bus_watch_name_on_connection (c
,
2031 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
2032 monitor_on_name_appeared
,
2033 monitor_on_name_vanished
,
2037 g_main_loop_run (loop
);
2038 g_main_loop_unref (loop
);
2045 g_option_context_free (o
);
2049 /* ---------------------------------------------------------------------------------------------------- */
2051 static gboolean opt_wait_activate_set
= FALSE
;
2052 static gchar
*opt_wait_activate_name
= NULL
;
2053 static gint64 opt_wait_timeout
= 0; /* no timeout */
2056 WAIT_STATE_RUNNING
, /* waiting to see the service */
2057 WAIT_STATE_SUCCESS
, /* seen it successfully */
2058 WAIT_STATE_TIMEOUT
, /* timed out before seeing it */
2062 opt_wait_activate_cb (const gchar
*option_name
,
2067 /* @value may be NULL */
2068 opt_wait_activate_set
= TRUE
;
2069 opt_wait_activate_name
= g_strdup (value
);
2074 static const GOptionEntry wait_entries
[] =
2076 { "activate", 'a', G_OPTION_FLAG_OPTIONAL_ARG
, G_OPTION_ARG_CALLBACK
,
2077 opt_wait_activate_cb
,
2078 N_("Service to activate before waiting for the other one (well-known name)"),
2080 { "timeout", 't', 0, G_OPTION_ARG_INT64
, &opt_wait_timeout
,
2081 N_("Timeout to wait for before exiting with an error (seconds); 0 for "
2082 "no timeout (default)"), "SECS" },
2087 wait_name_appeared_cb (GDBusConnection
*connection
,
2089 const gchar
*name_owner
,
2092 WaitState
*wait_state
= user_data
;
2094 *wait_state
= WAIT_STATE_SUCCESS
;
2098 wait_timeout_cb (gpointer user_data
)
2100 WaitState
*wait_state
= user_data
;
2102 *wait_state
= WAIT_STATE_TIMEOUT
;
2104 /* Removed in handle_wait(). */
2105 return G_SOURCE_CONTINUE
;
2109 handle_wait (gint
*argc
,
2111 gboolean request_completion
,
2112 const gchar
*completion_cur
,
2113 const gchar
*completion_prev
)
2120 guint watch_id
, timer_id
= 0, activate_watch_id
;
2121 const gchar
*activate_service
, *wait_service
;
2122 WaitState wait_state
= WAIT_STATE_RUNNING
;
2127 modify_argv0_for_command (argc
, argv
, "wait");
2129 o
= command_option_context_new (_("[OPTION…] BUS-NAME"),
2130 _("Wait for a bus name to appear."),
2131 wait_entries
, request_completion
);
2132 g_option_context_add_group (o
, connection_get_group ());
2134 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
2136 if (!request_completion
)
2138 s
= g_option_context_get_help (o
, FALSE
, NULL
);
2139 g_printerr ("%s", s
);
2146 c
= connection_get_dbus_connection (&error
);
2149 if (request_completion
)
2151 if (g_strcmp0 (completion_prev
, "--address") == 0)
2159 g_print ("--system \n--session \n--address \n");
2164 g_printerr (_("Error connecting: %s\n"), error
->message
);
2165 g_error_free (error
);
2170 /* All done with completion now */
2171 if (request_completion
)
2175 * Try and disentangle the command line arguments, with the aim of supporting:
2176 * gdbus wait --session --activate ActivateName WaitName
2177 * gdbus wait --session --activate ActivateAndWaitName
2178 * gdbus wait --activate --session ActivateAndWaitName
2179 * gdbus wait --session WaitName
2181 if (*argc
== 2 && opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2183 activate_service
= opt_wait_activate_name
;
2184 wait_service
= (*argv
)[1];
2186 else if (*argc
== 2 &&
2187 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2189 activate_service
= (*argv
)[1];
2190 wait_service
= (*argv
)[1];
2192 else if (*argc
== 2 && !opt_wait_activate_set
)
2194 activate_service
= NULL
; /* disabled */
2195 wait_service
= (*argv
)[1];
2197 else if (*argc
== 1 &&
2198 opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2200 activate_service
= opt_wait_activate_name
;
2201 wait_service
= opt_wait_activate_name
;
2203 else if (*argc
== 1 &&
2204 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2206 g_printerr (_("Error: A service to activate for must be specified.\n"));
2209 else if (*argc
== 1 && !opt_wait_activate_set
)
2211 g_printerr (_("Error: A service to wait for must be specified.\n"));
2214 else /* if (*argc > 2) */
2216 g_printerr (_("Error: Too many arguments.\n"));
2220 if (activate_service
!= NULL
&&
2221 (!g_dbus_is_name (activate_service
) ||
2222 g_dbus_is_unique_name (activate_service
)))
2224 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2229 if (!g_dbus_is_name (wait_service
) || g_dbus_is_unique_name (wait_service
))
2231 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2236 /* Start the prerequisite service if needed. */
2237 if (activate_service
!= NULL
)
2239 activate_watch_id
= g_bus_watch_name_on_connection (c
, activate_service
,
2240 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
2246 activate_watch_id
= 0;
2249 /* Wait for the expected name to appear. */
2250 watch_id
= g_bus_watch_name_on_connection (c
,
2252 G_BUS_NAME_WATCHER_FLAGS_NONE
,
2253 wait_name_appeared_cb
,
2254 NULL
, &wait_state
, NULL
);
2256 /* Safety timeout. */
2257 if (opt_wait_timeout
> 0)
2258 timer_id
= g_timeout_add (opt_wait_timeout
, wait_timeout_cb
, &wait_state
);
2260 while (wait_state
== WAIT_STATE_RUNNING
)
2261 g_main_context_iteration (NULL
, TRUE
);
2263 g_bus_unwatch_name (watch_id
);
2265 g_source_remove (timer_id
);
2266 if (activate_watch_id
!= 0)
2267 g_bus_unwatch_name (activate_watch_id
);
2269 ret
= (wait_state
== WAIT_STATE_SUCCESS
);
2272 g_clear_object (&c
);
2273 g_option_context_free (o
);
2274 g_free (opt_wait_activate_name
);
2275 opt_wait_activate_name
= NULL
;
2280 /* ---------------------------------------------------------------------------------------------------- */
2283 pick_word_at (const gchar
*s
,
2285 gint
*out_word_begins_at
)
2292 if (out_word_begins_at
!= NULL
)
2293 *out_word_begins_at
= -1;
2297 if (g_ascii_isspace (s
[cursor
]) && ((cursor
> 0 && g_ascii_isspace(s
[cursor
-1])) || cursor
== 0))
2299 if (out_word_begins_at
!= NULL
)
2300 *out_word_begins_at
= cursor
;
2301 return g_strdup ("");
2304 while (!g_ascii_isspace (s
[cursor
- 1]) && cursor
> 0)
2309 while (!g_ascii_isspace (s
[end
]) && s
[end
] != '\0')
2312 if (out_word_begins_at
!= NULL
)
2313 *out_word_begins_at
= begin
;
2315 return g_strndup (s
+ begin
, end
- begin
);
2319 main (gint argc
, gchar
*argv
[])
2322 const gchar
*command
;
2323 gboolean request_completion
;
2324 gchar
*completion_cur
;
2325 gchar
*completion_prev
;
2330 setlocale (LC_ALL
, "");
2331 textdomain (GETTEXT_PACKAGE
);
2334 tmp
= _glib_get_locale_dir ();
2335 bindtextdomain (GETTEXT_PACKAGE
, tmp
);
2338 bindtextdomain (GETTEXT_PACKAGE
, GLIB_LOCALE_DIR
);
2341 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2342 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
2346 completion_cur
= NULL
;
2347 completion_prev
= NULL
;
2351 usage (&argc
, &argv
, FALSE
);
2355 request_completion
= FALSE
;
2357 //completion_debug ("---- argc=%d --------------------------------------------------------", argc);
2361 if (g_strcmp0 (command
, "help") == 0)
2363 if (request_completion
)
2369 usage (&argc
, &argv
, TRUE
);
2374 else if (g_strcmp0 (command
, "emit") == 0)
2376 if (handle_emit (&argc
,
2384 else if (g_strcmp0 (command
, "call") == 0)
2386 if (handle_call (&argc
,
2394 else if (g_strcmp0 (command
, "introspect") == 0)
2396 if (handle_introspect (&argc
,
2404 else if (g_strcmp0 (command
, "monitor") == 0)
2406 if (handle_monitor (&argc
,
2414 else if (g_strcmp0 (command
, "wait") == 0)
2416 if (handle_wait (&argc
,
2424 else if (g_strcmp0 (command
, "complete") == 0 && argc
== 4 && !request_completion
)
2426 const gchar
*completion_line
;
2427 gchar
**completion_argv
;
2428 gint completion_argc
;
2429 gint completion_point
;
2433 request_completion
= TRUE
;
2435 completion_line
= argv
[2];
2436 completion_point
= strtol (argv
[3], &endp
, 10);
2437 if (endp
== argv
[3] || *endp
!= '\0')
2441 completion_debug ("completion_point=%d", completion_point
);
2442 completion_debug ("----");
2443 completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
2444 completion_debug ("'%s'", completion_line
);
2445 completion_debug (" %*s^",
2446 completion_point
, "");
2447 completion_debug ("----");
2450 if (!g_shell_parse_argv (completion_line
,
2455 /* it's very possible the command line can't be parsed (for
2456 * example, missing quotes etc) - in that case, we just
2457 * don't autocomplete at all
2462 /* compute cur and prev */
2463 completion_prev
= NULL
;
2464 completion_cur
= pick_word_at (completion_line
, completion_point
, &cur_begin
);
2468 for (prev_end
= cur_begin
- 1; prev_end
>= 0; prev_end
--)
2470 if (!g_ascii_isspace (completion_line
[prev_end
]))
2472 completion_prev
= pick_word_at (completion_line
, prev_end
, NULL
);
2478 completion_debug (" cur='%s'", completion_cur
);
2479 completion_debug ("prev='%s'", completion_prev
);
2482 argc
= completion_argc
;
2483 argv
= completion_argv
;
2491 if (request_completion
)
2493 g_print ("help \nemit \ncall \nintrospect \nmonitor \nwait \n");
2499 g_printerr ("Unknown command '%s'\n", command
);
2500 usage (&argc
, &argv
, FALSE
);
2506 g_free (completion_cur
);
2507 g_free (completion_prev
);