Properly determine match type to pass to header_match.

2001-08-08  Not Zed  <NotZed@Ximian.com>

        * camel-filter-search.c (check_header): Properly determine match
        type to pass to header_match.
        (address_matches_exactly): Removed, effectively added to
        camel_search_header_match.

        * camel-folder-search.c (check_header): Properly determine the
        match type to pass to header_match.

        * camel-search-private.c (camel_search_header_match): Add a new
        parameter 'type' which is the type of header we're matching
        against.  ASIS means utf8 format, ADDRESS means an internet
        address ('formatted'), ADDRESS_ENCODED means a raw address header,
        ENCODED means rfc 2047 encoded text.
        (header_match): Move original logic here, have search_header_match
        call it as appropriate for the 'type' of match.

2001-08-07  Not Zed  <NotZed@Ximian.com>

        * camel-session.c (camel_session_class_init): Only init the vee
        provider struct once (if we're subclassed this will get called
        multiple times).

        * camel-object.c (obj_finalize): Removed a bit of a debug that
        crept in with jacob's poolv patch (?).

svn path=/trunk/; revision=11772
This commit is contained in:
Not Zed
2001-08-08 09:37:40 +00:00
committed by Michael Zucci
parent 3f704068b6
commit 5dfe756f5f
7 changed files with 121 additions and 83 deletions

View File

@ -1,3 +1,30 @@
2001-08-08 Not Zed <NotZed@Ximian.com>
* camel-filter-search.c (check_header): Properly determine match
type to pass to header_match.
(address_matches_exactly): Removed, effectively added to
camel_search_header_match.
* camel-folder-search.c (check_header): Properly determine the
match type to pass to header_match.
* camel-search-private.c (camel_search_header_match): Add a new
parameter 'type' which is the type of header we're matching
against. ASIS means utf8 format, ADDRESS means an internet
address ('formatted'), ADDRESS_ENCODED means a raw address header,
ENCODED means rfc 2047 encoded text.
(header_match): Move original logic here, have search_header_match
call it as appropriate for the 'type' of match.
2001-08-07 Not Zed <NotZed@Ximian.com>
* camel-session.c (camel_session_class_init): Only init the vee
provider struct once (if we're subclassed this will get called
multiple times).
* camel-object.c (obj_finalize): Removed a bit of a debug that
crept in with jacob's poolv patch (?).
2001-08-07 Jeffrey Stedfast <fejj@ximian.com>
* camel-filter-search.c (address_matches_exactly): New function to

View File

@ -104,42 +104,6 @@ static struct {
{ "get-size", (ESExpFunc *) get_size, 0 },
};
static gboolean
address_matches_exactly (const char *header, const char *string)
{
CamelInternetAddress *cia;
GCompareFunc compare;
const char *p;
for (p = string; *p; p++)
if (isupper ((unsigned) *p))
break;
if (*p)
compare = (GCompareFunc) strcmp;
else
compare = (GCompareFunc) g_strcasecmp;
/* the simple case? */
if (!compare (header, string))
return TRUE;
cia = camel_internet_address_new ();
if (camel_address_decode (CAMEL_ADDRESS (cia), header) == 1) {
const char *name, *addr;
camel_internet_address_get (cia, 0, &name, &addr);
if (!compare (name, string))
return TRUE;
if (!compare (addr, string))
return TRUE;
}
camel_object_unref (CAMEL_OBJECT (cia));
return FALSE;
}
static ESExpResult *
check_header (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms, camel_search_match_t how)
{
@ -150,24 +114,21 @@ check_header (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess
if (argc > 1 && argv[0]->type == ESEXP_RES_STRING) {
char *name = argv[0]->value.string;
const char *header;
if (g_strcasecmp (name, "x-camel-mlist") == 0)
header = camel_message_info_mlist (fms->info);
else
header = camel_medium_get_header (CAMEL_MEDIUM (fms->message), argv[0]->value.string);
camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
if (strcasecmp(name, "x-camel-mlist") == 0) {
header = camel_message_info_mlist(fms->info);
type = CAMEL_SEARCH_TYPE_ASIS;
} 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)
type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
}
if (header) {
for (i = 1; i < argc && !matched; i++) {
if (argv[i]->type == ESEXP_RES_STRING) {
if (how == CAMEL_SEARCH_MATCH_EXACT
&& (!g_strcasecmp (name, "To")
|| !g_strcasecmp (name, "Cc")
|| !g_strcasecmp (name, "From")))
matched = address_matches_exactly (header, argv[i]->value.string);
else
matched = camel_search_header_match (header, argv[i]->value.string, how);
break;
}
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);
}
}
}

View File

@ -537,6 +537,7 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
const char *header = NULL;
char strbuf[32];
int i;
camel_search_t type = CAMEL_SEARCH_TYPE_ASIS;
/* only a subset of headers are supported .. */
headername = argv[0]->value.string;
@ -548,10 +549,13 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
header = strbuf;
} else if (!strcasecmp(headername, "from")) {
header = camel_message_info_from(search->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!strcasecmp(headername, "to")) {
header = camel_message_info_to(search->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!strcasecmp(headername, "cc")) {
header = camel_message_info_cc(search->current);
type = CAMEL_SEARCH_TYPE_ADDRESS;
} else if (!strcasecmp(headername, "x-camel-mlist")) {
header = camel_message_info_mlist(search->current);
} else {
@ -562,10 +566,8 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder
if (header) {
/* performs an OR of all words */
for (i=1;i<argc && !truth;i++) {
if (argv[i]->type == ESEXP_RES_STRING
&& camel_search_header_match(header, argv[i]->value.string, how)) {
truth = TRUE;
}
if (argv[i]->type == ESEXP_RES_STRING)
truth = camel_search_header_match(header, argv[i]->value.string, how, type);
}
}
}

View File

@ -337,10 +337,7 @@ obj_finalize (CamelObject * obj)
obj->s.magic = CAMEL_OBJECT_FINALIZED_VALUE;
if (obj->event_to_hooklist) {
#if 0
g_hash_table_foreach (obj->event_to_hooklist, (GHFunc) g_free,
NULL);
#endif
g_hash_table_foreach (obj->event_to_hooklist, (GHFunc) g_free, NULL);
g_hash_table_destroy (obj->event_to_hooklist);
obj->event_to_hooklist = NULL;
}

View File

@ -335,23 +335,18 @@ camel_ustrncasecmp (const char *s1, const char *s2, size_t len)
return 0;
}
/* searhces for match inside value, if match is mixed case, hten use case-sensitive,
else insensitive */
gboolean
camel_search_header_match (const char *value, const char *match, camel_search_match_t how)
/* value is the match value suitable for exact match if required */
static int
header_match(const char *value, const char *match, camel_search_match_t how)
{
const char *p;
int vlen, mlen;
while (*value && isspace (*value))
value++;
if (how == CAMEL_SEARCH_MATCH_SOUNDEX)
return header_soundex (value, match);
vlen = strlen (value);
mlen = strlen (match);
vlen = strlen(value);
mlen = strlen(match);
if (vlen < mlen)
return FALSE;
@ -359,16 +354,16 @@ camel_search_header_match (const char *value, const char *match, camel_search_ma
otherwise not */
p = match;
while (*p) {
if (isupper (*p)) {
if (isupper(*p)) {
switch (how) {
case CAMEL_SEARCH_MATCH_EXACT:
return strcmp (value, match) == 0;
return strcmp(value, match) == 0;
case CAMEL_SEARCH_MATCH_CONTAINS:
return strstr (value, match) != NULL;
return strstr(value, match) != NULL;
case CAMEL_SEARCH_MATCH_STARTS:
return strncmp (value, match, mlen) == 0;
return strncmp(value, match, mlen) == 0;
case CAMEL_SEARCH_MATCH_ENDS:
return strcmp (value + vlen - mlen, match) == 0;
return strcmp(value + vlen - mlen, match) == 0;
default:
break;
}
@ -379,13 +374,13 @@ camel_search_header_match (const char *value, const char *match, camel_search_ma
switch (how) {
case CAMEL_SEARCH_MATCH_EXACT:
return camel_ustrcasecmp (value, match) == 0;
return camel_ustrcasecmp(value, match) == 0;
case CAMEL_SEARCH_MATCH_CONTAINS:
return camel_ustrstrcase (value, match) != NULL;
return camel_ustrstrcase(value, match) != NULL;
case CAMEL_SEARCH_MATCH_STARTS:
return camel_ustrncasecmp (value, match, mlen) == 0;
return camel_ustrncasecmp(value, match, mlen) == 0;
case CAMEL_SEARCH_MATCH_ENDS:
return camel_ustrcasecmp (value + vlen - mlen, match) == 0;
return camel_ustrcasecmp(value + vlen - mlen, match) == 0;
default:
break;
}
@ -393,6 +388,53 @@ camel_search_header_match (const char *value, const char *match, camel_search_ma
return FALSE;
}
/* searhces for match inside value, if match is mixed case, hten use case-sensitive,
else insensitive */
gboolean
camel_search_header_match (const char *value, const char *match, camel_search_match_t how, camel_search_t type)
{
const char *name, *addr;
int truth = FALSE;
CamelInternetAddress *cia;
char *v;
while (*value && isspace (*value))
value++;
switch(type) {
case CAMEL_SEARCH_TYPE_ENCODED:
v = header_decode_string(value, camel_charset_locale_name());
truth = header_match(v, match, how);
g_free(v);
break;
case CAMEL_SEARCH_TYPE_ASIS:
truth = header_match(value, match, how);
break;
case CAMEL_SEARCH_TYPE_ADDRESS_ENCODED:
case CAMEL_SEARCH_TYPE_ADDRESS:
/* possible simple case to save some work if we can */
if (header_match(value, match, how))
return TRUE;
/* Now we decode any addresses, and try asis matches on name and address parts */
cia = camel_internet_address_new();
if (type == CAMEL_SEARCH_TYPE_ADDRESS_ENCODED)
camel_address_decode((CamelAddress *)cia, value);
else
camel_address_unformat((CamelAddress *)cia, value);
if (camel_address_length((CamelAddress *)cia) == 1) {
camel_internet_address_get(cia, 0, &name, &addr);
truth = header_match(name, match, how)
|| header_match(addr, match, how);
}
camel_object_unref((CamelObject *)cia);
break;
}
return truth;
}
/* performs a 'slow' content-based match */
/* there is also an identical copy of this in camel-filter-search.c */
gboolean

View File

@ -36,11 +36,18 @@ typedef enum {
CAMEL_SEARCH_MATCH_SOUNDEX,
} camel_search_match_t;
typedef enum {
CAMEL_SEARCH_TYPE_ASIS,
CAMEL_SEARCH_TYPE_ENCODED,
CAMEL_SEARCH_TYPE_ADDRESS,
CAMEL_SEARCH_TYPE_ADDRESS_ENCODED,
} camel_search_t;
/* builds a regex that represents a string search */
int camel_search_build_match_regex(regex_t *pattern, camel_search_flags_t type, int argc, struct _ESExpResult **argv, CamelException *ex);
gboolean camel_search_message_body_contains(CamelDataWrapper *object, regex_t *pattern);
gboolean camel_search_header_match(const char *value, const char *match, camel_search_match_t how);
gboolean camel_search_header_match(const char *value, const char *match, camel_search_match_t how, camel_search_t type);
gboolean camel_search_header_soundex(const char *header, const char *match);
#endif /* ! _CAMEL_SEARCH_PRIVATE_H */

View File

@ -127,8 +127,10 @@ camel_session_class_init (CamelSessionClass *camel_session_class)
camel_session_class->get_service = get_service;
camel_session_class->get_storage_path = get_storage_path;
vee_provider.object_types[CAMEL_PROVIDER_STORE] = camel_vee_store_get_type ();
vee_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal);
if (vee_provider.service_cache == NULL) {
vee_provider.object_types[CAMEL_PROVIDER_STORE] = camel_vee_store_get_type ();
vee_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal);
}
}
CamelType