Fix const declarations.
[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 "crypto.h"
62 #include "cryptlib.h"
63 #include "bio.h"
64 #include "stack.h"
65
66 static STACK *bio_meth=NULL;
67 static int bio_meth_num=0;
68
69 BIO *BIO_new(method)
70 BIO_METHOD *method;
71         {
72         BIO *ret=NULL;
73
74         ret=(BIO *)Malloc(sizeof(BIO));
75         if (ret == NULL)
76                 {
77                 BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
78                 return(NULL);
79                 }
80         if (!BIO_set(ret,method))
81                 {
82                 Free(ret);
83                 ret=NULL;
84                 }
85         return(ret);
86         }
87
88 int BIO_set(bio,method)
89 BIO *bio;
90 BIO_METHOD *method;
91         {
92         bio->method=method;
93         bio->callback=NULL;
94         bio->cb_arg=NULL;
95         bio->init=0;
96         bio->shutdown=1;
97         bio->flags=0;
98         bio->retry_reason=0;
99         bio->num=0;
100         bio->ptr=NULL;
101         bio->prev_bio=NULL;
102         bio->next_bio=NULL;
103         bio->references=1;
104         bio->num_read=0L;
105         bio->num_write=0L;
106         CRYPTO_new_ex_data(bio_meth,(char *)bio,&bio->ex_data);
107         if (method->create != NULL)
108                 if (!method->create(bio))
109                         return(0);
110         return(1);
111         }
112
113 int BIO_free(a)
114 BIO *a;
115         {
116         int ret=0,i;
117
118         if (a == NULL) return(0);
119
120         i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
121 #ifdef REF_PRINT
122         REF_PRINT("BIO",a);
123 #endif
124         if (i > 0) return(1);
125 #ifdef REF_CHECK
126         if (i < 0)
127                 {
128                 fprintf(stderr,"BIO_free, bad reference count\n");
129                 abort();
130                 }
131 #endif
132         if ((a->callback != NULL) &&
133                 ((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
134                         return(i);
135
136         CRYPTO_free_ex_data(bio_meth,(char *)a,&a->ex_data);
137
138         if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
139         ret=a->method->destroy(a);
140         Free(a);
141         return(1);
142         }
143
144 int BIO_read(b,out,outl)
145 BIO *b;
146 char *out;
147 int outl;
148         {
149         int i;
150         long (*cb)();
151
152         if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
153                 {
154                 BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
155                 return(-2);
156                 }
157
158         cb=b->callback;
159         if ((cb != NULL) &&
160                 ((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
161                         return(i);
162
163         if (!b->init)
164                 {
165                 BIOerr(BIO_F_BIO_READ,BIO_R_UNINITALISED);
166                 return(-2);
167                 }
168
169         i=b->method->bread(b,out,outl);
170
171         if (i > 0) b->num_read+=(unsigned long)i;
172
173         if (cb != NULL)
174                 i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
175                         0L,(long)i);
176         return(i);
177         }
178
179 int BIO_write(b,in,inl)
180 BIO *b;
181 const char *in;
182 int inl;
183         {
184         int i;
185         long (*cb)();
186
187         if (b == NULL)
188                 return(0);
189
190         cb=b->callback;
191         if ((b->method == NULL) || (b->method->bwrite == NULL))
192                 {
193                 BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
194                 return(-2);
195                 }
196
197         if ((cb != NULL) &&
198                 ((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
199                         return(i);
200
201         if (!b->init)
202                 {
203                 BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITALISED);
204                 return(-2);
205                 }
206
207         i=b->method->bwrite(b,in,inl);
208
209         if (i > 0) b->num_write+=(unsigned long)i;
210
211         /* This is evil and not thread safe.  If the BIO has been freed,
212          * we must not call the callback.  The only way to be able to
213          * determine this is the reference count which is now invalid since
214          * the memory has been free()ed.
215          */
216         if (b->references <= 0) abort();
217         if (cb != NULL) /* && (b->references >= 1)) */
218                 i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
219                         0L,(long)i);
220         return(i);
221         }
222
223 int BIO_puts(b,in)
224 BIO *b;
225 const char *in;
226         {
227         int i;
228         long (*cb)();
229
230         if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
231                 {
232                 BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
233                 return(-2);
234                 }
235
236         cb=b->callback;
237
238         if ((cb != NULL) &&
239                 ((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
240                         return(i);
241
242         if (!b->init)
243                 {
244                 BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITALISED);
245                 return(-2);
246                 }
247
248         i=b->method->bputs(b,in);
249
250         if (cb != NULL)
251                 i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
252                         0L,(long)i);
253         return(i);
254         }
255
256 int BIO_gets(b,in,inl)
257 BIO *b;
258 char *in;
259 int inl;
260         {
261         int i;
262         long (*cb)();
263
264         if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
265                 {
266                 BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
267                 return(-2);
268                 }
269
270         cb=b->callback;
271
272         if ((cb != NULL) &&
273                 ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
274                         return(i);
275
276         if (!b->init)
277                 {
278                 BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITALISED);
279                 return(-2);
280                 }
281
282         i=b->method->bgets(b,in,inl);
283
284         if (cb != NULL)
285                 i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
286                         0L,(long)i);
287         return(i);
288         }
289
290 long BIO_int_ctrl(b,cmd,larg,iarg)
291 BIO *b;
292 int cmd;
293 long larg;
294 int iarg;
295         {
296         int i;
297
298         i=iarg;
299         return(BIO_ctrl(b,cmd,larg,(char *)&i));
300         }
301
302 char *BIO_ptr_ctrl(b,cmd,larg)
303 BIO *b;
304 int cmd;
305 long larg;
306         {
307         char *p=NULL;
308
309         if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
310                 return(NULL);
311         else
312                 return(p);
313         }
314
315 long BIO_ctrl(b,cmd,larg,parg)
316 BIO *b;
317 int cmd;
318 long larg;
319 char *parg;
320         {
321         long ret;
322         long (*cb)();
323
324         if (b == NULL) return(0);
325
326         if ((b->method == NULL) || (b->method->ctrl == NULL))
327                 {
328                 BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
329                 return(-2);
330                 }
331
332         cb=b->callback;
333
334         if ((cb != NULL) &&
335                 ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
336                 return(ret);
337
338         ret=b->method->ctrl(b,cmd,larg,parg);
339
340         if (cb != NULL)
341                 ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
342                         larg,ret);
343         return(ret);
344         }
345
346 /* put the 'bio' on the end of b's list of operators */
347 BIO *BIO_push(b,bio)
348 BIO *b,*bio;
349         {
350         BIO *lb;
351
352         if (b == NULL) return(bio);
353         lb=b;
354         while (lb->next_bio != NULL)
355                 lb=lb->next_bio;
356         lb->next_bio=bio;
357         if (bio != NULL)
358                 bio->prev_bio=lb;
359         /* called to do internal processing */
360         BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
361         return(b);
362         }
363
364 /* Remove the first and return the rest */
365 BIO *BIO_pop(b)
366 BIO *b;
367         {
368         BIO *ret;
369
370         if (b == NULL) return(NULL);
371         ret=b->next_bio;
372
373         if (b->prev_bio != NULL)
374                 b->prev_bio->next_bio=b->next_bio;
375         if (b->next_bio != NULL)
376                 b->next_bio->prev_bio=b->prev_bio;
377
378         b->next_bio=NULL;
379         b->prev_bio=NULL;
380         BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
381         return(ret);
382         }
383
384 BIO *BIO_get_retry_BIO(bio,reason)
385 BIO *bio;
386 int *reason;
387         {
388         BIO *b,*last;
389
390         b=last=bio;
391         for (;;)
392                 {
393                 if (!BIO_should_retry(b)) break;
394                 last=b;
395                 b=b->next_bio;
396                 if (b == NULL) break;
397                 }
398         if (reason != NULL) *reason=last->retry_reason;
399         return(last);
400         }
401
402 int BIO_get_retry_reason(bio)
403 BIO *bio;
404         {
405         return(bio->retry_reason);
406         }
407
408 BIO *BIO_find_type(bio,type)
409 BIO *bio;
410 int type;
411         {
412         int mt,mask;
413
414         mask=type&0xff;
415         do      {
416                 if (bio->method != NULL)
417                         {
418                         mt=bio->method->type;
419
420                         if (!mask)
421                                 {
422                                 if (mt & type) return(bio);
423                                 }
424                         else if (mt == type)
425                                 return(bio);
426                         }
427                 bio=bio->next_bio;
428                 } while (bio != NULL);
429         return(NULL);
430         }
431
432 void BIO_free_all(bio)
433 BIO *bio;
434         {
435         BIO *b;
436         int ref;
437
438         while (bio != NULL)
439                 {
440                 b=bio;
441                 ref=b->references;
442                 bio=bio->next_bio;
443                 BIO_free(b);
444                 /* Since ref count > 1, don't free anyone else. */
445                 if (ref > 1) break;
446                 }
447         }
448
449 BIO *BIO_dup_chain(in)
450 BIO *in;
451         {
452         BIO *ret=NULL,*eoc=NULL,*bio,*new;
453
454         for (bio=in; bio != NULL; bio=bio->next_bio)
455                 {
456                 if ((new=BIO_new(bio->method)) == NULL) goto err;
457                 new->callback=bio->callback;
458                 new->cb_arg=bio->cb_arg;
459                 new->init=bio->init;
460                 new->shutdown=bio->shutdown;
461                 new->flags=bio->flags;
462
463                 /* This will let SSL_s_sock() work with stdin/stdout */
464                 new->num=bio->num;
465
466                 if (!BIO_dup_state(bio,(char *)new))
467                         {
468                         BIO_free(new);
469                         goto err;
470                         }
471
472                 /* copy app data */
473                 if (!CRYPTO_dup_ex_data(bio_meth,&new->ex_data,&bio->ex_data))
474                         goto err;
475
476                 if (ret == NULL)
477                         {
478                         eoc=new;
479                         ret=eoc;
480                         }
481                 else
482                         {
483                         BIO_push(eoc,new);
484                         eoc=new;
485                         }
486                 }
487         return(ret);
488 err:
489         if (ret != NULL)
490                 BIO_free(ret);
491         return(NULL);   
492         }
493
494 void BIO_copy_next_retry(b)
495 BIO *b;
496         {
497         BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
498         b->retry_reason=b->next_bio->retry_reason;
499         }
500
501 int BIO_get_ex_new_index(argl,argp,new_func,dup_func,free_func)
502 long argl;
503 char *argp;
504 int (*new_func)();
505 int (*dup_func)();
506 void (*free_func)();
507         {
508         bio_meth_num++;
509         return(CRYPTO_get_ex_new_index(bio_meth_num-1,&bio_meth,
510                 argl,argp,new_func,dup_func,free_func));
511         }
512
513 int BIO_set_ex_data(bio,idx,data)
514 BIO *bio;
515 int idx;
516 char *data;
517         {
518         return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
519         }
520
521 char *BIO_get_ex_data(bio,idx)
522 BIO *bio;
523 int idx;
524         {
525         return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
526         }
527