struct mail_index *mail_index_alloc(const char *dir, const char *prefix) { struct mail_index *index; index = i_new(struct mail_index, 1); index->dir = i_strdup(dir); index->prefix = i_strdup(prefix); index->fd = -1; index->extension_pool = pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024); p_array_init(&index->extensions, index->extension_pool, 5); i_array_init(&index->sync_lost_handlers, 4); i_array_init(&index->module_contexts, I_MIN(5, mail_index_module_register.id)); index->mode = 0600; index->gid = (gid_t)-1; index->lock_method = FILE_LOCK_METHOD_FCNTL; index->max_lock_timeout_secs = UINT_MAX; index->keywords_ext_id = mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS, 128, 2, 1); index->keywords_pool = pool_alloconly_create("keywords", 512); i_array_init(&index->keywords, 16); hash_table_create(&index->keywords_hash, index->keywords_pool, 0, strcase_hash, strcasecmp); index->log = mail_transaction_log_alloc(index); mail_index_modseq_init(index); return index; }
static void index_view_sync_recs_get(struct index_mailbox_sync_context *ctx) { struct mail_index_view_sync_rec sync_rec; uint32_t seq1, seq2; i_array_init(&ctx->flag_updates, 128); i_array_init(&ctx->hidden_updates, 32); while (mail_index_view_sync_next(ctx->sync_ctx, &sync_rec)) { switch (sync_rec.type) { case MAIL_INDEX_VIEW_SYNC_TYPE_MODSEQ: case MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS: if (!mail_index_lookup_seq_range(ctx->ctx.box->view, sync_rec.uid1, sync_rec.uid2, &seq1, &seq2)) break; if (!sync_rec.hidden && sync_rec.type == MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS) { seq_range_array_add_range(&ctx->flag_updates, seq1, seq2); } else { seq_range_array_add_range(&ctx->hidden_updates, seq1, seq2); } break; } } }
void mailbox_search_result_initial_done(struct mail_search_result *result) { if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_QUEUE_SYNC) != 0) { i_array_init(&result->removed_uids, 32); i_array_init(&result->added_uids, 32); } mail_search_args_seq2uid(result->search_args); }
void commands_init(void) { i_array_init(&imap_commands, 64); i_array_init(&command_hooks, 4); commands_unsorted = FALSE; command_register_array(imap4rev1_commands, IMAP4REV1_COMMANDS_COUNT); command_register_array(imap_ext_commands, IMAP_EXT_COMMANDS_COUNT); }
static struct mail_search_context * fts_mailbox_search_init(struct mailbox_transaction_context *t, struct mail_search_args *args, const enum mail_sort_type *sort_program, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers) { struct fts_transaction_context *ft = FTS_CONTEXT(t); struct fts_mailbox *fbox = FTS_CONTEXT(t->box); struct fts_mailbox_list *flist = FTS_LIST_CONTEXT(t->box->list); struct mail_search_context *ctx; struct fts_search_context *fctx; ctx = fbox->module_ctx.super.search_init(t, args, sort_program, wanted_fields, wanted_headers); if (!fts_backend_can_lookup(flist->backend, args->args)) return ctx; fctx = i_new(struct fts_search_context, 1); fctx->box = t->box; fctx->backend = flist->backend; fctx->t = t; fctx->args = args; fctx->result_pool = pool_alloconly_create("fts results", 1024*64); fctx->orig_matches = buffer_create_dynamic(default_pool, 64); fctx->virtual_mailbox = strcmp(t->box->storage->name, VIRTUAL_STORAGE_NAME) == 0; fctx->enforced = mail_user_plugin_getenv(t->box->storage->user, "fts_enforced") != NULL; i_array_init(&fctx->levels, 8); fctx->scores = i_new(struct fts_scores, 1); fctx->scores->refcount = 1; i_array_init(&fctx->scores->score_map, 64); MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx); /* FIXME: we'll assume that all the args are fuzzy. not good, but would require much more work to fix it. */ if (!fts_args_have_fuzzy(args->args) && mail_user_plugin_getenv(t->box->storage->user, "fts_no_autofuzzy") != NULL) fctx->flags |= FTS_LOOKUP_FLAG_NO_AUTO_FUZZY; /* transaction contains the last search's scores. they can be queried later with mail_get_special() */ if (ft->scores != NULL) fts_scores_unref(&ft->scores); ft->scores = fctx->scores; ft->scores->refcount++; if (fctx->enforced || fts_want_build_args(args->args)) fts_try_build_init(ctx, fctx); else fts_search_lookup(fctx); return ctx; }
struct dsync_worker *dsync_worker_init_test(void) { struct test_dsync_worker *worker; worker = i_new(struct test_dsync_worker, 1); worker->worker.v = test_dsync_worker; worker->tmp_pool = pool_alloconly_create("test worker", 256); i_array_init(&worker->box_events, 64); i_array_init(&worker->msg_events, 64); i_array_init(&worker->results, 64); worker->body_stream = i_stream_create_from_data("hdr\n\nbody", 9); return &worker->worker; }
static void stats_top(const char *path, const char *sort_type) { struct top_context ctx; memset(&ctx, 0, sizeof(ctx)); ctx.path = path; ctx.fd = doveadm_connect(path); ctx.prev_pool = pool_alloconly_create("stats top", 1024*16); ctx.cur_pool = pool_alloconly_create("stats top", 1024*16); i_array_init(&ctx.lines, 128); hash_table_create(&ctx.sessions, default_pool, 0, str_hash, strcmp); net_set_nonblock(ctx.fd, FALSE); ctx.input = i_stream_create_fd(ctx.fd, (size_t)-1, TRUE); if (strstr(sort_type, "cpu") != NULL) ctx.lines_sort = sort_cpu; else ctx.lines_sort = sort_num; ctx.sort_type = sort_type; stats_top_start(&ctx); i_stream_destroy(&ctx.input); hash_table_destroy(&ctx.sessions); array_free(&ctx.lines); pool_unref(&ctx.prev_pool); pool_unref(&ctx.cur_pool); i_close_fd(&ctx.fd); }
void commands_init(void) { i_array_init(&managesieve_commands, 16); commands_unsorted = FALSE; command_register_array(managesieve_base_commands, MANAGESIEVE_COMMANDS_COUNT); }
struct mail * virtual_mail_alloc(struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers) { struct virtual_mailbox *mbox = (struct virtual_mailbox *)t->box; struct virtual_mail *vmail; pool_t pool; pool = pool_alloconly_create("vmail", 1024); vmail = p_new(pool, struct virtual_mail, 1); vmail->imail.mail.pool = pool; vmail->imail.mail.v = virtual_mail_vfuncs; vmail->imail.mail.mail.box = t->box; vmail->imail.mail.mail.transaction = t; array_create(&vmail->imail.mail.module_contexts, pool, sizeof(void *), 5); vmail->imail.data_pool = pool_alloconly_create("virtual index_mail", 512); vmail->imail.ibox = INDEX_STORAGE_CONTEXT(t->box); vmail->imail.trans = (struct index_transaction_context *)t; vmail->wanted_fields = wanted_fields; if (wanted_headers != NULL) { vmail->wanted_headers = wanted_headers; mailbox_header_lookup_ref(wanted_headers); } i_array_init(&vmail->backend_mails, array_count(&mbox->backend_boxes)); return &vmail->imail.mail.mail; }
void mail_index_view_clone(struct mail_index_view *dest, const struct mail_index_view *src) { memset(dest, 0, sizeof(*dest)); dest->refcount = 1; dest->v = src->v; dest->index = src->index; if (src->log_view != NULL) { dest->log_view = mail_transaction_log_view_open(src->index->log); } dest->indexid = src->indexid; dest->inconsistency_id = src->inconsistency_id; dest->map = src->map; if (dest->map != NULL) dest->map->refcount++; dest->log_file_expunge_seq = src->log_file_expunge_seq; dest->log_file_expunge_offset = src->log_file_expunge_offset; dest->log_file_head_seq = src->log_file_head_seq; dest->log_file_head_offset = src->log_file_head_offset; i_array_init(&dest->module_contexts, I_MIN(5, mail_index_module_register.id)); DLLIST_PREPEND(&dest->index->views, dest); }
int mdbox_storage_create(struct mail_storage *_storage, struct mail_namespace *ns, const char **error_r) { struct mdbox_storage *storage = (struct mdbox_storage *)_storage; const char *dir; storage->set = mail_storage_get_driver_settings(_storage); storage->preallocate_space = storage->set->mdbox_preallocate_space; if (*ns->list->set.mailbox_dir_name == '\0') { *error_r = "mdbox: MAILBOXDIR must not be empty"; return -1; } _storage->unique_root_dir = p_strdup(_storage->pool, ns->list->set.root_dir); dir = mailbox_list_get_root_forced(ns->list, MAILBOX_LIST_PATH_TYPE_DIR); storage->storage_dir = p_strconcat(_storage->pool, dir, "/"MDBOX_GLOBAL_DIR_NAME, NULL); storage->alt_storage_dir = p_strconcat(_storage->pool, ns->list->set.alt_dir, "/"MDBOX_GLOBAL_DIR_NAME, NULL); i_array_init(&storage->open_files, 64); storage->map = mdbox_map_init(storage, ns->list); return dbox_storage_create(_storage, ns, error_r); }
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 void log_append_flag_updates(struct mail_index_export_context *ctx, struct mail_index_transaction *t) { ARRAY(struct mail_transaction_flag_update) log_updates; const struct mail_index_flag_update *updates; struct mail_transaction_flag_update *log_update; unsigned int i, count; updates = array_get(&t->updates, &count); if (count == 0) return; i_array_init(&log_updates, count); for (i = 0; i < count; i++) { log_update = array_append_space(&log_updates); log_update->uid1 = updates[i].uid1; log_update->uid2 = updates[i].uid2; log_update->add_flags = updates[i].add_flags & 0xff; log_update->remove_flags = updates[i].remove_flags & 0xff; if ((updates[i].add_flags & MAIL_INDEX_MAIL_FLAG_UPDATE_MODSEQ) != 0) log_update->modseq_inc_flag = 1; } log_append_buffer(ctx, log_updates.arr.buffer, MAIL_TRANSACTION_FLAG_UPDATE); array_free(&log_updates); }
struct mail_search_register *mail_search_register_init(void) { struct mail_search_register *reg; reg = i_new(struct mail_search_register, 1); i_array_init(®->args, 64); return reg; }
int main(int argc, char *argv[]) { ARRAY_TYPE(const_string) aenvs; const char *binary; const char *const *envs; int c, i; master_service = master_service_init("script", 0, &argc, &argv, "+e:"); t_array_init(&aenvs, 16); while ((c = master_getopt(master_service)) > 0) { switch (c) { case 'e': envs = t_strsplit_spaces(optarg,", \t"); while (*envs != NULL) { array_append(&aenvs, envs, 1); envs++; } break; default: return FATAL_DEFAULT; } } argc -= optind; argv += optind; array_append_zero(&aenvs); accepted_envs = p_strarray_dup(default_pool, array_idx(&aenvs, 0)); master_service_init_log(master_service, "script: "); if (argv[0] == NULL) i_fatal("Missing script path"); restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL); restrict_access_allow_coredumps(TRUE); master_service_init_finish(master_service); master_service_set_service_count(master_service, 1); if (argv[0][0] == '/') binary = argv[0]; else binary = t_strconcat(PKG_LIBEXECDIR"/", argv[0], NULL); i_array_init(&exec_args, argc + 16); array_append(&exec_args, &binary, 1); for (i = 1; i < argc; i++) { const char *arg = argv[i]; array_append(&exec_args, &arg, 1); } master_service_run(master_service, client_connected); array_free(&exec_args); i_free(accepted_envs); master_service_deinit(&master_service); return 0; }
static void request_add_context(struct indexer_request *request, void *context) { if (context == NULL) return; if (!array_is_created(&request->contexts)) i_array_init(&request->contexts, 2); array_append(&request->contexts, &context, 1); }
static int mdbox_sync_index(struct mdbox_sync_context *ctx) { struct mailbox *box = &ctx->mbox->box; const struct mail_index_header *hdr; struct mail_index_sync_rec sync_rec; uint32_t seq1, seq2; int ret = 0; hdr = mail_index_get_header(ctx->sync_view); if (hdr->uid_validity == 0) { /* newly created index file */ mail_storage_set_critical(box->storage, "Mailbox %s: Corrupted index, uidvalidity=0", box->vname); return 0; } /* mark the newly seen messages as recent */ if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid, hdr->next_uid, &seq1, &seq2)) { index_mailbox_set_recent_seq(&ctx->mbox->box, ctx->sync_view, seq1, seq2); } /* handle syncing records without map being locked. */ if (mdbox_map_atomic_is_locked(ctx->atomic)) { ctx->map_trans = mdbox_map_transaction_begin(ctx->atomic, FALSE); i_array_init(&ctx->expunged_seqs, 64); } while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) { if ((ret = mdbox_sync_rec(ctx, &sync_rec)) < 0) break; } /* write refcount changes to map index. transaction commit updates the log head, while tail is left behind. */ if (mdbox_map_atomic_is_locked(ctx->atomic)) { if (ret == 0) ret = mdbox_map_transaction_commit(ctx->map_trans); /* write changes to mailbox index */ if (ret == 0) ret = dbox_sync_mark_expunges(ctx); /* finish the map changes and unlock the map. this also updates map's tail -> head. */ if (ret < 0) mdbox_map_atomic_set_failed(ctx->atomic); mdbox_map_transaction_free(&ctx->map_trans); array_free(&ctx->expunged_seqs); } if (box->v.sync_notify != NULL) box->v.sync_notify(box, 0, 0); return ret == 0 ? 1 : (ctx->mbox->storage->corrupted ? 0 : -1); }
static int acl_backend_vfile_object_refresh_cache(struct acl_object *_aclobj) { struct acl_object_vfile *aclobj = (struct acl_object_vfile *)_aclobj; struct acl_backend_vfile *backend = (struct acl_backend_vfile *)_aclobj->backend; struct acl_backend_vfile_validity *old_validity; struct acl_backend_vfile_validity validity; time_t mtime; int ret; old_validity = acl_cache_get_validity(_aclobj->backend->cache, _aclobj->name); ret = _aclobj->backend->global_file != NULL ? acl_global_file_refresh(_aclobj->backend->global_file) : acl_backend_vfile_refresh(_aclobj, aclobj->global_path, old_validity == NULL ? NULL : &old_validity->global_validity); if (ret == 0) { ret = acl_backend_vfile_refresh(_aclobj, aclobj->local_path, old_validity == NULL ? NULL : &old_validity->local_validity); } if (ret <= 0) return ret; /* either global or local ACLs changed, need to re-read both */ if (!array_is_created(&_aclobj->rights)) { _aclobj->rights_pool = pool_alloconly_create("acl rights", 256); i_array_init(&_aclobj->rights, 16); } else { array_clear(&_aclobj->rights); p_clear(_aclobj->rights_pool); } memset(&validity, 0, sizeof(validity)); if (_aclobj->backend->global_file != NULL) acl_object_add_global_acls(_aclobj); else { if (acl_backend_vfile_read_with_retry(_aclobj, TRUE, aclobj->global_path, &validity.global_validity) < 0) return -1; } if (acl_backend_vfile_read_with_retry(_aclobj, FALSE, aclobj->local_path, &validity.local_validity) < 0) return -1; acl_rights_sort(_aclobj); /* update cache only after we've successfully read everything */ acl_object_rebuild_cache(_aclobj); acl_cache_set_validity(_aclobj->backend->cache, _aclobj->name, &validity); if (acl_backend_vfile_object_get_mtime(_aclobj, &mtime) == 0) acl_backend_vfile_acllist_verify(backend, _aclobj->name, mtime); return 0; }
struct imapc_msgmap *imapc_msgmap_init(void) { struct imapc_msgmap *msgmap; msgmap = i_new(struct imapc_msgmap, 1); i_array_init(&msgmap->uids, 128); msgmap->uid_next = 1; return msgmap; }
int squat_uidlist_build_init(struct squat_uidlist *uidlist, struct squat_uidlist_build_context **ctx_r) { struct squat_uidlist_build_context *ctx; int ret; i_assert(!uidlist->building); ret = squat_uidlist_open_or_create(uidlist); if (ret == 0 && lseek(uidlist->fd, uidlist->hdr.used_file_size, SEEK_SET) < 0) { i_error("lseek(%s) failed: %m", uidlist->path); ret = -1; } if (ret < 0) { if (uidlist->file_lock != NULL) file_unlock(&uidlist->file_lock); if (uidlist->dotlock != NULL) file_dotlock_delete(&uidlist->dotlock); return -1; } ctx = i_new(struct squat_uidlist_build_context, 1); ctx->uidlist = uidlist; ctx->output = o_stream_create_fd(uidlist->fd, 0); if (ctx->output->offset == 0) { struct squat_uidlist_file_header hdr; memset(&hdr, 0, sizeof(hdr)); o_stream_nsend(ctx->output, &hdr, sizeof(hdr)); } o_stream_cork(ctx->output); i_array_init(&ctx->lists, 10240); i_array_init(&ctx->block_offsets, 128); i_array_init(&ctx->block_end_indexes, 128); ctx->list_start_idx = uidlist->hdr.count; ctx->build_hdr = uidlist->hdr; uidlist->building = TRUE; *ctx_r = ctx; return 0; }
struct priorityq * priorityq_init(priorityq_cmp_callback_t *cmp_callback, unsigned int init_size) { struct priorityq *pq; pq = i_new(struct priorityq, 1); pq->cmp_callback = cmp_callback; i_array_init(&pq->items, init_size); return pq; }
void io_stream_add_destroy_callback(struct iostream_private *stream, void (*callback)(void *), void *context) { struct iostream_destroy_callback *dc; if (!array_is_created(&stream->destroy_callbacks)) i_array_init(&stream->destroy_callbacks, 2); dc = array_append_space(&stream->destroy_callbacks); dc->callback = callback; dc->context = context; }
void io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count) { struct ioloop_handler_context *ctx; ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1); i_array_init(&ctx->events, initial_fd_count); i_array_init(&ctx->fd_index, initial_fd_count); ctx->epfd = epoll_create(initial_fd_count); if (ctx->epfd < 0) { if (errno != EMFILE) i_fatal("epoll_create(): %m"); else { i_fatal("epoll_create(): %m (you may need to increase " "/proc/sys/fs/epoll/max_user_instances)"); } } fd_close_on_exec(ctx->epfd, TRUE); }
struct json_parser *json_parser_init(struct istream *input) { struct json_parser *parser; parser = i_new(struct json_parser, 1); parser->input = input; parser->value = str_new(default_pool, 128); i_array_init(&parser->nesting, 8); i_stream_ref(input); return parser; }
struct mail_search_result * mailbox_search_result_alloc(struct mailbox *box, struct mail_search_args *args, enum mailbox_search_result_flags flags) { struct mail_search_result *result; result = i_new(struct mail_search_result, 1); result->box = box; result->flags = flags; i_array_init(&result->uids, 32); i_array_init(&result->never_uids, 128); if ((result->flags & MAILBOX_SEARCH_RESULT_FLAG_UPDATE) != 0) { result->search_args = args; mail_search_args_ref(result->search_args); mailbox_search_result_analyze_args(result, args->args); } array_append(&result->box->search_results, &result, 1); return result; }
void io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count) { struct ioloop_handler_context *ctx; ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1); ctx->kq = kqueue(); if (ctx->kq < 0) i_fatal("kqueue() in io_loop_handler_init() failed: %m"); fd_close_on_exec(ctx->kq, TRUE); i_array_init(&ctx->events, initial_fd_count); }
static struct dsync_mailbox_tree_bfs_iter * dsync_mailbox_tree_bfs_iter_init(struct dsync_mailbox_tree *tree) { struct dsync_mailbox_tree_bfs_iter *iter; iter = i_new(struct dsync_mailbox_tree_bfs_iter, 1); iter->tree = tree; i_array_init(&iter->queue_arr, 32); iter->queue = aqueue_init(&iter->queue_arr.arr); iter->cur = tree->root.first_child; return iter; }
static void acllist_clear(struct acl_backend_vfile *backend, uoff_t file_size) { if (backend->acllist_pool == NULL) { backend->acllist_pool = pool_alloconly_create("vfile acllist", I_MAX(file_size / 2, 128)); i_array_init(&backend->acllist, I_MAX(16, file_size / 60)); } else { p_clear(backend->acllist_pool); array_clear(&backend->acllist); } }
struct mailbox_transaction_context * virtual_transaction_begin(struct mailbox *box, enum mailbox_transaction_flags flags) { struct virtual_mailbox *mbox = (struct virtual_mailbox *)box; struct virtual_transaction_context *vt; vt = i_new(struct virtual_transaction_context, 1); i_array_init(&vt->backend_transactions, array_count(&mbox->backend_boxes)); index_transaction_init(&vt->t, box, flags); return &vt->t; }
struct maildir_keywords_sync_ctx * maildir_keywords_sync_init(struct maildir_keywords *mk, struct mail_index *index) { struct maildir_keywords_sync_ctx *ctx; ctx = i_new(struct maildir_keywords_sync_ctx, 1); ctx->mk = mk; ctx->index = index; ctx->keywords = mail_index_get_keywords(index); i_array_init(&ctx->idx_to_chr, MAILDIR_MAX_KEYWORDS); return ctx; }