X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=crypto%2Fbio%2Fbio_lib.c;h=9c9646afa8a22c3a6a208877c76e7f92d8458f31;hb=94c666479d2c099f697233a3f8a8082afa135d0b;hp=62d26992af33d9404acd5bf3a89dd43e34393768;hpb=b1c4fe36258dde2950f59fec5d5f86743e495d9d;p=openssl.git diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 62d26992af..9c9646afa8 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -63,14 +63,11 @@ #include #include -static STACK *bio_meth=NULL; -static int bio_meth_num=0; - BIO *BIO_new(BIO_METHOD *method) { BIO *ret=NULL; - ret=(BIO *)Malloc(sizeof(BIO)); + ret=(BIO *)OPENSSL_malloc(sizeof(BIO)); if (ret == NULL) { BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE); @@ -78,7 +75,7 @@ BIO *BIO_new(BIO_METHOD *method) } if (!BIO_set(ret,method)) { - Free(ret); + OPENSSL_free(ret); ret=NULL; } return(ret); @@ -100,16 +97,20 @@ int BIO_set(BIO *bio, BIO_METHOD *method) bio->references=1; bio->num_read=0L; bio->num_write=0L; - CRYPTO_new_ex_data(bio_meth,(char *)bio,&bio->ex_data); + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); if (method->create != NULL) if (!method->create(bio)) + { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, + &bio->ex_data); return(0); + } return(1); } int BIO_free(BIO *a) { - int ret=0,i; + int i; if (a == NULL) return(0); @@ -129,18 +130,67 @@ int BIO_free(BIO *a) ((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0)) return(i); - CRYPTO_free_ex_data(bio_meth,(char *)a,&a->ex_data); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); if ((a->method == NULL) || (a->method->destroy == NULL)) return(1); - ret=a->method->destroy(a); - Free(a); + a->method->destroy(a); + OPENSSL_free(a); return(1); } +void BIO_vfree(BIO *a) + { BIO_free(a); } + +void BIO_clear_flags(BIO *b, int flags) + { + b->flags &= ~flags; + } + +int BIO_test_flags(const BIO *b, int flags) + { + return (b->flags & flags); + } + +void BIO_set_flags(BIO *b, int flags) + { + b->flags |= flags; + } + +long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long) + { + return b->callback; + } + +void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long)) + { + b->callback = cb; + } + +void BIO_set_callback_arg(BIO *b, char *arg) + { + b->cb_arg = arg; + } + +char * BIO_get_callback_arg(const BIO *b) + { + return b->cb_arg; + } + +const char * BIO_method_name(const BIO *b) + { + return b->method->name; + } + +int BIO_method_type(const BIO *b) + { + return b->method->type; + } + + int BIO_read(BIO *b, void *out, int outl) { int i; - long (*cb)(); + long (*cb)(BIO *,int,const char *,int,long,long); if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { @@ -169,10 +219,10 @@ int BIO_read(BIO *b, void *out, int outl) return(i); } -int BIO_write(BIO *b, const char *in, int inl) +int BIO_write(BIO *b, const void *in, int inl) { int i; - long (*cb)(); + long (*cb)(BIO *,int,const char *,int,long,long); if (b == NULL) return(0); @@ -198,13 +248,7 @@ int BIO_write(BIO *b, const char *in, int inl) if (i > 0) b->num_write+=(unsigned long)i; - /* This is evil and not thread safe. If the BIO has been freed, - * we must not call the callback. The only way to be able to - * determine this is the reference count which is now invalid since - * the memory has been free()ed. - */ - if (b->references <= 0) abort(); - if (cb != NULL) /* && (b->references >= 1)) */ + if (cb != NULL) i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl, 0L,(long)i); return(i); @@ -213,7 +257,7 @@ int BIO_write(BIO *b, const char *in, int inl) int BIO_puts(BIO *b, const char *in) { int i; - long (*cb)(); + long (*cb)(BIO *,int,const char *,int,long,long); if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { @@ -235,6 +279,8 @@ int BIO_puts(BIO *b, const char *in) i=b->method->bputs(b,in); + if (i > 0) b->num_write+=(unsigned long)i; + if (cb != NULL) i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0, 0L,(long)i); @@ -244,7 +290,7 @@ int BIO_puts(BIO *b, const char *in) int BIO_gets(BIO *b, char *in, int inl) { int i; - long (*cb)(); + long (*cb)(BIO *,int,const char *,int,long,long); if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { @@ -272,6 +318,18 @@ int BIO_gets(BIO *b, char *in, int inl) return(i); } +int BIO_indent(BIO *b,int indent,int max) + { + if(indent < 0) + indent=0; + if(indent > max) + indent=max; + while(indent--) + if(BIO_puts(b," ") != 1) + return 0; + return 1; + } + long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { int i; @@ -290,10 +348,10 @@ char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) return(p); } -long BIO_ctrl(BIO *b, int cmd, long larg, char *parg) +long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) { long ret; - long (*cb)(); + long (*cb)(BIO *,int,const char *,int,long,long); if (b == NULL) return(0); @@ -317,6 +375,47 @@ long BIO_ctrl(BIO *b, int cmd, long larg, char *parg) return(ret); } +long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long)) + { + long ret; + long (*cb)(BIO *,int,const char *,int,long,long); + + if (b == NULL) return(0); + + if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) + { + BIOerr(BIO_F_BIO_CALLBACK_CTRL,BIO_R_UNSUPPORTED_METHOD); + return(-2); + } + + cb=b->callback; + + if ((cb != NULL) && + ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0)) + return(ret); + + ret=b->method->callback_ctrl(b,cmd,fp); + + if (cb != NULL) + ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd, + 0,ret); + return(ret); + } + +/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros + * do; but those macros have inappropriate return type, and for interfacing + * from other programming languages, C macros aren't much of a help anyway. */ +size_t BIO_ctrl_pending(BIO *bio) + { + return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); + } + +size_t BIO_ctrl_wpending(BIO *bio) + { + return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); + } + + /* put the 'bio' on the end of b's list of operators */ BIO *BIO_push(BIO *b, BIO *bio) { @@ -330,7 +429,7 @@ BIO *BIO_push(BIO *b, BIO *bio) if (bio != NULL) bio->prev_bio=lb; /* called to do internal processing */ - BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); + BIO_ctrl(b,BIO_CTRL_PUSH,0,lb); return(b); } @@ -342,6 +441,8 @@ BIO *BIO_pop(BIO *b) if (b == NULL) return(NULL); ret=b->next_bio; + BIO_ctrl(b,BIO_CTRL_POP,0,b); + if (b->prev_bio != NULL) b->prev_bio->next_bio=b->next_bio; if (b->next_bio != NULL) @@ -349,7 +450,6 @@ BIO *BIO_pop(BIO *b) b->next_bio=NULL; b->prev_bio=NULL; - BIO_ctrl(b,BIO_CTRL_POP,0,NULL); return(ret); } @@ -378,6 +478,7 @@ BIO *BIO_find_type(BIO *bio, int type) { int mt,mask; + if(!bio) return NULL; mask=type&0xff; do { if (bio->method != NULL) @@ -396,6 +497,12 @@ BIO *BIO_find_type(BIO *bio, int type) return(NULL); } +BIO *BIO_next(BIO *b) + { + if(!b) return NULL; + return b->next_bio; + } + void BIO_free_all(BIO *bio) { BIO *b; @@ -414,39 +521,40 @@ void BIO_free_all(BIO *bio) BIO *BIO_dup_chain(BIO *in) { - BIO *ret=NULL,*eoc=NULL,*bio,*new; + BIO *ret=NULL,*eoc=NULL,*bio,*new_bio; for (bio=in; bio != NULL; bio=bio->next_bio) { - if ((new=BIO_new(bio->method)) == NULL) goto err; - new->callback=bio->callback; - new->cb_arg=bio->cb_arg; - new->init=bio->init; - new->shutdown=bio->shutdown; - new->flags=bio->flags; + if ((new_bio=BIO_new(bio->method)) == NULL) goto err; + new_bio->callback=bio->callback; + new_bio->cb_arg=bio->cb_arg; + new_bio->init=bio->init; + new_bio->shutdown=bio->shutdown; + new_bio->flags=bio->flags; /* This will let SSL_s_sock() work with stdin/stdout */ - new->num=bio->num; + new_bio->num=bio->num; - if (!BIO_dup_state(bio,(char *)new)) + if (!BIO_dup_state(bio,(char *)new_bio)) { - BIO_free(new); + BIO_free(new_bio); goto err; } /* copy app data */ - if (!CRYPTO_dup_ex_data(bio_meth,&new->ex_data,&bio->ex_data)) + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, + &bio->ex_data)) goto err; if (ret == NULL) { - eoc=new; + eoc=new_bio; ret=eoc; } else { - BIO_push(eoc,new); - eoc=new; + BIO_push(eoc,new_bio); + eoc=new_bio; } } return(ret); @@ -462,21 +570,33 @@ void BIO_copy_next_retry(BIO *b) b->retry_reason=b->next_bio->retry_reason; } -int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(), - int (*dup_func)(), void (*free_func)()) +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { - bio_meth_num++; - return(CRYPTO_get_ex_new_index(bio_meth_num-1,&bio_meth, - argl,argp,new_func,dup_func,free_func)); + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, + new_func, dup_func, free_func); } -int BIO_set_ex_data(BIO *bio, int idx, char *data) +int BIO_set_ex_data(BIO *bio, int idx, void *data) { return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data)); } -char *BIO_get_ex_data(BIO *bio, int idx) +void *BIO_get_ex_data(BIO *bio, int idx) { return(CRYPTO_get_ex_data(&(bio->ex_data),idx)); } +unsigned long BIO_number_read(BIO *bio) +{ + if(bio) return bio->num_read; + return 0; +} + +unsigned long BIO_number_written(BIO *bio) +{ + if(bio) return bio->num_write; + return 0; +} + +IMPLEMENT_STACK_OF(BIO)