void replace_eventcb(struct bufferevent * buffev, bufferevent_event_cb eventcb) { #if LIBEVENT_VERSION_NUMBER >= 0x02010100 bufferevent_data_cb readcb, writecb; void * arg; bufferevent_getcb(buffev, &readcb, &writecb, NULL, &arg); bufferevent_setcb(buffev, readcb, writecb, eventcb, arg); #else buffev->errorcb = eventcb; #endif }
static int imap_starttls(struct imap_context *ctx, struct imap_request *req, void *priv) { struct bufferevent *bev = ctx->client_bev; struct evbuffer *output = bufferevent_get_output(bev); SSL *ssl_client_ctx = SSL_new(ctx->driver->ssl_ctx); bufferevent_data_cb readcb, writecb; bufferevent_event_cb eventcb; void *orig_ctx; if (ctx->state & IMAP_TLS) { evbuffer_add_printf(output, "%s BAD TLS layer already in place" CRLF, req->tag.bv_val); return IMAP_OK; } /* retrieve the callbacks to apply them again on the filtering bev */ bufferevent_getcb(bev, &readcb, &writecb, &eventcb, &orig_ctx); evbuffer_add_printf(output, "%s OK Begin TLS negotiation now" CRLF, req->tag.bv_val); bev = bufferevent_openssl_filter_new(ctx->driver->base, bev, ssl_client_ctx, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); if (!bev) { return IMAP_SHUTDOWN; } bufferevent_setcb(bev, readcb, writecb, eventcb, orig_ctx); bufferevent_enable(bev, EV_READ|EV_WRITE); ctx->client_bev = bev; ctx->state |= IMAP_TLS; return IMAP_OK; }