/* crypto/bio/bf_nbio.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <errno.h>
#include "cryptlib.h"
#include "rand.h"
#include "bio.h"
#include "evp.h"

/* BIO_put and BIO_get both add to the digest,
 * BIO_gets returns the digest */

#ifndef NOPROTO
static int nbiof_write(BIO *h,char *buf,int num);
static int nbiof_read(BIO *h,char *buf,int size);
static int nbiof_puts(BIO *h,char *str);
static int nbiof_gets(BIO *h,char *str,int size);
static long nbiof_ctrl(BIO *h,int cmd,long arg1,char *arg2);
static int nbiof_new(BIO *h);
static int nbiof_free(BIO *data);
#else
static int nbiof_write();
static int nbiof_read();
static int nbiof_puts();
static int nbiof_gets();
static long nbiof_ctrl();
static int nbiof_new();
static int nbiof_free();
#endif

typedef struct nbio_test_st
	{
	/* only set if we sent a 'should retry' error */
	int lrn;
	int lwn;
	} NBIO_TEST;

static BIO_METHOD methods_nbiof=
	{
	BIO_TYPE_NBIO_TEST,
	"non-blocking IO test filter",
	nbiof_write,
	nbiof_read,
	nbiof_puts,
	nbiof_gets,
	nbiof_ctrl,
	nbiof_new,
	nbiof_free,
	};

BIO_METHOD *BIO_f_nbio_test()
	{
	return(&methods_nbiof);
	}

static int nbiof_new(bi)
BIO *bi;
	{
	NBIO_TEST *nt;

	nt=(NBIO_TEST *)Malloc(sizeof(NBIO_TEST));
	nt->lrn= -1;
	nt->lwn= -1;
	bi->ptr=(char *)nt;
	bi->init=1;
	bi->flags=0;
	return(1);
	}

static int nbiof_free(a)
BIO *a;
	{
	if (a == NULL) return(0);
	if (a->ptr != NULL)
		Free(a->ptr);
	a->ptr=NULL;
	a->init=0;
	a->flags=0;
	return(1);
	}
	
static int nbiof_read(b,out,outl)
BIO *b;
char *out;
int outl;
	{
	NBIO_TEST *nt;
	int ret=0;
#if 0
	int num;
	unsigned char n;
#endif

	if (out == NULL) return(0);
	if (b->next_bio == NULL) return(0);
	nt=(NBIO_TEST *)b->ptr;

	BIO_clear_retry_flags(b);
#if 0
	RAND_bytes(&n,1);
	num=(n&0x07);

	if (outl > num) outl=num;

	if (num == 0)
		{
		ret= -1;
		BIO_set_retry_read(b);
		}
	else
#endif
		{
		ret=BIO_read(b->next_bio,out,outl);
		if (ret < 0)
			BIO_copy_next_retry(b);
		}
	return(ret);
	}

static int nbiof_write(b,in,inl)
BIO *b;
char *in;
int inl;
	{
	NBIO_TEST *nt;
	int ret=0;
	int num;
	unsigned char n;

	if ((in == NULL) || (inl <= 0)) return(0);
	if (b->next_bio == NULL) return(0);
	nt=(NBIO_TEST *)b->ptr;

	BIO_clear_retry_flags(b);

#if 1
	if (nt->lwn > 0)
		{
		num=nt->lwn;
		nt->lwn=0;
		}
	else
		{
		RAND_bytes(&n,1);
		num=(n&7);
		}

	if (inl > num) inl=num;

	if (num == 0)
		{
		ret= -1;
		BIO_set_retry_write(b);
		}
	else
#endif
		{
		ret=BIO_write(b->next_bio,in,inl);
		if (ret < 0)
			{
			BIO_copy_next_retry(b);
			nt->lwn=inl;
			}
		}
	return(ret);
	}

static long nbiof_ctrl(b,cmd,num,ptr)
BIO *b;
int cmd;
long num;
char *ptr;
	{
	long ret;

	if (b->next_bio == NULL) return(0);
	switch (cmd)
		{
        case BIO_C_DO_STATE_MACHINE:
		BIO_clear_retry_flags(b);
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		BIO_copy_next_retry(b);
		break;
	case BIO_CTRL_DUP:
		ret=0L;
		break;
	default:
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
		}
	return(ret);
	}

static int nbiof_gets(bp,buf,size)
BIO *bp;
char *buf;
int size;
	{
	if (bp->next_bio == NULL) return(0);
	return(BIO_gets(bp->next_bio,buf,size));
	}


static int nbiof_puts(bp,str)
BIO *bp;
char *str;
	{
	if (bp->next_bio == NULL) return(0);
	return(BIO_puts(bp->next_bio,str));
	}


