Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/index/maildir/maildir-copy.c @ 47:306c20092a96 HEAD
Errors in user-specified messagesets are now properly reported back to user.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 27 Aug 2002 06:33:10 +0300 |
parents | 82b7de533f98 |
children | 4716cf66c2cc |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "mail-messageset.h" #include "maildir-storage.h" #include <stdlib.h> #include <unistd.h> typedef struct { MailStorage *storage; const char *dest_maildir; int error; } CopyHardContext; static int copy_hard_func(MailIndex *index, MailIndexRecord *rec, unsigned int seq __attr_unused__, void *context) { CopyHardContext *ctx = context; const char *fname; char src[1024], dest[1024]; /* link the file */ fname = index->lookup_field(index, rec, FIELD_TYPE_LOCATION); i_snprintf(src, sizeof(src), "%s/cur/%s", index->dir, fname); i_snprintf(dest, sizeof(dest), "%s/new/%s", ctx->dest_maildir, fname); if (link(src, dest) == 0) return TRUE; else { if (errno != EXDEV) { mail_storage_set_critical(ctx->storage, "link(%s, %s) " "failed: %m", src, dest); ctx->error = TRUE; } return FALSE; } } static int maildir_copy_with_hardlinks(IndexMailbox *src, IndexMailbox *dest, const char *messageset, int uidset) { CopyHardContext ctx; int ret; if (!src->index->set_lock(src->index, MAIL_LOCK_SHARED)) return mail_storage_set_index_error(src); if (!dest->index->set_lock(dest->index, MAIL_LOCK_EXCLUSIVE)) { (void)src->index->set_lock(src->index, MAIL_LOCK_UNLOCK); return mail_storage_set_index_error(dest); } ctx.storage = src->box.storage; ctx.dest_maildir = dest->index->dir; ctx.error = FALSE; ret = index_messageset_foreach(src, messageset, uidset, copy_hard_func, &ctx) <= 0; if (!dest->index->set_lock(dest->index, MAIL_LOCK_UNLOCK)) { mail_storage_set_index_error(dest); ret = -1; } if (!src->index->set_lock(src->index, MAIL_LOCK_SHARED)) { mail_storage_set_index_error(src); ret = -1; } return ctx.error ? -1 : ret; } int maildir_storage_copy(Mailbox *box, Mailbox *destbox, const char *messageset, int uidset) { IndexMailbox *ibox = (IndexMailbox *) box; if (destbox->readonly) { mail_storage_set_error(box->storage, "Destination mailbox is read-only"); return FALSE; } if (getenv("COPY_WITH_HARDLINKS") != NULL && destbox->storage == box->storage) { /* both source and destination mailbox are in maildirs and copy_with_hardlinks option is on, do it */ switch (maildir_copy_with_hardlinks(ibox, (IndexMailbox *) destbox, messageset, uidset)) { case -1: case -2: return FALSE; case 1: return TRUE; } /* non-fatal hardlinking failure, try the slow way */ } return index_storage_copy(box, destbox, messageset, uidset); }