#include "prefs_account.h"
#include "prefs_common.h"
#include "manage_window.h"
-#include "base64.h"
#include "manual.h"
#include "combobox.h"
void gtkut_ctree_expand_parent_all(GtkCMCTree *ctree, GtkCMCTreeNode *node)
{
+ gtk_cmclist_freeze(GTK_CMCLIST(ctree));
+
while ((node = gtkut_ctree_find_collapsed_parent(ctree, node)) != NULL)
gtk_cmctree_expand(ctree, node);
+
+ gtk_cmclist_thaw(GTK_CMCLIST(ctree));
}
gboolean gtkut_ctree_node_is_parent(GtkCMCTreeNode *parent, GtkCMCTreeNode *node)
wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
if (error != NULL) {
- g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s\n",
+ g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s",
error->message);
g_error_free(error);
}
wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
if (error != NULL) {
- g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s\n",
+ g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s",
error->message);
g_error_free(error);
}
clist = gtk_cmclist_new(1);
g_object_ref(G_OBJECT(clist));
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink (G_OBJECT(clist));
-#else
- gtk_object_ref (G_OBJECT(clist));
- gtk_object_sink (G_OBJECT(clist));
-#endif
gtkut_clist_bindings_add(clist);
g_object_unref(G_OBJECT(clist));
clist = gtk_cmctree_new(1, 0);
g_object_ref(G_OBJECT(clist));
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink (G_OBJECT(clist));
-#else
- gtk_object_ref (G_OBJECT(clist));
- gtk_object_sink (G_OBJECT(clist));
-#endif
gtkut_clist_bindings_add(clist);
g_object_unref(G_OBJECT(clist));
clist = gtk_sctree_new_with_titles(1, 0, NULL);
g_object_ref(G_OBJECT(clist));
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink (G_OBJECT(clist));
-#else
- gtk_object_ref (G_OBJECT(clist));
- gtk_object_sink (G_OBJECT(clist));
-#endif
gtkut_clist_bindings_add(clist);
g_object_unref(G_OBJECT(clist));
}
static gchar *xpm_xface[XPM_XFACE_HEIGHT];
static gboolean xpm_xface_init = TRUE;
gchar xface[2048];
- strncpy(xface, o_xface, sizeof(xface));
+ strncpy(xface, o_xface, sizeof(xface) - 1);
+ xface[sizeof(xface) - 1] = '\0';
if (uncompface(xface) < 0) {
- g_warning("uncompface failed\n");
+ g_warning("uncompface failed");
return NULL;
}
GtkWidget *face_get_from_header(const gchar *o_face)
{
gchar face[2048];
- gchar face_png[2048];
- gint pngsize;
+ gchar *face_png;
+ gsize pngsize;
GdkPixbuf *pixbuf;
GError *error = NULL;
GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
unfold_line(face); /* strip all whitespace and linebreaks */
remove_space(face);
- pngsize = base64_decode(face_png, face, strlen(face));
+ face_png = g_base64_decode(face, &pngsize);
+ debug_print("---------------------- loaded face png\n");
if (!gdk_pixbuf_loader_write (loader, face_png, pngsize, &error) ||
!gdk_pixbuf_loader_close (loader, &error)) {
- g_warning("loading face failed\n");
+ g_warning("loading face failed");
g_object_unref(loader);
+ g_free(face_png);
return NULL;
}
+ g_free(face_png);
pixbuf = g_object_ref(gdk_pixbuf_loader_get_pixbuf(loader));
if ((gdk_pixbuf_get_width(pixbuf) != 48) || (gdk_pixbuf_get_height(pixbuf) != 48)) {
g_object_unref(pixbuf);
- g_warning("wrong_size\n");
+ g_warning("wrong_size");
return NULL;
}
gtk_widget_set_style(btn_label, style);
#if !GTK_CHECK_VERSION(3, 0, 0)
} else
- g_warning("color allocation failed\n");
+ g_warning("color allocation failed");
#endif
g_signal_connect(G_OBJECT(btn), "enter",
if( txt == NULL )
return TRUE;
+
+ g_free(txt);
return FALSE;
}
for (row = 0; row < n_rows; row++) {
GtkTreeIter itern;
- gtk_tree_model_iter_nth_child(model, &itern, NULL, row);
- if (gtkut_tree_iter_comp(model, &iter, &itern))
+ if (gtk_tree_model_iter_nth_child(model, &itern, NULL, row)
+ && gtkut_tree_iter_comp(model, &iter, &itern))
return row;
}
return pixbuf;
}
+
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+static void auto_configure_done(const gchar *hostname, gint port, gboolean ssl, AutoConfigureData *data)
+{
+ if (hostname != NULL) {
+ if (data->hostname_entry)
+ gtk_entry_set_text(data->hostname_entry, hostname);
+ if (data->set_port)
+ gtk_toggle_button_set_active(data->set_port,
+ (ssl && port != data->default_ssl_port) || (!ssl && port != data->default_port));
+ if (data->port)
+ gtk_spin_button_set_value(data->port, port);
+ else if (data->hostname_entry) {
+ if ((ssl && port != data->default_ssl_port) || (!ssl && port != data->default_port)) {
+ gchar *tmp = g_strdup_printf("%s:%d", hostname, port);
+ gtk_entry_set_text(data->hostname_entry, tmp);
+ g_free(tmp);
+ } else
+ gtk_entry_set_text(data->hostname_entry, hostname);
+ }
+
+ if (ssl && data->ssl_checkbtn) {
+ gtk_toggle_button_set_active(data->ssl_checkbtn, TRUE);
+ gtk_toggle_button_set_active(data->tls_checkbtn, FALSE);
+ } else if (data->tls_checkbtn) {
+ if (!GTK_IS_RADIO_BUTTON(data->ssl_checkbtn)) {
+ /* Wizard where TLS is [x]SSL + [x]TLS */
+ gtk_toggle_button_set_active(data->ssl_checkbtn, TRUE);
+ }
+ gtk_toggle_button_set_active(data->tls_checkbtn, TRUE);
+ }
+
+ /* Check authentication by default. This is probably required if
+ * auto-configuration worked.
+ */
+ if (data->auth_checkbtn)
+ gtk_toggle_button_set_active(data->auth_checkbtn, TRUE);
+
+ /* Set user ID to full email address, which is used by the
+ * majority of providers where auto-configuration works.
+ */
+ if (data->uid_entry)
+ gtk_entry_set_text(data->uid_entry, data->address);
+
+ gtk_label_set_text(data->info_label, _("Done."));
+ } else {
+ gchar *msg;
+ switch (data->resolver_error) {
+ case G_RESOLVER_ERROR_NOT_FOUND:
+ msg = g_strdup(_("Failed: no service record found."));
+ break;
+ case G_RESOLVER_ERROR_TEMPORARY_FAILURE:
+ msg = g_strdup(_("Failed: network error."));
+ break;
+ default:
+ msg = g_strdup_printf(_("Failed: unknown error (%d)."), data->resolver_error);
+ }
+ gtk_label_set_text(data->info_label, msg);
+ g_free(msg);
+ }
+ gtk_widget_show(GTK_WIDGET(data->configure_button));
+ gtk_widget_hide(GTK_WIDGET(data->cancel_button));
+ g_free(data->address);
+ g_free(data);
+}
+
+static void resolve_done(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ AutoConfigureData *data = (AutoConfigureData *)user_data;
+ GResolver *resolver = (GResolver *)source;
+ GError *error = NULL;
+ gchar *hostname = NULL;
+ guint16 port;
+ GList *answers, *cur;
+ gboolean found = FALSE;
+ gboolean abort = FALSE;
+
+ answers = g_resolver_lookup_service_finish(resolver, result, &error);
+
+ if (answers) {
+ for (cur = g_srv_target_list_sort(answers); cur; cur = cur->next) {
+ GSrvTarget *target = (GSrvTarget *)cur->data;
+ const gchar *h = g_srv_target_get_hostname(target);
+ port = g_srv_target_get_port(target);
+ if (h && strcmp(h,"") && port > 0) {
+ hostname = g_strdup(h);
+ found = TRUE;
+ break;
+ }
+ }
+ g_resolver_free_targets(answers);
+ } else if (error) {
+ if (error->code == G_IO_ERROR_CANCELLED)
+ abort = TRUE;
+ else
+ data->resolver_error = error->code;
+ debug_print("error %s\n", error->message);
+ g_error_free(error);
+ }
+
+ if (found) {
+ auto_configure_done(hostname, port, data->ssl_service != NULL, data);
+ } else if (data->ssl_service && !abort) {
+ /* Fallback to TLS */
+ data->ssl_service = NULL;
+ auto_configure_service(data);
+ } else {
+ auto_configure_done(NULL, 0, FALSE, data);
+ }
+ g_free(hostname);
+ g_object_unref(resolver);
+}
+
+void auto_configure_service(AutoConfigureData *data)
+{
+ GResolver *resolver;
+ const gchar *cur_service = data->ssl_service != NULL ? data->ssl_service : data->tls_service;
+
+ cm_return_if_fail(cur_service != NULL);
+ cm_return_if_fail(data->address != NULL);
+
+ resolver = g_resolver_get_default();
+ if (resolver != NULL) {
+ const gchar *domain = strchr(data->address, '@') + 1;
+
+ gtk_label_set_text(data->info_label, _("Configuring..."));
+ gtk_widget_hide(GTK_WIDGET(data->configure_button));
+ gtk_widget_show(GTK_WIDGET(data->cancel_button));
+ g_resolver_lookup_service_async(resolver, cur_service, "tcp", domain,
+ data->cancel, resolve_done, data);
+ }
+}
+
+gboolean auto_configure_service_sync(const gchar *service, const gchar *domain, gchar **srvhost, guint16 *srvport)
+{
+ GResolver *resolver;
+ GList *answers, *cur;
+ GError *error = NULL;
+ gboolean result = FALSE;
+
+ cm_return_val_if_fail(service != NULL, FALSE);
+ cm_return_val_if_fail(domain != NULL, FALSE);
+
+ resolver = g_resolver_get_default();
+ if (resolver == NULL)
+ return FALSE;
+
+ answers = g_resolver_lookup_service(resolver, service, "tcp", domain, NULL, &error);
+
+ *srvhost = NULL;
+ *srvport = 0;
+
+ if (answers) {
+ for (cur = g_srv_target_list_sort(answers); cur; cur = cur->next) {
+ GSrvTarget *target = (GSrvTarget *)cur->data;
+ const gchar *hostname = g_srv_target_get_hostname(target);
+ guint16 port = g_srv_target_get_port(target);
+ if (hostname && strcmp(hostname,"") && port > 0) {
+ result = TRUE;
+ *srvhost = g_strdup(hostname);
+ *srvport = port;
+ break;
+ }
+ }
+ g_resolver_free_targets(answers);
+ } else if (error) {
+ g_error_free(error);
+ }
+
+ g_object_unref(resolver);
+ return result;
+}
+#endif