static void test_seq_range_array_remove_nth(void)
{
	ARRAY_TYPE(seq_range) range;
	const struct seq_range *r;

	test_begin("seq_range_array_remove_nth()");
	t_array_init(&range, 8);
	seq_range_array_add_range(&range, 1, 5);
	seq_range_array_add(&range, 7);
	seq_range_array_add_range(&range, 10,20);
	test_assert(array_count(&range) == 3);

	seq_range_array_remove_nth(&range, 0, 2);
	r = array_idx(&range, 0); test_assert(r->seq1 == 3 && r->seq2 == 5);

	seq_range_array_remove_nth(&range, 1, 4);
	r = array_idx(&range, 0); test_assert(r->seq1 == 3 && r->seq2 == 3);
	r = array_idx(&range, 1); test_assert(r->seq1 == 11 && r->seq2 == 20);

	seq_range_array_remove_nth(&range, 5, (uint32_t)-1);
	r = array_idx(&range, 1); test_assert(r->seq1 == 11 && r->seq2 == 14);

	test_assert(array_count(&range) == 2);
	test_end();
}
Beispiel #2
0
int acl_rights_update_import(struct acl_rights_update *update,
			     const char *id, const char *const *rights,
			     const char **error_r)
{
	ARRAY_TYPE(const_string) dest_rights, dest_neg_rights, *dest;
	unsigned int i, j;

	if (acl_identifier_parse(id, &update->rights) < 0) {
		*error_r = t_strdup_printf("Invalid ID: %s", id);
		return -1;
	}
	if (rights == NULL) {
		update->modify_mode = ACL_MODIFY_MODE_CLEAR;
		update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR;
		return 0;
	}

	t_array_init(&dest_rights, 8);
	t_array_init(&dest_neg_rights, 8);
	for (i = 0; rights[i] != NULL; i++) {
		const char *right = rights[i];

		if (right[0] != '-')
			dest = &dest_rights;
		else {
			right++;
			dest = &dest_neg_rights;
		}
		if (strcmp(right, "all") != 0) {
			if (*right == ':') {
				/* non-standard right */
				right++;
				array_append(dest, &right, 1);
			} else if (is_standard_right(right)) {
				array_append(dest, &right, 1);
			} else {
				*error_r = t_strdup_printf("Invalid right '%s'",
							   right);
				return -1;
			}
		} else {
			for (j = 0; all_mailbox_rights[j] != NULL; j++)
				array_append(dest, &all_mailbox_rights[j], 1);
		}
	}
	if (array_count(&dest_rights) > 0) {
		array_append_zero(&dest_rights);
		update->rights.rights = array_idx(&dest_rights, 0);
	} else if (update->modify_mode == ACL_MODIFY_MODE_REPLACE) {
		update->modify_mode = ACL_MODIFY_MODE_CLEAR;
	}
	if (array_count(&dest_neg_rights) > 0) {
		array_append_zero(&dest_neg_rights);
		update->rights.neg_rights = array_idx(&dest_neg_rights, 0);
	} else if (update->neg_modify_mode == ACL_MODIFY_MODE_REPLACE) {
		update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR;
	}
	return 0;
}
Beispiel #3
0
void io_loop_handler_run_internal(struct ioloop *ioloop)
{
	struct ioloop_handler_context *ctx = ioloop->handler_context;
	struct epoll_event *events;
	const struct epoll_event *event;
	struct io_list *list;
	struct io_file *io;
	struct timeval tv;
	unsigned int events_count;
	int msecs, ret, i, j;
	bool call;

        /* get the time left for next timeout task */
	msecs = io_loop_get_wait_time(ioloop, &tv);

	events = array_get_modifiable(&ctx->events, &events_count);
	if (ioloop->io_files != NULL && events_count > ctx->deleted_count) {
		ret = epoll_wait(ctx->epfd, events, events_count, msecs);
		if (ret < 0 && errno != EINTR)
			i_fatal("epoll_wait(): %m");
	} else {
		/* no I/Os, but we should have some timeouts.
		   just wait for them. */
		i_assert(msecs >= 0);
		usleep(msecs*1000);
		ret = 0;
	}

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

	if (!ioloop->running)
		return;

	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);
		list = event->data.ptr;

		for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
			io = list->ios[j];
			if (io == NULL)
				continue;

			call = FALSE;
			if ((event->events & (EPOLLHUP | EPOLLERR)) != 0)
				call = TRUE;
			else if ((io->io.condition & IO_READ) != 0)
				call = (event->events & EPOLLIN) != 0;
			else if ((io->io.condition & IO_WRITE) != 0)
				call = (event->events & EPOLLOUT) != 0;
			else if ((io->io.condition & IO_ERROR) != 0)
				call = (event->events & IO_EPOLL_ERROR) != 0;

			if (call)
				io_loop_call_io(&io->io);
		}
	}
}
Beispiel #4
0
void smtp_server_command_fail(struct smtp_server_command *cmd,
			      unsigned int status, const char *enh_code,
			      const char *fmt, ...)
{
	unsigned int i;
	va_list args;

	i_assert(status / 100 > 2);

	va_start(args, fmt);
	if (cmd->replies_expected == 1) {
		smtp_server_reply_indexv(&cmd->context, 0,
					 status, enh_code, fmt, args);
	} else for (i = 0; i < cmd->replies_expected; i++) {
		bool sent = FALSE;

		if (array_is_created(&cmd->replies)) {
			const struct smtp_server_reply *reply =
				array_idx(&cmd->replies, i);
			sent = reply->sent;
		}
	
		/* send the same reply for all */
		if (!sent) {
			va_list args_copy;
			VA_COPY(args_copy, args);
			smtp_server_reply_indexv(&cmd->context, i,
				status, enh_code, fmt, args_copy);
			va_end(args_copy);
		}
	}
	va_end(args);
}
Beispiel #5
0
rstatus_t
conf_server_each_transform(void *elem, void *data)
{
    struct string *group = elem;
    struct array *server = data;
    struct server *s;

    s = array_push(server);
    ASSERT(s != NULL);

    s->idx = array_idx(server, s);
    s->owner = NULL;

    string_init(&s->pname);
    s->name = *group;/* ref */
    string_init(&s->addrstr);
    s->port = 0;
    s->weight = 1;
    memset(&s->info, 0, sizeof(s->info));
    s->ns_conn_q = 0;
    TAILQ_INIT(&s->s_conn_q);
    s->timer = NULL;
    s->status = 0; 

    log_debug(LOG_VERB, "transform to server %"PRIu32" '%.*s'",
              s->idx, group->len, group->data);

    return NC_OK;
}
Beispiel #6
0
int sieve_stringlist_read_all
(struct sieve_stringlist *strlist, pool_t pool,
	const char * const **list_r)
{
	if ( strlist->read_all == NULL ) {
		ARRAY(const char *) items;
		string_t *item;
		int ret;

		sieve_stringlist_reset(strlist);

		p_array_init(&items, pool, 4);

		item = NULL;
		while ( (ret=sieve_stringlist_next_item(strlist, &item)) > 0 ) {
			const char *stritem = p_strdup(pool, str_c(item));

			array_append(&items, &stritem, 1);
		}

		(void)array_append_space(&items);
		*list_r = array_idx(&items, 0);

		return ( ret < 0 ? -1 : 1 );
	}

	return strlist->read_all(strlist, pool, list_r);
}
Beispiel #7
0
static void
exec_child(struct master_service_connection *conn, const char *const *args)
{
	unsigned int i, socket_count;

	if (dup2(conn->fd, STDIN_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (dup2(conn->fd, STDOUT_FILENO) < 0)
		i_fatal("dup2() failed: %m");

	/* close all fds */
	socket_count = master_service_get_socket_count(master_service);
	for (i = 0; i < socket_count; i++) {
		if (close(MASTER_LISTEN_FD_FIRST + i) < 0)
			i_error("close(listener) failed: %m");
	}
	if (close(MASTER_STATUS_FD) < 0)
		i_error("close(status) failed: %m");
	if (close(conn->fd) < 0)
		i_error("close(conn->fd) failed: %m");

	for (; *args != NULL; args++)
		array_append(&exec_args, args, 1);
	array_append_zero(&exec_args);

	env_clean();
	args = array_idx(&exec_args, 0);
	execvp_const(args[0], args);
}
static
void ldap_connection_abort_request(struct ldap_op_queue_entry *req)
{
	struct ldap_result res;

	/* too bad */
	if (req->to_abort != NULL)
		timeout_remove(&req->to_abort);
	if (req->msgid > -1)
		ldap_abandon_ext(req->conn->conn, req->msgid, NULL, NULL);

	memset(&res, 0, sizeof(res));
	res.openldap_ret = LDAP_TIMEOUT;
	res.error_string = "Aborting LDAP request after timeout";
	if (req->result_callback != NULL)
		req->result_callback(&res, req->result_callback_ctx);

	unsigned int n = aqueue_count(req->conn->request_queue);
	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(req->conn->request_array),
				  aqueue_idx(req->conn->request_queue, i));
		if (req == *reqp) {
			aqueue_delete(req->conn->request_queue, i);
			ldap_connection_request_destroy(&req);
			return;
		}
	}
	i_unreached();
}
int
mail_index_sync_keywords_reset(struct mail_index_sync_map_ctx *ctx,
			       const struct mail_transaction_header *hdr,
			       const struct mail_transaction_keyword_reset *r)
{
	struct mail_index_map *map = ctx->view->map;
	struct mail_index_record *rec;
	const struct mail_index_ext *ext;
	const struct mail_transaction_keyword_reset *end;
	uint32_t ext_map_idx, seq1, seq2;

	if (!mail_index_map_lookup_ext(map, MAIL_INDEX_EXT_KEYWORDS,
				       &ext_map_idx)) {
		/* nothing to do */
		return 1;
	}

	ext = array_idx(&map->extensions, ext_map_idx);
	end = CONST_PTR_OFFSET(r, hdr->size);
	for (; r != end; r++) {
		if (!mail_index_lookup_seq_range(ctx->view, r->uid1, r->uid2,
						 &seq1, &seq2))
			continue;

		mail_index_modseq_reset_keywords(ctx->modseq_ctx, seq1, seq2);
		for (; seq1 <= seq2; seq1++) {
			rec = MAIL_INDEX_REC_AT_SEQ(map, seq1);
			memset(PTR_OFFSET(rec, ext->record_offset),
			       0, ext->record_size);
		}
	}
	return 1;
}
Beispiel #10
0
uint32_t imapc_msgmap_rseq_to_uid(struct imapc_msgmap *msgmap, uint32_t rseq)
{
    const uint32_t *uidp;

    uidp = array_idx(&msgmap->uids, rseq-1);
    return *uidp;
}
Beispiel #11
0
static void
mirror_get_remote_cmd_line(const char *const *argv,
			   const char *const **cmd_args_r)
{
	ARRAY_TYPE(const_string) cmd_args;
	unsigned int i;
	const char *p;

	i_assert(argv[0] != NULL);

	t_array_init(&cmd_args, 16);
	for (i = 0; argv[i] != NULL; i++) {
		p = argv[i];
		array_append(&cmd_args, &p, 1);
	}

	if (legacy_dsync) {
		/* we're executing dsync */
		p = "server";
	} else {
		/* we're executing doveadm */
		p = "dsync-server";
	}
	array_append(&cmd_args, &p, 1);
	array_append_zero(&cmd_args);
	*cmd_args_r = array_idx(&cmd_args, 0);
}
Beispiel #12
0
static void worker_connection_disconnect(struct worker_connection *conn)
{
	unsigned int i, count = aqueue_count(conn->request_queue);

	if (conn->fd != -1) {
		io_remove(&conn->io);
		i_stream_destroy(&conn->input);
		o_stream_destroy(&conn->output);

		if (close(conn->fd) < 0)
			i_error("close(%s) failed: %m", conn->socket_path);
		conn->fd = -1;
	}

	/* cancel any pending requests */
	if (count > 0) {
		i_error("Indexer worker disconnected, "
			"discarding %u requests for %s",
			count, conn->request_username);
	}

	/* conn->callback() can try to destroy us */
	conn->refcount++;
	for (i = 0; i < count; i++) {
		void *const *contextp =
			array_idx(&conn->request_contexts,
				  aqueue_idx(conn->request_queue, 0));
		void *context = *contextp;

		aqueue_delete_tail(conn->request_queue);
		conn->callback(-1, context);
	}
	i_free_and_null(conn->request_username);
	worker_connection_unref(conn);
}
Beispiel #13
0
rstatus_t
conf_server_each_transform(void *elem, void *data)
{
    struct conf_server *cs = elem;
    struct array *server = data;
    struct server *s;

    ASSERT(cs->valid);

    s = array_push(server);
    ASSERT(s != NULL);

    s->idx = array_idx(server, s);
    s->owner = NULL;

    s->pname = cs->pname;
    s->name = cs->name;
    s->port = (uint16_t)cs->port;
    s->weight = (uint32_t)cs->weight;

    s->family = cs->info.family;
    s->addrlen = cs->info.addrlen;
    s->addr = (struct sockaddr *)&cs->info.addr;

    s->ns_conn_q = 0;
    TAILQ_INIT(&s->s_conn_q);

    s->next_retry = 0LL;
    s->failure_count = 0;

    log_debug(LOG_VERB, "transform to server %"PRIu32" '%.*s'",
              s->idx, s->pname.len, s->pname.data);

    return NC_OK;
}
Beispiel #14
0
static int
worker_connection_input_line(struct worker_connection *conn, const char *line)
{
	void *const *contextp, *context;
	int percentage;

	if (aqueue_count(conn->request_queue) == 0) {
		i_error("Input from worker without pending requests: %s", line);
		return -1;
	}

	if (str_to_int(line, &percentage) < 0 ||
	    percentage < -1 || percentage > 100) {
		i_error("Invalid input from worker: %s", line);
		return -1;
	}

	contextp = array_idx(&conn->request_contexts,
			     aqueue_idx(conn->request_queue, 0));
	context = *contextp;
	if (percentage < 0 || percentage == 100) {
		/* the request is finished */
		aqueue_delete_tail(conn->request_queue);
		if (aqueue_count(conn->request_queue) == 0)
			i_free_and_null(conn->request_username);
	}

	conn->callback(percentage, context);
	return 0;
}
static void
ext_reset_update_atomic(struct mail_index_transaction *t,
			uint32_t ext_id, uint32_t expected_reset_id)
{
	const struct mail_index_ext *map_ext;
	struct mail_transaction_ext_reset *reset;
	uint32_t idx, reset_id;

	if (!mail_index_map_get_ext_idx(t->view->index->map, ext_id, &idx)) {
		/* new extension */
		reset_id = 1;
	} else {
		map_ext = array_idx(&t->view->index->map->extensions, idx);
		reset_id = map_ext->reset_id + 1;
	}
	if (reset_id != expected_reset_id) {
		/* ignore this extension update */
		mail_index_ext_set_reset_id(t, ext_id, 0);
		return;
	}

	if (reset_id == 0)
		reset_id++;

	array_idx_set(&t->ext_reset_ids, ext_id, &reset_id);

	/* reseting existing data is optional */
	if (array_is_created(&t->ext_resets)) {
		reset = array_idx_modifiable(&t->ext_resets, ext_id);
		if (reset->new_reset_id == (uint32_t)-1)
			reset->new_reset_id = reset_id;
	}
}
void ldap_connection_kill(struct ldap_connection *conn)
{
	if (conn->io != NULL)
		io_remove_closed(&(conn->io));
	if (conn->to_disconnect != NULL)
		timeout_remove(&(conn->to_disconnect));
	if (conn->to_reconnect != NULL)
		timeout_remove(&(conn->to_reconnect));
	if (conn->request_queue != NULL) {
		unsigned int n = aqueue_count(conn->request_queue);

		for (unsigned int i = 0; i < n; i++) {
			struct ldap_op_queue_entry *const *reqp =
				array_idx(&(conn->request_array),
					  aqueue_idx(conn->request_queue, i));
			if ((*reqp)->msgid > -1)
				ldap_abandon_ext(conn->conn, (*reqp)->msgid, NULL, NULL);
			(*reqp)->msgid = -1;
		}
	}
	if (conn->conn != NULL) {
		ldap_unbind_ext(conn->conn, NULL, NULL);
		ldap_memfree(conn->scred);
	}
	conn->conn = NULL;
	conn->state = LDAP_STATE_DISCONNECT;
}
Beispiel #17
0
static void
imapc_sync_index_keyword(struct imapc_sync_context *ctx,
			 const struct mail_index_sync_rec *sync_rec)
{
	string_t *str = t_str_new(128);
	const char *const *kw_p;
	char change_char;

	switch (sync_rec->type) {
	case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
		change_char = '+';
		break;
	case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
		change_char = '-';
		break;
	default:
		i_unreached();
	}

	str_printfa(str, "UID STORE %u:%u %cFLAGS (",
		    sync_rec->uid1, sync_rec->uid2, change_char);

	kw_p = array_idx(ctx->keywords, sync_rec->keyword_idx);
	str_append(str, *kw_p);
	str_append_c(str, ')');
	imapc_sync_cmd(ctx, str_c(str));
}
static bool
proxy_client_worker_next_reply(struct proxy_client_dsync_worker *worker,
                               const char *line)
{
    const struct proxy_client_request *requests;
    struct proxy_client_request request;
    bool ret = TRUE;

    i_assert(worker->msg_get_data.input == NULL);

    if (aqueue_count(worker->request_queue) == 0) {
        i_error("Unexpected reply from server: %s", line);
        proxy_client_fail(worker);
        return FALSE;
    }

    requests = array_idx(&worker->request_array, 0);
    request = requests[aqueue_idx(worker->request_queue, 0)];
    aqueue_delete_tail(worker->request_queue);

    switch (request.type) {
    case PROXY_CLIENT_REQUEST_TYPE_COPY:
        ret = proxy_client_worker_next_copy(worker, &request, line);
        break;
    case PROXY_CLIENT_REQUEST_TYPE_GET:
        ret = proxy_client_worker_next_msg_get(worker, &request, line);
        break;
    case PROXY_CLIENT_REQUEST_TYPE_FINISH:
        proxy_client_worker_next_finish(worker, &request, line);
        break;
    }
    return ret;
}
Beispiel #19
0
static rstatus_t
dnode_peer_add_node(struct server_pool *sp, struct node *node)
{
	rstatus_t status;
	struct array *peers = &sp->peers;
	struct server *s = array_push(peers);

	s->owner = sp;

	uint32_t i,nelem;
	s->idx = array_idx(peers, s);

	//log_debug(LOG_VERB, "node rack_name         : '%.*s'", node->rack.len, node->rack.data);
	//log_debug(LOG_VERB, "node dc_name        : '%.*s'", node->dc.len, node->dc.data);
	//log_debug(LOG_VERB, "node address          : '%.*s'", node->pname.len, node->pname.data);
	//log_debug(LOG_VERB, "node ip         : '%.*s'", node->name.len, node->name.data);


	string_copy(&s->pname, node->pname.data, node->pname.len);
	string_copy(&s->name, node->name.data, node->name.len);
	string_copy(&s->rack, node->rack.data, node->rack.len);
	string_copy(&s->dc, node->dc.data, node->dc.len);

	s->port = (uint16_t) node->port;
	s->is_local = node->is_local;
	s->state = node->state;
	s->processed = 0;

	array_init(&s->tokens, 1, sizeof(struct dyn_token));
	struct dyn_token *src_token = &node->token;
	struct dyn_token *dst_token = array_push(&s->tokens);
	copy_dyn_token(src_token, dst_token);

	struct sockinfo  *info =  dn_alloc(sizeof(*info)); //need to free this
	dn_resolve(&s->name, s->port, info);
	s->family = info->family;
	s->addrlen = info->addrlen;
	s->addr = (struct sockaddr *)&info->addr;  //TODOs: fix this by copying, not reference
	s->ns_conn_q = 0;
	TAILQ_INIT(&s->s_conn_q);

	s->next_retry = 0LL;
	s->failure_count = 0;
	s->is_seed = node->is_seed;

	log_debug(LOG_VERB, "add a node to peer %"PRIu32" '%.*s'",
			s->idx, s->pname.len, s->pname.data);

	dnode_peer_relink_conn_owner(sp);

	status = dnode_peer_pool_run(sp);
	if (status != DN_OK)
		return status;

	status = dnode_peer_each_preconnect(s, NULL);

	return status;
}
Beispiel #20
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;
}
Beispiel #21
0
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 ldap_connection_send_next(struct ldap_connection *conn)
{
	unsigned int i = 0, n;
	struct ldap_op_queue_entry *req;

	if (conn->to_reconnect != NULL)
		timeout_remove(&(conn->to_reconnect));

	if (conn->state == LDAP_STATE_DISCONNECT) {
		if (ldap_connection_connect(conn) == -1)
			conn->to_reconnect = timeout_add(1000, ldap_connection_send_next, conn);
		return;
	}

	if (conn->state != LDAP_STATE_CONNECT) {
		return;
	}

	if (conn->pending > 10) return; /* try again later */

	req = NULL;
	/* get next request */
	n = aqueue_count(conn->request_queue);

	for(i=0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->msgid > -1)
			break;
		req = *reqp;
	}

	i--;

	/* nothing to actually send */
	if (req == NULL) return;

	i_assert(req->msgid == -1);

	const char *error;
	int ret;
	if ((ret = req->send_request_cb(conn, req, &error)) != LDAP_SUCCESS) {
		/* did not succeed */
		struct ldap_result res;

		memset(&res, 0, sizeof(res));
		res.openldap_ret = ret;
		if (req->result_callback != NULL)
			req->result_callback(&res, req->result_callback_ctx);

		ldap_connection_request_destroy(&req);
		aqueue_delete(conn->request_queue, i);
	} else conn->pending++;
}
Beispiel #23
0
static void doveadm_print_flow_print(const char *value)
{
	const struct doveadm_print_flow_header *hdr =
		array_idx(&ctx->headers, ctx->header_idx);

	if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE) == 0)
		printf("%s=", hdr->title);
	printf("%s", value);
	flow_next_hdr();
}
Beispiel #24
0
struct priorityq_item *priorityq_peek(struct priorityq *pq)
{
	struct priorityq_item *const *items;

	if (array_count(&pq->items) == 0)
		return NULL;

	items = array_idx(&pq->items, 0);
	return items[0];
}
Beispiel #25
0
void sieve_jumplist_resolve(struct sieve_jumplist *jlist)
{
	unsigned int i;

	for ( i = 0; i < array_count(&jlist->jumps); i++ ) {
		const sieve_size_t *jump = array_idx(&jlist->jumps, i);

		sieve_binary_resolve_offset(jlist->block, *jump);
	}
}
Beispiel #26
0
void io_loop_handler_run_internal(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, msecs;

	/* get the time left for next timeout task */
	msecs = 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);

	if (events_count > 0) {
		ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts);
		if (ret < 0 && errno != EINTR)
			i_panic("kevent() failed: %m");
	} else {
		if (msecs < 0)
			i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
		usleep(msecs * 1000);
		ret = 0;
	}

	/* 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);
	}
}
const char *auth_fields_find(struct auth_fields *fields, const char *key)
{
	const struct auth_field *field;
	unsigned int idx;

	if (!auth_fields_find_idx(fields, key, &idx))
		return NULL;

	field = array_idx(&fields->fields, idx);
	return field->value == NULL ? "" : field->value;
}
static bool thread_node_has_ancestor(struct mail_thread_cache *cache,
				     const struct mail_thread_node *node,
				     const struct mail_thread_node *ancestor)
{
	while (node != ancestor) {
		if (node->parent_idx == 0)
			return FALSE;

		node = array_idx(&cache->thread_nodes, node->parent_idx);
	}
	return TRUE;
}
Beispiel #29
0
bool index_sort_list_next(struct mail_search_sort_program *program,
			  uint32_t *seq_r)
{
	const uint32_t *seqp;

	if (program->iter_idx == array_count(&program->seqs))
		return FALSE;

	seqp = array_idx(&program->seqs, program->iter_idx++);
	*seq_r = *seqp;
	return TRUE;
}
Beispiel #30
0
const void *sieve_generator_extension_get_context
(struct sieve_generator *gentr, const struct sieve_extension *ext)
{
	void * const *ctx;

	if  ( ext->id < 0 || ext->id >= (int) array_count(&gentr->ext_contexts) )
		return NULL;

	ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext->id);

	return *ctx;
}