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) |