mail-index-open.c revision d3a288c47d1e99627ef3c525c654dc5430443b97
5e0ce63bb65db34d7f48b34bbb5545fa791781c4Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic const char *index_file_prefixes[] =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* main index */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen for (i = 0; index_file_prefixes[i] != NULL; i++) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int read_and_verify_header(int fd, MailIndexHeader *hdr,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* read the header */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (read(fd, hdr, sizeof(MailIndexHeader)) != sizeof(MailIndexHeader))
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* check the compatibility */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen return hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS &&
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen hdr->compat_data[2] == sizeof(unsigned int) &&
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen (!check_version || hdr->compat_data[0] == MAIL_INDEX_VERSION);
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen/* Returns TRUE if we're compatible with given index file. May delete the
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen file if it's from older version. */
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainenstatic int mail_check_compatible_index(MailIndex *index, const char *path)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen index_file_set_syscall_error(index, path, "open()");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen compatible = read_and_verify_header(fd, &hdr, FALSE);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (hdr.compat_data[0] != MAIL_INDEX_VERSION) {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /* version mismatch */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (hdr.compat_data[0] < MAIL_INDEX_VERSION) {
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainen /* of older version, we don't need it anymore */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Returns a file name of compatible index */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic const char *mail_find_index(MailIndex *index)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* first try .imap.index-<hostname> */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen name = t_strconcat(INDEX_FILE_PREFIX "-", my_hostname, NULL);
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen i_snprintf(path, sizeof(path), "%s/%s", index->dir, name);
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen /* then try the generic .imap.index */
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen i_snprintf(path, sizeof(path), "%s/%s", index->dir, name);
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainenstatic int mail_index_open_init(MailIndex *index, int update_recent)
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen /* update \Recent message counters */
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen if (update_recent && hdr->last_nonrecent_uid != hdr->next_uid-1) {
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen /* keep last_recent_uid to next_uid-1 */
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen index->first_recent_uid = index->header->last_nonrecent_uid+1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen index->header->last_nonrecent_uid = index->header->next_uid-1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen index->first_recent_uid = hdr->last_nonrecent_uid+1;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* UID values are getting too high, rebuild index */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (index->lock_type == MAIL_LOCK_EXCLUSIVE) {
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen /* finally reset the modify log marks, fsck or syncing might
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen have deleted some messages, and since we're only just
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen opening the index, there's no need to remember them */
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen if (!mail_modifylog_mark_synced(index->modifylog))
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int index_open_and_fix(MailIndex *index, int update_recent, int fast)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* open/create the index files */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* data file is corrupted, need to rebuild index */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* custom flags file needs to be open before
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen rebuilding index */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (rebuild || (index->header->flags & MAIL_INDEX_FLAG_REBUILD)) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* index is corrupted, rebuild */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* no inconsistency problems while still opening
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (index->header->flags & MAIL_INDEX_FLAG_FSCK) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* index needs fscking */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen if (!fast && (index->header->flags & MAIL_INDEX_FLAG_COMPRESS)) {
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen /* remove deleted blocks from index file */
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
if (failed) {
return FALSE;
return TRUE;
const char **index_path)
return FALSE;
return FALSE;
return FALSE;
return FALSE;
hostpid_init();
return FALSE;
return TRUE;
int update_recent)
return FALSE;
return FALSE;
return TRUE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
return TRUE;
return FALSE;
return FALSE;
if (failed)
return FALSE;
return TRUE;