int BIO_gets(BIO *b, char *in, int inl) { int i; long (*cb)(BIO *, int, const char *, int, long, long); if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { BIOerror(BIO_R_UNSUPPORTED_METHOD); return (-2); } cb = b->callback; if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0)) return (i); if (!b->init) { BIOerror(BIO_R_UNINITIALIZED); return (-2); } i = b->method->bgets(b, in, inl); if (cb != NULL) i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i); return (i); }
int BIO_puts(BIO *b, const char *in) { int i; long (*cb)(BIO *, int, const char *, int, long, long); if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { BIOerror(BIO_R_UNSUPPORTED_METHOD); return (-2); } cb = b->callback; if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0)) return (i); if (!b->init) { BIOerror(BIO_R_UNINITIALIZED); return (-2); } 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); return (i); }
int BIO_write(BIO *b, const void *in, int inl) { int i; long (*cb)(BIO *, int, const char *, int, long, long); if (b == NULL) return (0); cb = b->callback; if ((b->method == NULL) || (b->method->bwrite == NULL)) { BIOerror(BIO_R_UNSUPPORTED_METHOD); return (-2); } if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) return (i); if (!b->init) { BIOerror(BIO_R_UNINITIALIZED); return (-2); } i = b->method->bwrite(b, in, inl); if (i > 0) b->num_write += (unsigned long)i; if (cb != NULL) i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 0L, (long)i); return (i); }
int BIO_read(BIO *b, void *out, int outl) { int i; long (*cb)(BIO *, int, const char *, int, long, long); if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { BIOerror(BIO_R_UNSUPPORTED_METHOD); return (-2); } cb = b->callback; if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0)) return (i); if (!b->init) { BIOerror(BIO_R_UNINITIALIZED); return (-2); } i = b->method->bread(b, out, outl); if (i > 0) b->num_read += (unsigned long)i; if (cb != NULL) i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 0L, (long)i); return (i); }
static int mem_write(BIO *b, const char *in, int inl) { int ret = -1; int blen; BUF_MEM *bm; bm = (BUF_MEM *)b->ptr; if (in == NULL) { BIOerror(BIO_R_NULL_PARAMETER); goto end; } if (b->flags & BIO_FLAGS_MEM_RDONLY) { BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO); goto end; } BIO_clear_retry_flags(b); blen = bm->length; if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl)) goto end; memcpy(&(bm->data[blen]), in, inl); ret = inl; end: 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)) { BIOerror(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); }
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) { long ret; long (*cb)(BIO *, int, const char *, int, long, long); if (b == NULL) return (0); if ((b->method == NULL) || (b->method->ctrl == NULL)) { BIOerror(BIO_R_UNSUPPORTED_METHOD); return (-2); } cb = b->callback; if ((cb != NULL) && ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0)) return (ret); ret = b->method->ctrl(b, cmd, larg, parg); if (cb != NULL) ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret); return (ret); }
BIO * BIO_new(BIO_METHOD *method) { BIO *ret = NULL; ret = malloc(sizeof(BIO)); if (ret == NULL) { BIOerror(ERR_R_MALLOC_FAILURE); return (NULL); } if (!BIO_set(ret, method)) { free(ret); ret = NULL; } return (ret); }
int BIO_sock_init(void) { /* * WSAStartup loads the winsock .dll and initializes the networking * stack on Windows, or simply increases the reference count. */ static struct WSAData wsa_state = {0}; WORD version_requested = MAKEWORD(2, 2); static int wsa_init_done = 0; if (!wsa_init_done) { if (WSAStartup(version_requested, &wsa_state) != 0) { int err = WSAGetLastError(); SYSerror(err); BIOerror(BIO_R_WSASTARTUP); return (-1); } wsa_init_done = 1; } return (1); }
BIO * BIO_new_mem_buf(const void *buf, int len) { BIO *ret; BUF_MEM *b; size_t sz; if (!buf) { BIOerror(BIO_R_NULL_PARAMETER); return NULL; } sz = (len < 0) ? strlen(buf) : (size_t)len; if (!(ret = BIO_new(BIO_s_mem()))) return NULL; b = (BUF_MEM *)ret->ptr; b->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */ b->length = sz; b->max = sz; ret->flags |= BIO_FLAGS_MEM_RDONLY; /* Since this is static data retrying wont help */ ret->num = 0; return ret; }
static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) { 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 = malloc(num); if (p1 == NULL) goto malloc_error; free(ctx->ibuf); ctx->ibuf = p1; } ctx->ibuf_off = 0; ctx->ibuf_len = (int)num; memcpy(ctx->ibuf, ptr, 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 = malloc(num); if (p1 == NULL) goto malloc_error; } if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { p2 = malloc(num); if (p2 == NULL) { if (p1 != ctx->ibuf) free(p1); goto malloc_error; } } if (ctx->ibuf != p1) { free(ctx->ibuf); ctx->ibuf = p1; ctx->ibuf_off = 0; ctx->ibuf_len = 0; ctx->ibuf_size = ibs; } if (ctx->obuf != p2) { 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: BIOerror(ERR_R_MALLOC_FAILURE); return (0); }
static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO *dbio; BIO_LINEBUFFER_CTX *ctx; long ret = 1; char *p; int r; int obs; ctx = (BIO_LINEBUFFER_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: 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_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_C_SET_BUFF_SIZE: obs = (int)num; p = ctx->obuf; if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { p = malloc(num); if (p == NULL) goto malloc_error; } if (ctx->obuf != p) { if (ctx->obuf_len > obs) { ctx->obuf_len = obs; } memcpy(p, ctx->obuf, ctx->obuf_len); free(ctx->obuf); ctx->obuf = p; 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_len); BIO_copy_next_retry(b); if (r <= 0) return ((long)r); if (r < ctx->obuf_len) memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r); ctx->obuf_len -= r; } else { ctx->obuf_len = 0; ret = 1; break; } } ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; if (!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: BIOerror(ERR_R_MALLOC_FAILURE); return (0); }