diff options
Diffstat (limited to 'src/tools/list-sources')
-rw-r--r-- | src/tools/list-sources/CMakeLists.txt | 35 | ||||
-rw-r--r-- | src/tools/list-sources/list-sources.c | 448 |
2 files changed, 483 insertions, 0 deletions
diff --git a/src/tools/list-sources/CMakeLists.txt b/src/tools/list-sources/CMakeLists.txt new file mode 100644 index 000000000..a82824d9b --- /dev/null +++ b/src/tools/list-sources/CMakeLists.txt @@ -0,0 +1,35 @@ +set(DEPENDENCIES + edataserver +) + +set(SOURCES + list-sources.c +) + +add_executable(list-sources + ${SOURCES} +) + +add_dependencies(list-sources + ${DEPENDENCIES} +) + +target_compile_definitions(list-sources PRIVATE + -DG_LOG_DOMAIN=\"list-sources\" + -DLOCALEDIR=\"${LOCALE_INSTALL_DIR}\" +) + +target_include_directories(list-sources PUBLIC + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/src + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_CURRENT_BINARY_DIR} +) + +target_link_libraries(list-sources + ${DEPENDENCIES} +) + +install(TARGETS list-sources + DESTINATION ${privlibexecdir} +) diff --git a/src/tools/list-sources/list-sources.c b/src/tools/list-sources/list-sources.c new file mode 100644 index 000000000..5f784396a --- /dev/null +++ b/src/tools/list-sources/list-sources.c @@ -0,0 +1,448 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2017 Red Hat, Inc. (www.redhat.com) + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "evolution-data-server-config.h" + +#include <glib.h> +#include <glib/gi18n.h> + +#include <libedataserver/libedataserver.h> + +#define INDENT_LEVEL_SIZE 3 + +static void +print_with_indent (gint indent_level, + const gchar *format, + ...) +{ + va_list va; + gchar *str; + + g_return_if_fail (format != NULL); + + va_start (va, format); + str = g_strdup_vprintf (format, va); + va_end (va); + + g_print ("%*s%s\n", indent_level * INDENT_LEVEL_SIZE, "", str); + + g_free (str); +} + +static gint +compare_strings_safe (const gchar *str1, + const gchar *str2) +{ + if (str1 && str2) + return g_utf8_collate (str1, str2); + + return g_strcmp0 (str1, str2); +} + +static gint +sort_sources_cb (gconstpointer aa, + gconstpointer bb) +{ + ESource *a_source = (ESource *) aa; + ESource *b_source = (ESource *) bb; + gint res; + + res = compare_strings_safe (e_source_get_display_name (a_source), e_source_get_display_name (b_source)); + if (!res) + res = compare_strings_safe (e_source_get_uid (a_source), e_source_get_uid (b_source)); + + return res; +} + +/* Command-Line Options */ +static gboolean opt_only_enabled = FALSE; +static gboolean opt_show_uid = FALSE; +static gboolean opt_show_authentication = FALSE; +static gboolean opt_machine_readable = FALSE; +static gchar *opt_extension_name = NULL; + +static GOptionEntry entries[] = { + { "only-enabled", 'e', 0, + G_OPTION_ARG_NONE, &opt_only_enabled, + N_("Show only enabled sources") }, + { "show-uid", 'u', 0, + G_OPTION_ARG_NONE, &opt_show_uid, + N_("Show source's UID") }, + { "show-authentication", 'a', 0, + G_OPTION_ARG_NONE, &opt_show_authentication, + N_("Show source's authentication information") }, + { "machine-readable", 'm', 0, + G_OPTION_ARG_NONE, &opt_machine_readable, + N_("Write in machine readable format (one source per line, without localized property names and tab as separator)") }, + { "extension-name", 'x', 0, + G_OPTION_ARG_STRING, &opt_extension_name, + N_("Limit only to sources with given extension name"), + NULL }, + { NULL } +}; + +static const gchar * +boolean_to_string (gboolean value) +{ + if (opt_machine_readable) + return value ? "1" : "0"; + + return value ? _("yes") : _("no"); +} + +static void +examine_source (ESource *source, + const gchar **out_type, + const gchar **out_backend_name) +{ + gpointer extension = NULL; + + g_return_if_fail (E_IS_SOURCE (source)); + g_return_if_fail (out_type != NULL); + g_return_if_fail (out_backend_name != NULL); + + *out_type = ""; + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION)) { + if (opt_machine_readable) + *out_type = "Collection"; + else + *out_type = _("Collection"); + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_GOA)) { + if (opt_machine_readable) + *out_type = "Collection/GOA"; + else + *out_type = _("Collection/GNOME Online Accounts"); + } else if (e_source_has_extension (source, E_SOURCE_EXTENSION_UOA)) { + if (opt_machine_readable) + *out_type = "Collection/UOA"; + else + *out_type = _("Collection/Ubuntu Online Accounts"); + } + + extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION); + } else { + struct _extensions { + const gchar *extension_name; + const gchar *machine_description; + const gchar *localized_description; + } check_extensions[] = { + { E_SOURCE_EXTENSION_ADDRESS_BOOK, "AddressBook", N_("Address Book") }, + { E_SOURCE_EXTENSION_CALENDAR, "Calendar", N_("Calendar") }, + { E_SOURCE_EXTENSION_MEMO_LIST, "MemoList", N_("Memo List") }, + { E_SOURCE_EXTENSION_TASK_LIST, "TaskList", N_("Task List") }, + { E_SOURCE_EXTENSION_MAIL_ACCOUNT, "MailAccount", N_("Mail Account") }, + { E_SOURCE_EXTENSION_MAIL_TRANSPORT, "MailTransport", N_("Mail Transport") }, + { E_SOURCE_EXTENSION_MAIL_IDENTITY, "MailIdentity", N_("Mail Identity") }, + { E_SOURCE_EXTENSION_MAIL_SUBMISSION, "MailSubmission", N_("Mail Submission") }, + { E_SOURCE_EXTENSION_MAIL_SIGNATURE, "MailSignature", N_("Mail Signature") }, + { E_SOURCE_EXTENSION_PROXY, "Proxy", N_("Proxy") } + }; + gint ii; + + for (ii = 0; ii < G_N_ELEMENTS (check_extensions); ii++) { + if (e_source_has_extension (source, check_extensions[ii].extension_name)) { + if (opt_machine_readable) + *out_type = check_extensions[ii].machine_description; + else + *out_type = check_extensions[ii].localized_description; + + extension = e_source_get_extension (source, check_extensions[ii].extension_name); + break; + } + } + } + + if (extension && E_IS_SOURCE_BACKEND (extension)) + *out_backend_name = e_source_backend_get_backend_name (extension); + else + *out_backend_name = NULL; +} + +static void +dump_one_source (ESource *source, + gint indent_level) +{ + const gchar *type = NULL, *backend_name = NULL; + + g_return_if_fail (E_IS_SOURCE (source)); + + examine_source (source, &type, &backend_name); + + if (opt_machine_readable) { + g_print ("%*s%s\t%s", indent_level, "", type, e_source_get_display_name (source)); + if (opt_show_uid) { + const gchar *parent_uid; + + g_print ("\tUID:%s", e_source_get_uid (source)); + + parent_uid = e_source_get_parent (source); + if (parent_uid && *parent_uid) + g_print ("\tParentUID:%s", parent_uid); + } + if (!opt_only_enabled) + g_print ("\tEnabled:%s", boolean_to_string (e_source_get_enabled (source))); + if (backend_name) + g_print ("\tBackend:%s", backend_name); + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION)) { + ESourceCollection *collection = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION); + + g_print ("\tCalendarEnabled:%s", boolean_to_string (e_source_collection_get_calendar_enabled (collection))); + g_print ("\tContactsEnabled:%s", boolean_to_string (e_source_collection_get_contacts_enabled (collection))); + g_print ("\tMailEnabled:%s", boolean_to_string (e_source_collection_get_mail_enabled (collection))); + } + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE)) { + const gchar *mime_type = e_source_mail_signature_get_mime_type (e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE)); + + if (mime_type && *mime_type) + g_print ("\tMimeType:%s", mime_type); + } + } else { + print_with_indent (indent_level, "%s '%s'", type, e_source_get_display_name (source)); + if (opt_show_uid) { + const gchar *parent_uid; + + print_with_indent (indent_level + 1, _("UID: %s"), e_source_get_uid (source)); + + parent_uid = e_source_get_parent (source); + if (parent_uid && *parent_uid) + print_with_indent (indent_level + 1, _("Parent UID: %s"), e_source_get_uid (source)); + } + if (!opt_only_enabled) + print_with_indent (indent_level + 1, _("Enabled: %s"), boolean_to_string (e_source_get_enabled (source))); + if (backend_name) + print_with_indent (indent_level + 1, _("Backend: %s"), backend_name); + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION)) { + ESourceCollection *collection = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION); + + print_with_indent (indent_level + 1, _("Calendar enabled: %s"), boolean_to_string (e_source_collection_get_calendar_enabled (collection))); + print_with_indent (indent_level + 1, _("Contacts enabled: %s"), boolean_to_string (e_source_collection_get_contacts_enabled (collection))); + print_with_indent (indent_level + 1, _("Mail enabled: %s"), boolean_to_string (e_source_collection_get_mail_enabled (collection))); + } + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE)) { + const gchar *mime_type = e_source_mail_signature_get_mime_type (e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE)); + + if (mime_type && *mime_type) + print_with_indent (indent_level + 1, _("Mime Type: %s"), mime_type); + } + } + + if (opt_show_authentication && + e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION)) { + ESourceAuthentication *auth_extension; + const gchar *host, *user, *method, *proxy_uid; + guint16 port; + + auth_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION); + host = e_source_authentication_get_host (auth_extension); + port = e_source_authentication_get_port (auth_extension); + user = e_source_authentication_get_user (auth_extension); + method = e_source_authentication_get_method (auth_extension); + proxy_uid = e_source_authentication_get_proxy_uid (auth_extension); + + if (host && *host) { + if (port) { + if (opt_machine_readable) { + g_print ("\tAuthHost:%s:%d", host, port); + } else { + print_with_indent (indent_level + 1, _("Auth Host: %s:%d"), host, port); + } + } else { + if (opt_machine_readable) { + g_print ("\tAuthHost:%s", host); + } else { + print_with_indent (indent_level + 1, _("Auth Host: %s"), host); + } + } + + if (user && *user) { + if (opt_machine_readable) { + g_print ("\tAuthUser:%s", user); + } else { + print_with_indent (indent_level + 1, _("Auth User: %s"), user); + } + } + + if (method && *method) { + if (opt_machine_readable) { + g_print ("\tAuthMethod:%s", method); + } else { + print_with_indent (indent_level + 1, _("Auth Method: %s"), method); + } + } + + if (proxy_uid && *proxy_uid) { + if (opt_machine_readable) { + g_print ("\tAuthProxyUID:%s", proxy_uid); + } else { + print_with_indent (indent_level + 1, _("Auth Proxy UID: %s"), proxy_uid); + } + } + } + } + + if (opt_machine_readable) + g_print ("\n"); +} + +static void +dump_children (const GSList *in_child_sources, + GHashTable *children, + gint indent_level) +{ + GSList *child_sources, *link; + + if (!in_child_sources) + return; + + child_sources = g_slist_sort (g_slist_copy ((GSList *) in_child_sources), sort_sources_cb); + + for (link = child_sources; link; link = g_slist_next (link)) { + ESource *source = link->data; + + if (link != child_sources && !opt_machine_readable && !indent_level) + g_print ("\n"); + + dump_one_source (source, indent_level); + dump_children (g_hash_table_lookup (children, e_source_get_uid (source)), children, indent_level + 2); + + g_hash_table_remove (children, e_source_get_uid (source)); + } + + g_slist_free (child_sources); +} + +static void +dump_sources (GList *sources) +{ + GHashTable *children; /* gchar * (parent-uid) ~> GSList { ESource * } */ + GList *llink; + GSList *top_sources = NULL, *slink; + + children = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); + + for (llink = sources; llink; llink = g_list_next (llink)) { + ESource *source = llink->data; + const gchar *parent_uid; + + if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE) && + g_strcmp0 (opt_extension_name, E_SOURCE_EXTENSION_MAIL_SIGNATURE) != 0) + continue; + + parent_uid = e_source_get_parent (source); + if (!parent_uid || !*parent_uid) { + top_sources = g_slist_prepend (top_sources, source); + } else { + g_hash_table_insert (children, g_strdup (parent_uid), g_slist_prepend ( + g_slist_copy (g_hash_table_lookup (children, parent_uid)), source)); + } + } + + top_sources = g_slist_sort (top_sources, sort_sources_cb); + + for (slink = top_sources; slink; slink = g_slist_next (slink)) { + ESource *source = slink->data; + + if (slink != top_sources && !opt_machine_readable) + g_print ("\n"); + + dump_one_source (source, 0); + dump_children (g_hash_table_lookup (children, e_source_get_uid (source)), children, 2); + + g_hash_table_remove (children, e_source_get_uid (source)); + } + + g_slist_free (top_sources); + top_sources = NULL; + + if (g_hash_table_size (children)) { + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, children); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + top_sources = g_slist_concat (top_sources, g_slist_copy (value)); + } + + g_hash_table_remove_all (children); + + dump_children (top_sources, children, 0); + + g_slist_free (top_sources); + } + + g_hash_table_destroy (children); +} + +gint +main (gint argc, + gchar **argv) +{ + GOptionContext *context; + ESourceRegistry *registry; + GList *sources; + GError *error = NULL; + +#ifdef G_OS_WIN32 + e_util_win32_initialize (); +#endif + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_option_context_free (context); + g_printerr ("%s\n", error ? error->message : _("Failed to parse arguments: Unknown error")); + g_clear_error (&error); + return 1; + } + + g_option_context_free (context); + + registry = e_source_registry_new_sync (NULL, &error); + if (error || !registry) { + g_printerr (_("Failed to connect to source registry: %s\n"), error ? error->message : _("Unknown error")); + g_clear_error (&error); + return 2; + } + + if (opt_extension_name && !*opt_extension_name) + opt_extension_name = NULL; + + if (opt_only_enabled) + sources = e_source_registry_list_enabled (registry, opt_extension_name); + else + sources = e_source_registry_list_sources (registry, opt_extension_name); + + if (sources) + dump_sources (sources); + else if (!opt_machine_readable) + g_print (_("No sources had been found\n")); + + g_list_free_full (sources, g_object_unref); + g_object_unref (registry); + + return 0; +} |