aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog25
-rw-r--r--camel/camel-filter-search.c9
-rw-r--r--camel/camel-folder-search.c1
-rw-r--r--camel/camel-mime-utils.c277
-rw-r--r--camel/camel-mime-utils.h3
-rw-r--r--camel/camel-search-private.c21
-rw-r--r--camel/camel-search-private.h1
-rw-r--r--camel/camel.c6
8 files changed, 130 insertions, 213 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 70d0399299..4358626ed6 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,9 +1,34 @@
2001-10-22 <NotZed@Ximian.com>
+ * camel-filter-search.c, camel-folder-search.c (check_header): Use
+ search_type_mlist for mailing list searches.
+
+ * camel.c (camel_init): call camel-mime-utils-init func.
+
+ * camel-mime-utils.c: Changed mail mail_list_magic to include a
+ domain part, also pre-compile all the patterns. They are all
+ backward compatible except List-Id: which now uses the
+ mail-address-like <list-name.host.name> part rather than the
+ plain-text part (which might've been blank anyway).
+ (camel_mime_utils_init): Initialisation function to setup any
+ static data required by camel-mime-utils at run-time. We now
+ setup the base64/charset class tables here, so it doesn't need to
+ be done statically.
+ (camel_mime_special_table, camel_mime_base64_rank): No longer
+ statically initialise these.
+ (main): Removed + the tests at the end of the file.
+ (header_raw_check_mailing_list): Dont compile regex's here,
+ already compiled in utils_init. Use the regex patterns to remove
+ leading <'s from addresses. Also, if there is a domain part
+ matched, add that after a '@' is added.
+
* camel-search-private.c (camel_search_header_match): Match check
against all addresses in a multiple address match. Should fix
#13051.
(camel_search_header_match): Oops, missing i=0.
+ (camel_search_header_match): Added SEARCH_TYPE_MLIST for mlist
+ search types. It ignores the domain part if either (but not both)
+ of the values dont have it.
2001-10-22 Dan Winship <danw@ximian.com>
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index 9366a2f610..7b59622788 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -34,6 +34,10 @@
#include <string.h>
#include <ctype.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
#include <gal/util/e-iconv.h>
#include "e-util/e-sexp.h"
@@ -123,7 +127,7 @@ check_header (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess
if (strcasecmp(name, "x-camel-mlist") == 0) {
header = camel_message_info_mlist(fms->info);
- type = CAMEL_SEARCH_TYPE_ASIS;
+ type = CAMEL_SEARCH_TYPE_MLIST;
} else {
header = camel_medium_get_header(CAMEL_MEDIUM(fms->message), argv[0]->value.string);
if (strcasecmp("to", name) == 0 || strcasecmp("cc", name) == 0 || strcasecmp("from", name) == 0)
@@ -138,8 +142,7 @@ check_header (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess
if (header) {
for (i=1; i<argc && !matched; i++) {
if (argv[i]->type == ESEXP_RES_STRING)
- matched = camel_search_header_match(header, argv[i]->value.string,
- how, type, charset);
+ matched = camel_search_header_match(header, argv[i]->value.string, how, type, charset);
}
}
}
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index cca04d3248..1183f6c423 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -633,6 +633,7 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!strcasecmp(headername, "x-camel-mlist")) {
header = camel_message_info_mlist(search->current);
+ type = CAMEL_SEARCH_TYPE_MLIST;
} else {
e_sexp_resultv_free(f, argc, argv);
e_sexp_fatal_error(f, _("Performing query on unknown header: %s"), headername);
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 4f4090afbd..5598afe62d 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -88,52 +88,10 @@ static unsigned char tohex[16] = {
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
-static unsigned short camel_mime_special_table[256] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5,231, 7, 5, 5, 39, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 242,448, 76,192,192,192,192,192, 76, 76,448,448, 76,448, 72,324,
- 448,448,448,448,448,448,448,448,448,448, 76, 76, 76, 4, 76, 68,
- 76,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
- 448,448,448,448,448,448,448,448,448,448,448,108,236,108,192, 64,
- 192,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
- 448,448,448,448,448,448,448,448,448,448,448,192,192,192,192, 5,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static unsigned char camel_mime_base64_rank[256] = {
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
- 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
- 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-};
-
-/*
- if any of these change, then the tables above should be regenerated
- by compiling this with -DBUILD_TABLE, and running.
+static unsigned short camel_mime_special_table[256];
+static unsigned char camel_mime_base64_rank[256];
- gcc -DCLEAN_DATE -o buildtable -I.. `gnome-config --cflags --libs gal` -DBUILD_TABLE camel-mime-utils.c camel-charset-map.c
- ./buildtable
-
-*/
+/* Flags bits set in the mime_special table, use the is_*() mactos to access them normally */
enum {
IS_CTRL = 1<<0,
IS_LWSP = 1<<1,
@@ -158,9 +116,7 @@ enum {
#define is_especial(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_ESPECIAL) != 0)
#define is_psafe(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_PSAFE) != 0)
-/* only needs to be run to rebuild the tables above */
-#ifdef BUILD_TABLE
-
+/* Used by table initialisation code for special characters */
#define CHARS_LWSP " \t\n\r"
#define CHARS_TSPECIAL "()<>@,;:\\\"/[]?="
#define CHARS_SPECIAL "()<>@,;:\\\".[]"
@@ -235,7 +191,7 @@ header_decode_init(void)
header_init_bits(IS_PSAFE, 0, 0, CHARS_PSPECIAL);
}
-void
+static void
base64_init(void)
{
int i;
@@ -247,46 +203,6 @@ base64_init(void)
camel_mime_base64_rank['='] = 0;
}
-int main(int argc, char **argv)
-{
- int i;
- void run_test(void);
-
- header_decode_init();
- base64_init();
-
- printf("static unsigned short camel_mime_special_table[256] = {\n\t");
- for (i=0;i<256;i++) {
- printf("%3d,", camel_mime_special_table[i]);
- if ((i&15) == 15) {
- printf("\n");
- if (i!=255) {
- printf("\t");
- }
- }
- }
- printf("};\n");
-
- printf("static unsigned char camel_mime_base64_rank[256] = {\n\t");
- for (i=0;i<256;i++) {
- printf("%3d,", camel_mime_base64_rank[i]);
- if ((i&15) == 15) {
- printf("\n");
- if (i!=255) {
- printf("\t");
- }
- }
- }
- printf("};\n");
-
- run_test();
-
- return 0;
-}
-
-#endif
-
-
/* call this when finished encoding everything, to
flush off the last little bit */
int
@@ -3714,18 +3630,19 @@ header_msgid_generate (void)
static struct {
char *name;
char *pattern;
+ regex_t regex;
} mail_list_magic[] = {
/* Sender: owner-gnome-hackers@gnome.org */
/* Sender: owner-gnome-hacekrs */
- { "Sender", " *owner-([^@]+)@?([^ \n\t\r>]*)" },
+ { "Sender", " *owner-([^@]+)@?([^ @\n\t\r>]*)" },
/* Sender: gnome-hackers-owner@gnome.org */
/* Sender: gnome-hackers-owner */
- { "Sender", " *([^@]+)-owner@?(([^ \n\t\r>]*)" },
+ { "Sender", " *([^@]+)-owner@?([^ @\n\t\r>]*)" },
/* Sender: owner-gnome-hackers@gnome.org */
/* Sender: <owner-gnome-hackers@gnome.org> */
/* Sender: owner-gnome-hackers */
/* Sender: <owner-gnome-hackers> */
- { "Return-Path", " <?owner-([^@]+)@?([^ \n\t\r>]*)" },
+ { "Return-Path", " <?owner-([^@>]+)@?([^ \n\t\r>]*)" },
/* X-BeenThere: gnome-hackers@gnome.org */
/* X-BeenThere: gnome-hackers */
{ "X-BeenThere", " *([^@]+)@?([^ \n\t\r>]*)" },
@@ -3734,53 +3651,56 @@ static struct {
{ "Delivered-To", " *mailing list ([^@]+)@?([^ \n\t\r>]*)" },
/* X-Mailing-List: <gnome-hackers@gnome.org> arcive/latest/100 */
/* X-Mailing-List: gnome-hackers@gnome.org */
- { "X-Mailing-List", " <?*([^@]+)@?([^ \n\t\r>]*)" },
+ /* X-Mailing-List: gnome-hackers */
+ /* X-Mailing-List: <gnome-hackers> */
+ { "X-Mailing-List", " <?*([^@>]+)@?([^ \n\t\r>]*)" },
/* X-Loop: gnome-hackers@gnome.org */
{ "X-Loop", " *([^@]+)@?([^ \n\t\r>]*)" },
- { "List-Id", " *([^<]+)" },
- { "List-Post", " *<mailto:([^@]+)" },
- { "Mailing-List", " *list ([^@]+)" },
- { "Originator", " *([^@]+)" },
+ /* List-Id: GNOME stuff <gnome-hackers.gnome.org> */
+ /* List-Id: <gnome-hackers.gnome.org> */
+ /* List-Id: <gnome-hackers> */
+ /* This old one wasn't very useful: { "List-Id", " *([^<]+)" },*/
+ { "List-Id", "[^<]*<([^\\.>]+)\\.?([^ \n\t\r>]*)" },
+ /* List-Post: <mailto:gnome-hackers@gnome.org> */
+ /* List-Post: <mailto:gnome-hackers> */
+ { "List-Post", " *<mailto:([^@>]+)@?([^ \n\t\r>]*)" },
+ /* Mailing-List: list gnome-hackers@gnome.org; contact gnome-hackers-owner@gnome.org */
+ { "Mailing-List", " *list ([^@]+)@?([^ \n\t\r>;])*" },
+ /* Originator: gnome-hackers@gnome.org */
+ { "Originator", " *([^@]+)@?([^ \n\t\r>]*)" },
+ /* X-List: gnome-hackers */
+ /* X-List: gnome-hackers@gnome.org */
+ { "X-List", " *([^@]+)@?([^ \n\t\r>]*)" },
};
char *
header_raw_check_mailing_list(struct _header_raw **list)
{
const char *v;
- regex_t pattern;
- regmatch_t match[2];
- int i, errcode;
+ regmatch_t match[3];
+ int i;
for (i = 0; i < sizeof (mail_list_magic) / sizeof (mail_list_magic[0]); i++) {
- if ((errcode = regcomp (&pattern, mail_list_magic[i].pattern, REG_EXTENDED|REG_ICASE)) != 0) {
- char *errstr;
- size_t len;
-
- len = regerror (errcode, &pattern, NULL, 0);
- errstr = g_malloc0 (len + 1);
- regerror (errcode, &pattern, errstr, len);
- regfree (&pattern);
-
- g_warning ("Internal error, compiling regex failed: %s: %s",
- mail_list_magic[i].pattern, errstr);
- g_free (errstr);
-
- continue;
- }
-
v = header_raw_find (list, mail_list_magic[i].name, NULL);
- if (v != NULL && regexec (&pattern, v, 2, match, 0) == 0 && match[1].rm_so != -1) {
- const char *mlist, *mlend;
-
- regfree (&pattern);
- mlist = v + match[1].rm_so;
- mlend = v + match[1].rm_eo;
- if (*mlist == '<')
- mlist++;
-
- return g_strndup (mlist, mlend - mlist);
+ if (v != NULL && regexec (&mail_list_magic[i].regex, v, 3, match, 0) == 0 && match[1].rm_so != -1) {
+ char *list;
+ int len1, len2;
+
+ len1 = match[1].rm_eo - match[1].rm_so;
+ len2 = match[2].rm_eo - match[2].rm_so;
+
+ list = g_malloc(len1+len2+2);
+ memcpy(list, v + match[1].rm_so, len1);
+ if (len2) {
+ list[len1] = '@';
+ memcpy(list+len1+1, v+match[2].rm_so, len2);
+ list[len1+len2+1]=0;
+ } else {
+ list[len1] = 0;
+ }
+
+ return list;
}
- regfree (&pattern);
}
return NULL;
@@ -4178,89 +4098,32 @@ header_unfold(const char *in)
return out;
}
-#ifdef BUILD_TABLE
-
-/* for debugging tests */
-/* should also have some regression tests somewhere */
-
-void test_phrase(const char *in)
-{
- printf("'%s' -> '%s'\n", in, header_encode_phrase(in));
-}
-
-void test_fold(const char *in)
-{
- printf("'%s'\n ->\n '%s'\n", in, header_fold(in));
-}
-
-void run_test(void)
+void
+camel_mime_utils_init(void)
{
- char *to = "gnome hacker dudes: license-discuss@opensource.org,
- \"Richard M. Stallman\" <rms@gnu.org>,
- Barry Chester <barry_che@antdiv.gov.au>,
- Michael Zucchi <zucchi.michael(this (is a nested) comment)@zedzone.mmc.com.au>,
- Miguel de Icaza <miguel@gnome.org>;,
- zucchi@zedzone.mmc.com.au, \"Foo bar\" <zed@zedzone>,
- <frob@frobzone>";
-
-#if 0
- header_to_decode(to);
-
- header_mime_decode("1.0", 0, 0);
- header_mime_decode("1.3 (produced by metasend V1.0)", 0, 0);
- header_mime_decode("(produced by metasend V1.0) 5.2", 0, 0);
- header_mime_decode("7(produced by metasend 1.0) . (produced by helix/send/1.0) 9 . 5", 0, 0);
- header_mime_decode("3.", 0, 0);
- header_mime_decode(".", 0, 0);
- header_mime_decode(".5", 0, 0);
- header_mime_decode("c.d", 0, 0);
- header_mime_decode("", 0, 0);
-
- header_msgid_decode(" <\"L3x2i1.0.Nm5.Xd-Wu\"@lists.redhat.com>");
- header_msgid_decode("<200001180446.PAA02065@beaker.htb.com.au>");
-#endif
-
- test_fold("Header: This is a long header that should be folded properly at the right place, or so i hope. I should probably set the fold value to something lower for testing");
- test_fold("Header: nowletstryfoldingsomethingthatistoolongtofold,iwonderwhatitshoulddointsteadtofoldit?hmm,iguessicanjusttruncateitatsomepointortrytorefoldthepreviousstuff(yuck)tofit");
- test_phrase("Michael Zucchi (NotZed)");
- test_phrase("Zucchi, ( \\ NotZed \\ ) Michael");
- {
- int ic;
- char *outbuf, *inbuf, buffer[256];
- int inlen, outlen;
+ const char *v;
+ int i, errcode, regex_compilation_failed=0;
- outlen = 256;
- inbuf = "Dra¾en Kaèar";
- inlen = strlen(inbuf);
- outbuf = buffer;
- ic = iconv_open("UTF-8", "ISO-8859-1");
- iconv(ic, &inbuf, &inlen, &outbuf, &outlen);
- test_phrase(buffer);
-
- outlen = 256;
- inbuf = "This is an encoded phrase Tomasz K³oczko";
- inlen = strlen(inbuf);
- outbuf = buffer;
- ic = iconv_open("UTF-8", "ISO-8859-2");
- iconv(ic, &inbuf, &inlen, &outbuf, &outlen);
- test_phrase(buffer);
+ /* Init tables */
+ header_decode_init();
+ base64_init();
+ /* precompile regex's for speed at runtime */
+ for (i = 0; i < sizeof(mail_list_magic) / sizeof(mail_list_magic[0]); i++) {
+ errcode = regcomp(&mail_list_magic[i].regex, mail_list_magic[i].pattern, REG_EXTENDED|REG_ICASE);
+ if (errcode != 0) {
+ char *errstr;
+ size_t len;
+
+ len = regerror(errcode, &mail_list_magic[i].regex, NULL, 0);
+ errstr = g_malloc0(len + 1);
+ regerror(errcode, &mail_list_magic[i].regex, errstr, len);
+
+ g_warning("Internal error, compiling regex failed: %s: %s", mail_list_magic[i].pattern, errstr);
+ g_free(errstr);
+ regex_compilation_failed++;
+ }
}
- {
- char *str = "Blah blah\n\t = ? =? ?= This is a TEST For quoted-printable-encoding-encoding-of
- long lines, and lines that end in spaces
- and line sthat end in tabs
- And lines that just end.";
-
- char encoded[256];
- int state=-1,save=0;
- int len;
-
- len = quoted_encode_step(str, strlen(str), encoded, &state, &save);
- len += quoted_encode_close("", 0, encoded+len, &state, &save);
- printf("encoded = '%.*s'\n", len, encoded);
- }
+ g_assert(regex_compilation_failed == 0);
}
-
-#endif /* BUILD_TABLE */
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index d426668cb7..6e2787de8a 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -80,6 +80,9 @@ struct _header_address {
unsigned int refcount;
};
+/* MUST be called before everything else */
+void camel_mime_utils_init(void);
+
/* Address lists */
struct _header_address *header_address_new(void);
struct _header_address *header_address_new_name(const char *name, const char *addr);
diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c
index 5427e6a365..3369409936 100644
--- a/camel/camel-search-private.c
+++ b/camel/camel-search-private.c
@@ -398,7 +398,7 @@ camel_search_header_match (const char *value, const char *match, camel_search_ma
const char *name, *addr;
int truth = FALSE, i;
CamelInternetAddress *cia;
- char *v;
+ char *v, *vdom, *mdom;
while (*value && isspace (*value))
value++;
@@ -409,6 +409,25 @@ camel_search_header_match (const char *value, const char *match, camel_search_ma
truth = header_match(v, match, how);
g_free(v);
break;
+ case CAMEL_SEARCH_TYPE_MLIST:
+ /* Special mailing list old-version domain hack
+ If one of the mailing list names doesn't have an @ in it, its old-style, so
+ only match against the pre-domain part, which should be common */
+
+ vdom = strchr(value, '@');
+ mdom = strchr(match, '@');
+ if (mdom == NULL && vdom != NULL) {
+ v = alloca(vdom-value+1);
+ memcpy(v, value, vdom-value);
+ v[vdom-value] = 0;
+ value = (char *)v;
+ } else if (mdom != NULL && vdom == NULL) {
+ v = alloca(mdom-match+1);
+ memcpy(v, match, mdom-match);
+ v[mdom-match] = 0;
+ match = (char *)v;
+ }
+ /* Falls through */
case CAMEL_SEARCH_TYPE_ASIS:
truth = header_match(value, match, how);
break;
diff --git a/camel/camel-search-private.h b/camel/camel-search-private.h
index fdfe977a29..d2c4ea0b1c 100644
--- a/camel/camel-search-private.h
+++ b/camel/camel-search-private.h
@@ -42,6 +42,7 @@ typedef enum {
CAMEL_SEARCH_TYPE_ENCODED,
CAMEL_SEARCH_TYPE_ADDRESS,
CAMEL_SEARCH_TYPE_ADDRESS_ENCODED,
+ CAMEL_SEARCH_TYPE_MLIST, /* its a mailing list pseudo-header */
} camel_search_t;
/* builds a regex that represents a string search */
diff --git a/camel/camel.c b/camel/camel.c
index ab6795f6ba..023e03ff82 100644
--- a/camel/camel.c
+++ b/camel/camel.c
@@ -37,7 +37,7 @@
#endif /* HAVE_NSS */
#include "camel.h"
-#include "camel-charset-map.h"
+#include "camel-mime-utils.h"
gboolean camel_verbose_debug = FALSE;
@@ -64,7 +64,9 @@ camel_init (const char *configdir, gboolean nss_init)
if (getenv ("CAMEL_VERBOSE_DEBUG"))
camel_verbose_debug = TRUE;
-
+
+ camel_mime_utils_init();
+
#ifdef HAVE_NSS
if (nss_init) {
PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 10);