gaim/gaim

Patch 1093958 from Felipe Contreras. It fixes stuff.
oldstatus
2005-01-06, Stu Tomlinson
c7c2f12f48b7
Parents f729d24e9bc7
Children b82b4883c0db
Patch 1093958 from Felipe Contreras. It fixes stuff.

I also made some tweaks to make valgrind a bit happier.
--- a/ChangeLog Tue Jan 04 22:30:50 2005 -0500
+++ b/ChangeLog Thu Jan 06 21:48:07 2005 -0500
@@ -7,6 +7,7 @@
* 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
--- a/src/protocols/msn/cmdproc.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/cmdproc.c Thu Jan 06 21:48:07 2005 -0500
@@ -43,15 +43,13 @@
{
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 @@
{
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 @@
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 @@
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 @@
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 @@
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(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);
- }
-}
--- a/src/protocols/msn/cmdproc.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/cmdproc.h Thu Jan 06 21:48:07 2005 -0500
@@ -33,11 +33,6 @@
#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 @@
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 *cmdproc);
-void msn_cmdproc_show_error(MsnCmdProc *cmdproc, int error);
-
#endif /* _MSN_CMDPROC_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/msn/error.h Thu Jan 06 21:48:07 2005 -0500
@@ -0,0 +1,46 @@
+/**
+ * @file error.h Error functions
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _MSN_ERROR_H_
+#define _MSN_ERROR_H_
+
+#include "session.h"
+
+/**
+ * Returns the string representation of an error type.
+ *
+ * @param type The error type.
+ *
+ * @return The string representation of the error type.
+ */
+const char *msn_error_get_text(unsigned int type);
+
+/**
+ * Handles an error.
+ *
+ * @param session The current session.
+ * @param type The error type.
+ */
+void msn_error_handle(MsnSession *session, unsigned int type);
+
+#endif /* _MSN_ERROR_H_ */
--- a/src/protocols/msn/httpconn.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/httpconn.c Thu Jan 06 21:48:07 2005 -0500
@@ -28,7 +28,7 @@
typedef struct
{
MsnHttpConn *httpconn;
- char *buffer;
+ char *data;
size_t size;
} MsnHttpQueueData;
@@ -48,6 +48,8 @@
httpconn = g_new0(MsnHttpConn, 1);
+ gaim_debug_info("msn", "new httpconn (%p)\n", httpconn);
+
/* TODO: Remove this */
httpconn->session = servconn->session;
@@ -61,87 +63,55 @@
{
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;
-
- const char *names[] = { "Notification", "Switchboard" };
- const char *name;
-
- gc = gaim_account_get_connection(httpconn->servconn->session->account);
- name = names[httpconn->servconn->type];
+ char *buf;
+ size_t buf_len;
- 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;
- }
-
- if (httpconn->servconn->type == MSN_SERVER_NS)
- {
- gaim_connection_error(gc, tmp);
- }
- 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);
+ gaim_debug_misc("msn", "Writing HTTP (header): {%s}\n", header);
#endif
+ buf = g_strdup_printf("%s\r\n", header);
+ buf_len = strlen(buf);
+
+ if (body != NULL)
+ {
+ buf = g_realloc(buf, buf_len + body_len);
+ memcpy(buf + buf_len, body, body_len);
+ buf_len += body_len;
+ }
+
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;
}
@@ -149,8 +119,8 @@
void
msn_httpconn_poll(MsnHttpConn *httpconn)
{
+ char *header;
int r;
- char *temp;
g_return_if_fail(httpconn != NULL);
@@ -160,7 +130,7 @@
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 @@
"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 @@
else
{
gaim_debug_error("msn", "HTTP: Connection error\n");
- show_error(httpconn);
+ msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT);
}
}
@@ -257,7 +226,9 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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
-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 @@
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 @@
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 @@
"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,15 +485,9 @@
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(temp);
+ g_free(header);
if (r > 0)
{
@@ -541,7 +506,7 @@
{
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 @@
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 @@
if ((c = strchr(s, '\r')) == NULL)
{
- g_free(headers);
+ g_free(header);
return FALSE;
}
@@ -628,7 +593,7 @@
if (body_len != tmp_len)
{
- g_free(headers);
+ g_free(header);
#if 0
gaim_debug_warning("msn",
@@ -640,14 +605,16 @@
}
}
- 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 @@
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 @@
}
}
- g_free(headers);
+ g_free(header);
*ret_buf = body;
*ret_size = body_len;
--- a/src/protocols/msn/httpconn.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/httpconn.h Thu Jan 06 21:48:07 2005 -0500
@@ -28,101 +28,79 @@
#include "servconn.h"
+/**
+ * An HTTP Connection.
+ */
struct _MsnHttpConn
{
- MsnSession *session;
- MsnServConn *servconn;
-
- char *full_session_id;
- char *session_id;
+ MsnSession *session; /**< The MSN Session. */
+ MsnServConn *servconn; /**< The connection object. */
- int timer;
+ char *full_session_id; /**< The full session id. */
+ char *session_id; /**< The trimmed session id. */
- gboolean waiting_response;
- gboolean dirty; /**< The flag that states if we should poll. */
- gboolean connected;
+ int timer; /**< The timer for polling. */
- char *host;
- GList *queue;
-
- int fd;
- int inpa;
+ 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 *rx_buf;
- int rx_len;
+ char *host; /**< The HTTP gateway host. */
+ GList *queue; /**< The queue of data chunks to write. */
-#if 0
- GQueue *servconn_queue;
-#endif
+ int fd; /**< The connection's file descriptor. */
+ int inpa; /**< The connection's input handler. */
- gboolean virgin;
+ char *rx_buf; /**< The receive buffer. */
+ int rx_len; /**< The receive buffer lenght. */
};
+/**
+ * Creates a new HTTP connection object.
+ *
+ * @param servconn The connection object.
+ *
+ * @return The new object.
+ */
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.
- *
- * @param session The session.
- */
-void msn_http_session_init(MsnSession *session);
/**
- * 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);
-
-/**
- * Polls the server for data.
- *
- * @param servconn The server connection.
- */
-void msn_http_servconn_poll(MsnServConn *servconn);
+size_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size);
/**
- * Processes an incoming message and returns a string the rest of MSN
- * can deal with.
+ * Connects the HTTP connection object to a host.
*
- * @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.
+ * @param httpconn The HTTP connection object.
+ * @param host The host to connect to.
+ * @param port The port to connect to.
+ */
+gboolean msn_httpconn_connect(MsnHttpConn *httpconn,
+ const char *host, int port);
+
+/**
+ * Disconnects the HTTP connection object.
*
- * @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_ */
--- a/src/protocols/msn/msg.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/msg.c Thu Jan 06 21:48:07 2005 -0500
@@ -197,7 +197,8 @@
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");
--- a/src/protocols/msn/msn.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/msn.c Thu Jan 06 21:48:07 2005 -0500
@@ -631,22 +631,23 @@
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 @@
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,13 +754,7 @@
swboard = msn_session_find_swboard(session, who);
- if (swboard == NULL)
- return 0;
-
- if (swboard->empty)
- return 0;
-
- if (!g_queue_is_empty(swboard->im_queue))
+ if (swboard == NULL || !msn_switchboard_can_send(swboard))
return 0;
msg = msn_message_new(MSN_MSG_TYPING);
@@ -776,7 +764,7 @@
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 @@
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 @@
MsnCmdProc *cmdproc;
session = gc->proto_data;
+
cmdproc = session->notification->cmdproc;
if (!session->http_method)
--- a/src/protocols/msn/msn.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/msn.h Thu Jan 06 21:48:07 2005 -0500
@@ -45,8 +45,13 @@
#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
@@ -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"
--- a/src/protocols/msn/nexus.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/nexus.c Thu Jan 06 21:48:07 2005 -0500
@@ -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 @@
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 @@
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 @@
}
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 @@
}
}
- 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 @@
g_free(buffer);
}
+/**************************************************************************
+ * Connect
+ **************************************************************************/
+
static void
nexus_connect_cb(gpointer data, GaimSslConnection *gsc,
GaimInputCondition cond)
@@ -282,6 +312,8 @@
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,38 +364,6 @@
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)
{
--- a/src/protocols/msn/notification.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/notification.c Thu Jan 06 21:48:07 2005 -0500
@@ -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 @@
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 @@
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 @@
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 @@
/**************************************************************************
* Util
**************************************************************************/
+
static void
group_error_helper(MsnSession *session, const char *msg, int group_id, int error)
{
@@ -198,6 +191,7 @@
/**************************************************************************
* Login
**************************************************************************/
+
void
msn_got_login_params(MsnSession *session, const char *login_params)
{
@@ -205,6 +199,8 @@
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
-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 @@
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);
- msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
+ msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
- if (cmdproc->error)
- return;
-
- gaim_connection_update_progress(gc, _("Retrieving buddy list"),
- 7, MSN_CONNECT_STEPS);
+ msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
}
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,39 +258,9 @@
g_strfreev(elems);
- msn_nexus_connect(session->nexus);
-
- gaim_connection_update_progress(gc, _("Password sent"),
- 6, MSN_CONNECT_STEPS);
- }
- 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;
+ msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);
- 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);
+ msn_nexus_connect(session->nexus);
}
}
@@ -359,7 +289,8 @@
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 @@
/**************************************************************************
* 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 @@
/**************************************************************************
* Messages
**************************************************************************/
+
static void
msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
size_t len)
@@ -431,6 +365,7 @@
/**************************************************************************
* Challenges
**************************************************************************/
+
static void
chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
@@ -464,6 +399,7 @@
/**************************************************************************
* Buddy Lists
**************************************************************************/
+
static void
add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
@@ -873,22 +809,13 @@
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 @@
/**************************************************************************
* Misc commands
**************************************************************************/
+
static void
url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
@@ -1017,6 +945,7 @@
/**************************************************************************
* Switchboards
**************************************************************************/
+
static void
rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
@@ -1055,7 +984,8 @@
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 @@
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 @@
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 @@
/**************************************************************************
* Message Types
**************************************************************************/
+
static void
profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
@@ -1342,6 +1263,7 @@
/**************************************************************************
* Init
**************************************************************************/
+
void
msn_notification_init(void)
{
@@ -1359,7 +1281,6 @@
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); */
--- a/src/protocols/msn/notification.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/notification.h Thu Jan 06 21:48:07 2005 -0500
@@ -36,9 +36,6 @@
MsnCmdProc *cmdproc;
MsnServConn *servconn;
- gboolean destroying; /**< A flag that states if the notification is on
- the process of being destroyed. */
-
gboolean in_use;
};
--- a/src/protocols/msn/servconn.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/servconn.c Thu Jan 06 21:48:07 2005 -0500
@@ -27,6 +27,10 @@
static void read_cb(gpointer data, gint source, GaimInputCondition cond);
+/**************************************************************************
+ * Main
+ **************************************************************************/
+
MsnServConn *
msn_servconn_new(MsnSession *session, MsnServConnType type)
{
@@ -42,8 +46,7 @@
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 @@
return;
}
- if (servconn->destroying)
- return;
-
- servconn->destroying = TRUE;
-
if (servconn->connected)
msn_servconn_disconnect(servconn);
@@ -82,52 +80,83 @@
g_free(servconn);
}
-static void
-show_error(MsnServConn *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 *))
{
- GaimConnection *gc;
+ 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 @@
if (source > 0)
{
servconn->connected = TRUE;
- servconn->cmdproc->ready = TRUE;
/* Someone wants to know we connected. */
servconn->connect_cb(servconn);
@@ -155,8 +183,7 @@
}
else
{
- servconn->cmdproc->error = MSN_ERROR_CONNECT;
- show_error(servconn);
+ msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
}
}
@@ -188,7 +215,6 @@
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 @@
if (!servconn->connected)
{
+ /* We could not connect. */
if (servconn->disconnect_cb != NULL)
servconn->disconnect_cb(servconn);
@@ -224,7 +251,7 @@
if (servconn->session->http_method)
{
- /* Fake disconnection */
+ /* Fake disconnection. */
if (servconn->disconnect_cb != NULL)
servconn->disconnect_cb(servconn);
@@ -244,48 +271,11 @@
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 @@
{
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 @@
if (ret == -1)
{
- servconn->cmdproc->error = MSN_ERROR_WRITE;
- failed_io(servconn);
+ msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
}
return ret;
@@ -340,9 +331,7 @@
if (len <= 0)
{
- servconn->cmdproc->error = MSN_ERROR_READ;
-
- failed_io(servconn);
+ msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);
return;
}
--- a/src/protocols/msn/servconn.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/servconn.h Thu Jan 06 21:48:07 2005 -0500
@@ -32,21 +32,30 @@
#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 @@
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 *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_ */
--- a/src/protocols/msn/session.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/session.c Thu Jan 06 21:48:07 2005 -0500
@@ -28,8 +28,7 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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
+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;
--- a/src/protocols/msn/session.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/session.h Thu Jan 06 21:48:07 2005 -0500
@@ -40,6 +40,40 @@
#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,18 +82,16 @@
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;
-
- gboolean http_method;
- gint http_poll_timer;
+ MsnSync *sync;
MsnUserList *userlist;
MsnUserList *sync_userlist;
@@ -67,8 +99,9 @@
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 @@
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 @@
/**
* 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(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_ */
--- a/src/protocols/msn/slp.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/slp.h Thu Jan 06 21:48:07 2005 -0500
@@ -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"
--- a/src/protocols/msn/slpcall.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/slpcall.c Thu Jan 06 21:48:07 2005 -0500
@@ -96,11 +96,15 @@
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 @@
{
MsnSlpCall *slpcall;
- gaim_debug_info("msn", "slpcall timeout\n");
+ gaim_debug_info("msn", "slpcall timeout (%p)\n", slpcall);
slpcall = data;
--- a/src/protocols/msn/slplink.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/slplink.c Thu Jan 06 21:48:07 2005 -0500
@@ -213,15 +213,7 @@
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);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/msn/state.c Thu Jan 06 21:48:07 2005 -0500
@@ -0,0 +1,97 @@
+/**
+ * @file state.c State functions and definitions
+ *
+ * gaim
+ *
+ * Gaim is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "msn.h"
+#include "state.h"
+
+static const char *away_text[] =
+{
+ N_("Available"),
+ N_("Available"),
+ N_("Busy"),
+ N_("Idle"),
+ N_("Be Right Back"),
+ N_("Away From Computer"),
+ N_("On The Phone"),
+ N_("Out To Lunch"),
+ N_("Available"),
+ N_("Available")
+};
+
+void
+msn_change_status(MsnSession *session, MsnAwayType state)
+{
+ MsnCmdProc *cmdproc;
+ MsnUser *user;
+ 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);
+
+ msnobj = msn_user_get_object(user);
+
+ if (msnobj == NULL)
+ {
+ msn_cmdproc_send(cmdproc, "CHG", "%s %d", state_text,
+ MSN_CLIENT_ID);
+ }
+ else
+ {
+ char *msnobj_str;
+
+ msnobj_str = msn_object_to_string(msnobj);
+
+ msn_cmdproc_send(cmdproc, "CHG", "%s %d %s", state_text,
+ MSN_CLIENT_ID, gaim_url_encode(msnobj_str));
+
+ /*
+ * We need to set this just in case someone tries to set icon
+ * quickly on us - Justin
+ */
+ session->state = state;
+
+ g_free(msnobj_str);
+ }
+}
+
+const char *
+msn_away_get_text(MsnAwayType type)
+{
+ g_return_val_if_fail(type <= MSN_HIDDEN, NULL);
+
+ return _(away_text[type]);
+}
+
+const char *
+msn_state_get_text(MsnAwayType state)
+{
+ static char *status_text[] =
+ { "NLN", "NLN", "BSY", "IDL", "BRB", "AWY", "PHN", "LUN", "HDN", "HDN" };
+
+ return status_text[state];
+}
--- a/src/protocols/msn/switchboard.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/switchboard.c Thu Jan 06 21:48:07 2005 -0500
@@ -35,8 +35,9 @@
MsnMsgErrorType error);
/**************************************************************************
- * Main stuff
+ * Main
**************************************************************************/
+
MsnSwitchBoard *
msn_switchboard_new(MsnSession *session)
{
@@ -48,10 +49,10 @@
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 @@
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_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,8 +108,17 @@
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 @@
}
/**************************************************************************
- * Utility functions
+ * Utility
**************************************************************************/
+
static void
send_clientcaps(MsnSwitchBoard *swboard)
{
@@ -184,7 +190,7 @@
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 @@
}
/**************************************************************************
+ * 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 @@
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 @@
}
/**************************************************************************
- * 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 @@
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 @@
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 @@
/**************************************************************************
* Create & Transfer stuff
**************************************************************************/
+
static void
got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
@@ -1058,23 +1091,29 @@
{
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)
{
--- a/src/protocols/msn/switchboard.h Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/switchboard.h Thu Jan 06 21:48:07 2005 -0500
@@ -35,8 +35,8 @@
#include "slplink.h"
-/*
- * A switchboard error
+/**
+ * A switchboard error.
*/
typedef enum
{
@@ -49,9 +49,10 @@
} 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 @@
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 @@
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,9 +196,28 @@
*/
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(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_ */
--- a/src/protocols/msn/transaction.c Tue Jan 04 22:30:50 2005 -0500
+++ b/src/protocols/msn/transaction.c Thu Jan 06 21:48:07 2005 -0500
@@ -112,6 +112,9 @@
{
MsnCommand *cmd;
+ if (!cmdproc->servconn->connected)
+ return;
+
gaim_debug_info("msn", "unqueueing command.\n");
cmd = trans->pendent_cmd;