#include "intl.h"
#include "matcher_parser.h"
#include "prefs_gtk.h"
+#include <ctype.h>
/*!
*\brief Keyword lookup element
*
*\return gchar * Newly allocated string with escaped characters
*/
+#if 0
gchar *matcher_escape_str(const gchar *str)
{
register const gchar *walk;
*reswalk = 0;
return res;
}
+#endif
/*!
*\brief Unescape string by replacing escaped char sequences
*
*\return gchar * Pointer to changed buffer
*/
+#if 0
gchar *matcher_unescape_str(gchar *str)
{
gchar *tmp = alloca(strlen(str) + 1);
*dst = 0;
return str;
}
+#endif
/* **************** data structure allocation **************** */
*\return MatcherProp * Pointer to newly allocated matcher
* structure
*/
+#if 0
MatcherProp *matcherprop_unquote_new(gint criteria, const gchar *header,
gint matchtype, const gchar *expr,
int value)
return prop;
}
-
+#endif
/* ************** match ******************************/
return result;
}
+
+static gint quote_filter_str(gchar * result, guint size,
+ const gchar * path)
+{
+ const gchar * p;
+ gchar * result_p;
+ guint remaining;
+
+ result_p = result;
+ remaining = size;
+
+ for(p = path ; * p != '\0' ; p ++) {
+
+ if ((* p != '\"') || (* p != '\\')) {
+ if (remaining > 0) {
+ * result_p = * p;
+ result_p ++;
+ remaining --;
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+ }
+ else {
+ if (remaining >= 2) {
+ * result_p = '\\';
+ result_p ++;
+ * result_p = * p;
+ result_p ++;
+ remaining -= 2;
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+ }
+ }
+ if (remaining > 0) {
+ * result_p = '\0';
+ }
+ else {
+ result[size - 1] = '\0';
+ return -1;
+ }
+
+ return 0;
+}
+
+
+gchar * matcher_quote_str(const gchar * src)
+{
+ gchar * res;
+ gint len;
+
+ len = strlen(src) * 2 + 1;
+ res = g_malloc(len);
+ quote_filter_str(res, len, src);
+
+ return res;
+}
+
/*!
*\brief Convert a matcher structure to a string
*
const gchar *criteria_str;
const gchar *matchtype_str;
int i;
- gchar *expr;
-
+ gchar * quoted_expr;
+
criteria_str = NULL;
for (i = 0; i < (int) (sizeof(matchparser_tab) / sizeof(MatchParser)); i++) {
if (matchparser_tab[i].id == matcher->criteria)
return g_strdup(criteria_str);
case MATCHCRITERIA_TEST:
case MATCHCRITERIA_NOT_TEST:
- expr = matcher_escape_str(matcher->expr);
- matcher_str = g_strdup_printf("%s \"%s\"", criteria_str, expr);
- g_free((gpointer) expr);
+ quoted_expr = matcher_quote_str(matcher->expr);
+ matcher_str = g_strdup_printf("%s \"%s\"",
+ criteria_str, quoted_expr);
+ g_free(quoted_expr);
return matcher_str;
}
case MATCHTYPE_MATCHCASE:
case MATCHTYPE_REGEXP:
case MATCHTYPE_REGEXPCASE:
- expr = matcher_escape_str(matcher->expr);
- if (matcher->header)
+ quoted_expr = matcher_quote_str(matcher->expr);
+ if (matcher->header) {
+ gchar * quoted_header;
+
+ quoted_header = matcher_quote_str(matcher->header);
matcher_str = g_strdup_printf
("%s \"%s\" %s \"%s\"",
- criteria_str, matcher->header,
- matchtype_str, expr);
+ criteria_str, quoted_header,
+ matchtype_str, quoted_expr);
+ g_free(quoted_header);
+ }
else
matcher_str = g_strdup_printf
("%s %s \"%s\"", criteria_str,
- matchtype_str, expr);
- g_free((gpointer) expr);
+ matchtype_str, quoted_expr);
+ g_free(quoted_expr);
break;
}
return result;
}
+
#define STRLEN_ZERO(s) ((s) ? strlen(s) : 0)
#define STRLEN_DEFAULT(s,d) ((s) ? strlen(s) : STRLEN_ZERO(d))
+
+static void add_str_default(gchar ** dest,
+ const gchar * s, const gchar * d)
+{
+ gchar quoted_str[4096];
+ const gchar * str;
+
+ if (s != NULL)
+ str = s;
+ else
+ str = d;
+
+ quote_cmd_argument(quoted_str, sizeof(quoted_str), str);
+ strcpy(* dest, quoted_str);
+
+ (* dest) += strlen(* dest);
+}
+
/* matching_build_command() - preferably cmd should be unescaped */
/*!
*\brief Build the command line to execute
size += STRLEN_DEFAULT(info->references, no_references) - 2;
break;
case 'F': /* file */
- filename = folder_item_fetch_msg(info->folder,
- info->msgnum);
+ if (filename != NULL)
+ filename = folder_item_fetch_msg(info->folder, info->msgnum);
if (filename == NULL) {
g_warning("filename is not set");
return NULL;
}
- else
+ else {
size += strlen(filename) - 2;
+ }
break;
}
s++;
}
else s++;
}
+
+ /* as the string can be quoted, we double the result */
+ size *= 2;
processed_cmd = g_new0(gchar, size);
s = cmd;
p++;
break;
case 's': /* subject */
- if (info->subject != NULL)
- strcpy(p, info->subject);
- else
- strcpy(p, no_subject);
- p += strlen(p);
+ add_str_default(&p, info->subject,
+ no_subject);
break;
case 'f': /* from */
- if (info->from != NULL)
- strcpy(p, info->from);
- else
- strcpy(p, no_from);
- p += strlen(p);
+ add_str_default(&p, info->from,
+ no_from);
break;
case 't': /* to */
- if (info->to != NULL)
- strcpy(p, info->to);
- else
- strcpy(p, no_to);
- p += strlen(p);
+ add_str_default(&p, info->to,
+ no_to);
break;
case 'c': /* cc */
- if (info->cc != NULL)
- strcpy(p, info->cc);
- else
- strcpy(p, no_cc);
- p += strlen(p);
+ add_str_default(&p, info->cc,
+ no_cc);
break;
case 'd': /* date */
- if (info->date != NULL)
- strcpy(p, info->date);
- else
- strcpy(p, no_date);
- p += strlen(p);
+ add_str_default(&p, info->date,
+ no_date);
break;
case 'i': /* message-id */
- if (info->msgid != NULL)
- strcpy(p, info->msgid);
- else
- strcpy(p, no_msgid);
- p += strlen(p);
+ add_str_default(&p, info->msgid,
+ no_msgid);
break;
case 'n': /* newsgroups */
- if (info->newsgroups != NULL)
- strcpy(p, info->newsgroups);
- else
- strcpy(p, no_newsgroups);
- p += strlen(p);
+ add_str_default(&p, info->newsgroups,
+ no_newsgroups);
break;
case 'r': /* references */
- if (info->references != NULL)
- strcpy(p, info->references);
- else
- strcpy(p, no_references);
- p += strlen(p);
+ add_str_default(&p, info->references,
+ no_references);
break;
case 'F': /* file */
- strcpy(p, filename);
- p += strlen(p);
- g_free(filename);
+ if (filename != NULL)
+ add_str_default(&p, filename, NULL);
break;
default:
*p = '%';
s++;
}
}
-
+ g_free(filename);
+
return processed_cmd;
}
#undef STRLEN_DEFAULT
gint criteria = 0;
criteria = MATCHCRITERIA_ALL;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_UNREAD
{
gint criteria = 0;
criteria = MATCHCRITERIA_UNREAD;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_UNREAD
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_UNREAD;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NEW
{
gint criteria = 0;
criteria = MATCHCRITERIA_NEW;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_NEW
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_NEW;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_MARKED
{
gint criteria = 0;
criteria = MATCHCRITERIA_MARKED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_MARKED
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_MARKED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_DELETED
{
gint criteria = 0;
criteria = MATCHCRITERIA_DELETED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_DELETED
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_DELETED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_REPLIED
{
gint criteria = 0;
criteria = MATCHCRITERIA_REPLIED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_REPLIED
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_REPLIED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_FORWARDED
{
gint criteria = 0;
criteria = MATCHCRITERIA_FORWARDED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_FORWARDED
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_FORWARDED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_LOCKED
{
gint criteria = 0;
criteria = MATCHCRITERIA_LOCKED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_LOCKED
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_LOCKED;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_COLORLABEL MATCHER_INTEGER
{
value = strtol($2, NULL, 10);
if (value < 0) value = 0;
else if (value > MAX_COLORLABELS) value = MAX_COLORLABELS;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_NOT_COLORLABEL MATCHER_INTEGER
{
value = strtol($2, NULL, 0);
if (value < 0) value = 0;
else if (value > MAX_COLORLABELS) value = MAX_COLORLABELS;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_IGNORE_THREAD
{
gint criteria = 0;
criteria = MATCHCRITERIA_IGNORE_THREAD;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_NOT_IGNORE_THREAD
{
gint criteria = 0;
criteria = MATCHCRITERIA_NOT_IGNORE_THREAD;
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
}
| MATCHER_SUBJECT match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_SUBJECT;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_SUBJECT match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_SUBJECT;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_FROM match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_FROM;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_FROM match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_FROM;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_TO match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_TO;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_TO match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_TO;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_CC match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_CC;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_CC match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_CC;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_TO_OR_CC match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_TO_OR_CC;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_TO_AND_NOT_CC match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_TO_AND_NOT_CC;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_AGE_GREATER MATCHER_INTEGER
{
criteria = MATCHCRITERIA_AGE_GREATER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_AGE_LOWER MATCHER_INTEGER
{
criteria = MATCHCRITERIA_AGE_LOWER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_NEWSGROUPS match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NEWSGROUPS;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_NEWSGROUPS match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_NEWSGROUPS;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_INREPLYTO match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_INREPLYTO;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_INREPLYTO match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_INREPLYTO;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_REFERENCES match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_REFERENCES;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_REFERENCES match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_REFERENCES;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_SCORE_GREATER MATCHER_INTEGER
{
criteria = MATCHCRITERIA_SCORE_GREATER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_SCORE_LOWER MATCHER_INTEGER
{
criteria = MATCHCRITERIA_SCORE_LOWER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_SCORE_EQUAL MATCHER_INTEGER
{
criteria = MATCHCRITERIA_SCORE_EQUAL;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_SIZE_GREATER MATCHER_INTEGER
{
gint value = 0;
criteria = MATCHCRITERIA_SIZE_GREATER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_SIZE_SMALLER MATCHER_INTEGER
{
gint value = 0;
criteria = MATCHCRITERIA_SIZE_SMALLER;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_SIZE_EQUAL MATCHER_INTEGER
{
gint value = 0;
criteria = MATCHCRITERIA_SIZE_EQUAL;
value = strtol($2, NULL, 0);
- prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
+ prop = matcherprop_new(criteria, NULL, 0, NULL, value);
}
| MATCHER_HEADER MATCHER_STRING
{
criteria = MATCHCRITERIA_HEADER;
expr = $2;
- prop = matcherprop_unquote_new(criteria, header, match_type, expr, 0);
+ prop = matcherprop_new(criteria, header, match_type, expr, 0);
g_free(header);
}
| MATCHER_NOT_HEADER MATCHER_STRING
criteria = MATCHCRITERIA_NOT_HEADER;
expr = $2;
- prop = matcherprop_unquote_new(criteria, header, match_type, expr, 0);
+ prop = matcherprop_new(criteria, header, match_type, expr, 0);
g_free(header);
}
| MATCHER_HEADERS_PART match_type MATCHER_STRING
criteria = MATCHCRITERIA_HEADERS_PART;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_HEADERS_PART match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_HEADERS_PART;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_MESSAGE match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_MESSAGE;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_MESSAGE match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_MESSAGE;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_BODY_PART match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_BODY_PART;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_NOT_BODY_PART match_type MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_BODY_PART;
expr = $3;
- prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
+ prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
}
| MATCHER_TEST MATCHER_STRING
{
criteria = MATCHCRITERIA_TEST;
expr = $2;
- prop = matcherprop_unquote_new(criteria, NULL, 0, expr, 0);
+ prop = matcherprop_new(criteria, NULL, 0, expr, 0);
}
| MATCHER_NOT_TEST MATCHER_STRING
{
criteria = MATCHCRITERIA_NOT_TEST;
expr = $2;
- prop = matcherprop_unquote_new(criteria, NULL, 0, expr, 0);
+ prop = matcherprop_new(criteria, NULL, 0, expr, 0);
}
;