Exemplo n.º 1
0
void connection_init_from_streams(struct connection_list *list,
			    struct connection *conn, const char *name,
			    struct istream *input, struct ostream *output)
{
	i_assert(name != NULL);

	conn->list = list;
	conn->name = i_strdup(name);
	conn->fd_in = i_stream_get_fd(input);
	conn->fd_out = o_stream_get_fd(output);

	i_assert(conn->fd_in >= 0);
	i_assert(conn->fd_out >= 0);
	i_assert(conn->io == NULL);
	i_assert(conn->input == NULL);
	i_assert(conn->output == NULL);
	i_assert(conn->to == NULL);

	conn->input = input;
	i_stream_ref(conn->input);
	i_stream_set_name(conn->input, conn->name);

	conn->output = output;
	o_stream_ref(conn->output);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_set_name(conn->output, conn->name);

	conn->io = io_add_istream(conn->input, *list->v.input, conn);
	
	DLLIST_PREPEND(&list->connections, conn);
	list->connections_count++;

	if (list->v.client_connected != NULL)
		list->v.client_connected(conn, TRUE);
}
Exemplo n.º 2
0
static int mbox_mailbox_open(struct mailbox *box)
{
	struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
	struct stat st;
	int ret;

	if (box->input != NULL) {
		i_stream_ref(box->input);
		mbox->mbox_file_stream = box->input;
		mbox->backend_readonly = TRUE;
		mbox->backend_readonly_set = TRUE;
		mbox->no_mbox_file = TRUE;
		return mbox_mailbox_open_finish(mbox, FALSE);
	}

	ret = stat(mailbox_get_path(box), &st);
	if (ret == 0) {
		if (!S_ISDIR(st.st_mode))
			return mbox_mailbox_open_existing(mbox);
		mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
				       "Mailbox isn't selectable");
		return -1;
	} else if (ENOTFOUND(errno)) {
		mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
			T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname));
		return -1;
	} else if (mail_storage_set_error_from_errno(box->storage)) {
		return -1;
	} else {
		mail_storage_set_critical(box->storage,
			"stat(%s) failed: %m", mailbox_get_path(box));
		return -1;
	}
}
Exemplo n.º 3
0
static int o_stream_temp_dup_istream(struct temp_ostream *outstream,
				     struct istream *instream)
{
	uoff_t in_size;
	off_t ret;

	if (!instream->readable_fd || i_stream_get_fd(instream) == -1)
		return 0;

	if (i_stream_get_size(instream, TRUE, &in_size) <= 0) {
		if (outstream->dupstream != NULL)
			return o_stream_temp_dup_cancel(outstream);
		return 0;
	}

	if (outstream->dupstream == NULL) {
		outstream->dupstream = instream;
		outstream->dupstream_start_offset = instream->v_offset;
		i_stream_ref(outstream->dupstream);
	} else {
		if (outstream->dupstream != instream ||
		    outstream->dupstream_offset != instream->v_offset ||
		    outstream->dupstream_offset > in_size)
			return o_stream_temp_dup_cancel(outstream);
	}
	ret = in_size - instream->v_offset;
	i_stream_seek(instream, in_size);
	outstream->dupstream_offset = instream->v_offset;
	return ret;
}
Exemplo n.º 4
0
void connection_input_default(struct connection *conn)
{
	const char *line;
	struct istream *input;
	int ret = 0;

	switch (connection_input_read(conn)) {
	case -1:
		return;
	case 0: /* allow calling this function for buffered input */
	case 1:
		break;
	default:
		i_unreached();
	}

	input = conn->input;
	i_stream_ref(input);
	while (!input->closed && (line = i_stream_next_line(input)) != NULL) {
		T_BEGIN {
			ret = conn->list->v.input_line(conn, line);
		} T_END;
		if (ret <= 0)
			break;
	}
	if (ret < 0 && !input->closed) {
		conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT;
		conn->list->v.destroy(conn);
	}
	i_stream_unref(&input);
}
Exemplo n.º 5
0
static int
sieve_attribute_set_active_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage,
			   const struct mail_attribute_value *value)
{
	struct istream *input;

	if (value->value != NULL) {
		input = i_stream_create_from_data(value->value, strlen(value->value));
	} else if (value->value_stream != NULL) {
		input = value->value_stream;
		i_stream_ref(input);
	} else {
		return sieve_attribute_unset_active_script(storage, svstorage, value->last_change);
	}
	/* skip over the 'S' type */
	i_stream_skip(input, 1);

	if (sieve_storage_save_as_active
		(svstorage, input, value->last_change) < 0) {
		mail_storage_set_critical(storage,
			"Failed to save active sieve script: %s",
			sieve_storage_get_last_error(svstorage, NULL));
		i_stream_unref(&input);
		return -1;
	}

	sieve_storage_set_modified(svstorage, value->last_change);
	i_stream_unref(&input);
	return 0;
}
Exemplo n.º 6
0
void lmtp_client_send(struct lmtp_client *client, struct istream *data_input)
{
	i_stream_ref(data_input);
	client->data_input = data_input;

	(void)lmtp_client_send_data_cmd(client);
}
Exemplo n.º 7
0
void http_client_request_set_payload(struct http_client_request *req,
				     struct istream *input, bool sync)
{
	int ret;

	i_assert(req->state == HTTP_REQUEST_STATE_NEW);
	i_assert(req->payload_input == NULL);

	i_stream_ref(input);
	req->payload_input = input;
	if ((ret = i_stream_get_size(input, TRUE, &req->payload_size)) <= 0) {
		if (ret < 0) {
			i_error("i_stream_get_size(%s) failed: %s",
				i_stream_get_name(input),
				i_stream_get_error(input));
		}
		req->payload_size = 0;
		req->payload_chunked = TRUE;
	}
	req->payload_offset = input->v_offset;

	/* prepare request payload sync using 100 Continue response from server */
	if ((req->payload_chunked || req->payload_size > 0) && sync)
		req->payload_sync = TRUE;
}
Exemplo n.º 8
0
static struct istream *
fs_compress_read_stream(struct fs_file *_file, size_t max_buffer_size)
{
	struct compress_fs_file *file = (struct compress_fs_file *)_file;
	struct istream *input;

	if (file->input != NULL) {
		i_stream_ref(file->input);
		i_stream_seek(file->input, 0);
		return file->input;
	}

	input = fs_read_stream(file->super_read, max_buffer_size);
	file->input = file->fs->handler->create_istream(input, FALSE);
	i_stream_unref(&input);
	i_stream_ref(file->input);
	return file->input;
}
void script_client_set_input
(struct script_client *sclient, struct istream *input)
{
	if ( sclient->input )
		i_stream_unref(&sclient->input);
	if ( input != NULL )
		i_stream_ref(input);
	sclient->input = input;
}
Exemplo n.º 10
0
void program_client_set_input
(struct program_client *pclient, struct istream *input)
{
	if ( pclient->input != NULL )
		i_stream_unref(&pclient->input);
	if ( input != NULL )
		i_stream_ref(input);
	pclient->input = input;
}
Exemplo n.º 11
0
static void auth_server_connection_input(struct auth_server_connection *conn)
{
	struct istream *input;
	const char *line, *error;
	int ret;

	switch (i_stream_read(conn->input)) {
	case 0:
		return;
	case -1:
		/* disconnected */
		error = conn->input->stream_errno != 0 ?
			strerror(conn->input->stream_errno) : "EOF";
		auth_server_connection_reconnect(conn, error);
		return;
	case -2:
		/* buffer full - can't happen unless auth is buggy */
		i_error("BUG: Auth server sent us more than %d bytes of data",
			AUTH_SERVER_CONN_MAX_LINE_LENGTH);
		auth_server_connection_disconnect(conn, "buffer full");
		return;
	}

	if (!conn->version_received) {
		line = i_stream_next_line(conn->input);
		if (line == NULL)
			return;

		/* make sure the major version matches */
		if (strncmp(line, "VERSION\t", 8) != 0 ||
		    !str_uint_equals(t_strcut(line + 8, '\t'),
				     AUTH_CLIENT_PROTOCOL_MAJOR_VERSION)) {
			i_error("Authentication server not compatible with "
				"this client (mixed old and new binaries?)");
			auth_server_connection_disconnect(conn,
				"incompatible server");
			return;
		}
		conn->version_received = TRUE;
	}

	input = conn->input;
	i_stream_ref(input);
	while ((line = i_stream_next_line(input)) != NULL && !input->closed) {
		T_BEGIN {
			ret = auth_server_connection_input_line(conn, line);
		} T_END;

		if (ret < 0) {
			auth_server_connection_disconnect(conn, t_strdup_printf(
				"Received broken input: %s", line));
			break;
		}
	}
	i_stream_unref(&input);
}
Exemplo n.º 12
0
struct json_parser *json_parser_init(struct istream *input)
{
	struct json_parser *parser;

	parser = i_new(struct json_parser, 1);
	parser->input = input;
	parser->value = str_new(default_pool, 128);
	i_array_init(&parser->nesting, 8);
	i_stream_ref(input);
	return parser;
}
Exemplo n.º 13
0
static struct istream *
fs_crypt_read_stream(struct fs_file *_file, size_t max_buffer_size)
{
	struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
	struct istream *input;

	if (file->input != NULL) {
		i_stream_ref(file->input);
		i_stream_seek(file->input, 0);
		return file->input;
	}

	input = fs_read_stream(file->super_read, max_buffer_size);

	file->input = i_stream_create_decrypt_callback(input,
				fs_crypt_istream_get_key, file);
	i_stream_unref(&input);
	i_stream_ref(file->input);
	return file->input;
}
Exemplo n.º 14
0
static int pop3c_client_ssl_init(struct pop3c_client *client)
{
	struct ssl_iostream_settings ssl_set;
	struct stat st;
	const char *error;

	if (client->ssl_ctx == NULL) {
		i_error("pop3c(%s): No SSL context", client->set.host);
		return -1;
	}

	memset(&ssl_set, 0, sizeof(ssl_set));
	if (client->set.ssl_verify) {
		ssl_set.verbose_invalid_cert = TRUE;
		ssl_set.verify_remote_cert = TRUE;
		ssl_set.require_valid_cert = TRUE;
	}

	if (client->set.debug)
		i_debug("pop3c(%s): Starting SSL handshake", client->set.host);

	if (client->raw_input != client->input) {
		/* recreate rawlog after STARTTLS */
		i_stream_ref(client->raw_input);
		o_stream_ref(client->raw_output);
		i_stream_destroy(&client->input);
		o_stream_destroy(&client->output);
		client->input = client->raw_input;
		client->output = client->raw_output;
	}

	if (io_stream_create_ssl_client(client->ssl_ctx, client->set.host,
					&ssl_set, &client->input, &client->output,
					&client->ssl_iostream, &error) < 0) {
		i_error("pop3c(%s): Couldn't initialize SSL client: %s",
			client->set.host, error);
		return -1;
	}
	ssl_iostream_set_handshake_callback(client->ssl_iostream,
					    pop3c_client_ssl_handshaked,
					    client);
	if (ssl_iostream_handshake(client->ssl_iostream) < 0) {
		i_error("pop3c(%s): SSL handshake failed: %s", client->set.host,
			ssl_iostream_get_last_error(client->ssl_iostream));
		return -1;
	}

	if (*client->set.rawlog_dir != '\0' &&
	    stat(client->set.rawlog_dir, &st) == 0) {
		iostream_rawlog_create(client->set.rawlog_dir,
				       &client->input, &client->output);
	}
	return 0;
}
Exemplo n.º 15
0
static void
fts_tika_parser_response(const struct http_response *response,
			 struct tika_fts_parser *parser)
{
	i_assert(parser->payload == NULL);

	switch (response->status) {
	case 200:
		/* read response */
		if (response->payload == NULL)
			parser->payload = i_stream_create_from_data("", 0);
		else {
			i_stream_ref(response->payload);
			parser->payload = response->payload;
		}
		break;
	case 204: /* empty response */
	case 415: /* Unsupported Media Type */
	case 422: /* Unprocessable Entity */
		if (parser->user->mail_debug) {
			i_debug("fts_tika: PUT %s failed: %u %s",
				mail_user_plugin_getenv(parser->user, "fts_tika"),
				response->status, response->reason);
		}
		parser->payload = i_stream_create_from_data("", 0);
		break;
	case 500:
		/* Server Error - the problem could be anything (in Tika or
		   HTTP server or proxy) and might be retriable, but Tika has
		   trouble processing some documents and throws up this error
		   every time for those documents.

		   Unfortunately we can't easily re-send the request here,
		   because we would have to re-send the entire payload, which
		   isn't available anymore here. So we'd need to indicate
		   in fts_parser_deinit() that we want to retry.
		   FIXME: do this in v2.3. For now we'll just ignore it. */
		i_info("fts_tika: PUT %s failed: %u %s - ignoring",
		       mail_user_plugin_getenv(parser->user, "fts_tika"),
		       response->status, response->reason);
		parser->payload = i_stream_create_from_data("", 0);
		break;

	default:
		i_error("fts_tika: PUT %s failed: %u %s",
			mail_user_plugin_getenv(parser->user, "fts_tika"),
			response->status, response->reason);
		parser->failed = TRUE;
		break;
	}
	parser->http_req = NULL;
	io_loop_stop(current_ioloop);
}
Exemplo n.º 16
0
int istream_attachment_connector_add(struct istream_attachment_connector *conn,
				     struct istream *decoded_input,
				     uoff_t start_offset, uoff_t encoded_size,
				     unsigned int base64_blocks_per_line,
				     bool base64_have_crlf,
				     const char **error_r)
{
	struct istream *input, *input2;
	uoff_t base_prefix_size;

	if (start_offset < conn->encoded_offset) {
		*error_r = t_strdup_printf(
			"Attachment %s points before the previous attachment "
			"(%"PRIuUOFF_T" < %"PRIuUOFF_T")",
			i_stream_get_name(decoded_input),
			start_offset, conn->encoded_offset);
		return -1;
	}
	base_prefix_size = start_offset - conn->encoded_offset;
	if (start_offset + encoded_size > conn->msg_size) {
		*error_r = t_strdup_printf(
			"Attachment %s points outside message "
			"(%"PRIuUOFF_T" + %"PRIuUOFF_T" > %"PRIuUOFF_T")",
			i_stream_get_name(decoded_input),
			start_offset, encoded_size,
			conn->msg_size);
		return -1;
	}

	if (base_prefix_size > 0) {
		/* add a part of the base message before the attachment */
		input = i_stream_create_range(conn->base_input,
					      conn->base_input_offset,
					      base_prefix_size);
		array_append(&conn->streams, &input, 1);
		conn->base_input_offset += base_prefix_size;
		conn->encoded_offset += base_prefix_size;
	}
	conn->encoded_offset += encoded_size;

	if (base64_blocks_per_line == 0) {
		input = decoded_input;
		i_stream_ref(input);
	} else {
		input = i_stream_create_base64_encoder(decoded_input,
						       base64_blocks_per_line*4,
						       base64_have_crlf);
	}
	input2 = i_stream_create_sized(input, encoded_size);
	array_append(&conn->streams, &input2, 1);
	i_stream_unref(&input);
	return 0;
}
Exemplo n.º 17
0
static struct istream *mail_raw_create_stream
(struct mail_user *ruser, int fd, time_t *mtime_r, const char **sender)
{
	struct istream *input, *input2, *input_list[2];
	const unsigned char *data;
	size_t i, size;
	int ret, tz;
	char *env_sender = NULL;

	*mtime_r = (time_t)-1;
	fd_set_nonblock(fd, FALSE);

	input = i_stream_create_fd(fd, 4096, FALSE);
	input->blocking = TRUE;
	/* If input begins with a From-line, drop it */
	ret = i_stream_read_data(input, &data, &size, 5);
	if (ret > 0 && size >= 5 && memcmp(data, "From ", 5) == 0) {
		/* skip until the first LF */
		i_stream_skip(input, 5);
		while ( i_stream_read_data(input, &data, &size, 0) > 0 ) {
			for (i = 0; i < size; i++) {
				if (data[i] == '\n')
					break;
			}
			if (i != size) {
				(void)mbox_from_parse(data, i, mtime_r, &tz, &env_sender);
				i_stream_skip(input, i + 1);
				break;
			}
			i_stream_skip(input, size);
		}
	}

	if (env_sender != NULL && sender != NULL) {
		*sender = t_strdup(env_sender);
	}
	i_free(env_sender);

	if (input->v_offset == 0) {
		input2 = input;
		i_stream_ref(input2);
	} else {
		input2 = i_stream_create_limit(input, (uoff_t)-1);
	}
	i_stream_unref(&input);

	input_list[0] = input2; input_list[1] = NULL;
	input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER,
		seekable_fd_callback, (void*)ruser);
	i_stream_unref(&input2);
	return input;
}
Exemplo n.º 18
0
void i_stream_init_parent(struct istream_private *_stream,
			  struct istream *parent)
{
	_stream->access_counter = parent->real_stream->access_counter;
	_stream->parent = parent;
	_stream->parent_start_offset = parent->v_offset;
	_stream->parent_expected_offset = parent->v_offset;
	_stream->start_offset = parent->v_offset;
	/* if parent stream is an istream-error, copy the error */
	_stream->istream.stream_errno = parent->stream_errno;
	_stream->istream.eof = parent->eof;
	i_stream_ref(parent);
}
Exemplo n.º 19
0
struct tee_istream *tee_i_stream_create(struct istream *input)
{
	struct tee_istream *tee;

	tee = i_new(struct tee_istream, 1);
	if (input->v_offset == 0) {
		i_stream_ref(input);
		tee->input = input;
	} else {
		tee->input = i_stream_create_limit(input, (uoff_t)-1);
	}
	return tee;
}
Exemplo n.º 20
0
static void
fts_tika_parser_response(const struct http_response *response,
                         struct tika_fts_parser *parser)
{
    i_assert(parser->payload == NULL);

    switch (response->status) {
    case 200:
        /* read response */
        if (response->payload == NULL)
            parser->payload = i_stream_create_from_data("", 0);
        else {
            i_stream_ref(response->payload);
            parser->payload = response->payload;
        }
        break;
    case 204: /* empty response */
    case 415: /* Unsupported Media Type */
    case 422: /* Unprocessable Entity */
        if (parser->user->mail_debug) {
            i_debug("fts_tika: PUT %s failed: %u %s",
                    mail_user_plugin_getenv(parser->user, "fts_tika"),
                    response->status, response->reason);
        }
        parser->payload = i_stream_create_from_data("", 0);
        break;
    case 500:
        /* Server Error - the problem could be anything (in Tika or
           HTTP server or proxy) and might be retriable, but Tika has
           trouble processing some documents and throws up this error
           every time for those documents. So we try retrying this a
           couple of times, but if that doesn't work we'll just ignore
           it. */
        if (http_client_request_try_retry(parser->http_req))
            return;
        i_info("fts_tika: PUT %s failed: %u %s - ignoring",
               mail_user_plugin_getenv(parser->user, "fts_tika"),
               response->status, response->reason);
        parser->payload = i_stream_create_from_data("", 0);
        break;

    default:
        i_error("fts_tika: PUT %s failed: %u %s",
                mail_user_plugin_getenv(parser->user, "fts_tika"),
                response->status, response->reason);
        parser->failed = TRUE;
        break;
    }
    parser->http_req = NULL;
    io_loop_stop(current_ioloop);
}
Exemplo n.º 21
0
static int
imap_urlauth_fetch_request_callback(struct imap_urlauth_fetch_reply *reply,
				    void *context)
{
	struct imap_urlauth_fetch *ufetch =
		(struct imap_urlauth_fetch *)context;
	int ret = 1;

	if (ufetch->waiting_local && reply != NULL) {
		i_assert(ufetch->pending_reply.url == NULL);
		ufetch->pending_reply.url = i_strdup(reply->url);
		ufetch->pending_reply.flags = reply->flags;
		ufetch->pending_reply.bodypartstruct =
			i_strdup(reply->bodypartstruct);
		ufetch->pending_reply.error = i_strdup(reply->error);
		if (reply->input != NULL) {
			ufetch->pending_reply.input = reply->input;
			i_stream_ref(ufetch->pending_reply.input);
		}
		ufetch->pending_reply.size = reply->size;
		ufetch->pending_reply.succeeded = reply->succeeded;
		ufetch->pending_reply.binary_has_nuls = reply->binary_has_nuls;
		ufetch->waiting_service = TRUE;
		return 0;
	}

	ufetch->waiting_local = FALSE;
	ufetch->pending_requests--;

	imap_urlauth_fetch_ref(ufetch);

	if (!ufetch->failed) {
		bool last = ufetch->pending_requests == 0 || reply == NULL;
		ret = ufetch->callback(reply, last, ufetch->context);
	}

	/* report failure only once */
	if (ret < 0 || reply == NULL) {
		if (!ufetch->failed)
			imap_urlauth_fetch_abort_local(ufetch);
		ufetch->failed = TRUE;
	} else if (ret == 0) {
		ufetch->waiting_service = TRUE;
		ufetch->pending_requests++;
	}
	
	imap_urlauth_fetch_unref(&ufetch);
	return ret;
}
Exemplo n.º 22
0
struct ostream *
o_stream_create_cmp(struct ostream *output, struct istream *input)
{
	struct cmp_ostream *cstream;

	cstream = i_new(struct cmp_ostream, 1);
	cstream->ostream.sendv = o_stream_cmp_sendv;
	cstream->ostream.iostream.close = o_stream_cmp_close;
	cstream->input = input;
	cstream->equals = TRUE;
	i_stream_ref(input);

	return o_stream_create(&cstream->ostream, output,
			       o_stream_get_fd(output));
}
Exemplo n.º 23
0
struct json_parser *json_parser_init_flags(struct istream *input,
					   enum json_parser_flags flags)
{
	struct json_parser *parser;

	parser = i_new(struct json_parser, 1);
	parser->input = input;
	parser->flags = flags;
	parser->value = str_new(default_pool, 128);
	i_array_init(&parser->nesting, 8);
	i_stream_ref(input);

	if ((flags & JSON_PARSER_NO_ROOT_OBJECT) != 0)
		parser->state = JSON_STATE_VALUE;
	return parser;
}
Exemplo n.º 24
0
struct istream_attachment_connector *
istream_attachment_connector_begin(struct istream *base_input, uoff_t msg_size)
{
	struct istream_attachment_connector *conn;
	pool_t pool;

	pool = pool_alloconly_create("istream-attachment-connector", 1024);
	conn = p_new(pool, struct istream_attachment_connector, 1);
	conn->pool = pool;
	conn->base_input = base_input;
	conn->base_input_offset = base_input->v_offset;
	conn->msg_size = msg_size;
	p_array_init(&conn->streams, pool, 8);
	i_stream_ref(conn->base_input);
	return conn;
}
Exemplo n.º 25
0
struct istream *
i_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
{
	_stream->fd = fd;
	if (parent != NULL) {
		_stream->access_counter = parent->real_stream->access_counter;
		_stream->parent = parent;
		_stream->parent_start_offset = parent->v_offset;
		_stream->parent_expected_offset = parent->v_offset;
		_stream->abs_start_offset = parent->v_offset +
			parent->real_stream->abs_start_offset;
		/* if parent stream is an istream-error, copy the error */
		_stream->istream.stream_errno = parent->stream_errno;
		_stream->istream.eof = parent->eof;
		i_stream_ref(parent);
	}
	_stream->istream.real_stream = _stream;

	if (_stream->iostream.close == NULL)
		_stream->iostream.close = i_stream_default_close;
	if (_stream->iostream.destroy == NULL)
		_stream->iostream.destroy = i_stream_default_destroy;
	if (_stream->seek == NULL) {
		_stream->seek = _stream->istream.seekable ?
			i_stream_default_seek_seekable :
			i_stream_default_seek_nonseekable;
	}
	if (_stream->stat == NULL)
		_stream->stat = i_stream_default_stat;
	if (_stream->get_size == NULL)
		_stream->get_size = i_stream_default_get_size;
	if (_stream->iostream.set_max_buffer_size == NULL) {
		_stream->iostream.set_max_buffer_size =
			i_stream_default_set_max_buffer_size;
	}
	if (_stream->init_buffer_size == 0)
		_stream->init_buffer_size = I_STREAM_MIN_SIZE;

	memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
	_stream->statbuf.st_size = -1;
	_stream->statbuf.st_atime =
		_stream->statbuf.st_mtime =
		_stream->statbuf.st_ctime = ioloop_time;

	io_stream_init(&_stream->iostream);
	return &_stream->istream;
}
Exemplo n.º 26
0
static int fetch_body(struct imap_fetch_context *ctx, struct mail *mail,
		      const struct imap_fetch_body_data *body)
{
	const struct message_size *fetch_size;
	struct istream *input;
	struct message_size hdr_size, body_size;

	if (body->section[0] == '\0') {
		if (mail_get_stream(mail, NULL, NULL, &input) < 0 ||
		    mail_get_virtual_size(mail, &body_size.virtual_size) < 0 ||
		    mail_get_physical_size(mail, &body_size.physical_size) < 0)
			return -1;
	} else {
		if (mail_get_stream(mail, &hdr_size,
				    body->section[0] == 'H' ? NULL : &body_size,
				    &input) < 0)
			return -1;
	}

	ctx->cur_input = input;
	i_stream_ref(ctx->cur_input);
	ctx->update_partial = TRUE;

	switch (body->section[0]) {
	case '\0':
		/* BODY[] - fetch everything */
                fetch_size = &body_size;
		ctx->cur_size_field = MAIL_FETCH_VIRTUAL_SIZE;
		break;
	case 'H':
		/* BODY[HEADER] - fetch only header */
                fetch_size = &hdr_size;
		ctx->cur_size_field = MAIL_FETCH_MESSAGE_PARTS;
		break;
	case 'T':
		/* BODY[TEXT] - skip header */
		i_stream_skip(ctx->cur_input, hdr_size.physical_size);
                fetch_size = &body_size;
		ctx->cur_size_field = MAIL_FETCH_VIRTUAL_SIZE;
		break;
	default:
		i_unreached();
	}

	return fetch_data(ctx, body, fetch_size);
}
Exemplo n.º 27
0
static int
sieve_attribute_retrieve_script(struct mail_storage *storage,
			   struct sieve_storage *svstorage, struct sieve_script *script,
			   bool add_type_prefix,
			   struct mail_attribute_value *value_r, const char **errorstr_r)
{
	static char type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT;
	struct istream *input, *inputs[3];
	const struct stat *st;
	enum sieve_error error;

	if (script == NULL)
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
	else if (sieve_script_get_stream(script, &input, &error) < 0)
		sieve_script_unref(&script);
	
	if (script == NULL) {
		if (error == SIEVE_ERROR_NOT_FOUND) {
			/* already deleted, but return the last_change */
			(void)sieve_storage_get_last_change(svstorage,
							    &value_r->last_change);
			return 0;
		}
		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
		return -1;
	}
	if (i_stream_stat(input, FALSE, &st) < 0) {
		mail_storage_set_critical(storage,
			"stat(%s) failed: %m", i_stream_get_name(input));
	} else {
		value_r->last_change = st->st_mtime;
	}
	if (!add_type_prefix) {
		i_stream_ref(input);
		value_r->value_stream = input;
	} else {
		inputs[0] = i_stream_create_from_data(&type, 1);
		inputs[1] = input;
		inputs[2] = NULL;
		value_r->value_stream = i_stream_create_concat(inputs);
		i_stream_unref(&inputs[0]);
	}
	sieve_script_unref(&script);
	return 1;
}
Exemplo n.º 28
0
void program_client_init_streams(struct program_client *pclient)
{
	/* Create streams for normal program I/O */
	if ( pclient->fd_out >= 0 ) {
		pclient->program_output =
			o_stream_create_fd(pclient->fd_out, MAX_OUTPUT_BUFFER_SIZE, FALSE);
	}
	if ( pclient->fd_in >= 0 ) {
		struct istream *input;
		
		input = i_stream_create_fd(pclient->fd_in, (size_t)-1, FALSE);

		if (pclient->output_seekable) {
			struct istream *input2 = input, *input_list[2];
	
			input_list[0] = input2; input_list[1] = NULL;
			input = i_stream_create_seekable(input_list, MAX_OUTPUT_MEMORY_BUFFER,
						 program_client_seekable_fd_callback, pclient);
			i_stream_unref(&input2);
			pclient->seekable_output = input;
			i_stream_ref(pclient->seekable_output);
		}

		pclient->program_input = input;
		pclient->io = io_add
			(pclient->fd_in, IO_READ, program_client_program_input, pclient);
	}

	/* Create streams for additional output through side-channel fds */
	if ( array_is_created(&pclient->extra_fds) ) {
		struct program_client_extra_fd *efds = NULL;
		unsigned int count, i;
		
		efds = array_get_modifiable(&pclient->extra_fds, &count);
		for ( i = 0; i < count; i++ ) {
			i_assert( efds[i].parent_fd >= 0 );
			efds[i].input = i_stream_create_fd
				(efds[i].parent_fd, (size_t)-1, FALSE);
			efds[i].io = io_add
				(efds[i].parent_fd, IO_READ, program_client_extra_fd_input, &efds[i]);
		}
	}
}
Exemplo n.º 29
0
static struct dsync_ibc *
cmd_dsync_icb_stream_init(struct dsync_cmd_context *ctx,
			  const char *name, const char *temp_prefix)
{
	if (ctx->input == NULL) {
		fd_set_nonblock(ctx->fd_in, TRUE);
		fd_set_nonblock(ctx->fd_out, TRUE);
		ctx->input = i_stream_create_fd(ctx->fd_in, (size_t)-1, FALSE);
		ctx->output = o_stream_create_fd(ctx->fd_out, (size_t)-1, FALSE);
	}
	i_stream_ref(ctx->input);
	o_stream_ref(ctx->output);
	if (ctx->rawlog_path != NULL) {
		iostream_rawlog_create_path(ctx->rawlog_path,
					    &ctx->input, &ctx->output);
	}
	return dsync_ibc_init_stream(ctx->input, ctx->output,
				     name, temp_prefix);
}
Exemplo n.º 30
0
void lmtp_client_send(struct lmtp_client *client, struct istream *data_input)
{
	i_assert(client->data_input == NULL);

	i_stream_ref(data_input);
	client->data_input = data_input;

	/* now we actually want to start doing I/O. start the timeout
	   handling. */
	if (client->set.timeout_secs > 0) {
		if (client->to != NULL) {
			/* still waiting for connect to finish */
			timeout_remove(&client->to);
		}
		client->to = timeout_add(client->set.timeout_secs*1000,
					 lmtp_client_timeout, client);
	}

	(void)lmtp_client_send_data_cmd(client);
}