aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-04-12 12:27:31 -0300
committerdequis <dx@dxzone.com.ar>2015-04-12 12:27:31 -0300
commit951aefdab1f09f35f2deef8c490b590313c94192 (patch)
treea1cd6d8934c383f75a4e1b64e3c93bf5d7ef96fa
parent5fbf8152c7e760ca2c4140f54ba56c62bcd2571b (diff)
msn/gw.c: ensure that the im_connection still exists in callbacks
-rw-r--r--protocols/msn/gw.c45
-rw-r--r--protocols/msn/msn.h6
-rw-r--r--protocols/msn/ns.c9
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);