Add missing SSL settings copy when cloning accounts.
[claws.git] / src / account.c
index be5967f635a7abfb765b3762c9f153f8d90c9618..a8d8375f6e5b9284c1fd38ca740d612cefdf4043 100644 (file)
 #include "prefs_actions.h"
 #include "hooks.h"
 #include "passwordstore.h"
+#include "file-utils.h"
 
 enum {
        ACCOUNT_IS_DEFAULT,
-       ACCOUNT_ENABLE_GET_ALL, 
+       ACCOUNT_ENABLE_GET_ALL,
        ACCOUNT_NAME,
        ACCOUNT_PROTOCOL,
        ACCOUNT_SERVER,
@@ -70,14 +71,13 @@ enum {
 typedef enum
 {
        COL_DEFAULT     = 0,
-       COL_GETALL      = 1,
-       COL_NAME        = 2,
-       COL_PROTOCOL    = 3,
-       COL_SERVER      = 4
+       COL_GETALL,
+       COL_NAME,
+       COL_PROTOCOL,
+       COL_SERVER,
+       N_EDIT_ACCOUNT_COLS
 } EditAccountColumnPos;
 
-# define N_EDIT_ACCOUNT_COLS   5
-
 PrefsAccount *cur_account;
 
 static GList *account_list = NULL;
@@ -116,7 +116,6 @@ static gboolean account_key_pressed (GtkWidget      *widget,
 static gboolean account_search_func_cb (GtkTreeModel *model, gint column, 
                                                const gchar *key, GtkTreeIter *iter, 
                                                gpointer search_data);
-static void account_list_view_add      (PrefsAccount   *ac_prefs);
 static void account_list_view_set      (void);
 
 static void account_list_set           (void);
@@ -129,12 +128,7 @@ typedef struct FindAccountInStore {
 
 static GtkListStore* account_create_data_store (void);
 
-static void account_list_view_insert_account_item (GtkListStore        *list_store, 
-                                                  const gchar  *account_name,
-                                                  const gchar  *protocol, 
-                                                  const gchar  *server_name,
-                                                  gboolean      is_default, 
-                                                  gboolean      is_get_all,
+static void account_list_store_insert_account_item (GtkListStore       *list_store,
                                                   PrefsAccount *account_data);
 
 static GtkWidget *account_list_view_create     (void);
@@ -162,7 +156,7 @@ static gboolean find_account_in_store               (GtkTreeModel *model,
 static void account_get_all_toggled            (GtkCellRendererToggle  *widget, 
                                                 gchar                  *path, 
                                                 GtkWidget              *list_view);
-                                                
+
 static void account_double_clicked             (GtkTreeView            *list_view,
                                                 GtkTreePath            *path,
                                                 GtkTreeViewColumn      *column,
@@ -201,14 +195,14 @@ void account_read_config_all(void)
        debug_print("Reading all config for each account...\n");
 
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
-       if ((fp = g_fopen(rcpath, "rb")) == NULL) {
-               if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
+       if ((fp = claws_fopen(rcpath, "rb")) == NULL) {
+               if (ENOENT != errno) FILE_OP_ERROR(rcpath, "claws_fopen");
                g_free(rcpath);
                return;
        }
        g_free(rcpath);
 
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
+       while (claws_fgets(buf, sizeof(buf), fp) != NULL) {
                if (!strncmp(buf, "[Account: ", 10)) {
                        strretchomp(buf);
                        memmove(buf, buf + 1, sizeof(buf) - 1);
@@ -218,7 +212,7 @@ void account_read_config_all(void)
                                                       g_strdup(buf));
                }
        }
-       fclose(fp);
+       claws_fclose(fp);
 
        /* read config data from file */
        cur_account = NULL;
@@ -276,7 +270,20 @@ GList *account_find_all_from_address(GList *ac_list, const gchar *address)
        }
        return ac_list;
 }
-       
+
+GList *account_find_all(void)
+{
+       GList *cur;
+       PrefsAccount *ac;
+       GList *ac_list = NULL;
+
+       for (cur = account_list; cur != NULL; cur = cur->next) {
+               ac = (PrefsAccount *)cur->data;
+               ac_list = g_list_append(ac_list, ac);
+       }
+       return ac_list;
+}
+
 PrefsAccount *account_find_from_smtp_server(const gchar *address,
                                            const gchar *smtp_server)
 {
@@ -288,8 +295,8 @@ PrefsAccount *account_find_from_smtp_server(const gchar *address,
 
        for (cur = account_list; cur != NULL; cur = cur->next) {
                ac = (PrefsAccount *)cur->data;
-               if (!strcmp2(address, ac->address) &&
-                   !strcmp2(smtp_server, ac->smtp_server))
+               if (!g_strcmp0(address, ac->address) &&
+                   !g_strcmp0(smtp_server, ac->smtp_server))
                        return ac;
        }
 
@@ -450,7 +457,7 @@ void account_add(void)
        }
 }
 
-void account_open(PrefsAccount *ac_prefs)
+void account_open(PrefsAccount *ac_prefs, gboolean called_from_acc_list)
 {
        gboolean prev_default;
        gchar *ac_name, *old_prefix, *new_prefix;
@@ -471,13 +478,14 @@ void account_open(PrefsAccount *ac_prefs)
 
        prefs_account_open(ac_prefs, &account_dirty);
 
-       account_edit_focus();
+       if (called_from_acc_list)
+               account_edit_focus();
 
        if (account_dirty) {
                if (!prev_default && ac_prefs->is_default)
                        account_set_as_default(ac_prefs);
 
-               if (ac_prefs->folder && strcmp2(ac_name, ac_prefs->account_name) != 0) {
+               if (ac_prefs->folder && g_strcmp0(ac_name, ac_prefs->account_name) != 0) {
                        old_prefix = folder_get_identifier(FOLDER(ac_prefs->folder));
                        folder_set_name(FOLDER(ac_prefs->folder),
                                        ac_prefs->account_name);
@@ -862,7 +870,7 @@ static void account_edit_prefs(GtkWidget *widget, gpointer data)
        ac_prefs = account_list_view_get_selected_account(edit_account.list_view);
        
        if (ac_prefs) {
-               account_open(ac_prefs);
+               account_open(ac_prefs, TRUE);
                account_list_view_set();
        }               
 }
@@ -936,7 +944,13 @@ static void account_clone(GtkWidget *widget, gpointer data)
        ACP_FASSIGN(ssl_imap);
        ACP_FASSIGN(ssl_nntp);
        ACP_FASSIGN(ssl_smtp);
+       ACP_FASSIGN(ssl_certs_auto_accept);
        ACP_FASSIGN(use_nonblocking_ssl);
+       ACP_FASSIGN(use_tls_sni);
+       ACP_FASSIGN(in_ssl_client_cert_file);
+       ACP_FASSIGN(in_ssl_client_cert_pass);
+       ACP_FASSIGN(out_ssl_client_cert_file);
+       ACP_FASSIGN(out_ssl_client_cert_pass);
        
        /* receive */
        ACP_FASSIGN(use_apop_auth);
@@ -952,6 +966,10 @@ static void account_clone(GtkWidget *widget, gpointer data)
        ACP_FDUP(inbox);
        ACP_FDUP(local_inbox);
        ACP_FASSIGN(max_articles);
+       ACP_FASSIGN(autochk_use_default);
+       ACP_FASSIGN(autochk_use_custom);
+       ACP_FASSIGN(autochk_itv);
+       ac_clon->autocheck_timer = 0;
 
        ACP_FASSIGN(imap_auth_type);
 
@@ -1054,6 +1072,16 @@ static void account_clone(GtkWidget *widget, gpointer data)
 
        ACP_FASSIGN(config_version);
 
+       ACP_FASSIGN(use_proxy);
+       ACP_FASSIGN(use_default_proxy);
+       ACP_FASSIGN(use_proxy_for_send);
+       ACP_FASSIGN(proxy_info.proxy_type);
+       ACP_FDUP(proxy_info.proxy_host);
+       ACP_FASSIGN(proxy_info.proxy_port);
+       ACP_FASSIGN(proxy_info.use_proxy_auth);
+       ACP_FDUP(proxy_info.proxy_name);
+       ACP_FDUP(proxy_info.proxy_pass);
+
        account_list = g_list_append(account_list, ac_clon);
        account_list_view_set();
 }
@@ -1112,6 +1140,9 @@ static void account_delete(GtkWidget *widget, gpointer data)
                folder_destroy(FOLDER(ac_prefs->folder));
                folderview_set_all();
        }
+
+       inc_account_autocheck_timer_remove(ac_prefs);
+
        account_destroy(ac_prefs);
        account_list_view_set();
 
@@ -1302,55 +1333,6 @@ static gboolean account_search_func_cb (GtkTreeModel *model, gint column, const
 
        return retval;
 }
-static void account_list_view_add(PrefsAccount *ac_prefs)
-{
-       GtkTreeView *list_view = GTK_TREE_VIEW(edit_account.list_view);
-       GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model(list_view));
-       gchar *name, *protocol, *server;
-       gboolean has_getallbox;
-       gboolean getall;
-
-       name = ac_prefs->account_name;
-#ifdef USE_GNUTLS
-       protocol = ac_prefs->protocol == A_POP3 ?
-                 (ac_prefs->ssl_pop == SSL_TUNNEL ?
-                  "POP (SSL/TLS)" :
-                  ac_prefs->ssl_pop == SSL_STARTTLS ?
-                  "POP (STARTTLS)" : "POP") :
-                  ac_prefs->protocol == A_IMAP4 ?
-                 (ac_prefs->ssl_imap == SSL_TUNNEL ?
-                  "IMAP (SSL/TLS)" :
-                  ac_prefs->ssl_imap == SSL_STARTTLS ?
-                  "IMAP (STARTTLS)" : "IMAP") :
-                  ac_prefs->protocol == A_NNTP ?
-                 (ac_prefs->ssl_nntp == SSL_TUNNEL ?
-                  "NNTP (SSL/TLS)" : "NNTP") :
-                  ac_prefs->protocol == A_LOCAL ? "Local" :
-                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
-#else
-       protocol = ac_prefs->protocol == A_POP3  ? "POP" :
-                  ac_prefs->protocol == A_IMAP4 ? "IMAP" :
-                  ac_prefs->protocol == A_LOCAL ? "Local" :
-                  ac_prefs->protocol == A_NNTP  ? "NNTP" :
-                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
-#endif
-       server= ac_prefs->protocol == A_NNTP ? ac_prefs->nntp_server :
-                  ac_prefs->protocol == A_LOCAL ?  "-" :
-                  ac_prefs->protocol == A_NONE ? ac_prefs->smtp_server :
-                  ac_prefs->recv_server;
-
-       has_getallbox = (ac_prefs->protocol == A_POP3  ||
-                        ac_prefs->protocol == A_IMAP4 ||
-                        ac_prefs->protocol == A_NNTP  ||
-                        ac_prefs->protocol == A_LOCAL);
-       getall = has_getallbox && ac_prefs->recv_at_getall;
-
-       account_list_view_insert_account_item(list_store,
-                                            name, protocol, server,
-                                            ac_prefs->is_default,
-                                            getall, ac_prefs);
-       return;
-}
 
 static void account_list_view_set(void)
 {
@@ -1367,7 +1349,7 @@ static void account_list_view_set(void)
        gtk_list_store_clear(store);
        
        for (cur = account_list; cur != NULL; cur = cur->next) {
-               account_list_view_add((PrefsAccount *)cur->data);
+               account_list_store_insert_account_item(store, (PrefsAccount *)cur->data);
                if ((PrefsAccount *)cur->data == cur_account)
                        account_list_view_select_account
                                (edit_account.list_view, 
@@ -1510,24 +1492,54 @@ static GtkListStore* account_create_data_store(void)
  *\return      GtkTreeRowReference * A tree row reference, which is guaranteed to 
  *             stable whatever operations are performed on the list.
  */
-static void account_list_view_insert_account_item(GtkListStore *list_store, 
-                                                 const gchar *account_name,
-                                                 const gchar *protocol, 
-                                                 const gchar *server_name,
-                                                 gboolean is_default, 
-                                                 gboolean is_get_all,
-                                                 PrefsAccount *account_data)
+static void account_list_store_insert_account_item(GtkListStore *list_store,
+                                                 PrefsAccount *ac_prefs)
 {
        GtkTreeIter iter;
+       gboolean is_get_all = (ac_prefs->protocol == A_POP3 ||
+                       ac_prefs->protocol == A_IMAP4 ||
+                       ac_prefs->protocol == A_NNTP  ||
+                       ac_prefs->protocol == A_LOCAL) &&
+               ac_prefs->recv_at_getall;
+       gchar *protocol, *server;
        
+#ifdef USE_GNUTLS
+       protocol = ac_prefs->protocol == A_POP3 ?
+                 (ac_prefs->ssl_pop == SSL_TUNNEL ?
+                  "POP (SSL/TLS)" :
+                  ac_prefs->ssl_pop == SSL_STARTTLS ?
+                  "POP (STARTTLS)" : "POP") :
+                  ac_prefs->protocol == A_IMAP4 ?
+                 (ac_prefs->ssl_imap == SSL_TUNNEL ?
+                  "IMAP (SSL/TLS)" :
+                  ac_prefs->ssl_imap == SSL_STARTTLS ?
+                  "IMAP (STARTTLS)" : "IMAP") :
+                  ac_prefs->protocol == A_NNTP ?
+                 (ac_prefs->ssl_nntp == SSL_TUNNEL ?
+                  "NNTP (SSL/TLS)" : "NNTP") :
+                  ac_prefs->protocol == A_LOCAL ? "Local" :
+                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
+#else
+       protocol = ac_prefs->protocol == A_POP3  ? "POP" :
+                  ac_prefs->protocol == A_IMAP4 ? "IMAP" :
+                  ac_prefs->protocol == A_LOCAL ? "Local" :
+                  ac_prefs->protocol == A_NNTP  ? "NNTP" :
+                  ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
+#endif
+
+       server= ac_prefs->protocol == A_NNTP ? ac_prefs->nntp_server :
+                  ac_prefs->protocol == A_LOCAL ?  "-" :
+                  ac_prefs->protocol == A_NONE ? ac_prefs->smtp_server :
+                  ac_prefs->recv_server;
+
        gtk_list_store_append(list_store, &iter);
        gtk_list_store_set(list_store, &iter, 
-                          ACCOUNT_IS_DEFAULT,     is_default ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
+                          ACCOUNT_IS_DEFAULT,     ac_prefs->is_default ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
                           ACCOUNT_ENABLE_GET_ALL, is_get_all,
-                          ACCOUNT_NAME,           account_name,
+                          ACCOUNT_NAME,           ac_prefs->account_name,
                           ACCOUNT_PROTOCOL,       protocol,
-                          ACCOUNT_SERVER,         server_name,
-                          ACCOUNT_DATA,           account_data,
+                          ACCOUNT_SERVER,         server,
+                          ACCOUNT_DATA,           ac_prefs,
                           -1);
 }
 
@@ -1924,3 +1936,87 @@ gboolean password_get(const gchar *user,
        }
        return FALSE;
 }
+
+static GSList *account_sigsep_list = NULL;
+
+/* create a list of unique signatures from accounts list */
+void account_sigsep_matchlist_create(void)
+{
+       GList *cur_ac = NULL;
+       PrefsAccount *ac_prefs = NULL;
+
+       if (account_sigsep_list)
+               return;
+
+       account_sigsep_list = g_slist_prepend(account_sigsep_list, g_strdup("-- "));
+       for (cur_ac = account_get_list();
+                cur_ac != NULL;
+                cur_ac = g_list_next(cur_ac)) {
+               ac_prefs = (PrefsAccount *)cur_ac->data;
+
+               if (ac_prefs->sig_sep && *ac_prefs->sig_sep != '\0') {
+                       if (!g_slist_find_custom(account_sigsep_list, ac_prefs->sig_sep,
+                                       (GCompareFunc)g_strcmp0)) {
+                               account_sigsep_list = g_slist_prepend(account_sigsep_list,
+                                               g_strdup(ac_prefs->sig_sep));
+                       }
+               }
+       }
+}
+
+/* delete the list of signatures created by account_sigsep_matchlist_create() */
+void account_sigsep_matchlist_delete(void)
+{
+       if (account_sigsep_list) {
+               slist_free_strings_full(account_sigsep_list);
+               account_sigsep_list = NULL;
+       }
+}
+
+/* match a string against all signatures in list, using the specified format */
+gboolean account_sigsep_matchlist_str_found(const gchar *str, const gchar *format)
+{
+       gchar *tmp = NULL;
+       gboolean found = FALSE;
+       GSList *item;
+
+       for (item = account_sigsep_list;
+                item != NULL && !found;
+                item = g_slist_next(item)) {
+               tmp = g_strdup_printf(format, (gchar *)item->data);
+               if (tmp) {
+                       found = (strcmp(tmp, str) == 0);
+                       g_free(tmp);
+               } else {
+                       g_warning("account_sigsep_matchlist_str_found: g_strdup_printf failed, check format '%s'",
+                               format);
+                       return FALSE;
+               }
+       }
+       return found;
+}
+
+/* match M first char of a string against all signatures in list, using the specified format */
+gboolean account_sigsep_matchlist_nchar_found(const gchar *str, const gchar *format)
+{
+       gchar *tmp = NULL;
+       gboolean found = FALSE;
+       GSList *item;
+       gint len;
+
+       for (item = account_sigsep_list;
+                item != NULL && !found;
+                item = g_slist_next(item)) {
+               tmp = g_strdup_printf(format, (gchar *)item->data);
+               if (tmp) {
+                       len = strlen(tmp);
+                       found = (strncmp(tmp, str, len) == 0);
+                       g_free(tmp);
+               } else {
+                       g_warning("account_sigsep_matchlist_nchar_found: g_strdup_printf failed, check format '%s'",
+                               format);
+                       return FALSE;
+               }
+       }
+       return found;
+}