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; }
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; }