diff options
author | dequis <dx@dxzone.com.ar> | 2015-04-12 12:27:31 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-04-12 12:27:31 -0300 |
commit | 951aefdab1f09f35f2deef8c490b590313c94192 (patch) | |
tree | a1cd6d8934c383f75a4e1b64e3c93bf5d7ef96fa | |
parent | 5fbf8152c7e760ca2c4140f54ba56c62bcd2571b (diff) |
msn/gw.c: ensure that the im_connection still exists in callbacks
-rw-r--r-- | protocols/msn/gw.c | 45 | ||||
-rw-r--r-- | protocols/msn/msn.h | 6 | ||||
-rw-r--r-- | protocols/msn/ns.c | 9 |
3 files changed, 35 insertions, 25 deletions
diff --git a/protocols/msn/gw.c b/protocols/msn/gw.c index eecbdb3b..60514139 100644 --- a/protocols/msn/gw.c +++ b/protocols/msn/gw.c @@ -14,14 +14,15 @@ static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond); -struct msn_gw *msn_gw_new(struct msn_data *md) +struct msn_gw *msn_gw_new(struct im_connection *ic) { struct msn_gw *gw = g_new0(struct msn_gw, 1); gw->last_host = g_strdup(GATEWAY_HOST); gw->port = GATEWAY_PORT; gw->ssl = (GATEWAY_PORT == 443); gw->poll_timeout = -1; - gw->data = md; + gw->ic = ic; + gw->md = ic->proto_data; gw->in = g_byte_array_new(); gw->out = g_byte_array_new(); return gw; @@ -39,6 +40,16 @@ void msn_gw_free(struct msn_gw *gw) g_free(gw); } +static struct msn_gw *msn_gw_from_ic(struct im_connection *ic) +{ + if (g_slist_find(msn_connections, ic) == NULL) { + return NULL; + } else { + struct msn_data *md = ic->proto_data; + return md->gw; + } +} + static gboolean msn_gw_parse_session_header(struct msn_gw *gw, char *value) { int i; @@ -65,32 +76,29 @@ static gboolean msn_gw_parse_session_header(struct msn_gw *gw, char *value) void msn_gw_callback(struct http_request *req) { + struct msn_gw *gw; char *value; - struct msn_gw *gw = req->data; - - gw->waiting = FALSE; - gw->polling = FALSE; - if (!gw->open) { - /* the user tried to logout while the request was pending - * see msn_ns_close() */ - msn_gw_free(gw); + if (!(gw = msn_gw_from_ic(req->data))) { return; } + gw->waiting = FALSE; + gw->polling = FALSE; + if (getenv("BITLBEE_DEBUG")) { fprintf(stderr, "\n\x1b[90mHTTP:%s\n", req->reply_body); fprintf(stderr, "\n\x1b[97m\n"); } if (req->status_code != 200) { - gw->callback(gw->data, -1, B_EV_IO_READ); + gw->callback(gw->md, -1, B_EV_IO_READ); return; } if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Messenger", 0))) { if (!msn_gw_parse_session_header(gw, value)) { - gw->callback(gw->data, -1, B_EV_IO_READ); + gw->callback(gw->md, -1, B_EV_IO_READ); g_free(value); return; } @@ -104,13 +112,13 @@ void msn_gw_callback(struct http_request *req) if (req->body_size) { g_byte_array_append(gw->in, (const guint8 *) req->reply_body, req->body_size); - gw->callback(gw->data, -1, B_EV_IO_READ); + gw->callback(gw->md, -1, B_EV_IO_READ); } if (gw->poll_timeout != -1) { b_event_remove(gw->poll_timeout); } - gw->poll_timeout = b_timeout_add(500, msn_gw_poll_timeout, gw); + gw->poll_timeout = b_timeout_add(500, msn_gw_poll_timeout, gw->ic); } @@ -135,7 +143,7 @@ void msn_gw_dorequest(struct msn_gw *gw, char *args) request = g_strdup_printf(REQUEST_TEMPLATE, gw->session_id ? : "", args ? : "", gw->last_host, bodylen, body ? : ""); - http_dorequest(gw->last_host, gw->port, gw->ssl, request, msn_gw_callback, gw); + http_dorequest(gw->last_host, gw->port, gw->ssl, request, msn_gw_callback, gw->ic); gw->open = TRUE; gw->waiting = TRUE; @@ -150,7 +158,12 @@ void msn_gw_open(struct msn_gw *gw) static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond) { - struct msn_gw *gw = data; + struct msn_gw *gw; + + if (!(gw = msn_gw_from_ic(data))) { + return FALSE; + } + gw->poll_timeout = -1; if (!gw->waiting) { msn_gw_dorequest(gw, NULL); diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index ba7e4247..75dc2b7e 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -136,7 +136,9 @@ struct msn_gw { int poll_timeout; b_event_handler callback; - gpointer data; + + struct im_connection *ic; + struct msn_data *md; gboolean open; gboolean waiting; @@ -264,7 +266,7 @@ const struct msn_away_state *msn_away_state_by_name(char *name); const struct msn_status_code *msn_status_by_number(int number); /* gw.c */ -struct msn_gw *msn_gw_new(struct msn_data *md); +struct msn_gw *msn_gw_new(struct im_connection *ic); void msn_gw_free(struct msn_gw *gw); void msn_gw_open(struct msn_gw *gw); ssize_t msn_gw_read(struct msn_gw *gw, char **buf); diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 284a3c37..f4ee0806 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -89,7 +89,7 @@ gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port) } if (md->is_http) { - md->gw = msn_gw_new(md); + md->gw = msn_gw_new(ic); md->gw->callback = msn_ns_callback; msn_ns_connected(md, -1, B_EV_IO_READ); } else { @@ -147,12 +147,7 @@ static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition c void msn_ns_close(struct msn_data *md) { if (md->gw) { - if (md->gw->waiting) { - /* mark it as closed, let the request callback clean it */ - md->gw->open = FALSE; - } else { - msn_gw_free(md->gw); - } + msn_gw_free(md->gw); } if (md->fd >= 0) { closesocket(md->fd); |