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_OPENED);
22
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_OPENING);
23
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_ONLINE);
24
prop_names = g_slist_append (prop_names, (gpointer) CLIENT_BACKEND_PROPERTY_READONLY);
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, gpointer prop_value, gpointer user_data)
52
g_return_if_fail (prop_name != NULL);
54
if (prop_value == NULL) {
55
g_print ("\t %s: NULL\n", (const gchar *) prop_name);
59
g_print ("\t %s: ", (const gchar *) prop_name);
61
if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
62
GSList *values = e_client_util_parse_comma_strings (prop_value), *v;
64
for (v = values; v; v = v->next) {
68
g_print ("'%s'", (const gchar *) v->data);
71
e_client_util_free_string_slist (values);
73
g_print ("'%s'", (const gchar *) prop_value);
80
print_values (const ExtraValues *evals, EClient *client)
84
g_return_if_fail (evals != NULL);
86
g_print ("\treadonly:%s\n", e_client_is_readonly (client) ? "yes" : "no");
87
g_print ("\tonline:%s\n", e_client_is_online (client) ? "yes" : "no");
88
g_print ("\topened:%s\n", e_client_is_opened (client) ? "yes" : "no");
89
g_print ("\tcapabilities: ");
90
values = e_client_get_capabilities (client);
95
const gchar *cap = values->data;
97
g_print ("'%s'", cap);
98
if (!e_client_check_capability (client, cap))
99
g_print (" (not found in EClient)");
101
values = values->next;
109
g_print ("\tbackend properties:\n");
110
g_hash_table_foreach (evals->retrieved_props, print_each_property, NULL);
114
identify_source (ESource *source)
116
const gchar *name, *uri;
117
gchar *abs_uri = NULL;
119
g_return_if_fail (source != NULL);
121
name = e_source_peek_name (source);
123
name = "Unknown name";
125
uri = e_source_peek_absolute_uri (source);
127
abs_uri = e_source_build_absolute_uri (source);
131
uri = e_source_peek_relative_uri (source);
135
g_print ("\n Checking source '%s' (%s)\n", name, uri);
140
static void client_opened_async (GObject *source_object, GAsyncResult *result, gpointer async_data);
143
continue_next_source (gpointer async_data)
145
ESource *source = NULL;
147
g_return_if_fail (async_data != NULL);
149
while (async_data && foreach_configured_source_async_next (&async_data, &source)) {
150
identify_source (source);
151
e_client_utils_open_new (source, source_type, TRUE,
152
e_client_utils_authenticate_handler, NULL,
153
NULL, client_opened_async, async_data);
159
if (!running_async) {
160
while (source_type++, source_type < E_CLIENT_SOURCE_TYPE_LAST) {
161
if (foreach_async ())
171
client_got_backend_property_async (GObject *source_object, GAsyncResult *result, gpointer user_data)
173
ExtraValues *evals = user_data;
174
gchar *prop_value = NULL;
175
GError *error = NULL;
178
g_return_if_fail (source_object != NULL);
179
g_return_if_fail (E_IS_CLIENT (source_object));
180
g_return_if_fail (evals != NULL);
182
client = E_CLIENT (source_object);
184
if (!e_client_get_backend_property_finish (client, result, &prop_value, &error)) {
185
report_error ("get backend property finish", &error);
188
g_hash_table_insert (evals->retrieved_props, evals->todo_prop_names->data, prop_value);
189
evals->todo_prop_names = g_slist_remove (evals->todo_prop_names, evals->todo_prop_names->data);
191
if (!evals->todo_prop_names) {
192
/* to cache them, as it can be fetched with idle as well */
193
e_client_get_capabilities (client);
195
print_values (evals, client);
197
g_object_unref (source_object);
199
continue_next_source (evals->async_data);
200
extra_values_free (evals);
202
e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
207
client_set_backend_property_async (GObject *source_object, GAsyncResult *result, gpointer user_data)
209
ExtraValues *evals = user_data;
210
GError *error = NULL;
213
g_return_if_fail (source_object != NULL);
214
g_return_if_fail (E_IS_CLIENT (source_object));
215
g_return_if_fail (evals != NULL);
217
client = E_CLIENT (source_object);
219
if (!e_client_set_backend_property_finish (client, result, &error)) {
220
/* it may fail on the set_backend_property */
221
g_clear_error (&error);
223
g_printerr (" Might fail on set_backend_property, but reported success\n");
226
e_client_get_backend_property (client, evals->todo_prop_names->data, NULL, client_got_backend_property_async, evals);
230
client_opened_async (GObject *source_object, GAsyncResult *result, gpointer async_data)
233
GError *error = NULL;
234
EClient *client = NULL;
236
g_return_if_fail (source_object == NULL);
237
g_return_if_fail (async_data != NULL);
239
if (!e_client_utils_open_new_finish (result, &client, &error)) {
240
report_error ("client utils open new finish", &error);
241
continue_next_source (async_data);
245
evals = g_new0 (ExtraValues, 1);
246
evals->async_data = async_data;
247
evals->todo_prop_names = get_known_prop_names ();
248
evals->retrieved_props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
250
e_client_set_backend_property (client, "*unknown*property*", "*value*", NULL, client_set_backend_property_async, evals);
257
ESource *source = NULL;
259
async_data = foreach_configured_source_async_start (&source);
267
identify_source (source);
268
e_client_utils_open_new (source, source_type, TRUE,
269
e_client_utils_authenticate_handler, NULL,
270
NULL, client_opened_async, async_data);
276
in_main_thread_idle_cb (gpointer unused)
278
if (!foreach_async ())
284
static GMainLoop *loop = NULL;
285
static gint main_stop_result = 0;
288
stop_main_loop (gint stop_result)
290
g_return_if_fail (loop != NULL);
292
main_stop_result = stop_result;
293
g_main_loop_quit (loop);
297
get_main_loop_stop_result (void)
299
return main_stop_result;
302
struct ForeachConfiguredData
304
ESourceList *source_list;
305
GSList *current_group;
306
GSList *current_source;
310
foreach_configured_source_async_start (ESource **source)
312
struct ForeachConfiguredData *async_data;
313
ESourceList *source_list = NULL;
314
GError *error = NULL;
316
g_return_val_if_fail (source != NULL, NULL);
318
if (!e_client_utils_get_sources (&source_list, source_type, &error)) {
319
report_error ("get sources", &error);
323
g_return_val_if_fail (source_list != NULL, NULL);
325
async_data = g_new0 (struct ForeachConfiguredData, 1);
326
async_data->source_list = source_list;
327
async_data->current_group = e_source_list_peek_groups (source_list);
328
if (!async_data->current_group) {
329
gpointer ad = async_data;
331
foreach_configured_source_async_next (&ad, source);
335
async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
336
if (!async_data->current_source) {
337
gpointer ad = async_data;
339
if (foreach_configured_source_async_next (&ad, source))
345
*source = async_data->current_source->data;
351
foreach_configured_source_async_next (gpointer *foreach_async_data, ESource **source)
353
struct ForeachConfiguredData *async_data;
355
g_return_val_if_fail (foreach_async_data != NULL, FALSE);
356
g_return_val_if_fail (source != NULL, FALSE);
358
async_data = *foreach_async_data;
359
g_return_val_if_fail (async_data != NULL, FALSE);
360
g_return_val_if_fail (async_data->source_list != NULL, FALSE);
361
g_return_val_if_fail (async_data->current_group != NULL, FALSE);
363
if (async_data->current_source)
364
async_data->current_source = async_data->current_source->next;
365
if (async_data->current_source) {
366
*source = async_data->current_source->data;
371
async_data->current_group = async_data->current_group->next;
372
if (async_data->current_group)
373
async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
374
} while (async_data->current_group && !async_data->current_source);
376
if (async_data->current_source) {
377
*source = async_data->current_source->data;
381
g_object_unref (async_data->source_list);
384
*foreach_async_data = NULL;
390
report_error (const gchar *operation, GError **error)
392
g_return_if_fail (operation != NULL);
394
g_printerr ("Failed to %s: %s\n", operation, (error && *error) ? (*error)->message : "Unknown error");
396
g_clear_error (error);
400
main (gint argc, gchar **argv)
403
g_thread_init (NULL);
404
gtk_init (&argc, &argv);
408
g_idle_add (in_main_thread_idle_cb, NULL);
410
loop = g_main_loop_new (NULL, FALSE);
411
g_main_loop_run (loop);
412
g_main_loop_unref (loop);
414
return get_main_loop_stop_result ();