sdbox-copy.c revision 7f735cb86b2d8abd8f230089065eacfc24e9e5d6
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainensdbox_file_copy_attachments(struct sdbox_file *src_file,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct dbox_storage *src_storage = src_file->file.storage;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen struct dbox_storage *dest_storage = dest_file->file.storage;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen const char *extrefs_line, *src, *dest, *dest_relpath;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* no attachments in source storage */
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen /* different attachment dirs between storages.
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi have to copy the slow way. */
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen if ((ret = sdbox_file_get_attachments(&src_file->file,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen pool = pool_alloconly_create("sdbox attachments copy", 1024);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (!dbox_attachment_parse_extref(extrefs_line, pool, &extrefs)) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mail_storage_set_critical(&dest_storage->storage,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen "Can't copy %s with corrupted extref metadata: %s",
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen pool_alloconly_create("sdbox attachment copy paths", 512);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen p_array_init(&dest_file->attachment_paths, dest_file->attachment_pool,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen src = t_strdup_printf("%s/%s", dest_storage->attachment_dir,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen sdbox_file_attachment_relpath(src_file, extref->path));
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen dest_relpath = p_strconcat(dest_file->attachment_pool,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen dest = t_strdup_printf("%s/%s", dest_storage->attachment_dir,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if (fs_link(dest_storage->attachment_fs, src, dest) < 0) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mail_storage_set_critical(&dest_storage->storage, "%s",
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainensdbox_copy_hardlink(struct mail_save_context *_ctx, struct mail *mail)
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen (struct sdbox_mailbox *)_ctx->transaction->box;
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen if (strcmp(mail->box->storage->name, SDBOX_STORAGE_NAME) == 0)
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi /* Source storage isn't sdbox, can't hard link */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen src_file = sdbox_file_init(src_mbox, mail->uid);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen ret = nfs_safe_link(src_path, dest_file->cur_path, FALSE);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (ret < 0 && errno == ENOENT && src_file->alt_path != NULL) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen ret = nfs_safe_link(src_path, dest_file->cur_path, FALSE);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen "link(%s, %s) failed: %m",
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen ret = sdbox_file_copy_attachments((struct sdbox_file *)src_file,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen sdbox_file_unlink_aborted_save((struct sdbox_file *)dest_file);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen index_copy_cache_fields(_ctx, mail, ctx->seq);
a18e2525cb076066784967d6c8118a01dd38ac6bTimo Sirainenint sdbox_copy(struct mail_save_context *_ctx, struct mail *mail)
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct mailbox_transaction_context *_t = _ctx->transaction;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)_t->box;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (mail_storage_copy_can_use_hardlink(mail->box, &mbox->box)) {
a01faca549a403b2eda938cea0b1fb76c3ff44b6Aki Tuomi if (ret != 0) {
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen /* non-fatal hardlinking failure, try the slow way */