LCOV - code coverage report
Current view: top level - bio - bf_buff.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 80 235 34.0 %
Date: 2014-08-02 Functions: 5 9 55.6 %
Branches: 28 167 16.8 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/bio/bf_buff.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 "cryptlib.h"
      62                 :            : #include <openssl/bio.h>
      63                 :            : 
      64                 :            : static int buffer_write(BIO *h, const char *buf,int num);
      65                 :            : static int buffer_read(BIO *h, char *buf, int size);
      66                 :            : static int buffer_puts(BIO *h, const char *str);
      67                 :            : static int buffer_gets(BIO *h, char *str, int size);
      68                 :            : static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
      69                 :            : static int buffer_new(BIO *h);
      70                 :            : static int buffer_free(BIO *data);
      71                 :            : static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
      72                 :            : #define DEFAULT_BUFFER_SIZE     4096
      73                 :            : 
      74                 :            : static BIO_METHOD methods_buffer=
      75                 :            :         {
      76                 :            :         BIO_TYPE_BUFFER,
      77                 :            :         "buffer",
      78                 :            :         buffer_write,
      79                 :            :         buffer_read,
      80                 :            :         buffer_puts,
      81                 :            :         buffer_gets,
      82                 :            :         buffer_ctrl,
      83                 :            :         buffer_new,
      84                 :            :         buffer_free,
      85                 :            :         buffer_callback_ctrl,
      86                 :            :         };
      87                 :            : 
      88                 :       2231 : BIO_METHOD *BIO_f_buffer(void)
      89                 :            :         {
      90                 :       2231 :         return(&methods_buffer);
      91                 :            :         }
      92                 :            : 
      93                 :       2231 : static int buffer_new(BIO *bi)
      94                 :            :         {
      95                 :            :         BIO_F_BUFFER_CTX *ctx;
      96                 :            : 
      97                 :       2231 :         ctx=(BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
      98         [ +  - ]:       2231 :         if (ctx == NULL) return(0);
      99                 :       2231 :         ctx->ibuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
     100         [ -  + ]:       2231 :         if (ctx->ibuf == NULL) { OPENSSL_free(ctx); return(0); }
     101                 :       2231 :         ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
     102         [ -  + ]:       2231 :         if (ctx->obuf == NULL) { OPENSSL_free(ctx->ibuf); OPENSSL_free(ctx); return(0); }
     103                 :       2231 :         ctx->ibuf_size=DEFAULT_BUFFER_SIZE;
     104                 :       2231 :         ctx->obuf_size=DEFAULT_BUFFER_SIZE;
     105                 :       2231 :         ctx->ibuf_len=0;
     106                 :       2231 :         ctx->ibuf_off=0;
     107                 :       2231 :         ctx->obuf_len=0;
     108                 :       2231 :         ctx->obuf_off=0;
     109                 :            : 
     110                 :       2231 :         bi->init=1;
     111                 :       2231 :         bi->ptr=(char *)ctx;
     112                 :       2231 :         bi->flags=0;
     113                 :       2231 :         return(1);
     114                 :            :         }
     115                 :            : 
     116                 :       2231 : static int buffer_free(BIO *a)
     117                 :            :         {
     118                 :            :         BIO_F_BUFFER_CTX *b;
     119                 :            : 
     120         [ +  - ]:       2231 :         if (a == NULL) return(0);
     121                 :       2231 :         b=(BIO_F_BUFFER_CTX *)a->ptr;
     122         [ +  - ]:       2231 :         if (b->ibuf != NULL) OPENSSL_free(b->ibuf);
     123         [ +  - ]:       2231 :         if (b->obuf != NULL) OPENSSL_free(b->obuf);
     124                 :       2231 :         OPENSSL_free(a->ptr);
     125                 :       2231 :         a->ptr=NULL;
     126                 :       2231 :         a->init=0;
     127                 :       2231 :         a->flags=0;
     128                 :       2231 :         return(1);
     129                 :            :         }
     130                 :            :         
     131                 :          0 : static int buffer_read(BIO *b, char *out, int outl)
     132                 :            :         {
     133                 :          0 :         int i,num=0;
     134                 :            :         BIO_F_BUFFER_CTX *ctx;
     135                 :            : 
     136         [ #  # ]:          0 :         if (out == NULL) return(0);
     137                 :          0 :         ctx=(BIO_F_BUFFER_CTX *)b->ptr;
     138                 :            : 
     139 [ #  # ][ #  # ]:          0 :         if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
     140                 :          0 :         num=0;
     141                 :          0 :         BIO_clear_retry_flags(b);
     142                 :            : 
     143                 :            : start:
     144                 :          0 :         i=ctx->ibuf_len;
     145                 :            :         /* If there is stuff left over, grab it */
     146         [ #  # ]:          0 :         if (i != 0)
     147                 :            :                 {
     148         [ #  # ]:          0 :                 if (i > outl) i=outl;
     149                 :          0 :                 memcpy(out,&(ctx->ibuf[ctx->ibuf_off]),i);
     150                 :          0 :                 ctx->ibuf_off+=i;
     151                 :          0 :                 ctx->ibuf_len-=i;
     152                 :          0 :                 num+=i;
     153         [ #  # ]:          0 :                 if (outl == i)  return(num);
     154                 :          0 :                 outl-=i;
     155                 :          0 :                 out+=i;
     156                 :            :                 }
     157                 :            : 
     158                 :            :         /* We may have done a partial read. try to do more.
     159                 :            :          * We have nothing in the buffer.
     160                 :            :          * If we get an error and have read some data, just return it
     161                 :            :          * and let them retry to get the error again.
     162                 :            :          * copy direct to parent address space */
     163         [ #  # ]:          0 :         if (outl > ctx->ibuf_size)
     164                 :            :                 {
     165                 :            :                 for (;;)
     166                 :            :                         {
     167                 :          0 :                         i=BIO_read(b->next_bio,out,outl);
     168         [ #  # ]:          0 :                         if (i <= 0)
     169                 :            :                                 {
     170                 :          0 :                                 BIO_copy_next_retry(b);
     171 [ #  # ][ #  # ]:          0 :                                 if (i < 0) return((num > 0)?num:i);
     172         [ #  # ]:          0 :                                 if (i == 0) return(num);
     173                 :            :                                 }
     174                 :          0 :                         num+=i;
     175         [ #  # ]:          0 :                         if (outl == i) return(num);
     176                 :          0 :                         out+=i;
     177                 :          0 :                         outl-=i;
     178                 :          0 :                         }
     179                 :            :                 }
     180                 :            :         /* else */
     181                 :            : 
     182                 :            :         /* we are going to be doing some buffering */
     183                 :          0 :         i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
     184         [ #  # ]:          0 :         if (i <= 0)
     185                 :            :                 {
     186                 :          0 :                 BIO_copy_next_retry(b);
     187 [ #  # ][ #  # ]:          0 :                 if (i < 0) return((num > 0)?num:i);
     188         [ #  # ]:          0 :                 if (i == 0) return(num);
     189                 :            :                 }
     190                 :          0 :         ctx->ibuf_off=0;
     191                 :          0 :         ctx->ibuf_len=i;
     192                 :            : 
     193                 :            :         /* Lets re-read using ourselves :-) */
     194                 :          0 :         goto start;
     195                 :            :         }
     196                 :            : 
     197                 :      10352 : static int buffer_write(BIO *b, const char *in, int inl)
     198                 :            :         {
     199                 :      10352 :         int i,num=0;
     200                 :            :         BIO_F_BUFFER_CTX *ctx;
     201                 :            : 
     202         [ +  - ]:      10352 :         if ((in == NULL) || (inl <= 0)) return(0);
     203                 :      10352 :         ctx=(BIO_F_BUFFER_CTX *)b->ptr;
     204 [ +  - ][ +  - ]:      10352 :         if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
     205                 :            : 
     206                 :      10352 :         BIO_clear_retry_flags(b);
     207                 :            : start:
     208                 :      10352 :         i=ctx->obuf_size-(ctx->obuf_len+ctx->obuf_off);
     209                 :            :         /* add to buffer and return */
     210         [ +  - ]:      10352 :         if (i >= inl)
     211                 :            :                 {
     212                 :      10352 :                 memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl);
     213                 :      10352 :                 ctx->obuf_len+=inl;
     214                 :      10352 :                 return(num+inl);
     215                 :            :                 }
     216                 :            :         /* else */
     217                 :            :         /* stuff already in buffer, so add to it first, then flush */
     218         [ #  # ]:          0 :         if (ctx->obuf_len != 0)
     219                 :            :                 {
     220         [ #  # ]:          0 :                 if (i > 0) /* lets fill it up if we can */
     221                 :            :                         {
     222                 :          0 :                         memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i);
     223                 :          0 :                         in+=i;
     224                 :          0 :                         inl-=i;
     225                 :          0 :                         num+=i;
     226                 :          0 :                         ctx->obuf_len+=i;
     227                 :            :                         }
     228                 :            :                 /* we now have a full buffer needing flushing */
     229                 :            :                 for (;;)
     230                 :            :                         {
     231                 :          0 :                         i=BIO_write(b->next_bio,&(ctx->obuf[ctx->obuf_off]),
     232                 :            :                                 ctx->obuf_len);
     233         [ #  # ]:          0 :                         if (i <= 0)
     234                 :            :                                 {
     235                 :          0 :                                 BIO_copy_next_retry(b);
     236                 :            : 
     237 [ #  # ][ #  # ]:          0 :                                 if (i < 0) return((num > 0)?num:i);
     238         [ #  # ]:          0 :                                 if (i == 0) return(num);
     239                 :            :                                 }
     240                 :          0 :                         ctx->obuf_off+=i;
     241                 :          0 :                         ctx->obuf_len-=i;
     242         [ #  # ]:          0 :                         if (ctx->obuf_len == 0) break;
     243                 :            :                         }
     244                 :            :                 }
     245                 :            :         /* we only get here if the buffer has been flushed and we
     246                 :            :          * still have stuff to write */
     247                 :          0 :         ctx->obuf_off=0;
     248                 :            : 
     249                 :            :         /* we now have inl bytes to write */
     250         [ #  # ]:          0 :         while (inl >= ctx->obuf_size)
     251                 :            :                 {
     252                 :          0 :                 i=BIO_write(b->next_bio,in,inl);
     253         [ #  # ]:          0 :                 if (i <= 0)
     254                 :            :                         {
     255                 :          0 :                         BIO_copy_next_retry(b);
     256 [ #  # ][ #  # ]:          0 :                         if (i < 0) return((num > 0)?num:i);
     257         [ #  # ]:          0 :                         if (i == 0) return(num);
     258                 :            :                         }
     259                 :          0 :                 num+=i;
     260                 :          0 :                 in+=i;
     261                 :          0 :                 inl-=i;
     262         [ #  # ]:          0 :                 if (inl == 0) return(num);
     263                 :            :                 }
     264                 :            : 
     265                 :            :         /* copy the rest into the buffer since we have only a small 
     266                 :            :          * amount left */
     267                 :            :         goto start;
     268                 :            :         }
     269                 :            : 
     270                 :      20508 : static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
     271                 :            :         {
     272                 :            :         BIO *dbio;
     273                 :            :         BIO_F_BUFFER_CTX *ctx;
     274                 :      20508 :         long ret=1;
     275                 :            :         char *p1,*p2;
     276                 :            :         int r,i,*ip;
     277                 :            :         int ibs,obs;
     278                 :            : 
     279                 :      20508 :         ctx=(BIO_F_BUFFER_CTX *)b->ptr;
     280                 :            : 
     281   [ +  -  -  -  :      20508 :         switch (cmd)
          -  -  +  -  +  
                   -  + ]
     282                 :            :                 {
     283                 :            :         case BIO_CTRL_RESET:
     284                 :       2160 :                 ctx->ibuf_off=0;
     285                 :       2160 :                 ctx->ibuf_len=0;
     286                 :       2160 :                 ctx->obuf_off=0;
     287                 :       2160 :                 ctx->obuf_len=0;
     288         [ -  + ]:       2160 :                 if (b->next_bio == NULL) return(0);
     289                 :          0 :                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     290                 :          0 :                 break;
     291                 :            :         case BIO_CTRL_INFO:
     292                 :          0 :                 ret=(long)ctx->obuf_len;
     293                 :          0 :                 break;
     294                 :            :         case BIO_C_GET_BUFF_NUM_LINES:
     295                 :          0 :                 ret=0;
     296                 :          0 :                 p1=ctx->ibuf;
     297         [ #  # ]:          0 :                 for (i=0; i<ctx->ibuf_len; i++)
     298                 :            :                         {
     299         [ #  # ]:          0 :                         if (p1[ctx->ibuf_off + i] == '\n') ret++;
     300                 :            :                         }
     301                 :            :                 break;
     302                 :            :         case BIO_CTRL_WPENDING:
     303                 :          0 :                 ret=(long)ctx->obuf_len;
     304         [ #  # ]:          0 :                 if (ret == 0)
     305                 :            :                         {
     306         [ #  # ]:          0 :                         if (b->next_bio == NULL) return(0);
     307                 :          0 :                         ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     308                 :            :                         }
     309                 :            :                 break;
     310                 :            :         case BIO_CTRL_PENDING:
     311                 :          0 :                 ret=(long)ctx->ibuf_len;
     312         [ #  # ]:          0 :                 if (ret == 0)
     313                 :            :                         {
     314         [ #  # ]:          0 :                         if (b->next_bio == NULL) return(0);
     315                 :          0 :                         ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     316                 :            :                         }
     317                 :            :                 break;
     318                 :            :         case BIO_C_SET_BUFF_READ_DATA:
     319         [ #  # ]:          0 :                 if (num > ctx->ibuf_size)
     320                 :            :                         {
     321                 :          0 :                         p1=OPENSSL_malloc((int)num);
     322         [ #  # ]:          0 :                         if (p1 == NULL) goto malloc_error;
     323         [ #  # ]:          0 :                         if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf);
     324                 :          0 :                         ctx->ibuf=p1;
     325                 :            :                         }
     326                 :          0 :                 ctx->ibuf_off=0;
     327                 :          0 :                 ctx->ibuf_len=(int)num;
     328                 :          0 :                 memcpy(ctx->ibuf,ptr,(int)num);
     329                 :          0 :                 ret=1;
     330                 :          0 :                 break;
     331                 :            :         case BIO_C_SET_BUFF_SIZE:
     332         [ +  - ]:       2160 :                 if (ptr != NULL)
     333                 :            :                         {
     334                 :       2160 :                         ip=(int *)ptr;
     335         [ +  - ]:       2160 :                         if (*ip == 0)
     336                 :            :                                 {
     337                 :       2160 :                                 ibs=(int)num;
     338                 :       2160 :                                 obs=ctx->obuf_size;
     339                 :            :                                 }
     340                 :            :                         else /* if (*ip == 1) */
     341                 :            :                                 {
     342                 :          0 :                                 ibs=ctx->ibuf_size;
     343                 :          0 :                                 obs=(int)num;
     344                 :            :                                 }
     345                 :            :                         }
     346                 :            :                 else
     347                 :            :                         {
     348                 :          0 :                         ibs=(int)num;
     349                 :          0 :                         obs=(int)num;
     350                 :            :                         }
     351                 :       2160 :                 p1=ctx->ibuf;
     352                 :       2160 :                 p2=ctx->obuf;
     353 [ -  + ][ #  # ]:       2160 :                 if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size))
     354                 :            :                         {
     355                 :          0 :                         p1=(char *)OPENSSL_malloc((int)num);
     356         [ #  # ]:          0 :                         if (p1 == NULL) goto malloc_error;
     357                 :            :                         }
     358 [ -  + ][ #  # ]:       2160 :                 if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size))
     359                 :            :                         {
     360                 :          0 :                         p2=(char *)OPENSSL_malloc((int)num);
     361         [ #  # ]:          0 :                         if (p2 == NULL)
     362                 :            :                                 {
     363         [ #  # ]:          0 :                                 if (p1 != ctx->ibuf) OPENSSL_free(p1);
     364                 :            :                                 goto malloc_error;
     365                 :            :                                 }
     366                 :            :                         }
     367         [ -  + ]:       2160 :                 if (ctx->ibuf != p1)
     368                 :            :                         {
     369                 :          0 :                         OPENSSL_free(ctx->ibuf);
     370                 :          0 :                         ctx->ibuf=p1;
     371                 :          0 :                         ctx->ibuf_off=0;
     372                 :          0 :                         ctx->ibuf_len=0;
     373                 :          0 :                         ctx->ibuf_size=ibs;
     374                 :            :                         }
     375         [ -  + ]:       2160 :                 if (ctx->obuf != p2)
     376                 :            :                         {
     377                 :          0 :                         OPENSSL_free(ctx->obuf);
     378                 :          0 :                         ctx->obuf=p2;
     379                 :          0 :                         ctx->obuf_off=0;
     380                 :          0 :                         ctx->obuf_len=0;
     381                 :          0 :                         ctx->obuf_size=obs;
     382                 :            :                         }
     383                 :            :                 break;
     384                 :            :         case BIO_C_DO_STATE_MACHINE:
     385         [ #  # ]:          0 :                 if (b->next_bio == NULL) return(0);
     386                 :          0 :                 BIO_clear_retry_flags(b);
     387                 :          0 :                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     388                 :          0 :                 BIO_copy_next_retry(b);
     389                 :          0 :                 break;
     390                 :            : 
     391                 :            :         case BIO_CTRL_FLUSH:
     392         [ +  - ]:      11726 :                 if (b->next_bio == NULL) return(0);
     393         [ +  - ]:      11726 :                 if (ctx->obuf_len <= 0)
     394                 :            :                         {
     395                 :          0 :                         ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     396                 :          0 :                         break;
     397                 :            :                         }
     398                 :            : 
     399                 :            :                 for (;;)
     400                 :            :                         {
     401                 :      19239 :                         BIO_clear_retry_flags(b);
     402         [ +  + ]:      19239 :                         if (ctx->obuf_len > 0)
     403                 :            :                                 {
     404                 :      15939 :                                 r=BIO_write(b->next_bio,
     405                 :      15939 :                                         &(ctx->obuf[ctx->obuf_off]),
     406                 :            :                                         ctx->obuf_len);
     407                 :            : #if 0
     408                 :            : fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r);
     409                 :            : #endif
     410                 :      15939 :                                 BIO_copy_next_retry(b);
     411         [ +  + ]:      15939 :                                 if (r <= 0) return((long)r);
     412                 :       7513 :                                 ctx->obuf_off+=r;
     413                 :       7513 :                                 ctx->obuf_len-=r;
     414                 :            :                                 }
     415                 :            :                         else
     416                 :            :                                 {
     417                 :       3300 :                                 ctx->obuf_len=0;
     418                 :       3300 :                                 ctx->obuf_off=0;
     419                 :       3300 :                                 ret=1;
     420                 :            :                                 break;
     421                 :            :                                 }
     422                 :       7513 :                         }
     423                 :       3300 :                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     424                 :       3300 :                 break;
     425                 :            :         case BIO_CTRL_DUP:
     426                 :          0 :                 dbio=(BIO *)ptr;
     427   [ #  #  #  # ]:          0 :                 if (    !BIO_set_read_buffer_size(dbio,ctx->ibuf_size) ||
     428                 :          0 :                         !BIO_set_write_buffer_size(dbio,ctx->obuf_size))
     429                 :            :                         ret=0;
     430                 :            :                 break;
     431                 :            :         default:
     432         [ +  - ]:       4462 :                 if (b->next_bio == NULL) return(0);
     433                 :       4462 :                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
     434                 :       4462 :                 break;
     435                 :            :                 }
     436                 :       9922 :         return(ret);
     437                 :            : malloc_error:
     438                 :          0 :         BIOerr(BIO_F_BUFFER_CTRL,ERR_R_MALLOC_FAILURE);
     439                 :          0 :         return(0);
     440                 :            :         }
     441                 :            : 
     442                 :          0 : static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
     443                 :            :         {
     444                 :          0 :         long ret=1;
     445                 :            : 
     446         [ #  # ]:          0 :         if (b->next_bio == NULL) return(0);
     447                 :            :         switch (cmd)
     448                 :            :                 {
     449                 :            :         default:
     450                 :          0 :                 ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
     451                 :            :                 break;
     452                 :            :                 }
     453                 :          0 :         return(ret);
     454                 :            :         }
     455                 :            : 
     456                 :          0 : static int buffer_gets(BIO *b, char *buf, int size)
     457                 :            :         {
     458                 :            :         BIO_F_BUFFER_CTX *ctx;
     459                 :          0 :         int num=0,i,flag;
     460                 :            :         char *p;
     461                 :            : 
     462                 :          0 :         ctx=(BIO_F_BUFFER_CTX *)b->ptr;
     463                 :          0 :         size--; /* reserve space for a '\0' */
     464                 :          0 :         BIO_clear_retry_flags(b);
     465                 :            : 
     466                 :            :         for (;;)
     467                 :            :                 {
     468         [ #  # ]:          0 :                 if (ctx->ibuf_len > 0)
     469                 :            :                         {
     470                 :          0 :                         p= &(ctx->ibuf[ctx->ibuf_off]);
     471                 :          0 :                         flag=0;
     472 [ #  # ][ #  # ]:          0 :                         for (i=0; (i<ctx->ibuf_len) && (i<size); i++)
     473                 :            :                                 {
     474                 :          0 :                                 *(buf++)=p[i];
     475         [ #  # ]:          0 :                                 if (p[i] == '\n')
     476                 :            :                                         {
     477                 :          0 :                                         flag=1;
     478                 :          0 :                                         i++;
     479                 :          0 :                                         break;
     480                 :            :                                         }
     481                 :            :                                 }
     482                 :          0 :                         num+=i;
     483                 :          0 :                         size-=i;
     484                 :          0 :                         ctx->ibuf_len-=i;
     485                 :          0 :                         ctx->ibuf_off+=i;
     486         [ #  # ]:          0 :                         if (flag || size == 0)
     487                 :            :                                 {
     488                 :          0 :                                 *buf='\0';
     489                 :          0 :                                 return(num);
     490                 :            :                                 }
     491                 :            :                         }
     492                 :            :                 else    /* read another chunk */
     493                 :            :                         {
     494                 :          0 :                         i=BIO_read(b->next_bio,ctx->ibuf,ctx->ibuf_size);
     495         [ #  # ]:          0 :                         if (i <= 0)
     496                 :            :                                 {
     497                 :          0 :                                 BIO_copy_next_retry(b);
     498                 :          0 :                                 *buf='\0';
     499 [ #  # ][ #  # ]:          0 :                                 if (i < 0) return((num > 0)?num:i);
     500         [ #  # ]:          0 :                                 if (i == 0) return(num);
     501                 :            :                                 }
     502                 :          0 :                         ctx->ibuf_len=i;
     503                 :          0 :                         ctx->ibuf_off=0;
     504                 :            :                         }
     505                 :            :                 }
     506                 :            :         }
     507                 :            : 
     508                 :          0 : static int buffer_puts(BIO *b, const char *str)
     509                 :            :         {
     510                 :          0 :         return(buffer_write(b,str,strlen(str)));
     511                 :            :         }
     512                 :            : 

Generated by: LCOV version 1.9