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 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"
102 "Use “%s COMMAND --help” to get help on each command.\n"),
104 g_free (program_name
);
105 g_option_context_set_description (o
, s
);
107 s
= g_option_context_get_help (o
, FALSE
, NULL
);
111 g_printerr ("%s", s
);
113 g_option_context_free (o
);
117 modify_argv0_for_command (gint
*argc
, gchar
**argv
[], const gchar
*command
)
123 * 1. get a g_set_prgname() ?; or
124 * 2. save old argv[0] and restore later
127 g_assert (g_strcmp0 ((*argv
)[1], command
) == 0);
128 remove_arg (1, argc
, argv
);
130 program_name
= g_path_get_basename ((*argv
)[0]);
131 s
= g_strdup_printf ("%s %s", (*argv
)[0], command
);
133 g_free (program_name
);
136 /* ---------------------------------------------------------------------------------------------------- */
139 print_methods (GDBusConnection
*c
,
145 const gchar
*xml_data
;
151 result
= g_dbus_connection_call_sync (c
,
154 "org.freedesktop.DBus.Introspectable",
157 G_VARIANT_TYPE ("(s)"),
158 G_DBUS_CALL_FLAGS_NONE
,
164 g_printerr (_("Error: %s\n"), error
->message
);
165 g_error_free (error
);
168 g_variant_get (result
, "(&s)", &xml_data
);
171 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
172 g_variant_unref (result
);
175 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
176 g_error_free (error
);
180 for (n
= 0; node
->interfaces
!= NULL
&& node
->interfaces
[n
] != NULL
; n
++)
182 const GDBusInterfaceInfo
*iface
= node
->interfaces
[n
];
183 for (m
= 0; iface
->methods
!= NULL
&& iface
->methods
[m
] != NULL
; m
++)
185 const GDBusMethodInfo
*method
= iface
->methods
[m
];
186 g_print ("%s.%s \n", iface
->name
, method
->name
);
189 g_dbus_node_info_unref (node
);
196 print_paths (GDBusConnection
*c
,
202 const gchar
*xml_data
;
206 if (!g_dbus_is_name (name
))
208 g_printerr (_("Error: %s is not a valid name\n"), name
);
213 result
= g_dbus_connection_call_sync (c
,
216 "org.freedesktop.DBus.Introspectable",
219 G_VARIANT_TYPE ("(s)"),
220 G_DBUS_CALL_FLAGS_NONE
,
226 g_printerr (_("Error: %s\n"), error
->message
);
227 g_error_free (error
);
230 g_variant_get (result
, "(&s)", &xml_data
);
232 //g_printerr ("xml='%s'", xml_data);
235 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
236 g_variant_unref (result
);
239 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
240 g_error_free (error
);
244 //g_printerr ("bar '%s'\n", path);
246 if (node
->interfaces
!= NULL
)
247 g_print ("%s \n", path
);
249 for (n
= 0; node
->nodes
!= NULL
&& node
->nodes
[n
] != NULL
; n
++)
253 //g_printerr ("foo '%s'\n", node->nodes[n].path);
255 if (g_strcmp0 (path
, "/") == 0)
256 s
= g_strdup_printf ("/%s", node
->nodes
[n
]->path
);
258 s
= g_strdup_printf ("%s/%s", path
, node
->nodes
[n
]->path
);
260 print_paths (c
, name
, s
);
264 g_dbus_node_info_unref (node
);
271 print_names (GDBusConnection
*c
,
272 gboolean include_unique_names
)
278 GHashTable
*name_set
;
282 name_set
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
285 result
= g_dbus_connection_call_sync (c
,
286 "org.freedesktop.DBus",
287 "/org/freedesktop/DBus",
288 "org.freedesktop.DBus",
291 G_VARIANT_TYPE ("(as)"),
292 G_DBUS_CALL_FLAGS_NONE
,
298 g_printerr (_("Error: %s\n"), error
->message
);
299 g_error_free (error
);
302 g_variant_get (result
, "(as)", &iter
);
303 while (g_variant_iter_loop (iter
, "s", &str
))
304 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
305 g_variant_iter_free (iter
);
306 g_variant_unref (result
);
309 result
= g_dbus_connection_call_sync (c
,
310 "org.freedesktop.DBus",
311 "/org/freedesktop/DBus",
312 "org.freedesktop.DBus",
313 "ListActivatableNames",
315 G_VARIANT_TYPE ("(as)"),
316 G_DBUS_CALL_FLAGS_NONE
,
322 g_printerr (_("Error: %s\n"), error
->message
);
323 g_error_free (error
);
326 g_variant_get (result
, "(as)", &iter
);
327 while (g_variant_iter_loop (iter
, "s", &str
))
328 g_hash_table_insert (name_set
, g_strdup (str
), NULL
);
329 g_variant_iter_free (iter
);
330 g_variant_unref (result
);
332 keys
= g_hash_table_get_keys (name_set
);
333 keys
= g_list_sort (keys
, (GCompareFunc
) g_strcmp0
);
334 for (l
= keys
; l
!= NULL
; l
= l
->next
)
336 const gchar
*name
= l
->data
;
337 if (!include_unique_names
&& g_str_has_prefix (name
, ":"))
340 g_print ("%s \n", name
);
345 g_hash_table_unref (name_set
);
348 /* ---------------------------------------------------------------------------------------------------- */
350 static gboolean opt_connection_system
= FALSE
;
351 static gboolean opt_connection_session
= FALSE
;
352 static gchar
*opt_connection_address
= NULL
;
354 static const GOptionEntry connection_entries
[] =
356 { "system", 'y', 0, G_OPTION_ARG_NONE
, &opt_connection_system
, N_("Connect to the system bus"), NULL
},
357 { "session", 'e', 0, G_OPTION_ARG_NONE
, &opt_connection_session
, N_("Connect to the session bus"), NULL
},
358 { "address", 'a', 0, G_OPTION_ARG_STRING
, &opt_connection_address
, N_("Connect to given D-Bus address"), NULL
},
362 static GOptionGroup
*
363 connection_get_group (void)
365 static GOptionGroup
*g
;
367 g
= g_option_group_new ("connection",
368 N_("Connection Endpoint Options:"),
369 N_("Options specifying the connection endpoint"),
372 g_option_group_set_translation_domain (g
, GETTEXT_PACKAGE
);
373 g_option_group_add_entries (g
, connection_entries
);
378 static GDBusConnection
*
379 connection_get_dbus_connection (GError
**error
)
385 /* First, ensure we have exactly one connect */
386 if (!opt_connection_system
&& !opt_connection_session
&& opt_connection_address
== NULL
)
391 _("No connection endpoint specified"));
394 else if ((opt_connection_system
&& (opt_connection_session
|| opt_connection_address
!= NULL
)) ||
395 (opt_connection_session
&& (opt_connection_system
|| opt_connection_address
!= NULL
)) ||
396 (opt_connection_address
!= NULL
&& (opt_connection_system
|| opt_connection_session
)))
401 _("Multiple connection endpoints specified"));
405 if (opt_connection_system
)
407 c
= g_bus_get_sync (G_BUS_TYPE_SYSTEM
, NULL
, error
);
409 else if (opt_connection_session
)
411 c
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, error
);
413 else if (opt_connection_address
!= NULL
)
415 c
= g_dbus_connection_new_for_address_sync (opt_connection_address
,
416 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
,
417 NULL
, /* GDBusAuthObserver */
418 NULL
, /* GCancellable */
426 /* ---------------------------------------------------------------------------------------------------- */
429 call_helper_get_method_in_signature (GDBusConnection
*c
,
432 const gchar
*interface_name
,
433 const gchar
*method_name
,
438 GDBusNodeInfo
*node_info
;
439 const gchar
*xml_data
;
440 GDBusInterfaceInfo
*interface_info
;
441 GDBusMethodInfo
*method_info
;
448 result
= g_dbus_connection_call_sync (c
,
451 "org.freedesktop.DBus.Introspectable",
454 G_VARIANT_TYPE ("(s)"),
455 G_DBUS_CALL_FLAGS_NONE
,
462 g_variant_get (result
, "(&s)", &xml_data
);
463 node_info
= g_dbus_node_info_new_for_xml (xml_data
, error
);
464 if (node_info
== NULL
)
467 interface_info
= g_dbus_node_info_lookup_interface (node_info
, interface_name
);
468 if (interface_info
== NULL
)
470 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
471 _("Warning: According to introspection data, interface “%s” does not exist\n"),
476 method_info
= g_dbus_interface_info_lookup_method (interface_info
, method_name
);
477 if (method_info
== NULL
)
479 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
480 _("Warning: According to introspection data, method “%s” does not exist on interface “%s”\n"),
486 ret
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_variant_type_free
);
487 for (n
= 0; method_info
->in_args
!= NULL
&& method_info
->in_args
[n
] != NULL
; n
++)
489 g_ptr_array_add (ret
, g_variant_type_new (method_info
->in_args
[n
]->signature
));
493 if (node_info
!= NULL
)
494 g_dbus_node_info_unref (node_info
);
496 g_variant_unref (result
);
501 /* ---------------------------------------------------------------------------------------------------- */
504 _g_variant_parse_me_harder (GVariantType
*type
,
505 const gchar
*given_str
,
513 str
= g_string_new ("\"");
514 for (n
= 0; given_str
[n
] != '\0'; n
++)
516 if (G_UNLIKELY (given_str
[n
] == '\"'))
517 g_string_append (str
, "\\\"");
519 g_string_append_c (str
, given_str
[n
]);
521 g_string_append_c (str
, '"');
522 s
= g_string_free (str
, FALSE
);
524 value
= g_variant_parse (type
,
534 /* ---------------------------------------------------------------------------------------------------- */
536 static gchar
*opt_emit_dest
= NULL
;
537 static gchar
*opt_emit_object_path
= NULL
;
538 static gchar
*opt_emit_signal
= NULL
;
540 static const GOptionEntry emit_entries
[] =
542 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_emit_dest
, N_("Optional destination for signal (unique name)"), NULL
},
543 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_emit_object_path
, N_("Object path to emit signal on"), NULL
},
544 { "signal", 's', 0, G_OPTION_ARG_STRING
, &opt_emit_signal
, N_("Signal and interface name"), NULL
},
549 handle_emit (gint
*argc
,
551 gboolean request_completion
,
552 const gchar
*completion_cur
,
553 const gchar
*completion_prev
)
560 GVariant
*parameters
;
561 gchar
*interface_name
;
563 GVariantBuilder builder
;
564 gboolean skip_dashes
;
571 interface_name
= NULL
;
574 modify_argv0_for_command (argc
, argv
, "emit");
576 o
= g_option_context_new (NULL
);
577 g_option_context_set_help_enabled (o
, FALSE
);
578 g_option_context_set_summary (o
, _("Emit a signal."));
579 g_option_context_add_main_entries (o
, emit_entries
, GETTEXT_PACKAGE
);
580 g_option_context_add_group (o
, connection_get_group ());
582 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
584 if (!request_completion
)
586 s
= g_option_context_get_help (o
, FALSE
, NULL
);
587 g_printerr ("%s", s
);
594 c
= connection_get_dbus_connection (&error
);
597 if (request_completion
)
599 if (g_strcmp0 (completion_prev
, "--address") == 0)
607 g_print ("--system \n--session \n--address \n");
612 g_printerr (_("Error connecting: %s\n"), error
->message
);
613 g_error_free (error
);
618 /* All done with completion now */
619 if (request_completion
)
622 if (opt_emit_object_path
== NULL
)
624 g_printerr (_("Error: object path not specified.\n"));
627 if (!g_variant_is_object_path (opt_emit_object_path
))
629 g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path
);
633 if (opt_emit_signal
== NULL
)
635 g_printerr (_("Error: signal not specified.\n"));
639 s
= strrchr (opt_emit_signal
, '.');
642 g_printerr (_("Error: signal must be the fully-qualified name.\n"));
645 signal_name
= g_strdup (s
+ 1);
646 interface_name
= g_strndup (opt_emit_signal
, s
- opt_emit_signal
);
648 if (!g_dbus_is_interface_name (interface_name
))
650 g_printerr (_("Error: %s is not a valid interface name\n"), interface_name
);
654 if (!g_dbus_is_member_name (signal_name
))
656 g_printerr (_("Error: %s is not a valid member name\n"), signal_name
);
660 if (opt_emit_dest
!= NULL
&& !g_dbus_is_unique_name (opt_emit_dest
))
662 g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest
);
666 /* Read parameters */
667 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
670 for (n
= 1; n
< (guint
) *argc
; n
++)
674 /* Under certain conditions, g_option_context_parse returns the "--"
675 itself (setting off unparsed arguments), too: */
676 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
683 value
= g_variant_parse (NULL
,
692 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
693 g_error_free (error
);
695 value
= _g_variant_parse_me_harder (NULL
, (*argv
)[n
], &error
);
698 /* Use the original non-"parse-me-harder" error */
699 g_printerr (_("Error parsing parameter %d: %s\n"),
702 g_error_free (error
);
704 g_variant_builder_clear (&builder
);
709 g_variant_builder_add_value (&builder
, value
);
712 parameters
= g_variant_builder_end (&builder
);
714 if (parameters
!= NULL
)
715 parameters
= g_variant_ref_sink (parameters
);
716 if (!g_dbus_connection_emit_signal (c
,
718 opt_emit_object_path
,
724 g_printerr (_("Error: %s\n"), error
->message
);
725 g_error_free (error
);
729 if (!g_dbus_connection_flush_sync (c
, NULL
, &error
))
731 g_printerr (_("Error flushing connection: %s\n"), error
->message
);
732 g_error_free (error
);
741 if (parameters
!= NULL
)
742 g_variant_unref (parameters
);
743 g_free (interface_name
);
744 g_free (signal_name
);
745 g_option_context_free (o
);
749 /* ---------------------------------------------------------------------------------------------------- */
751 static gchar
*opt_call_dest
= NULL
;
752 static gchar
*opt_call_object_path
= NULL
;
753 static gchar
*opt_call_method
= NULL
;
754 static gint opt_call_timeout
= -1;
756 static const GOptionEntry call_entries
[] =
758 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_call_dest
, N_("Destination name to invoke method on"), NULL
},
759 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_call_object_path
, N_("Object path to invoke method on"), NULL
},
760 { "method", 'm', 0, G_OPTION_ARG_STRING
, &opt_call_method
, N_("Method and interface name"), NULL
},
761 { "timeout", 't', 0, G_OPTION_ARG_INT
, &opt_call_timeout
, N_("Timeout in seconds"), NULL
},
766 handle_call (gint
*argc
,
768 gboolean request_completion
,
769 const gchar
*completion_cur
,
770 const gchar
*completion_prev
)
777 GVariant
*parameters
;
778 gchar
*interface_name
;
781 GPtrArray
*in_signature_types
;
782 gboolean complete_names
;
783 gboolean complete_paths
;
784 gboolean complete_methods
;
785 GVariantBuilder builder
;
786 gboolean skip_dashes
;
793 interface_name
= NULL
;
796 in_signature_types
= NULL
;
798 modify_argv0_for_command (argc
, argv
, "call");
800 o
= g_option_context_new (NULL
);
801 g_option_context_set_help_enabled (o
, FALSE
);
802 g_option_context_set_summary (o
, _("Invoke a method on a remote object."));
803 g_option_context_add_main_entries (o
, call_entries
, GETTEXT_PACKAGE
);
804 g_option_context_add_group (o
, connection_get_group ());
806 complete_names
= FALSE
;
807 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
809 complete_names
= TRUE
;
810 remove_arg ((*argc
) - 1, argc
, argv
);
813 complete_paths
= FALSE
;
814 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
816 complete_paths
= TRUE
;
817 remove_arg ((*argc
) - 1, argc
, argv
);
820 complete_methods
= FALSE
;
821 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--method") == 0)
823 complete_methods
= TRUE
;
824 remove_arg ((*argc
) - 1, argc
, argv
);
827 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
829 if (!request_completion
)
831 s
= g_option_context_get_help (o
, FALSE
, NULL
);
832 g_printerr ("%s", s
);
839 c
= connection_get_dbus_connection (&error
);
842 if (request_completion
)
844 if (g_strcmp0 (completion_prev
, "--address") == 0)
852 g_print ("--system \n--session \n--address \n");
857 g_printerr (_("Error connecting: %s\n"), error
->message
);
858 g_error_free (error
);
863 /* validate and complete destination (bus name) */
864 if (g_dbus_connection_get_unique_name (c
) != NULL
)
866 /* this only makes sense on message bus connections */
869 print_names (c
, FALSE
);
872 if (opt_call_dest
== NULL
)
874 if (request_completion
)
875 g_print ("--dest \n");
877 g_printerr (_("Error: Destination is not specified\n"));
880 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
882 print_names (c
, g_str_has_prefix (opt_call_dest
, ":"));
887 if (!request_completion
&& !g_dbus_is_name (opt_call_dest
))
889 g_printerr (_("Error: %s is not a valid bus name\n"), opt_call_dest
);
893 /* validate and complete object path */
896 print_paths (c
, opt_call_dest
, "/");
899 if (opt_call_object_path
== NULL
)
901 if (request_completion
)
902 g_print ("--object-path \n");
904 g_printerr (_("Error: Object path is not specified\n"));
907 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
910 s
= g_strdup (opt_call_object_path
);
911 p
= strrchr (s
, '/');
918 print_paths (c
, opt_call_dest
, s
);
922 if (!request_completion
&& !g_variant_is_object_path (opt_call_object_path
))
924 g_printerr (_("Error: %s is not a valid object path\n"), opt_call_object_path
);
928 /* validate and complete method (interface + method name) */
929 if (complete_methods
)
931 print_methods (c
, opt_call_dest
, opt_call_object_path
);
934 if (opt_call_method
== NULL
)
936 if (request_completion
)
937 g_print ("--method \n");
939 g_printerr (_("Error: Method name is not specified\n"));
942 if (request_completion
&& g_strcmp0 ("--method", completion_prev
) == 0)
944 print_methods (c
, opt_call_dest
, opt_call_object_path
);
947 s
= strrchr (opt_call_method
, '.');
948 if (!request_completion
&& s
== NULL
)
950 g_printerr (_("Error: Method name “%s” is invalid\n"), opt_call_method
);
953 method_name
= g_strdup (s
+ 1);
954 interface_name
= g_strndup (opt_call_method
, s
- opt_call_method
);
956 /* All done with completion now */
957 if (request_completion
)
960 /* Introspect, for easy conversion - it's not fatal if we can't do this */
961 in_signature_types
= call_helper_get_method_in_signature (c
,
963 opt_call_object_path
,
967 if (in_signature_types
== NULL
)
969 //g_printerr ("Error getting introspection data: %s\n", error->message);
970 g_error_free (error
);
974 /* Read parameters */
975 g_variant_builder_init (&builder
, G_VARIANT_TYPE_TUPLE
);
978 for (n
= 1; n
< (guint
) *argc
; n
++)
983 /* Under certain conditions, g_option_context_parse returns the "--"
984 itself (setting off unparsed arguments), too: */
985 if (skip_dashes
&& g_strcmp0 ((*argv
)[n
], "--") == 0)
992 if (in_signature_types
!= NULL
)
994 if (parm
>= in_signature_types
->len
)
996 /* Only warn for the first param */
997 if (parm
== in_signature_types
->len
)
999 g_printerr ("Warning: Introspection data indicates %d parameters but more was passed\n",
1000 in_signature_types
->len
);
1005 type
= in_signature_types
->pdata
[parm
];
1010 value
= g_variant_parse (type
,
1019 context
= g_variant_parse_error_print_context (error
, (*argv
)[n
]);
1020 g_error_free (error
);
1022 value
= _g_variant_parse_me_harder (type
, (*argv
)[n
], &error
);
1027 s
= g_variant_type_dup_string (type
);
1028 g_printerr (_("Error parsing parameter %d of type “%s”: %s\n"),
1036 g_printerr (_("Error parsing parameter %d: %s\n"),
1040 g_error_free (error
);
1041 g_variant_builder_clear (&builder
);
1047 g_variant_builder_add_value (&builder
, value
);
1050 parameters
= g_variant_builder_end (&builder
);
1052 if (parameters
!= NULL
)
1053 parameters
= g_variant_ref_sink (parameters
);
1054 result
= g_dbus_connection_call_sync (c
,
1056 opt_call_object_path
,
1061 G_DBUS_CALL_FLAGS_NONE
,
1062 opt_call_timeout
> 0 ? opt_call_timeout
* 1000 : opt_call_timeout
,
1067 g_printerr (_("Error: %s\n"), error
->message
);
1069 if (g_error_matches (error
, G_DBUS_ERROR
, G_DBUS_ERROR_INVALID_ARGS
) && in_signature_types
!= NULL
)
1071 if (in_signature_types
->len
> 0)
1074 s
= g_string_new (NULL
);
1076 for (n
= 0; n
< in_signature_types
->len
; n
++)
1078 GVariantType
*type
= in_signature_types
->pdata
[n
];
1079 g_string_append_len (s
,
1080 g_variant_type_peek_string (type
),
1081 g_variant_type_get_string_length (type
));
1084 g_printerr ("(According to introspection data, you need to pass '%s')\n", s
->str
);
1085 g_string_free (s
, TRUE
);
1088 g_printerr ("(According to introspection data, you need to pass no arguments)\n");
1091 g_error_free (error
);
1095 s
= g_variant_print (result
, TRUE
);
1096 g_print ("%s\n", s
);
1102 if (in_signature_types
!= NULL
)
1103 g_ptr_array_unref (in_signature_types
);
1105 g_variant_unref (result
);
1108 if (parameters
!= NULL
)
1109 g_variant_unref (parameters
);
1110 g_free (interface_name
);
1111 g_free (method_name
);
1112 g_option_context_free (o
);
1116 /* ---------------------------------------------------------------------------------------------------- */
1118 static gchar
*opt_introspect_dest
= NULL
;
1119 static gchar
*opt_introspect_object_path
= NULL
;
1120 static gboolean opt_introspect_xml
= FALSE
;
1121 static gboolean opt_introspect_recurse
= FALSE
;
1122 static gboolean opt_introspect_only_properties
= FALSE
;
1125 dump_annotation (const GDBusAnnotationInfo
*o
,
1127 gboolean ignore_indent
)
1130 g_print ("%*s@%s(\"%s\")\n",
1131 ignore_indent
? 0 : indent
, "",
1134 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1135 dump_annotation (o
->annotations
[n
], indent
+ 2, FALSE
);
1139 dump_arg (const GDBusArgInfo
*o
,
1141 const gchar
*direction
,
1142 gboolean ignore_indent
,
1143 gboolean include_newline
)
1147 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1149 dump_annotation (o
->annotations
[n
], indent
, ignore_indent
);
1150 ignore_indent
= FALSE
;
1153 g_print ("%*s%s%s %s%s",
1154 ignore_indent
? 0 : indent
, "",
1158 include_newline
? ",\n" : "");
1162 count_args (GDBusArgInfo
**args
)
1168 while (args
[n
] != NULL
)
1175 dump_method (const GDBusMethodInfo
*o
,
1181 guint total_num_args
;
1183 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1184 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1186 g_print ("%*s%s(", indent
, "", o
->name
);
1187 name_len
= strlen (o
->name
);
1188 total_num_args
= count_args (o
->in_args
) + count_args (o
->out_args
);
1189 for (n
= 0, m
= 0; o
->in_args
!= NULL
&& o
->in_args
[n
] != NULL
; n
++, m
++)
1191 gboolean ignore_indent
= (m
== 0);
1192 gboolean include_newline
= (m
!= total_num_args
- 1);
1194 dump_arg (o
->in_args
[n
],
1195 indent
+ name_len
+ 1,
1200 for (n
= 0; o
->out_args
!= NULL
&& o
->out_args
[n
] != NULL
; n
++, m
++)
1202 gboolean ignore_indent
= (m
== 0);
1203 gboolean include_newline
= (m
!= total_num_args
- 1);
1204 dump_arg (o
->out_args
[n
],
1205 indent
+ name_len
+ 1,
1214 dump_signal (const GDBusSignalInfo
*o
,
1219 guint total_num_args
;
1221 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1222 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1224 g_print ("%*s%s(", indent
, "", o
->name
);
1225 name_len
= strlen (o
->name
);
1226 total_num_args
= count_args (o
->args
);
1227 for (n
= 0; o
->args
!= NULL
&& o
->args
[n
] != NULL
; n
++)
1229 gboolean ignore_indent
= (n
== 0);
1230 gboolean include_newline
= (n
!= total_num_args
- 1);
1231 dump_arg (o
->args
[n
],
1232 indent
+ name_len
+ 1,
1241 dump_property (const GDBusPropertyInfo
*o
,
1245 const gchar
*access
;
1248 if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_READABLE
)
1249 access
= "readonly";
1250 else if (o
->flags
== G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
)
1251 access
= "writeonly";
1252 else if (o
->flags
== (G_DBUS_PROPERTY_INFO_FLAGS_READABLE
| G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE
))
1253 access
= "readwrite";
1255 g_assert_not_reached ();
1257 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1258 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1262 gchar
*s
= g_variant_print (value
, FALSE
);
1263 g_print ("%*s%s %s %s = %s;\n", indent
, "", access
, o
->signature
, o
->name
, s
);
1268 g_print ("%*s%s %s %s;\n", indent
, "", access
, o
->signature
, o
->name
);
1273 dump_interface (GDBusConnection
*c
,
1275 const GDBusInterfaceInfo
*o
,
1277 const gchar
*object_path
)
1280 GHashTable
*properties
;
1282 properties
= g_hash_table_new_full (g_str_hash
,
1285 (GDestroyNotify
) g_variant_unref
);
1287 /* Try to get properties */
1288 if (c
!= NULL
&& name
!= NULL
&& object_path
!= NULL
&& o
->properties
!= NULL
)
1291 result
= g_dbus_connection_call_sync (c
,
1294 "org.freedesktop.DBus.Properties",
1296 g_variant_new ("(s)", o
->name
),
1298 G_DBUS_CALL_FLAGS_NONE
,
1304 if (g_variant_is_of_type (result
, G_VARIANT_TYPE ("(a{sv})")))
1308 g_variant_get (result
,
1311 while ((item
= g_variant_iter_next_value (iter
)))
1315 g_variant_get (item
,
1320 g_hash_table_insert (properties
, key
, g_variant_ref (value
));
1323 g_variant_unref (result
);
1328 for (n
= 0; o
->properties
!= NULL
&& o
->properties
[n
] != NULL
; n
++)
1330 result
= g_dbus_connection_call_sync (c
,
1333 "org.freedesktop.DBus.Properties",
1335 g_variant_new ("(ss)", o
->name
, o
->properties
[n
]->name
),
1336 G_VARIANT_TYPE ("(v)"),
1337 G_DBUS_CALL_FLAGS_NONE
,
1343 GVariant
*property_value
;
1344 g_variant_get (result
,
1347 g_hash_table_insert (properties
,
1348 g_strdup (o
->properties
[n
]->name
),
1349 g_variant_ref (property_value
));
1350 g_variant_unref (result
);
1356 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1357 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1359 g_print ("%*sinterface %s {\n", indent
, "", o
->name
);
1360 if (o
->methods
!= NULL
&& !opt_introspect_only_properties
)
1362 g_print ("%*s methods:\n", indent
, "");
1363 for (n
= 0; o
->methods
[n
] != NULL
; n
++)
1364 dump_method (o
->methods
[n
], indent
+ 4);
1366 if (o
->signals
!= NULL
&& !opt_introspect_only_properties
)
1368 g_print ("%*s signals:\n", indent
, "");
1369 for (n
= 0; o
->signals
[n
] != NULL
; n
++)
1370 dump_signal (o
->signals
[n
], indent
+ 4);
1372 if (o
->properties
!= NULL
)
1374 g_print ("%*s properties:\n", indent
, "");
1375 for (n
= 0; o
->properties
[n
] != NULL
; n
++)
1377 dump_property (o
->properties
[n
],
1379 g_hash_table_lookup (properties
, (o
->properties
[n
])->name
));
1385 g_hash_table_unref (properties
);
1389 introspect_do (GDBusConnection
*c
,
1390 const gchar
*object_path
,
1394 dump_node (GDBusConnection
*c
,
1396 const GDBusNodeInfo
*o
,
1398 const gchar
*object_path
,
1402 const gchar
*object_path_to_print
;
1404 object_path_to_print
= object_path
;
1405 if (o
->path
!= NULL
)
1406 object_path_to_print
= o
->path
;
1408 for (n
= 0; o
->annotations
!= NULL
&& o
->annotations
[n
] != NULL
; n
++)
1409 dump_annotation (o
->annotations
[n
], indent
, FALSE
);
1411 g_print ("%*snode %s", indent
, "", object_path_to_print
!= NULL
? object_path_to_print
: "(not set)");
1412 if (o
->interfaces
!= NULL
|| o
->nodes
!= NULL
)
1415 for (n
= 0; o
->interfaces
!= NULL
&& o
->interfaces
[n
] != NULL
; n
++)
1417 if (opt_introspect_only_properties
)
1419 if (o
->interfaces
[n
]->properties
!= NULL
&& o
->interfaces
[n
]->properties
[0] != NULL
)
1420 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1424 dump_interface (c
, name
, o
->interfaces
[n
], indent
+ 2, object_path
);
1427 for (n
= 0; o
->nodes
!= NULL
&& o
->nodes
[n
] != NULL
; n
++)
1432 if (g_variant_is_object_path (o
->nodes
[n
]->path
))
1434 child_path
= g_strdup (o
->nodes
[n
]->path
);
1435 /* avoid infinite loops */
1436 if (g_str_has_prefix (child_path
, object_path
))
1438 introspect_do (c
, child_path
, indent
+ 2);
1442 g_print ("Skipping path %s that is not enclosed by parent %s\n",
1443 child_path
, object_path
);
1448 if (g_strcmp0 (object_path
, "/") == 0)
1449 child_path
= g_strdup_printf ("/%s", o
->nodes
[n
]->path
);
1451 child_path
= g_strdup_printf ("%s/%s", object_path
, o
->nodes
[n
]->path
);
1452 introspect_do (c
, child_path
, indent
+ 2);
1454 g_free (child_path
);
1458 dump_node (NULL
, NULL
, o
->nodes
[n
], indent
+ 2, NULL
, recurse
);
1470 static const GOptionEntry introspect_entries
[] =
1472 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_introspect_dest
, N_("Destination name to introspect"), NULL
},
1473 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_introspect_object_path
, N_("Object path to introspect"), NULL
},
1474 { "xml", 'x', 0, G_OPTION_ARG_NONE
, &opt_introspect_xml
, N_("Print XML"), NULL
},
1475 { "recurse", 'r', 0, G_OPTION_ARG_NONE
, &opt_introspect_recurse
, N_("Introspect children"), NULL
},
1476 { "only-properties", 'p', 0, G_OPTION_ARG_NONE
, &opt_introspect_only_properties
, N_("Only print properties"), NULL
},
1481 introspect_do (GDBusConnection
*c
,
1482 const gchar
*object_path
,
1487 GDBusNodeInfo
*node
;
1489 const gchar
*xml_data
;
1496 result
= g_dbus_connection_call_sync (c
,
1497 opt_introspect_dest
,
1499 "org.freedesktop.DBus.Introspectable",
1502 G_VARIANT_TYPE ("(s)"),
1503 G_DBUS_CALL_FLAGS_NONE
,
1509 g_printerr (_("Error: %s\n"), error
->message
);
1510 g_error_free (error
);
1513 g_variant_get (result
, "(&s)", &xml_data
);
1515 if (opt_introspect_xml
)
1517 g_print ("%s", xml_data
);
1522 node
= g_dbus_node_info_new_for_xml (xml_data
, &error
);
1525 g_printerr (_("Error parsing introspection XML: %s\n"), error
->message
);
1526 g_error_free (error
);
1530 dump_node (c
, opt_introspect_dest
, node
, indent
, object_path
, opt_introspect_recurse
);
1537 g_dbus_node_info_unref (node
);
1539 g_variant_unref (result
);
1544 handle_introspect (gint
*argc
,
1546 gboolean request_completion
,
1547 const gchar
*completion_cur
,
1548 const gchar
*completion_prev
)
1555 gboolean complete_names
;
1556 gboolean complete_paths
;
1561 modify_argv0_for_command (argc
, argv
, "introspect");
1563 o
= g_option_context_new (NULL
);
1564 if (request_completion
)
1565 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1566 g_option_context_set_help_enabled (o
, FALSE
);
1567 g_option_context_set_summary (o
, _("Introspect a remote object."));
1568 g_option_context_add_main_entries (o
, introspect_entries
, GETTEXT_PACKAGE
);
1569 g_option_context_add_group (o
, connection_get_group ());
1571 complete_names
= FALSE
;
1572 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1574 complete_names
= TRUE
;
1575 remove_arg ((*argc
) - 1, argc
, argv
);
1578 complete_paths
= FALSE
;
1579 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1581 complete_paths
= TRUE
;
1582 remove_arg ((*argc
) - 1, argc
, argv
);
1585 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1587 if (!request_completion
)
1589 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1590 g_printerr ("%s", s
);
1597 c
= connection_get_dbus_connection (&error
);
1600 if (request_completion
)
1602 if (g_strcmp0 (completion_prev
, "--address") == 0)
1610 g_print ("--system \n--session \n--address \n");
1615 g_printerr (_("Error connecting: %s\n"), error
->message
);
1616 g_error_free (error
);
1621 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1625 print_names (c
, FALSE
);
1628 /* this only makes sense on message bus connections */
1629 if (opt_introspect_dest
== NULL
)
1631 if (request_completion
)
1632 g_print ("--dest \n");
1634 g_printerr (_("Error: Destination is not specified\n"));
1637 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1639 print_names (c
, g_str_has_prefix (opt_introspect_dest
, ":"));
1645 print_paths (c
, opt_introspect_dest
, "/");
1649 if (!request_completion
&& !g_dbus_is_name (opt_introspect_dest
))
1651 g_printerr (_("Error: %s is not a valid bus name\n"), opt_introspect_dest
);
1655 if (opt_introspect_object_path
== NULL
)
1657 if (request_completion
)
1658 g_print ("--object-path \n");
1660 g_printerr (_("Error: Object path is not specified\n"));
1663 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1666 s
= g_strdup (opt_introspect_object_path
);
1667 p
= strrchr (s
, '/');
1674 print_paths (c
, opt_introspect_dest
, s
);
1678 if (!request_completion
&& !g_variant_is_object_path (opt_introspect_object_path
))
1680 g_printerr (_("Error: %s is not a valid object path\n"), opt_introspect_object_path
);
1684 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_recurse
)
1686 g_print ("--recurse \n");
1689 if (request_completion
&& opt_introspect_object_path
!= NULL
&& !opt_introspect_only_properties
)
1691 g_print ("--only-properties \n");
1694 /* All done with completion now */
1695 if (request_completion
)
1698 if (!introspect_do (c
, opt_introspect_object_path
, 0))
1706 g_option_context_free (o
);
1710 /* ---------------------------------------------------------------------------------------------------- */
1712 static gchar
*opt_monitor_dest
= NULL
;
1713 static gchar
*opt_monitor_object_path
= NULL
;
1715 static guint monitor_filter_id
= 0;
1718 monitor_signal_cb (GDBusConnection
*connection
,
1719 const gchar
*sender_name
,
1720 const gchar
*object_path
,
1721 const gchar
*interface_name
,
1722 const gchar
*signal_name
,
1723 GVariant
*parameters
,
1727 s
= g_variant_print (parameters
, TRUE
);
1728 g_print ("%s: %s.%s %s\n",
1737 monitor_on_name_appeared (GDBusConnection
*connection
,
1739 const gchar
*name_owner
,
1742 g_print ("The name %s is owned by %s\n", name
, name_owner
);
1743 g_assert (monitor_filter_id
== 0);
1744 monitor_filter_id
= g_dbus_connection_signal_subscribe (connection
,
1746 NULL
, /* any interface */
1747 NULL
, /* any member */
1748 opt_monitor_object_path
,
1750 G_DBUS_SIGNAL_FLAGS_NONE
,
1752 NULL
, /* user_data */
1753 NULL
); /* user_data destroy notify */
1757 monitor_on_name_vanished (GDBusConnection
*connection
,
1761 g_print ("The name %s does not have an owner\n", name
);
1763 if (monitor_filter_id
!= 0)
1765 g_dbus_connection_signal_unsubscribe (connection
, monitor_filter_id
);
1766 monitor_filter_id
= 0;
1770 static const GOptionEntry monitor_entries
[] =
1772 { "dest", 'd', 0, G_OPTION_ARG_STRING
, &opt_monitor_dest
, N_("Destination name to monitor"), NULL
},
1773 { "object-path", 'o', 0, G_OPTION_ARG_STRING
, &opt_monitor_object_path
, N_("Object path to monitor"), NULL
},
1778 handle_monitor (gint
*argc
,
1780 gboolean request_completion
,
1781 const gchar
*completion_cur
,
1782 const gchar
*completion_prev
)
1789 gboolean complete_names
;
1790 gboolean complete_paths
;
1796 modify_argv0_for_command (argc
, argv
, "monitor");
1798 o
= g_option_context_new (NULL
);
1799 if (request_completion
)
1800 g_option_context_set_ignore_unknown_options (o
, TRUE
);
1801 g_option_context_set_help_enabled (o
, FALSE
);
1802 g_option_context_set_summary (o
, _("Monitor a remote object."));
1803 g_option_context_add_main_entries (o
, monitor_entries
, GETTEXT_PACKAGE
);
1804 g_option_context_add_group (o
, connection_get_group ());
1806 complete_names
= FALSE
;
1807 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--dest") == 0)
1809 complete_names
= TRUE
;
1810 remove_arg ((*argc
) - 1, argc
, argv
);
1813 complete_paths
= FALSE
;
1814 if (request_completion
&& *argc
> 1 && g_strcmp0 ((*argv
)[(*argc
)-1], "--object-path") == 0)
1816 complete_paths
= TRUE
;
1817 remove_arg ((*argc
) - 1, argc
, argv
);
1820 if (!g_option_context_parse (o
, argc
, argv
, NULL
))
1822 if (!request_completion
)
1824 s
= g_option_context_get_help (o
, FALSE
, NULL
);
1825 g_printerr ("%s", s
);
1832 c
= connection_get_dbus_connection (&error
);
1835 if (request_completion
)
1837 if (g_strcmp0 (completion_prev
, "--address") == 0)
1845 g_print ("--system \n--session \n--address \n");
1850 g_printerr (_("Error connecting: %s\n"), error
->message
);
1851 g_error_free (error
);
1856 if (g_dbus_connection_get_unique_name (c
) != NULL
)
1860 print_names (c
, FALSE
);
1863 /* this only makes sense on message bus connections */
1864 if (opt_monitor_dest
== NULL
)
1866 if (request_completion
)
1867 g_print ("--dest \n");
1869 g_printerr (_("Error: Destination is not specified\n"));
1872 if (request_completion
&& g_strcmp0 ("--dest", completion_prev
) == 0)
1874 print_names (c
, g_str_has_prefix (opt_monitor_dest
, ":"));
1879 if (!request_completion
&& !g_dbus_is_name (opt_monitor_dest
))
1881 g_printerr (_("Error: %s is not a valid bus name\n"), opt_monitor_dest
);
1887 print_paths (c
, opt_monitor_dest
, "/");
1890 if (opt_monitor_object_path
== NULL
)
1892 if (request_completion
)
1894 g_print ("--object-path \n");
1897 /* it's fine to not have an object path */
1899 if (request_completion
&& g_strcmp0 ("--object-path", completion_prev
) == 0)
1902 s
= g_strdup (opt_monitor_object_path
);
1903 p
= strrchr (s
, '/');
1910 print_paths (c
, opt_monitor_dest
, s
);
1914 if (!request_completion
&& (opt_monitor_object_path
!= NULL
&& !g_variant_is_object_path (opt_monitor_object_path
)))
1916 g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path
);
1920 /* All done with completion now */
1921 if (request_completion
)
1924 if (opt_monitor_object_path
!= NULL
)
1925 g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path
, opt_monitor_dest
);
1927 g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest
);
1929 loop
= g_main_loop_new (NULL
, FALSE
);
1930 g_bus_watch_name_on_connection (c
,
1932 G_BUS_NAME_WATCHER_FLAGS_AUTO_START
,
1933 monitor_on_name_appeared
,
1934 monitor_on_name_vanished
,
1938 g_main_loop_run (loop
);
1939 g_main_loop_unref (loop
);
1946 g_option_context_free (o
);
1950 /* ---------------------------------------------------------------------------------------------------- */
1953 pick_word_at (const gchar
*s
,
1955 gint
*out_word_begins_at
)
1962 if (out_word_begins_at
!= NULL
)
1963 *out_word_begins_at
= -1;
1967 if (g_ascii_isspace (s
[cursor
]) && ((cursor
> 0 && g_ascii_isspace(s
[cursor
-1])) || cursor
== 0))
1969 if (out_word_begins_at
!= NULL
)
1970 *out_word_begins_at
= cursor
;
1971 return g_strdup ("");
1974 while (!g_ascii_isspace (s
[cursor
- 1]) && cursor
> 0)
1979 while (!g_ascii_isspace (s
[end
]) && s
[end
] != '\0')
1982 if (out_word_begins_at
!= NULL
)
1983 *out_word_begins_at
= begin
;
1985 return g_strndup (s
+ begin
, end
- begin
);
1989 main (gint argc
, gchar
*argv
[])
1992 const gchar
*command
;
1993 gboolean request_completion
;
1994 gchar
*completion_cur
;
1995 gchar
*completion_prev
;
2000 setlocale (LC_ALL
, "");
2001 textdomain (GETTEXT_PACKAGE
);
2004 tmp
= _glib_get_locale_dir ();
2005 bindtextdomain (GETTEXT_PACKAGE
, tmp
);
2008 bindtextdomain (GETTEXT_PACKAGE
, GLIB_LOCALE_DIR
);
2011 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2012 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
2016 completion_cur
= NULL
;
2017 completion_prev
= NULL
;
2021 usage (&argc
, &argv
, FALSE
);
2025 request_completion
= FALSE
;
2027 //completion_debug ("---- argc=%d --------------------------------------------------------", argc);
2031 if (g_strcmp0 (command
, "help") == 0)
2033 if (request_completion
)
2039 usage (&argc
, &argv
, TRUE
);
2044 else if (g_strcmp0 (command
, "emit") == 0)
2046 if (handle_emit (&argc
,
2054 else if (g_strcmp0 (command
, "call") == 0)
2056 if (handle_call (&argc
,
2064 else if (g_strcmp0 (command
, "introspect") == 0)
2066 if (handle_introspect (&argc
,
2074 else if (g_strcmp0 (command
, "monitor") == 0)
2076 if (handle_monitor (&argc
,
2084 else if (g_strcmp0 (command
, "complete") == 0 && argc
== 4 && !request_completion
)
2086 const gchar
*completion_line
;
2087 gchar
**completion_argv
;
2088 gint completion_argc
;
2089 gint completion_point
;
2093 request_completion
= TRUE
;
2095 completion_line
= argv
[2];
2096 completion_point
= strtol (argv
[3], &endp
, 10);
2097 if (endp
== argv
[3] || *endp
!= '\0')
2101 completion_debug ("completion_point=%d", completion_point
);
2102 completion_debug ("----");
2103 completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
2104 completion_debug ("'%s'", completion_line
);
2105 completion_debug (" %*s^",
2106 completion_point
, "");
2107 completion_debug ("----");
2110 if (!g_shell_parse_argv (completion_line
,
2115 /* it's very possible the command line can't be parsed (for
2116 * example, missing quotes etc) - in that case, we just
2117 * don't autocomplete at all
2122 /* compute cur and prev */
2123 completion_prev
= NULL
;
2124 completion_cur
= pick_word_at (completion_line
, completion_point
, &cur_begin
);
2128 for (prev_end
= cur_begin
- 1; prev_end
>= 0; prev_end
--)
2130 if (!g_ascii_isspace (completion_line
[prev_end
]))
2132 completion_prev
= pick_word_at (completion_line
, prev_end
, NULL
);
2138 completion_debug (" cur='%s'", completion_cur
);
2139 completion_debug ("prev='%s'", completion_prev
);
2142 argc
= completion_argc
;
2143 argv
= completion_argv
;
2151 if (request_completion
)
2153 g_print ("help \nemit \ncall \nintrospect \nmonitor \n");
2159 g_printerr ("Unknown command '%s'\n", command
);
2160 usage (&argc
, &argv
, FALSE
);
2166 g_free (completion_cur
);
2167 g_free (completion_prev
);