<commit_before>/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "master-service.h"
#include "mail-index-modseq.h"
#include "mail-search-build.h"
#include "mailbox-list-private.h"
#include "dbox-mail.h"
#include "dbox-save.h"
#include "sdbox-file.h"
#include "sdbox-sync.h"
#include "sdbox-storage.h"

extern struct mail_storage dbox_storage, sdbox_storage;
extern struct mailbox sdbox_mailbox;
extern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;

static struct mail_storage *sdbox_storage_alloc(void)
{
	struct sdbox_storage *storage;
	pool_t pool;

	pool = pool_alloconly_create("sdbox storage", 512+256);
	storage = p_new(pool, struct sdbox_storage, 1);
	storage->storage.v = sdbox_dbox_storage_vfuncs;
	storage->storage.storage = sdbox_storage;
	storage->storage.storage.pool = pool;
	return &storage->storage.storage;
}

static const char *
sdbox_storage_find_root_dir(const struct mail_namespace *ns)
{
	bool debug = ns->mail_set->mail_debug;
	const char *home, *path;

	if (mail_user_get_home(ns->owner, &home) > 0) {
		path = t_strconcat(home, "/sdbox", NULL);
		if (access(path, R_OK|W_OK|X_OK) == 0) {
			if (debug)
				i_debug("sdbox: root exists (%s)", path);
			return path;
		} 
		if (debug)
			i_debug("sdbox: access(%s, rwx): failed: %m", path);
	}
	return NULL;
}

static bool sdbox_storage_autodetect(const struct mail_namespace *ns,
				     struct mailbox_list_settings *set)
{
	bool debug = ns->mail_set->mail_debug;
	struct stat st;
	const char *path, *root_dir;

	if (set->root_dir != NULL)
		root_dir = set->root_dir;
	else {
		root_dir = sdbox_storage_find_root_dir(ns);
		if (root_dir == NULL) {
			if (debug)
				i_debug("sdbox: couldn't find root dir");
			return FALSE;
		}
	}

	/* NOTE: this check works for mdbox as well. we'll rely on the
	   autodetect ordering to catch mdbox before we get here. */
	path = t_strconcat(root_dir, "/"DBOX_MAILBOX_DIR_NAME, NULL);
	if (stat(path, &st) < 0) {
		if (debug)
			i_debug("sdbox autodetect: stat(%s) failed: %m", path);
		return FALSE;
	}

	if (!S_ISDIR(st.st_mode)) {
		if (debug)
			i_debug("sdbox autodetect: %s not a directory", path);
		return FALSE;
	}

	set->root_dir = root_dir;
	dbox_storage_get_list_settings(ns, set);
	return TRUE;
}

static struct mailbox *
sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
		    const char *vname, enum mailbox_flags flags)
{
	struct sdbox_mailbox *mbox;
	struct index_mailbox_context *ibox;
	pool_t pool;

	/* dbox can't work without index files */
	flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;

	pool = pool_alloconly_create("sdbox mailbox", 1024*3);
	mbox = p_new(pool, struct sdbox_mailbox, 1);
	mbox->box = sdbox_mailbox;
	mbox->box.pool = pool;
	mbox->box.storage = storage;
	mbox->box.list = list;
	mbox->box.mail_vfuncs = &sdbox_mail_vfuncs;

	index_storage_mailbox_alloc(&mbox->box, vname,
				    flags, DBOX_INDEX_PREFIX);

	ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
	ibox->index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
		MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;

	mbox->storage = (struct sdbox_storage *)storage;
	return &mbox->box;
}

int sdbox_read_header(struct sdbox_mailbox *mbox,
		      struct sdbox_index_header *hdr, bool log_error)
{
	struct mail_index_view *view;
	const void *data;
	size_t data_size;
	int ret;<commit_msg>sdbox: Fixed sdbox_read_header() randomly failing.<commit_after>/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "master-service.h"
#include "mail-index-modseq.h"
#include "mail-search-build.h"
#include "mailbox-list-private.h"
#include "dbox-mail.h"
#include "dbox-save.h"
#include "sdbox-file.h"
#include "sdbox-sync.h"
#include "sdbox-storage.h"

extern struct mail_storage dbox_storage, sdbox_storage;
extern struct mailbox sdbox_mailbox;
extern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;

static struct mail_storage *sdbox_storage_alloc(void)
{
	struct sdbox_storage *storage;
	pool_t pool;

	pool = pool_alloconly_create("sdbox storage", 512+256);
	storage = p_new(pool, struct sdbox_storage, 1);
	storage->storage.v = sdbox_dbox_storage_vfuncs;
	storage->storage.storage = sdbox_storage;
	storage->storage.storage.pool = pool;
	return &storage->storage.storage;
}

static const char *
sdbox_storage_find_root_dir(const struct mail_namespace *ns)
{
	bool debug = ns->mail_set->mail_debug;
	const char *home, *path;

	if (mail_user_get_home(ns->owner, &home) > 0) {
		path = t_strconcat(home, "/sdbox", NULL);
		if (access(path, R_OK|W_OK|X_OK) == 0) {
			if (debug)
				i_debug("sdbox: root exists (%s)", path);
			return path;
		} 
		if (debug)
			i_debug("sdbox: access(%s, rwx): failed: %m", path);
	}
	return NULL;
}

static bool sdbox_storage_autodetect(const struct mail_namespace *ns,
				     struct mailbox_list_settings *set)
{
	bool debug = ns->mail_set->mail_debug;
	struct stat st;
	const char *path, *root_dir;

	if (set->root_dir != NULL)
		root_dir = set->root_dir;
	else {
		root_dir = sdbox_storage_find_root_dir(ns);
		if (root_dir == NULL) {
			if (debug)
				i_debug("sdbox: couldn't find root dir");
			return FALSE;
		}
	}

	/* NOTE: this check works for mdbox as well. we'll rely on the
	   autodetect ordering to catch mdbox before we get here. */
	path = t_strconcat(root_dir, "/"DBOX_MAILBOX_DIR_NAME, NULL);
	if (stat(path, &st) < 0) {
		if (debug)
			i_debug("sdbox autodetect: stat(%s) failed: %m", path);
		return FALSE;
	}

	if (!S_ISDIR(st.st_mode)) {
		if (debug)
			i_debug("sdbox autodetect: %s not a directory", path);
		return FALSE;
	}

	set->root_dir = root_dir;
	dbox_storage_get_list_settings(ns, set);
	return TRUE;
}

static struct mailbox *
sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
		    const char *vname, enum mailbox_flags flags)
{
	struct sdbox_mailbox *mbox;
	struct index_mailbox_context *ibox;
	pool_t pool;

	/* dbox can't work without index files */
	flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;

	pool = pool_alloconly_create("sdbox mailbox", 1024*3);
	mbox = p_new(pool, struct sdbox_mailbox, 1);
	mbox->box = sdbox_mailbox;
	mbox->box.pool = pool;
	mbox->box.storage = storage;
	mbox->box.list = list;
	mbox->box.mail_vfuncs = &sdbox_mail_vfuncs;

	index_storage_mailbox_alloc(&mbox->box, vname,
				    flags, DBOX_INDEX_PREFIX);

	ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
	ibox->index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
		MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;

	mbox->storage = (struct sdbox_storage *)storage;
	return &mbox->box;
}

int sdbox_read_header(struct sdbox_mailbox *mbox,
		      struct sdbox_index_header *hdr, bool log_error)
{
	struct mail_index_view *view;
	const void *data;
	size_t data_size;
	int ret = 0;
{'fraction_non_alphanumeric': 0.12398163235076284, 'fraction_numerical': 0.0072581839727447785, 'mean_word_length': 4.8307426597582035, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '523289', 'n_tokens_mistral': 2789, 'n_tokens_neox': 2541, 'n_words': 596}