+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto & The Sylpheed Claws 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
+ * 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.
+ */
+
+/*
+ * initial Hoa initial
+ *
+ * 07/18/01 Alfons when we want a file name from a MsgInfo, get that
+ * from MsgInfo->folder if the message is being filtered
+ * from incorporation. also some more safe string checking.
+ */
+
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
{MATCHING_ACTION_MARK_AS_UNREAD, "mark_as_unread"},
{MATCHING_ACTION_FORWARD, "forward"},
{MATCHING_ACTION_FORWARD_AS_ATTACHMENT, "forward_as_attachment"},
+ {MATCHING_ACTION_COLOR, "color"}
/* {MATCHING_EXECUTE, "execute"}, */
};
return g_strdup(start);
}
+/* matcher_parse_str() - parses a string until it hits a
+ * terminating \". to unescape characters use \. The string
+ * should not be used directly: matcher_unescape_str()
+ * returns a string that can be used directly. */
gchar * matcher_parse_str(gchar ** str)
{
gchar * p;
p ++;
start = p;
dest = p;
- while (*p != '"') {
+
+ for ( ; *p && *p != '\"'; p++, dest++) {
if (*p == '\\') {
- p++;
+ *dest++ = *p++;
*dest = *p;
}
- else
+ else
*dest = *p;
- dest++;
- p++;
}
*dest = '\0';
-
+
*str += dest - dup + 2;
return g_strdup(start);
}
+gchar *matcher_unescape_str(gchar *str)
+{
+ gchar *tmp = alloca(strlen(str) + 1);
+ register gchar *src = tmp;
+ register gchar *dst = str;
+
+ strcpy(tmp, str);
+
+ for ( ; *src; src++) {
+ if (*src != '\\')
+ *dst++ = *src;
+ else {
+ src++;
+ if (*src == '\\')
+ *dst++ = '\\';
+ else if (*src == 'n')
+ *dst++ = '\n';
+ else if (*src == 'r')
+ *dst++ = '\r';
+ else if (*src == '\'' || *src == '\"')
+ *dst++ = *src;
+ else {
+ src--;
+ *dst++ = *src;
+ }
+ }
+ }
+ *dst = 0;
+ return str;
+}
+
/* **************** data structure allocation **************** */
gboolean matcherprop_match_execute(MatcherProp * prop, MsgInfo * info)
{
- gchar * file;
gchar * cmd;
- file = procmsg_get_message_file(info);
- if (file == NULL)
- return FALSE;
-
cmd = matching_build_command(prop->expr, info);
if (cmd == NULL)
return FALSE;
procheader_header_free(header);
return result;
}
+ else {
+ procheader_header_free(header);
+ }
break;
case MATCHING_HEADERS_PART:
case MATCHING_MESSAGE:
GSList * l;
FILE * fp;
gchar * file;
-
- /* file need to be read ? */
-
+ gboolean is_incorporating = MSG_IS_FILTERING(info->flags);
+
+ /* check which things we need to do */
read_headers = FALSE;
- read_body = FALSE;
+ read_body = FALSE;
+
for(l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
MatcherProp * matcher = (MatcherProp *) l->data;
if (!read_headers && !read_body)
return result;
- file = procmsg_get_message_file(info);
+ file = is_incorporating ? g_strdup(info->folder)
+ : procmsg_get_message_file(info);
+
if (file == NULL)
return FALSE;
return result;
}
+static inline gint strlen_with_check(const gchar *expr, gint fline, const gchar *str)
+{
+ if (str)
+ return strlen(str);
+ else {
+ debug_print("%s(%d) - invalid string %s\n", __FILE__, fline, expr);
+ return 0;
+ }
+}
+
+#define STRLEN_WITH_CHECK(expr) \
+ strlen_with_check(#expr, __LINE__, expr)
gchar * matching_build_command(gchar * cmd, MsgInfo * info)
{
gchar * p;
gint size;
+ matcher_unescape_str(cmd);
+
size = strlen(cmd) + 1;
while (*s != '\0') {
if (*s == '%') {
size -= 1;
break;
case 's': /* subject */
- size += strlen(info->subject) - 2;
+ size += STRLEN_WITH_CHECK(info->subject) - 2;
break;
case 'f': /* from */
- size += strlen(info->from) - 2;
+ size += STRLEN_WITH_CHECK(info->from) - 2;
break;
case 't': /* to */
- size += strlen(info->to) - 2;
+ size += STRLEN_WITH_CHECK(info->to) - 2;
break;
case 'c': /* cc */
- size += strlen(info->cc) - 2;
+ size += STRLEN_WITH_CHECK(info->cc) - 2;
break;
case 'd': /* date */
- size += strlen(info->date) - 2;
+ size += STRLEN_WITH_CHECK(info->date) - 2;
break;
case 'i': /* message-id */
- size += strlen(info->msgid) - 2;
+ size += STRLEN_WITH_CHECK(info->msgid) - 2;
break;
case 'n': /* newsgroups */
- size += strlen(info->newsgroups) - 2;
+ size += STRLEN_WITH_CHECK(info->newsgroups) - 2;
break;
case 'r': /* references */
- size += strlen(info->references) - 2;
+ size += STRLEN_WITH_CHECK(info->references) - 2;
break;
case 'F': /* file */
- filename = folder_item_fetch_msg(info->folder,
- info->msgnum);
+ if (MSG_IS_FILTERING(info->flags))
+ filename = g_strdup(info->folder);
+ else
+ filename = folder_item_fetch_msg(info->folder, info->msgnum);
if (filename == NULL) {
- g_warning(_("filename is not set"));
+ debug_print(_("%s(%d) - filename is not set"), __FILE__, __LINE__);
return NULL;
}
else
else s++;
}
-
processed_cmd = g_new0(gchar, size);
s = cmd;
p = processed_cmd;
s++;
}
}
+
+ debug_print("*** exec string \"%s\"\n", processed_cmd);
+
+ g_free(filename);
return processed_cmd;
}