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 (GDBusConnection
*c
,
146 const gchar
*xml_data
;
152 result
= g_dbus_connection_call_sync (c
,
155 "org.freedesktop.DBus.Introspectable",
158 G_VARIANT_TYPE ("(s)"),
159 G_DBUS_CALL_FLAGS_NONE
,
165 g_printerr (_("Error: %s\n"), error
->message
);
166 g_error_free (error
);
169 g_variant_get (result
, "(&s)", &xml_data
);
172 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
173 g_variant_unref (result
);
176 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
177 g_error_free (error
);
181 for (n
= 0; node
->interfaces
!= NULL
&& node
->interfaces
[n
] != NULL
; n
++)
183 const GDBusInterfaceInfo
*iface
= node
->interfaces
[n
];
184 for (m
= 0; iface
->methods
!= NULL
&& iface
->methods
[m
] != NULL
; m
++)
186 const GDBusMethodInfo
*method
= iface
->methods
[m
];
187 g_print ("%s.%s \n", iface
->name
, method
->name
);
190 g_dbus_node_info_unref (node
);
197 print_paths (GDBusConnection
*c
,
203 const gchar
*xml_data
;
207 if (!g_dbus_is_name (name
))
209 g_printerr (_("Error: %s is not a valid name\n"), name
);
214 result
= g_dbus_connection_call_sync (c
,
217 "org.freedesktop.DBus.Introspectable",
220 G_VARIANT_TYPE ("(s)"),
221 G_DBUS_CALL_FLAGS_NONE
,
227 g_printerr (_("Error: %s\n"), error
->message
);
228 g_error_free (error
);
231 g_variant_get (result
, "(&s)", &xml_data
);
233 //g_printerr ("xml='%s'", xml_data);
236 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
237 g_variant_unref (result
);
240 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
241 g_error_free (error
);
245 //g_printerr ("bar '%s'\n", path);
247 if (node
->interfaces
!= NULL
)
248 g_print ("%s \n", path
);
250 for (n
= 0; node
->nodes
!= NULL
&& node
->nodes
[n
] != NULL
; n
++)
254 //g_printerr ("foo '%s'\n", node->nodes[n].path);
256 if (g_strcmp0 (path
, "/") == 0)
257 s
= g_strdup_printf ("/%s", node
->nodes
[n
]->path
);
259 s
= g_strdup_printf ("%s/%s", path
, node
->nodes
[n
]->path
);
261 print_paths (c
, name
, s
);
265 g_dbus_node_info_unref (node
);
272 print_names (GDBusConnection
*c
,
273 gboolean include_unique_names
)
279 GHashTable
*name_set
;
283 name_set
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
286 result
= g_dbus_connection_call_sync (c
,
287 "org.freedesktop.DBus",
288 "/org/freedesktop/DBus",
289 "org.freedesktop.DBus",
292 G_VARIANT_TYPE ("(as)"),
293 G_DBUS_CALL_FLAGS_NONE
,
299 g_printerr (_("Error: %s\n"), error
->message
);
300 g_error_free (error
);
303 g_variant_get (result
, "(as)", &iter
);
304 while (g_variant_iter_loop (iter
, "s", &str
))
305 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
306 g_variant_iter_free (iter
);
307 g_variant_unref (result
);
310 result
= g_dbus_connection_call_sync (c
,
311 "org.freedesktop.DBus",
312 "/org/freedesktop/DBus",
313 "org.freedesktop.DBus",
314 "ListActivatableNames",
316 G_VARIANT_TYPE ("(as)"),
317 G_DBUS_CALL_FLAGS_NONE
,
323 g_printerr (_("Error: %s\n"), error
->message
);
324 g_error_free (error
);
327 g_variant_get (result
, "(as)", &iter
);
328 while (g_variant_iter_loop (iter
, "s", &str
))
329 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
330 g_variant_iter_free (iter
);
331 g_variant_unref (result
);
333 keys
= g_hash_table_get_keys (name_set
);
334 keys
= g_list_sort (keys
, (GCompareFunc
) g_strcmp0
);
335 for (l
= keys
; l
!= NULL
; l
= l
->next
)
337 const gchar
*name
= l
->data
;
338 if (!include_unique_names
&& g_str_has_prefix (name
, ":"))
341 g_print ("%s \n", name
);
346 g_hash_table_unref (name_set
);
349 /* ---------------------------------------------------------------------------------------------------- */
351 static gboolean opt_connection_system
= FALSE
;
352 static gboolean opt_connection_session
= FALSE
;
353 static gchar
*opt_connection_address
= NULL
;
355 static const GOptionEntry connection_entries
[] =
357 { "system", 'y', 0, G_OPTION_ARG_NONE
, &opt_connection_system
, N_("Connect to the system bus"), NULL
},
358 { "session", 'e', 0, G_OPTION_ARG_NONE
, &opt_connection_session
, N_("Connect to the session bus"), NULL
},
359 { "address", 'a', 0, G_OPTION_ARG_STRING
, &opt_connection_address
, N_("Connect to given D-Bus address"), NULL
},
363 static GOptionGroup
*
364 connection_get_group (void)
366 static GOptionGroup
*g
;
368 g
= g_option_group_new ("connection",
369 N_("Connection Endpoint Options:"),
370 N_("Options specifying the connection endpoint"),
373 g_option_group_set_translation_domain (g
, GETTEXT_PACKAGE
);
374 g_option_group_add_entries (g
, connection_entries
);
379 static GDBusConnection
*
380 connection_get_dbus_connection (GError
**error
)
386 /* First, ensure we have exactly one connect */
387 if (!opt_connection_system
&& !opt_connection_session
&& opt_connection_address
== NULL
)
392 _("No connection endpoint specified"));
395 else if ((opt_connection_system
&& (opt_connection_session
|| opt_connection_address
!= NULL
)) ||
396 (opt_connection_session
&& (opt_connection_system
|| opt_connection_address
!= NULL
)) ||
397 (opt_connection_address
!= NULL
&& (opt_connection_system
|| opt_connection_session
)))
402 _("Multiple connection endpoints specified"));
406 if (opt_connection_system
)
408 c
= g_bus_get_sync (G_BUS_TYPE_SYSTEM
, NULL
, error
);
410 else if (opt_connection_session
)
412 c
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, error
);
414 else if (opt_connection_address
!= NULL
)
416 c
= g_dbus_connection_new_for_address_sync (opt_connection_address
,
417 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
,
418 NULL
, /* GDBusAuthObserver */
419 NULL
, /* GCancellable */
427 /* ---------------------------------------------------------------------------------------------------- */
430 call_helper_get_method_in_signature (GDBusConnection
*c
,
433 const gchar
*interface_name
,
434 const gchar
*method_name
,
439 GDBusNodeInfo
*node_info
;
440 const gchar
*xml_data
;
441 GDBusInterfaceInfo
*interface_info
;
442 GDBusMethodInfo
*method_info
;
449 result
= g_dbus_connection_call_sync (c
,
452 "org.freedesktop.DBus.Introspectable",
455 G_VARIANT_TYPE ("(s)"),
456 G_DBUS_CALL_FLAGS_NONE
,
463 g_variant_get (result
, "(&s)", &xml_data
);
464 node_info
= g_dbus_node_info_new_for_xml (xml_data
, error
);
465 if (node_info
== NULL
)
468 interface_info
= g_dbus_node_info_lookup_interface (node_info
, interface_name
);
469 if (interface_info
== NULL
)
471 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
472 _("Warning: According to introspection data, interface “%s” does not exist\n"),
477 method_info
= g_dbus_interface_info_lookup_method (interface_info
, method_name
);
478 if (method_info
== NULL
)
480 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
481 _("Warning: According to introspection data, method “%s” does not exist on interface “%s”\n"),
487 ret
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_variant_type_free
);
488 for (n
= 0; method_info
->in_args
!= NULL
&& method_info
->in_args
[n
] != NULL
; n
++)
490 g_ptr_array_add (ret
, g_variant_type_new (method_info
->in_args
[n
]->signature
));
494 if (node_info
!= NULL
)
495 g_dbus_node_info_unref (node_info
);
497 g_variant_unref (result
);
502 /* ---------------------------------------------------------------------------------------------------- */
505 _g_variant_parse_me_harder (GVariantType
*type
,
506 const gchar
*given_str
,
514 str
= g_string_new ("\"");
515 for (n
= 0; given_str
[n
] != '\0'; n
++)
517 if (G_UNLIKELY (given_str
[n
] == '\"'))
518 g_string_append (str
, "\\\"");
520 g_string_append_c (str
, given_str
[n
]);
522 g_string_append_c (str
, '"');
523 s
= g_string_free (str
, FALSE
);
525 value
= g_variant_parse (type
,
535 /* ---------------------------------------------------------------------------------------------------- */
537 static gchar
*opt_emit_dest
= NULL
;
538 static gchar
*opt_emit_object_path
= NULL
;
539 static gchar
*opt_emit_signal
= NULL
;
541 static const GOptionEntry emit_entries
[] =
543 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_emit_dest
, N_("Optional destination for signal (unique name)"), NULL
},
544 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_emit_object_path
, N_("Object path to emit signal on"), NULL
},
545 { "signal", 's', 0, G_OPTION_ARG_STRING
, &opt_emit_signal
, N_("Signal and interface name"), NULL
},
550 handle_emit (gint
*argc
,
552 gboolean request_completion
,
553 const gchar
*completion_cur
,
554 const gchar
*completion_prev
)
561 GVariant
*parameters
;
562 gchar
*interface_name
;
564 GVariantBuilder builder
;
565 gboolean skip_dashes
;
572 interface_name
= NULL
;
575 modify_argv0_for_command (argc
, argv
, "emit");
577 o
= g_option_context_new (NULL
);
578 g_option_context_set_help_enabled (o
, FALSE
);
579 g_option_context_set_summary (o
, _("Emit a signal."));
580 g_option_context_add_main_entries (o
, emit_entries
, GETTEXT_PACKAGE
);
581 g_option_context_add_group (o
, connection_get_group ());
583 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
585 if (!request_completion
)
587 s
= g_option_context_get_help (o
, FALSE
, NULL
);
588 g_printerr ("%s", s
);
595 c
= connection_get_dbus_connection (&error
);
598 if (request_completion
)
600 if (g_strcmp0 (completion_prev
, "--address") == 0)
608 g_print ("--system \n--session \n--address \n");
613 g_printerr (_("Error connecting: %s\n"), error
->message
);
614 g_error_free (error
);
619 /* All done with completion now */
620 if (request_completion
)
623 if (opt_emit_object_path
== NULL
)
625 g_printerr (_("Error: object path not specified.\n"));
628 if (!g_variant_is_object_path (opt_emit_object_path
))
630 g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path
);
634 if (opt_emit_signal
== NULL
)
636 g_printerr (_("Error: signal not specified.\n"));
640 s
= strrchr (opt_emit_signal
, '.');
643 g_printerr (_("Error: signal must be the fully-qualified name.\n"));
646 signal_name
= g_strdup (s
+ 1);
647 interface_name
= g_strndup (opt_emit_signal
, s
- opt_emit_signal
);
649 if (!g_dbus_is_interface_name (interface_name
))
651 g_printerr (_("Error: %s is not a valid interface name\n"), interface_name
);
655 if (!g_dbus_is_member_name (signal_name
))
657 g_printerr (_("Error: %s is not a valid member name\n"), signal_name
);
661 if (opt_emit_dest
!= NULL
&& !g_dbus_is_unique_name (opt_emit_dest
))
663 g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest
);
667 /* Read parameters */
668 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
671 for (n
= 1; n
< (guint
) *argc
; n
++)
675 /* Under certain conditions, g_option_context_parse returns the "--"
676 itself (setting off unparsed arguments), too: */
677 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
684 value
= g_variant_parse (NULL
,
693 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
694 g_error_free (error
);
696 value
= _g_variant_parse_me_harder (NULL
, (*argv
)[n
], &error
);
699 /* Use the original non-"parse-me-harder" error */
700 g_printerr (_("Error parsing parameter %d: %s\n"),
703 g_error_free (error
);
705 g_variant_builder_clear (&builder
);
710 g_variant_builder_add_value (&builder
, value
);
713 parameters
= g_variant_builder_end (&builder
);
715 if (parameters
!= NULL
)
716 parameters
= g_variant_ref_sink (parameters
);
717 if (!g_dbus_connection_emit_signal (c
,
719 opt_emit_object_path
,
725 g_printerr (_("Error: %s\n"), error
->message
);
726 g_error_free (error
);
730 if (!g_dbus_connection_flush_sync (c
, NULL
, &error
))
732 g_printerr (_("Error flushing connection: %s\n"), error
->message
);
733 g_error_free (error
);
742 if (parameters
!= NULL
)
743 g_variant_unref (parameters
);
744 g_free (interface_name
);
745 g_free (signal_name
);
746 g_option_context_free (o
);
750 /* ---------------------------------------------------------------------------------------------------- */
752 static gchar
*opt_call_dest
= NULL
;
753 static gchar
*opt_call_object_path
= NULL
;
754 static gchar
*opt_call_method
= NULL
;
755 static gint opt_call_timeout
= -1;
757 static const GOptionEntry call_entries
[] =
759 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_call_dest
, N_("Destination name to invoke method on"), NULL
},
760 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_call_object_path
, N_("Object path to invoke method on"), NULL
},
761 { "method", 'm', 0, G_OPTION_ARG_STRING
, &opt_call_method
, N_("Method and interface name"), NULL
},
762 { "timeout", 't', 0, G_OPTION_ARG_INT
, &opt_call_timeout
, N_("Timeout in seconds"), NULL
},
767 handle_call (gint
*argc
,
769 gboolean request_completion
,
770 const gchar
*completion_cur
,
771 const gchar
*completion_prev
)
778 GVariant
*parameters
;
779 gchar
*interface_name
;
782 GPtrArray
*in_signature_types
;
783 gboolean complete_names
;
784 gboolean complete_paths
;
785 gboolean complete_methods
;
786 GVariantBuilder builder
;
787 gboolean skip_dashes
;
794 interface_name
= NULL
;
797 in_signature_types
= NULL
;
799 modify_argv0_for_command (argc
, argv
, "call");
801 o
= g_option_context_new (NULL
);
802 g_option_context_set_help_enabled (o
, FALSE
);
803 g_option_context_set_summary (o
, _("Invoke a method on a remote object."));
804 g_option_context_add_main_entries (o
, call_entries
, GETTEXT_PACKAGE
);
805 g_option_context_add_group (o
, connection_get_group ());
807 complete_names
= FALSE
;
808 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
810 complete_names
= TRUE
;
811 remove_arg ((*argc
) - 1, argc
, argv
);
814 complete_paths
= FALSE
;
815 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
817 complete_paths
= TRUE
;
818 remove_arg ((*argc
) - 1, argc
, argv
);
821 complete_methods
= FALSE
;
822 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--method") == 0)
824 complete_methods
= TRUE
;
825 remove_arg ((*argc
) - 1, argc
, argv
);
828 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
830 if (!request_completion
)
832 s
= g_option_context_get_help (o
, FALSE
, NULL
);
833 g_printerr ("%s", s
);
840 c
= connection_get_dbus_connection (&error
);
843 if (request_completion
)
845 if (g_strcmp0 (completion_prev
, "--address") == 0)
853 g_print ("--system \n--session \n--address \n");
858 g_printerr (_("Error connecting: %s\n"), error
->message
);
859 g_error_free (error
);
864 /* validate and complete destination (bus name) */
865 if (g_dbus_connection_get_unique_name (c
) != NULL
)
867 /* this only makes sense on message bus connections */
870 print_names (c
, FALSE
);
873 if (opt_call_dest
== NULL
)
875 if (request_completion
)
876 g_print ("--dest \n");
878 g_printerr (_("Error: Destination is not specified\n"));
881 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
883 print_names (c
, g_str_has_prefix (opt_call_dest
, ":"));
888 if (!request_completion
&& !g_dbus_is_name (opt_call_dest
))
890 g_printerr (_("Error: %s is not a valid bus name\n"), opt_call_dest
);
894 /* validate and complete object path */
897 print_paths (c
, opt_call_dest
, "/");
900 if (opt_call_object_path
== NULL
)
902 if (request_completion
)
903 g_print ("--object-path \n");
905 g_printerr (_("Error: Object path is not specified\n"));
908 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
911 s
= g_strdup (opt_call_object_path
);
912 p
= strrchr (s
, '/');
919 print_paths (c
, opt_call_dest
, s
);
923 if (!request_completion
&& !g_variant_is_object_path (opt_call_object_path
))
925 g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path
);
929 /* validate and complete method (interface + method name) */
930 if (complete_methods
)
932 print_methods (c
, opt_call_dest
, opt_call_object_path
);
935 if (opt_call_method
== NULL
)
937 if (request_completion
)
938 g_print ("--method \n");
940 g_printerr (_("Error: Method name is not specified\n"));
943 if (request_completion
&& g_strcmp0 ("--method", completion_prev
) == 0)
945 print_methods (c
, opt_call_dest
, opt_call_object_path
);
948 s
= strrchr (opt_call_method
, '.');
949 if (!request_completion
&& s
== NULL
)
951 g_printerr (_("Error: Method name “%s” is invalid\n"), opt_call_method
);
954 method_name
= g_strdup (s
+ 1);
955 interface_name
= g_strndup (opt_call_method
, s
- opt_call_method
);
957 /* All done with completion now */
958 if (request_completion
)
961 /* Introspect, for easy conversion - it's not fatal if we can't do this */
962 in_signature_types
= call_helper_get_method_in_signature (c
,
964 opt_call_object_path
,
968 if (in_signature_types
== NULL
)
970 //g_printerr ("Error getting introspection data: %s\n", error->message);
971 g_error_free (error
);
975 /* Read parameters */
976 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
979 for (n
= 1; n
< (guint
) *argc
; n
++)
984 /* Under certain conditions, g_option_context_parse returns the "--"
985 itself (setting off unparsed arguments), too: */
986 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
993 if (in_signature_types
!= NULL
)
995 if (parm
>= in_signature_types
->len
)
997 /* Only warn for the first param */
998 if (parm
== in_signature_types
->len
)
1000 g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n",
1001 in_signature_types
->len
);
1006 type
= in_signature_types
->pdata
[parm
];
1011 value
= g_variant_parse (type
,
1020 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
1021 g_error_free (error
);
1023 value
= _g_variant_parse_me_harder (type
, (*argv
)[n
], &error
);
1028 s
= g_variant_type_dup_string (type
);
1029 g_printerr (_("Error parsing parameter %d of type “%s”: %s\n"),
1037 g_printerr (_("Error parsing parameter %d: %s\n"),
1041 g_error_free (error
);
1042 g_variant_builder_clear (&builder
);
1048 g_variant_builder_add_value (&builder
, value
);
1051 parameters
= g_variant_builder_end (&builder
);
1053 if (parameters
!= NULL
)
1054 parameters
= g_variant_ref_sink (parameters
);
1055 result
= g_dbus_connection_call_sync (c
,
1057 opt_call_object_path
,
1062 G_DBUS_CALL_FLAGS_NONE
,
1063 opt_call_timeout
> 0 ? opt_call_timeout
* 1000 : opt_call_timeout
,
1068 g_printerr (_("Error: %s\n"), error
->message
);
1070 if (g_error_matches (error
, G_DBUS_ERROR
, G_DBUS_ERROR_INVALID_ARGS
) && in_signature_types
!= NULL
)
1072 if (in_signature_types
->len
> 0)
1075 s
= g_string_new (NULL
);
1077 for (n
= 0; n
< in_signature_types
->len
; n
++)
1079 GVariantType
*type
= in_signature_types
->pdata
[n
];
1080 g_string_append_len (s
,
1081 g_variant_type_peek_string (type
),
1082 g_variant_type_get_string_length (type
));
1085 g_printerr ("(According to introspection data, you need to pass '%s')\n", s
->str
);
1086 g_string_free (s
, TRUE
);
1089 g_printerr ("(According to introspection data, you need to pass no arguments)\n");
1092 g_error_free (error
);
1096 s
= g_variant_print (result
, TRUE
);
1097 g_print ("%s\n", s
);
1103 if (in_signature_types
!= NULL
)
1104 g_ptr_array_unref (in_signature_types
);
1106 g_variant_unref (result
);
1109 if (parameters
!= NULL
)
1110 g_variant_unref (parameters
);
1111 g_free (interface_name
);
1112 g_free (method_name
);
1113 g_option_context_free (o
);
1117 /* ---------------------------------------------------------------------------------------------------- */
1119 static gchar
*opt_introspect_dest
= NULL
;
1120 static gchar
*opt_introspect_object_path
= NULL
;
1121 static gboolean opt_introspect_xml
= FALSE
;
1122 static gboolean opt_introspect_recurse
= FALSE
;
1123 static gboolean opt_introspect_only_properties
= FALSE
;
1126 dump_annotation (const GDBusAnnotationInfo
*o
,
1128 gboolean ignore_indent
)
1131 g_print ("%*s@%s(\"%s\")\n",
1132 ignore_indent
? 0 : indent
, "",
1135 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1136 dump_annotation (o
->annotations
[n
], indent
+ 2, FALSE
);
1140 dump_arg (const GDBusArgInfo
*o
,
1142 const gchar
*direction
,
1143 gboolean ignore_indent
,
1144 gboolean include_newline
)
1148 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1150 dump_annotation (o
->annotations
[n
], indent
, ignore_indent
);
1151 ignore_indent
= FALSE
;
1154 g_print ("%*s%s%s %s%s",
1155 ignore_indent
? 0 : indent
, "",
1159 include_newline
? ",\n" : "");
1163 count_args (GDBusArgInfo
**args
)
1169 while (args
[n
] != NULL
)
1176 dump_method (const GDBusMethodInfo
*o
,
1182 guint total_num_args
;
1184 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1185 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1187 g_print ("%*s%s(", indent
, "", o
->name
);
1188 name_len
= strlen (o
->name
);
1189 total_num_args
= count_args (o
->in_args
) + count_args (o
->out_args
);
1190 for (n
= 0, m
= 0; o
->in_args
!= NULL
&& o
->in_args
[n
] != NULL
; n
++, m
++)
1192 gboolean ignore_indent
= (m
== 0);
1193 gboolean include_newline
= (m
!= total_num_args
- 1);
1195 dump_arg (o
->in_args
[n
],
1196 indent
+ name_len
+ 1,
1201 for (n
= 0; o
->out_args
!= NULL
&& o
->out_args
[n
] != NULL
; n
++, m
++)
1203 gboolean ignore_indent
= (m
== 0);
1204 gboolean include_newline
= (m
!= total_num_args
- 1);
1205 dump_arg (o
->out_args
[n
],
1206 indent
+ name_len
+ 1,
1215 dump_signal (const GDBusSignalInfo
*o
,
1220 guint total_num_args
;
1222 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1223 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1225 g_print ("%*s%s(", indent
, "", o
->name
);
1226 name_len
= strlen (o
->name
);
1227 total_num_args
= count_args (o
->args
);
1228 for (n
= 0; o
->args
!= NULL
&& o
->args
[n
] != NULL
; n
++)
1230 gboolean ignore_indent
= (n
== 0);
1231 gboolean include_newline
= (n
!= total_num_args
- 1);
1232 dump_arg (o
->args
[n
],
1233 indent
+ name_len
+ 1,
1242 dump_property (const GDBusPropertyInfo
*o
,
1246 const gchar
*access
;
1249 if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
1250 access
= "readonly";
1251 else if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
)
1252 access
= "writeonly";
1253 else if (o
->flags
== (G_DBUS_PROPERTY_INFO_FLAGS_READABLE
| G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
))
1254 access
= "readwrite";
1256 g_assert_not_reached ();
1258 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1259 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1263 gchar
*s
= g_variant_print (value
, FALSE
);
1264 g_print ("%*s%s %s %s = %s;\n", indent
, "", access
, o
->signature
, o
->name
, s
);
1269 g_print ("%*s%s %s %s;\n", indent
, "", access
, o
->signature
, o
->name
);
1274 dump_interface (GDBusConnection
*c
,
1276 const GDBusInterfaceInfo
*o
,
1278 const gchar
*object_path
)
1281 GHashTable
*properties
;
1283 properties
= g_hash_table_new_full (g_str_hash
,
1286 (GDestroyNotify
) g_variant_unref
);
1288 /* Try to get properties */
1289 if (c
!= NULL
&& name
!= NULL
&& object_path
!= NULL
&& o
->properties
!= NULL
)
1292 result
= g_dbus_connection_call_sync (c
,
1295 "org.freedesktop.DBus.Properties",
1297 g_variant_new ("(s)", o
->name
),
1299 G_DBUS_CALL_FLAGS_NONE
,
1305 if (g_variant_is_of_type (result
, G_VARIANT_TYPE ("(a{sv})")))
1309 g_variant_get (result
,
1312 while ((item
= g_variant_iter_next_value (iter
)))
1316 g_variant_get (item
,
1321 g_hash_table_insert (properties
, key
, g_variant_ref (value
));
1324 g_variant_unref (result
);
1329 for (n
= 0; o
->properties
!= NULL
&& o
->properties
[n
] != NULL
; n
++)
1331 result
= g_dbus_connection_call_sync (c
,
1334 "org.freedesktop.DBus.Properties",
1336 g_variant_new ("(ss)", o
->name
, o
->properties
[n
]->name
),
1337 G_VARIANT_TYPE ("(v)"),
1338 G_DBUS_CALL_FLAGS_NONE
,
1344 GVariant
*property_value
;
1345 g_variant_get (result
,
1348 g_hash_table_insert (properties
,
1349 g_strdup (o
->properties
[n
]->name
),
1350 g_variant_ref (property_value
));
1351 g_variant_unref (result
);
1357 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1358 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1360 g_print ("%*sinterface %s {\n", indent
, "", o
->name
);
1361 if (o
->methods
!= NULL
&& !opt_introspect_only_properties
)
1363 g_print ("%*s methods:\n", indent
, "");
1364 for (n
= 0; o
->methods
[n
] != NULL
; n
++)
1365 dump_method (o
->methods
[n
], indent
+ 4);
1367 if (o
->signals
!= NULL
&& !opt_introspect_only_properties
)
1369 g_print ("%*s signals:\n", indent
, "");
1370 for (n
= 0; o
->signals
[n
] != NULL
; n
++)
1371 dump_signal (o
->signals
[n
], indent
+ 4);
1373 if (o
->properties
!= NULL
)
1375 g_print ("%*s properties:\n", indent
, "");
1376 for (n
= 0; o
->properties
[n
] != NULL
; n
++)
1378 dump_property (o
->properties
[n
],
1380 g_hash_table_lookup (properties
, (o
->properties
[n
])->name
));
1386 g_hash_table_unref (properties
);
1390 introspect_do (GDBusConnection
*c
,
1391 const gchar
*object_path
,
1395 dump_node (GDBusConnection
*c
,
1397 const GDBusNodeInfo
*o
,
1399 const gchar
*object_path
,
1403 const gchar
*object_path_to_print
;
1405 object_path_to_print
= object_path
;
1406 if (o
->path
!= NULL
)
1407 object_path_to_print
= o
->path
;
1409 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1410 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1412 g_print ("%*snode %s", indent
, "", object_path_to_print
!= NULL
? object_path_to_print
: "(not set)");
1413 if (o
->interfaces
!= NULL
|| o
->nodes
!= NULL
)
1416 for (n
= 0; o
->interfaces
!= NULL
&& o
->interfaces
[n
] != NULL
; n
++)
1418 if (opt_introspect_only_properties
)
1420 if (o
->interfaces
[n
]->properties
!= NULL
&& o
->interfaces
[n
]->properties
[0] != NULL
)
1421 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1425 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1428 for (n
= 0; o
->nodes
!= NULL
&& o
->nodes
[n
] != NULL
; n
++)
1433 if (g_variant_is_object_path (o
->nodes
[n
]->path
))
1435 child_path
= g_strdup (o
->nodes
[n
]->path
);
1436 /* avoid infinite loops */
1437 if (g_str_has_prefix (child_path
, object_path
))
1439 introspect_do (c
, child_path
, indent
+ 2);
1443 g_print ("Skipping path %s that is not enclosed by parent %s\n",
1444 child_path
, object_path
);
1449 if (g_strcmp0 (object_path
, "/") == 0)
1450 child_path
= g_strdup_printf ("/%s", o
->nodes
[n
]->path
);
1452 child_path
= g_strdup_printf ("%s/%s", object_path
, o
->nodes
[n
]->path
);
1453 introspect_do (c
, child_path
, indent
+ 2);
1455 g_free (child_path
);
1459 dump_node (NULL
, NULL
, o
->nodes
[n
], indent
+ 2, NULL
, recurse
);
1471 static const GOptionEntry introspect_entries
[] =
1473 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_introspect_dest
, N_("Destination name to introspect"), NULL
},
1474 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_introspect_object_path
, N_("Object path to introspect"), NULL
},
1475 { "xml", 'x', 0, G_OPTION_ARG_NONE
, &opt_introspect_xml
, N_("Print XML"), NULL
},
1476 { "recurse", 'r', 0, G_OPTION_ARG_NONE
, &opt_introspect_recurse
, N_("Introspect children"), NULL
},
1477 { "only-properties", 'p', 0, G_OPTION_ARG_NONE
, &opt_introspect_only_properties
, N_("Only print properties"), NULL
},
1482 introspect_do (GDBusConnection
*c
,
1483 const gchar
*object_path
,
1488 GDBusNodeInfo
*node
;
1490 const gchar
*xml_data
;
1497 result
= g_dbus_connection_call_sync (c
,
1498 opt_introspect_dest
,
1500 "org.freedesktop.DBus.Introspectable",
1503 G_VARIANT_TYPE ("(s)"),
1504 G_DBUS_CALL_FLAGS_NONE
,
1510 g_printerr (_("Error: %s\n"), error
->message
);
1511 g_error_free (error
);
1514 g_variant_get (result
, "(&s)", &xml_data
);
1516 if (opt_introspect_xml
)
1518 g_print ("%s", xml_data
);
1523 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
1526 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
1527 g_error_free (error
);
1531 dump_node (c
, opt_introspect_dest
, node
, indent
, object_path
, opt_introspect_recurse
);
1538 g_dbus_node_info_unref (node
);
1540 g_variant_unref (result
);
1545 handle_introspect (gint
*argc
,
1547 gboolean request_completion
,
1548 const gchar
*completion_cur
,
1549 const gchar
*completion_prev
)
1556 gboolean complete_names
;
1557 gboolean complete_paths
;
1562 modify_argv0_for_command (argc
, argv
, "introspect");
1564 o
= g_option_context_new (NULL
);
1565 if (request_completion
)
1566 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1567 g_option_context_set_help_enabled (o
, FALSE
);
1568 g_option_context_set_summary (o
, _("Introspect a remote object."));
1569 g_option_context_add_main_entries (o
, introspect_entries
, GETTEXT_PACKAGE
);
1570 g_option_context_add_group (o
, connection_get_group ());
1572 complete_names
= FALSE
;
1573 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1575 complete_names
= TRUE
;
1576 remove_arg ((*argc
) - 1, argc
, argv
);
1579 complete_paths
= FALSE
;
1580 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1582 complete_paths
= TRUE
;
1583 remove_arg ((*argc
) - 1, argc
, argv
);
1586 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1588 if (!request_completion
)
1590 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1591 g_printerr ("%s", s
);
1598 c
= connection_get_dbus_connection (&error
);
1601 if (request_completion
)
1603 if (g_strcmp0 (completion_prev
, "--address") == 0)
1611 g_print ("--system \n--session \n--address \n");
1616 g_printerr (_("Error connecting: %s\n"), error
->message
);
1617 g_error_free (error
);
1622 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1626 print_names (c
, FALSE
);
1629 /* this only makes sense on message bus connections */
1630 if (opt_introspect_dest
== NULL
)
1632 if (request_completion
)
1633 g_print ("--dest \n");
1635 g_printerr (_("Error: Destination is not specified\n"));
1638 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1640 print_names (c
, g_str_has_prefix (opt_introspect_dest
, ":"));
1646 print_paths (c
, opt_introspect_dest
, "/");
1650 if (!request_completion
&& !g_dbus_is_name (opt_introspect_dest
))
1652 g_printerr (_("Error: %s is not a valid bus name\n"), opt_introspect_dest
);
1656 if (opt_introspect_object_path
== NULL
)
1658 if (request_completion
)
1659 g_print ("--object-path \n");
1661 g_printerr (_("Error: Object path is not specified\n"));
1664 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1667 s
= g_strdup (opt_introspect_object_path
);
1668 p
= strrchr (s
, '/');
1675 print_paths (c
, opt_introspect_dest
, s
);
1679 if (!request_completion
&& !g_variant_is_object_path (opt_introspect_object_path
))
1681 g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path
);
1685 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_recurse
)
1687 g_print ("--recurse \n");
1690 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_only_properties
)
1692 g_print ("--only-properties \n");
1695 /* All done with completion now */
1696 if (request_completion
)
1699 if (!introspect_do (c
, opt_introspect_object_path
, 0))
1707 g_option_context_free (o
);
1711 /* ---------------------------------------------------------------------------------------------------- */
1713 static gchar
*opt_monitor_dest
= NULL
;
1714 static gchar
*opt_monitor_object_path
= NULL
;
1716 static guint monitor_filter_id
= 0;
1719 monitor_signal_cb (GDBusConnection
*connection
,
1720 const gchar
*sender_name
,
1721 const gchar
*object_path
,
1722 const gchar
*interface_name
,
1723 const gchar
*signal_name
,
1724 GVariant
*parameters
,
1728 s
= g_variant_print (parameters
, TRUE
);
1729 g_print ("%s: %s.%s %s\n",
1738 monitor_on_name_appeared (GDBusConnection
*connection
,
1740 const gchar
*name_owner
,
1743 g_print ("The name %s is owned by %s\n", name
, name_owner
);
1744 g_assert (monitor_filter_id
== 0);
1745 monitor_filter_id
= g_dbus_connection_signal_subscribe (connection
,
1747 NULL
, /* any interface */
1748 NULL
, /* any member */
1749 opt_monitor_object_path
,
1751 G_DBUS_SIGNAL_FLAGS_NONE
,
1753 NULL
, /* user_data */
1754 NULL
); /* user_data destroy notify */
1758 monitor_on_name_vanished (GDBusConnection
*connection
,
1762 g_print ("The name %s does not have an owner\n", name
);
1764 if (monitor_filter_id
!= 0)
1766 g_dbus_connection_signal_unsubscribe (connection
, monitor_filter_id
);
1767 monitor_filter_id
= 0;
1771 static const GOptionEntry monitor_entries
[] =
1773 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_monitor_dest
, N_("Destination name to monitor"), NULL
},
1774 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_monitor_object_path
, N_("Object path to monitor"), NULL
},
1779 handle_monitor (gint
*argc
,
1781 gboolean request_completion
,
1782 const gchar
*completion_cur
,
1783 const gchar
*completion_prev
)
1790 gboolean complete_names
;
1791 gboolean complete_paths
;
1797 modify_argv0_for_command (argc
, argv
, "monitor");
1799 o
= g_option_context_new (NULL
);
1800 if (request_completion
)
1801 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1802 g_option_context_set_help_enabled (o
, FALSE
);
1803 g_option_context_set_summary (o
, _("Monitor a remote object."));
1804 g_option_context_add_main_entries (o
, monitor_entries
, GETTEXT_PACKAGE
);
1805 g_option_context_add_group (o
, connection_get_group ());
1807 complete_names
= FALSE
;
1808 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1810 complete_names
= TRUE
;
1811 remove_arg ((*argc
) - 1, argc
, argv
);
1814 complete_paths
= FALSE
;
1815 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1817 complete_paths
= TRUE
;
1818 remove_arg ((*argc
) - 1, argc
, argv
);
1821 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1823 if (!request_completion
)
1825 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1826 g_printerr ("%s", s
);
1833 c
= connection_get_dbus_connection (&error
);
1836 if (request_completion
)
1838 if (g_strcmp0 (completion_prev
, "--address") == 0)
1846 g_print ("--system \n--session \n--address \n");
1851 g_printerr (_("Error connecting: %s\n"), error
->message
);
1852 g_error_free (error
);
1857 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1861 print_names (c
, FALSE
);
1864 /* this only makes sense on message bus connections */
1865 if (opt_monitor_dest
== NULL
)
1867 if (request_completion
)
1868 g_print ("--dest \n");
1870 g_printerr (_("Error: Destination is not specified\n"));
1873 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1875 print_names (c
, g_str_has_prefix (opt_monitor_dest
, ":"));
1880 if (!request_completion
&& !g_dbus_is_name (opt_monitor_dest
))
1882 g_printerr (_("Error: %s is not a valid bus name\n"), opt_monitor_dest
);
1888 print_paths (c
, opt_monitor_dest
, "/");
1891 if (opt_monitor_object_path
== NULL
)
1893 if (request_completion
)
1895 g_print ("--object-path \n");
1898 /* it's fine to not have an object path */
1900 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1903 s
= g_strdup (opt_monitor_object_path
);
1904 p
= strrchr (s
, '/');
1911 print_paths (c
, opt_monitor_dest
, s
);
1915 if (!request_completion
&& (opt_monitor_object_path
!= NULL
&& !g_variant_is_object_path (opt_monitor_object_path
)))
1917 g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path
);
1921 /* All done with completion now */
1922 if (request_completion
)
1925 if (opt_monitor_object_path
!= NULL
)
1926 g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path
, opt_monitor_dest
);
1928 g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest
);
1930 loop
= g_main_loop_new (NULL
, FALSE
);
1931 g_bus_watch_name_on_connection (c
,
1933 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
1934 monitor_on_name_appeared
,
1935 monitor_on_name_vanished
,
1939 g_main_loop_run (loop
);
1940 g_main_loop_unref (loop
);
1947 g_option_context_free (o
);
1951 /* ---------------------------------------------------------------------------------------------------- */
1953 static gboolean opt_wait_activate_set
= FALSE
;
1954 static gchar
*opt_wait_activate_name
= NULL
;
1955 static gint64 opt_wait_timeout
= 0; /* no timeout */
1958 WAIT_STATE_RUNNING
, /* waiting to see the service */
1959 WAIT_STATE_SUCCESS
, /* seen it successfully */
1960 WAIT_STATE_TIMEOUT
, /* timed out before seeing it */
1964 opt_wait_activate_cb (const gchar
*option_name
,
1969 /* @value may be NULL */
1970 opt_wait_activate_set
= TRUE
;
1971 opt_wait_activate_name
= g_strdup (value
);
1976 static const GOptionEntry wait_entries
[] =
1978 { "activate", 'a', G_OPTION_FLAG_OPTIONAL_ARG
, G_OPTION_ARG_CALLBACK
,
1979 opt_wait_activate_cb
,
1980 N_("Service to activate before waiting for the other one (well-known name)"),
1982 { "timeout", 't', 0, G_OPTION_ARG_INT64
, &opt_wait_timeout
,
1983 N_("Timeout to wait for before exiting with an error (seconds); 0 for "
1984 "no timeout (default)"), "SECS" },
1989 wait_name_appeared_cb (GDBusConnection
*connection
,
1991 const gchar
*name_owner
,
1994 WaitState
*wait_state
= user_data
;
1996 *wait_state
= WAIT_STATE_SUCCESS
;
2000 wait_timeout_cb (gpointer user_data
)
2002 WaitState
*wait_state
= user_data
;
2004 *wait_state
= WAIT_STATE_TIMEOUT
;
2006 /* Removed in handle_wait(). */
2007 return G_SOURCE_CONTINUE
;
2011 handle_wait (gint
*argc
,
2013 gboolean request_completion
,
2014 const gchar
*completion_cur
,
2015 const gchar
*completion_prev
)
2022 guint watch_id
, timer_id
= 0, activate_watch_id
;
2023 const gchar
*activate_service
, *wait_service
;
2024 WaitState wait_state
= WAIT_STATE_RUNNING
;
2029 modify_argv0_for_command (argc
, argv
, "wait");
2031 o
= g_option_context_new (_("[OPTION…] BUS-NAME"));
2032 g_option_context_set_help_enabled (o
, FALSE
);
2033 g_option_context_set_summary (o
, _("Wait for a bus name to appear."));
2034 g_option_context_add_main_entries (o
, wait_entries
, GETTEXT_PACKAGE
);
2035 g_option_context_add_group (o
, connection_get_group ());
2037 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
2039 if (!request_completion
)
2041 s
= g_option_context_get_help (o
, FALSE
, NULL
);
2042 g_printerr ("%s", s
);
2049 c
= connection_get_dbus_connection (&error
);
2052 if (request_completion
)
2054 if (g_strcmp0 (completion_prev
, "--address") == 0)
2062 g_print ("--system \n--session \n--address \n");
2067 g_printerr (_("Error connecting: %s\n"), error
->message
);
2068 g_error_free (error
);
2073 /* All done with completion now */
2074 if (request_completion
)
2078 * Try and disentangle the command line arguments, with the aim of supporting:
2079 * gdbus wait --session --activate ActivateName WaitName
2080 * gdbus wait --session --activate ActivateAndWaitName
2081 * gdbus wait --activate --session ActivateAndWaitName
2082 * gdbus wait --session WaitName
2084 if (*argc
== 2 && opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2086 activate_service
= opt_wait_activate_name
;
2087 wait_service
= (*argv
)[1];
2089 else if (*argc
== 2 &&
2090 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2092 activate_service
= (*argv
)[1];
2093 wait_service
= (*argv
)[1];
2095 else if (*argc
== 2 && !opt_wait_activate_set
)
2097 activate_service
= NULL
; /* disabled */
2098 wait_service
= (*argv
)[1];
2100 else if (*argc
== 1 &&
2101 opt_wait_activate_set
&& opt_wait_activate_name
!= NULL
)
2103 activate_service
= opt_wait_activate_name
;
2104 wait_service
= opt_wait_activate_name
;
2106 else if (*argc
== 1 &&
2107 opt_wait_activate_set
&& opt_wait_activate_name
== NULL
)
2109 g_printerr (_("Error: A service to activate for must be specified.\n"));
2112 else if (*argc
== 1 && !opt_wait_activate_set
)
2114 g_printerr (_("Error: A service to wait for must be specified.\n"));
2117 else /* if (*argc > 2) */
2119 g_printerr (_("Error: Too many arguments.\n"));
2123 if (activate_service
!= NULL
&&
2124 (!g_dbus_is_name (activate_service
) ||
2125 g_dbus_is_unique_name (activate_service
)))
2127 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2132 if (!g_dbus_is_name (wait_service
) || g_dbus_is_unique_name (wait_service
))
2134 g_printerr (_("Error: %s is not a valid well-known bus name.\n"),
2139 /* Start the prerequisite service if needed. */
2140 if (activate_service
!= NULL
)
2142 activate_watch_id
= g_bus_watch_name_on_connection (c
, activate_service
,
2143 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
2149 activate_watch_id
= 0;
2152 /* Wait for the expected name to appear. */
2153 watch_id
= g_bus_watch_name_on_connection (c
,
2155 G_BUS_NAME_WATCHER_FLAGS_NONE
,
2156 wait_name_appeared_cb
,
2157 NULL
, &wait_state
, NULL
);
2159 /* Safety timeout. */
2160 if (opt_wait_timeout
> 0)
2161 timer_id
= g_timeout_add (opt_wait_timeout
, wait_timeout_cb
, &wait_state
);
2163 while (wait_state
== WAIT_STATE_RUNNING
)
2164 g_main_context_iteration (NULL
, TRUE
);
2166 g_bus_unwatch_name (watch_id
);
2168 g_source_remove (timer_id
);
2169 if (activate_watch_id
!= 0)
2170 g_bus_unwatch_name (activate_watch_id
);
2172 ret
= (wait_state
== WAIT_STATE_SUCCESS
);
2175 g_clear_object (&c
);
2176 g_option_context_free (o
);
2177 g_free (opt_wait_activate_name
);
2178 opt_wait_activate_name
= NULL
;
2183 /* ---------------------------------------------------------------------------------------------------- */
2186 pick_word_at (const gchar
*s
,
2188 gint
*out_word_begins_at
)
2195 if (out_word_begins_at
!= NULL
)
2196 *out_word_begins_at
= -1;
2200 if (g_ascii_isspace (s
[cursor
]) && ((cursor
> 0 && g_ascii_isspace(s
[cursor
-1])) || cursor
== 0))
2202 if (out_word_begins_at
!= NULL
)
2203 *out_word_begins_at
= cursor
;
2204 return g_strdup ("");
2207 while (!g_ascii_isspace (s
[cursor
- 1]) && cursor
> 0)
2212 while (!g_ascii_isspace (s
[end
]) && s
[end
] != '\0')
2215 if (out_word_begins_at
!= NULL
)
2216 *out_word_begins_at
= begin
;
2218 return g_strndup (s
+ begin
, end
- begin
);
2222 main (gint argc
, gchar
*argv
[])
2225 const gchar
*command
;
2226 gboolean request_completion
;
2227 gchar
*completion_cur
;
2228 gchar
*completion_prev
;
2233 setlocale (LC_ALL
, "");
2234 textdomain (GETTEXT_PACKAGE
);
2237 tmp
= _glib_get_locale_dir ();
2238 bindtextdomain (GETTEXT_PACKAGE
, tmp
);
2241 bindtextdomain (GETTEXT_PACKAGE
, GLIB_LOCALE_DIR
);
2244 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2245 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
2249 completion_cur
= NULL
;
2250 completion_prev
= NULL
;
2254 usage (&argc
, &argv
, FALSE
);
2258 request_completion
= FALSE
;
2260 //completion_debug ("---- argc=%d --------------------------------------------------------", argc);
2264 if (g_strcmp0 (command
, "help") == 0)
2266 if (request_completion
)
2272 usage (&argc
, &argv
, TRUE
);
2277 else if (g_strcmp0 (command
, "emit") == 0)
2279 if (handle_emit (&argc
,
2287 else if (g_strcmp0 (command
, "call") == 0)
2289 if (handle_call (&argc
,
2297 else if (g_strcmp0 (command
, "introspect") == 0)
2299 if (handle_introspect (&argc
,
2307 else if (g_strcmp0 (command
, "monitor") == 0)
2309 if (handle_monitor (&argc
,
2317 else if (g_strcmp0 (command
, "wait") == 0)
2319 if (handle_wait (&argc
,
2327 else if (g_strcmp0 (command
, "complete") == 0 && argc
== 4 && !request_completion
)
2329 const gchar
*completion_line
;
2330 gchar
**completion_argv
;
2331 gint completion_argc
;
2332 gint completion_point
;
2336 request_completion
= TRUE
;
2338 completion_line
= argv
[2];
2339 completion_point
= strtol (argv
[3], &endp
, 10);
2340 if (endp
== argv
[3] || *endp
!= '\0')
2344 completion_debug ("completion_point=%d", completion_point
);
2345 completion_debug ("----");
2346 completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
2347 completion_debug ("'%s'", completion_line
);
2348 completion_debug (" %*s^",
2349 completion_point
, "");
2350 completion_debug ("----");
2353 if (!g_shell_parse_argv (completion_line
,
2358 /* it's very possible the command line can't be parsed (for
2359 * example, missing quotes etc) - in that case, we just
2360 * don't autocomplete at all
2365 /* compute cur and prev */
2366 completion_prev
= NULL
;
2367 completion_cur
= pick_word_at (completion_line
, completion_point
, &cur_begin
);
2371 for (prev_end
= cur_begin
- 1; prev_end
>= 0; prev_end
--)
2373 if (!g_ascii_isspace (completion_line
[prev_end
]))
2375 completion_prev
= pick_word_at (completion_line
, prev_end
, NULL
);
2381 completion_debug (" cur='%s'", completion_cur
);
2382 completion_debug ("prev='%s'", completion_prev
);
2385 argc
= completion_argc
;
2386 argv
= completion_argv
;
2394 if (request_completion
)
2396 g_print ("help \nemit \ncall \nintrospect \nmonitor \nwait \n");
2402 g_printerr ("Unknown command '%s'\n", command
);
2403 usage (&argc
, &argv
, FALSE
);
2409 g_free (completion_cur
);
2410 g_free (completion_prev
);