mail-index.h revision a4663ce76645f28d521c7461abecb44537207cb2
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Create index if it doesn't exist */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Update \Recent flag counters */
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen /* Compressing and cache updates are not performed */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* internal: we're creating the index */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Rebuild flag is set while index is being rebuilt or when
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen some error is noticed in the index file. If this flag is set,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen the index shouldn't be used before rebuilding it. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* separate from above, but in same bitmask */
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen (((field) & (DATA_FIELD_BODY | DATA_FIELD_BODYSTRUCTURE | \
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* If binary flags are set, it's not checked whether mail is
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen missing CRs. So this flag may be set as an optimization for
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen regular non-binary mails as well if it's known that it contains
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen valid CR+LF line breaks. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Currently this means with mbox format that message flags have
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen been changed in index, but not written into mbox file yet. */
fcca16701767c6b92227a9ee125de69d257882f6Timo Sirainen /* Mailbox is locked, will abort in secs_left */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Mailbox lock looks stale, will override in secs_left */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Index is locked, will abort in secs_left */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* No errors */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Internal error, see get_error_text() for more information. */
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen /* Index is now in inconsistent state with the previous known state,
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen meaning that the message IDs etc. may have changed - only way to
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen recover this would be to fully close the mailbox and reopen it.
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen With IMAP this would mean a forced disconnection since we can't do
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen forced CLOSE. */
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen /* We ran out of available disk space. */
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen /* Mail index locking timeouted */
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen /* Mailbox locking timeouted */
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainentypedef void mail_lock_notify_callback_t(enum mail_lock_notify_type notify_type,
7bcb308d0e13dfa48b483b0addccd889a77bb598Timo Sirainen /* 0 = version
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen 2 = sizeof(unsigned int),
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen 3 = sizeof(time_t),
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen 4 = sizeof(uoff_t),
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen 5 = MEM_ALIGN_SIZE */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int indexid;
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int sync_id; /* re-mmap() when changed, required only
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen if file size is changed */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int flags;
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* these UIDs may not exist and may not even be unseen */
5069adb2f5b3609fff9a0a705c6edeae56e0030aTimo Sirainen unsigned int indexid;
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int reserved; /* for alignment mostly */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int uid;
5297aa3ceddf3a4ecc09f49c832bc424eff8f906Timo Sirainen unsigned int index_flags; /* enum mail_index_mail_flag */
5297aa3ceddf3a4ecc09f49c832bc424eff8f906Timo Sirainen unsigned int data_fields; /* enum mail_data_field */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen unsigned int data_size; /* including this header */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int field; /* enum mail_data_field */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen char data[MEM_ALIGN_SIZE]; /* variable size */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen (sizeof(struct mail_index_data_record) - MEM_ALIGN_SIZE)
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen (SIZEOF_MAIL_INDEX_DATA + (rec)->full_field_size)
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen /* Note that opening same index twice in the same process is a bad
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen idea since they share the same file locks. As soon one of the
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen indexes is closed, the locks in second index are dropped which
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen especially hurts modify log since it keeps locks all the time. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen int (*open)(struct mail_index *index, enum mail_index_open_flags flags);
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Free index from memory. */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Lock/unlock index. May block. Note that unlocking must not
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen reset error from get_last_error() as unlocking can be done as
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen a cleanup after some other function failed. Index is always
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen mmap()ed after set_lock() succeeds.
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen Trying to change a shared lock into exclusive lock is a fatal
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen error, since it may create a deadlock. Even though operating
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen system should detect it and fail, it's not a good idea to even
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen let it happen. Better ways to do this would be to a) mark the
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen data to be updated later, b) use try_lock() if the update is
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen preferred but not required, c) unlock + lock again, but make
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen sure that won't create race conditions. */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Try locking the index. Returns TRUE if the lock was got and
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen FALSE if lock isn't possible to get currently or some other error
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen occured. Never blocks. */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* If we have to wait for the lock, the given lock notify function
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen is called once in a while. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen void (*set_lock_notify_callback)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Rebuild the whole index. Note that this changes the indexid
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen so all the other files must also be rebuilt after this call.
8d235b34022f0bf0f7db54fdbda2d4fd204ed864Timo Sirainen Index MUST NOT have shared lock, but exclusive lock or no lock at
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen all is fine. Note that this function may leave the index
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen exclusively locked, and always sets index->inconsistent = TRUE. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Verify that the index is valid. If anything invalid is found,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen index is set inconsistent and to be rebuilt at next open.
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen Same locking issues as with rebuild(). */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Synchronize the index with the mailbox. Index must not have shared
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen lock when calling this function. The data_lock_type specifies what
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen lock should be set to data file (mbox file). This function may
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen leave the index in ANY locking state. If changes is non-NULL, it's
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen set to TRUE if any changes were noticed. */
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen int (*sync_and_lock)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen enum mail_lock_type data_lock_type, int *changes);
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Returns the index header (never fails). The index needs to be
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen locked before calling this function, and must be kept locked as
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen long as you keep using the returned structure. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen struct mail_index_header *(*get_header)(struct mail_index *index);
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* sequence -> data lookup. The index needs to be locked before calling
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen this function, and must be kept locked as long as you keep using
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen the returned structure. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen struct mail_index_record *(*lookup)(struct mail_index *index,
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen unsigned int seq);
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Return the next record after specified record, or NULL if it was
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen last record. The index must be locked all the time between
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen lookup() and last next() call. */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen struct mail_index_record *(*next)(struct mail_index *index,
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen /* Find first existing UID in range. Sequence number is also retrieved
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen if seq_r is non-NULL. */
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen struct mail_index_record *(*lookup_uid_range)(struct mail_index *index,
34830cefe1757de0ffca67acdc529d5bc8b06b66Timo Sirainen unsigned int *seq_r);
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Find field from specified record, or NULL if it's not in index.
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen Makes sure that the field ends with \0. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen const char *(*lookup_field)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Find field from specified record, or NULL if it's not in index. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen const void *(*lookup_field_raw)(struct mail_index *index,
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen /* Mark the fields to be cached later. If any of them is already
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen set in hdr->cache_fields, mark the caching to happen next time
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen index is opened. */
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen void (*cache_fields_later)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Open mail file and return it as mmap()ed IStream. If we fail,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen we return NULL and set deleted = TRUE if failure was because the
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen mail was just deleted (ie. not an error). internal_date is set
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if it's non-NULL. */
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct istream *(*open_mail)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Returns internal date of message, or (time_t)-1 if error occured. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen time_t (*get_internal_date)(struct mail_index *index,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Expunge a mail from index. Tree and modifylog is also updated. The
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen index must be exclusively locked before calling this function.
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen If seq is 0, the modify log isn't updated. This is useful if
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen after append() something goes wrong and you wish to delete the
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen mail immediately. If external_change is TRUE, the modify log is
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen always written.
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen Note that the sequence numbers also update immediately after this
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen call, so if you want to delete messages 1..4 just call this
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen function 4 times with seq being 1. */
1fb8ce8b21d0616796ced699b1573b5dd0b61793Timo Sirainen int (*expunge)(struct mail_index *index, struct mail_index_record *rec,
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Update mail flags. The index must be exclusively locked before
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen calling this function. This shouldn't be called in the middle of
7efee0bb408b0d5253e41997857bdda57855cdc7Timo Sirainen update_begin() as it may modify location field. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Append a new record to index. The index must be exclusively
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen locked before calling this function. rec->uid is updated in
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen append_end(). */
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen struct mail_index_record *(*append_begin)(struct mail_index *index);
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen void (*append_abort)(struct mail_index *index,
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen /* Updating fields happens by calling update_begin(), one or more
8255a22cccf3b0ccf38206c594941820ac1c9e00Timo Sirainen update_field()s and finally update_end() which does the actual
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen updating. The index must be exclusively locked all this time.
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen update_begin() and update_field() functions cannot fail.
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen The extra_space parameter for update_field() specifies the amount
fcca16701767c6b92227a9ee125de69d257882f6Timo Sirainen of extra empty space we should leave after the value, so that if
fcca16701767c6b92227a9ee125de69d257882f6Timo Sirainen the field grows in future it could be expanded without copying it
fcca16701767c6b92227a9ee125de69d257882f6Timo Sirainen to end of file. When the field already exists, the extra_space
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen The files may not actually be updated until after you've unlocked
4499995f7029bafd85094694b6a14752ea34c9b3Timo Sirainen int (*update_end)(struct mail_index_update *update);
4499995f7029bafd85094694b6a14752ea34c9b3Timo Sirainen void (*update_field)(struct mail_index_update *update,
4499995f7029bafd85094694b6a14752ea34c9b3Timo Sirainen /* Just remember that full_field_size will be MEM_ALIGNed, so
4499995f7029bafd85094694b6a14752ea34c9b3Timo Sirainen it may differer from the given size parameter. */
4499995f7029bafd85094694b6a14752ea34c9b3Timo Sirainen void (*update_field_raw)(struct mail_index_update *update,
ab7b5b9286104974c2a572a499ccf8b56c5d2955Timo Sirainen /* Returns the last error code. */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen enum mail_index_error (*get_last_error)(struct mail_index *index);
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* Returns the full error message for last error. This message may
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen contain paths etc. so it shouldn't be shown to users. */
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen const char *(*get_last_error_text)(struct mail_index *index);
fcca16701767c6b92227a9ee125de69d257882f6Timo Sirainen/* private: */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen char *dir; /* directory where to place the index files */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen char *mailbox_path; /* file/directory for mailbox location */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen char *custom_flags_dir; /* destination for .customflags file */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen enum mail_data_field default_cache_fields, never_cache_fields;
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int indexid;
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen unsigned int sync_id;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen /* updated whenever exclusive lock is set/unset */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* these counters can be used to check that we've synced the mailbox
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainen after locking it */
2201e2cc1b3f744dac61c2bf8095bcb6b5719540Timo Sirainen /* last mbox sync: */
void *mmap_base;
unsigned int first_recent_uid;
void *lock_notify_context;
unsigned int set_flags;
#ifdef DEV_T_STRUCT
# define MAIL_INDEX_PRIVATE_FILL 0
#define MAIL_INDEX_PRIVATE_FILL \
void *context);
unsigned int seq);
struct mail_index_record *
int external_change);
struct mail_index_update *
void *context);
((struct mail_index_record *) \
((struct mail_index_record *) \
sizeof(struct mail_index_record))
sizeof(struct mail_index_record))
#define INDEX_FILE_MIN_SIZE \
(sizeof(struct mail_index_header) + \