Revision a8c2b9a0511a8917d2466c48e33f2c7db96065c8
nosnilmot at pidgin.im
nosnilmot at pidgin.im
Wed Apr 11 01:22:44 EDT 2007
o -----------------------------------------------------------------
| Revision: a8c2b9a0511a8917d2466c48e33f2c7db96065c8
| Ancestor: d35d1a34b828fb7a08b7eb8bcb4ab333d7e640cc
| Author: nosnilmot
| Date: 2005-01-07T02:48:07
| Branch: im.pidgin.gaim.oldstatus
|
| Modified files:
| ChangeLog src/protocols/msn/cmdproc.c
| src/protocols/msn/cmdproc.h src/protocols/msn/error.h
| src/protocols/msn/httpconn.c src/protocols/msn/httpconn.h
| src/protocols/msn/msg.c src/protocols/msn/msn.c
| src/protocols/msn/msn.h src/protocols/msn/nexus.c
| src/protocols/msn/notification.c
| src/protocols/msn/notification.h
| src/protocols/msn/servconn.c src/protocols/msn/servconn.h
| src/protocols/msn/session.c src/protocols/msn/session.h
| src/protocols/msn/slp.h src/protocols/msn/slpcall.c
| src/protocols/msn/slplink.c src/protocols/msn/state.c
| src/protocols/msn/switchboard.c
| src/protocols/msn/switchboard.h
| src/protocols/msn/transaction.c
|
| ChangeLog:
|
| [gaim-migrate @ 11768]
| Patch 1093958 from Felipe Contreras. It fixes stuff.
|
| I also made some tweaks to make valgrind a bit happier.
| ============================================================
| --- ChangeLog b712c8d8958c929a2e698eff8e307b36b5f6971a
| +++ ChangeLog 44072951e090a6f76b484a890554456061101115
| @@ -7,6 +7,7 @@ version 1.1.2:
| * Fix a crash inviting MSN user to a chat when they're already there
| * AIM SecurID login support
| * Fix configuration of Jabber chat rooms on some servers
| + * More MSN bug fixes (Felipe Contreras)
|
| version 1.1.1 (12/28/2004):
| * Allow SILC authentication via public key if your key is password
| ============================================================
| --- src/protocols/msn/cmdproc.c 7150f585520ede58759991963ef12c4ea6c7f48c
| +++ src/protocols/msn/cmdproc.c 25e666a31f262345923a562e5eeb61a580824e3b
| @@ -43,15 +43,13 @@ msn_cmdproc_destroy(MsnCmdProc *cmdproc)
| {
| MsnTransaction *trans;
|
| - if (cmdproc->last_trans != NULL)
| - g_free(cmdproc->last_trans);
| -
| while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL)
| msn_transaction_destroy(trans);
|
| g_queue_free(cmdproc->txqueue);
|
| msn_history_destroy(cmdproc->history);
| + g_free(cmdproc);
| }
|
| void
| @@ -59,11 +57,8 @@ msn_cmdproc_process_queue(MsnCmdProc *cm
| {
| MsnTransaction *trans;
|
| - while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL &&
| - cmdproc->error == 0)
| - {
| + while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL)
| msn_cmdproc_send_trans(cmdproc, trans);
| - }
| }
|
| void
| @@ -109,19 +104,17 @@ msn_cmdproc_send_trans(MsnCmdProc *cmdpr
| size_t len;
|
| g_return_if_fail(cmdproc != NULL);
| - g_return_if_fail(cmdproc->ready);
| g_return_if_fail(trans != NULL);
|
| servconn = cmdproc->servconn;
| +
| + if (!servconn->connected)
| + return;
| +
| msn_history_add(cmdproc->history, trans);
|
| data = msn_transaction_to_string(trans);
|
| - if (cmdproc->last_trans != NULL)
| - g_free(cmdproc->last_trans);
| -
| - cmdproc->last_trans = g_strdup(data);
| -
| len = strlen(data);
|
| show_debug_cmd(cmdproc, FALSE, data);
| @@ -153,11 +146,13 @@ msn_cmdproc_send_quick(MsnCmdProc *cmdpr
| size_t len;
|
| g_return_if_fail(cmdproc != NULL);
| - g_return_if_fail(cmdproc->ready);
| g_return_if_fail(command != NULL);
|
| servconn = cmdproc->servconn;
|
| + if (!servconn->connected)
| + return;
| +
| if (format != NULL)
| {
| va_start(arg, format);
| @@ -189,9 +184,11 @@ msn_cmdproc_send(MsnCmdProc *cmdproc, co
| va_list arg;
|
| g_return_if_fail(cmdproc != NULL);
| - g_return_if_fail(cmdproc->ready);
| g_return_if_fail(command != NULL);
|
| + if (!cmdproc->servconn->connected)
| + return;
| +
| trans = g_new0(MsnTransaction, 1);
|
| trans->command = g_strdup(command);
| @@ -317,19 +314,8 @@ msn_cmdproc_process_cmd(MsnCmdProc *cmdp
| cmd->command);
| }
|
| -#if 1
| - /* TODO this is really ugly */
| - /* Since commands have not stored payload and we need it for pendent
| - * commands at the time we process again the same command we will try
| - * to read again the payload of payload_len size but we will actually
| - * read sometime else, and reading from server synchronization goes to
| - * hell. */
| - /* Now we store the payload in the command when we queue them :D */
| -
| if (trans != NULL && trans->pendent_cmd != NULL)
| - if (cmdproc->ready)
| - msn_transaction_unqueue_cmd(trans, cmdproc);
| -#endif
| + msn_transaction_unqueue_cmd(trans, cmdproc);
| }
|
| void
| @@ -344,32 +330,3 @@ msn_cmdproc_process_cmd_text(MsnCmdProc
|
| msn_cmdproc_process_cmd(cmdproc, cmdproc->last_cmd);
| }
| -
| -void
| -msn_cmdproc_show_error(MsnCmdProc *cmdproc, int error)
| -{
| - GaimConnection *gc =
| - gaim_account_get_connection(cmdproc->session->account);
| -
| - char *tmp;
| -
| - tmp = NULL;
| -
| - switch (error)
| - {
| - case MSN_ERROR_MISC:
| - tmp = _("Miscellaneous error"); break;
| - case MSN_ERROR_SIGNOTHER:
| - gc->wants_to_die = TRUE;
| - tmp = _("You have signed on from another location."); break;
| - case MSN_ERROR_SERVDOWN:
| - tmp = _("The MSN servers are going down temporarily."); break;
| - default:
| - break;
| - }
| -
| - if (tmp != NULL)
| - {
| - gaim_connection_error(gc, tmp);
| - }
| -}
| ============================================================
| --- src/protocols/msn/cmdproc.h a5f9b743ba99626816fe01d153ec8d92f8b5ff99
| +++ src/protocols/msn/cmdproc.h 18c5f6b6a08237483746bcab9612d911c9a73dde
| @@ -33,11 +33,6 @@ typedef struct _MsnCmdProc MsnCmdProc;
| #include "table.h"
| #include "history.h"
|
| -#if 0
| -typedef void (*MsnPayloadCb)(MsnCmdProc *cmdproc, char *payload,
| - size_t len);
| -#endif
| -
| struct _MsnCmdProc
| {
| MsnSession *session;
| @@ -45,14 +40,9 @@ struct _MsnCmdProc
|
| GQueue *txqueue;
|
| - gboolean ready;
| - MsnErrorType error;
| -
| MsnCommand *last_cmd;
| - char *last_trans;
|
| MsnTable *cbs_table;
| - /* MsnPayloadCb payload_cb; */
|
| MsnHistory *history;
|
| @@ -81,6 +71,4 @@ void msn_cmdproc_disconnect(MsnCmdProc *
|
| void msn_cmdproc_disconnect(MsnCmdProc *cmdproc);
|
| -void msn_cmdproc_show_error(MsnCmdProc *cmdproc, int error);
| -
| #endif /* _MSN_CMDPROC_H_ */
| ============================================================
| --- src/protocols/msn/error.h ca6833b624efb539ff31a1e450ae8f72fdb88eef
| +++ src/protocols/msn/error.h 51ba95e1afea1b124f47c0661a7dce52880ed950
| @@ -24,18 +24,6 @@
| #ifndef _MSN_ERROR_H_
| #define _MSN_ERROR_H_
|
| -typedef enum
| -{
| - MSN_ERROR_NONE,
| - MSN_ERROR_MISC,
| - MSN_ERROR_CONNECT,
| - MSN_ERROR_WRITE,
| - MSN_ERROR_READ,
| - MSN_ERROR_SIGNOTHER,
| - MSN_ERROR_SERVDOWN
| -
| -} MsnErrorType;
| -
| #include "session.h"
|
| /**
| ============================================================
| --- src/protocols/msn/httpconn.c 312604acf4f06a425d1674d9fd16c6ec88b37721
| +++ src/protocols/msn/httpconn.c 25f4a0215f77010533e964644ea4e91cf7d92b67
| @@ -28,7 +28,7 @@ typedef struct
| typedef struct
| {
| MsnHttpConn *httpconn;
| - char *buffer;
| + char *data;
| size_t size;
|
| } MsnHttpQueueData;
| @@ -48,6 +48,8 @@ msn_httpconn_new(MsnServConn *servconn)
|
| httpconn = g_new0(MsnHttpConn, 1);
|
| + gaim_debug_info("msn", "new httpconn (%p)\n", httpconn);
| +
| /* TODO: Remove this */
| httpconn->session = servconn->session;
|
| @@ -61,96 +63,64 @@ msn_httpconn_destroy(MsnHttpConn *httpco
| {
| g_return_if_fail(httpconn != NULL);
|
| + gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn);
| +
| if (httpconn->connected)
| msn_httpconn_disconnect(httpconn);
|
| - if (httpconn->host != NULL)
| - g_free(httpconn->host);
| -
| g_free(httpconn);
| }
|
| -static void
| -show_error(MsnHttpConn *httpconn)
| +static ssize_t
| +write_raw(MsnHttpConn *httpconn, const char *header,
| + const char *body, size_t body_len)
| {
| - GaimConnection *gc;
| - char *tmp;
| - char *cmd;
| + char *buf;
| + size_t buf_len;
|
| - const char *names[] = { "Notification", "Switchboard" };
| - const char *name;
| + ssize_t s;
| + ssize_t res; /* result of the write operation */
|
| - gc = gaim_account_get_connection(httpconn->servconn->session->account);
| - name = names[httpconn->servconn->type];
| +#ifdef MSN_DEBUG_HTTP
| + gaim_debug_misc("msn", "Writing HTTP (header): {%s}\n", header);
| +#endif
|
| - switch (httpconn->servconn->cmdproc->error)
| - {
| - case MSN_ERROR_CONNECT:
| - tmp = g_strdup_printf(_("Unable to connect to %s server"),
| - name);
| - break;
| - case MSN_ERROR_WRITE:
| - tmp = g_strdup_printf(_("Error writing to %s server"), name);
| - break;
| - case MSN_ERROR_READ:
| - cmd = httpconn->servconn->cmdproc->last_trans;
| - tmp = g_strdup_printf(_("Error reading from %s server"), name);
| - gaim_debug_info("msn", "Last command was: %s\n", cmd);
| - break;
| - default:
| - tmp = g_strdup_printf(_("Unknown error from %s server"), name);
| - break;
| - }
| + buf = g_strdup_printf("%s\r\n", header);
| + buf_len = strlen(buf);
|
| - if (httpconn->servconn->type == MSN_SERVER_NS)
| + if (body != NULL)
| {
| - gaim_connection_error(gc, tmp);
| + buf = g_realloc(buf, buf_len + body_len);
| + memcpy(buf + buf_len, body, body_len);
| + buf_len += body_len;
| }
| - else
| - {
| - MsnSwitchBoard *swboard;
| - swboard = httpconn->servconn->cmdproc->data;
| - swboard->error = MSN_SB_ERROR_CONNECTION;
| - }
|
| - g_free(tmp);
| -}
| -
| -static ssize_t
| -write_raw(MsnHttpConn *httpconn, const void *buffer, size_t len)
| -{
| - ssize_t s;
| - ssize_t res; /* result of the write operation */
| -
| -#ifdef MSN_DEBUG_HTTP
| - gaim_debug_misc("msn", "Writing HTTP: {%s}\n", buffer);
| -#endif
| -
| s = 0;
|
| do
| {
| - res = write(httpconn->fd, buffer, len);
| + res = write(httpconn->fd, buf, buf_len);
| if (res >= 0)
| {
| s += res;
| }
| else if (errno != EAGAIN)
| {
| - httpconn->servconn->cmdproc->error = MSN_ERROR_WRITE;
| - show_error(httpconn);
| + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE);
| return -1;
| }
| - } while (s < len);
| + } while (s < buf_len);
|
| + g_free(buf);
| +
| return s;
| }
|
| void
| msn_httpconn_poll(MsnHttpConn *httpconn)
| {
| + char *header;
| int r;
| - char *temp;
|
| g_return_if_fail(httpconn != NULL);
|
| @@ -160,7 +130,7 @@ msn_httpconn_poll(MsnHttpConn *httpconn)
| return;
| }
|
| - temp = g_strdup_printf(
| + header = g_strdup_printf(
| "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n"
| "Accept: */*\r\n"
| "Accept-Language: en-us\r\n"
| @@ -170,15 +140,14 @@ msn_httpconn_poll(MsnHttpConn *httpconn)
| "Connection: Keep-Alive\r\n"
| "Pragma: no-cache\r\n"
| "Content-Type: application/x-msn-messenger\r\n"
| - "Content-Length: 0\r\n"
| - "\r\n",
| + "Content-Length: 0\r\n",
| httpconn->host,
| httpconn->full_session_id,
| httpconn->host);
|
| - r = write_raw(httpconn, temp, strlen(temp));
| + r = write_raw(httpconn, header, NULL, -1);
|
| - g_free(temp);
| + g_free(header);
|
| if (r > 0)
| {
| @@ -224,7 +193,7 @@ connect_cb(gpointer data, gint source, G
| else
| {
| gaim_debug_error("msn", "HTTP: Connection error\n");
| - show_error(httpconn);
| + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT);
| }
| }
|
| @@ -257,8 +226,10 @@ msn_httpconn_disconnect(MsnHttpConn *htt
| msn_httpconn_disconnect(MsnHttpConn *httpconn)
| {
| g_return_if_fail(httpconn != NULL);
| - g_return_if_fail(httpconn->connected);
|
| + if (!httpconn->connected)
| + return;
| +
| if (httpconn->timer)
| gaim_timeout_remove(httpconn->timer);
|
| @@ -302,7 +273,7 @@ read_cb(gpointer data, gint source, Gaim
| if (len <= 0)
| {
| gaim_debug_error("msn", "HTTP: Read error\n");
| - show_error(httpconn);
| + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ);
| msn_httpconn_disconnect(httpconn);
|
| return;
| @@ -329,7 +300,7 @@ read_cb(gpointer data, gint source, Gaim
| if (error)
| {
| gaim_debug_error("msn", "HTTP: Special error\n");
| - show_error(httpconn);
| + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ);
| msn_httpconn_disconnect(httpconn);
|
| return;
| @@ -341,6 +312,7 @@ read_cb(gpointer data, gint source, Gaim
| #if 0
| gaim_debug_info("msn", "HTTP: nothing to do here\n");
| #endif
| + g_free(result_msg);
| g_free(httpconn->rx_buf);
| httpconn->rx_buf = NULL;
| httpconn->rx_len = 0;
| @@ -351,6 +323,7 @@ read_cb(gpointer data, gint source, Gaim
| httpconn->rx_buf = NULL;
| httpconn->rx_len = 0;
|
| + g_free(servconn->rx_buf);
| servconn->rx_buf = result_msg;
| servconn->rx_len = result_len;
|
| @@ -425,10 +398,10 @@ msn_httpconn_process_queue(MsnHttpConn *
| httpconn->queue = g_list_remove(httpconn->queue, queue_data);
|
| msn_httpconn_write(queue_data->httpconn,
| - queue_data->buffer,
| + queue_data->data,
| queue_data->size);
|
| - g_free(queue_data->buffer);
| + g_free(queue_data->data);
| g_free(queue_data);
| }
| else
| @@ -438,22 +411,21 @@ size_t
| }
|
| size_t
| -msn_httpconn_write(MsnHttpConn *httpconn, const char *buf, size_t size)
| +msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size)
| {
| char *params;
| - char *temp;
| + char *header;
| gboolean first;
| const char *server_types[] = { "NS", "SB" };
| const char *server_type;
| size_t r; /* result of the write operation */
| - size_t len;
| char *host;
| MsnServConn *servconn;
|
| /* TODO: remove http data from servconn */
|
| g_return_val_if_fail(httpconn != NULL, 0);
| - g_return_val_if_fail(buf != NULL, 0);
| + g_return_val_if_fail(data != NULL, 0);
| g_return_val_if_fail(size > 0, 0);
|
| servconn = httpconn->servconn;
| @@ -463,7 +435,7 @@ msn_httpconn_write(MsnHttpConn *httpconn
| MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1);
|
| queue_data->httpconn = httpconn;
| - queue_data->buffer = g_memdup(buf, size);
| + queue_data->data = g_memdup(data, size);
| queue_data->size = size;
|
| httpconn->queue = g_list_append(httpconn->queue, queue_data);
| @@ -495,7 +467,7 @@ msn_httpconn_write(MsnHttpConn *httpconn
| httpconn->full_session_id);
| }
|
| - temp = g_strdup_printf(
| + header = g_strdup_printf(
| "POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n"
| "Accept: */*\r\n"
| "Accept-Language: en-us\r\n"
| @@ -505,8 +477,7 @@ msn_httpconn_write(MsnHttpConn *httpconn
| "Connection: Keep-Alive\r\n"
| "Pragma: no-cache\r\n"
| "Content-Type: application/x-msn-messenger\r\n"
| - "Content-Length: %d\r\n"
| - "\r\n",
| + "Content-Length: %d\r\n",
| host,
| params,
| host,
| @@ -514,16 +485,10 @@ msn_httpconn_write(MsnHttpConn *httpconn
|
| g_free(params);
|
| - len = strlen(temp);
| - temp = g_realloc(temp, len + size + 1);
| - memcpy(temp + len, buf, size);
| - len += size;
| - temp[len] = '\0';
| + r = write_raw(httpconn, header, data, size);
|
| - r = write_raw(httpconn, temp, len);
| + g_free(header);
|
| - g_free(temp);
| -
| if (r > 0)
| {
| httpconn->virgin = FALSE;
| @@ -541,7 +506,7 @@ msn_httpconn_parse_data(MsnHttpConn *htt
| {
| GaimConnection *gc;
| const char *s, *c;
| - char *headers, *body;
| + char *header, *body;
| const char *body_start;
| char *tmp;
| size_t body_len = 0;
| @@ -604,12 +569,12 @@ msn_httpconn_parse_data(MsnHttpConn *htt
| if ((s = strstr(buf, "\r\n\r\n")) == NULL)
| return FALSE;
|
| - headers = g_strndup(buf, s - buf);
| + header = g_strndup(buf, s - buf);
| s += 4; /* Skip \r\n */
| body_start = s;
| body_len = size - (body_start - buf);
|
| - if ((s = strstr(headers, "Content-Length: ")) != NULL)
| + if ((s = strstr(header, "Content-Length: ")) != NULL)
| {
| int tmp_len;
|
| @@ -617,7 +582,7 @@ msn_httpconn_parse_data(MsnHttpConn *htt
|
| if ((c = strchr(s, '\r')) == NULL)
| {
| - g_free(headers);
| + g_free(header);
|
| return FALSE;
| }
| @@ -628,7 +593,7 @@ msn_httpconn_parse_data(MsnHttpConn *htt
|
| if (body_len != tmp_len)
| {
| - g_free(headers);
| + g_free(header);
|
| #if 0
| gaim_debug_warning("msn",
| @@ -640,14 +605,16 @@ msn_httpconn_parse_data(MsnHttpConn *htt
| }
| }
|
| - body = g_memdup(body_start, body_len);
| + body = g_malloc0(body_len + 1);
| + memcpy(body, body_start, body_len);
|
| #ifdef MSN_DEBUG_HTTP
| - gaim_debug_misc("msn", "Incoming HTTP buffer: {%s\r\n\r\n%s}\n", headers, body);
| + gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n",
| + header);
| #endif
|
| /* Now we should be able to process the data. */
| - if ((s = strstr(headers, "X-MSN-Messenger: ")) != NULL)
| + if ((s = strstr(header, "X-MSN-Messenger: ")) != NULL)
| {
| char *full_session_id, *gw_ip, *session_action;
| char *t, *session_id;
| @@ -659,10 +626,12 @@ msn_httpconn_parse_data(MsnHttpConn *htt
|
| if ((c = strchr(s, '\r')) == NULL)
| {
| - gaim_connection_error(gc, "Malformed X-MSN-Messenger field.");
| + msn_session_set_error(httpconn->session,
| + MSN_ERROR_HTTP_MALFORMED, NULL);
| gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}",
| buf);
|
| + g_free(body);
| return FALSE;
| }
|
| @@ -731,7 +700,7 @@ msn_httpconn_parse_data(MsnHttpConn *htt
| }
| }
|
| - g_free(headers);
| + g_free(header);
|
| *ret_buf = body;
| *ret_size = body_len;
| ============================================================
| --- src/protocols/msn/httpconn.h 439f53ee3453fd0e85b101a4656e0a4f3b455abe
| +++ src/protocols/msn/httpconn.h 7b3611f4ac46fb2d06db98ae7fabdea96b241f4b
| @@ -28,101 +28,79 @@ typedef struct _MsnHttpConn MsnHttpConn;
|
| #include "servconn.h"
|
| +/**
| + * An HTTP Connection.
| + */
| struct _MsnHttpConn
| {
| - MsnSession *session;
| - MsnServConn *servconn;
| + MsnSession *session; /**< The MSN Session. */
| + MsnServConn *servconn; /**< The connection object. */
|
| - char *full_session_id;
| - char *session_id;
| + char *full_session_id; /**< The full session id. */
| + char *session_id; /**< The trimmed session id. */
|
| - int timer;
| + int timer; /**< The timer for polling. */
|
| - gboolean waiting_response;
| - gboolean dirty; /**< The flag that states if we should poll. */
| - gboolean connected;
| + gboolean waiting_response; /**< The flag that states if we are waiting
| + a response from the server. */
| + gboolean dirty; /**< The flag that states if we should poll. */
| + gboolean connected; /**< The flag that states if the connection is on. */
| + gboolean virgin; /**< The flag that states if this connection
| + should specify the host (not gateway) to
| + connect to. */
|
| - char *host;
| - GList *queue;
| + char *host; /**< The HTTP gateway host. */
| + GList *queue; /**< The queue of data chunks to write. */
|
| - int fd;
| - int inpa;
| + int fd; /**< The connection's file descriptor. */
| + int inpa; /**< The connection's input handler. */
|
| - char *rx_buf;
| - int rx_len;
| -
| -#if 0
| - GQueue *servconn_queue;
| -#endif
| -
| - gboolean virgin;
| + char *rx_buf; /**< The receive buffer. */
| + int rx_len; /**< The receive buffer lenght. */
| };
|
| -MsnHttpConn *msn_httpconn_new(MsnServConn *servconn);
| -void msn_httpconn_destroy(MsnHttpConn *httpconn);
| -size_t msn_httpconn_write(MsnHttpConn *httpconn, const char *buf, size_t size);
| -
| -gboolean msn_httpconn_connect(MsnHttpConn *httpconn,
| - const char *host, int port);
| -void msn_httpconn_disconnect(MsnHttpConn *httpconn);
| -
| -#if 0
| -void msn_httpconn_queue_servconn(MsnHttpConn *httpconn, MsnServConn *servconn);
| -#endif
| -
| -#if 0
| /**
| - * Initializes the HTTP data for a session.
| + * Creates a new HTTP connection object.
| *
| - * @param session The session.
| + * @param servconn The connection object.
| + *
| + * @return The new object.
| */
| -void msn_http_session_init(MsnSession *session);
| +MsnHttpConn *msn_httpconn_new(MsnServConn *servconn);
|
| /**
| - * Uninitializes the HTTP data for a session.
| + * Destroys an HTTP connection object.
| *
| - * @param session The session.
| + * @param httpconn The HTTP connection object.
| */
| -void msn_http_session_uninit(MsnSession *session);
| +void msn_httpconn_destroy(MsnHttpConn *httpconn);
|
| /**
| - * Writes data to the server using the HTTP connection method.
| + * Writes a chunk of data to the HTTP connection.
| *
| * @param servconn The server connection.
| - * @param buf The data to write.
| + * @param data The data to write.
| * @param size The size of the data to write.
| - * @param server_type The optional server type.
| *
| * @return The number of bytes written.
| */
| -size_t msn_http_servconn_write(MsnServConn *servconn, const char *buf,
| - size_t size, const char *server_type);
| +size_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size);
|
| /**
| - * Polls the server for data.
| + * Connects the HTTP connection object to a host.
| *
| - * @param servconn The server connection.
| + * @param httpconn The HTTP connection object.
| + * @param host The host to connect to.
| + * @param port The port to connect to.
| */
| -void msn_http_servconn_poll(MsnServConn *servconn);
| +gboolean msn_httpconn_connect(MsnHttpConn *httpconn,
| + const char *host, int port);
|
| /**
| - * Processes an incoming message and returns a string the rest of MSN
| - * can deal with.
| + * Disconnects the HTTP connection object.
| *
| - * @param servconn The server connection.
| - * @param buf The incoming buffer.
| - * @param size The incoming size.
| - * @param ret_buf The returned buffer.
| - * @param ret_len The returned length.
| - * @param error TRUE if there was an HTTP error.
| - *
| - * @return TRUE if the returned buffer is ready to be processed.
| - * FALSE otherwise.
| + * @param httpconn The HTTP connection object.
| */
| -gboolean msn_http_servconn_parse_data(MsnServConn *servconn,
| - const char *buf, size_t size,
| - char **ret_buf, size_t *ret_size,
| - gboolean *error);
| -#endif
| +void msn_httpconn_disconnect(MsnHttpConn *httpconn);
|
| #endif /* _MSN_HTTPCONN_H_ */
| ============================================================
| --- src/protocols/msn/msg.c 8ef3972be90725ec63e42aed7ca310ee17fe527b
| +++ src/protocols/msn/msg.c ee30626ec805c02e1b1a7467593dd8e36a760889
| @@ -197,7 +197,8 @@ msn_message_parse_payload(MsnMessage *ms
|
| g_return_if_fail(payload != NULL);
|
| - tmp_base = tmp = g_memdup(payload, payload_len);
| + tmp_base = tmp = g_malloc0(payload_len + 1);
| + memcpy(tmp_base, payload, payload_len);
|
| /* Parse the attributes. */
| end = strstr(tmp, "\r\n\r\n");
| ============================================================
| --- src/protocols/msn/msn.c bcb1643b0a8018bacf8e59c1c8848f9a64893436
| +++ src/protocols/msn/msn.c 86533d3f4656b13555453e39059309042bc4f153
| @@ -631,22 +631,23 @@ msn_login(GaimAccount *account)
| http_method = TRUE;
|
| host = gaim_account_get_string(account, "server", MSN_SERVER);
| - port = gaim_account_get_int(account, "port", MSN_PORT);
| + port = gaim_account_get_int(account, "port", MSN_PORT);
|
| - session = msn_session_new(account, host, port, http_method);
| + session = msn_session_new(account);
|
| gc->proto_data = session;
| gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_FORMATTING_WBFO | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_FONTSIZE | GAIM_CONNECTION_NO_URLDESC;
|
| - gaim_connection_update_progress(gc, _("Connecting"), 0, MSN_CONNECT_STEPS);
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_START);
|
| /* Hmm, I don't like this. */
| + /* XXX shx: Me neither */
| username = msn_normalize(account, gaim_account_get_username(account));
|
| if (strcmp(username, gaim_account_get_username(account)))
| gaim_account_set_username(account, username);
|
| - msn_session_connect(session);
| + msn_session_connect(session, host, port, http_method);
| }
|
| static void
| @@ -698,14 +699,7 @@ msn_send_im(GaimConnection *gc, const ch
| session = gc->proto_data;
| swboard = msn_session_get_swboard(session, who);
|
| - if (!g_queue_is_empty(swboard->im_queue) || swboard->empty)
| - {
| - msn_switchboard_queue_msg(swboard, msg);
| - }
| - else
| - {
| - msn_switchboard_send_msg(swboard, msg);
| - }
| + msn_switchboard_send_msg(swboard, msg, TRUE);
| }
| else
| {
| @@ -760,15 +754,9 @@ msn_send_typing(GaimConnection *gc, cons
|
| swboard = msn_session_find_swboard(session, who);
|
| - if (swboard == NULL)
| + if (swboard == NULL || !msn_switchboard_can_send(swboard))
| return 0;
|
| - if (swboard->empty)
| - return 0;
| -
| - if (!g_queue_is_empty(swboard->im_queue))
| - return 0;
| -
| msg = msn_message_new(MSN_MSG_TYPING);
| msn_message_set_content_type(msg, "text/x-msmsgscontrol");
| msn_message_set_flag(msg, 'U');
| @@ -776,7 +764,7 @@ msn_send_typing(GaimConnection *gc, cons
| gaim_account_get_username(account));
| msn_message_set_bin_data(msg, "\r\n", 2);
|
| - msn_switchboard_send_msg(swboard, msg);
| + msn_switchboard_send_msg(swboard, msg, FALSE);
|
| msn_message_destroy(msg);
|
| @@ -1124,7 +1112,7 @@ msn_chat_send(GaimConnection *gc, int id
|
| msg = msn_message_new_plain(msgtext);
| msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
| - msn_switchboard_send_msg(swboard, msg);
| + msn_switchboard_send_msg(swboard, msg, FALSE);
| msn_message_destroy(msg);
|
| g_free(msgformat);
| @@ -1143,6 +1131,7 @@ msn_keepalive(GaimConnection *gc)
| MsnCmdProc *cmdproc;
|
| session = gc->proto_data;
| +
| cmdproc = session->notification->cmdproc;
|
| if (!session->http_method)
| ============================================================
| --- src/protocols/msn/msn.h 33ebb47c5cc5e403e3637c6488be1ee91db0fb71
| +++ src/protocols/msn/msn.h 2f37626407aa695f9ead618675675ba821fecdb6
| @@ -45,9 +45,14 @@
|
| #include "ft.h"
|
| -/* XXX */
| -#include "gaim.h"
| +/* #define MSN_DEBUG_MSG 1 */
| +/* #define MSN_DEBUG_SLPMSG 1 */
| +/* #define MSN_DEBUG_HTTP 1 */
|
| +/* #define MSN_DEBUG_SLP 1 */
| +/* #define MSN_DEBUG_SLP_VERBOSE 1 */
| +/* #define MSN_DEBUG_SLP_FILES 1 */
| +
| #define MSN_BUF_LEN 8192
|
| #define USEROPT_MSNSERVER 3
| @@ -67,8 +72,6 @@
|
| #define MSN_FT_GUID "{5D3E02AB-6190-11d3-BBBB-00C04F795683}"
|
| -#define MSN_CONNECT_STEPS 8
| -
| #define MSN_CLIENTINFO \
| "Client-Name: Gaim/" VERSION "\r\n" \
| "Chat-Logging: Y\r\n"
| ============================================================
| --- src/protocols/msn/nexus.c 83ed4afa08e58d80df293bcc96f306909c73d102
| +++ src/protocols/msn/nexus.c f54fd42744b2afe062d596b626c278dffa953431
| @@ -26,6 +26,38 @@
| #include "notification.h"
|
| /**************************************************************************
| + * Main
| + **************************************************************************/
| +
| +MsnNexus *
| +msn_nexus_new(MsnSession *session)
| +{
| + MsnNexus *nexus;
| +
| + nexus = g_new0(MsnNexus, 1);
| + nexus->session = session;
| + nexus->challenge_data = g_hash_table_new_full(g_str_hash, g_str_equal,
| + g_free, g_free);
| +
| + return nexus;
| +}
| +
| +void
| +msn_nexus_destroy(MsnNexus *nexus)
| +{
| + if (nexus->login_host != NULL)
| + g_free(nexus->login_host);
| +
| + if (nexus->login_path != NULL)
| + g_free(nexus->login_path);
| +
| + if (nexus->challenge_data != NULL)
| + g_hash_table_destroy(nexus->challenge_data);
| +
| + g_free(nexus);
| +}
| +
| +/**************************************************************************
| * Util
| **************************************************************************/
|
| @@ -76,7 +108,7 @@ login_error_cb(GaimSslConnection *gsc, G
| gc = gaim_account_get_connection(account);
| g_return_if_fail(gc != NULL);
|
| - gaim_connection_error(gc, _("Unable to connect to server"));
| + msn_session_set_error(session, MSN_ERROR_AUTH, _("Unable to connect"));
|
| msn_nexus_destroy(nexus);
| session->nexus = NULL;
| @@ -100,6 +132,8 @@ login_connect_cb(gpointer data, GaimSslC
| session = nexus->session;
| g_return_if_fail(session != NULL);
|
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
| +
| username =
| g_strdup(gaim_url_encode(gaim_account_get_username(session->account)));
|
| @@ -191,14 +225,15 @@ login_connect_cb(gpointer data, GaimSslC
| }
| else if (strstr(buffer, "HTTP/1.1 401 Unauthorized") != NULL)
| {
| - GaimConnection *gc;
| - const char *error, *c;
| - char *temp;
| + const char *error;
|
| if ((error = strstr(buffer, "WWW-Authenticate")) != NULL)
| {
| if ((error = strstr(error, "cbtxt=")) != NULL)
| {
| + const char *c;
| + char *temp;
| +
| error += strlen("cbtxt=");
|
| if ((c = strchr(error, '\n')) == NULL)
| @@ -210,16 +245,7 @@ login_connect_cb(gpointer data, GaimSslC
| }
| }
|
| - gc = gaim_account_get_connection(session->account);
| -
| - if (error == NULL)
| - {
| - gaim_connection_error(gc,
| - _("Unknown error when attempting to authorize with "
| - "MSN login server."));
| - }
| - else
| - gaim_connection_error(gc, error);
| + msn_session_set_error(session, MSN_ERROR_AUTH, error);
| }
| else if (strstr(buffer, "HTTP/1.1 200 OK"))
| {
| @@ -264,6 +290,10 @@ login_connect_cb(gpointer data, GaimSslC
| g_free(buffer);
| }
|
| +/**************************************************************************
| + * Connect
| + **************************************************************************/
| +
| static void
| nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
| GaimInputCondition cond)
| @@ -282,6 +312,8 @@ nexus_connect_cb(gpointer data, GaimSslC
| session = nexus->session;
| g_return_if_fail(session != NULL);
|
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH);
| +
| request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n");
|
| if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0)
| @@ -332,39 +364,7 @@ nexus_connect_cb(gpointer data, GaimSslC
| login_error_cb, nexus);
| }
|
| -/**************************************************************************
| - * Nexus
| - **************************************************************************/
| -
| -MsnNexus *
| -msn_nexus_new(MsnSession *session)
| -{
| - MsnNexus *nexus;
| -
| - nexus = g_new0(MsnNexus, 1);
| - nexus->session = session;
| - nexus->challenge_data = g_hash_table_new_full(g_str_hash, g_str_equal,
| - g_free, g_free);
| -
| - return nexus;
| -}
| -
| void
| -msn_nexus_destroy(MsnNexus *nexus)
| -{
| - if (nexus->login_host != NULL)
| - g_free(nexus->login_host);
| -
| - if (nexus->login_path != NULL)
| - g_free(nexus->login_path);
| -
| - if (nexus->challenge_data != NULL)
| - g_hash_table_destroy(nexus->challenge_data);
| -
| - g_free(nexus);
| -}
| -
| -void
| msn_nexus_connect(MsnNexus *nexus)
| {
| gaim_ssl_connect(nexus->session->account, "nexus.passport.com",
| ============================================================
| --- src/protocols/msn/notification.c 556e5263194a4e7ef6cc95d194da6bb19d0ef460
| +++ src/protocols/msn/notification.c bd5b923eadf1ed1c3a3d747d3a286e7ee7a20325
| @@ -32,13 +32,12 @@
| #include "sync.h"
| #include "slplink.h"
|
| -#define BUDDY_ALIAS_MAXLEN 388
| -
| static MsnTable *cbs_table;
|
| /**************************************************************************
| * Main
| **************************************************************************/
| +
| static void
| destroy_cb(MsnServConn *servconn)
| {
| @@ -61,7 +60,7 @@ msn_notification_new(MsnSession *session
| notification = g_new0(MsnNotification, 1);
|
| notification->session = session;
| - notification->servconn = servconn = msn_servconn_new(session, MSN_SERVER_NS);
| + notification->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_NS);
| msn_servconn_set_destroy_cb(servconn, destroy_cb);
|
| notification->cmdproc = servconn->cmdproc;
| @@ -74,20 +73,19 @@ msn_notification_destroy(MsnNotification
| void
| msn_notification_destroy(MsnNotification *notification)
| {
| - if (notification->destroying)
| - return;
| + notification->cmdproc->data = NULL;
|
| - notification->destroying = TRUE;
| + msn_servconn_set_destroy_cb(notification->servconn, NULL);
|
| msn_servconn_destroy(notification->servconn);
|
| - notification->session->notification = NULL;
| g_free(notification);
| }
|
| /**************************************************************************
| * Connect
| **************************************************************************/
| +
| static void
| connect_cb(MsnServConn *servconn)
| {
| @@ -113,17 +111,11 @@ connect_cb(MsnServConn *servconn)
|
| vers = g_strjoinv(" ", a);
|
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);
| msn_cmdproc_send(cmdproc, "VER", "%s", vers);
|
| g_strfreev(a);
| g_free(vers);
| -
| - if (cmdproc->error)
| - return;
| -
| - if (session->user == NULL)
| - session->user = msn_user_new(session->userlist,
| - gaim_account_get_username(account), NULL);
| }
|
| gboolean
| @@ -155,6 +147,7 @@ msn_notification_disconnect(MsnNotificat
| /**************************************************************************
| * Util
| **************************************************************************/
| +
| static void
| group_error_helper(MsnSession *session, const char *msg, int group_id, int error)
| {
| @@ -198,6 +191,7 @@ group_error_helper(MsnSession *session,
| /**************************************************************************
| * Login
| **************************************************************************/
| +
| void
| msn_got_login_params(MsnSession *session, const char *login_params)
| {
| @@ -205,6 +199,8 @@ msn_got_login_params(MsnSession *session
|
| cmdproc = session->notification->cmdproc;
|
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END);
| +
| msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params);
| }
|
| @@ -220,31 +216,6 @@ static void
| }
|
| static void
| -inf_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| -{
| - GaimAccount *account;
| - GaimConnection *gc;
| -
| - account = cmdproc->session->account;
| - gc = gaim_account_get_connection(account);
| -
| - if (strcmp(cmd->params[1], "MD5"))
| - {
| - msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
| - return;
| - }
| -
| - msn_cmdproc_send(cmdproc, "USR", "MD5 I %s",
| - gaim_account_get_username(account));
| -
| - if (cmdproc->error)
| - return;
| -
| - gaim_connection_update_progress(gc, _("Requesting to send password"),
| - 5, MSN_CONNECT_STEPS);
| -}
| -
| -static void
| usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| MsnSession *session;
| @@ -255,33 +226,22 @@ usr_cmd(MsnCmdProc *cmdproc, MsnCommand
| account = session->account;
| gc = gaim_account_get_connection(account);
|
| - /*
| - * We're either getting the passport connect info (if we're on
| - * MSNP8 or higher), or a challenge request (MSNP7 and lower).
| - *
| - * Let's find out.
| - */
| if (!g_ascii_strcasecmp(cmd->params[1], "OK"))
| {
| + /* OK */
| const char *friendly = gaim_url_decode(cmd->params[3]);
|
| - /* OK */
| + gaim_connection_set_display_name(gc, friendly);
|
| - gaim_connection_set_display_name(gc, friendly);
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
|
| msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
| -
| - if (cmdproc->error)
| - return;
| -
| - gaim_connection_update_progress(gc, _("Retrieving buddy list"),
| - 7, MSN_CONNECT_STEPS);
| }
| else if (!g_ascii_strcasecmp(cmd->params[1], "TWN"))
| {
| + /* Passport authentication */
| char **elems, **cur, **tokens;
|
| - /* Passport authentication */
| session->nexus = msn_nexus_new(session);
|
| /* Parse the challenge data. */
| @@ -298,40 +258,10 @@ usr_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| g_strfreev(elems);
|
| - msn_nexus_connect(session->nexus);
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);
|
| - gaim_connection_update_progress(gc, _("Password sent"),
| - 6, MSN_CONNECT_STEPS);
| + msn_nexus_connect(session->nexus);
| }
| - else if (!g_ascii_strcasecmp(cmd->params[1], "MD5"))
| - {
| - /* Challenge */
| - const char *challenge;
| - const char *password;
| - char buf[33];
| - md5_state_t st;
| - md5_byte_t di[16];
| - int i;
| -
| - challenge = cmd->params[3];
| - password = gaim_account_get_password(account);
| -
| - md5_init(&st);
| - md5_append(&st, (const md5_byte_t *)challenge, strlen(challenge));
| - md5_append(&st, (const md5_byte_t *)password, strlen(password));
| - md5_finish(&st, di);
| -
| - for (i = 0; i < 16; i++)
| - g_snprintf(buf + (i*2), 3, "%02x", di[i]);
| -
| - msn_cmdproc_send(cmdproc, "USR", "MD5 S %s", buf);
| -
| - if (cmdproc->error)
| - return;
| -
| - gaim_connection_update_progress(gc, _("Password sent"),
| - 6, MSN_CONNECT_STEPS);
| - }
| }
|
| static void
| @@ -359,7 +289,8 @@ ver_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| if (!protocol_supported)
| {
| - msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
| + msn_session_set_error(session, MSN_ERROR_UNSUPORTED_PROTOCOL,
| + NULL);
| return;
| }
|
| @@ -371,13 +302,15 @@ ver_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Log out
| **************************************************************************/
| +
| static void
| out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| if (!g_ascii_strcasecmp(cmd->params[0], "OTH"))
| - msn_cmdproc_show_error(cmdproc, MSN_ERROR_SIGNOTHER);
| + msn_session_set_error(cmdproc->session, MSN_ERROR_SIGN_OTHER,
| + NULL);
| else if (!g_ascii_strcasecmp(cmd->params[0], "SSD"))
| - msn_cmdproc_show_error(cmdproc, MSN_ERROR_SERVDOWN);
| + msn_session_set_error(cmdproc->session, MSN_ERROR_SERV_DOWN, NULL);
| }
|
| void
| @@ -393,6 +326,7 @@ msn_notification_close(MsnNotification *
| /**************************************************************************
| * Messages
| **************************************************************************/
| +
| static void
| msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
| size_t len)
| @@ -431,6 +365,7 @@ msg_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Challenges
| **************************************************************************/
| +
| static void
| chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -464,6 +399,7 @@ chl_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Buddy Lists
| **************************************************************************/
| +
| static void
| add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -873,22 +809,13 @@ syn_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| if (cmd->param_count == 2)
| {
| - char *buf;
| /*
| * This can happen if we sent a SYN with an up-to-date
| * buddy list revision, but we send 0 to get a full list.
| * So, error out.
| */
| - buf = g_strdup_printf(
| - _("Your MSN buddy list for %s is temporarily unavailable. "
| - "Please wait and try again."),
| - gaim_account_get_username(session->account));
|
| - gaim_connection_error(gaim_account_get_connection(session->account),
| - buf);
| -
| - g_free(buf);
| -
| + msn_session_set_error(cmdproc->session, MSN_ERROR_BAD_BLIST, NULL);
| return;
| }
|
| @@ -915,6 +842,7 @@ syn_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Misc commands
| **************************************************************************/
| +
| static void
| url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -1017,6 +945,7 @@ url_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Switchboards
| **************************************************************************/
| +
| static void
| rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -1055,7 +984,8 @@ xfr_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
| {
| - msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
| + /* Maybe we can have a generic bad command error. */
| + gaim_debug_error("msn", "Bad XFR command (%s)\n", cmd->params[1]);
| return;
| }
|
| @@ -1064,19 +994,6 @@ xfr_cmd(MsnCmdProc *cmdproc, MsnCommand
| if (!strcmp(cmd->params[1], "SB"))
| {
| gaim_debug_error("msn", "This shouldn't be handled here.\n");
| -#if 0
| - swboard = cmd->trans->data;
| -
| - if (swboard != NULL)
| - {
| - msn_switchboard_set_auth_key(swboard, cmd->params[4]);
| -
| - if (session->http_method)
| - port = 80;
| -
| - msn_switchboard_connect(swboard, host, port);
| - }
| -#endif
| }
| else if (!strcmp(cmd->params[1], "NS"))
| {
| @@ -1084,6 +1001,9 @@ xfr_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| session = cmdproc->session;
|
| + if (!session->logged_in)
| + msn_session_set_login_step(session, MSN_LOGIN_STEP_TRANSFER);
| +
| msn_notification_connect(session->notification, host, port);
| }
|
| @@ -1093,6 +1013,7 @@ xfr_cmd(MsnCmdProc *cmdproc, MsnCommand
| /**************************************************************************
| * Message Types
| **************************************************************************/
| +
| static void
| profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
| {
| @@ -1342,6 +1263,7 @@ msn_notification_rem_buddy(MsnNotificati
| /**************************************************************************
| * Init
| **************************************************************************/
| +
| void
| msn_notification_init(void)
| {
| @@ -1359,7 +1281,6 @@ msn_notification_init(void)
| msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd);
| msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd);
| msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd);
| - msn_table_add_cmd(cbs_table, "INF", "INF", inf_cmd);
| msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd);
| msn_table_add_cmd(cbs_table, "REA", "REA", rea_cmd);
| /* msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd); */
| ============================================================
| --- src/protocols/msn/notification.h 632f7c36affddbcc7f9b3cb387f2c3a1c22c4b22
| +++ src/protocols/msn/notification.h 360279e0975110d80faf5468f768e23cbec5007d
| @@ -36,9 +36,6 @@ struct _MsnNotification
| MsnCmdProc *cmdproc;
| MsnServConn *servconn;
|
| - gboolean destroying; /**< A flag that states if the notification is on
| - the process of being destroyed. */
| -
| gboolean in_use;
| };
|
| ============================================================
| --- src/protocols/msn/servconn.c 9c0aff4019343c183bffb448a67647c89894701e
| +++ src/protocols/msn/servconn.c c90ed444a410c540f48f1e0f411a3955f562ac70
| @@ -27,6 +27,10 @@ static void read_cb(gpointer data, gint
|
| static void read_cb(gpointer data, gint source, GaimInputCondition cond);
|
| +/**************************************************************************
| + * Main
| + **************************************************************************/
| +
| MsnServConn *
| msn_servconn_new(MsnSession *session, MsnServConnType type)
| {
| @@ -42,8 +46,7 @@ msn_servconn_new(MsnSession *session, Ms
| servconn->cmdproc = msn_cmdproc_new(session);
| servconn->cmdproc->servconn = servconn;
|
| - if (session->http_method)
| - servconn->httpconn = msn_httpconn_new(servconn);
| + servconn->httpconn = msn_httpconn_new(servconn);
|
| servconn->num = session->servconns_count++;
|
| @@ -61,11 +64,6 @@ msn_servconn_destroy(MsnServConn *servco
| return;
| }
|
| - if (servconn->destroying)
| - return;
| -
| - servconn->destroying = TRUE;
| -
| if (servconn->connected)
| msn_servconn_disconnect(servconn);
|
| @@ -82,52 +80,83 @@ msn_servconn_destroy(MsnServConn *servco
| g_free(servconn);
| }
|
| -static void
| -show_error(MsnServConn *servconn)
| +void
| +msn_servconn_set_connect_cb(MsnServConn *servconn,
| + void (*connect_cb)(MsnServConn *))
| {
| - GaimConnection *gc;
| + g_return_if_fail(servconn != NULL);
| + servconn->connect_cb = connect_cb;
| +}
| +
| +void
| +msn_servconn_set_disconnect_cb(MsnServConn *servconn,
| + void (*disconnect_cb)(MsnServConn *))
| +{
| + g_return_if_fail(servconn != NULL);
| +
| + servconn->disconnect_cb = disconnect_cb;
| +}
| +
| +void
| +msn_servconn_set_destroy_cb(MsnServConn *servconn,
| + void (*destroy_cb)(MsnServConn *))
| +{
| + g_return_if_fail(servconn != NULL);
| +
| + servconn->destroy_cb = destroy_cb;
| +}
| +
| +/**************************************************************************
| + * Utility
| + **************************************************************************/
| +
| +void
| +msn_servconn_got_error(MsnServConn *servconn, MsnServConnError error)
| +{
| char *tmp;
| - char *cmd;
| + const char *reason;
|
| const char *names[] = { "Notification", "Switchboard" };
| const char *name;
|
| - gc = gaim_account_get_connection(servconn->session->account);
| name = names[servconn->type];
|
| - switch (servconn->cmdproc->error)
| + switch (error)
| {
| - case MSN_ERROR_CONNECT:
| - tmp = g_strdup_printf(_("Unable to connect to %s server"),
| - name);
| - break;
| - case MSN_ERROR_WRITE:
| - tmp = g_strdup_printf(_("Error writing to %s server"), name);
| - break;
| - case MSN_ERROR_READ:
| - cmd = servconn->cmdproc->last_trans;
| - tmp = g_strdup_printf(_("Error reading from %s server"), name);
| - gaim_debug_info("msn", "Last command was: %s\n", cmd);
| - break;
| + case MSN_SERVCONN_ERROR_CONNECT:
| + reason = _("Unable to connect"); break;
| + case MSN_SERVCONN_ERROR_WRITE:
| + reason = _("Writing error"); break;
| + case MSN_SERVCONN_ERROR_READ:
| + reason = _("Reading error"); break;
| default:
| - tmp = g_strdup_printf(_("Unknown error from %s server"), name);
| - break;
| + reason = _("Unknown error"); break;
| }
|
| - if (servconn->type != MSN_SERVER_SB)
| + tmp = g_strdup_printf(_("Connection error from %s server (%s):\n%s"),
| + name, servconn->host, reason);
| +
| + if (servconn->type == MSN_SERVCONN_NS)
| {
| - gaim_connection_error(gc, tmp);
| + msn_session_set_error(servconn->session, MSN_ERROR_SERVCONN, tmp);
| }
| - else
| + else if (servconn->type == MSN_SERVCONN_SB)
| {
| MsnSwitchBoard *swboard;
| swboard = servconn->cmdproc->data;
| - swboard->error = MSN_SB_ERROR_CONNECTION;
| + if (swboard != NULL)
| + swboard->error = MSN_SB_ERROR_CONNECTION;
| }
|
| + msn_servconn_disconnect(servconn);
| +
| g_free(tmp);
| }
|
| +/**************************************************************************
| + * Connect
| + **************************************************************************/
| +
| static void
| connect_cb(gpointer data, gint source, GaimInputCondition cond)
| {
| @@ -146,7 +175,6 @@ connect_cb(gpointer data, gint source, G
| if (source > 0)
| {
| servconn->connected = TRUE;
| - servconn->cmdproc->ready = TRUE;
|
| /* Someone wants to know we connected. */
| servconn->connect_cb(servconn);
| @@ -155,8 +183,7 @@ connect_cb(gpointer data, gint source, G
| }
| else
| {
| - servconn->cmdproc->error = MSN_ERROR_CONNECT;
| - show_error(servconn);
| + msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
| }
| }
|
| @@ -188,7 +215,6 @@ msn_servconn_connect(MsnServConn *servco
| msn_httpconn_connect(servconn->httpconn, host, port);
|
| servconn->connected = TRUE;
| - servconn->cmdproc->ready = TRUE;
| servconn->httpconn->virgin = TRUE;
|
| /* Someone wants to know we connected. */
| @@ -216,6 +242,7 @@ msn_servconn_disconnect(MsnServConn *ser
|
| if (!servconn->connected)
| {
| + /* We could not connect. */
| if (servconn->disconnect_cb != NULL)
| servconn->disconnect_cb(servconn);
|
| @@ -224,7 +251,7 @@ msn_servconn_disconnect(MsnServConn *ser
|
| if (servconn->session->http_method)
| {
| - /* Fake disconnection */
| + /* Fake disconnection. */
| if (servconn->disconnect_cb != NULL)
| servconn->disconnect_cb(servconn);
|
| @@ -244,48 +271,11 @@ msn_servconn_disconnect(MsnServConn *ser
| servconn->payload_len = 0;
|
| servconn->connected = FALSE;
| - servconn->cmdproc->ready = FALSE;
|
| if (servconn->disconnect_cb != NULL)
| servconn->disconnect_cb(servconn);
| }
|
| -void
| -msn_servconn_set_connect_cb(MsnServConn *servconn,
| - void (*connect_cb)(MsnServConn *))
| -{
| - g_return_if_fail(servconn != NULL);
| - servconn->connect_cb = connect_cb;
| -}
| -
| -void
| -msn_servconn_set_disconnect_cb(MsnServConn *servconn,
| - void (*disconnect_cb)(MsnServConn *))
| -{
| - g_return_if_fail(servconn != NULL);
| -
| - servconn->disconnect_cb = disconnect_cb;
| -}
| -
| -void
| -msn_servconn_set_destroy_cb(MsnServConn *servconn,
| - void (*destroy_cb)(MsnServConn *))
| -{
| - g_return_if_fail(servconn != NULL);
| -
| - servconn->destroy_cb = destroy_cb;
| -}
| -
| -static void
| -failed_io(MsnServConn *servconn)
| -{
| - g_return_if_fail(servconn != NULL);
| -
| - show_error(servconn);
| -
| - msn_servconn_disconnect(servconn);
| -}
| -
| size_t
| msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
| {
| @@ -297,14 +287,16 @@ msn_servconn_write(MsnServConn *servconn
| {
| switch (servconn->type)
| {
| - case MSN_SERVER_NS:
| - case MSN_SERVER_SB:
| + case MSN_SERVCONN_NS:
| + case MSN_SERVCONN_SB:
| ret = write(servconn->fd, buf, len);
| break;
| - case MSN_SERVER_DC:
| +#if 0
| + case MSN_SERVCONN_DC:
| ret = write(servconn->fd, &buf, sizeof(len));
| ret = write(servconn->fd, buf, len);
| break;
| +#endif
| default:
| ret = write(servconn->fd, buf, len);
| break;
| @@ -317,8 +309,7 @@ msn_servconn_write(MsnServConn *servconn
|
| if (ret == -1)
| {
| - servconn->cmdproc->error = MSN_ERROR_WRITE;
| - failed_io(servconn);
| + msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
| }
|
| return ret;
| @@ -340,10 +331,8 @@ read_cb(gpointer data, gint source, Gaim
|
| if (len <= 0)
| {
| - servconn->cmdproc->error = MSN_ERROR_READ;
| + msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);
|
| - failed_io(servconn);
| -
| return;
| }
|
| ============================================================
| --- src/protocols/msn/servconn.h 9e77af0c3ffcb14a64634462c94f385c7d523977
| +++ src/protocols/msn/servconn.h da44ea75ef03e06f6bb6f0d1115f24a141cfe407
| @@ -32,21 +32,30 @@ typedef struct _MsnServConn MsnServConn;
| #include "proxy.h"
| #include "httpconn.h"
|
| -/*
| - * Connection types
| +/**
| + * Connection error types.
| */
| typedef enum
| {
| - MSN_SERVER_NS,
| - MSN_SERVER_SB,
| - MSN_SERVER_NX,
| - MSN_SERVER_DC,
| - MSN_SERVER_HT
| + MSN_SERVCONN_ERROR_NONE,
| + MSN_SERVCONN_ERROR_CONNECT,
| + MSN_SERVCONN_ERROR_WRITE,
| + MSN_SERVCONN_ERROR_READ,
|
| +} MsnServConnError;
| +
| +/**
| + * Connection types.
| + */
| +typedef enum
| +{
| + MSN_SERVCONN_NS,
| + MSN_SERVCONN_SB
| +
| } MsnServConnType;
|
| -/*
| - * A Connection
| +/**
| + * A Connection.
| */
| struct _MsnServConn
| {
| @@ -58,8 +67,6 @@ struct _MsnServConn
| gboolean processing; /**< A flag that states if something is working
| with this connection. */
| gboolean wasted; /**< A flag that states if it should be destroyed. */
| - gboolean destroying; /**< A flag that states if the connection is on
| - the process of being destroyed. */
|
| char *host; /**< The host this connection is connected or should be
| connected to. */
| @@ -148,4 +155,12 @@ size_t msn_servconn_write(MsnServConn *s
| size_t msn_servconn_write(MsnServConn *servconn, const char *buf,
| size_t size);
|
| +/**
| + * Function to call whenever an error related to a switchboard occurs.
| + *
| + * @param servconn The servconn.
| + * @param error The error that happened.
| + */
| +void msn_servconn_got_error(MsnServConn *servconn, MsnServConnError error);
| +
| #endif /* _MSN_SERVCONN_H_ */
| ============================================================
| --- src/protocols/msn/session.c 8d9b746cf7977992be741cb035bcbee43d4ff533
| +++ src/protocols/msn/session.c 5bc0dfd60f8b8896ff24c6c083ae40d454001e93
| @@ -28,8 +28,7 @@ MsnSession *
| #include "dialog.h"
|
| MsnSession *
| -msn_session_new(GaimAccount *account, const char *host, int port,
| - gboolean http_method)
| +msn_session_new(GaimAccount *account)
| {
| MsnSession *session;
|
| @@ -37,15 +36,14 @@ msn_session_new(GaimAccount *account, co
|
| session = g_new0(MsnSession, 1);
|
| - session->account = account;
| - session->dispatch_host = g_strdup(host);
| - session->dispatch_port = port;
| - session->http_method = http_method;
| -
| + session->account = account;
| session->notification = msn_notification_new(session);
| session->userlist = msn_userlist_new(session);
| session->sync_userlist = msn_userlist_new(session);
|
| + session->user = msn_user_new(session->userlist,
| + gaim_account_get_username(account), NULL);
| +
| session->protocol_ver = 9;
|
| return session;
| @@ -61,9 +59,6 @@ msn_session_destroy(MsnSession *session)
| if (session->connected)
| msn_session_disconnect(session);
|
| - if (session->dispatch_host != NULL)
| - g_free(session->dispatch_host);
| -
| if (session->notification != NULL)
| msn_notification_destroy(session->notification);
|
| @@ -102,16 +97,21 @@ msn_session_destroy(MsnSession *session)
| if (session->nexus != NULL)
| msn_nexus_destroy(session->nexus);
|
| + if (session->user != NULL)
| + msn_user_destroy(session->user);
| +
| g_free(session);
| }
|
| gboolean
| -msn_session_connect(MsnSession *session)
| +msn_session_connect(MsnSession *session, const char *host, int port,
| + gboolean http_method)
| {
| g_return_val_if_fail(session != NULL, FALSE);
| g_return_val_if_fail(!session->connected, TRUE);
|
| session->connected = TRUE;
| + session->http_method = http_method;
|
| if (session->notification == NULL)
| {
| @@ -119,9 +119,7 @@ msn_session_connect(MsnSession *session)
| g_return_val_if_reached(FALSE);
| }
|
| - if (msn_notification_connect(session->notification,
| - session->dispatch_host,
| - session->dispatch_port))
| + if (msn_notification_connect(session->notification, host, port))
| {
| return TRUE;
| }
| @@ -135,13 +133,13 @@ msn_session_disconnect(MsnSession *sessi
| g_return_if_fail(session != NULL);
| g_return_if_fail(session->connected);
|
| + session->connected = FALSE;
| +
| while (session->switches != NULL)
| msn_switchboard_close(session->switches->data);
|
| if (session->notification != NULL)
| msn_notification_close(session->notification);
| -
| - session->connected = FALSE;
| }
|
| /* TODO: This must go away when conversation is redesigned */
| @@ -280,6 +278,86 @@ void
| }
|
| void
| +msn_session_set_error(MsnSession *session, MsnErrorType error,
| + const char *info)
| +{
| + GaimConnection *gc;
| + char *msg;
| +
| + gc = session->account->gc;
| +
| + switch (error)
| + {
| + case MSN_ERROR_SERVCONN:
| + msg = g_strdup(info);
| + break;
| + case MSN_ERROR_UNSUPORTED_PROTOCOL:
| + msg = g_strdup(_("Our protocol is not supported by the "
| + "server."));
| + break;
| + case MSN_ERROR_HTTP_MALFORMED:
| + msg = g_strdup(_("Error parsing HTTP."));
| + break;
| + case MSN_ERROR_SIGN_OTHER:
| + gc->wants_to_die = TRUE;
| + msg = g_strdup(_("You have signed on from another location."));
| + break;
| + case MSN_ERROR_SERV_DOWN:
| + msg = g_strdup(_("The MSN servers are going down "
| + "temporarily."));
| + break;
| + case MSN_ERROR_AUTH:
| + msg = g_strdup_printf(_("Unable to authenticate: %s"),
| + (info == NULL ) ?
| + _("Unknown error") : info);
| + break;
| + case MSN_ERROR_BAD_BLIST:
| + msg = g_strdup(_("Your MSN buddy list is temporarily "
| + "unavailable. Please wait and try "
| + "again."));
| + break;
| + default:
| + msg = g_strdup(_("Unknown error."));
| + break;
| + }
| +
| + msn_session_disconnect(session);
| + gaim_connection_error(gc, msg);
| +
| + g_free(msg);
| +}
| +
| +static const char *
| +get_login_step_text(MsnSession *session)
| +{
| + const char *steps_text[] = {
| + _("Connecting"),
| + _("Handshaking"),
| + _("Transfering"),
| + _("Starting authentication"),
| + _("Getting cookie"),
| + _("Authenticating"),
| + _("Sending cookie"),
| + _("Retrieving buddy list")
| + };
| +
| + return steps_text[session->login_step];
| +}
| +
| +void
| +msn_session_set_login_step(MsnSession *session, MsnLoginStep step)
| +{
| + GaimConnection *gc;
| +
| + gc = session->account->gc;
| +
| + session->login_step = step;
| +
| + gaim_connection_update_progress(gc, get_login_step_text(session), step,
| + MSN_LOGIN_STEPS);
| +}
| +
| +void
| msn_session_finish_login(MsnSession *session)
| {
| GaimAccount *account;
| ============================================================
| --- src/protocols/msn/session.h 95401b94ff46d95388832a0c491dd4500fdacb8d
| +++ src/protocols/msn/session.h 0c3930d575a930a9936f9b10d44878e13171e374
| @@ -40,6 +40,40 @@ typedef struct _MsnSession MsnSession;
| #include "userlist.h"
| #include "sync.h"
|
| +/**
| + * Types of errors.
| + */
| +typedef enum
| +{
| + MSN_ERROR_SERVCONN,
| + MSN_ERROR_UNSUPORTED_PROTOCOL,
| + MSN_ERROR_HTTP_MALFORMED,
| + MSN_ERROR_AUTH,
| + MSN_ERROR_BAD_BLIST,
| + MSN_ERROR_SIGN_OTHER,
| + MSN_ERROR_SERV_DOWN
| +
| +} MsnErrorType;
| +
| +/**
| + * Login steps.
| + */
| +typedef enum
| +{
| + MSN_LOGIN_STEP_START,
| + MSN_LOGIN_STEP_HANDSHAKE,
| + MSN_LOGIN_STEP_TRANSFER,
| + MSN_LOGIN_STEP_AUTH_START,
| + MSN_LOGIN_STEP_AUTH,
| + MSN_LOGIN_STEP_GET_COOKIE,
| + MSN_LOGIN_STEP_AUTH_END,
| + MSN_LOGIN_STEP_SYN,
| + MSN_LOGIN_STEP_END
| +
| +} MsnLoginStep;
| +
| +#define MSN_LOGIN_STEPS MSN_LOGIN_STEP_END
| +
| struct _MsnSession
| {
| GaimAccount *account;
| @@ -48,27 +82,26 @@ struct _MsnSession
|
| guint protocol_ver;
|
| - char *dispatch_host;
| - int dispatch_port;
| + MsnLoginStep login_step; /**< The current step in the login process. */
|
| gboolean connected;
| gboolean logged_in; /**< A temporal flag to ignore local buddy list adds. */
| gboolean destroying; /**< A flag that states if the session is being destroyed. */
| + gboolean http_method;
|
| MsnNotification *notification;
| MsnNexus *nexus;
| + MsnSync *sync;
|
| - gboolean http_method;
| - gint http_poll_timer;
| -
| MsnUserList *userlist;
| MsnUserList *sync_userlist;
|
| int servconns_count; /**< The count of server connections. */
| GList *switches; /**< The list of all the switchboards. */
| GList *directconns; /**< The list of all the directconnections. */
| + GList *slplinks; /**< The list of all the slplinks. */
|
| - int conv_seq;
| + int conv_seq; /**< The current conversation sequence number. */
|
| struct
| {
| @@ -81,27 +114,16 @@ struct _MsnSession
| int client_port;
|
| } passport_info;
| -
| - /* You have no idea how much I hate all that is below. */
| - /* shx: What? ;) */
| -
| - MsnSync *sync;
| -
| - GList *slplinks;
| };
|
| /**
| * Creates an MSN session.
| *
| * @param account The account.
| - * @param host The dispatch server host.
| - * @param port The dispatch server port.
| *
| * @return The new MSN session.
| */
| -MsnSession *msn_session_new(GaimAccount *account,
| - const char *host, int port,
| - gboolean http_method);
| +MsnSession *msn_session_new(GaimAccount *account);
|
| /**
| * Destroys an MSN session.
| @@ -113,11 +135,16 @@ void msn_session_destroy(MsnSession *ses
| /**
| * Connects to and initiates an MSN session.
| *
| - * @param session The MSN session.
| + * @param session The MSN session.
| + * @param host The dispatch server host.
| + * @param port The dispatch server port.
| + * @param http_method Whether to use or not http_method.
| *
| * @return @c TRUE on success, @c FALSE on failure.
| */
| -gboolean msn_session_connect(MsnSession *session);
| +gboolean msn_session_connect(MsnSession *session,
| + const char *host, int port,
| + gboolean http_method);
|
| /**
| * Disconnects from an MSN session.
| @@ -142,6 +169,29 @@ MsnSwitchBoard *msn_session_get_swboard(
| MsnSwitchBoard *msn_session_get_swboard(MsnSession *session,
| const char *username);
|
| +/**
| + * Sets an error for the MSN session.
| + *
| + * @param session The MSN session.
| + * @param error The error.
| + * @param info Extra information.
| + */
| +void msn_session_set_error(MsnSession *session, MsnErrorType error,
| + const char *info);
| +
| +/**
| + * Sets the current step in the login proccess.
| + *
| + * @param session The MSN session.
| + * @param step The current step.
| + */
| +void msn_session_set_login_step(MsnSession *session, MsnLoginStep step);
| +
| +/**
| + * Finish the login proccess.
| + *
| + * @param session The MSN session.
| + */
| void msn_session_finish_login(MsnSession *session);
|
| #endif /* _MSN_SESSION_H_ */
| ============================================================
| --- src/protocols/msn/slp.h 0cbf4f9e6b27d779fce798aa600e906b5d3efd25
| +++ src/protocols/msn/slp.h e82284a14294a4d7697fdc40503104f7ad07f4b4
| @@ -24,13 +24,6 @@
| #ifndef _MSN_SLP_H_
| #define _MSN_SLP_H_
|
| -/* #define MSN_DEBUG_MSG 1 */
| -/* #define MSN_DEBUG_SLPMSG 1 */
| -
| -/* #define MSN_DEBUG_SLP 1 */
| -/* #define MSN_DEBUG_SLP_VERBOSE 1 */
| -/* #define MSN_DEBUG_SLP_FILES 1 */
| -
| #include "slpcall.h"
|
| #include "ft.h"
| ============================================================
| --- src/protocols/msn/slpcall.c 202f415ff32ee1f76187122fc38fa5ce68798da0
| +++ src/protocols/msn/slpcall.c 3fa8f263568cf95b79f591f989ff94f94fda1e8e
| @@ -96,11 +96,15 @@ msn_slp_call_destroy(MsnSlpCall *slpcall
|
| g_return_if_fail(slpmsg != NULL);
|
| +#if 0
| gaim_debug_info("msn", "slpcall destroy: trying slp_msg (%p)\n",
| slpmsg);
| +#endif
|
| if (slpmsg->slpcall == slpcall)
| + {
| msn_slpmsg_destroy(slpmsg);
| + }
| }
|
| if (slpcall->end_cb != NULL)
| @@ -188,7 +192,7 @@ msn_slp_call_timeout(gpointer data)
| {
| MsnSlpCall *slpcall;
|
| - gaim_debug_info("msn", "slpcall timeout\n");
| + gaim_debug_info("msn", "slpcall timeout (%p)\n", slpcall);
|
| slpcall = data;
|
| ============================================================
| --- src/protocols/msn/slplink.c a4b1a2cc8527f507cfccb4831b39d27e2d7ad7d7
| +++ src/protocols/msn/slplink.c f0cdbc8162de40076e1672e43db94751e649477f
| @@ -213,15 +213,7 @@ msn_slplink_send_msg(MsnSlpLink *slplink
| slplink->swboard->slplink = slplink;
| }
|
| - if (!g_queue_is_empty(slplink->swboard->im_queue) ||
| - slplink->swboard->empty)
| - {
| - msn_switchboard_queue_msg(slplink->swboard, msg);
| - }
| - else
| - {
| - msn_switchboard_send_msg(slplink->swboard, msg);
| - }
| + msn_switchboard_send_msg(slplink->swboard, msg, TRUE);
| }
| }
|
| ============================================================
| --- src/protocols/msn/state.c 78d9483230de7cd6649427a2434a18667d0ebab6
| +++ src/protocols/msn/state.c 6deb541d3bf0af8cd5b316dda2c433d5047e23f6
| @@ -46,12 +46,13 @@ msn_change_status(MsnSession *session, M
| MsnObject *msnobj;
| const char *state_text;
|
| + g_return_if_fail(session != NULL);
| + g_return_if_fail(session->notification != NULL);
| +
| cmdproc = session->notification->cmdproc;
| user = session->user;
| state_text = msn_state_get_text(state);
|
| - g_return_if_fail(session != NULL);
| -
| msnobj = msn_user_get_object(user);
|
| if (msnobj == NULL)
| ============================================================
| --- src/protocols/msn/switchboard.c 4004ab1e171612e21a078a1c0cae403cf7455fcc
| +++ src/protocols/msn/switchboard.c ec1aac7b5e388761f710c5cde899f20f9c31c302
| @@ -35,8 +35,9 @@ static void msg_error_helper(MsnCmdProc
| MsnMsgErrorType error);
|
| /**************************************************************************
| - * Main stuff
| + * Main
| **************************************************************************/
| +
| MsnSwitchBoard *
| msn_switchboard_new(MsnSession *session)
| {
| @@ -48,10 +49,10 @@ msn_switchboard_new(MsnSession *session)
| swboard = g_new0(MsnSwitchBoard, 1);
|
| swboard->session = session;
| - swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB);
| + swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_SB);
| swboard->cmdproc = servconn->cmdproc;
|
| - swboard->im_queue = g_queue_new();
| + swboard->msg_queue = g_queue_new();
| swboard->empty = TRUE;
|
| swboard->cmdproc->data = swboard;
| @@ -71,17 +72,12 @@ msn_switchboard_destroy(MsnSwitchBoard *
|
| g_return_if_fail(swboard != NULL);
|
| - if (swboard->destroying)
| - return;
| -
| - swboard->destroying = TRUE;
| -
| /* If it linked us is because its looking for trouble */
| if (swboard->slplink != NULL)
| msn_slplink_destroy(swboard->slplink);
|
| /* Destroy the message queue */
| - while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL)
| + while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)
| {
| if (swboard->error != MSN_SB_ERROR_NONE)
| {
| @@ -92,7 +88,7 @@ msn_switchboard_destroy(MsnSwitchBoard *
| msn_message_unref(msg);
| }
|
| - g_queue_free(swboard->im_queue);
| + g_queue_free(swboard->msg_queue);
|
| for (l = swboard->ack_list; l != NULL; l = l->next)
| msn_message_unref(l->data);
| @@ -112,9 +108,18 @@ msn_switchboard_destroy(MsnSwitchBoard *
| session = swboard->session;
| session->switches = g_list_remove(session->switches, swboard);
|
| +#if 0
| + /* This should never happen or we are in trouble. */
| if (swboard->servconn != NULL)
| msn_servconn_destroy(swboard->servconn);
| +#endif
|
| + swboard->cmdproc->data = NULL;
| +
| + msn_servconn_set_disconnect_cb(swboard->servconn, NULL);
| +
| + msn_servconn_destroy(swboard->servconn);
| +
| g_free(swboard);
| }
|
| @@ -172,8 +177,9 @@ msn_switchboard_is_invited(MsnSwitchBoar
| }
|
| /**************************************************************************
| - * Utility functions
| + * Utility
| **************************************************************************/
| +
| static void
| send_clientcaps(MsnSwitchBoard *swboard)
| {
| @@ -184,7 +190,7 @@ send_clientcaps(MsnSwitchBoard *swboard)
| msn_message_set_flag(msg, 'U');
| msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO));
|
| - msn_switchboard_send_msg(swboard, msg);
| + msn_switchboard_send_msg(swboard, msg, TRUE);
|
| msn_message_destroy(msg);
| }
| @@ -421,8 +427,165 @@ msg_error_helper(MsnCmdProc *cmdproc, Ms
| }
|
| /**************************************************************************
| + * Message Stuff
| + **************************************************************************/
| +
| +/** Called when a message times out. */
| +static void
| +msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans)
| +{
| + MsnMessage *msg;
| +
| + msg = trans->data;
| +
| + msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT);
| +}
| +
| +/** Called when we receive an error of a message. */
| +static void
| +msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
| +{
| + msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN);
| +}
| +
| +#if 0
| +/** Called when we receive an ack of a special message. */
| +static void
| +msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd)
| +{
| + MsnMessage *msg;
| +
| + msg = cmd->trans->data;
| +
| + if (msg->ack_cb != NULL)
| + msg->ack_cb(msg->ack_data);
| +
| + msn_message_unref(msg);
| +}
| +
| +/** Called when we receive a nak of a special message. */
| +static void
| +msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd)
| +{
| + MsnMessage *msg;
| +
| + msg = cmd->trans->data;
| +
| + msn_message_unref(msg);
| +}
| +#endif
| +
| +static void
| +release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
| +{
| + MsnCmdProc *cmdproc;
| + MsnTransaction *trans;
| + char *payload;
| + gsize payload_len;
| +
| + g_return_if_fail(swboard != NULL);
| + g_return_if_fail(msg != NULL);
| +
| + cmdproc = swboard->cmdproc;
| +
| + payload = msn_message_gen_payload(msg, &payload_len);
| +
| + /* msn_message_show_readable(msg, "SB SEND", FALSE); */
| +
| + trans = msn_transaction_new(cmdproc, "MSG", "%c %d",
| + msn_message_get_flag(msg), payload_len);
| +
| + /* Data for callbacks */
| + msn_transaction_set_data(trans, msg);
| +
| + if (msg->type == MSN_MSG_TEXT)
| + {
| + msg->ack_ref = TRUE;
| + msn_message_ref(msg);
| + swboard->ack_list = g_list_append(swboard->ack_list, msg);
| + msn_transaction_set_timeout_cb(trans, msg_timeout);
| + }
| + else if (msg->type == MSN_MSG_SLP)
| + {
| + msg->ack_ref = TRUE;
| + msn_message_ref(msg);
| + swboard->ack_list = g_list_append(swboard->ack_list, msg);
| + msn_transaction_set_timeout_cb(trans, msg_timeout);
| +#if 0
| + if (msg->ack_cb != NULL)
| + {
| + msn_transaction_add_cb(trans, "ACK", msg_ack);
| + msn_transaction_add_cb(trans, "NAK", msg_nak);
| + }
| +#endif
| + }
| +
| + trans->payload = payload;
| + trans->payload_len = payload_len;
| +
| + msg->trans = trans;
| +
| + msn_cmdproc_send_trans(cmdproc, trans);
| +}
| +
| +static void
| +queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
| +{
| + g_return_if_fail(swboard != NULL);
| + g_return_if_fail(msg != NULL);
| +
| + gaim_debug_info("msn", "Appending message to queue.\n");
| +
| + g_queue_push_tail(swboard->msg_queue, msg);
| +
| + msn_message_ref(msg);
| +}
| +
| +static void
| +process_queue(MsnSwitchBoard *swboard)
| +{
| + MsnMessage *msg;
| +
| + g_return_if_fail(swboard != NULL);
| +
| + gaim_debug_info("msn", "Processing queue\n");
| +
| + while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)
| + {
| + gaim_debug_info("msn", "Sending message\n");
| + release_msg(swboard, msg);
| + msn_message_unref(msg);
| + }
| +}
| +
| +gboolean
| +msn_switchboard_can_send(MsnSwitchBoard *swboard)
| +{
| + g_return_val_if_fail(swboard != NULL, FALSE);
| +
| + if (swboard->empty || !g_queue_is_empty(swboard->msg_queue))
| + return FALSE;
| +
| + return TRUE;
| +}
| +
| +void
| +msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
| + gboolean queue)
| +{
| + g_return_if_fail(swboard != NULL);
| + g_return_if_fail(msg != NULL);
| +
| + if (msn_switchboard_can_send(swboard))
| + release_msg(swboard, msg);
| + else if (queue)
| + queue_msg(swboard, msg);
| +}
| +
| +/**************************************************************************
| * Switchboard Commands
| **************************************************************************/
| +
| static void
| ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -528,7 +691,7 @@ joi_cmd(MsnCmdProc *cmdproc, MsnCommand
|
| msn_switchboard_add_user(swboard, passport);
|
| - msn_switchboard_process_queue(swboard);
| + process_queue(swboard);
|
| if (!session->http_method)
| send_clientcaps(swboard);
| @@ -735,137 +898,6 @@ clientcaps_msg(MsnCmdProc *cmdproc, MsnM
| }
|
| /**************************************************************************
| - * Message stuff
| - **************************************************************************/
| -/** Called when a message times out. */
| -static void
| -msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans)
| -{
| - MsnMessage *msg;
| -
| - msg = trans->data;
| -
| - msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT);
| -}
| -
| -/** Called when we receive an error of a message. */
| -static void
| -msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
| -{
| - msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN);
| -}
| -
| -#if 0
| -/** Called when we receive an ack of a special message. */
| -static void
| -msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd)
| -{
| - MsnMessage *msg;
| -
| - msg = cmd->trans->data;
| -
| - if (msg->ack_cb != NULL)
| - msg->ack_cb(msg->ack_data);
| -
| - msn_message_unref(msg);
| -}
| -
| -/** Called when we receive a nak of a special message. */
| -static void
| -msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd)
| -{
| - MsnMessage *msg;
| -
| - msg = cmd->trans->data;
| -
| - msn_message_unref(msg);
| -}
| -#endif
| -
| -void
| -msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
| -{
| - MsnCmdProc *cmdproc;
| - MsnTransaction *trans;
| - char *payload;
| - gsize payload_len;
| -
| - g_return_if_fail(swboard != NULL);
| - g_return_if_fail(msg != NULL);
| -
| - cmdproc = swboard->cmdproc;
| -
| - payload = msn_message_gen_payload(msg, &payload_len);
| -
| - /* msn_message_show_readable(msg, "SB SEND", FALSE); */
| -
| - trans = msn_transaction_new(cmdproc, "MSG", "%c %d",
| - msn_message_get_flag(msg), payload_len);
| -
| - /* Data for callbacks */
| - msn_transaction_set_data(trans, msg);
| -
| - if (msg->type == MSN_MSG_TEXT)
| - {
| - msg->ack_ref = TRUE;
| - msn_message_ref(msg);
| - swboard->ack_list = g_list_append(swboard->ack_list, msg);
| - msn_transaction_set_timeout_cb(trans, msg_timeout);
| - }
| - else if (msg->type == MSN_MSG_SLP)
| - {
| - msg->ack_ref = TRUE;
| - msn_message_ref(msg);
| - swboard->ack_list = g_list_append(swboard->ack_list, msg);
| - msn_transaction_set_timeout_cb(trans, msg_timeout);
| -#if 0
| - if (msg->ack_cb != NULL)
| - {
| - msn_transaction_add_cb(trans, "ACK", msg_ack);
| - msn_transaction_add_cb(trans, "NAK", msg_nak);
| - }
| -#endif
| - }
| -
| - trans->payload = payload;
| - trans->payload_len = payload_len;
| -
| - msg->trans = trans;
| -
| - msn_cmdproc_send_trans(cmdproc, trans);
| -}
| -
| -void
| -msn_switchboard_queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
| -{
| - g_return_if_fail(swboard != NULL);
| - g_return_if_fail(msg != NULL);
| -
| - gaim_debug_info("msn", "Appending message to queue.\n");
| -
| - g_queue_push_tail(swboard->im_queue, msg);
| -
| - msn_message_ref(msg);
| -}
| -
| -void
| -msn_switchboard_process_queue(MsnSwitchBoard *swboard)
| -{
| - MsnMessage *msg;
| -
| - g_return_if_fail(swboard != NULL);
| -
| - gaim_debug_info("msn", "Processing queue\n");
| -
| - while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL)
| - {
| - gaim_debug_info("msn", "Sending message\n");
| - msn_switchboard_send_msg(swboard, msg);
| - msn_message_unref(msg);
| - }
| -}
| -
| -/**************************************************************************
| * Connect stuff
| **************************************************************************/
| static void
| @@ -878,8 +910,6 @@ connect_cb(MsnServConn *servconn)
| cmdproc = servconn->cmdproc;
| g_return_if_fail(cmdproc != NULL);
|
| - cmdproc->ready = TRUE;
| -
| account = cmdproc->session->account;
| swboard = cmdproc->data;
| g_return_if_fail(swboard != NULL);
| @@ -908,6 +938,8 @@ disconnect_cb(MsnServConn *servconn)
| swboard = servconn->cmdproc->data;
| g_return_if_fail(swboard != NULL);
|
| + msn_servconn_set_disconnect_cb(swboard->servconn, NULL);
| +
| msn_switchboard_destroy(swboard);
| }
|
| @@ -999,6 +1031,7 @@ msn_switchboard_request_add_user(MsnSwit
| /**************************************************************************
| * Create & Transfer stuff
| **************************************************************************/
| +
| static void
| got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd)
| {
| @@ -1058,23 +1091,29 @@ msn_switchboard_close(MsnSwitchBoard *sw
| {
| g_return_if_fail(swboard != NULL);
|
| - if (g_queue_is_empty(swboard->im_queue))
| + if (swboard->error != MSN_SB_ERROR_NONE)
| {
| + msn_switchboard_destroy(swboard);
| + }
| + else if (g_queue_is_empty(swboard->msg_queue) ||
| + !swboard->session->connected)
| + {
| MsnCmdProc *cmdproc;
| -
| cmdproc = swboard->cmdproc;
| -
| msn_cmdproc_send_quick(cmdproc, "OUT", NULL, NULL);
|
| msn_switchboard_destroy(swboard);
| }
| else
| + {
| swboard->closed = TRUE;
| + }
| }
|
| /**************************************************************************
| * Init stuff
| **************************************************************************/
| +
| void
| msn_switchboard_init(void)
| {
| ============================================================
| --- src/protocols/msn/switchboard.h 703f8caf7c5712c129461c018b51531234587c18
| +++ src/protocols/msn/switchboard.h 89eb281fe4fa362c65bda72f6ae55569fcc081db
| @@ -35,8 +35,8 @@ typedef struct _MsnSwitchBoard MsnSwitch
|
| #include "slplink.h"
|
| -/*
| - * A switchboard error
| +/**
| + * A switchboard error.
| */
| typedef enum
| {
| @@ -49,9 +49,10 @@ typedef enum
|
| } MsnSBErrorType;
|
| -/*
| - * A switchboard A place where a bunch of users send messages to the rest
| - * of the users.
| +/**
| + * A switchboard.
| + *
| + * A place where a bunch of users send messages to the rest of the users.
| */
| struct _MsnSwitchBoard
| {
| @@ -71,8 +72,6 @@ struct _MsnSwitchBoard
| users in it. */
| gboolean invited; /**< A flag that states if we were invited to the
| switchboard. */
| - gboolean destroying; /**< A flag that states if the switchboard is on
| - the process of being destroyed. */
| gboolean ready; /**< A flag that states if this switchboard is
| ready to be used. */
| gboolean closed; /**< A flag that states if the switchboard has
| @@ -84,7 +83,7 @@ struct _MsnSwitchBoard
|
| int chat_id;
|
| - GQueue *im_queue; /**< Queue of messages to send. */
| + GQueue *msg_queue; /**< Queue of messages to send. */
| GList *ack_list; /**< List of messages waiting for an ack. */
|
| MsnSBErrorType error; /**< The error that occurred in this switchboard
| @@ -197,10 +196,29 @@ void msn_switchboard_close(MsnSwitchBoar
| */
| void msn_switchboard_close(MsnSwitchBoard *swboard);
|
| -void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg);
| -void msn_switchboard_queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg);
| -void msn_switchboard_process_queue(MsnSwitchBoard *swboard);
| +/**
| + * Returns whether or not we currently can send a message through this
| + * switchboard.
| + *
| + * @param swboard The switchboard.
| + *
| + * @return @c TRUE if a message can be sent, @c FALSE otherwise.
| + */
| +gboolean msn_switchboard_can_send(MsnSwitchBoard *swboard);
|
| +/**
| + * Sends a message through this switchboard.
| + *
| + * @param swboard The switchboard.
| + * @param msg The message.
| + * @param queue A flag that states if we want this message to be queued (in
| + * the case it cannot currently be sent).
| + *
| + * @return @c TRUE if a message can be sent, @c FALSE otherwise.
| + */
| +void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
| + gboolean queue);
| +
| gboolean msn_switchboard_chat_leave(MsnSwitchBoard *swboard);
| gboolean msn_switchboard_chat_invite(MsnSwitchBoard *swboard, const char *who);
|
| @@ -208,13 +226,27 @@ void msn_switchboard_request_add_user(Ms
| void msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user);
|
| /**
| - * Processes application/x-msnmsgrp2p messages.
| + * Processes peer to peer messages.
| *
| * @param cmdproc The command processor.
| * @param msg The message.
| */
| void msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
| +
| +/**
| + * Processes emoticon messages.
| + *
| + * @param cmdproc The command processor.
| + * @param msg The message.
| + */
| void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
| +
| +/**
| + * Processes INVITE messages.
| + *
| + * @param cmdproc The command processor.
| + * @param msg The message.
| + */
| void msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
|
| #endif /* _MSN_SWITCHBOARD_H_ */
| ============================================================
| --- src/protocols/msn/transaction.c d42613fa99e4519b50f4d4ef146cbdd9936207a5
| +++ src/protocols/msn/transaction.c 870253681feed9e2fd32d99cbae62a5c2eb138ee
| @@ -112,6 +112,9 @@ msn_transaction_unqueue_cmd(MsnTransacti
| {
| MsnCommand *cmd;
|
| + if (!cmdproc->servconn->connected)
| + return;
| +
| gaim_debug_info("msn", "unqueueing command.\n");
| cmd = trans->pendent_cmd;
|
To get the patch for this revision, please do this:
mtn log --last 1 --diffs --from a8c2b9a0511a8917d2466c48e33f2c7db96065c8
More information about the Commits
mailing list