break;
if(ctx->tmp_len == 0) break;  else i = 0; }  else break;
static int b64_read(BIO *b, char *out, int outl)	{	int ret=0,i,ii,j,k,x,n,num,ret_code=0;	BIO_B64_CTX *ctx;	unsigned char *p,*q;	if (out == NULL) return(0);	ctx=(BIO_B64_CTX *)b->ptr;	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);	if (ctx->encode != B64_DECODE)		{		ctx->encode=B64_DECODE;		ctx->buf_len=0;		ctx->buf_off=0;		ctx->tmp_len=0;		EVP_DecodeInit(&(ctx->base64));		}	/* First check if there are bytes decoded/encoded */	if (ctx->buf_len > 0)		{		i=ctx->buf_len-ctx->buf_off;		if (i > outl) i=outl;		OPENSSL_assert(ctx->buf_off+i < sizeof ctx->buf);		memcpy(out,&(ctx->buf[ctx->buf_off]),i);		ret=i;		out+=i;		outl-=i;		ctx->buf_off+=i;		if (ctx->buf_len == ctx->buf_off)			{			ctx->buf_len=0;			ctx->buf_off=0;			}		}	/* At this point, we have room of outl bytes and an empty	 * buffer, so we should read in some more. */	ret_code=0;	while (outl > 0)		{		if (ctx->cont <= 0) break;		i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]),			B64_BLOCK_SIZE-ctx->tmp_len);		if (i <= 0)			{			ret_code=i;			/* Should be continue next time we are called? */			if (!BIO_should_retry(b->next_bio))				ctx->cont=i;			/* else we should continue when called again */			break;			}		i+=ctx->tmp_len;		/* We need to scan, a line at a time until we		 * have a valid line if we are starting. */		if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL))			{			/* ctx->start=1; */			ctx->tmp_len=0;			}		else if (ctx->start)			{			q=p=(unsigned char *)ctx->tmp;			for (j=0; j<i; j++)				{				if (*(q++) != '\n') continue;				/* due to a previous very long line,				 * we need to keep on scanning for a '\n'				 * before we even start looking for				 * base64 encoded stuff. */				if (ctx->tmp_nl)					{					p=q;					ctx->tmp_nl=0;					continue;					}				k=EVP_DecodeUpdate(&(ctx->base64),					(unsigned char *)ctx->buf,					&num,p,q-p);				if ((k <= 0) && (num == 0) && (ctx->start))					EVP_DecodeInit(&ctx->base64);				else 					{					if (p != (unsigned char *)						&(ctx->tmp[0]))						{						i-=(p- (unsigned char *)							&(ctx->tmp[0]));						for (x=0; x < i; x++)							ctx->tmp[x]=p[x];						}					EVP_DecodeInit(&ctx->base64);					ctx->start=0;					break;					}				p=q;				}			/* we fell off the end without starting */			if (j == i)				{				/* Is this is one long chunk?, if so, keep on				 * reading until a new line. */				if (p == (unsigned char *)&(ctx->tmp[0]))					{					ctx->tmp_nl=1;					ctx->tmp_len=0;					}				else if (p != q) /* finished on a '\n' */					{					n=q-p;					for (ii=0; ii<n; ii++)						ctx->tmp[ii]=p[ii];					ctx->tmp_len=n;					}				/* else finished on a '\n' */				continue;				}			else				ctx->tmp_len=0;			}		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)			{			int z,jj;			jj=(i>>2)<<2;			z=EVP_DecodeBlock((unsigned char *)ctx->buf,				(unsigned char *)ctx->tmp,jj);			if (jj > 2)				{				if (ctx->tmp[jj-1] == '=')					{					z--;					if (ctx->tmp[jj-2] == '=')						z--;					}				}			/* z is now number of output bytes and jj is the			 * number consumed */			if (jj != i)				{				memcpy((unsigned char *)ctx->tmp,					(unsigned char *)&(ctx->tmp[jj]),i-jj);				ctx->tmp_len=i-jj;				}			ctx->buf_len=0;			if (z > 0)				{				ctx->buf_len=z;				i=1;				}			else				i=z;			}		else			{			i=EVP_DecodeUpdate(&(ctx->base64),				(unsigned char *)ctx->buf,&ctx->buf_len,				(unsigned char *)ctx->tmp,i);			}		ctx->cont=i;		ctx->buf_off=0;		if (i < 0)			{			ret_code=0;			ctx->buf_len=0;			break;			}		if (ctx->buf_len <= outl)			i=ctx->buf_len;		else			i=outl;		memcpy(out,ctx->buf,i);		ret+=i;		ctx->buf_off=i;		if (ctx->buf_off == ctx->buf_len)			{			ctx->buf_len=0;			ctx->buf_off=0;			}		outl-=i;		out+=i;		}	BIO_clear_retry_flags(b);	BIO_copy_next_retry(b);	return((ret == 0)?ret_code:ret);	}