fix CID 1596595: Resource leaks, and CID 1596594: (CHECKED_RETURN)
[claws.git] / src / plugins / address_keeper / address_keeper.c
index 085f8b6190f26c9218a0cbc81eeda8218cbac311..38dc6d2ae85a3262b5186b2801b1f78ffb1eaf9e 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail Team
- * Copyright (C) 2009-2010 Ricardo Mones
+ * Claws Mail -- a GTK based, lightweight, and fast e-mail client
+ * Copyright (C) 2009-2015 Ricardo Mones 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
@@ -14,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation, 
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  */
 
 #ifdef HAVE_CONFIG_H
@@ -35,7 +33,7 @@
 #include "prefs_common.h"
 
 /** Identifier for the hook. */
-static guint hook_id;
+static gulong hook_id = HOOK_NONE;
 
 /**
  * Extracts name from an address.
@@ -87,19 +85,43 @@ gchar *get_comment_from_addr(const gchar *addr)
        return NULL;
 }
 
+/**
+ * Checks an address for matching a blocked address pattern.
+ *
+ * @param addr The full address.
+ * @param blocked The regexp matching blocked addresses.
+ *
+ * @return TRUE if given address matches any of the patterns, FALSE otherwise.
+ */
+gboolean matches_blocked_address(gchar *addr, MatcherList *blocked)
+{
+       if (blocked != NULL) {
+               MsgInfo info;
+
+               info.subject = addr;
+               return matcherlist_match(blocked, &info);
+       }
+       return FALSE;
+}
+
 /**
  * Saves an address to the configured addressbook folder if not known.
  *
  * @param abf The address book file containing target folder.
  * @param folder The address book folder where addresses are added.
  * @param addr The address to be added.
+ * @param blocked The regexp matching blocked addresses.
  */
-void keep_if_unknown(AddressBookFile * abf, ItemFolder * folder, gchar *addr)
+void keep_if_unknown(AddressBookFile * abf, ItemFolder * folder, gchar *addr, MatcherList *blocked)
 {
        gchar *clean_addr = NULL;
        gchar *keepto = addkeeperprefs.addressbook_folder;
 
        debug_print("checking addr '%s'\n", addr);
+       if (matches_blocked_address(addr, blocked)) {
+               debug_print("addr '%s' is blocked by regexp\n", addr);
+               return;
+       }
        clean_addr = g_strdup(addr);
        extract_address(clean_addr);
        start_address_completion(NULL);
@@ -111,7 +133,7 @@ void keep_if_unknown(AddressBookFile * abf, ItemFolder * folder, gchar *addr)
                a_name = get_name_from_addr(addr);
                a_comment = get_comment_from_addr(addr);
                if (!addrbook_add_contact(abf, folder, a_name, clean_addr, a_comment)) {
-                       g_warning("contact could not be added\n");
+                       g_warning("contact could not be added");
                } else {
                        addressbook_refresh();
                }
@@ -146,6 +168,7 @@ static gboolean addrk_before_send_hook(gpointer source, gpointer data)
        const gchar *to_hdr;
        const gchar *cc_hdr;
        const gchar *bcc_hdr;
+       MatcherList *blocked = NULL;
 
        debug_print("address_keeper invoked!\n");
        if (compose->batch)
@@ -157,11 +180,11 @@ static gboolean addrk_before_send_hook(gpointer source, gpointer data)
        }
 
        if (!addressbook_peek_folder_exists(keepto, &book, &folder)) {
-               g_warning("addressbook folder not found '%s'\n", keepto);
+               g_warning("addressbook folder not found '%s'", keepto);
                return FALSE;
        }
        if (!book) {
-               g_warning("addressbook_peek_folder_exists: NULL book\n");
+               g_warning("addressbook_peek_folder_exists: NULL book");
                return FALSE;
        }
        abf = book->rawDataSource;
@@ -170,6 +193,12 @@ static gboolean addrk_before_send_hook(gpointer source, gpointer data)
        cc_hdr = prefs_common_translated_header_name("Cc:");
        bcc_hdr = prefs_common_translated_header_name("Bcc:");
 
+       if (addkeeperprefs.block_matching_addrs != NULL
+                       && addkeeperprefs.block_matching_addrs[0] != '\0') {
+               blocked = matcherlist_new_from_lines(addkeeperprefs.block_matching_addrs, FALSE, FALSE);
+               if (blocked == NULL)
+                       g_warning("couldn't allocate matcher");
+       }
        for (cur = compose->header_list; cur != NULL; cur = cur->next) {
                gchar *header;
                gchar *entry;
@@ -183,20 +212,22 @@ static gboolean addrk_before_send_hook(gpointer source, gpointer data)
                if (*entry != '\0') {
                        if (!g_ascii_strcasecmp(header, to_hdr)
                                && addkeeperprefs.keep_to_addrs == TRUE) {
-                               keep_if_unknown(abf, folder, entry);
+                               keep_if_unknown(abf, folder, entry, blocked);
                        }
                        if (!g_ascii_strcasecmp(header, cc_hdr)
                                && addkeeperprefs.keep_cc_addrs == TRUE) {
-                               keep_if_unknown(abf, folder, entry);
+                               keep_if_unknown(abf, folder, entry, blocked);
                        }
                        if (!g_ascii_strcasecmp(header, bcc_hdr)
                                && addkeeperprefs.keep_bcc_addrs == TRUE) {
-                               keep_if_unknown(abf, folder, entry);
+                               keep_if_unknown(abf, folder, entry, blocked);
                        }
                }
                g_free(header);
                g_free(entry);
-       }       
+       }
+       if (blocked != NULL)    
+               matcherlist_free(blocked);
 
        return FALSE;   /* continue sending */
 }
@@ -217,7 +248,7 @@ gint plugin_init(gchar **error)
        hook_id = hooks_register_hook(COMPOSE_CHECK_BEFORE_SEND_HOOKLIST, 
                                      addrk_before_send_hook, NULL);
        
-       if (hook_id == -1) {
+       if (hook_id == HOOK_NONE) {
                *error = g_strdup(_("Failed to register check before send hook"));
                return -1;
        }
@@ -264,11 +295,11 @@ const gchar *plugin_desc(void)
 /**
  * Get the kind of plugin.
  *
- * @return The "GTK2" constant.
+ * @return The "GTK3" constant.
  */
 const gchar *plugin_type(void)
 {
-       return "GTK2";
+       return "GTK3";
 }
 
 /**