[dovecot-cvs] dovecot/src/pop3 client.c,1.1,1.2 client.h,1.1,1.2 commands.c,1.1,1.2
cras at procontrol.fi
cras at procontrol.fi
Mon Jan 27 08:44:52 EET 2003
- Previous message: [dovecot-cvs] dovecot/src/pop3 .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 client.c,NONE,1.1 client.h,NONE,1.1 commands.c,NONE,1.1 commands.h,NONE,1.1 common.h,NONE,1.1 mail-storage-callbacks.c,NONE,1.1 main.c,NONE,1.1
- Next message: [dovecot-cvs] dovecot/src/pop3 commands.c,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/pop3
In directory danu:/tmp/cvs-serv26645
Modified Files:
client.c client.h commands.c
Log Message:
Read the sizes of all messages to memory at startup. More failsafe and
faster.
Index: client.c
===================================================================
RCS file: /home/cvs/dovecot/src/pop3/client.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- client.c 27 Jan 2003 05:45:47 -0000 1.1
+++ client.c 27 Jan 2003 06:44:49 -0000 1.2
@@ -37,10 +37,72 @@
o_stream_close(client->output);
}
+static int init_mailbox(struct client *client)
+{
+ struct mail_fetch_context *ctx;
+ struct mail *mail;
+ struct mailbox_status status;
+ const char *messageset;
+ int i, all_found, failed;
+
+ if (!client->mailbox->get_status(client->mailbox,
+ STATUS_MESSAGES | STATUS_UIDVALIDITY,
+ &status)) {
+ client_send_storage_error(client);
+ return FALSE;
+ }
+
+ client->messages_count = status.messages;
+ client->uidvalidity = status.uidvalidity;
+ client->message_sizes = i_new(uoff_t, client->messages_count);
+
+ messageset = t_strdup_printf("1:%u", client->messages_count);
+ for (i = 0; i < 2; i++) {
+ ctx = client->mailbox->fetch_init(client->mailbox,
+ MAIL_FETCH_SIZE,
+ NULL, messageset, FALSE);
+ if (ctx == NULL) {
+ client_send_storage_error(client);
+ return FALSE;
+ }
+
+ client->total_size = 0;
+ failed = FALSE;
+ while ((mail = client->mailbox->fetch_next(ctx)) != NULL) {
+ uoff_t size = mail->get_size(mail);
+
+ if (size == (uoff_t)-1) {
+ failed = TRUE;
+ break;
+ }
+ client->total_size += size;
+
+ i_assert(mail->seq <= client->messages_count);
+ client->message_sizes[mail->seq-1] = size;
+ }
+
+ if (!client->mailbox->fetch_deinit(ctx, &all_found)) {
+ client_send_storage_error(client);
+ return FALSE;
+ }
+
+ if (!failed && all_found)
+ return TRUE;
+
+ /* well, sync and try again */
+ if (!client->mailbox->sync(client->mailbox, TRUE)) {
+ client_send_storage_error(client);
+ return FALSE;
+ }
+ }
+
+ client_send_line(client, "-ERR Couldn't sync mailbox.");
+ return FALSE;
+}
+
struct client *client_create(int hin, int hout, struct mailbox *mailbox)
{
struct client *client;
- struct mailbox_status status;
client = i_new(struct client, 1);
client->input = i_stream_create_file(hin, default_pool,
@@ -64,11 +126,10 @@
i_assert(my_client == NULL);
my_client = client;
- if (!mailbox->get_status(mailbox, STATUS_MESSAGES, &status)) {
+ if (!init_mailbox(client)) {
client_destroy(client);
- return NULL;
+ client = NULL;
}
- client->messages_count = status.messages;
return client;
}
@@ -81,8 +142,8 @@
client->mailbox->close(client->mailbox);
mail_storage_destroy(client->storage);
- if (client->deleted_bitmask != NULL)
- i_free(client->deleted_bitmask);
+ i_free(client->message_sizes);
+ i_free(client->deleted_bitmask);
io_remove(client->io);
@@ -115,6 +176,14 @@
(void)o_stream_send_str(client->output, t_strdup_vprintf(fmt, va));
(void)o_stream_send(client->output, "\r\n", 2);
va_end(va);
+}
+
+void client_send_storage_error(struct client *client)
+{
+ const char *error;
+
+ error = client->storage->get_last_error(client->storage, NULL);
+ client_send_line(client, "-ERR %s", error);
}
static void client_input(void *context)
Index: client.h
===================================================================
RCS file: /home/cvs/dovecot/src/pop3/client.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- client.h 27 Jan 2003 05:45:47 -0000 1.1
+++ client.h 27 Jan 2003 06:44:49 -0000 1.2
@@ -16,6 +16,10 @@
unsigned int bad_counter;
unsigned int messages_count;
+ unsigned int uidvalidity;
+ uoff_t *message_sizes;
+ uoff_t total_size;
+
unsigned char *deleted_bitmask;
unsigned int deleted:1;
@@ -32,6 +36,7 @@
/* Send a line of data to client */
void client_send_line(struct client *client, const char *fmt, ...)
__attr_format__(2, 3);
+void client_send_storage_error(struct client *client);
void clients_init(void);
void clients_deinit(void);
Index: commands.c
===================================================================
RCS file: /home/cvs/dovecot/src/pop3/commands.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- commands.c 27 Jan 2003 05:45:47 -0000 1.1
+++ commands.c 27 Jan 2003 06:44:49 -0000 1.2
@@ -9,14 +9,6 @@
#define MSGS_BITMASK_SIZE(client) \
((client->messages_count + (CHAR_BIT-1)) / CHAR_BIT)
-static void client_send_storage_error(struct client *client)
-{
- const char *error;
-
- error = client->storage->get_last_error(client->storage, NULL);
- client_send_line(client, "-ERR %s", error);
-}
-
static const char *get_msgnum(struct client *client, const char *args,
unsigned int *msgnum)
{
@@ -106,53 +98,25 @@
client_send_line(client, "+OK Marked to be deleted.");
}
-static void list_sizes(struct client *client, unsigned int message)
-{
- struct mail_fetch_context *ctx;
- struct mail *mail;
- const char *messageset;
- int found = FALSE;
-
- if (client->messages_count == 0 && message == 0)
- return;
-
- messageset = message == 0 ?
- t_strdup_printf("1:%u", client->messages_count) :
- t_strdup_printf("%u", message);
-
- ctx = client->mailbox->fetch_init(client->mailbox, MAIL_FETCH_SIZE,
- NULL, messageset, FALSE);
- if (ctx == NULL) {
- client_send_storage_error(client);
- return;
- }
-
- while ((mail = client->mailbox->fetch_next(ctx)) != NULL) {
- uoff_t size = mail->get_size(mail);
-
- client_send_line(client, message == 0 ? "%u %"PRIuUOFF_T :
- "+OK %u %"PRIuUOFF_T, mail->seq, size);
- found = TRUE;
- }
-
- (void)client->mailbox->fetch_deinit(ctx, NULL);
-
- if (!found && message != 0)
- client_send_line(client, "-ERR Message not found.");
-}
-
static void cmd_list(struct client *client, const char *args)
{
+ unsigned int i;
+
if (*args == '\0') {
client_send_line(client, "+OK %u messages:",
client->messages_count);
- list_sizes(client, 0);
+ for (i = 0; i < client->messages_count; i++) {
+ client_send_line(client, "%u %"PRIuUOFF_T,
+ i, client->message_sizes[i]);
+ }
client_send_line(client, ".");
} else {
unsigned int msgnum;
- if (get_msgnum(client, args, &msgnum) != NULL)
- list_sizes(client, msgnum);
+ if (get_msgnum(client, args, &msgnum) != NULL) {
+ client_send_line(client, "+OK %u %"PRIuUOFF_T,
+ msgnum, client->message_sizes[msgnum]);
+ }
}
}
@@ -223,7 +187,6 @@
struct mail_fetch_context *ctx;
struct mail *mail;
struct istream *stream;
- struct message_size hdr_size, body_size;
ctx = client->mailbox->fetch_init(client->mailbox,
MAIL_FETCH_STREAM_HEADER |
@@ -239,15 +202,18 @@
if (mail == NULL)
client_send_line(client, "-ERR Message not found.");
else {
- stream = mail->get_stream(mail, &hdr_size, &body_size);
- message_size_add(&body_size, &hdr_size);
+ stream = mail->get_stream(mail, NULL, NULL);
- client_send_line(client, "+OK %"PRIuUOFF_T" octets",
- body_size.virtual_size);
+ if (max_lines == (uoff_t)-1) {
+ client_send_line(client, "+OK %"PRIuUOFF_T" octets",
+ client->message_sizes[msgnum]);
+ } else {
+ client_send_line(client, "+OK");
+ }
// FIXME: "." lines needs to be escaped
// FIXME: and send only max_lines
- message_send(client->output, stream, &body_size, 0, (uoff_t)-1);
+ client_send_line(client, ".");
}
(void)client->mailbox->fetch_deinit(ctx, NULL);
@@ -273,35 +239,8 @@
static void cmd_stat(struct client *client, const char *args __attr_unused__)
{
- struct mail_fetch_context *ctx;
- struct mail *mail;
- uoff_t size, total_size;
- const char *messageset;
-
- if (client->messages_count == 0) {
- client_send_line(client, "+OK 0 0");
- return;
- }
-
- messageset = t_strdup_printf("1:%u", client->messages_count);
- ctx = client->mailbox->fetch_init(client->mailbox, MAIL_FETCH_SIZE,
- NULL, messageset, FALSE);
- if (ctx == NULL) {
- client_send_storage_error(client);
- return;
- }
-
- total_size = 0;
- while ((mail = client->mailbox->fetch_next(ctx)) != NULL) {
- size = mail->get_size(mail);
- if (size != (uoff_t)-1)
- total_size += size;
- }
-
- (void)client->mailbox->fetch_deinit(ctx, NULL);
-
- client_send_line(client, "+OK %u %"PRIuUOFF_T,
- client->messages_count, total_size);
+ client_send_line(client, "+OK %u %"PRIuUOFF_T, client->
+ messages_count, client->total_size);
}
static void cmd_top(struct client *client, const char *args)
@@ -337,7 +276,8 @@
while ((mail = client->mailbox->fetch_next(ctx)) != NULL) {
client_send_line(client, message == 0 ?
- "%u %u" : "+OK %u %u", mail->seq, mail->uid);
+ "%u %u.%u" : "+OK %u %u.%u",
+ mail->seq, client->uidvalidity, mail->uid);
found = TRUE;
}
- Previous message: [dovecot-cvs] dovecot/src/pop3 .cvsignore,NONE,1.1 Makefile.am,NONE,1.1 client.c,NONE,1.1 client.h,NONE,1.1 commands.c,NONE,1.1 commands.h,NONE,1.1 common.h,NONE,1.1 mail-storage-callbacks.c,NONE,1.1 main.c,NONE,1.1
- Next message: [dovecot-cvs] dovecot/src/pop3 commands.c,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list