os/ossrv/ssl/libcrypto/src/crypto/bio/bio_lib.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* crypto/bio/bio_lib.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
#include <stdio.h>
sl@0
    60
#include <errno.h>
sl@0
    61
#include <openssl/crypto.h>
sl@0
    62
#include "cryptlib.h"
sl@0
    63
#include <openssl/bio.h>
sl@0
    64
#include <openssl/stack.h>
sl@0
    65
sl@0
    66
EXPORT_C BIO *BIO_new(BIO_METHOD *method)
sl@0
    67
	{
sl@0
    68
	BIO *ret=NULL;
sl@0
    69
sl@0
    70
	ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
sl@0
    71
	if (ret == NULL)
sl@0
    72
		{
sl@0
    73
		BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
sl@0
    74
		return(NULL);
sl@0
    75
		}
sl@0
    76
#ifdef SYMBIAN
sl@0
    77
   memset(ret,0,sizeof(BIO));
sl@0
    78
#endif		
sl@0
    79
	if (!BIO_set(ret,method))
sl@0
    80
		{
sl@0
    81
		OPENSSL_free(ret);
sl@0
    82
		ret=NULL;
sl@0
    83
		}
sl@0
    84
	return(ret);
sl@0
    85
	}
sl@0
    86
sl@0
    87
EXPORT_C int BIO_set(BIO *bio, BIO_METHOD *method)
sl@0
    88
	{
sl@0
    89
	bio->method=method;
sl@0
    90
	bio->callback=NULL;
sl@0
    91
	bio->cb_arg=NULL;
sl@0
    92
	bio->init=0;
sl@0
    93
	bio->shutdown=1;
sl@0
    94
	bio->flags=0;
sl@0
    95
	bio->retry_reason=0;
sl@0
    96
	bio->num=0;
sl@0
    97
	bio->ptr=NULL;
sl@0
    98
	bio->prev_bio=NULL;
sl@0
    99
	bio->next_bio=NULL;
sl@0
   100
	bio->references=1;
sl@0
   101
	bio->num_read=0L;
sl@0
   102
	bio->num_write=0L;
sl@0
   103
	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
sl@0
   104
	if (method->create != NULL)
sl@0
   105
		if (!method->create(bio))
sl@0
   106
			{
sl@0
   107
			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
sl@0
   108
					&bio->ex_data);
sl@0
   109
			return(0);
sl@0
   110
			}
sl@0
   111
	return(1);
sl@0
   112
	}
sl@0
   113
sl@0
   114
EXPORT_C int BIO_free(BIO *a)
sl@0
   115
	{
sl@0
   116
	int ret=0,i;
sl@0
   117
sl@0
   118
	if (a == NULL) return(0);
sl@0
   119
sl@0
   120
	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
sl@0
   121
#ifdef REF_PRINT
sl@0
   122
	REF_PRINT("BIO",a);
sl@0
   123
#endif
sl@0
   124
	if (i > 0) return(1);
sl@0
   125
#ifdef REF_CHECK
sl@0
   126
	if (i < 0)
sl@0
   127
		{
sl@0
   128
		fprintf(stderr,"BIO_free, bad reference count\n");
sl@0
   129
		abort();
sl@0
   130
		}
sl@0
   131
#endif
sl@0
   132
	if ((a->callback != NULL) &&
sl@0
   133
		((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
sl@0
   134
			return(i);
sl@0
   135
sl@0
   136
	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
sl@0
   137
sl@0
   138
	if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
sl@0
   139
	ret=a->method->destroy(a);
sl@0
   140
	OPENSSL_free(a);
sl@0
   141
	return(1);
sl@0
   142
	}
sl@0
   143
sl@0
   144
EXPORT_C void BIO_vfree(BIO *a)
sl@0
   145
    { BIO_free(a); }
sl@0
   146
sl@0
   147
EXPORT_C void BIO_clear_flags(BIO *b, int flags)
sl@0
   148
	{
sl@0
   149
	b->flags &= ~flags;
sl@0
   150
	}
sl@0
   151
sl@0
   152
EXPORT_C int	BIO_test_flags(const BIO *b, int flags)
sl@0
   153
	{
sl@0
   154
	return (b->flags & flags);
sl@0
   155
	}
sl@0
   156
sl@0
   157
EXPORT_C void	BIO_set_flags(BIO *b, int flags)
sl@0
   158
	{
sl@0
   159
	b->flags |= flags;
sl@0
   160
	}
sl@0
   161
sl@0
   162
EXPORT_C long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long)
sl@0
   163
	{
sl@0
   164
	return b->callback;
sl@0
   165
	}
sl@0
   166
sl@0
   167
EXPORT_C void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long))
sl@0
   168
	{
sl@0
   169
	b->callback = cb;
sl@0
   170
	}
sl@0
   171
sl@0
   172
EXPORT_C void BIO_set_callback_arg(BIO *b, char *arg)
sl@0
   173
	{
sl@0
   174
	b->cb_arg = arg;
sl@0
   175
	}
sl@0
   176
sl@0
   177
EXPORT_C char * BIO_get_callback_arg(const BIO *b)
sl@0
   178
	{
sl@0
   179
	return b->cb_arg;
sl@0
   180
	}
sl@0
   181
sl@0
   182
EXPORT_C const char * BIO_method_name(const BIO *b)
sl@0
   183
	{
sl@0
   184
	return b->method->name;
sl@0
   185
	}
sl@0
   186
sl@0
   187
EXPORT_C int BIO_method_type(const BIO *b)
sl@0
   188
	{
sl@0
   189
	return b->method->type;
sl@0
   190
	}
sl@0
   191
EXPORT_C int BIO_read(BIO *b, void *out, int outl)
sl@0
   192
	{
sl@0
   193
	int i;
sl@0
   194
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   195
sl@0
   196
	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
sl@0
   197
		{
sl@0
   198
		BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
sl@0
   199
		return(-2);
sl@0
   200
		}
sl@0
   201
sl@0
   202
	cb=b->callback;
sl@0
   203
	if ((cb != NULL) &&
sl@0
   204
		((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
sl@0
   205
			return(i);
sl@0
   206
sl@0
   207
	if (!b->init)
sl@0
   208
		{
sl@0
   209
		BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
sl@0
   210
		return(-2);
sl@0
   211
		}
sl@0
   212
sl@0
   213
	i=b->method->bread(b,out,outl);
sl@0
   214
sl@0
   215
	if (i > 0) b->num_read+=(unsigned long)i;
sl@0
   216
sl@0
   217
	if (cb != NULL)
sl@0
   218
		i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
sl@0
   219
			0L,(long)i);
sl@0
   220
	return(i);
sl@0
   221
	}
sl@0
   222
sl@0
   223
EXPORT_C int BIO_write(BIO *b, const void *in, int inl)
sl@0
   224
	{
sl@0
   225
	int i;
sl@0
   226
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   227
sl@0
   228
	if (b == NULL)
sl@0
   229
		return(0);
sl@0
   230
sl@0
   231
	cb=b->callback;
sl@0
   232
	if ((b->method == NULL) || (b->method->bwrite == NULL))
sl@0
   233
		{
sl@0
   234
		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
sl@0
   235
		return(-2);
sl@0
   236
		}
sl@0
   237
sl@0
   238
	if ((cb != NULL) &&
sl@0
   239
		((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
sl@0
   240
			return(i);
sl@0
   241
sl@0
   242
	if (!b->init)
sl@0
   243
		{
sl@0
   244
		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
sl@0
   245
		return(-2);
sl@0
   246
		}
sl@0
   247
sl@0
   248
	i=b->method->bwrite(b,in,inl);
sl@0
   249
sl@0
   250
	if (i > 0) b->num_write+=(unsigned long)i;
sl@0
   251
sl@0
   252
	if (cb != NULL)
sl@0
   253
		i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
sl@0
   254
			0L,(long)i);
sl@0
   255
	return(i);
sl@0
   256
	}
sl@0
   257
sl@0
   258
EXPORT_C int BIO_puts(BIO *b, const char *in)
sl@0
   259
	{
sl@0
   260
	int i;
sl@0
   261
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   262
sl@0
   263
	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
sl@0
   264
		{
sl@0
   265
		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
sl@0
   266
		return(-2);
sl@0
   267
		}
sl@0
   268
sl@0
   269
	cb=b->callback;
sl@0
   270
sl@0
   271
	if ((cb != NULL) &&
sl@0
   272
		((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
sl@0
   273
			return(i);
sl@0
   274
sl@0
   275
	if (!b->init)
sl@0
   276
		{
sl@0
   277
		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
sl@0
   278
		return(-2);
sl@0
   279
		}
sl@0
   280
sl@0
   281
	i=b->method->bputs(b,in);
sl@0
   282
sl@0
   283
	if (i > 0) b->num_write+=(unsigned long)i;
sl@0
   284
sl@0
   285
	if (cb != NULL)
sl@0
   286
		i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
sl@0
   287
			0L,(long)i);
sl@0
   288
	return(i);
sl@0
   289
	}
sl@0
   290
sl@0
   291
EXPORT_C int BIO_gets(BIO *b, char *in, int inl)
sl@0
   292
	{
sl@0
   293
	int i;
sl@0
   294
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   295
sl@0
   296
	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
sl@0
   297
		{
sl@0
   298
		BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
sl@0
   299
		return(-2);
sl@0
   300
		}
sl@0
   301
sl@0
   302
	cb=b->callback;
sl@0
   303
sl@0
   304
	if ((cb != NULL) &&
sl@0
   305
		((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
sl@0
   306
			return(i);
sl@0
   307
sl@0
   308
	if (!b->init)
sl@0
   309
		{
sl@0
   310
		BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
sl@0
   311
		return(-2);
sl@0
   312
		}
sl@0
   313
sl@0
   314
	i=b->method->bgets(b,in,inl);
sl@0
   315
sl@0
   316
	if (cb != NULL)
sl@0
   317
		i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
sl@0
   318
			0L,(long)i);
sl@0
   319
	return(i);
sl@0
   320
	}
sl@0
   321
sl@0
   322
EXPORT_C int BIO_indent(BIO *b,int indent,int max)
sl@0
   323
	{
sl@0
   324
	if(indent < 0)
sl@0
   325
		indent=0;
sl@0
   326
	if(indent > max)
sl@0
   327
		indent=max;
sl@0
   328
	while(indent--)
sl@0
   329
		if(BIO_puts(b," ") != 1)
sl@0
   330
			return 0;
sl@0
   331
	return 1;
sl@0
   332
	}
sl@0
   333
sl@0
   334
EXPORT_C long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
sl@0
   335
	{
sl@0
   336
	int i;
sl@0
   337
sl@0
   338
	i=iarg;
sl@0
   339
	return(BIO_ctrl(b,cmd,larg,(char *)&i));
sl@0
   340
	}
sl@0
   341
sl@0
   342
EXPORT_C char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
sl@0
   343
	{
sl@0
   344
	char *p=NULL;
sl@0
   345
sl@0
   346
	if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
sl@0
   347
		return(NULL);
sl@0
   348
	else
sl@0
   349
		return(p);
sl@0
   350
	}
sl@0
   351
sl@0
   352
EXPORT_C long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
sl@0
   353
	{
sl@0
   354
	long ret;
sl@0
   355
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   356
sl@0
   357
	if (b == NULL) return(0);
sl@0
   358
sl@0
   359
	if ((b->method == NULL) || (b->method->ctrl == NULL))
sl@0
   360
		{
sl@0
   361
		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
sl@0
   362
		return(-2);
sl@0
   363
		}
sl@0
   364
sl@0
   365
	cb=b->callback;
sl@0
   366
sl@0
   367
	if ((cb != NULL) &&
sl@0
   368
		((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
sl@0
   369
		return(ret);
sl@0
   370
sl@0
   371
	ret=b->method->ctrl(b,cmd,larg,parg);
sl@0
   372
sl@0
   373
	if (cb != NULL)
sl@0
   374
		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
sl@0
   375
			larg,ret);
sl@0
   376
	return(ret);
sl@0
   377
	}
sl@0
   378
sl@0
   379
EXPORT_C long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
sl@0
   380
	{
sl@0
   381
	long ret;
sl@0
   382
	long (*cb)(BIO *,int,const char *,int,long,long);
sl@0
   383
sl@0
   384
	if (b == NULL) return(0);
sl@0
   385
sl@0
   386
	if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
sl@0
   387
		{
sl@0
   388
		BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD);
sl@0
   389
		return(-2);
sl@0
   390
		}
sl@0
   391
sl@0
   392
	cb=b->callback;
sl@0
   393
sl@0
   394
	if ((cb != NULL) &&
sl@0
   395
		((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
sl@0
   396
		return(ret);
sl@0
   397
sl@0
   398
	ret=b->method->callback_ctrl(b,cmd,fp);
sl@0
   399
sl@0
   400
	if (cb != NULL)
sl@0
   401
		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
sl@0
   402
			0,ret);
sl@0
   403
	return(ret);
sl@0
   404
	}
sl@0
   405
sl@0
   406
/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
sl@0
   407
 * do; but those macros have inappropriate return type, and for interfacing
sl@0
   408
 * from other programming languages, C macros aren't much of a help anyway. */
sl@0
   409
EXPORT_C size_t BIO_ctrl_pending(BIO *bio)
sl@0
   410
	{
sl@0
   411
	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
sl@0
   412
	}
sl@0
   413
sl@0
   414
EXPORT_C size_t BIO_ctrl_wpending(BIO *bio)
sl@0
   415
	{
sl@0
   416
	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
sl@0
   417
	}
sl@0
   418
sl@0
   419
sl@0
   420
/* put the 'bio' on the end of b's list of operators */
sl@0
   421
EXPORT_C BIO *BIO_push(BIO *b, BIO *bio)
sl@0
   422
	{
sl@0
   423
	BIO *lb;
sl@0
   424
sl@0
   425
	if (b == NULL) return(bio);
sl@0
   426
	lb=b;
sl@0
   427
	while (lb->next_bio != NULL)
sl@0
   428
		lb=lb->next_bio;
sl@0
   429
	lb->next_bio=bio;
sl@0
   430
	if (bio != NULL)
sl@0
   431
		bio->prev_bio=lb;
sl@0
   432
	/* called to do internal processing */
sl@0
   433
	BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
sl@0
   434
	return(b);
sl@0
   435
	}
sl@0
   436
sl@0
   437
/* Remove the first and return the rest */
sl@0
   438
EXPORT_C BIO *BIO_pop(BIO *b)
sl@0
   439
	{
sl@0
   440
	BIO *ret;
sl@0
   441
sl@0
   442
	if (b == NULL) return(NULL);
sl@0
   443
	ret=b->next_bio;
sl@0
   444
sl@0
   445
	BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
sl@0
   446
sl@0
   447
	if (b->prev_bio != NULL)
sl@0
   448
		b->prev_bio->next_bio=b->next_bio;
sl@0
   449
	if (b->next_bio != NULL)
sl@0
   450
		b->next_bio->prev_bio=b->prev_bio;
sl@0
   451
sl@0
   452
	b->next_bio=NULL;
sl@0
   453
	b->prev_bio=NULL;
sl@0
   454
	return(ret);
sl@0
   455
	}
sl@0
   456
sl@0
   457
EXPORT_C BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
sl@0
   458
	{
sl@0
   459
	BIO *b,*last;
sl@0
   460
sl@0
   461
	b=last=bio;
sl@0
   462
	for (;;)
sl@0
   463
		{
sl@0
   464
		if (!BIO_should_retry(b)) break;
sl@0
   465
		last=b;
sl@0
   466
		b=b->next_bio;
sl@0
   467
		if (b == NULL) break;
sl@0
   468
		}
sl@0
   469
	if (reason != NULL) *reason=last->retry_reason;
sl@0
   470
	return(last);
sl@0
   471
	}
sl@0
   472
sl@0
   473
EXPORT_C int BIO_get_retry_reason(BIO *bio)
sl@0
   474
	{
sl@0
   475
	return(bio->retry_reason);
sl@0
   476
	}
sl@0
   477
sl@0
   478
EXPORT_C BIO *BIO_find_type(BIO *bio, int type)
sl@0
   479
	{
sl@0
   480
	int mt,mask;
sl@0
   481
sl@0
   482
	if(!bio) return NULL;
sl@0
   483
	mask=type&0xff;
sl@0
   484
	do	{
sl@0
   485
		if (bio->method != NULL)
sl@0
   486
			{
sl@0
   487
			mt=bio->method->type;
sl@0
   488
sl@0
   489
			if (!mask)
sl@0
   490
				{
sl@0
   491
				if (mt & type) return(bio);
sl@0
   492
				}
sl@0
   493
			else if (mt == type)
sl@0
   494
				return(bio);
sl@0
   495
			}
sl@0
   496
		bio=bio->next_bio;
sl@0
   497
		} while (bio != NULL);
sl@0
   498
	return(NULL);
sl@0
   499
	}
sl@0
   500
sl@0
   501
EXPORT_C BIO *BIO_next(BIO *b)
sl@0
   502
	{
sl@0
   503
	if(!b) return NULL;
sl@0
   504
	return b->next_bio;
sl@0
   505
	}
sl@0
   506
sl@0
   507
EXPORT_C void BIO_free_all(BIO *bio)
sl@0
   508
	{
sl@0
   509
	BIO *b;
sl@0
   510
	int ref;
sl@0
   511
sl@0
   512
	while (bio != NULL)
sl@0
   513
		{
sl@0
   514
		b=bio;
sl@0
   515
		ref=b->references;
sl@0
   516
		bio=bio->next_bio;
sl@0
   517
		BIO_free(b);
sl@0
   518
		/* Since ref count > 1, don't free anyone else. */
sl@0
   519
		if (ref > 1) break;
sl@0
   520
		}
sl@0
   521
	}
sl@0
   522
sl@0
   523
EXPORT_C BIO *BIO_dup_chain(BIO *in)
sl@0
   524
	{
sl@0
   525
	BIO *ret=NULL,*eoc=NULL,*bio,*new;
sl@0
   526
sl@0
   527
	for (bio=in; bio != NULL; bio=bio->next_bio)
sl@0
   528
		{
sl@0
   529
		if ((new=BIO_new(bio->method)) == NULL) goto err;
sl@0
   530
		new->callback=bio->callback;
sl@0
   531
		new->cb_arg=bio->cb_arg;
sl@0
   532
		new->init=bio->init;
sl@0
   533
		new->shutdown=bio->shutdown;
sl@0
   534
		new->flags=bio->flags;
sl@0
   535
sl@0
   536
		/* This will let SSL_s_sock() work with stdin/stdout */
sl@0
   537
		new->num=bio->num;
sl@0
   538
sl@0
   539
		if (!BIO_dup_state(bio,(char *)new))
sl@0
   540
			{
sl@0
   541
			BIO_free(new);
sl@0
   542
			goto err;
sl@0
   543
			}
sl@0
   544
sl@0
   545
		/* copy app data */
sl@0
   546
		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
sl@0
   547
					&bio->ex_data))
sl@0
   548
			goto err;
sl@0
   549
sl@0
   550
		if (ret == NULL)
sl@0
   551
			{
sl@0
   552
			eoc=new;
sl@0
   553
			ret=eoc;
sl@0
   554
			}
sl@0
   555
		else
sl@0
   556
			{
sl@0
   557
			BIO_push(eoc,new);
sl@0
   558
			eoc=new;
sl@0
   559
			}
sl@0
   560
		}
sl@0
   561
	return(ret);
sl@0
   562
err:
sl@0
   563
	if (ret != NULL)
sl@0
   564
		BIO_free(ret);
sl@0
   565
	return(NULL);	
sl@0
   566
	}
sl@0
   567
sl@0
   568
EXPORT_C void BIO_copy_next_retry(BIO *b)
sl@0
   569
	{
sl@0
   570
	BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
sl@0
   571
	b->retry_reason=b->next_bio->retry_reason;
sl@0
   572
	}
sl@0
   573
sl@0
   574
EXPORT_C int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
sl@0
   575
	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
sl@0
   576
	{
sl@0
   577
	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
sl@0
   578
				new_func, dup_func, free_func);
sl@0
   579
	}
sl@0
   580
sl@0
   581
EXPORT_C int BIO_set_ex_data(BIO *bio, int idx, void *data)
sl@0
   582
	{
sl@0
   583
	return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
sl@0
   584
	}
sl@0
   585
sl@0
   586
EXPORT_C void *BIO_get_ex_data(BIO *bio, int idx)
sl@0
   587
	{
sl@0
   588
	return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
sl@0
   589
	}
sl@0
   590
sl@0
   591
EXPORT_C unsigned long BIO_number_read(BIO *bio)
sl@0
   592
{
sl@0
   593
	if(bio) return bio->num_read;
sl@0
   594
	return 0;
sl@0
   595
}
sl@0
   596
sl@0
   597
EXPORT_C unsigned long BIO_number_written(BIO *bio)
sl@0
   598
{
sl@0
   599
	if(bio) return bio->num_write;
sl@0
   600
	return 0;
sl@0
   601
}
sl@0
   602
sl@0
   603
IMPLEMENT_STACK_OF(BIO)