Ejemplo n.º 1
0
const char *lmtp_client_state_to_string(struct lmtp_client *client)
{
	uoff_t size;

	switch (client->input_state) {
	case LMTP_INPUT_STATE_GREET:
		return "greeting";
	case LMTP_INPUT_STATE_LHLO:
		return "LHLO";
	case LMTP_INPUT_STATE_MAIL_FROM:
		return "MAIL FROM";
	case LMTP_INPUT_STATE_RCPT_TO:
		return "RCPT TO";
	case LMTP_INPUT_STATE_DATA_CONTINUE:
		return "DATA init";
	case LMTP_INPUT_STATE_DATA:
		if (client->output_finished)
			return "DATA reply";
		else if (i_stream_get_size(client->data_input, FALSE, &size) > 0) {
			return t_strdup_printf(
				"DATA (%"PRIuUOFF_T"/%"PRIuUOFF_T")",
				client->data_input->v_offset, size);
		} else {
			return t_strdup_printf("DATA (%"PRIuUOFF_T"/?)",
					       client->data_input->v_offset);
		}
	case LMTP_INPUT_STATE_XCLIENT:
		return "XCLIENT";
	}
	return "??";
}
Ejemplo n.º 2
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;
}
Ejemplo 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;
}
Ejemplo n.º 4
0
static int imapc_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
{
	struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
	struct index_mail *mail = (struct index_mail *)_mail;
	struct index_mail_data *data = &mail->data;
	struct istream *input;
	uoff_t old_offset;
	int ret;

	if (data->physical_size == (uoff_t)-1) {
		(void)index_mail_get_physical_size(_mail, size_r);
		if (data->physical_size != (uoff_t)-1) {
			*size_r = data->physical_size;
			return 0;
		}
	}

	if (IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_RFC822_SIZE) &&
	    data->stream == NULL) {
		/* trust RFC822.SIZE to be correct */
		if (imapc_mail_fetch(_mail, MAIL_FETCH_PHYSICAL_SIZE) < 0)
			return -1;
		if (data->physical_size == (uoff_t)-1) {
			if (imapc_mail_failed(_mail, "RFC822.SIZE") < 0)
				return -1;
			/* assume that the server never returns RFC822.SIZE
			   for this mail (see BODY[] failure handling) */
			data->physical_size = 0;
		}
		*size_r = data->physical_size;
		return 0;
	}

	old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
	if (mail_get_stream(_mail, NULL, NULL, &input) < 0)
		return -1;
	i_stream_seek(data->stream, old_offset);

	ret = i_stream_get_size(data->stream, TRUE,
				&data->physical_size);
	if (ret <= 0) {
		i_assert(ret != 0);
		mail_storage_set_critical(_mail->box->storage,
					  "imapc: stat(%s) failed: %m",
					  i_stream_get_name(data->stream));
		return -1;
	}
	*size_r = data->physical_size;
	return 0;
}
Ejemplo n.º 5
0
static void mail_crypt_close(struct mail *_mail)
{
	struct mail_private *mail = (struct mail_private *)_mail;
	union mail_module_context *mmail = MAIL_CRYPT_MAIL_CONTEXT(mail);
	struct mail_crypt_user *muser =
		MAIL_CRYPT_USER_CONTEXT(_mail->box->storage->user);
	struct mail_crypt_cache *cache = &muser->cache;
	uoff_t size;

	if (_mail->uid > 0 && cache->uid == _mail->uid && cache->box == _mail->box) {
		/* make sure we have read the entire email into the seekable
		   stream (which causes the original input stream to be
		   unrefed). we can't safely keep the original input stream
		   open after the mail is closed. */
		if (i_stream_get_size(cache->input, TRUE, &size) < 0)
			mail_crypt_cache_close(muser);
	}
	mmail->super.close(_mail);
}
Ejemplo n.º 6
0
static void pop3c_mail_cache_size(struct index_mail *mail)
{
	struct mail *_mail = &mail->mail.mail;
	uoff_t size;
	unsigned int cache_idx;

	if (i_stream_get_size(mail->data.stream, TRUE, &size) <= 0)
		return;
	mail->data.virtual_size = size;

	cache_idx = mail->ibox->cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
	if (mail_cache_field_exists(_mail->transaction->cache_view,
				    _mail->seq, cache_idx) == 0) {
		index_mail_cache_add_idx(mail, cache_idx, &size, sizeof(size));
		/* make sure it's not cached twice */
		mail->data.dont_cache_fetch_fields |=
			MAIL_CACHE_VIRTUAL_FULL_SIZE;
	}
}
Ejemplo n.º 7
0
static bool
o_stream_temp_dup_istream(struct temp_ostream *outstream,
			  struct istream *instream,
			  enum ostream_send_istream_result *res_r)
{
	uoff_t in_size;

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

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

	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, res_r);
	}
	i_stream_seek(instream, in_size);
	/* we should be at EOF now. o_stream_send_istream() asserts if
	   eof isn't set. */
	instream->eof = TRUE;
	outstream->dupstream_offset = instream->v_offset;
	outstream->ostream.ostream.offset =
		outstream->dupstream_offset - outstream->dupstream_start_offset;
	*res_r = OSTREAM_SEND_ISTREAM_RESULT_FINISHED;
	return TRUE;
}
Ejemplo n.º 8
0
static bool cmd_putscript_continue_parsing(struct client_command_context *cmd)
{
	struct client *client = cmd->client;
	struct cmd_putscript_context *ctx = cmd->context;
	const struct managesieve_arg *args;
	int ret;

	/* if error occurs, the CRLF is already read. */
	client->input_skip_line = FALSE;

	/* <script literal> */
	ret = managesieve_parser_read_args(ctx->save_parser, 0,
				    MANAGESIEVE_PARSE_FLAG_STRING_STREAM, &args);
	if (ret == -1 || client->output->closed) {
		cmd_putscript_finish(ctx);
		client_send_command_error(cmd, "Invalid arguments.");
		client->input_skip_line = TRUE;
		return TRUE;
	}
	if (ret < 0) {
		/* need more data */
		return FALSE;
	}

	/* Validate the script argument */
	if ( !managesieve_arg_get_string_stream(args,&ctx->input) ) {
		client_send_command_error(cmd, "Invalid arguments.");
		return cmd_putscript_cancel(ctx, FALSE);
	}

	if ( i_stream_get_size(ctx->input, FALSE, &ctx->script_size) > 0 ) {
		if ( ctx->script_size == 0 ) {
			/* no script content, abort */
			if ( ctx->scriptname != NULL )
				client_send_no(client, "PUTSCRIPT aborted (empty script).");
			else
				client_send_no(client, "CHECKSCRIPT aborted (empty script).");

			cmd_putscript_finish(ctx);
			return TRUE;

		/* Check quota */
		} else if ( ctx->scriptname == NULL ) {
			if ( !managesieve_quota_check_validsize(client, ctx->script_size) )
				return cmd_putscript_cancel(ctx, TRUE);
		} else {
			if ( !managesieve_quota_check_all
				(client, ctx->scriptname, ctx->script_size) )
				return cmd_putscript_cancel(ctx, TRUE);
		}

	} else {
		ctx->max_script_size = managesieve_quota_max_script_size(client);
	}

	/* save the script */
	ctx->save_ctx = sieve_storage_save_init
		(ctx->storage, ctx->scriptname, ctx->input);

	if ( ctx->save_ctx == NULL ) {
		/* save initialization failed */
		client_send_storage_error(client, ctx->storage);
		return cmd_putscript_cancel(ctx, TRUE);
	}

	/* after literal comes CRLF, if we fail make sure we eat it away */
	client->input_skip_line = TRUE;

	client->command_pending = TRUE;
	cmd->func = cmd_putscript_continue_script;
	return cmd_putscript_continue_script(cmd);
}