mail-index.c revision 0cfdf8ba03034ffe98abe73c21fdb69e5c0a4509
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2003-2014 Dovecot authors, see the included COPYING file */
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen hash_table_create(&index->keywords_hash, index->keywords_pool, 0,
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen index->log = mail_transaction_log_alloc(index);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenvoid mail_index_free(struct mail_index **_index)
ab1b9a793d57a60c230a41f65f1a25d52c026233Timo Sirainenvoid mail_index_set_fsync_mode(struct mail_index *index,
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen mode_t mode, gid_t gid, const char *gid_origin)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid mail_index_set_lock_method(struct mail_index *index,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen index->max_lock_timeout_secs = max_timeout_secs;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0)
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen i_panic("mail_index_ext_register(%s): Invalid name", name);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (default_record_size != 0 && default_record_align == 0) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (mail_index_ext_lookup(index, name, &ext_id))
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen rext.name = p_strdup(index->extension_pool, name);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen rext.index_idx = array_count(&index->extensions);
5fbf8719b9ef072295c16bc4492f9f0ece92117dTimo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen const struct mail_index_registered_ext *extensions;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int i, count;
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen extensions = array_get(&index->extensions, &count);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen for (i = 0; i < count; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
5fbf8719b9ef072295c16bc4492f9f0ece92117dTimo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen rext->expunge_handler_call_always = call_always;
a0b89f3b1df99b3a32f44623f13ad1893118825bTimo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
5fbf8719b9ef072295c16bc4492f9f0ece92117dTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
5fbf8719b9ef072295c16bc4492f9f0ece92117dTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_assert(rext->sync_handler.callback != NULL);
4c9c55e15f35474f53f11659e796c63b1c34e884Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen unsigned int i, count;
ab1b9a793d57a60c230a41f65f1a25d52c026233Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
ab1b9a793d57a60c230a41f65f1a25d52c026233Timo Sirainen for (i = 0; i < count; i++) {
ab1b9a793d57a60c230a41f65f1a25d52c026233Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen Keywords are never removed from it, so the index values are valid
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen for the lifetime of the mail_index. */
d16b506f5540e3407d256bda35624b38a5ecf88fTimo Sirainen if (hash_table_lookup_full(index->keywords_hash, keyword,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen unsigned int *idx_r)
ccffb125d94adff0ad776de5a96e22f864d6fb0aTimo Sirainen if (mail_index_keyword_lookup(index, keyword, idx_r))
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen hash_table_insert(index->keywords_hash, keyword_dup,
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen /* keep the array NULL-terminated, but the NULL itself invisible */
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen array_delete(&index->keywords, array_count(&index->keywords)-1, 1);
c44f402f17f9a58ead24ac0083945cae86fb172bTimo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenmail_index_keywords_create(struct mail_index *index,
f6e301cb2060c4367d8145e2bf5d553ba87ceb34Timo Sirainen const char *const keywords[])
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* @UNSAFE */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* look up the keywords from index. they're never removed from there
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen so we can permanently store indexes to them. */
a1aaf11831cab8346d6d0dc702e37b3f1d95eb43Timo Sirainen mail_index_keyword_lookup_or_create(index, keywords[src],
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* ignore if this is a duplicate */
a1aaf11831cab8346d6d0dc702e37b3f1d95eb43Timo Sirainen for (i = 0; i < src; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenmail_index_keywords_create_from_indexes(struct mail_index *index,
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen const unsigned int *indexes;
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen /* @UNSAFE */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* copy but skip duplicates */
e958a3c4573058f17999f0083a34080ca35e34d8Timo Sirainen for (i = 0; i < src; i++) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_keywords_ref(struct mail_keywords *keywords)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_keywords_unref(struct mail_keywords **_keywords)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint mail_index_try_open_only(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* Note that our caller must close index->fd by itself. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen index->fd = nfs_safe_open(index->filepath, O_RDWR);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_set_syscall_error(index, "open()");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* have to create it */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* it's corrupted - recreate it */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen mail_index_set_syscall_error(index, "close()");
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenint mail_index_create_tmp_file(struct mail_index *index, const char **path_r)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen path = *path_r = t_strconcat(index->filepath, ".tmp", NULL);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* stale temp file. unlink and recreate rather than overwriting,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen just to make sure locking problems won't cause corruption */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_file_set_syscall_error(index, path, "creat()");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int mail_index_open_files(struct mail_index *index,
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
9fcf7b79236b0045f7709718f7b65ada516565e7Timo Sirainen /* if dovecot.index exists, read it first so that we can get
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen the correct indexid and log sequence */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen /* Create a new indexid for us. If we're opening index
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen into memory, index->map doesn't exist yet. */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen ret = mail_transaction_log_create(index->log, FALSE);
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen /* log creation could have changed it if someone else
24ce0c343cefe54af841871fa39dbc3464028b06Timo Sirainen just created it. */
5fbf8719b9ef072295c16bc4492f9f0ece92117dTimo Sirainen ret = index->map != NULL ? 1 : mail_index_try_open(index);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* corrupted */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen ret = mail_transaction_log_create(index->log, TRUE);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* open/create failed, fallback to in-memory indexes */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen index->cache = created ? mail_cache_create(index) :
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenmail_index_open_opened(struct mail_index *index,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((index->map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen /* index was marked corrupted. we'll probably need to
36c4702131e5a04984ad5d07cf5d8d5c633d43c3Timo Sirainen recreate the files. */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0)
36c4702131e5a04984ad5d07cf5d8d5c633d43c3Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
36c4702131e5a04984ad5d07cf5d8d5c633d43c3Timo Sirainen if ((ret = mail_index_open_opened(index, flags)) <= 0) {
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen /* doesn't exist and create flag not used */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen index->filepath = MAIL_INDEX_IS_IN_MEMORY(index) ?
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_strconcat(index->dir, "/", index->prefix, NULL);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen index->readonly = (flags & MAIL_INDEX_OPEN_FLAG_READONLY) != 0;
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_fatal("nfs flush requires mail_fsync=always");
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen (flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen i_fatal("nfs flush requires mmap_disable=yes");
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* NOTE: increase open_count only after mail_index_open_files().
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen it's used elsewhere to check if we're doing an initial opening
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen of the index files */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0) {
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen /* doesn't exist and create flag not used */
06f537a8e0b399222cc2a7755015ef3963525fd2Timo Sirainenint mail_index_open_or_create(struct mail_index *index,
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainenvoid mail_index_close_file(struct mail_index *index)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen mail_index_set_syscall_error(index, "close()");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenvoid mail_index_close(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint mail_index_unlink(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index) || index->readonly)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* main index */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (unlink(index->filepath) < 0 && errno != ENOENT)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen path = t_strconcat(index->filepath, MAIL_TRANSACTION_LOG_SUFFIX, NULL);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen path = t_strconcat(index->filepath, MAIL_CACHE_FILE_SUFFIX, NULL);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint mail_index_reopen_if_changed(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (nfs_safe_stat(index->filepath, &st2) < 0) {
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_set_syscall_error(index, "stat()");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_index_set_syscall_error(index, "fstat()");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* the same file */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* new file, new locks. the old fd can keep its locks, they don't
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen matter anymore as no-one's going to modify the file. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint mail_index_refresh(struct mail_index *index)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenstruct mail_cache *mail_index_get_cache(struct mail_index *index)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
1ac19c5c2b66a12f5598792aad15114ee3eb62e2Timo Sirainenbool mail_index_is_in_memory(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenint mail_index_move_to_memory(struct mail_index *index)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* set the index as being into memory */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen index->filepath = i_strdup("(in-memory index)");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* index was never even opened. just mark it as being in
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen memory and let the caller re-open the index. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* move index map to memory */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen /* move transaction log to memory */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen mail_transaction_log_move_to_memory(index->log);
9672bb2a11c37c275d695451accd824da5c9e485Timo Sirainen mail_index_set_syscall_error(index, "close()");
9672bb2a11c37c275d695451accd824da5c9e485Timo Sirainenvoid mail_index_mark_corrupted(struct mail_index *index)
9672bb2a11c37c275d695451accd824da5c9e485Timo Sirainen index->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen mail_index_set_syscall_error(index, "unlink()");
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen (void)mail_transaction_log_unlink(index->log);
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainenbool mail_index_is_deleted(struct mail_index *index)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen return index->index_delete_requested || index->index_deleted;
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainenint mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r)
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen if (mail_transaction_log_get_mtime(index->log, mtime_r) < 0)
9c2b0eb659540b9db8dd3a8a6a2515921fbe8eebTimo Sirainen mail_index_set_syscall_error(index, "stat()");
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path)
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen /* no gid changing */
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen } else if (fchown(fd, (uid_t)-1, index->gid) == 0) {
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen /* success */
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen } if ((index->mode & 0060) >> 3 == (index->mode & 0006)) {
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen /* group and world permissions are the same, so group doesn't
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen really matter. ignore silently. */
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen mail_index_file_set_syscall_error(index, path, "fchown()");
dc9de21d4375faeedbe5b7e941502ac578650da9Timo Sirainen eperm_error_get_chgrp("fchown", path, index->gid,
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainen /* continue, but change permissions so that only the common
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainen subset of group and world is used. this makes sure no one
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen gets any extra permissions. */
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen mode = ((index->mode & 0060) >> 3) & (index->mode & 0006);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen mail_index_file_set_syscall_error(index, path, "fchmod()");
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
bfdf0fd7b6186f64cbdcbf1cb2bf9c42a9007b77Timo Sirainen mail_index_file_set_syscall_error(index, index->filepath, function);
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainenvoid mail_index_file_set_syscall_error(struct mail_index *index,
f4c0b1874b0533bcf2df1d28d584ff02cfdae3faTimo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) == 0)
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen errstr = eacces_error_get_creating(function, filepath);
f4c0b1874b0533bcf2df1d28d584ff02cfdae3faTimo Sirainen errstr = eacces_error_get(function, filepath);
6b2738c39a868ff9291867138c55029fc40cf105Timo Sirainen " (process was started with ulimit -f limit)";
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainen mail_index_set_error(index, "%s failed with file %s: "
892b3cbf0eba9ba455448adcf71864a409345c6dTimo Sirainenconst char *mail_index_get_error_message(struct mail_index *index)