Mercurial > dovecot > core-2.2
view src/lib-storage/index/maildir/maildir-copy.c @ 903:fd8888f6f037 HEAD
Naming style changes, finally got tired of most of the typedefs. Also the
previous enum -> macro change reverted so that we don't use the highest bit
anymore, that's incompatible with old indexes so they will be rebuilt.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 05 Jan 2003 15:09:51 +0200 |
parents | 86cf24da85f1 |
children | 411006be3c66 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "index-messageset.h" #include "maildir-index.h" #include "maildir-storage.h" #include "mail-custom-flags.h" #include <stdlib.h> #include <unistd.h> struct copy_hard_context { struct mail_storage *storage; struct index_mailbox *dest; int error; const char **custom_flags; }; static int copy_hard_func(struct mail_index *index, struct mail_index_record *rec, unsigned int client_seq __attr_unused__, unsigned int idx_seq __attr_unused__, void *context) { struct copy_hard_context *ctx = context; enum mail_flags flags; const char *fname; char src[PATH_MAX], dest[PATH_MAX]; flags = rec->msg_flags; if (!index_mailbox_fix_custom_flags(ctx->dest, &flags, ctx->custom_flags)) return FALSE; /* link the file */ fname = index->lookup_field(index, rec, DATA_FIELD_LOCATION); if (str_ppath(src, sizeof(src), index->mailbox_path, "cur/", fname) < 0) { mail_storage_set_critical(ctx->storage, "Filename too long: %s", fname); return FALSE; } fname = maildir_filename_set_flags(maildir_generate_tmp_filename(), flags); if (str_ppath(dest, sizeof(dest), ctx->dest->index->mailbox_path, "new/", fname) < 0) { mail_storage_set_critical(ctx->storage, "Filename too long: %s", fname); return FALSE; } 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(struct index_mailbox *src, struct index_mailbox *dest, const char *messageset, int uidset) { struct copy_hard_context ctx; int ret; if (!index_storage_sync_and_lock(src, TRUE, MAIL_LOCK_SHARED)) return -1; ctx.storage = src->box.storage; ctx.dest = dest; ctx.error = FALSE; ctx.custom_flags = mail_custom_flags_list_get(src->index->custom_flags); ret = index_messageset_foreach(src, messageset, uidset, copy_hard_func, &ctx); (void)index_storage_lock(src, MAIL_LOCK_UNLOCK); return ctx.error ? -1 : ret; } int maildir_storage_copy(struct mailbox *box, struct mailbox *destbox, const char *messageset, int uidset) { struct index_mailbox *ibox = (struct index_mailbox *) box; if (destbox->readonly) { mail_storage_set_error(box->storage, "Destination mailbox is read-only"); return FALSE; } if (getenv("MAILDIR_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, (struct index_mailbox *) destbox, messageset, uidset)) { case 1: return TRUE; case 0: /* non-fatal hardlinking failure, try the slow way */ break; default: return FALSE; } } return index_storage_copy(box, destbox, messageset, uidset); }