- {
- BIO *dbio;
- BIO_F_BUFFER_CTX *ctx;
- long ret=1;
- char *p1,*p2;
- int r,i,*ip;
- int ibs,obs;
-
- ctx=(BIO_F_BUFFER_CTX *)b->ptr;
-
- switch (cmd)
- {
- case BIO_CTRL_RESET:
- ctx->ibuf_off=0;
- ctx->ibuf_len=0;
- ctx->obuf_off=0;
- ctx->obuf_len=0;
- if (b->next_bio == NULL) return(0);
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- break;
- case BIO_CTRL_INFO:
- ret=(long)ctx->obuf_len;
- break;
- case BIO_C_GET_BUFF_NUM_LINES:
- ret=0;
- p1=ctx->ibuf;
- for (i=ctx->ibuf_off; i<ctx->ibuf_len; i++)
- {
- if (p1[i] == '\n') ret++;
- }
- break;
- case BIO_CTRL_WPENDING:
- ret=(long)ctx->obuf_len;
- if (ret == 0)
- {
- if (b->next_bio == NULL) return(0);
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- }
- break;
- case BIO_CTRL_PENDING:
- ret=(long)ctx->ibuf_len;
- if (ret == 0)
- {
- if (b->next_bio == NULL) return(0);
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- }
- break;
- case BIO_C_SET_BUFF_READ_DATA:
- if (num > ctx->ibuf_size)
- {
- p1=OPENSSL_malloc((int)num);
- if (p1 == NULL) goto malloc_error;
- if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf);
- ctx->ibuf=p1;
- }
- ctx->ibuf_off=0;
- ctx->ibuf_len=(int)num;
- memcpy(ctx->ibuf,ptr,(int)num);
- ret=1;
- break;
- case BIO_C_SET_BUFF_SIZE:
- if (ptr != NULL)
- {
- ip=(int *)ptr;
- if (*ip == 0)
- {
- ibs=(int)num;
- obs=ctx->obuf_size;
- }
- else /* if (*ip == 1) */
- {
- ibs=ctx->ibuf_size;
- obs=(int)num;
- }
- }
- else
- {
- ibs=(int)num;
- obs=(int)num;
- }
- p1=ctx->ibuf;
- p2=ctx->obuf;
- if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size))
- {
- p1=(char *)OPENSSL_malloc((int)num);
- if (p1 == NULL) goto malloc_error;
- }
- if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size))
- {
- p2=(char *)OPENSSL_malloc((int)num);
- if (p2 == NULL)
- {
- if (p1 != ctx->ibuf) OPENSSL_free(p1);
- goto malloc_error;
- }
- }
- if (ctx->ibuf != p1)
- {
- OPENSSL_free(ctx->ibuf);
- ctx->ibuf=p1;
- ctx->ibuf_off=0;
- ctx->ibuf_len=0;
- ctx->ibuf_size=ibs;
- }
- if (ctx->obuf != p2)
- {
- OPENSSL_free(ctx->obuf);
- ctx->obuf=p2;
- ctx->obuf_off=0;
- ctx->obuf_len=0;
- ctx->obuf_size=obs;
- }
- break;
- case BIO_C_DO_STATE_MACHINE:
- if (b->next_bio == NULL) return(0);
- BIO_clear_retry_flags(b);
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- BIO_copy_next_retry(b);
- break;
-
- case BIO_CTRL_FLUSH:
- if (b->next_bio == NULL) return(0);
- if (ctx->obuf_len <= 0)
- {
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- break;
- }
-
- for (;;)
- {
- BIO_clear_retry_flags(b);
- if (ctx->obuf_len > ctx->obuf_off)
- {
- r=BIO_write(b->next_bio,
- &(ctx->obuf[ctx->obuf_off]),
- ctx->obuf_len-ctx->obuf_off);
-#if 0
-fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r);
-#endif
- BIO_copy_next_retry(b);
- if (r <= 0) return((long)r);
- ctx->obuf_off+=r;
- }
- else
- {
- ctx->obuf_len=0;
- ctx->obuf_off=0;
- ret=1;
- break;
- }
- }
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- break;
- case BIO_CTRL_DUP:
- dbio=(BIO *)ptr;
- if ( !BIO_set_read_buffer_size(dbio,ctx->ibuf_size) ||
- !BIO_set_write_buffer_size(dbio,ctx->obuf_size))
- ret=0;
- break;
- default:
- if (b->next_bio == NULL) return(0);
- ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
- break;
- }
- return(ret);
-malloc_error:
- BIOerr(BIO_F_BUFFER_CTRL,ERR_R_MALLOC_FAILURE);
- return(0);
- }
+{
+ BIO *dbio;
+ BIO_F_BUFFER_CTX *ctx;
+ long ret = 1;
+ char *p1, *p2;
+ int r, i, *ip;
+ int ibs, obs;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->obuf_len;
+ break;
+ case BIO_C_GET_BUFF_NUM_LINES:
+ ret = 0;
+ p1 = ctx->ibuf;
+ for (i = 0; i < ctx->ibuf_len; i++) {
+ if (p1[ctx->ibuf_off + i] == '\n')
+ ret++;
+ }
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = (long)ctx->obuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)ctx->ibuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_C_SET_BUFF_READ_DATA:
+ if (num > ctx->ibuf_size) {
+ p1 = OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ }
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = (int)num;
+ memcpy(ctx->ibuf, ptr, (int)num);
+ ret = 1;
+ break;
+ case BIO_C_SET_BUFF_SIZE:
+ if (ptr != NULL) {
+ ip = (int *)ptr;
+ if (*ip == 0) {
+ ibs = (int)num;
+ obs = ctx->obuf_size;
+ } else { /* if (*ip == 1) */
+
+ ibs = ctx->ibuf_size;
+ obs = (int)num;
+ }
+ } else {
+ ibs = (int)num;
+ obs = (int)num;
+ }
+ p1 = ctx->ibuf;
+ p2 = ctx->obuf;
+ if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
+ p1 = OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ }
+ if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
+ p2 = OPENSSL_malloc((int)num);
+ if (p2 == NULL) {
+ if (p1 != ctx->ibuf)
+ OPENSSL_free(p1);
+ goto malloc_error;
+ }
+ }
+ if (ctx->ibuf != p1) {
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->ibuf_size = ibs;
+ }
+ if (ctx->obuf != p2) {
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = p2;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ ctx->obuf_size = obs;
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ if (b->next_bio == NULL)
+ return (0);
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (b->next_bio == NULL)
+ return (0);
+ if (ctx->obuf_len <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+
+ for (;;) {
+ BIO_clear_retry_flags(b);
+ if (ctx->obuf_len > 0) {
+ r = BIO_write(b->next_bio,
+ &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
+ BIO_copy_next_retry(b);
+ if (r <= 0)
+ return ((long)r);
+ ctx->obuf_off += r;
+ ctx->obuf_len -= r;
+ } else {
+ ctx->obuf_len = 0;
+ ctx->obuf_off = 0;
+ break;
+ }
+ }
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
+ !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ ret = 0;
+ break;
+ default:
+ if (b->next_bio == NULL)
+ return (0);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+ malloc_error:
+ BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ return (0);
+}