struct maildir_keywords * maildir_keywords_init_readonly(struct mailbox *box) { struct maildir_keywords *mk; const char *dir; if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_CONTROL, &dir) <= 0) i_unreached(); mk = i_new(struct maildir_keywords, 1); mk->storage = box->storage; mk->path = i_strconcat(dir, "/" MAILDIR_KEYWORDS_NAME, NULL); mk->pool = pool_alloconly_create("maildir keywords", 512); i_array_init(&mk->list, MAILDIR_MAX_KEYWORDS); hash_table_create(&mk->hash, mk->pool, 0, strcase_hash, strcasecmp); mk->dotlock_settings.use_excl_lock = box->storage->set->dotlock_use_excl; mk->dotlock_settings.nfs_flush = box->storage->set->mail_nfs_storage; mk->dotlock_settings.timeout = mail_storage_get_lock_timeout(box->storage, KEYWORDS_LOCK_STALE_TIMEOUT + 2); mk->dotlock_settings.stale_timeout = KEYWORDS_LOCK_STALE_TIMEOUT; mk->dotlock_settings.temp_prefix = mailbox_list_get_temp_prefix(box->list); return mk; }
static int index_mailbox_alloc_index(struct mailbox *box, struct mail_index **index_r) { const char *index_dir, *mailbox_path; if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &mailbox_path) < 0) return -1; if ((box->flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 || mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, &index_dir) <= 0) index_dir = NULL; *index_r = mail_index_alloc_cache_get(mailbox_path, index_dir, box->index_prefix); return 0; }
int index_storage_mailbox_exists_full(struct mailbox *box, const char *subdir, enum mailbox_existence *existence_r) { struct stat st; enum mail_error error; const char *path, *path2; int ret; /* see if it's selectable */ ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path); if (ret < 0) { mailbox_list_get_last_error(box->list, &error); if (error != MAIL_ERROR_NOTFOUND) return -1; *existence_r = MAILBOX_EXISTENCE_NONE; return 0; } if (ret == 0) { /* no mailboxes in this storage? */ *existence_r = MAILBOX_EXISTENCE_NONE; return 0; } if (subdir != NULL) path = t_strconcat(path, "/", subdir, NULL); if (stat(path, &st) == 0) { *existence_r = MAILBOX_EXISTENCE_SELECT; return 0; } if (!ENOTFOUND(errno) && errno != EACCES) { mail_storage_set_critical(box->storage, "stat(%s) failed: %m", path); return -1; } /* see if it's non-selectable */ if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_DIR, &path2) <= 0 || (strcmp(path, path2) != 0 && stat(path2, &st) == 0)) { *existence_r = MAILBOX_EXISTENCE_NOSELECT; return 0; } *existence_r = MAILBOX_EXISTENCE_NONE; return 0; }
int mbox_list_index_has_changed(struct mailbox *box, struct mail_index_view *list_view, uint32_t seq) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; const struct mbox_list_index_record *rec; const void *data; const char *path; struct stat st; uint32_t ext_id; bool expunged; int ret; ret = index_storage_list_index_has_changed(box, list_view, seq); if (ret != 0 || box->storage->set->mailbox_list_index_very_dirty_syncs) return ret; ext_id = mbox_list_get_ext_id(mbox, list_view); mail_index_lookup_ext(list_view, seq, ext_id, &data, &expunged); rec = data; if (rec == NULL || expunged || rec->mtime == 0) { /* doesn't exist or not synced */ return 1; } ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX, &path); if (ret < 0) return ret; i_assert(ret > 0); if (stat(path, &st) < 0) { mail_storage_set_critical(box->storage, "stat(%s) failed: %m", path); return -1; } if ((time_t)rec->mtime != st.st_mtime || rec->size != (uint32_t)(st.st_size & 0xffffffffU)) return 1; return 0; }
static int index_mailbox(struct master_connection *conn, struct mail_user *user, const char *mailbox, unsigned int max_recent_msgs, const char *what) { struct mail_namespace *ns; struct mailbox *box; struct mailbox_status status; const char *path, *errstr; enum mail_error error; enum mailbox_sync_flags sync_flags = MAILBOX_SYNC_FLAG_FULL_READ; int ret; ns = mail_namespace_find(user->namespaces, mailbox); box = mailbox_alloc(ns->list, mailbox, 0); mailbox_set_reason(box, "indexing"); ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, &path); if (ret < 0) { i_error("Getting path to mailbox %s failed: %s", mailbox, mailbox_get_last_internal_error(box, NULL)); mailbox_free(&box); return -1; } if (ret == 0) { i_info("Indexes disabled for mailbox %s, skipping", mailbox); mailbox_free(&box); return 0; } ret = 0; if (max_recent_msgs != 0) { /* index only if there aren't too many recent messages. don't bother syncing the mailbox, that alone can take a while with large maildirs. */ if (mailbox_open(box) < 0) { i_error("Opening mailbox %s failed: %s", mailbox, mailbox_get_last_internal_error(box, NULL)); ret = -1; } else { mailbox_get_open_status(box, STATUS_RECENT, &status); } if (ret < 0 || status.recent > max_recent_msgs) { mailbox_free(&box); return ret; } } if (strchr(what, 'o') != NULL) sync_flags |= MAILBOX_SYNC_FLAG_OPTIMIZE; if (mailbox_sync(box, sync_flags) < 0) { errstr = mailbox_get_last_internal_error(box, &error); if (error != MAIL_ERROR_NOTFOUND) { i_error("Syncing mailbox %s failed: %s", mailbox, errstr); } else if (user->mail_debug) { i_debug("Syncing mailbox %s failed: %s", mailbox, errstr); } ret = -1; } else if (strchr(what, 'i') != NULL) { if (index_mailbox_precache(conn, box) < 0) ret = -1; } mailbox_free(&box); return ret; }