diff options
| author | dequis <dx@dxzone.com.ar> | 2015-03-09 05:35:50 -0300 | 
|---|---|---|
| committer | dequis <dx@dxzone.com.ar> | 2015-04-10 14:10:40 -0300 | 
| commit | 11e42dcf7366ee547b9651648724d35d12e36091 (patch) | |
| tree | afc7c81e586d1fb119c5e2856be0742db9963430 /protocols | |
| parent | 254a4dab408b67f78b94054514bbf6f629dd6bba (diff) | |
msn: removed switchboards, implemented SDG message
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/msn/Makefile | 2 | ||||
| -rw-r--r-- | protocols/msn/msn.c | 80 | ||||
| -rw-r--r-- | protocols/msn/msn.h | 81 | ||||
| -rw-r--r-- | protocols/msn/msn_util.c | 7 | ||||
| -rw-r--r-- | protocols/msn/ns.c | 207 | ||||
| -rw-r--r-- | protocols/msn/sb.c | 712 | ||||
| -rw-r--r-- | protocols/msn/tables.c | 8 | 
7 files changed, 85 insertions, 1012 deletions
| diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile index 417bab78..ce4a3325 100644 --- a/protocols/msn/Makefile +++ b/protocols/msn/Makefile @@ -12,7 +12,7 @@ _SRCDIR_ := $(_SRCDIR_)protocols/msn/  endif  # [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 diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index ef78646b..c1b5ce77 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -29,7 +29,6 @@  int msn_chat_id;  GSList *msn_connections; -GSList *msn_switchboards;  static char *set_eval_display_name(set_t *set, char *value); @@ -47,7 +46,6 @@ static void msn_init(account_t *acc)  	s->flags |= ACC_SET_OFFLINE_ONLY;  	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 |  	              ACC_FLAG_HANDLE_DOMAINS; @@ -79,12 +77,12 @@ static void msn_login(account_t *acc)  	md->ic = ic;  	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"));  } @@ -95,11 +93,7 @@ static void msn_logout(struct im_connection *ic)  	int i;  	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);  		msn_soapq_flush(ic, FALSE); @@ -153,29 +147,15 @@ static void msn_logout(struct im_connection *ic)  static int msn_buddy_msg(struct im_connection *ic, char *who, char *message, int away)  {  	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 -#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); +		return 0;  	} +#endif +	msn_ns_sendmessage(ic, bu, message);  	return(0);  } @@ -197,7 +177,7 @@ static GList *msn_away_states(struct im_connection *ic)  static void msn_set_away(struct im_connection *ic, char *state, char *message)  { -	char *uux; +	//char *uux;  	struct msn_data *md = ic->proto_data;  	if (state == NULL) { @@ -257,53 +237,24 @@ static void msn_remove_buddy(struct im_connection *ic, char *who, char *group)  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;  }  static void msn_keepalive(struct im_connection *ic) @@ -323,14 +274,7 @@ static void msn_rem_permit(struct im_connection *ic, char *who)  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); -	}  }  static void msn_rem_deny(struct im_connection *ic, char *who) diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 0ef71083..3827c992 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -31,7 +31,6 @@  #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r"  #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  #define debug(text ...) imcb_log(ic, text); @@ -67,11 +66,20 @@  #define MSN_CAP1        0xC000  #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" \  	"Content-Type: text/x-msmsgscontrol\r\n" \ @@ -84,10 +92,6 @@  	"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/"  typedef enum { @@ -98,7 +102,7 @@ typedef enum {  	MSN_EMAIL_UNVERIFIED = 16,  } msn_flags_t; -struct msn_handler_data { +struct msn_data {  	int fd, inpa;  	int rxlen;  	char *rxq; @@ -106,17 +110,8 @@ struct msn_handler_data {  	int msglen;  	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;  	int trId; @@ -125,9 +120,6 @@ struct msn_data {  	char *uuid;  	GSList *msgq, *grpq, *soapq; -	GSList *switchboards; -	int sb_failures; -	time_t first_sb_failure;  	const struct msn_away_state *away_state;  	GSList *groups; @@ -140,26 +132,6 @@ struct msn_data {  	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; -}; -  struct msn_away_state {  	char code[4];  	char name[16]; @@ -204,8 +176,6 @@ struct msn_group {  /* Bitfield values for msn_status_code.flags */  #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;  extern const struct msn_away_state msn_away_state_list[]; @@ -217,17 +187,18 @@ extern const struct msn_status_code msn_status_code_list[];     connection), the callback should check whether it's still listed here     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);  int msn_ns_finish_login(struct im_connection *ic);  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 */  int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, @@ -235,7 +206,7 @@ int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const c  int msn_buddy_list_remove(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group);  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);  gint msn_domaintree_cmp(gconstpointer a_, gconstpointer b_); @@ -250,18 +221,4 @@ const struct msn_away_state *msn_away_state_by_code(char *code);  const struct msn_away_state *msn_away_state_by_name(char *name);  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 diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index e4c7aa61..43256a2a 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -265,8 +265,9 @@ char **msn_linesplit(char *line)                     0: Command reported error; Abort *immediately*. (The connection does not exist anymore)                     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;  	h->rxq = g_renew(char, h->rxq, h->rxlen + 1024); @@ -298,7 +299,7 @@ int msn_handler(struct msn_handler_data *h)  					for (count = 0; cmd[count]; count++) {  						;  					} -					st = h->exec_command(h, cmd, count); +					st = msn_ns_command(h, cmd, count);  					g_free(cmd_text);  					/* If the connection broke, don't continue. We don't even exist anymore. */ @@ -339,7 +340,7 @@ int msn_handler(struct msn_handler_data *h)  				;  			} -			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);  			h->cmd_text = NULL; diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 2ebbf358..5ccdd8b3 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -34,8 +34,6 @@  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);  static void msn_ns_send_adl(struct im_connection *ic); @@ -53,7 +51,7 @@ int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...)  	va_end(params);  	if (fd < 0) { -		fd = md->ns->fd; +		fd = md->fd;  	}  	if (getenv("BITLBEE_DEBUG")) { @@ -72,15 +70,14 @@ int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...)  	return 1;  } -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) {  		imcb_error(ic, "Could not connect to server"); @@ -93,15 +90,9 @@ gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handl  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) {  		imcb_error(ic, "Could not connect to server"); @@ -136,7 +127,7 @@ static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition c  	return FALSE;  } -void msn_ns_close(struct msn_handler_data *handler) +void msn_ns_close(struct msn_data *handler)  {  	if (handler->fd >= 0) {  		closesocket(handler->fd); @@ -154,8 +145,8 @@ void msn_ns_close(struct msn_handler_data *handler)  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. */  		imcb_error(ic, "Error while reading from server"); @@ -167,10 +158,10 @@ static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition co  	}  } -static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts) +int msn_ns_command(struct msn_data *handler, char **cmd, int num_parts)  { -	struct im_connection *ic = handler->data; -	struct msn_data *md = ic->proto_data; +	struct im_connection *ic = handler->ic; +	struct msn_data *md = handler;  	if (num_parts == 0) {  		/* Hrrm... Empty command...? Ignore? */ @@ -208,54 +199,7 @@ static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_  			server = cmd[3];  			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");  			imc_logout(ic, TRUE); @@ -360,7 +304,6 @@ static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_  		                  (cap & 1 ? OPT_MOBILE : 0),  		                  st->name, NULL); -		msn_sb_stop_keepalives(msn_sb_by_handle(ic, handle));  	} else if (strcmp(cmd[0], "FLN") == 0) {  		const char *handle; @@ -370,47 +313,6 @@ static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_  		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; @@ -493,7 +395,7 @@ static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_  		if (num_parts >= 2) {  			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]);  		} @@ -525,9 +427,9 @@ static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_  	return(1);  } -static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts) +int msn_ns_message(struct msn_data *handler, char *msg, int msglen, char **cmd, int num_parts)  { -	struct im_connection *ic = handler->data; +	struct im_connection *ic = handler->ic;  	char *body;  	int blen = 0; @@ -716,32 +618,29 @@ static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msgle  				}  			}  		} -	} 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; -		} +	} 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; -		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]); -		} +		if ((from = get_rfc822_header(parts[0], "From", 0)) && +		    (mt = get_rfc822_header(parts[2], "Message-Type", 0)) && +		    (s = strchr(from, ';'))) { -		imcb_buddy_msg(ic, handle, body, 0, 0); -		g_free(handle); +			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;  	}  	return 1; @@ -892,11 +791,12 @@ int msn_ns_finish_login(struct im_connection *ic)  	return 1;  } +// 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) {  		/* Err. Shouldn't happen but I guess it can. Don't send others @@ -904,27 +804,10 @@ int msn_ns_sendmessage(struct im_connection *ic, bee_user_t *bu, const char *tex  		return 1;  	} -	/* 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;  }  void msn_ns_oim_send_queue(struct im_connection *ic, GSList **msgq) diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c deleted file mode 100644 index 673d65c7..00000000 --- a/protocols/msn/sb.c +++ /dev/null @@ -1,712 +0,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; -	} -} diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c index c4dc895e..712116e5 100644 --- a/protocols/msn/tables.c +++ b/protocols/msn/tables.c @@ -72,12 +72,12 @@ const struct msn_status_code msn_status_code_list[] =  	{ 205, "Invalid (non-existent) handle",                         0 },  	{ 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 },  	{ 223, "Too many groups",                                       0 }, @@ -112,7 +112,7 @@ const struct msn_status_code msn_status_code_list[] =  	{ 710, "Invalid CVR parameters",                                STATUS_FATAL },  	{ 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 },  	{ 717, "Bad friend file",                                       STATUS_FATAL }, | 
