mail-messageset.c revision 4f08c1d64625ab2c0dda7f5793b539852238d19c
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
45155bb1250cf5a120278f349465aded513a100fTimo Sirainenstatic unsigned int get_next_number(const char **str)
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen unsigned int num;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainenstatic int mail_index_foreach(MailIndex *index,
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen const char **error)
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen const unsigned int *expunges;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* Second sequence can't be smaller than first - we could swap
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen them but I think it's a bug in client if it does this,
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen and better complain about it immediately than later let
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen them wonder why it doesn't work with other imapds.. */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen *error = t_strdup_printf("Invalid messageset range: %u > %u",
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen /* get list of expunged messages in our range. the expunges_before
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen can be used to calculate the current real sequence position */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen expunges = mail_modifylog_seq_get_expunges(index->modifylog, seq, seq2,
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* Reset index errors, since we later rely on it to check if failed */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen /* get the first non-expunged message. note that if all messages
d7cd49f01fad7c87c5a0865ebf54a548275e9feeTimo Sirainen were expunged in the range, this points outside wanted range. */
d7cd49f01fad7c87c5a0865ebf54a548275e9feeTimo Sirainen rec = index->lookup(index, seq - expunges_before);
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen /* skip expunged sequences */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen while (*expunges != 0 && *expunges < rec->uid) {
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen if (rec == NULL && index->get_last_error(index) != NULL) {
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* error occured */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainenint mail_index_messageset_foreach(MailIndex *index, const char *messageset,
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen const char **error)
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen /* no messages in mailbox */
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen /* last message */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen /* first:last range */
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen "messageset: ",
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen /* too large .. ignore silently */
e3a838c80f54f024115fade93c6c87a0998f1fabTimo Sirainen *error = t_strdup_printf("Unexpected char '%c' "
e3a838c80f54f024115fade93c6c87a0998f1fabTimo Sirainen "with messageset: %s",
4b6ddd3770c8484da7308032b75fc93b91aa1b49Timo Sirainen /* too large .. ignore silently */
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainenstatic int mail_index_uid_foreach(MailIndex *index,
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainen const char **error)
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainen const unsigned int *expunges;
6e8ad595d0603295f57bef576da8a3a00b55c5e2Timo Sirainen unsigned int seq;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* not allowed - see mail_index_foreach() */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen *error = t_strdup_printf("Invalid uidset range: %u > %u",
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* get list of expunged messages in our range. */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen expunges = mail_modifylog_uid_get_expunges(index->modifylog, uid, uid2);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* skip expunged messages at the beginning */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* all were expunged */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* since we skipped the known expunged messages at the beginning
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen and our UIDs are contiguously allocated, the first hash lookup
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen _should_ work.. */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen if (pos + sizeof(MailIndexRecord) > index->mmap_length) {
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen /* hash is corrupted */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen index_set_error(index, "Corrupted hash for index %s: "
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen "lookup returned offset outside range",
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen index->set_flags |= MAIL_INDEX_FLAG_REBUILD_HASH;
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen rec = (MailIndexRecord *) ((char *) index->mmap_base + pos);
ab1236617440e654d5c5a043b677512714b788ddTimo Sirainen /* hash is corrupted */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen index_set_error(index, "Corrupted hash for index %s: "
f8a78c816b4dbfda42f13d8ee152e0cdb28c6a4aTimo Sirainen "lookup returned offset to "
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen index->set_flags |= MAIL_INDEX_FLAG_REBUILD_HASH;
ccef83820a01bb37ad48653a05a9c5aa6560826aTimo Sirainen /* ..however if for any reason it doesn't,
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen still handle it properly */
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen rec = index->lookup_uid_range(index, uid+1, uid2);
71f1783adc89b4fe3588c72b23e059b320da8fadTimo Sirainen while (rec != NULL && rec->uid <= uid2 && seq <= max_sequence) {
71f1783adc89b4fe3588c72b23e059b320da8fadTimo Sirainen while (*expunges != 0 && *expunges < rec->uid) {
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen if (rec == NULL && index->get_last_error(index) != NULL) {
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen /* error occured */
f30577ff7cf29858f1878abe963b4f40a436434fTimo Sirainen return !expunges_found && uid == uid2 ? 1 : 2;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint mail_index_uidset_foreach(MailIndex *index, const char *uidset,
ba90e657bc68a72ab3b3021e2f4a874fac9965baTimo Sirainen const char **error)
const char *input;
if (messages_count == 0) {
input++;
if (uid == 0) {
input++;
if (uid2 == 0) {
input++;
input++;
if (ret <= 0)
return ret;