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:
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user