Example #1
0
int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id)
{
	struct stat st;
	const char *old_path;
	const char *new_dir, *new_fname, *new_path;

	i_assert(file->file_id == 0);
	i_assert(file_id != 0);

	old_path = file->file.cur_path;
	new_fname = t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id);
	new_dir = !dbox_file_is_in_alt(&file->file) ?
		file->storage->storage_dir : file->storage->alt_storage_dir;
	new_path = t_strdup_printf("%s/%s", new_dir, new_fname);

	if (stat(new_path, &st) == 0) {
		mail_storage_set_critical(&file->file.storage->storage,
			"mdbox: %s already exists, rebuilding index", new_path);
		mdbox_storage_set_corrupted(file->storage);
		return -1;
	}
	if (rename(old_path, new_path) < 0) {
		mail_storage_set_critical(&file->storage->storage.storage,
					  "rename(%s, %s) failed: %m",
					  old_path, new_path);
		return -1;
	}
	mdbox_file_init_paths(file, new_fname,
			      dbox_file_is_in_alt(&file->file));
	file->file_id = file_id;
	array_append(&file->storage->open_files, &file, 1);
	return 0;
}
Example #2
0
static struct dbox_file *
mdbox_file_init_full(struct mdbox_storage *storage,
		     uint32_t file_id, bool alt_dir)
{
	struct mdbox_file *file;
	const char *fname;
	unsigned int count;

	file = file_id == 0 ? NULL :
		mdbox_find_and_move_open_file(storage, file_id);
	if (file != NULL) {
		file->file.refcount++;
		return &file->file;
	}

	count = array_count(&storage->open_files);
	if (count > MDBOX_MAX_OPEN_UNUSED_FILES) {
		mdbox_close_open_files(storage,
				       count - MDBOX_MAX_OPEN_UNUSED_FILES);
	}

	file = i_new(struct mdbox_file, 1);
	file->storage = storage;
	file->file.storage = &storage->storage;
	file->file_id = file_id;
	fname = file_id == 0 ? dbox_generate_tmp_filename() :
		t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id);
	mdbox_file_init_paths(file, fname);
	dbox_file_init(&file->file);
	if (alt_dir)
		file->file.cur_path = file->file.alt_path;

	if (file_id != 0)
		array_append(&storage->open_files, &file, 1);
	else
		(void)mdbox_file_create(file);
	return &file->file;
}