[dovecot-cvs]
dovecot/src/imap cmd-copy.c,1.12,1.13 cmd-fetch.c,1.18,1.19
cmd-store.c,1.17,1.18 imap-fetch-body-section.c,1.14,1.15
imap-fetch.c,1.9,1.10 imap-fetch.h,1.3,1.4 imap-search.c,1.3,1.4
imap-thread.c,1.3,1.4
cras at procontrol.fi
cras at procontrol.fi
Thu Aug 7 00:16:03 EEST 2003
Update of /home/cvs/dovecot/src/imap
In directory danu:/tmp/cvs-serv13163/imap
Modified Files:
cmd-copy.c cmd-fetch.c cmd-store.c imap-fetch-body-section.c
imap-fetch.c imap-fetch.h imap-search.c imap-thread.c
Log Message:
Index cache file rewrite. It's not finished yet and mbox support is
completely broken. But it's getting difficult to maintain outside cvs :)
Index: cmd-copy.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-copy.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cmd-copy.c 27 Jul 2003 04:48:32 -0000 1.12
+++ cmd-copy.c 6 Aug 2003 20:15:30 -0000 1.13
@@ -12,7 +12,8 @@
int failed = FALSE;
fetch_ctx = box->fetch_init(box, MAIL_FETCH_STREAM_HEADER |
- MAIL_FETCH_STREAM_BODY, messageset, uidset);
+ MAIL_FETCH_STREAM_BODY, NULL,
+ messageset, uidset);
if (fetch_ctx == NULL)
return FALSE;
Index: cmd-fetch.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-fetch.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cmd-fetch.c 27 Jul 2003 04:48:32 -0000 1.18
+++ cmd-fetch.c 6 Aug 2003 20:15:30 -0000 1.19
@@ -70,7 +70,10 @@
}
if (strncmp(section, "HEADER", 6) == 0) {
- *fetch_data |= MAIL_FETCH_STREAM_HEADER;
+ /* exact header matches could be cached */
+ if (strncmp(section, "HEADER.FIELDS ", 14) != 0)
+ *fetch_data |= MAIL_FETCH_STREAM_HEADER;
+
if (check_header_section(section+6))
return TRUE;
} else if (*section >= '0' && *section <= '9') {
Index: cmd-store.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-store.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cmd-store.c 27 Jul 2003 04:48:32 -0000 1.17
+++ cmd-store.c 6 Aug 2003 20:15:30 -0000 1.18
@@ -96,9 +96,16 @@
/* and update the flags */
box = client->mailbox;
- failed = !box->lock(box, MAILBOX_LOCK_FLAGS | MAILBOX_LOCK_READ);
+ if (!box->is_readonly(box)) {
+ /* read-only, don't every try to get write locking */
+ failed = FALSE;
+ } else {
+ failed = !box->lock(box, MAILBOX_LOCK_FLAGS |
+ MAILBOX_LOCK_READ);
+ }
+
fetch_ctx = failed ? NULL :
- box->fetch_init(box, MAIL_FETCH_FLAGS,
+ box->fetch_init(box, MAIL_FETCH_FLAGS, NULL,
messageset, client->cmd_uid);
if (fetch_ctx == NULL)
failed = TRUE;
Index: imap-fetch-body-section.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-fetch-body-section.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- imap-fetch-body-section.c 4 Jun 2003 15:57:58 -0000 1.14
+++ imap-fetch-body-section.c 6 Aug 2003 20:15:30 -0000 1.15
@@ -20,6 +20,9 @@
#define MAX_HEADER_BUFFER_SIZE (32*1024)
struct fetch_header_field_context {
+ struct imap_fetch_context *fetch_ctx;
+ struct mail *mail;
+
buffer_t *dest;
struct ostream *output;
uoff_t dest_size;
@@ -116,26 +119,6 @@
return ret >= 0;
}
-static const char **get_fields_array(const char *fields)
-{
- const char **field_list, **field;
-
- while (*fields == ' ')
- fields++;
- if (*fields == '(')
- fields++;
-
- field_list = t_strsplit(fields, " )");
-
- /* array ends at ")" element */
- for (field = field_list; *field != NULL; field++) {
- if (strcmp(*field, ")") == 0)
- *field = NULL;
- }
-
- return field_list;
-}
-
static int header_match(const char *const *fields,
const char *name, size_t size)
{
@@ -252,10 +235,16 @@
struct message_header_line *hdr;
if (strncmp(section, "HEADER.FIELDS ", 14) == 0) {
- ctx->fields = get_fields_array(section + 14);
+ ctx->fields = imap_fetch_get_body_fields(section + 14);
ctx->match_func = header_match;
+
+ if (ctx->fetch_ctx->body_fetch_from_cache) {
+ input = ctx->mail->get_headers(ctx->mail, ctx->fields);
+ if (input == NULL)
+ return FALSE;
+ }
} else if (strncmp(section, "HEADER.FIELDS.NOT ", 18) == 0) {
- ctx->fields = get_fields_array(section + 18);
+ ctx->fields = imap_fetch_get_body_fields(section + 18);
ctx->match_func = header_match_not;
} else if (strcmp(section, "MIME") == 0) {
/* Mime-Version + Content-* fields */
@@ -329,18 +318,21 @@
the size first and then send the data directly to output stream. */
memset(&hdr_ctx, 0, sizeof(hdr_ctx));
+ hdr_ctx.mail = mail;
+ hdr_ctx.fetch_ctx = ctx;
hdr_ctx.skip = body->skip;
hdr_ctx.max_size = body->max_size;
hdr_ctx.fix_nuls = !mail->has_no_nuls;
failed = FALSE;
- start_offset = input->v_offset;
+ start_offset = input == NULL ? 0 : input->v_offset;
t_push();
/* first pass, we need at least the size */
if (size->virtual_size > MAX_HEADER_BUFFER_SIZE &&
- body->max_size > MAX_HEADER_BUFFER_SIZE) {
+ body->max_size > MAX_HEADER_BUFFER_SIZE &&
+ !ctx->body_fetch_from_cache) {
if (!fetch_header_fields(input, header_section, &hdr_ctx))
failed = TRUE;
@@ -392,9 +384,13 @@
struct istream *stream;
struct message_size hdr_size;
- stream = mail->get_stream(mail, &hdr_size, NULL);
- if (stream == NULL)
- return FALSE;
+ if (ctx->body_fetch_from_cache)
+ stream = NULL;
+ else {
+ stream = mail->get_stream(mail, &hdr_size, NULL);
+ if (stream == NULL)
+ return FALSE;
+ }
return fetch_header_from(ctx, stream, &hdr_size,
mail, body, body->section);
Index: imap-fetch.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-fetch.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- imap-fetch.c 26 Jul 2003 16:55:11 -0000 1.9
+++ imap-fetch.c 6 Aug 2003 20:15:30 -0000 1.10
@@ -1,6 +1,7 @@
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
+#include "buffer.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
@@ -12,6 +13,31 @@
#include <unistd.h>
+const char *const *imap_fetch_get_body_fields(const char *fields)
+{
+ const char **field_list, **field, **dest;
+
+ while (*fields == ' ')
+ fields++;
+ if (*fields == '(')
+ fields++;
+
+ field_list = t_strsplit(fields, " )");
+
+ /* array ends at ")" element */
+ for (field = dest = field_list; *field != NULL; field++) {
+ if (strcmp(*field, ")") == 0)
+ break;
+ if (**field != '\0') {
+ *dest = *field;
+ dest++;
+ }
+ }
+ *dest = NULL;
+
+ return field_list;
+}
+
static void fetch_uid(struct imap_fetch_context *ctx, struct mail *mail)
{
str_printfa(ctx->str, "UID %u ", mail->uid);
@@ -265,6 +291,10 @@
struct mailbox *box = client->mailbox;
struct imap_fetch_context ctx;
struct mail *mail;
+ struct imap_fetch_body_data *body;
+ const char *null = NULL;
+ const char *const *wanted_headers, *const *arr;
+ buffer_t *buffer;
int all_found;
memset(&ctx, 0, sizeof(ctx));
@@ -277,9 +307,7 @@
if (!box->is_readonly(box)) {
/* If we have any BODY[..] sections, \Seen flag is added for
- all messages */
- struct imap_fetch_body_data *body;
-
+ all messages. */
for (body = bodies; body != NULL; body = body->next) {
if (!body->peek) {
ctx.update_seen = TRUE;
@@ -291,12 +319,34 @@
ctx.update_seen = TRUE;
}
+ /* If we have only BODY[HEADER.FIELDS (...)] fetches, get them
+ separately rather than parsing the full header so mail storage
+ can try to cache them. */
+ ctx.body_fetch_from_cache = TRUE;
+ buffer = buffer_create_dynamic(data_stack_pool, 64, (size_t)-1);
+ for (body = bodies; body != NULL; body = body->next) {
+ if (strncmp(body->section, "HEADER.FIELDS ", 14) != 0) {
+ ctx.body_fetch_from_cache = FALSE;
+ break;
+ }
+
+ arr = imap_fetch_get_body_fields(body->section + 14);
+ while (*arr != NULL) {
+ buffer_append(buffer, arr, sizeof(*arr));
+ arr++;
+ }
+ }
+ buffer_append(buffer, &null, sizeof(null));
+ wanted_headers = !ctx.body_fetch_from_cache ? NULL :
+ buffer_get_data(buffer, NULL);
+
if (ctx.update_seen) {
if (!box->lock(box, MAILBOX_LOCK_FLAGS | MAILBOX_LOCK_READ))
return -1;
}
- ctx.fetch_ctx = box->fetch_init(box, fetch_data, messageset, uidset);
+ ctx.fetch_ctx = box->fetch_init(box, fetch_data, wanted_headers,
+ messageset, uidset);
if (ctx.fetch_ctx == NULL)
ctx.failed = TRUE;
else {
Index: imap-fetch.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-fetch.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- imap-fetch.h 23 Jul 2003 01:44:16 -0000 1.3
+++ imap-fetch.h 6 Aug 2003 20:15:30 -0000 1.4
@@ -33,7 +33,7 @@
int update_seen;
struct mail_full_flags seen_flag;
- int first, failed;
+ int first, failed, body_fetch_from_cache;
};
int imap_fetch(struct client *client,
@@ -45,5 +45,7 @@
int imap_fetch_body_section(struct imap_fetch_context *ctx,
const struct imap_fetch_body_data *body,
struct mail *mail);
+
+const char *const *imap_fetch_get_body_fields(const char *fields);
#endif
Index: imap-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-search.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- imap-search.c 27 Jan 2003 04:23:45 -0000 1.3
+++ imap-search.c 6 Aug 2003 20:15:30 -0000 1.4
@@ -21,20 +21,26 @@
return arg;
}
-#define ARG_NEW(type, value) \
- arg_new(data, args, next_sarg, type, value)
+#define ARG_NEW(type) \
+ arg_new(data, args, next_sarg, type, TRUE, NULL)
+
+#define ARG_NEW_FLAG(type) \
+ arg_new(data, args, next_sarg, type, FALSE, NULL)
+
+#define ARG_NEW_HEADER(type, hdr_name) \
+ arg_new(data, args, next_sarg, type, TRUE, hdr_name)
static int arg_new(struct search_build_data *data, struct imap_arg **args,
struct mail_search_arg **next_sarg,
- enum mail_search_arg_type type, int value)
+ enum mail_search_arg_type type, int have_value,
+ const char *hdr_name)
{
struct mail_search_arg *sarg;
*next_sarg = sarg = search_arg_new(data->pool, type);
- if (value == 0)
+ if (!have_value)
return TRUE;
- /* first arg */
if ((*args)->type == IMAP_ARG_EOL) {
data->error = "Missing parameter for argument";
return FALSE;
@@ -49,23 +55,8 @@
sarg->value.str = str_ucase(IMAP_ARG_STR(*args));
*args += 1;
- /* second arg */
- if (value == 2) {
- if ((*args)->type == IMAP_ARG_EOL) {
- data->error = "Missing parameter for argument";
- return FALSE;
- }
-
- if ((*args)->type != IMAP_ARG_ATOM &&
- (*args)->type != IMAP_ARG_STRING) {
- data->error = "Invalid parameter for argument";
- return FALSE;
- }
-
- sarg->hdr_field_name = sarg->value.str;
- sarg->value.str = str_ucase(IMAP_ARG_STR(*args));
- *args += 1;
- }
+ if (hdr_name != NULL)
+ sarg->hdr_field_name = hdr_name;
return TRUE;
}
@@ -122,40 +113,40 @@
switch (*str) {
case 'A':
if (strcmp(str, "ANSWERED") == 0)
- return ARG_NEW(SEARCH_ANSWERED, 0);
+ return ARG_NEW_FLAG(SEARCH_ANSWERED);
else if (strcmp(str, "ALL") == 0)
- return ARG_NEW(SEARCH_ALL, 0);
+ return ARG_NEW_FLAG(SEARCH_ALL);
break;
case 'B':
if (strcmp(str, "BODY") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_BODY, 1);
+ return ARG_NEW(SEARCH_BODY);
} else if (strcmp(str, "BEFORE") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_BEFORE, 1);
+ return ARG_NEW(SEARCH_BEFORE);
} else if (strcmp(str, "BCC") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_BCC, 1);
+ return ARG_NEW_HEADER(SEARCH_HEADER_ADDRESS, str);
}
break;
case 'C':
if (strcmp(str, "CC") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_CC, 1);
+ return ARG_NEW_HEADER(SEARCH_HEADER_ADDRESS, str);
}
break;
case 'D':
if (strcmp(str, "DELETED") == 0)
- return ARG_NEW(SEARCH_DELETED, 0);
+ return ARG_NEW_FLAG(SEARCH_DELETED);
else if (strcmp(str, "DRAFT") == 0)
- return ARG_NEW(SEARCH_DRAFT, 0);
+ return ARG_NEW_FLAG(SEARCH_DRAFT);
break;
case 'F':
if (strcmp(str, "FLAGGED") == 0)
- return ARG_NEW(SEARCH_FLAGGED, 0);
+ return ARG_NEW_FLAG(SEARCH_FLAGGED);
else if (strcmp(str, "FROM") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_FROM, 1);
+ return ARG_NEW_HEADER(SEARCH_HEADER_ADDRESS, str);
}
break;
case 'H':
@@ -174,43 +165,20 @@
}
key = str_ucase(IMAP_ARG_STR(*args));
-
- if (strcmp(key, "FROM") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_FROM, 1);
- } else if (strcmp(key, "TO") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_TO, 1);
- } else if (strcmp(key, "CC") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_CC, 1);
- } else if (strcmp(key, "BCC") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_BCC, 1);
- } else if (strcmp(key, "SUBJECT") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_SUBJECT, 1);
- } else if (strcmp(key, "IN-REPLY-TO") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_IN_REPLY_TO, 1);
- } else if (strcmp(key, "MESSAGE-ID") == 0) {
- *args += 1;
- return ARG_NEW(SEARCH_MESSAGE_ID, 1);
- } else {
- return ARG_NEW(SEARCH_HEADER, 2);
- }
+ *args += 1;
+ return ARG_NEW_HEADER(SEARCH_HEADER, key);
}
break;
case 'K':
if (strcmp(str, "KEYWORD") == 0) {
/* <flag> */
- return ARG_NEW(SEARCH_KEYWORD, 1);
+ return ARG_NEW(SEARCH_KEYWORD);
}
break;
case 'L':
if (strcmp(str, "LARGER") == 0) {
/* <n> */
- return ARG_NEW(SEARCH_LARGER, 1);
+ return ARG_NEW(SEARCH_LARGER);
}
break;
case 'N':
@@ -260,10 +228,10 @@
return TRUE;
} if (strcmp(str, "ON") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_ON, 1);
+ return ARG_NEW(SEARCH_ON);
} if (strcmp(str, "OLD") == 0) {
/* OLD == NOT RECENT */
- if (!ARG_NEW(SEARCH_RECENT, 0))
+ if (!ARG_NEW_FLAG(SEARCH_RECENT))
return FALSE;
(*next_sarg)->not = TRUE;
@@ -272,71 +240,71 @@
break;
case 'R':
if (strcmp(str, "RECENT") == 0)
- return ARG_NEW(SEARCH_RECENT, 0);
+ return ARG_NEW_FLAG(SEARCH_RECENT);
break;
case 'S':
if (strcmp(str, "SEEN") == 0)
- return ARG_NEW(SEARCH_SEEN, 0);
+ return ARG_NEW_FLAG(SEARCH_SEEN);
else if (strcmp(str, "SUBJECT") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_SUBJECT, 1);
+ return ARG_NEW_HEADER(SEARCH_HEADER, str);
} else if (strcmp(str, "SENTBEFORE") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_SENTBEFORE, 1);
+ return ARG_NEW(SEARCH_SENTBEFORE);
} else if (strcmp(str, "SENTON") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_SENTON, 1);
+ return ARG_NEW(SEARCH_SENTON);
} else if (strcmp(str, "SENTSINCE") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_SENTSINCE, 1);
+ return ARG_NEW(SEARCH_SENTSINCE);
} else if (strcmp(str, "SINCE") == 0) {
/* <date> */
- return ARG_NEW(SEARCH_SINCE, 1);
+ return ARG_NEW(SEARCH_SINCE);
} else if (strcmp(str, "SMALLER") == 0) {
/* <n> */
- return ARG_NEW(SEARCH_SMALLER, 1);
+ return ARG_NEW(SEARCH_SMALLER);
}
break;
case 'T':
if (strcmp(str, "TEXT") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_TEXT, 1);
+ return ARG_NEW(SEARCH_TEXT);
} else if (strcmp(str, "TO") == 0) {
/* <string> */
- return ARG_NEW(SEARCH_TO, 1);
+ return ARG_NEW_HEADER(SEARCH_HEADER_ADDRESS, str);
}
break;
case 'U':
if (strcmp(str, "UID") == 0) {
/* <message set> */
- return ARG_NEW(SEARCH_UID, 1);
+ return ARG_NEW(SEARCH_UID);
} else if (strcmp(str, "UNANSWERED") == 0) {
- if (!ARG_NEW(SEARCH_ANSWERED, 0))
+ if (!ARG_NEW_FLAG(SEARCH_ANSWERED))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
} else if (strcmp(str, "UNDELETED") == 0) {
- if (!ARG_NEW(SEARCH_DELETED, 0))
+ if (!ARG_NEW_FLAG(SEARCH_DELETED))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
} else if (strcmp(str, "UNDRAFT") == 0) {
- if (!ARG_NEW(SEARCH_DRAFT, 0))
+ if (!ARG_NEW_FLAG(SEARCH_DRAFT))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
} else if (strcmp(str, "UNFLAGGED") == 0) {
- if (!ARG_NEW(SEARCH_FLAGGED, 0))
+ if (!ARG_NEW_FLAG(SEARCH_FLAGGED))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
} else if (strcmp(str, "UNKEYWORD") == 0) {
- if (!ARG_NEW(SEARCH_KEYWORD, 0))
+ if (!ARG_NEW_FLAG(SEARCH_KEYWORD))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
} else if (strcmp(str, "UNSEEN") == 0) {
- if (!ARG_NEW(SEARCH_SEEN, 0))
+ if (!ARG_NEW_FLAG(SEARCH_SEEN))
return FALSE;
(*next_sarg)->not = TRUE;
return TRUE;
@@ -345,7 +313,7 @@
default:
if (*str == '*' || (*str >= '0' && *str <= '9')) {
/* <message-set> */
- if (!ARG_NEW(SEARCH_SET, 0))
+ if (!ARG_NEW_FLAG(SEARCH_SET))
return FALSE;
(*next_sarg)->value.str = str;
Index: imap-thread.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-thread.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- imap-thread.c 27 Jan 2003 04:23:45 -0000 1.3
+++ imap-thread.c 6 Aug 2003 20:15:30 -0000 1.4
@@ -103,7 +103,7 @@
struct mail_search_arg *args, enum mail_thread_type type)
{
static const char *wanted_headers[] = {
- "message-id", "in-reply-to", "references",
+ "message-id", "in-reply-to", "references", "subject",
NULL
};
struct thread_context *ctx;
More information about the dovecot-cvs
mailing list