1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bio/bf_buff.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_write(BIO *h, const char *buf,int num);
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_read(BIO *h, char *buf, int size);
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_puts(BIO *h, const char *str);
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_gets(BIO *h, char *str, int size);
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_new(BIO *h);
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_free(BIO *data);
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* A 10k maximum should be enough for most purposes */
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define DEFAULT_LINEBUFFER_SIZE	1024*10
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* #define DEBUG */
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_linebuffer=
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_TYPE_LINEBUFFER,
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"linebuffer",
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_write,
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_read,
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_puts,
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_gets,
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_ctrl,
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_new,
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_free,
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	linebuffer_callback_ctrl,
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_f_linebuffer(void)
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&methods_linebuffer);
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct bio_linebuffer_ctx_struct
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *obuf;		/* the output char array */
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int obuf_size;		/* how big is the output buffer */
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int obuf_len;		/* how many bytes are in it */
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BIO_LINEBUFFER_CTX;
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_new(BIO *bi)
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_LINEBUFFER_CTX *ctx;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX));
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx == NULL) return(0);
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); }
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->obuf_len=0;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->init=1;
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->ptr=(char *)ctx;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->flags=0;
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_free(BIO *a)
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_LINEBUFFER_CTX *b;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL) return(0);
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b=(BIO_LINEBUFFER_CTX *)a->ptr;
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->obuf != NULL) OPENSSL_free(b->obuf);
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(a->ptr);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->ptr=NULL;
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->init=0;
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->flags=0;
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_read(BIO *b, char *out, int outl)
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0;
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (out == NULL) return(0);
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->next_bio == NULL) return(0);
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret=BIO_read(b->next_bio,out,outl);
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_copy_next_retry(b);
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_write(BIO *b, const char *in, int inl)
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i,num=0,foundnl;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_LINEBUFFER_CTX *ctx;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((in == NULL) || (inl <= 0)) return(0);
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const char *p;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(p = in; p < in + inl && *p != '\n'; p++)
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*p == '\n')
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p++;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			foundnl = 1;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			foundnl = 0;
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If a NL was found and we already have text in the save
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   buffer, concatenate them and write */
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			&& ctx->obuf_len > 0)
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			int orig_olen = ctx->obuf_len;
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i = ctx->obuf_size - ctx->obuf_len;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (p - in > 0)
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (i >= p - in)
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					memcpy(&(ctx->obuf[ctx->obuf_len]),
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						in,p - in);
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->obuf_len += p - in;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					inl -= p - in;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					num += p - in;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					in = p;
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				else
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					memcpy(&(ctx->obuf[ctx->obuf_len]),
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						in,i);
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->obuf_len += i;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					inl -= i;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					in += i;
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					num += i;
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, "<*<", 3);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=BIO_write(b->next_bio,
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf, ctx->obuf_len);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i <= 0)
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf_len = orig_olen;
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, ">*>", 3);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (i < 0) return((num > 0)?num:i);
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (i == 0) return(num);
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, ">*>", 3);
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i < ctx->obuf_len)
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				memmove(ctx->obuf, ctx->obuf + i,
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->obuf_len - i);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->obuf_len-=i;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Now that the save buffer is emptied, let's write the input
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   buffer if a NL was found and there is anything to write. */
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((foundnl || p - in > ctx->obuf_size) && p - in > 0)
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, "<*<", 3);
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=BIO_write(b->next_bio,in,p - in);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i <= 0)
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, ">*>", 3);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (i < 0) return((num > 0)?num:i);
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (i == 0) return(num);
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_write(b->next_bio, ">*>", 3);
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			num+=i;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			in+=i;
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			inl-=i;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(foundnl && inl > 0);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* We've written as much as we can.  The rest of the input buffer, if
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	   any, is text that doesn't and with a NL and therefore needs to be
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	   saved for the next trip. */
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (inl > 0)
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->obuf_len += inl;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num += inl;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *dbio;
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_LINEBUFFER_CTX *ctx;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *p;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int r;
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int obs;
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_RESET:
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->obuf_len=0;
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->next_bio == NULL) return(0);
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_INFO:
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=(long)ctx->obuf_len;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_WPENDING:
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=(long)ctx->obuf_len;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret == 0)
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (b->next_bio == NULL) return(0);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_SET_BUFF_SIZE:
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		obs=(int)num;
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p=ctx->obuf;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size))
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p=(char *)OPENSSL_malloc((int)num);
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (p == NULL)
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto malloc_error;
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->obuf != p)
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ctx->obuf_len > obs)
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf_len = obs;
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(p, ctx->obuf, ctx->obuf_len);
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_free(ctx->obuf);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->obuf=p;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->obuf_size=obs;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_DO_STATE_MACHINE:
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->next_bio == NULL) return(0);
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_clear_retry_flags(b);
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_copy_next_retry(b);
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_FLUSH:
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->next_bio == NULL) return(0);
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->obuf_len <= 0)
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (;;)
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_clear_retry_flags(b);
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ctx->obuf_len > 0)
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				r=BIO_write(b->next_bio,
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->obuf, ctx->obuf_len);
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectfprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r);
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (r <= 0) return((long)r);
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (r < ctx->obuf_len)
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					memmove(ctx->obuf, ctx->obuf + r,
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						ctx->obuf_len - r);
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf_len-=r;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf_len=0;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=1;
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_DUP:
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dbio=(BIO *)ptr;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (	!BIO_set_write_buffer_size(dbio,ctx->obuf_size))
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=0;
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->next_bio == NULL) return(0);
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectmalloc_error:
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE);
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(0);
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->next_bio == NULL) return(0);
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_gets(BIO *b, char *buf, int size)
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->next_bio == NULL) return(0);
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(BIO_gets(b->next_bio,buf,size));
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int linebuffer_puts(BIO *b, const char *str)
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(linebuffer_write(b,str,strlen(str)));
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
398