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