1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 #include <libedataserver/e-source-group.h>
4 #include <libedataserverui/e-client-utils.h>
5 #include <libedataserverui/e-passwords.h>
7 static void stop_main_loop (gint stop_result);
8 static void report_error (const gchar *operation, GError **error);
9 static gpointer foreach_configured_source_async_start (ESource **source);
10 static gboolean foreach_configured_source_async_next (gpointer *foreach_async_data, ESource **source);
11 static gboolean foreach_async (void);
13 static gint running_async = 0;
14 static EClientSourceType source_type = E_CLIENT_SOURCE_TYPE_CONTACTS;
17 get_known_prop_names (void)
19 GSList *prop_names = NULL;
21 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_READONLY);
22 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_ONLINE);
23 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENED);
24 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENING);
25 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CACHE_DIR);
26 prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_CAPABILITIES);
31 typedef struct _ExtraValues {
34 GSList *todo_prop_names;
35 GHashTable *retrieved_props;
39 extra_values_free (ExtraValues *evals)
44 g_slist_free (evals->todo_prop_names);
45 g_hash_table_destroy (evals->retrieved_props);
50 print_each_property (gpointer prop_name,
54 g_return_if_fail (prop_name != NULL);
56 if (prop_value == NULL) {
57 g_print ("\t %s: NULL\n", (const gchar *) prop_name);
61 g_print ("\t %s: ", (const gchar *) prop_name);
63 if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
64 GSList *values = e_client_util_parse_comma_strings (prop_value), *v;
66 for (v = values; v; v = v->next) {
70 g_print ("'%s'", (const gchar *) v->data);
73 e_client_util_free_string_slist (values);
75 g_print ("'%s'", (const gchar *) prop_value);
82 print_values (const ExtraValues *evals,
87 g_return_if_fail (evals != NULL);
89 g_print ("\treadonly:%s\n", e_client_is_readonly (client) ? "yes" : "no");
90 g_print ("\tonline:%s\n", e_client_is_online (client) ? "yes" : "no");
91 g_print ("\topened:%s\n", e_client_is_opened (client) ? "yes" : "no");
92 g_print ("\tcapabilities: ");
93 values = e_client_get_capabilities (client);
98 const gchar *cap = values->data;
100 g_print ("'%s'", cap);
101 if (!e_client_check_capability (client, cap))
102 g_print (" (not found in EClient)");
104 values = values->next;
112 g_print ("\tbackend properties:\n");
113 g_hash_table_foreach (evals->retrieved_props, print_each_property, NULL);
117 identify_source (ESource *source)
119 const gchar *name, *uri;
120 gchar *abs_uri = NULL;
122 g_return_if_fail (source != NULL);
124 name = e_source_peek_name (source);
126 name = "Unknown name";
128 uri = e_source_peek_absolute_uri (source);
130 abs_uri = e_source_build_absolute_uri (source);
134 uri = e_source_peek_relative_uri (source);
138 g_print ("\n Checking source '%s' (%s)\n", name, uri);
143 static void client_opened_async (GObject *source_object, GAsyncResult *result, gpointer async_data);
146 continue_next_source (gpointer async_data)
148 ESource *source = NULL;
150 g_return_if_fail (async_data != NULL);
152 while (async_data && foreach_configured_source_async_next (&async_data, &source)) {
153 identify_source (source);
154 e_client_utils_open_new (source, source_type, TRUE, NULL,
155 e_client_utils_authenticate_handler, NULL,
156 client_opened_async, async_data);
162 if (!running_async) {
163 while (source_type++, source_type < E_CLIENT_SOURCE_TYPE_LAST) {
164 if (foreach_async ())
174 client_got_backend_property_async (GObject *source_object,
175 GAsyncResult *result,
178 ExtraValues *evals = user_data;
179 gchar *prop_value = NULL;
180 GError *error = NULL;
183 g_return_if_fail (source_object != NULL);
184 g_return_if_fail (E_IS_CLIENT (source_object));
185 g_return_if_fail (evals != NULL);
187 client = E_CLIENT (source_object);
189 if (!e_client_get_backend_property_finish (client, result, &prop_value, &error)) {
190 report_error ("get backend property finish", &error);
193 g_hash_table_insert (evals->retrieved_props, evals->todo_prop_names->data, prop_value);
194 evals->todo_prop_names = g_slist_remove (evals->todo_prop_names, evals->todo_prop_names->data);
196 if (!evals->todo_prop_names) {
197 /* to cache them, as it can be fetched with idle as well */
198 e_client_get_capabilities (client);
200 print_values (evals, client);
202 g_object_unref (source_object);
204 continue_next_source (evals->async_data);
205 extra_values_free (evals);
207 e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
212 client_set_backend_property_async (GObject *source_object,
213 GAsyncResult *result,
216 ExtraValues *evals = user_data;
217 GError *error = NULL;
220 g_return_if_fail (source_object != NULL);
221 g_return_if_fail (E_IS_CLIENT (source_object));
222 g_return_if_fail (evals != NULL);
224 client = E_CLIENT (source_object);
226 if (!e_client_set_backend_property_finish (client, result, &error)) {
227 /* it may fail on the set_backend_property */
228 g_clear_error (&error);
230 g_printerr (" Might fail on set_backend_property, but reported success\n");
233 e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
237 client_opened_async (GObject *source_object,
238 GAsyncResult *result,
242 GError *error = NULL;
243 EClient *client = NULL;
245 g_return_if_fail (source_object != NULL);
246 g_return_if_fail (E_IS_SOURCE (source_object));
247 g_return_if_fail (async_data != NULL);
249 if (!e_client_utils_open_new_finish (E_SOURCE (source_object), result, &client, &error)) {
250 report_error ("client utils open new finish", &error);
251 continue_next_source (async_data);
255 evals = g_new0 (ExtraValues, 1);
256 evals->async_data = async_data;
257 evals->todo_prop_names = get_known_prop_names ();
258 evals->retrieved_props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
260 e_client_set_backend_property (client, "*unknown*property*", "*value*", NULL, client_set_backend_property_async, evals);
267 ESource *source = NULL;
269 async_data = foreach_configured_source_async_start (&source);
277 identify_source (source);
278 e_client_utils_open_new (source, source_type, TRUE, NULL,
279 e_client_utils_authenticate_handler, NULL,
280 client_opened_async, async_data);
286 in_main_thread_idle_cb (gpointer unused)
288 if (!foreach_async ())
294 static GMainLoop *loop = NULL;
295 static gint main_stop_result = 0;
298 stop_main_loop (gint stop_result)
300 g_return_if_fail (loop != NULL);
302 main_stop_result = stop_result;
303 g_main_loop_quit (loop);
307 get_main_loop_stop_result (void)
309 return main_stop_result;
312 struct ForeachConfiguredData
314 ESourceList *source_list;
315 GSList *current_group;
316 GSList *current_source;
320 foreach_configured_source_async_start (ESource **source)
322 struct ForeachConfiguredData *async_data;
323 ESourceList *source_list = NULL;
324 GError *error = NULL;
326 g_return_val_if_fail (source != NULL, NULL);
328 if (!e_client_utils_get_sources (&source_list, source_type, &error)) {
329 report_error ("get sources", &error);
333 g_return_val_if_fail (source_list != NULL, NULL);
335 async_data = g_new0 (struct ForeachConfiguredData, 1);
336 async_data->source_list = source_list;
337 async_data->current_group = e_source_list_peek_groups (source_list);
338 if (!async_data->current_group) {
339 gpointer ad = async_data;
341 foreach_configured_source_async_next (&ad, source);
345 async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
346 if (!async_data->current_source) {
347 gpointer ad = async_data;
349 if (foreach_configured_source_async_next (&ad, source))
355 *source = async_data->current_source->data;
361 foreach_configured_source_async_next (gpointer *foreach_async_data,
364 struct ForeachConfiguredData *async_data;
366 g_return_val_if_fail (foreach_async_data != NULL, FALSE);
367 g_return_val_if_fail (source != NULL, FALSE);
369 async_data = *foreach_async_data;
370 g_return_val_if_fail (async_data != NULL, FALSE);
371 g_return_val_if_fail (async_data->source_list != NULL, FALSE);
372 g_return_val_if_fail (async_data->current_group != NULL, FALSE);
374 if (async_data->current_source)
375 async_data->current_source = async_data->current_source->next;
376 if (async_data->current_source) {
377 *source = async_data->current_source->data;
382 async_data->current_group = async_data->current_group->next;
383 if (async_data->current_group)
384 async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
385 } while (async_data->current_group && !async_data->current_source);
387 if (async_data->current_source) {
388 *source = async_data->current_source->data;
392 g_object_unref (async_data->source_list);
395 *foreach_async_data = NULL;
401 report_error (const gchar *operation,
404 g_return_if_fail (operation != NULL);
406 g_printerr ("Failed to %s: %s\n", operation, (error && *error) ? (*error)->message : "Unknown error");
408 g_clear_error (error);
416 #if !GLIB_CHECK_VERSION(2,31,0)
417 g_thread_init (NULL);
419 gtk_init (&argc, &argv);
423 g_idle_add (in_main_thread_idle_cb, NULL);
425 loop = g_main_loop_new (NULL, FALSE);
426 g_main_loop_run (loop);
427 g_main_loop_unref (loop);
429 return get_main_loop_stop_result ();