static void client_input(struct client *client)
{
	const char *const *args, *error;
	int ret;

	if (client->to_pending != NULL)
		timeout_remove(&client->to_pending);

	switch (i_stream_read(client->input)) {
	case -2:
		i_error("BUG: Stats client sent too much data");
		client_destroy(&client);
		return;
	case -1:
		client_destroy(&client);
		return;
	}

	o_stream_cork(client->output);
	while ((args = client_read_next_line(client)) != NULL) {
		ret = client_handle_request(client, args, &error);
		if (ret < 0) {
			i_error("Stats client input error: %s", error);
			client_destroy(&client);
			return;
		}
		if (ret == 0) {
			o_stream_set_flush_pending(client->output, TRUE);
			io_remove(&client->io);
			break;
		}
		client->cmd_more = NULL;
	}
	o_stream_uncork(client->output);
}
Exemple #2
0
static void proxy_client_input(struct login_proxy *proxy)
{
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	proxy->last_io = ioloop_time;
	if (o_stream_get_buffer_used_size(proxy->server_output) >
	    OUTBUF_THRESHOLD) {
		/* proxy's output buffer is already quite full.
		   don't send more until we're below threshold. */
		io_remove(&proxy->client_io);
		return;
	}

	if (i_stream_read_data(proxy->client_input, &data, &size, 0) < 0) {
		const char *errstr = i_stream_get_error(proxy->client_input);
		login_proxy_free_errstr(&proxy, errstr, FALSE);
		return;
	}
	o_stream_cork(proxy->server_output);
	ret = o_stream_send(proxy->server_output, data, size);
	o_stream_uncork(proxy->server_output);
	if (ret != (ssize_t)size)
		login_proxy_free_ostream(&proxy, proxy->server_output, TRUE);
	else
		i_stream_skip(proxy->client_input, ret);
}
Exemple #3
0
static void server_input(struct login_proxy *proxy)
{
	unsigned char buf[OUTBUF_THRESHOLD];
	ssize_t ret, ret2;

	proxy->last_io = ioloop_time;
	if (o_stream_get_buffer_used_size(proxy->client_output) >
	    OUTBUF_THRESHOLD) {
		/* client's output buffer is already quite full.
		   don't send more until we're below threshold. */
		io_remove(&proxy->server_io);
		return;
	}

	ret = net_receive(proxy->server_fd, buf, sizeof(buf));
	if (ret < 0) {
		login_proxy_free_errno(&proxy, errno, TRUE);
		return;
	}
	o_stream_cork(proxy->client_output);
	ret2 = o_stream_send(proxy->client_output, buf, ret);
	o_stream_uncork(proxy->client_output);
	if (ret2 != ret)
		login_proxy_free_ostream(&proxy, proxy->client_output, FALSE);
}
Exemple #4
0
static void lmtp_client_input(struct lmtp_client *client)
{
	const char *line;
	int ret;

	lmtp_client_ref(client);
	o_stream_cork(client->output);
	while ((line = i_stream_read_next_line(client->input)) != NULL) {
		T_BEGIN {
			ret = lmtp_client_input_line(client, line);
		} T_END;
		if (ret < 0) {
			o_stream_uncork(client->output);
			lmtp_client_unref(&client);
			return;
		}
		if (ret > 0)
			str_truncate(client->input_multiline, 0);
	}

	if (client->input->stream_errno == ENOBUFS) {
		lmtp_client_fail(client,
				 "501 5.5.4 Command reply line too long");
	} else if (client->input->stream_errno != 0) {
		errno = client->input->stream_errno;
		i_error("lmtp client: read() failed: %m");
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (read failure)");
	} else if (client->input->eof) {
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (disconnected in input)");
	}
	o_stream_uncork(client->output);
	lmtp_client_unref(&client);
}
int client_output(struct client *client)
{
	int ret;

	i_assert(!client->destroyed);

	client->last_output = ioloop_time;
	timeout_reset(client->to_idle);
	if (client->to_idle_output != NULL)
		timeout_reset(client->to_idle_output);

	o_stream_cork(client->output);
	if ((ret = o_stream_flush(client->output)) < 0) {
		client_destroy(client, NULL);
		return 1;
	}

	client_output_commands(client);
	(void)cmd_sync_delayed(client);

	o_stream_uncork(client->output);
	imap_refresh_proctitle();
	if (client->disconnected)
		client_destroy(client, NULL);
	else
		client_continue_pending_input(client);
	return ret;
}
client_auth_result(struct client *client, enum client_auth_result result,
		   const struct client_auth_reply *reply, const char *text)
{
	o_stream_cork(client->output);
	client->v.auth_result(client, result, reply, text);
	o_stream_uncork(client->output);
}
Exemple #7
0
int maildir_save_begin(struct mail_save_context *_ctx, struct istream *input)
{
	struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
	struct maildir_filename *mf;

	/* new mail, new failure state */
	ctx->failed = FALSE;

	T_BEGIN {
		/* create a new file in tmp/ directory */
		const char *fname;

		ctx->fd = maildir_create_tmp(ctx->mbox, ctx->tmpdir, &fname);
		if (ctx->fd == -1)
			ctx->failed = TRUE;
		else {
			if (ctx->mbox->storage->storage.set->mail_save_crlf)
				ctx->input = i_stream_create_crlf(input);
			else
				ctx->input = i_stream_create_lf(input);
			mf = maildir_save_add(_ctx, fname, NULL);
			if (_ctx->data.guid != NULL) {
				maildir_save_set_dest_basename(_ctx, mf,
							       _ctx->data.guid);
			}
		}
	} T_END;

	if (!ctx->failed) {
		_ctx->data.output = o_stream_create_fd_file(ctx->fd, 0, FALSE);
		o_stream_cork(_ctx->data.output);
		ctx->last_save_finished = FALSE;
	}
	return ctx->failed ? -1 : 0;
}
Exemple #8
0
static void
idle_finish(struct cmd_idle_context *ctx, bool done_ok, bool free_cmd)
{
	struct client *client = ctx->client;

	if (ctx->keepalive_to != NULL)
		timeout_remove(&ctx->keepalive_to);

	if (ctx->sync_ctx != NULL) {
		/* we're here only in connection failure cases */
		(void)imap_sync_deinit(ctx->sync_ctx, ctx->cmd);
	}

	o_stream_cork(client->output);
	if (client->io != NULL)
		io_remove(&client->io);

	if (client->mailbox != NULL)
		mailbox_notify_changes_stop(client->mailbox);

	if (done_ok)
		client_send_tagline(ctx->cmd, "OK Idle completed.");
	else
		client_send_tagline(ctx->cmd, "BAD Expected DONE.");

	o_stream_uncork(client->output);
	if (free_cmd)
		client_command_free(&ctx->cmd);
}
Exemple #9
0
static void client_input_append(struct client_command_context *cmd)
{
	struct cmd_append_context *ctx = cmd->context;
	struct client *client = cmd->client;
	const char *reason;
	bool finished;
	uoff_t lit_offset;

	i_assert(!client->destroyed);

	client->last_input = ioloop_time;
	timeout_reset(client->to_idle);

	switch (i_stream_read(client->input)) {
	case -1:
		/* disconnected */
		lit_offset = ctx->litinput == NULL ? 0 :
			ctx->litinput->v_offset;
		reason = get_disconnect_reason(ctx, lit_offset);
		cmd_append_finish(cmd->context);
		/* Reset command so that client_destroy() doesn't try to call
		   cmd_append_continue_message() anymore. */
		client_command_free(&cmd);
		client_destroy(client, reason);
		return;
	case -2:
		if (ctx->message_input) {
			/* message data, this is handled internally by
			   mailbox_save_continue() */
			break;
		}
		cmd_append_finish(cmd->context);

		/* parameter word is longer than max. input buffer size.
		   this is most likely an error, so skip the new data
		   until newline is found. */
		client->input_skip_line = TRUE;

		if (!ctx->failed)
			client_send_command_error(cmd, "Too long argument.");
		cmd->param_error = TRUE;
		client_command_free(&cmd);
		return;
	}

	o_stream_cork(client->output);
	finished = command_exec(cmd);
	if (!finished)
		(void)client_handle_unfinished_cmd(cmd);
	else
		client_command_free(&cmd);
	cmd_sync_delayed(client);
	o_stream_uncork(client->output);

	if (client->disconnected)
		client_destroy(client, NULL);
	else
		client_continue_pending_input(client);
}
Exemple #10
0
static int mail_index_recreate(struct mail_index *index)
{
	struct mail_index_map *map = index->map;
	struct ostream *output;
	unsigned int base_size;
	const char *path;
	int ret = 0, fd;

	i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
	i_assert(map->hdr.indexid == index->indexid);
	i_assert((map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) == 0);
	i_assert(index->indexid != 0);

	fd = mail_index_create_tmp_file(index, index->filepath, &path);
	if (fd == -1)
		return -1;

	output = o_stream_create_fd_file(fd, 0, FALSE);
	o_stream_cork(output);

	base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
	o_stream_nsend(output, &map->hdr, base_size);
	o_stream_nsend(output, CONST_PTR_OFFSET(map->hdr_base, base_size),
		       map->hdr.header_size - base_size);
	o_stream_nsend(output, map->rec_map->records,
		       map->rec_map->records_count * map->hdr.record_size);
	o_stream_nflush(output);
	if (o_stream_nfinish(output) < 0) {
		mail_index_file_set_syscall_error(index, path, "write()");
		ret = -1;
	}
	o_stream_destroy(&output);

	if (ret == 0 && index->fsync_mode != FSYNC_MODE_NEVER) {
		if (fdatasync(fd) < 0) {
			mail_index_file_set_syscall_error(index, path,
							  "fdatasync()");
			ret = -1;
		}
	}

	if (close(fd) < 0) {
		mail_index_file_set_syscall_error(index, path, "close()");
		ret = -1;
	}

	if ((index->flags & MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS) != 0)
		(void)mail_index_create_backup(index);

	if (ret == 0 && rename(path, index->filepath) < 0) {
		mail_index_set_error(index, "rename(%s, %s) failed: %m",
				     path, index->filepath);
		ret = -1;
	}

	if (ret < 0)
		i_unlink(path);
	return ret;
}
Exemple #11
0
void lmtp_client_send_more(struct lmtp_client *client)
{
	if (client->input_state == LMTP_INPUT_STATE_DATA) {
		o_stream_cork(client->output);
		lmtp_client_send_data(client);
		o_stream_uncork(client->output);
	}
}
static void proxy_input(struct client *client)
{
	struct istream *input;
	struct ostream *output;
	const char *line;
	unsigned int duration;

	if (client->login_proxy == NULL) {
		/* we're just freeing the proxy */
		return;
	}

	input = login_proxy_get_istream(client->login_proxy);
	if (input == NULL) {
		if (client->destroyed) {
			/* we came here from client_destroy() */
			return;
		}

		/* failed for some reason, probably server disconnected */
		client_proxy_failed(client, TRUE);
		return;
	}

	i_assert(!client->destroyed);

	switch (i_stream_read(input)) {
	case -2:
		client_log_err(client, "proxy: Remote input buffer full");
		client_proxy_failed(client, TRUE);
		return;
	case -1:
		line = i_stream_next_line(input);
		duration = ioloop_time - client->created;
		client_log_err(client, t_strdup_printf(
			"proxy: Remote %s:%u disconnected: %s "
			"(state=%u, duration=%us)%s",
			login_proxy_get_host(client->login_proxy),
			login_proxy_get_port(client->login_proxy),
			get_disconnect_reason(input),
			client->proxy_state, duration,
			line == NULL ? "" : t_strdup_printf(
				" - BUG: line not read: %s", line)));
		client_proxy_failed(client, TRUE);
		return;
	}

	output = client->output;
	o_stream_ref(output);
	o_stream_cork(output);
	while ((line = i_stream_next_line(input)) != NULL) {
		if (client->v.proxy_parse_line(client, line) != 0)
			break;
	}
	o_stream_uncork(output);
	o_stream_unref(&output);
}
Exemple #13
0
static void iostream_pump_copy(struct iostream_pump *pump)
{
	enum ostream_send_istream_result res;
	size_t old_size;

	o_stream_cork(pump->output);
	old_size = o_stream_get_max_buffer_size(pump->output);
	o_stream_set_max_buffer_size(pump->output,
		I_MIN(IO_BLOCK_SIZE,
		      o_stream_get_max_buffer_size(pump->output)));
	res = o_stream_send_istream(pump->output, pump->input);
	o_stream_set_max_buffer_size(pump->output, old_size);
	o_stream_uncork(pump->output);

	switch(res) {
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
		io_remove(&pump->io);
		pump->callback(IOSTREAM_PUMP_STATUS_INPUT_ERROR,
			       pump->context);
		return;
	case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
		io_remove(&pump->io);
		pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR,
			       pump->context);
		return;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
		i_assert(!pump->output->blocking);
		pump->waiting_output = TRUE;
		io_remove(&pump->io);
		return;
	case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
		pump->waiting_output = FALSE;
		io_remove(&pump->io);
		/* flush it */
		switch (o_stream_flush(pump->output)) {
		case -1:
			pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR,
				       pump->context);
			break;
		case 0:
			pump->waiting_output = TRUE;
			pump->completed = TRUE;
			break;
		default:
			pump->callback(IOSTREAM_PUMP_STATUS_INPUT_EOF,
				       pump->context);
			break;
		}
		return;
	case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
		i_assert(!pump->input->blocking);
		pump->waiting_output = FALSE;
		return;
	}
	i_unreached();
}
Exemple #14
0
static int
cmd_setmetadata_entry(struct imap_setmetadata_context *ctx,
                      const char *entry_name,
                      const struct imap_arg *entry_value)
{
    struct istream *inputs[2];
    struct mail_attribute_value value;
    string_t *path;
    int ret;

    switch (entry_value->type) {
    case IMAP_ARG_NIL:
    case IMAP_ARG_ATOM:
    case IMAP_ARG_STRING:
        /* we have the value already */
        if (ctx->failed)
            return 1;
        memset(&value, 0, sizeof(value));
        value.value = imap_arg_as_nstring(entry_value);
        ret = imap_metadata_set(ctx->trans, entry_name, &value);
        if (ret < 0) {
            /* delay reporting the failure so we'll finish
               reading the command input */
            ctx->storage_failure = TRUE;
            ctx->failed = TRUE;
        }
        return 1;
    case IMAP_ARG_LITERAL_SIZE:
        o_stream_nsend(ctx->cmd->client->output, "+ OK\r\n", 6);
        o_stream_nflush(ctx->cmd->client->output);
        o_stream_uncork(ctx->cmd->client->output);
        o_stream_cork(ctx->cmd->client->output);
    /* fall through */
    case IMAP_ARG_LITERAL_SIZE_NONSYNC:
        i_free(ctx->entry_name);
        ctx->entry_name = i_strdup(entry_name);
        ctx->entry_value_len = imap_arg_as_literal_size(entry_value);

        inputs[0] = i_stream_create_limit(ctx->cmd->client->input,
                                          ctx->entry_value_len);
        inputs[1] = NULL;

        path = t_str_new(128);
        mail_user_set_get_temp_prefix(path, ctx->cmd->client->user->set);
        ctx->input = i_stream_create_seekable_path(inputs,
                     METADATA_MAX_INMEM_SIZE, str_c(path));
        i_stream_set_name(ctx->input, i_stream_get_name(inputs[0]));
        i_stream_unref(&inputs[0]);
        return cmd_setmetadata_entry_read_stream(ctx);
    case IMAP_ARG_LITERAL:
    case IMAP_ARG_LIST:
    case IMAP_ARG_EOL:
        break;
    }
    i_unreached();
}
Exemple #15
0
static void o_stream_zlib_cork(struct ostream_private *stream, bool set)
{
	struct zlib_ostream *zstream = (struct zlib_ostream *)stream;

	stream->corked = set;
	if (set)
		o_stream_cork(zstream->output);
	else {
		(void)o_stream_flush(&stream->ostream);
		o_stream_uncork(zstream->output);
	}
}
Exemple #16
0
static void o_stream_default_cork(struct ostream_private *_stream, bool set)
{
	_stream->corked = set;
	if (set) {
		if (_stream->parent != NULL)
			o_stream_cork(_stream->parent);
	} else {
		(void)o_stream_flush(&_stream->ostream);
		if (_stream->parent != NULL)
			o_stream_uncork(_stream->parent);
	}
}
Exemple #17
0
static bool cmd_append_send_literal_continue(struct cmd_append_context *ctx)
{
	if (ctx->failed) {
		/* tagline was already sent, we can abort here */
		return FALSE;
	}

	o_stream_nsend(ctx->client->output, "+ OK\r\n", 6);
	o_stream_nflush(ctx->client->output);
	o_stream_uncork(ctx->client->output);
	o_stream_cork(ctx->client->output);
	return TRUE;
}
static int server_connection_output(struct server_connection *conn)
{
    int ret;

    o_stream_cork(conn->output);
    ret = o_stream_flush(conn->output);
    if (ret > 0 && conn->cmd_input != NULL && conn->delayed_cmd == NULL)
        ret = server_connection_send_cmd_input_more(conn);
    o_stream_uncork(conn->output);
    if (ret < 0)
        server_connection_destroy(&conn);
    return ret;
}
Exemple #19
0
static bool openssl_iostream_bio_output(struct ssl_iostream *ssl_io)
{
	size_t bytes, max_bytes;
	ssize_t sent;
	unsigned char buffer[IO_BLOCK_SIZE];
	bool bytes_sent = FALSE;
	int ret;

	o_stream_cork(ssl_io->plain_output);
	while ((bytes = BIO_ctrl_pending(ssl_io->bio_ext)) > 0) {
		/* bytes contains how many SSL encrypted bytes we should be
		   sending out */
		max_bytes = o_stream_get_buffer_avail_size(ssl_io->plain_output);
		if (bytes > max_bytes) {
			if (max_bytes == 0) {
				/* wait until output buffer clears */
				o_stream_set_flush_pending(ssl_io->plain_output,
							   TRUE);
				break;
			}
			bytes = max_bytes;
		}
		if (bytes > sizeof(buffer))
			bytes = sizeof(buffer);

		/* BIO_read() is guaranteed to return all the bytes that
		   BIO_ctrl_pending() returned */
		ret = BIO_read(ssl_io->bio_ext, buffer, bytes);
		i_assert(ret == (int)bytes);

		/* we limited number of read bytes to plain_output's
		   available size. this send() is guaranteed to either
		   fully succeed or completely fail due to some error. */
		sent = o_stream_send(ssl_io->plain_output, buffer, bytes);
		if (sent < 0) {
			i_assert(ssl_io->plain_output->closed ||
				 ssl_io->plain_output->stream_errno != 0);
			i_free(ssl_io->plain_stream_errstr);
			ssl_io->plain_stream_errstr =
				i_strdup(o_stream_get_error(ssl_io->plain_output));
			ssl_io->plain_stream_errno =
				ssl_io->plain_output->stream_errno;
			ssl_io->closed = TRUE;
			break;
		}
		i_assert(sent == (ssize_t)bytes);
		bytes_sent = TRUE;
	}
	o_stream_uncork(ssl_io->plain_output);
	return bytes_sent;
}
Exemple #20
0
static int lmtp_client_output(struct lmtp_client *client)
{
	int ret;

	lmtp_client_ref(client);
	o_stream_cork(client->output);
	if ((ret = o_stream_flush(client->output)) < 0)
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (disconnected in output)");
	else if (client->input_state == LMTP_INPUT_STATE_DATA)
		lmtp_client_send_data(client);
	o_stream_uncork(client->output);
	lmtp_client_unref(&client);
	return ret;
}
static int astream_open_output(struct attachment_istream *astream)
{
	int fd;

	i_assert(astream->part.temp_fd == -1);

	fd = astream->set.open_temp_fd(astream->context);
	if (fd == -1)
		return -1;

	astream->part.temp_fd = fd;
	astream->part.temp_output = o_stream_create_fd(fd, 0);
	o_stream_cork(astream->part.temp_output);
	return 0;
}
Exemple #22
0
static void client_add_input(struct client *client, const buffer_t *buf)
{
	struct ostream *output;

	if (buf != NULL && buf->used > 0) {
		if (!i_stream_add_data(client->input, buf->data, buf->used))
			i_panic("Couldn't add client input to stream");
	}

	output = client->output;
	o_stream_ref(output);
	o_stream_cork(output);
	(void)client_handle_input(client);
	o_stream_uncork(output);
	o_stream_unref(&output);
}
Exemple #23
0
static void dns_client_input(struct dns_client *client)
{
	const char *line;
	int ret = 0;

	o_stream_cork(client->output);
	while ((line = i_stream_read_next_line(client->input)) != NULL) {
		if (dns_client_input_line(client, line) < 0) {
			ret = -1;
			break;
		}
	}
	o_stream_uncork(client->output);

	if (client->input->eof || client->input->stream_errno != 0 || ret < 0)
		dns_client_destroy(&client);
}
Exemple #24
0
static void test_ostream_file_random(void)
{
	struct ostream *output;
	string_t *path = t_str_new(128);
	char buf[MAX_BUFSIZE*4], buf2[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE];
	unsigned int i, offset, size;
	ssize_t ret;
	int fd;

	memset(buf, 0, sizeof(buf));
	fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
	if (fd == -1)
		i_fatal("safe_mkstemp(%s) failed: %m", str_c(path));
	if (unlink(str_c(path)) < 0)
		i_fatal("unlink(%s) failed: %m", str_c(path));
	output = o_stream_create_fd(fd, MAX_BUFSIZE, FALSE);
	o_stream_cork(output);

	size = (rand() % MAX_BUFSIZE) + 1;
	random_fill_weak(randbuf, size);
	memcpy(buf, randbuf, size);
	test_assert(o_stream_send(output, buf, size) > 0);

	for (i = 0; i < 10; i++) {
		offset = rand() % (MAX_BUFSIZE*3);
		size = (rand() % MAX_BUFSIZE) + 1;
		random_fill_weak(randbuf, size);
		memcpy(buf + offset, randbuf, size);
		test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0);
		if (rand() % 10 == 0)
			test_assert(o_stream_flush(output) > 0);
	}

	test_assert(o_stream_flush(output) > 0);
	o_stream_uncork(output);
	ret = pread(fd, buf2, sizeof(buf2), 0);
	if (ret < 0)
		i_fatal("pread() failed: %m");
	else {
		i_assert(ret > 0);
		test_assert(memcmp(buf, buf2, ret) == 0);
	}
	o_stream_unref(&output);
	i_close_fd(&fd);
}
void client_input(struct client *client)
{
	struct client_command_context *cmd;
	struct ostream *output = client->output;
	ssize_t bytes;

	i_assert(client->io != NULL);

	client->last_input = ioloop_time;
	timeout_reset(client->to_idle);

	if (client->to_delayed_input != NULL)
		timeout_remove(&client->to_delayed_input);

	bytes = i_stream_read(client->input);
	if (bytes == -1) {
		/* disconnected */
		client_destroy(client, NULL);
		return;
	}

	o_stream_ref(output);
	o_stream_cork(output);
	if (!client_handle_input(client) && bytes == -2) {
		/* parameter word is longer than max. input buffer size.
		   this is most likely an error, so skip the new data
		   until newline is found. */
		client->input_skip_line = TRUE;

		cmd = client->input_lock != NULL ? client->input_lock :
			client_command_new(client);
		cmd->param_error = TRUE;
		client_send_command_error(cmd, "Too long argument.");
		client_command_free(&cmd);
	}
	o_stream_uncork(output);
	o_stream_unref(&output);
	imap_refresh_proctitle();

	if (client->disconnected)
		client_destroy(client, NULL);
	else
		client_continue_pending_input(client);
}
Exemple #26
0
static int
zlib_mail_save_compress_begin(struct mail_save_context *ctx,
			      struct istream *input)
{
	struct mailbox *box = ctx->transaction->box;
	struct zlib_user *zuser = ZLIB_USER_CONTEXT(box->storage->user);
	union mailbox_module_context *zbox = ZLIB_CONTEXT(box);
	struct ostream *output;

	if (zbox->super.save_begin(ctx, input) < 0)
		return -1;

	output = zuser->save_handler->create_ostream(ctx->data.output,
						     zuser->save_level);
	o_stream_unref(&ctx->data.output);
	ctx->data.output = output;
	o_stream_cork(ctx->data.output);
	return 0;
}
Exemple #27
0
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;
}
static int client_output(struct client *client)
{
	int ret = 1;

	o_stream_cork(client->output);
	if (o_stream_flush(client->output) < 0) {
		client_destroy(&client);
		return 1;
	}
	if (client->cmd_more != NULL)
		ret = client->cmd_more(client);
	o_stream_uncork(client->output);

	if (ret > 0) {
		client->cmd_more = NULL;
		if (client->io == NULL)
			client_enable_io(client);
	}
	return ret;
}
static int
proxy_client_worker_output_real(struct proxy_client_dsync_worker *worker)
{
    int ret;

    if ((ret = o_stream_flush(worker->output)) < 0)
        return 1;

    if (worker->save_input != NULL) {
        /* proxy_client_worker_msg_save() hasn't finished yet. */
        o_stream_cork(worker->output);
        proxy_client_send_stream(worker);
        if (worker->save_input != NULL)
            return 1;
    }

    if (worker->worker.output_callback != NULL)
        worker->worker.output_callback(worker->worker.output_context);
    return ret;
}
Exemple #30
0
static void client_add_input(struct client *client, const buffer_t *buf)
{
	struct ostream *output;
	struct client_input input;

	if (buf != NULL && buf->used > 0) {
		client_parse_input(buf->data, buf->used, &input);
		if (input.input_size > 0 &&
		    !i_stream_add_data(client->input, input.input,
				       input.input_size))
			i_panic("Couldn't add client input to stream");
	} else {
		/* IMAPLOGINTAG environment is compatible with mailfront */
		memset(&input, 0, sizeof(input));
		input.tag = getenv("IMAPLOGINTAG");
	}

	output = client->output;
	o_stream_ref(output);
	o_stream_cork(output);
	if (input.tag == NULL) {
		client_send_line(client, t_strconcat(
			"* PREAUTH [CAPABILITY ",
			str_c(client->capability_string), "] "
			"Logged in as ", client->user->username, NULL));
	} else if (input.send_untagged_capability) {
		/* client doesn't seem to understand tagged capabilities. send
		   untagged instead and hope that it works. */
		client_send_line(client, t_strconcat("* CAPABILITY ",
			str_c(client->capability_string), NULL));
		client_send_line(client,
				 t_strconcat(input.tag, " OK Logged in", NULL));
	} else {
		client_send_line(client, t_strconcat(
			input.tag, " OK [CAPABILITY ",
			str_c(client->capability_string), "] Logged in", NULL));
	}
	(void)client_handle_input(client);
	o_stream_uncork(output);
	o_stream_unref(&output);
}