struct mailbox_list_iterate_context *
mailbox_list_subscriptions_iter_init(struct mailbox_list *list,
                                     const char *const *patterns,
                                     enum mailbox_list_iter_flags flags)
{
    struct subscriptions_mailbox_list_iterate_context *ctx;
    pool_t pool;
    char sep = mail_namespace_get_sep(list->ns);

    pool = pool_alloconly_create("mailbox list subscriptions iter", 1024);
    ctx = p_new(pool, struct subscriptions_mailbox_list_iterate_context, 1);
    ctx->ctx.pool = pool;
    ctx->ctx.list = list;
    ctx->ctx.flags = flags;
    ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, sep);
    array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5);

    ctx->tree = mailbox_tree_init(sep);
    mailbox_list_subscriptions_fill(&ctx->ctx, ctx->tree, FALSE);

    ctx->info.ns = list->ns;
    /* the tree usually has only those entries we want to iterate through,
       but there are also non-matching root entries (e.g. "LSUB foo/%" will
       include the "foo"), which we'll drop with MAILBOX_MATCHED. */
    ctx->iter = mailbox_tree_iterate_init(ctx->tree, NULL, MAILBOX_MATCHED);
    return &ctx->ctx;
}
Пример #2
0
struct lmtp_client *
lmtp_client_init(const struct lmtp_client_settings *set,
		 lmtp_finish_callback_t *finish_callback, void *context)
{
	struct lmtp_client *client;
	pool_t pool;

	i_assert(*set->mail_from == '<');
	i_assert(*set->my_hostname != '\0');

	pool = pool_alloconly_create("lmtp client", 512);
	client = p_new(pool, struct lmtp_client, 1);
	client->refcount = 1;
	client->pool = pool;
	client->set.mail_from = p_strdup(pool, set->mail_from);
	client->set.my_hostname = p_strdup(pool, set->my_hostname);
	client->set.dns_client_socket_path =
		p_strdup(pool, set->dns_client_socket_path);
	client->set.source_ip = set->source_ip;
	client->set.source_port = set->source_port;
	client->set.proxy_ttl = set->proxy_ttl;
	client->set.proxy_timeout_secs = set->proxy_timeout_secs;
	client->set.timeout_secs = set->timeout_secs;
	client->finish_callback = finish_callback;
	client->finish_context = context;
	client->fd = -1;
	client->input_multiline = str_new(default_pool, 128);
	p_array_init(&client->recipients, pool, 16);
	return client;
}
Пример #3
0
static int
fts_filter_stopwords_create(const struct fts_language *lang,
                            const char *const *settings,
                            struct fts_filter **filter_r,
                            const char **error_r)
{
	struct fts_filter_stopwords *sp;
	pool_t pp;
	const char *dir = NULL;
	unsigned int i;

	for (i = 0; settings[i] != NULL; i += 2) {
		const char *key = settings[i], *value = settings[i+1];

		if (strcmp(key, "stopwords_dir") == 0) {
			dir = value;
		} else {
			*error_r = t_strdup_printf("Unknown setting: %s", key);
			return -1;
		}
	}
	pp = pool_alloconly_create(MEMPOOL_GROWING"fts_filter_stopwords",
	                           sizeof(struct fts_filter));
	sp = p_new(pp, struct fts_filter_stopwords, 1);
	sp->filter = *fts_filter_stopwords;
	sp->pool = pp;
	sp->lang = p_malloc(sp->pool, sizeof(struct fts_language));
	sp->lang->name = p_strdup(sp->pool, lang->name);
	if (dir != NULL)
		sp->stopwords_dir = p_strdup(pp, dir);
	else
		sp->stopwords_dir = DATADIR"/stopwords";
	*filter_r = &sp->filter;
	return 0;
}
Пример #4
0
static void
get_metadata_cache_fields(struct mailbox *box,
			  struct mailbox_metadata *metadata_r)
{
	const struct mail_cache_field *fields;
	enum mail_cache_decision_type dec;
	ARRAY_TYPE(mailbox_cache_field) *cache_fields;
	struct mailbox_cache_field *cf;
	unsigned int i, count;

	if (box->metadata_pool == NULL) {
		box->metadata_pool =
			pool_alloconly_create("mailbox metadata", 1024*3);
	}

	fields = mail_cache_register_get_list(box->cache,
					      box->metadata_pool, &count);

	cache_fields = p_new(box->metadata_pool,
			     ARRAY_TYPE(mailbox_cache_field), 1);
	p_array_init(cache_fields, box->metadata_pool, count);
	for (i = 0; i < count; i++) {
		dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
		if (dec != MAIL_CACHE_DECISION_NO) {
			cf = array_append_space(cache_fields);
			cf->name = fields[i].name;
			cf->decision = fields[i].decision;
			cf->last_used = fields[i].last_used;
		}
	}
	metadata_r->cache_fields = cache_fields;
}
Пример #5
0
struct client_connection *
client_connection_create(int fd, int listen_fd, bool ssl)
{
	struct client_connection *conn;
	unsigned int port;
	pool_t pool;

	pool = pool_alloconly_create("doveadm client", 1024*16);
	conn = p_new(pool, struct client_connection, 1);
	conn->pool = pool;
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, client_connection_input, conn);
	conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(conn->output, TRUE);

	(void)net_getsockname(fd, &conn->local_ip, &port);
	(void)net_getpeername(fd, &conn->remote_ip, &port);

	if (client_connection_read_settings(conn) < 0) {
		client_connection_destroy(&conn);
		return NULL;
	}
	if (ssl) {
		if (client_connection_init_ssl(conn) < 0) {
			client_connection_destroy(&conn);
			return NULL;
		}
	}
	client_connection_send_auth_handshake(conn, listen_fd);
	return conn;
}
void test_mempool_alloconly(void)
{
#define PMALLOC_MAX_COUNT 128
    pool_t pool;
    unsigned int i, j, k;
    void *mem[PMALLOC_MAX_COUNT + 1];
    bool success = TRUE;

    for (i = 0; i < 64; i++) {
        for (j = 1; j <= 128; j++) {
            pool = pool_alloconly_create(MEMPOOL_GROWING"test", i);
            mem[0] = p_malloc(pool, j);
            memset(mem[0], j, j);

            for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
                mem[k] = p_malloc(pool, k);
                memset(mem[k], k, k);
            }

            if (!mem_has_bytes(mem[0], j, j))
                success = FALSE;
            for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
                if (!mem_has_bytes(mem[k], k, k))
                    success = FALSE;
            }
            pool_unref(&pool);
        }
    }
    test_out("mempool_alloconly", success);
}
Пример #7
0
static int
imap_master_client_input_line(struct connection *conn, const char *line)
{
	char *const *args;
	pool_t pool;
	int fd_client, ret;

	if (!conn->version_received) {
		if (connection_verify_version(conn, t_strsplit_tabescaped(line)) < 0)
			return -1;
		conn->version_received = TRUE;
		return 1;
	}

	fd_client = i_stream_unix_get_read_fd(conn->input);
	if (fd_client == -1) {
		i_error("imap-master: IMAP client fd not received");
		return -1;
	}

	if (imap_debug)
		i_debug("imap-master: Client input: %s", line);

	pool = pool_alloconly_create("imap master client cmd", 1024);
	args = p_strsplit_tabescaped(pool, line);
	ret = imap_master_client_input_args(conn, (void *)args, fd_client, pool);
	pool_unref(&pool);
	return ret;
}
Пример #8
0
int hash_format_init(const char *format_string, struct hash_format **format_r,
		     const char **error_r)
{
	struct hash_format *format;
	pool_t pool;
	int ret;

	pool = pool_alloconly_create("hash format", 1024);
	format = p_new(pool, struct hash_format, 1);
	format->pool = pool;
	format->str = p_strdup(pool, format_string);
	format->pos = &format->list;
	T_BEGIN {
		ret = hash_format_string_analyze(format, format_string,
						 error_r);
		if (ret < 0)
			*error_r = p_strdup(format->pool, *error_r);
	} T_END;
	if (ret < 0) {
		*error_r = t_strdup(*error_r);
		pool_unref(&pool);
		return -1;
	}
	*format_r = format;
	return 0;
}
Пример #9
0
static struct mail_save_context *
maildir_save_transaction_init(struct mailbox_transaction_context *t)
{
	struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->box;
	struct maildir_save_context *ctx;
	const char *path;
	pool_t pool;

	pool = pool_alloconly_create("maildir_save_context", 4096);
	ctx = p_new(pool, struct maildir_save_context, 1);
	ctx->ctx.transaction = t;
	ctx->pool = pool;
	ctx->mbox = mbox;
	ctx->trans = t->itrans;
	ctx->files_tail = &ctx->files;
	ctx->fd = -1;

	path = mailbox_get_path(&mbox->box);
	ctx->tmpdir = p_strconcat(pool, path, "/tmp", NULL);
	ctx->newdir = p_strconcat(pool, path, "/new", NULL);
	ctx->curdir = p_strconcat(pool, path, "/cur", NULL);

	buffer_create_from_const_data(&ctx->keywords_buffer, "", 0);
	array_create_from_buffer(&ctx->keywords_array, &ctx->keywords_buffer,
				 sizeof(unsigned int));
	ctx->last_save_finished = TRUE;
	return &ctx->ctx;
}
Пример #10
0
struct sieve_generator *sieve_generator_create
(struct sieve_ast *ast, struct sieve_error_handler *ehandler,
	enum sieve_compile_flags flags)
{
	pool_t pool;
	struct sieve_generator *gentr;
	struct sieve_script *script;
	struct sieve_instance *svinst;

	pool = pool_alloconly_create("sieve_generator", 4096);
	gentr = p_new(pool, struct sieve_generator, 1);
	gentr->pool = pool;

	gentr->ehandler = ehandler;
	sieve_error_handler_ref(ehandler);

	gentr->genenv.gentr = gentr;
	gentr->genenv.flags = flags;
	gentr->genenv.ast = ast;
	sieve_ast_ref(ast);

	script = sieve_ast_script(ast);
	svinst = sieve_script_svinst(script);

	gentr->genenv.script = script;
	gentr->genenv.svinst = svinst;

	/* Setup storage for extension contexts */
	p_array_init(&gentr->ext_contexts, pool, sieve_extensions_get_count(svinst));

	return gentr;
}
Пример #11
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;
}
Пример #12
0
void index_mail_init(struct index_mail *mail,
		     struct mailbox_transaction_context *_t,
		     enum mail_fetch_field wanted_fields,
		     struct mailbox_header_lookup_ctx *_wanted_headers)
{
	struct index_transaction_context *t =
		(struct index_transaction_context *)_t;
	struct index_header_lookup_ctx *wanted_headers =
		(struct index_header_lookup_ctx *)_wanted_headers;
	const struct mail_index_header *hdr;

	array_create(&mail->mail.module_contexts, mail->mail.pool,
		     sizeof(void *), 5);

	mail->mail.v = *_t->box->mail_vfuncs;
	mail->mail.mail.box = _t->box;
	mail->mail.mail.transaction = &t->mailbox_ctx;
	mail->mail.wanted_fields = wanted_fields;
	mail->mail.wanted_headers = _wanted_headers;

	hdr = mail_index_get_header(_t->box->view);
	mail->uid_validity = hdr->uid_validity;

	t->mail_ref_count++;
	mail->data_pool = pool_alloconly_create("index_mail", 16384);
	mail->ibox = INDEX_STORAGE_CONTEXT(_t->box);
	mail->trans = t;
	mail->wanted_fields = wanted_fields;
	if (wanted_headers != NULL) {
		mail->wanted_headers = wanted_headers;
		mailbox_header_lookup_ref(_wanted_headers);
	}
}
static int
fts_filter_stemmer_snowball_create(const struct fts_language *lang,
                                   const char *const *settings,
                                   struct fts_filter **filter_r,
                                   const char **error_r)
{
    struct fts_filter_stemmer_snowball *sp;
    pool_t pp;

    *filter_r = NULL;

    if (settings[0] != NULL) {
        *error_r = t_strdup_printf("Unknown setting: %s", settings[0]);
        return -1;
    }
    pp = pool_alloconly_create(MEMPOOL_GROWING"fts_filter_stemmer_snowball",
                               sizeof(struct fts_filter));
    sp = p_new(pp, struct fts_filter_stemmer_snowball, 1);
    sp->pool = pp;
    sp->filter = *fts_filter_stemmer_snowball;
    sp->lang = p_malloc(sp->pool, sizeof(struct fts_language));
    sp->lang->name = p_strdup(sp->pool, lang->name);
    *filter_r = &sp->filter;
    return 0;
}
Пример #14
0
static struct mailbox *
mbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
		   const char *vname, enum mailbox_flags flags)
{
	struct mbox_mailbox *mbox;
	pool_t pool;

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

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

	mbox->storage = (struct mbox_storage *)storage;
	mbox->mbox_fd = -1;
	mbox->mbox_lock_type = F_UNLCK;
	mbox->mbox_list_index_ext_id = (uint32_t)-1;

	if (strcmp(mbox->storage->set->mbox_md5, "apop3d") == 0)
		mbox->md5_v = mbox_md5_apop3d;
	else if (strcmp(mbox->storage->set->mbox_md5, "all") == 0)
		mbox->md5_v = mbox_md5_all;
	else {
		i_fatal("Invalid mbox_md5 setting: %s",
			mbox->storage->set->mbox_md5);
	}

	if ((storage->flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0)
		mbox->mbox_save_md5 = TRUE;
	return &mbox->box;
}
Пример #15
0
struct mail_user *mail_user_alloc(const char *username,
				  const struct setting_parser_info *set_info,
				  const struct mail_user_settings *set)
{
	struct mail_user *user;
	const char *error;
	pool_t pool;

	i_assert(username != NULL);
	i_assert(*username != '\0');

	pool = pool_alloconly_create(MEMPOOL_GROWING"mail user", 16*1024);
	user = p_new(pool, struct mail_user, 1);
	user->pool = pool;
	user->refcount = 1;
	user->username = p_strdup(pool, username);
	user->set_info = set_info;
	user->unexpanded_set = settings_dup(set_info, set, pool);
	user->set = settings_dup(set_info, set, pool);
	user->service = master_service_get_name(master_service);
	user->default_normalizer = uni_utf8_to_decomposed_titlecase;

	/* check settings so that the duplicated structure will again
	   contain the parsed fields */
	if (!settings_check(set_info, pool, user->set, &error))
		i_panic("Settings check unexpectedly failed: %s", error);

	user->v.deinit = mail_user_deinit_base;
	user->v.stats_fill = mail_user_stats_fill_base;
	p_array_init(&user->module_contexts, user->pool, 5);
	return user;
}
Пример #16
0
void mail_storage_service_init_settings(struct mail_storage_service_ctx *ctx,
					const struct mail_storage_service_input *input)
{
	const struct setting_parser_info *user_info;
	const struct mail_user_settings *user_set;
	const struct setting_parser_context *set_parser;
	const char *error;
	pool_t temp_pool;
	void **sets;

	if (ctx->conn != NULL)
		return;

	temp_pool = pool_alloconly_create("service all settings", 4096);
	if (mail_storage_service_read_settings(ctx, input, temp_pool,
					       &user_info, &set_parser,
					       &error) < 0)
		i_fatal("%s", error);
	sets = master_service_settings_parser_get_others(master_service,
							 set_parser);
	user_set = sets[0];

	mail_storage_service_first_init(ctx, user_info, user_set);
	pool_unref(&temp_pool);
}
int index_transaction_commit(struct mailbox_transaction_context *t,
			     struct mail_transaction_commit_changes *changes_r)
{
	struct mailbox *box = t->box;
	struct mail_index_transaction *itrans = t->itrans;
	struct mail_index_transaction_commit_result result;
	int ret = 0;

	memset(changes_r, 0, sizeof(*changes_r));
	changes_r->pool = pool_alloconly_create(MEMPOOL_GROWING
						"transaction changes", 512);
	p_array_init(&changes_r->saved_uids, changes_r->pool, 32);
	t->changes = changes_r;

	if (t->itrans_pvt != NULL)
		ret = mail_index_transaction_commit(&t->itrans_pvt);
	if (mail_index_transaction_commit_full(&itrans, &result) < 0)
		ret = -1;
	t = NULL;

	if (ret < 0 && mail_index_is_deleted(box->index))
		mailbox_set_deleted(box);

	changes_r->ignored_modseq_changes = result.ignored_modseq_changes;
	return ret;
}
Пример #18
0
enum fatal_test_state fatal_mempool(int stage)
{
	static pool_t pool;

	switch(stage) {
	case 0: /* forbidden size */
		test_begin("fatal_mempool");
		pool = pool_alloconly_create(MEMPOOL_GROWING"fatal", 1);
		(void)p_malloc(pool, 0);
		return FATAL_TEST_FAILURE;

	case 1: /* logically impossible size */
		(void)p_malloc(pool, SSIZE_T_MAX + 1ULL);
		return FATAL_TEST_FAILURE;

	case 2: /* physically impossible size */
		(void)p_malloc(pool, SSIZE_T_MAX - (size_t)MEM_ALIGN(1));
		return FATAL_TEST_FAILURE;

	/* Continue with other tests as follows:
	case 3:
		something_fatal();
		return FATAL_TEST_FAILURE;
	*/
	}

	/* Either our tests have finished, or the test suite has got confused. */
	pool_unref(&pool);
	test_end();
	return FATAL_TEST_FINISHED;
}
Пример #19
0
static int
cmd_user_input(const char *auth_socket_path, const struct authtest_input *input,
	       const char *show_field, bool userdb)
{
	const char *lookup_name = userdb ? "userdb lookup" : "passdb lookup";
	struct auth_master_connection *conn;
	pool_t pool;
	const char *username, *const *fields, *p;
	int ret;

	if (auth_socket_path == NULL) {
		auth_socket_path = t_strconcat(doveadm_settings->base_dir,
					       "/auth-userdb", NULL);
	}

	pool = pool_alloconly_create("auth master lookup", 1024);

	conn = auth_master_init(auth_socket_path, 0);
	if (userdb) {
		ret = auth_master_user_lookup(conn, input->username, &input->info,
					      pool, &username, &fields);
	} else {
		ret = auth_master_pass_lookup(conn, input->username, &input->info,
					      pool, &fields);
	}
	if (ret < 0) {
		if (fields[0] == NULL)
			i_error("%s failed for %s", lookup_name, input->username);
		else {
			i_error("%s failed for %s: %s", lookup_name,
				input->username, fields[0]);
		}
	} else if (ret == 0) {
		fprintf(show_field == NULL ? stdout : stderr,
			"%s: user %s doesn't exist\n", lookup_name,
			input->username);
	} else if (show_field != NULL) {
		unsigned int show_field_len = strlen(show_field);

		for (; *fields; fields++) {
			if (strncmp(*fields, show_field, show_field_len) == 0 &&
			    (*fields)[show_field_len] == '=')
				printf("%s\n", *fields + show_field_len + 1);
		}
	} else {
		printf("%s: %s\n", userdb ? "userdb" : "passdb", input->username);

		for (; *fields; fields++) {
			p = strchr(*fields, '=');
			if (p == NULL)
				printf("  %-10s\n", *fields);
			else {
				printf("  %-10s: %s\n",
				       t_strcut(*fields, '='), p + 1);
			}
		}
	}
	auth_master_deinit(&conn);
	return ret;
}
Пример #20
0
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, MAIL_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 = SDBOX_STORAGE(storage);
	return &mbox->box;
}
Пример #21
0
static void test_imap_match_globs_equal(void)
{
	struct imap_match_glob *glob;
	pool_t pool;

	pool = pool_alloconly_create("imap match globs equal", 1024);
	test_begin("imap match globs equal");

	glob = imap_match_init(pool, "1", FALSE, '/');
	test_assert(imap_match_globs_equal(glob,
		imap_match_init(pool, "1", FALSE, '/')));
	test_assert(imap_match_globs_equal(glob,
		imap_match_init(pool, "1", TRUE, '/')));
	test_assert(!imap_match_globs_equal(glob,
		imap_match_init(pool, "1", FALSE, '.')));
	test_assert(!imap_match_globs_equal(glob,
		imap_match_init(pool, "11", FALSE, '/')));

	glob = imap_match_init(pool, "in%", TRUE, '/');
	test_assert(!imap_match_globs_equal(glob,
		imap_match_init(pool, "in%", FALSE, '/')));
	test_assert(!imap_match_globs_equal(glob,
		imap_match_init(pool, "In%", TRUE, '/')));

	pool_unref(&pool);
	test_end();
}
Пример #22
0
static int
cmd_deduplicate_box(struct doveadm_mail_cmd_context *_ctx,
		    const struct mailbox_info *info,
		    struct mail_search_args *search_args)
{
	struct deduplicate_cmd_context *ctx =
		(struct deduplicate_cmd_context *)_ctx;
	struct doveadm_mail_iter *iter;
	struct mailbox *box;
	struct mail *mail;
	enum mail_error error;
	pool_t pool;
	HASH_TABLE(const char *, struct uidlist *) hash;
	const char *key, *errstr;
	struct uidlist *value;
	int ret = 0;

	if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL,
				   &iter) < 0)
		return -1;

	pool = pool_alloconly_create("deduplicate", 10240);
	hash_table_create(&hash, pool, 0, str_hash, strcmp);
	while (doveadm_mail_iter_next(iter, &mail)) {
		if (ctx->by_msgid) {
			if (mail_get_first_header(mail, "Message-ID", &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup Message-ID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		} else {
			if (mail_get_special(mail, MAIL_FETCH_GUID, &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup GUID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		}
		if (key != NULL && *key != '\0') {
			value = p_new(pool, struct uidlist, 1);
			value->uid = mail->uid;
			value->next = hash_table_lookup(hash, key);

			if (value->next == NULL) {
				key = p_strdup(pool, key);
				hash_table_insert(hash, key, value);
			} else {
				hash_table_update(hash, key, value);
			}
		}
	}
Пример #23
0
struct auth_client_request *
auth_client_request_new(struct auth_client *client,
			const struct auth_request_info *request_info,
			auth_request_callback_t *callback, void *context)
{
	struct auth_client_request *request;
	pool_t pool;

	pool = pool_alloconly_create("auth client request", 512);
	request = p_new(pool, struct auth_client_request, 1);
	request->pool = pool;
	request->conn = client->conn;

	request->request_info = *request_info;
	request->request_info.mech = p_strdup(pool, request_info->mech);
	request->request_info.service = p_strdup(pool, request_info->service);
	request->request_info.session_id =
		p_strdup_empty(pool, request_info->session_id);
	request->request_info.cert_username =
		p_strdup_empty(pool, request_info->cert_username);
	request->request_info.initial_resp_base64 =
		p_strdup_empty(pool, request_info->initial_resp_base64);
	
	request->callback = callback;
	request->context = context;

	request->id =
		auth_server_connection_add_request(request->conn, request);
	request->created = ioloop_time;
	T_BEGIN {
		auth_server_send_new_request(request->conn, request);
	} T_END;
	return request;
}
static void test_message_parser_small_blocks(void)
{
	struct message_parser_ctx *parser;
	struct istream *input;
	struct message_part *parts, *parts2;
	struct message_block block;
	unsigned int i, end_of_headers_idx;
	pool_t pool;
	int ret;

	test_begin("message parser in small blocks");
	pool = pool_alloconly_create("message parser", 10240);
	input = test_istream_create(test_msg);

	/* full parsing */
	parser = message_parser_init(pool, input, 0, 0);
	while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
	test_assert(ret < 0);
	test_assert(message_parser_deinit(&parser, &parts) == 0);

	/* parsing in small blocks */
	i_stream_seek(input, 0);
	test_istream_set_allow_eof(input, FALSE);

	parser = message_parser_init(pool, input, 0, 0);
	for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
		test_istream_set_size(input, i/2);
		if (i > TEST_MSG_LEN*2)
			test_istream_set_allow_eof(input, TRUE);
		while ((ret = message_parser_parse_next_block(parser,
							      &block)) > 0) ;
		test_assert((ret == 0 && i <= TEST_MSG_LEN*2) ||
			    (ret < 0 && i > TEST_MSG_LEN*2));
	}
	test_assert(message_parser_deinit(&parser, &parts2) == 0);
	test_assert(msg_parts_cmp(parts, parts2));

	/* parsing in small blocks from preparsed parts */
	i_stream_seek(input, 0);
	test_istream_set_allow_eof(input, FALSE);

	end_of_headers_idx = (strstr(test_msg, "\n-----") - test_msg);
	parser = message_parser_init_from_parts(parts, input, 0,
					MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
	for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
		test_istream_set_size(input, i/2);
		if (i > TEST_MSG_LEN*2)
			test_istream_set_allow_eof(input, TRUE);
		while ((ret = message_parser_parse_next_block(parser,
							      &block)) > 0) ;
		test_assert((ret == 0 && i/2 <= end_of_headers_idx) ||
			    (ret < 0 && i/2 > end_of_headers_idx));
	}
	test_assert(message_parser_deinit(&parser, &parts2) == 0);
	test_assert(msg_parts_cmp(parts, parts2));

	i_stream_unref(&input);
	pool_unref(&pool);
	test_end();
}
Пример #25
0
static void doveadm_print_formatted_init(void)
{
	memset(&ctx,0,sizeof(ctx));
	ctx.pool = pool_alloconly_create("doveadm formatted print", 1024);
	ctx.buf = str_new(ctx.pool, 256);
	p_array_init(&ctx.headers, ctx.pool, 8);
	ctx.idx = 0;
}
Пример #26
0
int pop3c_sync_get_uidls(struct pop3c_mailbox *mbox)
{
	ARRAY_TYPE(const_string) uidls;
	struct istream *input;
	const char *error, *cline;
	char *line, *p;
	unsigned int seq, line_seq;

	if (mbox->msg_uidls != NULL)
		return 0;
	if ((pop3c_client_get_capabilities(mbox->client) &
	     POP3C_CAPABILITY_UIDL) == 0) {
		mail_storage_set_error(mbox->box.storage,
				       MAIL_ERROR_NOTPOSSIBLE,
				       "UIDLs not supported by server");
		return -1;
	}

	if (pop3c_client_cmd_stream(mbox->client, "UIDL\r\n",
				    &input, &error) < 0) {
		mail_storage_set_critical(mbox->box.storage,
					  "UIDL failed: %s", error);
		return -1;
	}

	mbox->uidl_pool = pool_alloconly_create("POP3 UIDLs", 1024*32);
	p_array_init(&uidls, mbox->uidl_pool, 64); seq = 0;
	while ((line = i_stream_read_next_line(input)) != NULL) {
		seq++;
		p = strchr(line, ' ');
		if (p == NULL) {
			mail_storage_set_critical(mbox->box.storage,
				"Invalid UIDL line: %s", line);
			break;
		}
		*p++ = '\0';
		if (str_to_uint(line, &line_seq) < 0 || line_seq != seq) {
			mail_storage_set_critical(mbox->box.storage,
				"Unexpected UIDL seq: %s != %u", line, seq);
			break;
		}

		cline = p_strdup(mbox->uidl_pool, p);
		array_append(&uidls, &cline, 1);
	}
	i_stream_destroy(&input);
	if (line != NULL) {
		pool_unref(&mbox->uidl_pool);
		return -1;
	}
	if (seq == 0) {
		/* make msg_uidls non-NULL */
		array_append_zero(&uidls);
	}
	mbox->msg_uidls = array_idx(&uidls, 0);
	mbox->msg_count = seq;
	return 0;
}
Пример #27
0
static void doveadm_print_flow_init(void)
{
	pool_t pool;

	pool = pool_alloconly_create("doveadm print flow", 1024);
	ctx = p_new(pool, struct doveadm_print_flow_context, 1);
	ctx->pool = pool;
	p_array_init(&ctx->headers, pool, 16);
}
Пример #28
0
void env_put(const char *env)
{
	if (env_pool == NULL) {
		env_pool = pool_alloconly_create(MEMPOOL_GROWING"Environment",
						 2048);
	}
	if (putenv(p_strdup(env_pool, env)) != 0)
		i_fatal("putenv(%s) failed: %m", env);
}
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;
}
Пример #30
0
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;
}