maildir-copy.c revision 721b683078dab7a46e2a42cfcb81c7d066b57dea
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic int do_hardlink(struct maildir_mailbox *mbox, const char *path,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_error(STORAGE(mbox->storage),
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen "Not enough disk space");
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_storage_set_critical(STORAGE(mbox->storage),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "link(%s, %s) failed: %m",
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenmaildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen enum mail_flags flags, struct mail_keywords *keywords,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen t->save_ctx = maildir_save_transaction_init(t);
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen /* don't allow caller to specify recent flag */
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen /* the generated filename is _always_ unique, so we don't bother
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen trying to check if it already exists */
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen dest_fname = maildir_generate_tmp_filename(&ioloop_timeval);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (keywords == NULL || keywords->count == 0) {
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen /* no keywords, hardlink directly to destination */
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen fname = maildir_filename_set_flags(NULL, dest_fname,
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen /* keywords, hardlink to tmp/ with basename and later when we
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen have uidlist locked, move it to new/cur. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen t_strconcat(dest_mbox->path, "/tmp/", dest_fname, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maildir_file_do(src_mbox, mail->uid, do_hardlink, &do_ctx) < 0)
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen /* couldn't copy with hardlinking, fallback to copying */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (keywords == NULL || keywords->count == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* hardlinked to destination, set hardlinked-flag */
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen /* hardlinked to tmp/, treat as normal copied mail */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq = maildir_save_add(t, dest_fname, flags, keywords,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint maildir_copy(struct mailbox_transaction_context *_t, struct mail *mail,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen enum mail_flags flags, struct mail_keywords *keywords,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->ictx.ibox;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen mail->box->storage == mbox->ibox.box.storage) {
4b41116563110d00330896a568eff1078c382827Timo Sirainen /* non-fatal hardlinking failure, try the slow way */