annotate src/imap/cmd-append.c @ 2670:e24c801dbc09 HEAD

If message was APPENDed with LITERALPLUS and it failed for some reason (eg. mailbox didn't exist), we didn't consume the following message but instead treated it as commands.
author Timo Sirainen <tss@iki.fi>
date Sun, 26 Sep 2004 13:37:03 +0300
parents f8be7a5e273a
children b63b4080c6b2
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);
2460
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
62
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
63 if (client->input_pending)
3accbeb04383 crashfixes
Timo Sirainen <tss@iki.fi>
parents: 2455
diff changeset
64 _client_input(client);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
65 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
66 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
67
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 /* Returns -1 = error, 0 = need more data, 1 = successful. flags and
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 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
70 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
71 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
72 const char **internal_date, uoff_t *msg_size,
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
73 int *nonsync)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 {
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
75 /* [<flags>] */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
76 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
77 *flags = NULL;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
78 else {
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
79 *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
80 args++;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
83 /* [<internal date>] */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
84 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
85 *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
86 else {
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 = 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
88 args++;
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
89 }
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90
1022
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
91 if (args->type != IMAP_ARG_LITERAL_SIZE &&
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
92 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
93 return FALSE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94
1022
09bac2875ed8 Support for LITERAL+ extension.
Timo Sirainen <tss@iki.fi>
parents: 1015
diff changeset
95 *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
96 *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
97 return TRUE;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
100 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
101 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
102 size_t size;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
103
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
104 io_remove(ctx->client->io);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
105 ctx->client->io = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
106
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
107 imap_parser_destroy(ctx->save_parser);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
108
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
109 if (ctx->input != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
110 i_stream_unref(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
111
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
112 if (ctx->save_ctx != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
113 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
114
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
115 if (ctx->t != NULL)
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
116 mailbox_transaction_rollback(ctx->t);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
117
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
118 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
119 mailbox_close(ctx->box);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
120
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
121 (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
122 ctx->client->input_pending = size != 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
123 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
124
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
125 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
126 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
127 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
128 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
129
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
130 (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
131 (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
132 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
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 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
135 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
136 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
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 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
139 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
140
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
141 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
142 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
143 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
144 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
145 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
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
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
148 /* 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
149 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
150 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
151 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
152 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
153
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->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
155 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
156 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
157 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
158 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
159
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
160 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
161 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
162 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
163 struct imap_arg *args;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
164 struct imap_arg_list *flags_list;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
165 struct mail_full_flags flags;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
166 const char *internal_date_str;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
167 time_t internal_date;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
168 int ret, timezone_offset, nonsync;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
169
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
170 /* 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
171 client->input_skip_line = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
172
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
173 /* [<flags>] [<internal date>] <message literal> */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
174 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
175 IMAP_PARSE_FLAG_LITERAL_SIZE, &args);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
176 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
177 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
178 client_send_command_error(client, NULL);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
179 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
180 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
181 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
182 if (ret < 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
183 /* need more data */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
184 return FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
185 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
186
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
187 if (args->type == IMAP_ARG_EOL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
188 /* last message */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
189 enum mailbox_sync_flags sync_flags;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
190
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
191 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
192 /* 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
193 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
194 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
195 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
196
2518
f8be7a5e273a Added sync flags parameter to mailbox_transaction_commit(), so EXPUNGE can
Timo Sirainen <tss@iki.fi>
parents: 2501
diff changeset
197 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
198 ctx->t = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
199 if (ret < 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
200 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
201 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
202 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
203 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
204
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
205 sync_flags = ctx->box == client->mailbox ?
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
206 0 : MAILBOX_SYNC_FLAG_FAST;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
207
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
208 client->input_skip_line = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
209 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
210 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
211 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
212
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
213 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
214 &ctx->msg_size, &nonsync)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
215 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
216 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
217 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
218
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
219 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
220 /* 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
221 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
222 return cmd_append_cancel(ctx, nonsync);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
223 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
224
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
225 if (flags_list != NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
226 if (!client_parse_mail_flags(client, flags_list->args,
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
227 &client->keywords, &flags))
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 } else {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
230 memset(&flags, 0, sizeof(flags));
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
231 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
232
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
233 if (internal_date_str == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
234 /* no time given, default to now. */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
235 internal_date = (time_t)-1;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
236 timezone_offset = 0;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
237 } 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
238 &internal_date, &timezone_offset)) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
239 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
240 return cmd_append_cancel(ctx, nonsync);
2446
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
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
243 if (ctx->msg_size == 0) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
244 /* no message data, abort */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
245 client_send_tagline(client, "NO Append aborted.");
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
246 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
247 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
248 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
249
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
250 if (!nonsync) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
251 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
252 o_stream_flush(client->output);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
253 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
254
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
255 /* 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
256 client->input_skip_line = 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 /* save the mail */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
259 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
260 client->input->v_offset,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
261 ctx->msg_size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
262 ctx->save_ctx = mailbox_save_init(ctx->t, &flags, internal_date,
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
263 timezone_offset, NULL,
2455
d38f3876f3ad Forgot want_mail=TRUE parameter from debugging.
Timo Sirainen <tss@iki.fi>
parents: 2446
diff changeset
264 ctx->input, FALSE);
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
265
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
266 client->command_pending = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
267 client->cmd_func = cmd_append_continue_message;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
268 return cmd_append_continue_message(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
269 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
270
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
271 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
272 {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
273 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
274 size_t size;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
275 int failed;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
276
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
277 if (ctx->save_ctx != NULL) {
2501
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
278 if (mailbox_save_continue(ctx->save_ctx) < 0 ||
b7eec64e0735 Deinitialize command handlers always.
Timo Sirainen <tss@iki.fi>
parents: 2460
diff changeset
279 client->input->closed) {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
280 /* 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
281 from client */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
282 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
283 ctx->save_ctx = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
284 }
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
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
287 if (ctx->save_ctx == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
288 (void)i_stream_read(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
289 (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
290 i_stream_skip(ctx->input, size);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
291 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
292
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
293 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
294 /* finished */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
295 i_stream_unref(ctx->input);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
296 ctx->input = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
297
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
298 if (ctx->save_ctx == NULL) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
299 /* failed above */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
300 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
301 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
302 } else if (client->input->eof) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
303 /* client disconnected */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
304 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
305 mailbox_save_cancel(ctx->save_ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
306 } 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
307 failed = TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
308 client_send_storage_error(client, ctx->storage);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
309 } else {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
310 failed = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
311 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
312 ctx->save_ctx = NULL;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
313
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
314 if (failed) {
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
315 cmd_append_finish(ctx);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
316 return TRUE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
317 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
318
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
319 /* prepare for next message */
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
320 client->command_pending = FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
321 imap_parser_reset(ctx->save_parser);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
322 client->cmd_func = cmd_append_continue_parsing;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
323 return cmd_append_continue_parsing(client);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
324 }
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 return FALSE;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
327 }
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
328
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
329 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
330 {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
331 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
332 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
333
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
334 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
335 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
336
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
337 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
338 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
339 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
340
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
341 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
342 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
343 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
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 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
346 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
347 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
348 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
349 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
350 }
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 box;
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
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 877
diff changeset
354 int cmd_append(struct client *client)
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
355 {
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
356 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
357 struct mailbox_status status;
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
358 const char *mailbox;
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
359
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
360 /* <mailbox> */
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
361 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
362 return FALSE;
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 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
365 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
366 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
367 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
368 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
369
2670
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
370 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
371 &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
372 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
373 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
374 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
375 } else {
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
376 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
377 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
378 }
e24c801dbc09 If message was APPENDed with LITERALPLUS and it failed for some reason (eg.
Timo Sirainen <tss@iki.fi>
parents: 2518
diff changeset
379 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
380 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
381 }
1168
03f1455664d7 Added setting to limit length of custom flag names.
Timo Sirainen <tss@iki.fi>
parents: 1041
diff changeset
382
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
383 io_remove(client->io);
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
384 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
385 client_input, client);
1015
40a327d356de Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
Timo Sirainen <tss@iki.fi>
parents: 988
diff changeset
386
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
387 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
388 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
389
2446
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
390 client->cmd_func = cmd_append_continue_parsing;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
391 client->cmd_context = ctx;
47e1e05cede0 Changed mail saving API to be nonblocking.
Timo Sirainen <tss@iki.fi>
parents: 2427
diff changeset
392 return cmd_append_continue_parsing(client);
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393 }