Fix bug #3741: Deleting an account doesn't delete imapcache
[claws.git] / src / account.c
index a5053e48e575f2b30dd170185d7ba5e2308396d6..9625056828cb9d5c9516dedf3cc1bfb5d2d2d1ab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2013 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
 #include "filtering.h"
 #include "prefs_actions.h"
 #include "hooks.h"
+#include "passwordstore.h"
 
 enum {
        ACCOUNT_IS_DEFAULT,
@@ -210,7 +211,7 @@ void account_read_config_all(void)
        while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (!strncmp(buf, "[Account: ", 10)) {
                        strretchomp(buf);
-                       memmove(buf, buf + 1, strlen(buf));
+                       memmove(buf, buf + 1, sizeof(buf) - 1);
                        buf[strlen(buf) - 1] = '\0';
                        debug_print("Found label: %s\n", buf);
                        ac_label_list = g_slist_append(ac_label_list,
@@ -375,6 +376,9 @@ GList *account_get_list(void)
 
 void account_edit_focus(void)
 {
+       if (edit_account.window == NULL) {
+               return;
+       }
        manage_window_set_transient(GTK_WINDOW(edit_account.window));
        gtk_widget_grab_focus(edit_account.close_btn);
        gtk_widget_show(edit_account.window);
@@ -391,7 +395,7 @@ void account_edit_open(gpointer a, gpointer b)
        if (compose_get_compose_list()) {
                alertpanel_error(_("Some composing windows are open.\n"
                                   "Please close all the composing "
-                                  "windows before editing the accounts."));
+                                  "windows before editing accounts."));
                inc_unlock();
                return;
        }
@@ -455,6 +459,13 @@ void account_open(PrefsAccount *ac_prefs)
 
        cm_return_if_fail(ac_prefs != NULL);
 
+       if (compose_get_compose_list()) {
+               alertpanel_error(_("Some composing windows are open.\n"
+                                  "Please close all the composing "
+                                  "windows before editing accounts."));
+               return;
+       }
+
        prev_default = ac_prefs->is_default;
        Xstrdup_a(ac_name, ac_prefs->account_name ? ac_prefs->account_name : "",
                  return);
@@ -948,7 +959,6 @@ static void account_clone(GtkWidget *widget, gpointer data)
        /* send */
        ACP_FASSIGN(gen_msgid);
        ACP_FASSIGN(gen_xmailer);
-       ACP_FASSIGN(gen_xnewsreader);
        ACP_FASSIGN(add_customhdr);
        ACP_FASSIGN(use_smtp_auth);
        ACP_FASSIGN(smtp_auth_type);
@@ -1049,6 +1059,27 @@ static void account_clone(GtkWidget *widget, gpointer data)
 #undef ACP_FDUP
 #undef ACP_FASSIGN
 
+static void account_empty_cache(PrefsAccount *ac_prefs)
+{
+       gchar *cache_dir;
+
+       cache_dir = prefs_account_cache_dir(ac_prefs, FALSE);
+       if (cache_dir == NULL)
+               return; /* no cache dir, nothing to do */
+
+       if (is_dir_exist(cache_dir) && remove_dir_recursive(cache_dir) < 0) {
+               g_warning("can't remove directory '%s'", cache_dir);
+       } else {
+               gchar *server_dir =  prefs_account_cache_dir(ac_prefs, TRUE);
+               if (g_rmdir(server_dir) == 0)
+                       debug_print("Removed empty cache server directory\n");
+               else
+                       debug_print("Cache server directory not empty: not removed\n");
+               g_free(server_dir);
+       }
+       g_free(cache_dir);
+}
+
 static void account_delete(GtkWidget *widget, gpointer data)
 {
        PrefsAccount *ac_prefs;
@@ -1056,7 +1087,7 @@ static void account_delete(GtkWidget *widget, gpointer data)
        GList *list;
        Folder *folder;
        GSList *cur;
+
        ac_prefs = account_list_view_get_selected_account(edit_account.list_view);
        if (ac_prefs == NULL)
                return;
@@ -1094,6 +1125,10 @@ static void account_delete(GtkWidget *widget, gpointer data)
                                GINT_TO_POINTER(ac_prefs->account_id));
        }
 
+       gchar *uid = g_strdup_printf("%d", ac_prefs->account_id);
+       passwd_store_delete_block(PWS_ACCOUNT, uid);
+       g_free(uid);
+
        debug_print("Removing filter rules relative to this account...\n");
        for(cur = filtering_rules ; cur != NULL ;) {
                FilteringProp * prop = (FilteringProp *) cur->data;
@@ -1109,6 +1144,10 @@ static void account_delete(GtkWidget *widget, gpointer data)
                        cur = g_slist_next(cur);
                }
        }
+
+       debug_print("Removing cache directory of this account...\n");
+       account_empty_cache(ac_prefs);
+
        folder_write_list();
 }
 
@@ -1274,22 +1313,22 @@ static void account_list_view_add(PrefsAccount *ac_prefs)
 #ifdef USE_GNUTLS
        protocol = ac_prefs->protocol == A_POP3 ?
                  (ac_prefs->ssl_pop == SSL_TUNNEL ?
-                  "POP3 (SSL)" :
+                  "POP (SSL/TLS)" :
                   ac_prefs->ssl_pop == SSL_STARTTLS ?
-                  "POP3 (TLS)" : "POP3") :
+                  "POP (STARTTLS)" : "POP") :
                   ac_prefs->protocol == A_IMAP4 ?
                  (ac_prefs->ssl_imap == SSL_TUNNEL ?
-                  "IMAP4 (SSL)" :
+                  "IMAP (SSL/TLS)" :
                   ac_prefs->ssl_imap == SSL_STARTTLS ?
-                  "IMAP4 (TLS)" : "IMAP4") :
+                  "IMAP (STARTTLS)" : "IMAP") :
                   ac_prefs->protocol == A_NNTP ?
                  (ac_prefs->ssl_nntp == SSL_TUNNEL ?
-                  "NNTP (SSL)" : "NNTP") :
+                  "NNTP (SSL/TLS)" : "NNTP") :
                   ac_prefs->protocol == A_LOCAL ? "Local" :
                   ac_prefs->protocol == A_NONE ?  "SMTP" : "-";
 #else
-       protocol = ac_prefs->protocol == A_POP3  ? "POP3" :
-                  ac_prefs->protocol == A_IMAP4 ? "IMAP4" :
+       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" : "-";
@@ -1358,7 +1397,7 @@ static void account_list_set(void)
                GtkTreeIter iter;
 
                if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
-                       g_warning("%s(%d) - no iter found???\n", __FILE__, __LINE__);                                         
+                       g_warning("%s(%d) - no iter found???", __FILE__, __LINE__);
                        continue;
                }
        
@@ -1385,41 +1424,54 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
        /* select the account set in folderitem's property (if enabled) */
        if (msginfo->folder->prefs && msginfo->folder->prefs->enable_default_account)
                account = account_find_from_id(msginfo->folder->prefs->default_account);
-       
+       else if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
+                folder_has_parent_of_type(msginfo->folder, F_OUTBOX) ||
+                folder_has_parent_of_type(msginfo->folder, F_DRAFT)) {
+                       gchar *from = NULL;
+                       if (!procheader_get_header_from_msginfo
+                               (msginfo, &from, "From:")) {
+                               gchar *buf = from + strlen("From:");
+                               extract_address(buf);
+                               account = account_find_from_address(buf, FALSE);
+                       g_free(from);
+                       }
+       }
        /* select account by to: and cc: header if enabled */
        if (reply_autosel) {
                gchar * field = NULL;
                int fieldno = 0;
                for (field = msginfo->to; fieldno++ < 2; field = msginfo->cc) {
                        if (!account && field) {
-                               gchar *to = NULL;
-                               if (!strchr(field, ',')) {
-                                       Xstrdup_a(to, field, return NULL);
-                                       extract_address(to);
-                                       account = account_find_from_address(to, FALSE);
-                               } else {
-                                       gchar **split = g_strsplit(field, ",", -1);
-                                       int i = -1;
+                               gchar *f = g_strdup(field);
+                               if (f) {
+                                       gchar *cur = f;
+                                       gchar *next = NULL;
+                                       gchar *to = NULL;
                                        do {
-                                               i++;
-                                               if (!split[i])
-                                                       break;
-                                               Xstrdup_a(to, split[i], return NULL);
+                                               next = strchr_with_skip_quote(cur, '"', ',');
+                                               if (next)
+                                                       (*next) = 0;
+                                               Xstrdup_a(to, cur, return NULL);
                                                extract_address(to);
                                                account = account_find_from_address(to, FALSE);
+                                               if (next)
+                                                       cur = next + 1;
+                                               else
+                                                       break;
                                        } while (!account);
-                                       g_strfreev(split);
+                                       g_free(f);
                                }
                        }
                }
                if (!account) {
-                       gchar deliveredto[BUFFSIZE];
+                       gchar *deliveredto = NULL;
                        if (!procheader_get_header_from_msginfo
-                               (msginfo, deliveredto,sizeof deliveredto , "Delivered-To:")) { 
+                               (msginfo, &deliveredto, "Delivered-To:")) {
                                gchar *buf = deliveredto + strlen("Delivered-To:");
                                extract_address(buf);
                                account = account_find_from_address(buf, FALSE);
-                       }
+                       g_free(deliveredto);
+                       }
                }
        }
 
@@ -1807,23 +1859,30 @@ gchar *account_get_signature_str(PrefsAccount *account)
                return NULL;
 
        if (account->sig_type == SIG_FILE) {
-               if (!is_file_or_fifo_exist(account->sig_path)) {
-                       g_warning("can't open signature file: %s\n",
-                                 account->sig_path);
+               gchar *sig_full_path;
+               if (!g_path_is_absolute(account->sig_path)) {
+                       sig_full_path = g_build_filename(get_home_dir(), account->sig_path, NULL);
+               } else {
+                       sig_full_path = g_strdup(account->sig_path);
+               }
+
+               if (!is_file_or_fifo_exist(sig_full_path)) {
+                       g_warning("can't open signature file: '%s'", sig_full_path);
+                       g_free(sig_full_path);
                        return NULL;
                }
-       }
 
-       if (account->sig_type == SIG_COMMAND)
-               sig_body = get_command_output(account->sig_path);
-       else {
-               gchar *tmp;
+               debug_print("Reading signature from file '%s'\n", sig_full_path);
+               gchar *tmp = file_read_to_str(sig_full_path);
+               g_free(sig_full_path);
 
-               tmp = file_read_to_str(account->sig_path);
                if (!tmp)
                        return NULL;
+
                sig_body = normalize_newlines(tmp);
                g_free(tmp);
+       } else {
+               sig_body = get_command_output(account->sig_path);
        }
 
        if (account->sig_sep) {