79
80
ctx->finished = FALSE;
80
81
ctx->temp_path = i_strdup(path);
81
82
ctx->input = i_stream_create_crlf(input);
82
_ctx->output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
83
o_stream_cork(_ctx->output);
83
_ctx->data.output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
84
o_stream_cork(_ctx->data.output);
95
if (o_stream_send_istream(_ctx->output, ctx->input) < 0) {
96
if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) {
96
97
if (!mail_storage_set_error_from_errno(storage)) {
97
98
mail_storage_set_critical(storage,
98
99
"o_stream_send_istream(%s) failed: %m",
165
167
uint32_t uid = 0;
167
169
if (reply->state == IMAPC_COMMAND_STATE_OK) {
168
if (strcasecmp(reply->resp_text_key, "APPENDUID") == 0)
170
if (reply->resp_text_key != NULL &&
171
strcasecmp(reply->resp_text_key, "APPENDUID") == 0)
169
172
imapc_save_appenduid(ctx->ctx, reply, &uid);
170
173
imapc_save_add_to_index(ctx->ctx, uid);
178
181
"imapc: COPY failed: %s", reply->text_full);
181
imapc_client_stop(ctx->ctx->mbox->storage->client);
184
imapc_client_stop(ctx->ctx->mbox->storage->client->client);
188
imapc_save_noop_callback(const struct imapc_command_reply *reply ATTR_UNUSED,
191
struct imapc_save_cmd_context *ctx = context;
193
/* we don't really care about the reply */
195
imapc_client_stop(ctx->ctx->mbox->storage->client->client);
200
214
static int imapc_save_append(struct imapc_save_context *ctx)
202
216
struct mail_save_context *_ctx = &ctx->ctx;
217
struct mail_save_data *mdata = &_ctx->data;
203
218
struct imapc_command *cmd;
204
219
struct imapc_save_cmd_context sctx;
205
220
struct istream *input;
206
221
const char *flags = "", *internaldate = "";
208
if (_ctx->flags != 0 || _ctx->keywords != NULL) {
223
if (mdata->flags != 0 || mdata->keywords != NULL) {
209
224
string_t *str = t_str_new(64);
211
226
str_append(str, " (");
212
imap_write_flags(str, _ctx->flags & ~MAIL_RECENT, NULL);
213
if (_ctx->keywords != NULL)
214
imapc_append_keywords(str, _ctx->keywords);
227
imap_write_flags(str, mdata->flags & ~MAIL_RECENT, NULL);
228
if (mdata->keywords != NULL)
229
imapc_append_keywords(str, mdata->keywords);
215
230
str_append_c(str, ')');
216
231
flags = str_c(str);
218
if (_ctx->received_date != (time_t)-1) {
233
if (mdata->received_date != (time_t)-1) {
219
234
internaldate = t_strdup_printf(" \"%s\"",
220
imap_to_datetime(_ctx->received_date));
235
imap_to_datetime(mdata->received_date));
238
ctx->mbox->exists_received = FALSE;
223
240
input = i_stream_create_fd(ctx->fd, IO_BLOCK_SIZE, FALSE);
226
cmd = imapc_client_cmd(ctx->mbox->storage->client,
243
cmd = imapc_client_cmd(ctx->mbox->storage->client->client,
227
244
imapc_save_callback, &sctx);
228
245
imapc_command_sendf(cmd, "APPEND %s%1s%1s %p",
229
246
ctx->mbox->box.name, flags, internaldate, input);
230
247
i_stream_unref(&input);
231
248
while (sctx.ret == -2)
232
imapc_storage_run(ctx->mbox->storage);
249
imapc_mailbox_run(ctx->mbox);
251
if (sctx.ret == 0 && ctx->mbox->selected &&
252
!ctx->mbox->exists_received) {
253
/* e.g. Courier doesn't send EXISTS reply before the tagged
254
APPEND reply. That isn't exactly required by the IMAP RFC,
255
but it makes the behavior better. See if NOOP finds
258
cmd = imapc_client_cmd(ctx->mbox->storage->client->client,
259
imapc_save_noop_callback, &sctx);
260
imapc_command_send(cmd, "NOOP");
261
while (sctx.ret == -2)
262
imapc_mailbox_run(ctx->mbox);
241
272
ctx->finished = TRUE;
243
274
if (!ctx->failed) {
244
if (o_stream_flush(_ctx->output) < 0) {
275
if (o_stream_nfinish(_ctx->data.output) < 0) {
245
276
if (!mail_storage_set_error_from_errno(storage)) {
246
277
mail_storage_set_critical(storage,
247
"o_stream_flush(%s) failed: %m",
278
"write(%s) failed: %m", ctx->temp_path);
250
280
ctx->failed = TRUE;
354
385
uint32_t uid = 0;
356
387
if (reply->state == IMAPC_COMMAND_STATE_OK) {
357
if (strcasecmp(reply->resp_text_key, "COPYUID") == 0)
388
if (reply->resp_text_key != NULL &&
389
strcasecmp(reply->resp_text_key, "COPYUID") == 0)
358
390
imapc_save_copyuid(ctx->ctx, reply, &uid);
359
391
imapc_save_add_to_index(ctx->ctx, uid);
389
421
imapc_command_sendf(cmd, "UID COPY %u %s",
390
422
mail->uid, _t->box->name);
391
423
while (sctx.ret == -2)
392
imapc_storage_run(src_mbox->storage);
424
imapc_mailbox_run(src_mbox);
393
425
ctx->finished = TRUE;
426
index_save_context_free(_ctx);
396
429
return mail_storage_copy(_ctx, mail);