Index: protocols/msn/Makefile
===================================================================
--- protocols/msn/Makefile	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/Makefile	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -13,5 +13,5 @@
 
 # [SH] Program variables
-objects = msn.o msn_util.o ns.o sb.o soap.o tables.o
+objects = msn.o msn_util.o ns.o soap.o tables.o
 
 LFLAGS += -r
Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/msn.c	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -30,5 +30,4 @@
 int msn_chat_id;
 GSList *msn_connections;
-GSList *msn_switchboards;
 
 static char *set_eval_display_name(set_t *set, char *value);
@@ -48,5 +47,4 @@
 
 	set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
-	set_add(&acc->set, "switchboard_keepalives", "false", set_eval_bool, acc);
 
 	acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
@@ -80,10 +78,10 @@
 	md->away_state = msn_away_state_list;
 	md->domaintree = g_tree_new(msn_domaintree_cmp);
-	md->ns->fd = -1;
+	md->fd = -1;
 
 	msn_connections = g_slist_prepend(msn_connections, ic);
 
 	imcb_log(ic, "Connecting");
-	msn_ns_connect(ic, md->ns, server,
+	msn_ns_connect(ic, server,
 	               set_getint(&ic->acc->set, "port"));
 }
@@ -96,9 +94,5 @@
 
 	if (md) {
-		msn_ns_close(md->ns);
-
-		while (md->switchboards) {
-			msn_sb_destroy(md->switchboards->data);
-		}
+		msn_ns_close(md);
 
 		msn_msgq_purge(ic, &md->msgq);
@@ -154,27 +148,13 @@
 {
 	struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
-	struct msn_buddy_data *bd = bu ? bu->data : NULL;
-	struct msn_switchboard *sb;
 
 #ifdef DEBUG
 	if (strcmp(who, "raw") == 0) {
 		msn_ns_write(ic, -1, "%s\r\n", message);
-	} else
+		return 0;
+	}
 #endif
-	if (bd && bd->flags & MSN_BUDDY_FED) {
-		msn_ns_sendmessage(ic, bu, message);
-	} else if ((sb = msn_sb_by_handle(ic, who))) {
-		return(msn_sb_sendmessage(sb, message));
-	} else {
-		struct msn_message *m;
-
-		/* Create a message. We have to arrange a usable switchboard, and send the message later. */
-		m = g_new0(struct msn_message, 1);
-		m->who = g_strdup(who);
-		m->text = g_strdup(message);
-
-		return msn_sb_write_msg(ic, m);
-	}
-
+
+	msn_ns_sendmessage(ic, bu, message);
 	return(0);
 }
@@ -198,5 +178,5 @@
 static void msn_set_away(struct im_connection *ic, char *state, char *message)
 {
-	char *uux;
+	//char *uux;
 	struct msn_data *md = ic->proto_data;
 
@@ -258,51 +238,22 @@
 static void msn_chat_msg(struct groupchat *c, char *message, int flags)
 {
-	struct msn_switchboard *sb = msn_sb_by_chat(c);
-
-	if (sb) {
-		msn_sb_sendmessage(sb, message);
-	}
-	/* FIXME: Error handling (although this can't happen unless something's
-	   already severely broken) disappeared here! */
+	/* TODO: groupchats*/
 }
 
 static void msn_chat_invite(struct groupchat *c, char *who, char *message)
 {
-	struct msn_switchboard *sb = msn_sb_by_chat(c);
-
-	if (sb) {
-		msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, who);
-	}
+	/* TODO: groupchats*/
 }
 
 static void msn_chat_leave(struct groupchat *c)
 {
-	struct msn_switchboard *sb = msn_sb_by_chat(c);
-
-	if (sb) {
-		msn_sb_write(sb, "OUT\r\n");
-	}
+	/* TODO: groupchats*/
 }
 
 static struct groupchat *msn_chat_with(struct im_connection *ic, char *who)
 {
-	struct msn_switchboard *sb;
+	/* TODO: groupchats*/
 	struct groupchat *c = imcb_chat_new(ic, who);
-
-	if ((sb = msn_sb_by_handle(ic, who))) {
-		debug("Converting existing switchboard to %s to a groupchat", who);
-		return msn_sb_to_chat(sb);
-	} else {
-		struct msn_message *m;
-
-		/* Create a magic message. This is quite hackish, but who cares? :-P */
-		m = g_new0(struct msn_message, 1);
-		m->who = g_strdup(who);
-		m->text = g_strdup(GROUPCHAT_SWITCHBOARD_MESSAGE);
-
-		msn_sb_write_msg(ic, m);
-
-		return c;
-	}
+	return c;
 }
 
@@ -324,12 +275,5 @@
 static void msn_add_deny(struct im_connection *ic, char *who)
 {
-	struct msn_switchboard *sb;
-
 	msn_buddy_list_add(ic, MSN_BUDDY_BL, who, who, NULL);
-
-	/* If there's still a conversation with this person, close it. */
-	if ((sb = msn_sb_by_handle(ic, who))) {
-		msn_sb_destroy(sb);
-	}
 }
 
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/msn.h	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -32,5 +32,4 @@
 #define NUDGE_MESSAGE "\r\r\rSHAKE THAT THING\r\r\r"
 #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r"
-#define SB_KEEPALIVE_MESSAGE "\r\r\rDONT HANG UP ON ME!\r\r\r"
 
 #ifdef DEBUG_MSN
@@ -68,9 +67,18 @@
 #define MSN_CAP2        0x0000
 
-#define MSN_MESSAGE_HEADERS "MIME-Version: 1.0\r\n" \
+#define MSN_MESSAGE_HEADERS \
+	"Routing: 1.0\r\n" \
+	"To: 1:%s\r\n" \
+	"From: 1:%s;epid={%s}\r\n" \
+	"\r\n" \
+	"Reliability: 1.0\r\n" \
+	"\r\n" \
+	"Messaging: 2.0\r\n" \
+	"Message-Type: Text\r\n" \
+	"Content-Length: %zd\r\n" \
 	"Content-Type: text/plain; charset=UTF-8\r\n" \
-	"User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \
-	"X-MMS-IM-Format: FN=MS%20Shell%20Dlg; EF=; CO=0; CS=0; PF=0\r\n" \
-	"\r\n"
+	"X-MMS-IM-Format: FN=Segoe%%20UI; EF=; CO=0; CS=0; PF=0\r\n" \
+	"\r\n" \
+	"%s"
 
 #define MSN_TYPING_HEADERS "MIME-Version: 1.0\r\n" \
@@ -84,8 +92,4 @@
 	"ID: 1\r\n" \
 	"\r\n"
-
-#define MSN_SB_KEEPALIVE_HEADERS "MIME-Version: 1.0\r\n" \
-	"Content-Type: text/x-ping\r\n" \
-	"\r\n\r\n"
 
 #define PROFILE_URL "http://members.msn.com/"
@@ -99,5 +103,5 @@
 } msn_flags_t;
 
-struct msn_handler_data {
+struct msn_data {
 	int fd, inpa;
 	int rxlen;
@@ -107,15 +111,6 @@
 	char *cmd_text;
 
-	/* Either ic or sb */
-	gpointer data;
-
-	int (*exec_command) (struct msn_handler_data *handler, char **cmd, int count);
-	int (*exec_message) (struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int count);
-};
-
-struct msn_data {
 	struct im_connection *ic;
 
-	struct msn_handler_data ns[1];
 	msn_flags_t flags;
 
@@ -126,7 +121,4 @@
 
 	GSList *msgq, *grpq, *soapq;
-	GSList *switchboards;
-	int sb_failures;
-	time_t first_sb_failure;
 
 	const struct msn_away_state *away_state;
@@ -139,24 +131,4 @@
 	GTree *domaintree;
 	int adl_todo;
-};
-
-struct msn_switchboard {
-	struct im_connection *ic;
-
-	/* The following two are also in the handler. TODO: Clean up. */
-	int fd;
-	gint inp;
-	struct msn_handler_data *handler;
-	gint keepalive;
-
-	int trId;
-	int ready;
-
-	int session;
-	char *key;
-
-	GSList *msgq;
-	char *who;
-	struct groupchat *chat;
 };
 
@@ -205,6 +177,4 @@
 #define STATUS_FATAL            1
 #define STATUS_SB_FATAL         2
-#define STATUS_SB_IM_SPARE      4       /* Make one-to-one conversation switchboard available again, invite failed. */
-#define STATUS_SB_CHAT_SPARE    8       /* Same, but also for groupchats (not used yet). */
 
 extern int msn_chat_id;
@@ -218,10 +188,9 @@
    before doing *anything* else. */
 extern GSList *msn_connections;
-extern GSList *msn_switchboards;
 
 /* ns.c */
 int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...) G_GNUC_PRINTF(3, 4);
-gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port);
-void msn_ns_close(struct msn_handler_data *handler);
+gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port);
+void msn_ns_close(struct msn_data *handler);
 void msn_auth_got_passport_token(struct im_connection *ic, const char *token, const char *error);
 void msn_auth_got_contact_list(struct im_connection *ic);
@@ -229,4 +198,6 @@
 int msn_ns_sendmessage(struct im_connection *ic, struct bee_user *bu, const char *text);
 void msn_ns_oim_send_queue(struct im_connection *ic, GSList **msgq);
+int msn_ns_command(struct msn_data *md, char **cmd, int num_parts);
+int msn_ns_message(struct msn_data *md, char *msg, int msglen, char **cmd, int num_parts);
 
 /* msn_util.c */
@@ -236,5 +207,5 @@
 void msn_buddy_ask(bee_user_t *bu);
 char **msn_linesplit(char *line);
-int msn_handler(struct msn_handler_data *h);
+int msn_handler(struct msn_data *h);
 void msn_msgq_purge(struct im_connection *ic, GSList **list);
 char *msn_p11_challenge(char *challenge);
@@ -251,17 +222,3 @@
 const struct msn_status_code *msn_status_by_number(int number);
 
-/* sb.c */
-int msn_sb_write(struct msn_switchboard *sb, const char *fmt, ...) G_GNUC_PRINTF(2, 3);;
-struct msn_switchboard *msn_sb_create(struct im_connection *ic, char *host, int port, char *key, int session);
-struct msn_switchboard *msn_sb_by_handle(struct im_connection *ic, const char *handle);
-struct msn_switchboard *msn_sb_by_chat(struct groupchat *c);
-struct msn_switchboard *msn_sb_spare(struct im_connection *ic);
-int msn_sb_sendmessage(struct msn_switchboard *sb, char *text);
-struct groupchat *msn_sb_to_chat(struct msn_switchboard *sb);
-void msn_sb_destroy(struct msn_switchboard *sb);
-gboolean msn_sb_connected(gpointer data, gint source, b_input_condition cond);
-int msn_sb_write_msg(struct im_connection *ic, struct msn_message *m);
-void msn_sb_start_keepalives(struct msn_switchboard *sb, gboolean initial);
-void msn_sb_stop_keepalives(struct msn_switchboard *sb);
-
 #endif //_MSN_H
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/msn_util.c	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -266,6 +266,7 @@
                    1: OK */
 
-int msn_handler(struct msn_handler_data *h)
-{
+int msn_handler(struct msn_data *h)
+{
+	struct im_connection *ic = h->ic;
 	int st;
 
@@ -299,5 +300,5 @@
 						;
 					}
-					st = h->exec_command(h, cmd, count);
+					st = msn_ns_command(h, cmd, count);
 					g_free(cmd_text);
 
@@ -340,5 +341,5 @@
 			}
 
-			st = h->exec_message(h, msg, h->msglen, cmd, count);
+			st = msn_ns_message(h, msg, h->msglen, cmd, count);
 			g_free(msg);
 			g_free(h->cmd_text);
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/ns.c	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -35,6 +35,4 @@
 static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond);
 static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond);
-static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts);
-static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts);
 
 static void msn_ns_send_adl_start(struct im_connection *ic);
@@ -54,5 +52,5 @@
 
 	if (fd < 0) {
-		fd = md->ns->fd;
+		fd = md->fd;
 	}
 
@@ -73,13 +71,12 @@
 }
 
-gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port)
-{
+gboolean msn_ns_connect(struct im_connection *ic, const char *host, int port)
+{
+	struct msn_data *handler = ic->proto_data;
+
 	if (handler->fd >= 0) {
 		closesocket(handler->fd);
 	}
 
-	handler->exec_command = msn_ns_command;
-	handler->exec_message = msn_ns_message;
-	handler->data = ic;
 	handler->fd = proxy_connect(host, port, msn_ns_connected, handler);
 	if (handler->fd < 0) {
@@ -94,13 +91,7 @@
 static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond)
 {
-	struct msn_handler_data *handler = data;
-	struct im_connection *ic = handler->data;
-	struct msn_data *md;
-
-	if (!g_slist_find(msn_connections, ic)) {
-		return FALSE;
-	}
-
-	md = ic->proto_data;
+	struct msn_data *md = data;
+	struct msn_data *handler = md;
+	struct im_connection *ic = md->ic;
 
 	if (source == -1) {
@@ -137,5 +128,5 @@
 }
 
-void msn_ns_close(struct msn_handler_data *handler)
+void msn_ns_close(struct msn_data *handler)
 {
 	if (handler->fd >= 0) {
@@ -155,6 +146,6 @@
 static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond)
 {
-	struct msn_handler_data *handler = data;
-	struct im_connection *ic = handler->data;
+	struct msn_data *handler = data;
+	struct im_connection *ic = handler->ic;
 
 	if (msn_handler(handler) == -1) {  /* Don't do this on ret == 0, it's already done then. */
@@ -168,8 +159,8 @@
 }
 
-static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts)
-{
-	struct im_connection *ic = handler->data;
-	struct msn_data *md = ic->proto_data;
+int msn_ns_command(struct msn_data *handler, char **cmd, int num_parts)
+{
+	struct im_connection *ic = handler->ic;
+	struct msn_data *md = handler;
 
 	if (num_parts == 0) {
@@ -209,52 +200,5 @@
 
 			imcb_log(ic, "Transferring to other server");
-			return msn_ns_connect(ic, handler, server, port);
-		} else if (num_parts >= 6 && strcmp(cmd[2], "SB") == 0) {
-			struct msn_switchboard *sb;
-
-			server = strchr(cmd[3], ':');
-			if (!server) {
-				imcb_error(ic, "Syntax error");
-				imc_logout(ic, TRUE);
-				return(0);
-			}
-			*server = 0;
-			port = atoi(server + 1);
-			server = cmd[3];
-
-			if (strcmp(cmd[4], "CKI") != 0) {
-				imcb_error(ic, "Unknown authentication method for switchboard");
-				imc_logout(ic, TRUE);
-				return(0);
-			}
-
-			debug("Connecting to a new switchboard with key %s", cmd[5]);
-
-			if ((sb = msn_sb_create(ic, server, port, cmd[5], MSN_SB_NEW)) == NULL) {
-				/* Although this isn't strictly fatal for the NS connection, it's
-				   definitely something serious (we ran out of file descriptors?). */
-				imcb_error(ic, "Could not create new switchboard");
-				imc_logout(ic, TRUE);
-				return(0);
-			}
-
-			if (md->msgq) {
-				struct msn_message *m = md->msgq->data;
-				GSList *l;
-
-				sb->who = g_strdup(m->who);
-
-				/* Move all the messages to the first user in the message
-				   queue to the switchboard message queue. */
-				l = md->msgq;
-				while (l) {
-					m = l->data;
-					l = l->next;
-					if (strcmp(m->who, sb->who) == 0) {
-						sb->msgq = g_slist_append(sb->msgq, m);
-						md->msgq = g_slist_remove(md->msgq, m);
-					}
-				}
-			}
+			return msn_ns_connect(ic, server, port);
 		} else {
 			imcb_error(ic, "Syntax error");
@@ -361,5 +305,4 @@
 		                  st->name, NULL);
 
-		msn_sb_stop_keepalives(msn_sb_by_handle(ic, handle));
 	} else if (strcmp(cmd[0], "FLN") == 0) {
 		const char *handle;
@@ -371,45 +314,4 @@
 		handle = msn_normalize_handle(cmd[1]);
 		imcb_buddy_status(ic, handle, 0, NULL, NULL);
-		msn_sb_start_keepalives(msn_sb_by_handle(ic, handle), TRUE);
-	} else if (strcmp(cmd[0], "RNG") == 0) {
-		struct msn_switchboard *sb;
-		char *server;
-		int session, port;
-
-		if (num_parts < 7) {
-			imcb_error(ic, "Syntax error");
-			imc_logout(ic, TRUE);
-			return(0);
-		}
-
-		session = atoi(cmd[1]);
-
-		server = strchr(cmd[2], ':');
-		if (!server) {
-			imcb_error(ic, "Syntax error");
-			imc_logout(ic, TRUE);
-			return(0);
-		}
-		*server = 0;
-		port = atoi(server + 1);
-		server = cmd[2];
-
-		if (strcmp(cmd[3], "CKI") != 0) {
-			imcb_error(ic, "Unknown authentication method for switchboard");
-			imc_logout(ic, TRUE);
-			return(0);
-		}
-
-		debug("Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4]);
-
-		if ((sb = msn_sb_create(ic, server, port, cmd[4], session)) == NULL) {
-			/* Although this isn't strictly fatal for the NS connection, it's
-			   definitely something serious (we ran out of file descriptors?). */
-			imcb_error(ic, "Could not create new switchboard");
-			imc_logout(ic, TRUE);
-			return(0);
-		} else {
-			sb->who = g_strdup(msn_normalize_handle(cmd[5]));
-		}
 	} else if (strcmp(cmd[0], "OUT") == 0) {
 		int allow_reconnect = TRUE;
@@ -494,5 +396,5 @@
 			handler->msglen = atoi(cmd[1]);
 		}
-	} else if (strcmp(cmd[0], "NFY") == 0) {
+	} else if ((strcmp(cmd[0], "NFY") == 0) || (strcmp(cmd[0], "SDG") == 0)) {
 		if (num_parts >= 3) {
 			handler->msglen = atoi(cmd[2]);
@@ -526,7 +428,7 @@
 }
 
-static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts)
-{
-	struct im_connection *ic = handler->data;
+int msn_ns_message(struct msn_data *handler, char *msg, int msglen, char **cmd, int num_parts)
+{
+	struct im_connection *ic = handler->ic;
 	char *body;
 	int blen = 0;
@@ -717,30 +619,27 @@
 			}
 		}
-	} else if (strcmp(cmd[0], "UBM") == 0) {
-		/* This one will give us msgs from federated networks. Technically
-		   it should also get us offline messages, but I don't know how
-		   I can signal MSN servers to use it. */
-		char *ct, *handle;
-
-		if (strcmp(cmd[1], ic->acc->user) == 0) {
-			/* With MPOP, you'll get copies of your own msgs from other
-			   sessions. Discard those at least for now. */
-			return 1;
-		}
-
-		ct = get_rfc822_header(msg, "Content-Type", msglen);
-		if (strncmp(ct, "text/plain", 10) != 0) {
-			/* Typing notification or something? */
-			g_free(ct);
-			return 1;
-		}
-		if (strcmp(cmd[2], "1") != 0) {
-			handle = g_strdup_printf("%s:%s", cmd[2], cmd[1]);
-		} else {
-			handle = g_strdup(cmd[1]);
-		}
-
-		imcb_buddy_msg(ic, handle, body, 0, 0);
-		g_free(handle);
+	} else if (strcmp(cmd[0], "SDG") == 0) {
+		char **parts = g_strsplit(msg, "\r\n\r\n", 4);
+		char *from = NULL;
+		char *mt = NULL;
+		char *who = NULL;
+		char *s = NULL;
+
+		if ((from = get_rfc822_header(parts[0], "From", 0)) &&
+		    (mt = get_rfc822_header(parts[2], "Message-Type", 0)) &&
+		    (s = strchr(from, ';'))) {
+
+			who = g_strndup(from + 2, s - from - 2);
+
+			if (strcmp(mt, "Control/Typing") == 0) {
+				imcb_buddy_typing(ic, who, OPT_TYPING);
+			} else if (strcmp(mt, "Text") == 0) {
+				imcb_buddy_msg(ic, who, parts[3], 0, 0);
+			}
+		}
+		g_free(from);
+		g_free(mt);
+		g_free(who);
+		return 1;
 	}
 
@@ -893,9 +792,10 @@
 }
 
+// TODO: typing notifications, nudges lol, etc
 int msn_ns_sendmessage(struct im_connection *ic, bee_user_t *bu, const char *text)
 {
 	struct msn_data *md = ic->proto_data;
-	int type = 0;
-	char *buf, *handle;
+	int retval = 0;
+	char *buf;
 
 	if (strncmp(text, "\r\r\r", 3) == 0) {
@@ -905,25 +805,8 @@
 	}
 
-	/* This might be a federated contact. Get its network number,
-	   prefixed to bu->handle with a colon. Default is 1. */
-	for (handle = bu->handle; g_ascii_isdigit(*handle); handle++) {
-		type = type * 10 + *handle - '0';
-	}
-	if (*handle == ':') {
-		handle++;
-	} else {
-		type = 1;
-	}
-
-	buf = g_strdup_printf("%s%s", MSN_MESSAGE_HEADERS, text);
-
-	if (msn_ns_write(ic, -1, "UUM %d %s %d %d %zd\r\n%s",
-	                 ++md->trId, handle, type,
-	                 1,          /* type == IM (not nudge/typing) */
-	                 strlen(buf), buf)) {
-		return 1;
-	} else {
-		return 0;
-	}
+	buf = g_strdup_printf(MSN_MESSAGE_HEADERS, bu->handle, ic->acc->user, md->uuid, strlen(text), text);
+	retval = msn_ns_write(ic, -1, "SDG %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
+	g_free(buf);
+	return retval;
 }
 
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ 	(revision )
@@ -1,712 +1,0 @@
-/********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2012 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* MSN module - Switchboard server callbacks and utilities              */
-
-/*
-  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 with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
-  Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#include <ctype.h>
-#include "nogaim.h"
-#include "msn.h"
-#include "md5.h"
-#include "soap.h"
-
-static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond);
-static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts);
-static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts);
-
-int msn_sb_write(struct msn_switchboard *sb, const char *fmt, ...)
-{
-	va_list params;
-	char *out;
-	size_t len;
-	int st;
-
-	va_start(params, fmt);
-	out = g_strdup_vprintf(fmt, params);
-	va_end(params);
-
-	if (getenv("BITLBEE_DEBUG")) {
-		fprintf(stderr, "->SB%d:%s\n", sb->fd, out);
-	}
-
-	len = strlen(out);
-	st = write(sb->fd, out, len);
-	g_free(out);
-	if (st != len) {
-		msn_sb_destroy(sb);
-		return 0;
-	}
-
-	return 1;
-}
-
-int msn_sb_write_msg(struct im_connection *ic, struct msn_message *m)
-{
-	struct msn_data *md = ic->proto_data;
-	struct msn_switchboard *sb;
-
-	/* FIXME: *CHECK* the reliability of using spare sb's! */
-	if ((sb = msn_sb_spare(ic))) {
-		debug("Trying to use a spare switchboard to message %s", m->who);
-
-		sb->who = g_strdup(m->who);
-		if (msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, m->who)) {
-			/* He/She should join the switchboard soon, let's queue the message. */
-			sb->msgq = g_slist_append(sb->msgq, m);
-			return(1);
-		}
-	}
-
-	debug("Creating a new switchboard to message %s", m->who);
-
-	/* If we reach this line, there was no spare switchboard, so let's make one. */
-	if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) {
-		g_free(m->who);
-		g_free(m->text);
-		g_free(m);
-
-		return(0);
-	}
-
-	/* And queue the message to md. We'll pick it up when the switchboard comes up. */
-	md->msgq = g_slist_append(md->msgq, m);
-
-	/* FIXME: If the switchboard creation fails, the message will not be sent. */
-
-	return(1);
-}
-
-struct msn_switchboard *msn_sb_create(struct im_connection *ic, char *host, int port, char *key, int session)
-{
-	struct msn_data *md = ic->proto_data;
-	struct msn_switchboard *sb = g_new0(struct msn_switchboard, 1);
-
-	sb->fd = proxy_connect(host, port, msn_sb_connected, sb);
-	if (sb->fd < 0) {
-		g_free(sb);
-		return(NULL);
-	}
-
-	sb->ic = ic;
-	sb->key = g_strdup(key);
-	sb->session = session;
-
-	msn_switchboards = g_slist_append(msn_switchboards, sb);
-	md->switchboards = g_slist_append(md->switchboards, sb);
-
-	return(sb);
-}
-
-struct msn_switchboard *msn_sb_by_handle(struct im_connection *ic, const char *handle)
-{
-	struct msn_data *md = ic->proto_data;
-	struct msn_switchboard *sb;
-	GSList *l;
-
-	for (l = md->switchboards; l; l = l->next) {
-		sb = l->data;
-		if (sb->who && strcmp(sb->who, handle) == 0) {
-			return(sb);
-		}
-	}
-
-	return(NULL);
-}
-
-struct msn_switchboard *msn_sb_by_chat(struct groupchat *c)
-{
-	struct msn_data *md = c->ic->proto_data;
-	struct msn_switchboard *sb;
-	GSList *l;
-
-	for (l = md->switchboards; l; l = l->next) {
-		sb = l->data;
-		if (sb->chat == c) {
-			return(sb);
-		}
-	}
-
-	return(NULL);
-}
-
-struct msn_switchboard *msn_sb_spare(struct im_connection *ic)
-{
-	struct msn_data *md = ic->proto_data;
-	struct msn_switchboard *sb;
-	GSList *l;
-
-	for (l = md->switchboards; l; l = l->next) {
-		sb = l->data;
-		if (!sb->who && !sb->chat) {
-			return(sb);
-		}
-	}
-
-	return(NULL);
-}
-
-int msn_sb_sendmessage(struct msn_switchboard *sb, char *text)
-{
-	if (sb->ready) {
-		char *buf;
-		int i, j;
-
-		/* Build the message. Convert LF to CR-LF for normal messages. */
-		if (strcmp(text, TYPING_NOTIFICATION_MESSAGE) == 0) {
-			i = strlen(MSN_TYPING_HEADERS) + strlen(sb->ic->acc->user);
-			buf = g_new0(char, i);
-			i = g_snprintf(buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user);
-		} else if (strcmp(text, NUDGE_MESSAGE) == 0) {
-			buf = g_strdup(MSN_NUDGE_HEADERS);
-			i = strlen(buf);
-		} else if (strcmp(text, SB_KEEPALIVE_MESSAGE) == 0) {
-			buf = g_strdup(MSN_SB_KEEPALIVE_HEADERS);
-			i = strlen(buf);
-		} else {
-			buf = g_new0(char, sizeof(MSN_MESSAGE_HEADERS) + strlen(text) * 2 + 1);
-			i = strlen(MSN_MESSAGE_HEADERS);
-
-			strcpy(buf, MSN_MESSAGE_HEADERS);
-			for (j = 0; text[j]; j++) {
-				if (text[j] == '\n') {
-					buf[i++] = '\r';
-				}
-
-				buf[i++] = text[j];
-			}
-		}
-
-		/* Build the final packet (MSG command + the message). */
-		if (msn_sb_write(sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf)) {
-			g_free(buf);
-			return 1;
-		} else {
-			g_free(buf);
-			return 0;
-		}
-	} else if (sb->who) {
-		struct msn_message *m = g_new0(struct msn_message, 1);
-
-		m->who = g_strdup("");
-		m->text = g_strdup(text);
-		sb->msgq = g_slist_append(sb->msgq, m);
-
-		return(1);
-	} else {
-		return(0);
-	}
-}
-
-struct groupchat *msn_sb_to_chat(struct msn_switchboard *sb)
-{
-	struct im_connection *ic = sb->ic;
-	struct groupchat *c = NULL;
-	char buf[1024];
-
-	/* Create the groupchat structure. */
-	g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session);
-	if (sb->who) {
-		c = bee_chat_by_title(ic->bee, ic, sb->who);
-	}
-	if (c && !msn_sb_by_chat(c)) {
-		sb->chat = c;
-	} else {
-		sb->chat = imcb_chat_new(ic, buf);
-	}
-
-	/* Populate the channel. */
-	if (sb->who) {
-		imcb_chat_add_buddy(sb->chat, sb->who);
-	}
-	imcb_chat_add_buddy(sb->chat, ic->acc->user);
-
-	/* And make sure the switchboard doesn't look like a regular chat anymore. */
-	if (sb->who) {
-		g_free(sb->who);
-		sb->who = NULL;
-	}
-
-	return sb->chat;
-}
-
-void msn_sb_destroy(struct msn_switchboard *sb)
-{
-	struct im_connection *ic = sb->ic;
-	struct msn_data *md = ic->proto_data;
-
-	debug("Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "");
-
-	msn_msgq_purge(ic, &sb->msgq);
-	msn_sb_stop_keepalives(sb);
-
-	if (sb->key) {
-		g_free(sb->key);
-	}
-	if (sb->who) {
-		g_free(sb->who);
-	}
-
-	if (sb->chat) {
-		imcb_chat_free(sb->chat);
-	}
-
-	if (sb->handler) {
-		if (sb->handler->rxq) {
-			g_free(sb->handler->rxq);
-		}
-		if (sb->handler->cmd_text) {
-			g_free(sb->handler->cmd_text);
-		}
-		g_free(sb->handler);
-	}
-
-	if (sb->inp) {
-		b_event_remove(sb->inp);
-	}
-	closesocket(sb->fd);
-
-	msn_switchboards = g_slist_remove(msn_switchboards, sb);
-	md->switchboards = g_slist_remove(md->switchboards, sb);
-	g_free(sb);
-}
-
-gboolean msn_sb_connected(gpointer data, gint source, b_input_condition cond)
-{
-	struct msn_switchboard *sb = data;
-	struct im_connection *ic;
-	struct msn_data *md;
-	char buf[1024];
-
-	/* Are we still alive? */
-	if (!g_slist_find(msn_switchboards, sb)) {
-		return FALSE;
-	}
-
-	ic = sb->ic;
-	md = ic->proto_data;
-
-	if (source != sb->fd) {
-		debug("Error %d while connecting to switchboard server", 1);
-		msn_sb_destroy(sb);
-		return FALSE;
-	}
-
-	/* Prepare the callback */
-	sb->handler = g_new0(struct msn_handler_data, 1);
-	sb->handler->fd = sb->fd;
-	sb->handler->rxq = g_new0(char, 1);
-	sb->handler->data = sb;
-	sb->handler->exec_command = msn_sb_command;
-	sb->handler->exec_message = msn_sb_message;
-
-	if (sb->session == MSN_SB_NEW) {
-		g_snprintf(buf, sizeof(buf), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key);
-	} else {
-		g_snprintf(buf, sizeof(buf), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key,
-		           sb->session);
-	}
-
-	if (msn_sb_write(sb, "%s", buf)) {
-		sb->inp = b_input_add(sb->fd, B_EV_IO_READ, msn_sb_callback, sb);
-	} else {
-		debug("Error %d while connecting to switchboard server", 2);
-	}
-
-	return FALSE;
-}
-
-static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond)
-{
-	struct msn_switchboard *sb = data;
-	struct im_connection *ic = sb->ic;
-	struct msn_data *md = ic->proto_data;
-
-	if (msn_handler(sb->handler) != -1) {
-		return TRUE;
-	}
-
-	if (sb->msgq != NULL) {
-		time_t now = time(NULL);
-
-		if (now - md->first_sb_failure > 600) {
-			/* It's not really the first one, but the start of this "series".
-			   With this, the warning below will be shown only if this happens
-			   at least three times in ten minutes. This algorithm isn't
-			   perfect, but for this purpose it will do. */
-			md->first_sb_failure = now;
-			md->sb_failures = 0;
-		}
-
-		debug("Error: Switchboard died");
-		if (++md->sb_failures >= 3) {
-			imcb_log(ic, "Warning: Many switchboard failures on MSN connection. "
-			         "There might be problems delivering your messages.");
-		}
-
-		if (md->msgq == NULL) {
-			md->msgq = sb->msgq;
-		} else {
-			GSList *l;
-
-			for (l = md->msgq; l->next; l = l->next) {
-				;
-			}
-			l->next = sb->msgq;
-		}
-		sb->msgq = NULL;
-
-		debug("Moved queued messages back to the main queue, "
-		      "creating a new switchboard to retry.");
-		if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) {
-			return FALSE;
-		}
-	}
-
-	msn_sb_destroy(sb);
-	return FALSE;
-}
-
-static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts)
-{
-	struct msn_switchboard *sb = handler->data;
-	struct im_connection *ic = sb->ic;
-
-	if (!num_parts) {
-		/* Hrrm... Empty command...? Ignore? */
-		return(1);
-	}
-
-	if (strcmp(cmd[0], "XFR") == 0) {
-		imcb_error(ic,
-		           "Received an XFR from a switchboard server, unable to comply! This is likely to be a bug, please report it!");
-		imc_logout(ic, TRUE);
-		return(0);
-	} else if (strcmp(cmd[0], "USR") == 0) {
-		if (num_parts < 5) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		if (strcmp(cmd[2], "OK") != 0) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		if (sb->who) {
-			return msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, sb->who);
-		} else {
-			debug("Just created a switchboard, but I don't know what to do with it.");
-		}
-	} else if (strcmp(cmd[0], "IRO") == 0) {
-		int num, tot;
-
-		if (num_parts < 6) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		num = atoi(cmd[2]);
-		tot = atoi(cmd[3]);
-
-		if (tot <= 0) {
-			msn_sb_destroy(sb);
-			return(0);
-		} else if (tot > 1) {
-			char buf[1024];
-
-			/* For as much as I understand this MPOP stuff now, a
-			   switchboard has two (or more) roster entries per
-			   participant. One "bare JID" and one JID;UUID. Ignore
-			   the latter. */
-			if (!strchr(cmd[4], ';')) {
-				/* HACK: Since even 1:1 chats now have >2 participants
-				   (ourselves included) it gets hard to tell them apart
-				   from rooms. Let's hope this is enough: */
-				if (sb->chat == NULL && num != tot) {
-					g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session);
-					sb->chat = imcb_chat_new(ic, buf);
-
-					g_free(sb->who);
-					sb->who = NULL;
-				}
-
-				if (sb->chat) {
-					imcb_chat_add_buddy(sb->chat, cmd[4]);
-				}
-			}
-
-			/* We have the full roster, start showing the channel to
-			   the user. */
-			if (num == tot && sb->chat) {
-				imcb_chat_add_buddy(sb->chat, ic->acc->user);
-			}
-		}
-	} else if (strcmp(cmd[0], "ANS") == 0) {
-		if (num_parts < 3) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		if (strcmp(cmd[2], "OK") != 0) {
-			debug("Switchboard server sent a negative ANS reply");
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		sb->ready = 1;
-
-		msn_sb_start_keepalives(sb, FALSE);
-	} else if (strcmp(cmd[0], "CAL") == 0) {
-		if (num_parts < 4 || !g_ascii_isdigit(cmd[3][0])) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		sb->session = atoi(cmd[3]);
-	} else if (strcmp(cmd[0], "JOI") == 0) {
-		if (num_parts < 3) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		/* See IRO above. Handle "bare JIDs" only. */
-		if (strchr(cmd[1], ';')) {
-			return 1;
-		}
-
-		if (sb->who && g_strcasecmp(cmd[1], sb->who) == 0) {
-			/* The user we wanted to talk to is finally there, let's send the queued messages then. */
-			struct msn_message *m;
-			GSList *l;
-			int st = 1;
-
-			debug("%s arrived in the switchboard session, now sending queued message(s)", cmd[1]);
-
-			/* Without this, sendmessage() will put everything back on the queue... */
-			sb->ready = 1;
-
-			while ((l = sb->msgq)) {
-				m = l->data;
-				if (st) {
-					/* This hack is meant to convert a regular new chat into a groupchat */
-					if (strcmp(m->text, GROUPCHAT_SWITCHBOARD_MESSAGE) == 0) {
-						msn_sb_to_chat(sb);
-					} else {
-						st = msn_sb_sendmessage(sb, m->text);
-					}
-				}
-				sb->msgq = g_slist_remove(sb->msgq, m);
-				g_free(m->text);
-				g_free(m->who);
-				g_free(m);
-			}
-
-			msn_sb_start_keepalives(sb, FALSE);
-
-			return(st);
-		} else if (strcmp(cmd[1], ic->acc->user) == 0) {
-			/* Well, gee thanks. Thanks for letting me know I've arrived.. */
-		} else if (sb->who) {
-			debug("Converting chat with %s to a groupchat because %s joined the session.", sb->who, cmd[1]);
-
-			/* This SB is a one-to-one chat right now, but someone else is joining. */
-			msn_sb_to_chat(sb);
-
-			imcb_chat_add_buddy(sb->chat, cmd[1]);
-		} else if (sb->chat) {
-			imcb_chat_add_buddy(sb->chat, cmd[1]);
-			sb->ready = 1;
-		} else {
-			/* PANIC! */
-		}
-	} else if (strcmp(cmd[0], "MSG") == 0) {
-		if (num_parts < 4) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		sb->handler->msglen = atoi(cmd[3]);
-
-		if (sb->handler->msglen <= 0) {
-			debug("Received a corrupted message on the switchboard, the switchboard will be closed");
-			msn_sb_destroy(sb);
-			return(0);
-		}
-	} else if (strcmp(cmd[0], "NAK") == 0) {
-		if (sb->who) {
-			imcb_log(ic, "The MSN servers could not deliver one of your messages to %s.", sb->who);
-		} else {
-			imcb_log(ic,
-			         "The MSN servers could not deliver one of your groupchat messages to all participants.");
-		}
-	} else if (strcmp(cmd[0], "BYE") == 0) {
-		if (num_parts < 2) {
-			msn_sb_destroy(sb);
-			return(0);
-		}
-
-		/* if( cmd[2] && *cmd[2] == '1' ) -=> Chat is being cleaned up because of idleness */
-
-		if (sb->who) {
-			msn_sb_stop_keepalives(sb);
-
-			/* This is a single-person chat, and the other person is leaving. */
-			g_free(sb->who);
-			sb->who = NULL;
-			sb->ready = 0;
-
-			debug("Person %s left the one-to-one switchboard connection. Keeping it around as a spare...",
-			      cmd[1]);
-
-			/* We could clean up the switchboard now, but keeping it around
-			   as a spare for a next conversation sounds more sane to me.
-			   The server will clean it up when it's idle for too long. */
-		} else if (sb->chat && !strchr(cmd[1], ';')) {
-			imcb_chat_remove_buddy(sb->chat, cmd[1], "");
-		} else {
-			/* PANIC! */
-		}
-	} else if (g_ascii_isdigit(cmd[0][0])) {
-		int num = atoi(cmd[0]);
-		const struct msn_status_code *err = msn_status_by_number(num);
-
-		/* If the person is offline, send an offline message instead,
-		   and don't report an error. */
-		if (num == 217) {
-			msn_ns_oim_send_queue(ic, &sb->msgq);
-		} else {
-			imcb_error(ic, "Error reported by switchboard server: %s", err->text);
-		}
-
-		if (err->flags & STATUS_SB_FATAL) {
-			msn_sb_destroy(sb);
-			return 0;
-		} else if (err->flags & STATUS_FATAL) {
-			imc_logout(ic, TRUE);
-			return 0;
-		} else if (err->flags & STATUS_SB_IM_SPARE) {
-			if (sb->who) {
-				/* Apparently some invitation failed. We might want to use this
-				   board later, so keep it as a spare. */
-				g_free(sb->who);
-				sb->who = NULL;
-
-				/* Also clear the msgq, otherwise someone else might get them. */
-				msn_msgq_purge(ic, &sb->msgq);
-			}
-
-			/* Do NOT return 0 here, we want to keep this sb. */
-		}
-	} else {
-		/* debug( "Received unknown command from switchboard server: %s", cmd[0] ); */
-	}
-
-	return(1);
-}
-
-static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts)
-{
-	struct msn_switchboard *sb = handler->data;
-	struct im_connection *ic = sb->ic;
-	char *body;
-
-	if (!num_parts) {
-		return(1);
-	}
-
-	if ((body = strstr(msg, "\r\n\r\n"))) {
-		body += 4;
-	}
-
-	if (strcmp(cmd[0], "MSG") == 0) {
-		char *ct = get_rfc822_header(msg, "Content-Type:", msglen);
-
-		if (!ct) {
-			return(1);
-		}
-
-		if (g_strncasecmp(ct, "text/plain", 10) == 0) {
-			g_free(ct);
-
-			if (!body) {
-				return(1);
-			}
-
-			if (sb->who) {
-				imcb_buddy_msg(ic, cmd[1], body, 0, 0);
-			} else if (sb->chat) {
-				imcb_chat_msg(sb->chat, cmd[1], body, 0, 0);
-			} else {
-				/* PANIC! */
-			}
-		}
-		else if (g_strncasecmp(ct, "application/x-msnmsgrp2p", 24) == 0) {
-			/* Not currently implemented. Don't warn about it since
-			   this seems to be used for avatars now. */
-			g_free(ct);
-		} else if (g_strncasecmp(ct, "text/x-msmsgscontrol", 20) == 0) {
-			char *who = get_rfc822_header(msg, "TypingUser:", msglen);
-
-			if (who) {
-				imcb_buddy_typing(ic, who, OPT_TYPING);
-				g_free(who);
-			}
-
-			g_free(ct);
-		} else {
-			g_free(ct);
-		}
-	}
-
-	return(1);
-}
-
-static gboolean msn_sb_keepalive(gpointer data, gint source, b_input_condition cond)
-{
-	struct msn_switchboard *sb = data;
-
-	return sb->ready && msn_sb_sendmessage(sb, SB_KEEPALIVE_MESSAGE);
-}
-
-void msn_sb_start_keepalives(struct msn_switchboard *sb, gboolean initial)
-{
-	bee_user_t *bu;
-
-	if (sb && sb->who && sb->keepalive == 0 &&
-	    (bu = bee_user_by_handle(sb->ic->bee, sb->ic, sb->who)) &&
-	    !(bu->flags & BEE_USER_ONLINE) &&
-	    set_getbool(&sb->ic->acc->set, "switchboard_keepalives")) {
-		if (initial) {
-			msn_sb_keepalive(sb, 0, 0);
-		}
-
-		sb->keepalive = b_timeout_add(20000, msn_sb_keepalive, sb);
-	}
-}
-
-void msn_sb_stop_keepalives(struct msn_switchboard *sb)
-{
-	if (sb && sb->keepalive > 0) {
-		b_event_remove(sb->keepalive);
-		sb->keepalive = 0;
-	}
-}
Index: protocols/msn/tables.c
===================================================================
--- protocols/msn/tables.c	(revision 254a4dab408b67f78b94054514bbf6f629dd6bba)
+++ protocols/msn/tables.c	(revision 11e42dcf7366ee547b9651648724d35d12e36091)
@@ -73,10 +73,10 @@
 	{ 206, "Domain name missing",                                   0 },
 	{ 207, "Already logged in",                                     0 },
-	{ 208, "Invalid handle",                                        STATUS_SB_IM_SPARE },
+	{ 208, "Invalid handle",                                        0 },
 	{ 209, "Forbidden nickname",                                    0 },
 	{ 210, "Buddy list too long",                                   0 },
 	{ 215, "Handle is already in list",                             0 },
-	{ 216, "Handle is not in list",                                 STATUS_SB_IM_SPARE },
-	{ 217, "Person is off-line or non-existent",                    STATUS_SB_IM_SPARE },
+	{ 216, "Handle is not in list",                                 0 },
+	{ 217, "Person is off-line or non-existent",                    0 },
 	{ 218, "Already in that mode",                                  0 },
 	{ 219, "Handle is already in opposite list",                    0 },
@@ -113,5 +113,5 @@
 	{ 711, "Write is blocking",                                     STATUS_FATAL },
 	{ 712, "Session is overloaded",                                 STATUS_FATAL },
-	{ 713, "Calling too rapidly",                                   STATUS_SB_IM_SPARE },
+	{ 713, "Calling too rapidly",                                   0 },
 	{ 714, "Too many sessions",                                     STATUS_FATAL },
 	{ 715, "Not expected/Invalid argument/action",                  0 },
