plug another memleak reported by Martin Kluge
[claws.git] / src / matcher.c
index 3c88091ebce1a5c8e953333c6ad1047150170978..f68eb5b1b1de822a973062ab203971faad16751c 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2002 by the Sylpheed Claws Team and Hiroyuki Yamamoto
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
@@ -91,7 +110,7 @@ static MatchParser matchparser_tab[] = {
        {MATCHACTION_FORWARD_AS_ATTACHMENT, "forward_as_attachment"},
        {MATCHACTION_EXECUTE, "execute"},
        {MATCHACTION_COLOR, "color"},
-       {MATCHACTION_BOUNCE, "bounce"},
+       {MATCHACTION_REDIRECT, "redirect"},
        {MATCHACTION_DELETE_ON_SERVER, "delete_on_server"}
 };
 
@@ -262,6 +281,7 @@ static gboolean matcherprop_string_match(MatcherProp * prop, gchar * str)
                                    ? REG_ICASE : 0)) != 0) {
                                prop->error = 1;
                                g_free(prop->preg);
+                               prop->preg = NULL;
                        }
                }
                if (prop->preg == NULL)
@@ -294,6 +314,7 @@ gboolean matcherprop_match_execute(MatcherProp * prop, MsgInfo * info)
 {
        gchar * file;
        gchar * cmd;
+       gint retval;
 
        file = procmsg_get_message_file(info);
        if (file == NULL)
@@ -303,7 +324,10 @@ gboolean matcherprop_match_execute(MatcherProp * prop, MsgInfo * info)
        if (cmd == NULL)
                return FALSE;
 
-       return (system(cmd) == 0);
+       retval = system(cmd);
+       debug_print("Command exit code: %d\n", retval);
+
+       return (retval == 0);
 }
 
 /* match a message and his headers, hlist can be NULL if you don't
@@ -846,6 +870,9 @@ gchar * matcherprop_to_string(MatcherProp * matcher)
        case MATCHCRITERIA_FORWARDED:
        case MATCHCRITERIA_NOT_FORWARDED:
                return g_strdup(criteria_str);
+       case MATCHCRITERIA_EXECUTE:
+       case MATCHCRITERIA_NOT_EXECUTE:
+               return g_strdup_printf("%s \"%s\"", criteria_str, matcher->expr);
        }
 
        matchtype_str = NULL;
@@ -909,6 +936,8 @@ gchar * matcherlist_to_string(MatcherList * matchers)
        return result;
 }
 
+#define STRLEN_ZERO(s) ((s) ? strlen(s) : 0)
+#define STRLEN_DEFAULT(s,d) ((s) ? strlen(s) : STRLEN_ZERO(d))
 /* matching_build_command() - preferably cmd should be unescaped */
 gchar * matching_build_command(gchar * cmd, MsgInfo * info)
 {
@@ -918,7 +947,16 @@ gchar * matching_build_command(gchar * cmd, MsgInfo * info)
        gchar * p;
        gint size;
 
-       size = strlen(cmd) + 1;
+       const gchar *const no_subject    = _("(none)") ;
+       const gchar *const no_from       = _("(none)") ;
+       const gchar *const no_to         = _("(none)") ;
+       const gchar *const no_cc         = _("(none)") ;
+       const gchar *const no_date       = _("(none)") ;
+       const gchar *const no_msgid      = _("(none)") ;
+       const gchar *const no_newsgroups = _("(none)") ;
+       const gchar *const no_references = _("(none)") ;
+
+       size = STRLEN_ZERO(cmd) + 1;
        while (*s != '\0') {
                if (*s == '%') {
                        s++;
@@ -927,28 +965,28 @@ gchar * matching_build_command(gchar * cmd, MsgInfo * info)
                                size -= 1;
                                break;
                        case 's': /* subject */
-                               size += strlen(info->subject) - 2;
+                               size += STRLEN_DEFAULT(info->subject, no_subject) - 2;
                                break;
                        case 'f': /* from */
-                               size += strlen(info->from) - 2;
+                               size += STRLEN_DEFAULT(info->from, no_from) - 2;
                                break;
                        case 't': /* to */
-                               size += strlen(info->to) - 2;
+                               size += STRLEN_DEFAULT(info->to, no_to) - 2;
                                break;
                        case 'c': /* cc */
-                               size += strlen(info->cc) - 2;
+                               size += STRLEN_DEFAULT(info->cc, no_cc) - 2;
                                break;
                        case 'd': /* date */
-                               size += strlen(info->date) - 2;
+                               size += STRLEN_DEFAULT(info->date, no_date) - 2;
                                break;
                        case 'i': /* message-id */
-                               size += strlen(info->msgid) - 2;
+                               size += STRLEN_DEFAULT(info->msgid, no_msgid) - 2;
                                break;
                        case 'n': /* newsgroups */
-                               size += strlen(info->newsgroups) - 2;
+                               size += STRLEN_DEFAULT(info->newsgroups, no_newsgroups) - 2;
                                break;
                        case 'r': /* references */
-                               size += strlen(info->references) - 2;
+                               size += STRLEN_DEFAULT(info->references, no_references) - 2;
                                break;
                        case 'F': /* file */
                                filename = folder_item_fetch_msg(info->folder,
@@ -984,61 +1022,62 @@ gchar * matching_build_command(gchar * cmd, MsgInfo * info)
                                if (info->subject != NULL)
                                        strcpy(p, info->subject);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_subject);
                                p += strlen(p);
                                break;
                        case 'f': /* from */
                                if (info->from != NULL)
                                        strcpy(p, info->from);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_from);
                                p += strlen(p);
                                break;
                        case 't': /* to */
                                if (info->to != NULL)
                                        strcpy(p, info->to);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_to);
                                p += strlen(p);
                                break;
                        case 'c': /* cc */
                                if (info->cc != NULL)
                                        strcpy(p, info->cc);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_cc);
                                p += strlen(p);
                                break;
                        case 'd': /* date */
                                if (info->date != NULL)
                                        strcpy(p, info->date);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_date);
                                p += strlen(p);
                                break;
                        case 'i': /* message-id */
                                if (info->msgid != NULL)
                                        strcpy(p, info->msgid);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_msgid);
                                p += strlen(p);
                                break;
                        case 'n': /* newsgroups */
                                if (info->newsgroups != NULL)
                                        strcpy(p, info->newsgroups);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_newsgroups);
                                p += strlen(p);
                                break;
                        case 'r': /* references */
                                if (info->references != NULL)
                                        strcpy(p, info->references);
                                else
-                                       strcpy(p, _("(none)"));
+                                       strcpy(p, no_references);
                                p += strlen(p);
                                break;
                        case 'F': /* file */
                                strcpy(p, filename);
                                p += strlen(p);
+                               g_free(filename);
                                break;
                        default:
                                *p = '%';
@@ -1059,6 +1098,8 @@ gchar * matching_build_command(gchar * cmd, MsgInfo * info)
        debug_print("*** exec string \"%s\"\n", processed_cmd);
        return processed_cmd;
 }
+#undef STRLEN_DEFAULT
+#undef STRLEN_ZERO
 
 /* ************************************************************ */
 
@@ -1168,7 +1209,7 @@ void prefs_matcher_write_config(void)
        GSList *cur;
        ScoringProp * prop;
 
-       debug_print(_("Writing matcher configuration...\n"));
+       debug_print("Writing matcher configuration...\n");
 
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
                             MATCHER_RC, NULL);
@@ -1204,8 +1245,10 @@ void prefs_matcher_read_config(void)
        f = fopen(rcpath, "rb");
        g_free(rcpath);
 
-       if (f != NULL)
+       if (f != NULL) {
                matcher_parser_start_parsing(f);
+               fclose(f);
+       }
        else {
                /* previous version compatibily */