annotate src/imap/cmd-append.c @ 3131:e139dcb1744d HEAD

And a non-crashing fix.
author Timo Sirainen <tss@iki.fi>
date Mon, 31 Jan 2005 20:19:39 +0200
parents d14b7e7943c3
children fbe844061fe2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (C) 2002 Timo Sirainen */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "common.h"
117
97d0b9fcc18a APPEND was broken.
Timo Sirainen <tss@iki.fi>
parents: 0
diff changeset
4 #include "ioloop.h"
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
5 #include "istream.h"
764
f57c52738f90 Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents: 546
diff changeset
6 #include "ostream.h"
2190
755ec9442a58 mailbox_save() and mailbox_copy() functions can now return the saved mail so
Timo Sirainen <tss@iki.fi>
parents: 1958
diff changeset
7 #include "str.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "commands.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "imap-parser.h"
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents: 117
diff changeset
10 #include "imap-date.h"
1041
47ecd950a702 some header file cleanups
Timo Sirainen <tss@iki.fi>
parents: 1023
diff changeset
11 #include "mail-storage.h"
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 450
diff changeset
13 #include <sys/time.h>
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 450
diff changeset
14
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
15 struct cmd_append_context {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
16 struct client *client;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
17 struct mail_storage *storage;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
18 struct mailbox *box;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
19 struct mailbox_transaction_context *t;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
20
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
21 struct istream *input;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
22 uoff_t msg_size;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
23
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
24 struct imap_parser *save_parser;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
25 struct mail_save_context *save_ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
26 };
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
27
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
28 static int cmd_append_continue_message(struct client *client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
29
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
30 static void client_input(void *context)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
31 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
32 struct client *client = context;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
33
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
34 client->last_input = ioloop_time;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
35
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
36 switch (i_stream_read(client->input)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
37 case -1:
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
38 /* disconnected */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
39 client_destroy(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
40 return;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
41 case -2:
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
42 if (client->command_pending) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
43 /* message data, this is handled internally by
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
44 mailbox_save_continue() */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
45 break;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
46 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
47
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
48 /* parameter word is longer than max. input buffer size.
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
49 this is most likely an error, so skip the new data
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
50 until newline is found. */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
51 client->input_skip_line = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
52
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
53 client_send_command_error(client, "Too long argument.");
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
54 _client_reset_command(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
55 break;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
56 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
57
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
58 if (client->cmd_func(client)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
59 /* command execution was finished */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
60 client->bad_counter = 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
61 _client_reset_command(client);
2878
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
62 o_stream_set_flush_callback(client->output,
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
63 _client_output, client);
2460
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
64
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
65 if (client->input_pending)
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
66 _client_input(client);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
67 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
68 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
69
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 /* Returns -1 = error, 0 = need more data, 1 = successful. flags and
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 internal_date may be NULL as a result, but mailbox and msg_size are always
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 set when successful. */
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
73 static int validate_args(struct imap_arg *args, struct imap_arg_list **flags,
1022
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
74 const char **internal_date, uoff_t *msg_size,
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
75 int *nonsync)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 {
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
77 /* [<flags>] */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
78 if (args->type != IMAP_ARG_LIST)
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
79 *flags = NULL;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
80 else {
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
81 *flags = IMAP_ARG_LIST(args);
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
82 args++;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
85 /* [<internal date>] */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
86 if (args->type != IMAP_ARG_STRING)
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
87 *internal_date = NULL;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
88 else {
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
89 *internal_date = IMAP_ARG_STR(args);
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
90 args++;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
91 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92
1022
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
93 if (args->type != IMAP_ARG_LITERAL_SIZE &&
2731
b63b4080c6b2 Handle failures without crashing
Timo Sirainen <tss@iki.fi>
parents: 2670
diff changeset
94 args->type != IMAP_ARG_LITERAL_SIZE_NONSYNC) {
b63b4080c6b2 Handle failures without crashing
Timo Sirainen <tss@iki.fi>
parents: 2670
diff changeset
95 *nonsync = FALSE;
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
96 return FALSE;
2731
b63b4080c6b2 Handle failures without crashing
Timo Sirainen <tss@iki.fi>
parents: 2670
diff changeset
97 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98
1022
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
99 *nonsync = args->type == IMAP_ARG_LITERAL_SIZE_NONSYNC;
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
100 *msg_size = IMAP_ARG_LITERAL_SIZE(args);
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
101 return TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
104 static void cmd_append_finish(struct cmd_append_context *ctx)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
105 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
106 size_t size;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
107
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
108 io_remove(ctx->client->io);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
109 ctx->client->io = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
110
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
111 imap_parser_destroy(ctx->save_parser);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
112
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
113 if (ctx->input != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
114 i_stream_unref(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
115
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
116 if (ctx->save_ctx != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
117 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
118
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
119 if (ctx->t != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
120 mailbox_transaction_rollback(ctx->t);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
121
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
122 if (ctx->box != ctx->client->mailbox && ctx->box != NULL)
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
123 mailbox_close(ctx->box);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
124
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
125 (void)i_stream_get_data(ctx->client->input, &size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
126 ctx->client->input_pending = size != 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
127 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
128
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
129 static int cmd_append_continue_cancel(struct client *client)
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
130 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
131 struct cmd_append_context *ctx = client->cmd_context;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
132 size_t size;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
133
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
134 (void)i_stream_read(ctx->input);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
135 (void)i_stream_get_data(ctx->input, &size);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
136 i_stream_skip(ctx->input, size);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
137
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
138 if (ctx->input->v_offset == ctx->msg_size || ctx->input->closed) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
139 cmd_append_finish(ctx);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
140 return TRUE;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
141 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
142 return FALSE;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
143 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
144
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
145 static int cmd_append_cancel(struct cmd_append_context *ctx, int nonsync)
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
146 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
147 if (!nonsync) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
148 cmd_append_finish(ctx);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
149 return TRUE;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
150 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
151
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
152 /* we have to read the nonsynced literal so we don't treat the message
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
153 data as commands. */
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
154 ctx->input = i_stream_create_limit(default_pool, ctx->client->input,
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
155 ctx->client->input->v_offset,
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
156 ctx->msg_size);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
157
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
158 ctx->client->command_pending = TRUE;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
159 ctx->client->cmd_func = cmd_append_continue_cancel;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
160 ctx->client->cmd_context = ctx;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
161 return cmd_append_continue_cancel(ctx->client);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
162 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
163
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
164 static int cmd_append_continue_parsing(struct client *client)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
165 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
166 struct cmd_append_context *ctx = client->cmd_context;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
167 struct imap_arg *args;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
168 struct imap_arg_list *flags_list;
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
169 enum mail_flags flags;
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
170 const char *const *keywords_list;
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
171 struct mail_keywords *keywords;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
172 const char *internal_date_str;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
173 time_t internal_date;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
174 int ret, timezone_offset, nonsync;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
175
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
176 /* if error occurs, the CRLF is already read. */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
177 client->input_skip_line = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
178
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
179 /* [<flags>] [<internal date>] <message literal> */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
180 ret = imap_parser_read_args(ctx->save_parser, 0,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
181 IMAP_PARSE_FLAG_LITERAL_SIZE, &args);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
182 if (ret == -1) {
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
183 if (ctx->box != NULL)
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
184 client_send_command_error(client, NULL);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
185 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
186 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
187 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
188 if (ret < 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
189 /* need more data */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
190 return FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
191 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
192
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
193 if (args->type == IMAP_ARG_EOL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
194 /* last message */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
195 enum mailbox_sync_flags sync_flags;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
196
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
197 if (ctx->box == NULL) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
198 /* we failed earlier, error message is sent */
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
199 cmd_append_finish(ctx);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
200 return TRUE;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
201 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
202
2518
f8be7a5e273a Added sync flags parameter to mailbox_transaction_commit(), so EXPUNGE can
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
203 ret = mailbox_transaction_commit(ctx->t, 0);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
204 ctx->t = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
205 if (ret < 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
206 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
207 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
208 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
209 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
210
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
211 sync_flags = ctx->box == client->mailbox ?
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
212 0 : MAILBOX_SYNC_FLAG_FAST;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
213
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
214 client->input_skip_line = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
215 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
216 return cmd_sync(client, sync_flags, "OK Append completed.");
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
217 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
218
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
219 if (!validate_args(args, &flags_list, &internal_date_str,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
220 &ctx->msg_size, &nonsync)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
221 client_send_command_error(client, "Invalid arguments.");
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
222 return cmd_append_cancel(ctx, nonsync);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
223 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
224
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
225 if (ctx->box == NULL) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
226 /* we failed earlier, make sure we just eat nonsync-literal
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
227 if it's given. */
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
228 return cmd_append_cancel(ctx, nonsync);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
229 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
230
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
231 if (flags_list != NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
232 if (!client_parse_mail_flags(client, flags_list->args,
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
233 &flags, &keywords_list))
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
234 return cmd_append_cancel(ctx, nonsync);
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
235 keywords = keywords_list == NULL ? NULL :
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
236 mailbox_keywords_create(ctx->t, keywords_list);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
237 } else {
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
238 flags = 0;
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
239 keywords = NULL;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
240 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
241
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
242 if (internal_date_str == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
243 /* no time given, default to now. */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
244 internal_date = (time_t)-1;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
245 timezone_offset = 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
246 } else if (!imap_parse_datetime(internal_date_str,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
247 &internal_date, &timezone_offset)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
248 client_send_tagline(client, "BAD Invalid internal date.");
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
249 return cmd_append_cancel(ctx, nonsync);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
250 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
251
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
252 if (ctx->msg_size == 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
253 /* no message data, abort */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
254 client_send_tagline(client, "NO Append aborted.");
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
255 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
256 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
257 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
258
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
259 if (!nonsync) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
260 o_stream_send(client->output, "+ OK\r\n", 6);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
261 o_stream_flush(client->output);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
262 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
263
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
264 /* after literal comes CRLF, if we fail make sure we eat it away */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
265 client->input_skip_line = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
266
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
267 /* save the mail */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
268 ctx->input = i_stream_create_limit(default_pool, client->input,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
269 client->input->v_offset,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
270 ctx->msg_size);
3016
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
271 ctx->save_ctx = mailbox_save_init(ctx->t, flags, keywords,
61c8d205d887 Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents: 2878
diff changeset
272 internal_date, timezone_offset, NULL,
2455
d38f3876f3ad Forgot want_mail=TRUE parameter from debugging.
Timo Sirainen <tss@iki.fi>
parents: 2446
diff changeset
273 ctx->input, FALSE);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
274
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
275 client->command_pending = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
276 client->cmd_func = cmd_append_continue_message;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
277 return cmd_append_continue_message(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
278 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
279
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
280 static int cmd_append_continue_message(struct client *client)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
281 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
282 struct cmd_append_context *ctx = client->cmd_context;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
283 size_t size;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
284 int failed;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
285
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
286 if (ctx->save_ctx != NULL) {
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
287 if (mailbox_save_continue(ctx->save_ctx) < 0 ||
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
288 client->input->closed) {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
289 /* we still have to finish reading the message
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
290 from client */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
291 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
292 ctx->save_ctx = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
293 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
294 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
295
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
296 if (ctx->save_ctx == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
297 (void)i_stream_read(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
298 (void)i_stream_get_data(ctx->input, &size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
299 i_stream_skip(ctx->input, size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
300 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
301
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
302 if (ctx->input->v_offset == ctx->msg_size || ctx->input->closed) {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
303 /* finished */
3131
e139dcb1744d And a non-crashing fix.
Timo Sirainen <tss@iki.fi>
parents: 3130
diff changeset
304 failed = ctx->input->closed;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
305 i_stream_unref(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
306 ctx->input = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
307
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
308 if (ctx->save_ctx == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
309 /* failed above */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
310 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
311 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
312 } else if (client->input->eof) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
313 /* client disconnected */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
314 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
315 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
316 } else if (mailbox_save_finish(ctx->save_ctx, NULL) < 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
317 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
318 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
319 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
320 ctx->save_ctx = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
321
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
322 if (failed) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
323 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
324 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
325 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
326
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
327 /* prepare for next message */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
328 client->command_pending = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
329 imap_parser_reset(ctx->save_parser);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
330 client->cmd_func = cmd_append_continue_parsing;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
331 return cmd_append_continue_parsing(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
332 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
333
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
334 return FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
335 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
336
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
337 static struct mailbox *get_mailbox(struct client *client, const char *name)
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
338 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
339 struct mail_storage *storage;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
340 struct mailbox *box;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
341
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
342 if (!client_verify_mailbox_name(client, name, TRUE, FALSE))
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
343 return NULL;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
344
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
345 storage = client_find_storage(client, &name);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
346 if (storage == NULL)
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
347 return NULL;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
348
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
349 if (client->mailbox != NULL &&
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
350 mailbox_name_equals(mailbox_get_name(client->mailbox), name))
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
351 return client->mailbox;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
352
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
353 box = mailbox_open(storage, name, MAILBOX_OPEN_FAST |
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
354 MAILBOX_OPEN_KEEP_RECENT);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
355 if (box == NULL) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
356 client_send_storage_error(client, storage);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
357 return NULL;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
358 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
359 return box;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
360 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
361
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 877
diff changeset
362 int cmd_append(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
363 {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
364 struct cmd_append_context *ctx;
1168
03f1455664d7 Added setting to limit length of custom flag names.
Timo Sirainen <tss@iki.fi>
parents: 1041
diff changeset
365 struct mailbox_status status;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
366 const char *mailbox;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
367
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
368 /* <mailbox> */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
369 if (!client_read_string_args(client, 1, &mailbox))
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
370 return FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
371
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
372 ctx = p_new(client->cmd_pool, struct cmd_append_context, 1);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
373 ctx->client = client;
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
374 ctx->box = get_mailbox(client, mailbox);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
375 if (ctx->box != NULL) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
376 ctx->storage = mailbox_get_storage(ctx->box);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
377
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
378 if (mailbox_get_status(ctx->box, STATUS_KEYWORDS,
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
379 &status) < 0) {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
380 client_send_storage_error(client, ctx->storage);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
381 mailbox_close(ctx->box);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
382 ctx->box = NULL;
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
383 } else {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
384 client_save_keywords(&client->keywords, status.keywords,
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
385 status.keywords_count);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
386 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
387 ctx->t = ctx->box == NULL ? NULL :
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
388 mailbox_transaction_begin(ctx->box, FALSE);
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
389 }
1168
03f1455664d7 Added setting to limit length of custom flag names.
Timo Sirainen <tss@iki.fi>
parents: 1041
diff changeset
390
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
391 io_remove(client->io);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
392 client->io = io_add(i_stream_get_fd(client->input), IO_READ,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
393 client_input, client);
2878
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
394 /* append is special because we're only waiting on client input, not
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
395 client output, so disable the standard output handler until we're
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
396 finished */
904c31d74acc APPEND was using all CPU.
Timo Sirainen <tss@iki.fi>
parents: 2731
diff changeset
397 o_stream_set_flush_callback(client->output, NULL, NULL);
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
398
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
399 ctx->save_parser = imap_parser_create(client->input, client->output,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
400 imap_max_line_length);
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
401
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
402 client->cmd_func = cmd_append_continue_parsing;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
403 client->cmd_context = ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
404 return cmd_append_continue_parsing(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405 }