[dovecot-cvs] dovecot/src/lib-storage/index index-search.c,1.39,1.40 index-storage.h,1.18,1.19
cras at procontrol.fi
cras at procontrol.fi
Sun Nov 3 10:39:46 EET 2002
Update of /home/cvs/dovecot/src/lib-storage/index
In directory danu:/tmp/cvs-serv3305/src/lib-storage/index
Modified Files:
index-search.c index-storage.h
Log Message:
SEARCH CHARSET support. Currently we do it through iconv() and only ASCII
characters are compared case-insensitively.
Index: index-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-search.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- index-search.c 2 Nov 2002 20:10:21 -0000 1.39
+++ index-search.c 3 Nov 2002 08:39:44 -0000 1.40
@@ -7,6 +7,7 @@
#include "rfc822-tokenize.h"
#include "rfc822-date.h"
#include "message-size.h"
+#include "message-header-search.h"
#include "imap-date.h"
#include "imap-envelope.h"
#include "index-storage.h"
@@ -24,13 +25,17 @@
} STMT_END
typedef struct {
+ Pool hdr_pool;
IndexMailbox *ibox;
MailIndexRecord *rec;
unsigned int client_seq;
int cached;
+ const char *charset;
+ const char *error;
} SearchIndexContext;
typedef struct {
+ SearchIndexContext *index_context;
MailSearchArg *args;
int custom_header;
@@ -295,30 +300,44 @@
}
}
-static int search_substr(const char *haystack, const char *needle)
+static HeaderSearchContext *search_header_context(SearchIndexContext *ctx,
+ MailSearchArg *arg)
{
- size_t i, needle_len;
+ int unknown_charset;
- /* note: needle is already uppercased */
- needle_len = strlen(needle);
- for (i = 0; haystack[i] != '\0'; i++) {
- if (needle[0] == i_toupper(haystack[i]) &&
- strncasecmp(needle, haystack+i, needle_len) == 0)
- return 1;
+ if (arg->context != NULL) {
+ message_header_search_reset(arg->context);
+ return arg->context;
}
- return 0;
+ if (ctx->hdr_pool == NULL) {
+ ctx->hdr_pool = pool_create("message_header_search",
+ 8192, FALSE);
+ }
+
+ arg->context = message_header_search_init(ctx->hdr_pool, arg->value.str,
+ ctx->charset,
+ &unknown_charset);
+ if (arg->context == NULL) {
+ ctx->error = unknown_charset ?
+ "Unknown charset" : "Invalid search key";
+ }
+
+ return arg->context;
}
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
-static int search_arg_match_envelope(MailIndex *index, MailIndexRecord *rec,
- MailSearchArgType type, const char *value)
+static int search_arg_match_envelope(SearchIndexContext *ctx,
+ MailSearchArg *arg)
{
- ImapEnvelopeField env_field;
+ MailIndex *index = ctx->ibox->index;
+ ImapEnvelopeField env_field;
+ HeaderSearchContext *hdr_search_ctx;
const char *envelope, *field;
+ size_t size;
int ret;
- switch (type) {
+ switch (arg->type) {
case SEARCH_SENTBEFORE:
case SEARCH_SENTON:
case SEARCH_SENTSINCE:
@@ -354,7 +373,7 @@
t_push();
/* get field from hopefully cached envelope */
- envelope = index->lookup_field(index, rec, DATA_FIELD_ENVELOPE);
+ envelope = index->lookup_field(index, ctx->rec, DATA_FIELD_ENVELOPE);
if (envelope != NULL)
field = imap_envelope_parse(envelope, env_field);
else {
@@ -365,13 +384,21 @@
if (field == NULL)
ret = -1;
else {
- switch (type) {
+ switch (arg->type) {
case SEARCH_SENTBEFORE:
case SEARCH_SENTON:
case SEARCH_SENTSINCE:
- ret = search_sent(type, value, field);
+ ret = search_sent(arg->type, arg->value.str, field);
default:
- ret = search_substr(field, value);
+ hdr_search_ctx = search_header_context(ctx, arg);
+ if (hdr_search_ctx == NULL) {
+ ret = 0;
+ break;
+ }
+
+ size = strlen(field);
+ ret = message_header_search(field, &size,
+ hdr_search_ctx) ? 1 : 0;
}
}
t_pop();
@@ -382,8 +409,7 @@
{
SearchIndexContext *ctx = context;
- switch (search_arg_match_envelope(ctx->ibox->index, ctx->rec,
- arg->type, arg->value.str)) {
+ switch (search_arg_match_envelope(ctx, arg)) {
case -1:
/* unknown */
break;
@@ -396,52 +422,10 @@
}
}
-/* needle must be uppercased */
-static int header_value_match(const char *haystack, size_t haystack_len,
- const char *needle)
-{
- const char *n;
- size_t i, j, needle_len, max;
-
- if (*needle == '\0')
- return TRUE;
-
- needle_len = strlen(needle);
- if (haystack_len < needle_len)
- return FALSE;
-
- max = haystack_len - needle_len;
- for (i = 0; i <= max; i++) {
- if (needle[0] != i_toupper(haystack[i]))
- continue;
-
- for (j = i, n = needle; j < haystack_len; j++) {
- if (haystack[j] == '\r') {
- if (j+1 != haystack_len)
- j++;
- }
-
- if (haystack[j] == '\n' && j+1 < haystack_len &&
- IS_LWSP(haystack[j+1])) {
- /* long header continuation */
- j++;
- }
-
- if (*n++ != i_toupper(haystack[j]))
- break;
-
- if (*n == '\0')
- return 1;
- }
- }
-
- return -1;
-}
-
static void search_header_arg(MailSearchArg *arg, void *context)
{
SearchHeaderContext *ctx = context;
- const char *value;
+ HeaderSearchContext *hdr_search_ctx;
size_t len;
int ret;
@@ -462,47 +446,48 @@
if (ctx->name_len != 4 ||
strncasecmp(ctx->name, "From", 4) != 0)
return;
- value = arg->value.str;
break;
case SEARCH_TO:
if (ctx->name_len != 2 ||
strncasecmp(ctx->name, "To", 2) != 0)
return;
- value = arg->value.str;
break;
case SEARCH_CC:
if (ctx->name_len != 2 ||
strncasecmp(ctx->name, "Cc", 2) != 0)
return;
- value = arg->value.str;
break;
case SEARCH_BCC:
if (ctx->name_len != 3 ||
strncasecmp(ctx->name, "Bcc", 3) != 0)
return;
- value = arg->value.str;
break;
case SEARCH_SUBJECT:
if (ctx->name_len != 7 ||
strncasecmp(ctx->name, "Subject", 7) != 0)
return;
- value = arg->value.str;
break;
case SEARCH_HEADER:
ctx->custom_header = TRUE;
- len = strlen(arg->value.str);
+ len = strlen(arg->hdr_field_name);
if (ctx->name_len != len ||
- strncasecmp(ctx->name, arg->value.str, len) != 0)
+ strncasecmp(ctx->name, arg->hdr_field_name, len) != 0)
return;
-
- value = arg->hdr_value;
default:
return;
}
/* then check if the value matches */
- ret = header_value_match(ctx->value, ctx->value_len, value);
+ hdr_search_ctx = search_header_context(ctx->index_context, arg);
+ if (hdr_search_ctx == NULL)
+ ret = 0;
+ else {
+ len = ctx->value_len;
+ ret = message_header_search(ctx->value, &len,
+ hdr_search_ctx) ? 1 : 0;
+ }
+
ARG_SET_RESULT(arg, ret);
}
@@ -623,15 +608,16 @@
return FALSE;
if (have_headers) {
- SearchHeaderContext ctx;
+ SearchHeaderContext hdr_ctx;
- memset(&ctx, 0, sizeof(ctx));
+ memset(&hdr_ctx, 0, sizeof(hdr_ctx));
/* header checks */
- ctx.custom_header = TRUE;
- ctx.args = args;
+ hdr_ctx.index_context = ctx;
+ hdr_ctx.custom_header = TRUE;
+ hdr_ctx.args = args;
message_parse_header(NULL, inbuf, &hdr_size,
- search_header, &ctx);
+ search_header, &hdr_ctx);
}
if (have_text) {
@@ -822,8 +808,8 @@
return TRUE;
}
-static int search_messages(IndexMailbox *ibox, MailSearchArg *args,
- OBuffer *outbuf, int uid_result)
+static int search_messages(IndexMailbox *ibox, const char *charset,
+ MailSearchArg *args, OBuffer *outbuf, int uid_result)
{
SearchIndexContext ctx;
MailIndexRecord *rec;
@@ -850,7 +836,10 @@
&expunges_before);
client_seq += expunges_before;
+ memset(&ctx, 0, sizeof(ctx));
ctx.ibox = ibox;
+ ctx.charset = charset;
+
for (; rec != NULL && rec->uid <= last_uid; client_seq++) {
while (expunges->uid1 != 0 && expunges->uid1 < rec->uid) {
i_assert(expunges->uid2 < rec->uid);
@@ -875,6 +864,9 @@
imap_msgcache_close(ibox->cache);
t_pop();
+ if (ctx.error != NULL)
+ break;
+
if (!failed) {
found = TRUE;
for (arg = args; arg != NULL; arg = arg->next) {
@@ -894,10 +886,15 @@
rec = ibox->index->next(ibox->index, rec);
}
- return TRUE;
+ if (ctx.hdr_pool != NULL)
+ pool_unref(ctx.hdr_pool);
+
+ if (ctx.error != NULL)
+ mail_storage_set_error(ibox->box.storage, "%s", ctx.error);
+ return ctx.error == NULL;
}
-int index_storage_search(Mailbox *box, MailSearchArg *args,
+int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args,
OBuffer *outbuf, int uid_result)
{
IndexMailbox *ibox = (IndexMailbox *) box;
@@ -907,7 +904,7 @@
return FALSE;
o_buffer_send(outbuf, "* SEARCH", 8);
- failed = !search_messages(ibox, args, outbuf, uid_result);
+ failed = !search_messages(ibox, charset, args, outbuf, uid_result);
o_buffer_send(outbuf, "\r\n", 2);
if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
Index: index-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/index-storage.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- index-storage.h 2 Nov 2002 20:10:21 -0000 1.18
+++ index-storage.h 3 Nov 2002 08:39:44 -0000 1.19
@@ -73,7 +73,7 @@
int *all_found);
int index_storage_fetch(Mailbox *box, MailFetchData *fetch_data,
OBuffer *outbuf, int *all_found);
-int index_storage_search(Mailbox *box, MailSearchArg *args,
+int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args,
OBuffer *outbuf, int uid_result);
#endif
More information about the dovecot-cvs
mailing list