示例#1
0
static int
zlib_mailbox_transaction_commit(struct mailbox_transaction_context *t,
				struct mail_transaction_commit_changes *changes_r)
{
	union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
	struct zlib_transaction_context *zt = ZLIB_CONTEXT(t);
	int ret;

	if (zt->tmp_mail != NULL)
		mail_free(&zt->tmp_mail);

	ret = zbox->super.transaction_commit(t, changes_r);
	i_free(zt);
	return ret;
}
示例#2
0
int message_search_msg(struct message_search_context *ctx,
		       struct istream *input, struct message_part *parts,
		       const char **error_r)
{
	char *error;
	int ret;

	T_BEGIN {
		ret = message_search_msg_real(ctx, input, parts, error_r);
		error = i_strdup(*error_r);
	} T_END;
	*error_r = t_strdup(error);
	i_free(error);
	return ret;
}
示例#3
0
static void tcpwrap_client_destroy(struct tcpwrap_client **_client)
{
	struct tcpwrap_client *client = *_client;

	*_client = NULL;

	timeout_remove(&client->to);
	io_remove(&client->io);
	if (close(client->fd) < 0)
		i_error("close() failed: %m");
	i_free(client);

	tcpwrap_client = NULL;
	master_service_client_connection_destroyed(master_service);
}
示例#4
0
static void
index_sort_list_finish_float(struct mail_search_sort_program *program)
{
	ARRAY_TYPE(mail_sort_node_float) *nodes = program->context;

	/* NOTE: higher relevancy is returned first, unlike with all
	   other number based sort keys, so temporarily reverse the search */
	static_node_cmp_context.reverse = !static_node_cmp_context.reverse;
	array_sort(nodes, sort_node_float_cmp);
	static_node_cmp_context.reverse = !static_node_cmp_context.reverse;

	memcpy(&program->seqs, nodes, sizeof(program->seqs));
	i_free(nodes);
	program->context = NULL;
}
示例#5
0
void client_destroy(struct client *client, const char *prefix,
		    const char *reason)
{
	if (client->destroyed)
		return;
	client->destroyed = TRUE;

	client_disconnect(client, prefix, reason);

	submission_client_count--;
	DLLIST_REMOVE(&submission_clients, client);

	if (client->proxy_conn != NULL)
		smtp_client_connection_close(&client->proxy_conn);

	if (client->anvil_sent) {
		master_service_anvil_send(master_service, t_strconcat(
			"DISCONNECT\t", my_pid, "\tsubmission/",
			mail_user_get_anvil_userip_ident(client->user),
			"\n", NULL));
	}

	if (client->urlauth_ctx != NULL)
		imap_urlauth_deinit(&client->urlauth_ctx);

	mail_user_unref(&client->user);
	mail_storage_service_user_unref(&client->service_user);

	client_state_reset(client);

	i_free(client->session_id);
	i_free(client);

	master_service_client_connection_destroyed(master_service);
	submission_refresh_proctitle();
}
示例#6
0
void connection_list_deinit(struct connection_list **_list)
{
	struct connection_list *list = *_list;
	struct connection *conn;

	*_list = NULL;

	while (list->connections != NULL) {
		conn = list->connections;
		conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT;
		list->v.destroy(conn);
		i_assert(conn != list->connections);
	}
	i_free(list);
}
示例#7
0
文件: main.c 项目: Raffprta/core
static void login_access_lookup_free(struct login_access_lookup *lookup)
{
	if (lookup->io != NULL)
		io_remove(&lookup->io);
	if (lookup->access != NULL)
		access_lookup_destroy(&lookup->access);
	if (lookup->conn.fd != -1) {
		if (close(lookup->conn.fd) < 0)
			i_error("close(client) failed: %m");
		master_service_client_connection_destroyed(master_service);
	}

	p_strsplit_free(default_pool, lookup->sockets);
	i_free(lookup);
}
void mail_transaction_log_move_to_memory(struct mail_transaction_log *log)
{
	struct mail_transaction_log_file *file;

	if (!log->index->initial_mapped && log->files != NULL &&
	    log->files->hdr.prev_file_seq != 0) {
		/* we couldn't read dovecot.index and we don't have the first
		   .log file, so just start from scratch */
		mail_transaction_log_close(log);
	}

	i_free(log->filepath);
	i_free(log->filepath2);
	log->filepath = i_strconcat(log->index->filepath,
				    MAIL_TRANSACTION_LOG_SUFFIX, NULL);
	log->filepath2 = i_strconcat(log->filepath, ".2", NULL);

	if (log->head != NULL)
		mail_transaction_log_file_move_to_memory(log->head);
	else {
		file = mail_transaction_log_file_alloc_in_memory(log);
		mail_transaction_log_set_head(log, file);
	}
}
示例#9
0
void master_connection_destroy(struct master_connection **_conn)
{
	struct master_connection *conn = *_conn;

	*_conn = NULL;

	io_remove(&conn->io);
	i_stream_destroy(&conn->input);

	if (close(conn->fd) < 0)
		i_error("close(master conn) failed: %m");
	i_free(conn);

	master_service_client_connection_destroyed(master_service);
}
示例#10
0
void sieve_tool_set_homedir(struct sieve_tool *tool, const char *homedir)
{
	if ( tool->homedir != NULL ) {
		if ( strcmp(homedir, tool->homedir) == 0 )
			return;

		i_free(tool->homedir);
	}

	tool->homedir = i_strdup(homedir);

	if ( tool->mail_user_dovecot != NULL )
		mail_user_set_home(tool->mail_user_dovecot, tool->homedir);
	if ( tool->mail_user != NULL )
		mail_user_set_home(tool->mail_user, tool->homedir);
}
示例#11
0
void mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
				  const void *data, size_t size)
{
	const struct mail_index_registered_ext *rext;

	i_assert(index->ext_hdr_init_data == NULL ||
		 index->ext_hdr_init_id == ext_id);

	rext = array_idx(&index->extensions, ext_id);
	i_assert(rext->hdr_size == size);

	index->ext_hdr_init_id = ext_id;
	i_free(index->ext_hdr_init_data);
	index->ext_hdr_init_data = i_malloc(size);
	memcpy(index->ext_hdr_init_data, data, size);
}
int mail_storage_service_next(struct mail_storage_service_ctx *ctx,
			      struct mail_storage_service_user *user,
			      struct mail_user **mail_user_r)
{
	char *old_log_prefix = i_strdup(i_get_failure_prefix());
	int ret;

	mail_storage_service_set_log_prefix(ctx, user->user_set, user,
					    &user->input, NULL);
	i_set_failure_prefix("%s", old_log_prefix);
	ret = mail_storage_service_next_real(ctx, user, mail_user_r);
	if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) != 0)
		i_set_failure_prefix("%s", old_log_prefix);
	i_free(old_log_prefix);
	return ret;
}
示例#13
0
void replicator_connection_destroy(struct replicator_connection **_conn)
{
	struct replicator_connection *conn = *_conn;
	unsigned int i;

	*_conn = NULL;
	replicator_connection_disconnect(conn);

	for (i = REPLICATION_PRIORITY_LOW; i <= REPLICATION_PRIORITY_SYNC; i++)
		buffer_free(&conn->queue[i]);

	if (conn->to != NULL)
		timeout_remove(&conn->to);
	hash_table_destroy(&conn->requests);
	i_free(conn);
}
示例#14
0
static void dns_client_destroy(struct dns_client **_client)
{
	struct dns_client *client = *_client;

	*_client = NULL;

	io_remove(&client->io);
	i_stream_destroy(&client->input);
	o_stream_destroy(&client->output);
	if (close(client->fd) < 0)
		i_error("close() failed: %m");
	i_free(client);

	dns_client = NULL;
	master_service_client_connection_destroyed(master_service);
}
示例#15
0
static void fts_parser_tika_deinit(struct fts_parser *_parser)
{
	struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser;

	if (parser->ioloop != NULL) {
		io_remove(&parser->io);
		io_loop_destroy(&parser->ioloop);
	}
	if (parser->payload != NULL)
		i_stream_unref(&parser->payload);
	/* FIXME: kludgy, http_req should be NULL here if we don't want to
	   free it. requires lib-http changes. */
	if (parser->http_req != NULL)
		http_client_request_abort(&parser->http_req);
	i_free(parser);
}
void notify_contexts_mail_transaction_commit(struct mailbox_transaction_context *t,
					     struct mail_transaction_commit_changes *changes)
{
	struct notify_context *ctx;
	struct notify_mail_txn *mail_txn;

	for (ctx = ctx_list; ctx != NULL; ctx = ctx->next) {
		if (ctx->v.mail_transaction_commit == NULL)
			continue;
		mail_txn = notify_context_find_mail_txn(ctx, t);
		if (ctx->v.mail_transaction_commit != NULL)
			ctx->v.mail_transaction_commit(mail_txn->txn, changes);
		DLLIST_REMOVE(&ctx->mail_txn_list, mail_txn);
		i_free(mail_txn);
	}
}
static int
imap_client_auth_begin(struct imap_client *imap_client, const char *mech_name,
		       const char *init_resp)
{
	char *prefix;

	prefix = i_strdup_printf("%d%s",
			imap_client->client_ignores_capability_resp_code,
			imap_client->cmd_tag);

	i_free(imap_client->common.master_data_prefix);
	imap_client->common.master_data_prefix = (void *)prefix;
	imap_client->common.master_data_prefix_len = strlen(prefix)+1;

	return client_auth_begin(&imap_client->common, mech_name, init_resp);
}
示例#18
0
int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx,
			      struct mailbox_sync_status *status_r)
{
	struct index_mailbox_sync_context *ctx =
		(struct index_mailbox_sync_context *)_ctx;
	struct mailbox_sync_rec sync_rec;
	bool delayed_expunges = FALSE;
	int ret = ctx->failed ? -1 : 0;

	/* finish handling expunges, so we don't break when updating
	   recent flags */
	while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ;

	/* convert sequences to uids before syncing view */
	index_sync_search_results_uidify(ctx);

	if (ctx->sync_ctx != NULL) {
		if (mail_index_view_sync_commit(&ctx->sync_ctx,
						&delayed_expunges) < 0) {
			mailbox_set_index_error(_ctx->box);
			ret = -1;
		}
	}
	index_mailbox_expunge_unseen_recent(ctx);

	if ((_ctx->box->flags & MAILBOX_FLAG_DROP_RECENT) == 0 &&
	    _ctx->box->opened) {
		/* mailbox syncing didn't necessarily update our recent state */
		index_sync_update_recent_count(_ctx->box);
	}

	if (status_r != NULL)
		status_r->sync_delayed_expunges = delayed_expunges;

	/* update search results after private index is updated */
	index_sync_search_results_update(ctx);

	if (array_is_created(&ctx->flag_updates))
		array_free(&ctx->flag_updates);
	if (array_is_created(&ctx->hidden_updates))
		array_free(&ctx->hidden_updates);
	if (array_is_created(&ctx->all_flag_update_uids))
		array_free(&ctx->all_flag_update_uids);

	i_free(ctx);
	return ret;
}
void io_loop_handler_run(struct ioloop *ioloop)
{
	struct ioloop_handler_context *ctx = ioloop->handler_context;
	struct kevent *events;
	const struct kevent *event;
	struct timeval tv;
	struct timespec ts;
	struct io_file *io;
	unsigned int events_count;
	int ret, i;

	/* get the time left for next timeout task */
	io_loop_get_wait_time(ioloop, &tv);
	ts.tv_sec = tv.tv_sec;
	ts.tv_nsec = tv.tv_usec * 1000;

	/* wait for events */
	events = array_get_modifiable(&ctx->events, &events_count);
	ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts);
	if (ret < 0 && errno != EINTR)
		i_fatal("kevent(): %m");

	/* reference all IOs */
	for (i = 0; i < ret; i++) {
		io = (void *)events[i].udata;
		i_assert(io->refcount > 0);
		io->refcount++;
	}

	/* execute timeout handlers */
	io_loop_handle_timeouts(ioloop);

	for (i = 0; i < ret; i++) {
		/* io_loop_handle_add() may cause events array reallocation,
		   so we have use array_idx() */
		event = array_idx(&ctx->events, i);
		io = (void *)event->udata;

		/* callback is NULL if io_remove() was already called */
		if (io->io.callback != NULL)
			io_loop_call_io(&io->io);

		i_assert(io->refcount > 0);
		if (--io->refcount == 0)
			i_free(io);
	}
}
示例#20
0
static int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx)
{
	struct sql_userdb_iterate_context *ctx =
		(struct sql_userdb_iterate_context *)_ctx;
	int ret = _ctx->failed ? -1 : 0;

	auth_request_unref(&_ctx->auth_request);
	if (ctx->result == NULL) {
		/* sql query hasn't finished yet */
		ctx->freed = TRUE;
	} else {
		if (ctx->result != NULL)
			sql_result_unref(ctx->result);
		i_free(ctx);
	}
	return ret;
}
示例#21
0
static void stats_transaction_free(struct stats_user *suser,
				   struct stats_transaction_context *strans)
{
	const struct mailbox_transaction_stats *src = &strans->trans->stats;
	struct mailbox_transaction_stats *dest =
		&suser->finished_transaction_stats;

	DLLIST_REMOVE(&suser->transactions, strans);

	dest->open_lookup_count += src->open_lookup_count;
	dest->stat_lookup_count += src->stat_lookup_count;
	dest->fstat_lookup_count += src->fstat_lookup_count;
	dest->files_read_count += src->files_read_count;
	dest->files_read_bytes += src->files_read_bytes;
	dest->cache_hit_count += src->cache_hit_count;
	i_free(strans);
}
示例#22
0
文件: faction.c 项目: eressea/server
static void give_special_items(unit *u, item **items) {
    item **iter = items;
    while (*iter) {
        item *itm = *iter;
        if (itm->number > 0 && itm->type->flags & ITF_NOTLOST) {
            i_change(&u->items, itm->type, itm->number);
            *iter = itm->next;
            if (iter == items) {
                *items = *iter;
            }
            i_free(itm);
        }
        else {
            iter = &itm->next;
        }
    }
}
示例#23
0
void mail_index_transaction_unref(struct mail_index_transaction **_t)
{
	struct mail_index_transaction *t = *_t;

	*_t = NULL;
	if (--t->refcount > 0)
		return;

	mail_index_transaction_reset_v(t);

	array_free(&t->module_contexts);
	mail_index_view_transaction_unref(t->view);
	if (t->latest_view != NULL)
		mail_index_view_close(&t->latest_view);
	mail_index_view_close(&t->view);
	i_free(t);
}
static void
auth_postfix_connection_unref(struct auth_postfix_connection **_conn)
{
	struct auth_postfix_connection *conn = *_conn;

	*_conn = NULL;
	i_assert(conn->refcount > 0);

	if (--conn->refcount > 0)
		return;

	if (conn->input != NULL)
		i_stream_unref(&conn->input);
	if (conn->output != NULL)
		o_stream_unref(&conn->output);
	i_free(conn);
}
struct mail_transaction_log_file *
mail_transaction_log_file_alloc_in_memory(struct mail_transaction_log *log)
{
	struct mail_transaction_log_file *file;

	file = mail_transaction_log_file_alloc(log, MEMORY_LOG_NAME);
	if (mail_transaction_log_init_hdr(log, &file->hdr) < 0) {
		i_free(file);
		return NULL;
	}

	file->buffer = buffer_create_dynamic(default_pool, 4096);
	file->buffer_offset = sizeof(file->hdr);

	mail_transaction_log_file_add_to_list(file);
	return file;
}
示例#26
0
int cmd_lhlo(struct client *client, const char *args)
{
	struct rfc822_parser_context parser;
	string_t *domain = t_str_new(128);
	const char *p;
	int ret = 0;

	if (*args == '\0') {
		client_send_line(client, "501 Missing hostname");
		return 0;
	}

	/* domain / address-literal */
	rfc822_parser_init(&parser, (const unsigned char *)args, strlen(args),
			   NULL);
	if (*args != '[')
		ret = rfc822_parse_dot_atom(&parser, domain);
	else {
		for (p = args+1; *p != ']'; p++) {
			if (*p == '\\' || *p == '[')
				break;
		}
		if (strcmp(p, "]") != 0)
			ret = -1;
	}
	if (ret < 0) {
		str_truncate(domain, 0);
		str_append(domain, "invalid");
	}

	client_state_reset(client, "LHLO");
	client_send_line(client, "250-%s", client->my_domain);
	if (master_service_ssl_is_enabled(master_service) &&
	    client->ssl_iostream == NULL)
		client_send_line(client, "250-STARTTLS");
	if (client_is_trusted(client))
		client_send_line(client, "250-XCLIENT ADDR PORT TTL TIMEOUT");
	client_send_line(client, "250-8BITMIME");
	client_send_line(client, "250-ENHANCEDSTATUSCODES");
	client_send_line(client, "250 PIPELINING");

	i_free(client->lhlo);
	client->lhlo = i_strdup(str_c(domain));
	client_state_set(client, "LHLO", "");
	return 0;
}
示例#27
0
void io_loop_notify_remove(struct io *_io)
{
	struct ioloop_notify_handler_context *ctx =
		_io->ioloop->notify_handler_context;
	struct io_notify *io = (struct io_notify *)_io;
	struct kevent ev;

	MY_EV_SET(&ev, io->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
	if (kevent(ctx->kq, &ev, 1, NULL, 0, 0) < 0)
		i_error("kevent(%d) for notify remove failed: %m", io->fd);
	if (close(io->fd) < 0)
		i_error("close(%d) for notify remove failed: %m", io->fd);
	io->fd = -1;

	if (--io->refcount == 0)
		i_free(io);
}
示例#28
0
static int proxy_input_banner(struct imap_client *client,
			      struct ostream *output, const char *line)
{
	const char *const *capabilities = NULL;
	string_t *str;
	int ret;

	if (!str_begins(line, "* OK ")) {
		client_log_err(&client->common, t_strdup_printf(
			"proxy: Remote returned invalid banner: %s",
			str_sanitize(line, 160)));
		return -1;
	}

	str = t_str_new(128);
	if (str_begins(line + 5, "[CAPABILITY ")) {
		capabilities = t_strsplit(t_strcut(line + 5 + 12, ']'), " ");
		if (str_array_icase_find(capabilities, "SASL-IR"))
			client->proxy_sasl_ir = TRUE;
		if (str_array_icase_find(capabilities, "LOGINDISABLED"))
			client->proxy_logindisabled = TRUE;
		i_free(client->proxy_backend_capability);
		client->proxy_backend_capability =
			i_strdup(t_strcut(line + 5 + 12, ']'));
		if (str_array_icase_find(capabilities, "ID") &&
		    !client->common.proxy_not_trusted) {
			client->proxy_sent_state |= IMAP_PROXY_SENT_STATE_ID;
			proxy_write_id(client, str);
			if (client->common.proxy_nopipelining) {
				/* write login or starttls after I OK */
				o_stream_nsend(output, str_data(str), str_len(str));
				return 0;
			}
		}
	}

	if ((ret = proxy_write_starttls(client, str)) < 0) {
		return -1;
	} else if (ret == 0) {
		if (proxy_write_login(client, str) < 0)
			return -1;
	}

	o_stream_nsend(output, str_data(str), str_len(str));
	return 0;
}
示例#29
0
static int proxy_input_banner(struct imap_client *client,
			      struct ostream *output, const char *line)
{
	enum login_proxy_ssl_flags ssl_flags;
	const char *const *capabilities = NULL;
	string_t *str;

	if (strncmp(line, "* OK ", 5) != 0) {
		client_log_err(&client->common, t_strdup_printf(
			"proxy: Remote returned invalid banner: %s",
			str_sanitize(line, 160)));
		return -1;
	}

	str = t_str_new(128);
	if (strncmp(line + 5, "[CAPABILITY ", 12) == 0) {
		capabilities = t_strsplit(t_strcut(line + 5 + 12, ']'), " ");
		if (str_array_icase_find(capabilities, "ID"))
			proxy_write_id(client, str);
		if (str_array_icase_find(capabilities, "SASL-IR"))
			client->proxy_sasl_ir = TRUE;
		if (str_array_icase_find(capabilities, "LOGINDISABLED"))
			client->proxy_logindisabled = TRUE;
		i_free(client->proxy_backend_capability);
		client->proxy_backend_capability =
			i_strdup(t_strcut(line + 5 + 12, ']'));
	}

	ssl_flags = login_proxy_get_ssl_flags(client->common.login_proxy);
	if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) != 0) {
		if (capabilities != NULL &&
		    !str_array_icase_find(capabilities, "STARTTLS")) {
			client_log_err(&client->common,
				"proxy: Remote doesn't support STARTTLS");
			return -1;
		}
		str_append(str, "S STARTTLS\r\n");
	} else {
		if (proxy_write_login(client, str) < 0)
			return -1;
	}

	o_stream_nsend(output, str_data(str), str_len(str));
	return 0;
}
示例#30
0
static int userdb_dict_iterate_deinit(struct userdb_iterate_context *_ctx)
{
	struct dict_userdb_iterate_context *ctx =
		(struct dict_userdb_iterate_context *)_ctx;
	const char *error;
	int ret = _ctx->failed ? -1 : 0;

	if (ctx->iter != NULL) {
		if (dict_iterate_deinit(&ctx->iter, &error) < 0) {
			i_error("dict_iterate(%s) failed: %s",
				ctx->key_prefix, error);
			ret = -1;
		}
	}
	auth_request_unref(&ctx->ctx.auth_request);
	i_free(ctx);
	return ret;
}