예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
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;
}