diff options
Diffstat (limited to 'protocols/msn/ns.c')
| -rw-r--r-- | protocols/msn/ns.c | 207 | 
1 files changed, 45 insertions, 162 deletions
| 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) | 
