# HG changeset patch # User Christian Hammond # Date 1069462044 0 # Node ID 3a48ade4f51078cec86d801d5235b8c9cf1206f4 # Parent 59c1cee97cbba04f49c910408603fe12db8606f1 [gaim-migrate @ 8208] The MSNSLP stuff pretty much works. I have it disabled in this commit just in case, but I should have the rest done tonight. Also, client IDs are now sent (which was part of the problem), as are the MSNObjects (the other half of the problem). committer: Tailor Script diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/msg.c --- a/src/protocols/msn/msg.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/msg.c Sat Nov 22 00:47:24 2003 +0000 @@ -157,11 +157,14 @@ GET_NEXT(tmp); /* Skip the username or flag */ msg->size = atoi(tmp); +#if 0 + /* Put this back when we intelligently handle binary strings. */ if (msg->size != strlen(strchr(str, '\n') + 1)) { gaim_debug(GAIM_DEBUG_ERROR, "msn", "Incoming message size (%d) and string length (%d) " "do not match!\n", msg->size, strlen(str)); } +#endif /* * We're going to make sure this is incoming by checking field1. diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/msn.c Sat Nov 22 00:47:24 2003 +0000 @@ -608,16 +608,19 @@ MsnSession *session = gc->proto_data; const char *away; - if (gc->away != NULL) { + if (gc->away != NULL) + { g_free(gc->away); gc->away = NULL; } - if (msg != NULL) { + if (msg != NULL) + { gc->away = g_strdup(""); away = "AWY"; } - else if (state) { + else if (state) + { gc->away = g_strdup(""); if (!strcmp(state, _("Away From Computer"))) @@ -632,7 +635,8 @@ away = "LUN"; else if (!strcmp(state, _("Hidden"))) away = "HDN"; - else { + else + { g_free(gc->away); gc->away = NULL; away = "NLN"; @@ -643,10 +647,7 @@ else away = "NLN"; - if (!msn_servconn_send_command(session->notification_conn, "CHG", away)) { - gaim_connection_error(gc, _("Write error")); - return; - } + msn_session_change_status(session, away); } static void @@ -657,12 +658,7 @@ if (gc->away != NULL) return; - if (!msn_servconn_send_command(session->notification_conn, "CHG", - (idle ? "IDL" : "NLN"))) { - - gaim_connection_error(gc, _("Write error")); - return; - } + msn_session_change_status(session, (idle ? "IDL" : "NLN")); } static void @@ -1234,6 +1230,17 @@ } static void +msn_set_buddy_icon(GaimConnection *gc, const char *filename) +{ + MsnSession *session = (MsnSession *)gc->proto_data; + MsnUser *user = session->user; + + msn_user_set_buddy_icon(user, filename); + + msn_session_change_status(session, session->away_state); +} + +static void msn_remove_group(GaimConnection *gc, const char *name) { MsnSession *session = (MsnSession *)gc->proto_data; @@ -1605,7 +1612,7 @@ msn_buddy_free, msn_convo_closed, msn_normalize, - NULL, + msn_set_buddy_icon, msn_remove_group }; diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/msn.h --- a/src/protocols/msn/msn.h Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/msn.h Sat Nov 22 00:47:24 2003 +0000 @@ -37,6 +37,7 @@ #include "prpl.h" #include "request.h" #include "server.h" +#include "sha.h" #include "sslconn.h" #include "util.h" @@ -83,4 +84,36 @@ } MsnListOp; +typedef enum +{ + MSN_CLIENT_CAP_WIN_MOBILE = 0x01, + MSN_CLIENT_CAP_UNKNOWN_1 = 0x02, + MSN_CLIENT_CAP_VIEW_INK = 0x04, + MSN_CLIENT_CAP_SEND_INK = 0x08, + MSN_CLIENT_CAP_VIDEO_CHAT = 0x10, + MSN_CLIENT_CAP_BASE = 0x20, + MSN_CLIENT_CAP_UNKNOWN_2 = 0x40, + MSN_CLIENT_CAP_UNKNOWN_3 = 0x80 + +} MsnClientCaps; + +typedef enum +{ + MSN_CLIENT_VER_5_0 = 0x00, + MSN_CLIENT_VER_6_0 = 0x10, + MSN_CLIENT_VER_6_1 = 0x20 + +} MsnClientVerId; + +#define MSN_CLIENT_ID_VERSION MSN_CLIENT_VER_6_0 +#define MSN_CLIENT_ID_RESERVED_1 0x00 +#define MSN_CLIENT_ID_RESERVED_2 0x00 +#define MSN_CLIENT_ID_CAPABILITIES (MSN_CLIENT_CAP_BASE | MSN_CLIENT_CAP_VIEW_INK) + +#define MSN_CLIENT_ID \ + ((MSN_CLIENT_ID_VERSION << 24) | \ + (MSN_CLIENT_ID_RESERVED_1 << 16) | \ + (MSN_CLIENT_ID_RESERVED_2 << 8) | \ + (MSN_CLIENT_ID_CAPABILITIES)) + #endif /* _MSN_H_ */ diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/msnslp.c --- a/src/protocols/msn/msnslp.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/msnslp.c Sat Nov 22 00:47:24 2003 +0000 @@ -214,6 +214,7 @@ char *branch; char *content; char *body; + char *c; g_return_if_fail(slpsession != NULL); g_return_if_fail(local_user != NULL); @@ -224,10 +225,8 @@ msnobj_base64 = gaim_base64_encode(msnobj_data, strlen(msnobj_data)); g_free(msnobj_data); -#if 0 if ((c = strchr(msnobj_base64, '=')) != NULL) *c = '\0'; -#endif session_id = rand() % 0xFFFFFF00 + 4; diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/notification.c --- a/src/protocols/msn/notification.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/notification.c Sat Nov 22 00:47:24 2003 +0000 @@ -1278,12 +1278,11 @@ if (session->num_users == session->total_users) { - if (!msn_servconn_send_command(servconn, "CHG", "NLN")) - { - gaim_connection_error(gc, _("Unable to write")); - + msn_user_set_buddy_icon(session->user, + gaim_account_get_buddy_icon(session->account)); + + if (!msn_session_change_status(session, "NLN")) return FALSE; - } gaim_connection_set_state(gc, GAIM_CONNECTED); serv_finish_login(gc); @@ -1446,12 +1445,8 @@ /* Now we're at the last one, so we can do final work. */ if (!session->lists_synced) { - if (!msn_servconn_send_command(servconn, "CHG", "NLN")) - { - gaim_connection_error(gc, _("Unable to write")); - + if (!msn_session_change_status(session, "NLN")) return FALSE; - } gaim_connection_set_state(gc, GAIM_CONNECTED); serv_finish_login(gc); diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/session.c --- a/src/protocols/msn/session.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/session.c Sat Nov 22 00:47:24 2003 +0000 @@ -37,6 +37,8 @@ session->dispatch_server = g_strdup(server); session->dispatch_port = port; + session->away_state = NULL; + session->users = msn_users_new(); session->groups = msn_groups_new(); @@ -93,6 +95,9 @@ if (session->passport_info.file != NULL) g_free(session->passport_info.file); + if (session->away_state != NULL) + g_free(session->away_state); + g_free(session); } @@ -155,8 +160,8 @@ g_return_val_if_fail(session != NULL, NULL); - if (msn_servconn_send_command(session->notification_conn, - "XFR", "SB") < 0) { + if (msn_servconn_send_command(session->notification_conn, "XFR", "SB") < 0) + { return NULL; } @@ -165,6 +170,49 @@ return swboard; } +gboolean +msn_session_change_status(MsnSession *session, const char *state) +{ + MsnUser *user = session->user; + MsnObject *msnobj; + char buf[MSN_BUF_LEN]; + + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(state != NULL, FALSE); + + msnobj = msn_user_get_object(user); + + if (state != session->away_state) + { + if (session->away_state != NULL) + g_free(session->away_state); + + session->away_state = g_strdup(state); + } + + if (msnobj == NULL) + g_snprintf(buf, sizeof(buf), "%s %d", state, MSN_CLIENT_ID); + else + { + char *msnobj_str = msn_object_to_string(msnobj); + + g_snprintf(buf, sizeof(buf), "%s %d %s", state, MSN_CLIENT_ID, + gaim_url_encode(msnobj_str)); + + g_free(msnobj_str); + } + + if (!msn_servconn_send_command(session->notification_conn, "CHG", buf)) + { + gaim_connection_error(gaim_account_get_connection(session->account), + _("Write error")); + + return FALSE; + } + + return TRUE; +} + MsnSwitchBoard * msn_session_find_switch_with_passport(const MsnSession *session, const char *passport) @@ -224,4 +272,3 @@ return NULL; } - diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/session.h --- a/src/protocols/msn/session.h Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/session.h Sat Nov 22 00:47:24 2003 +0000 @@ -35,6 +35,7 @@ { GaimAccount *account; MsnUser *user; + char *away_state; int protocol_ver; @@ -150,6 +151,14 @@ MsnSwitchBoard *msn_session_open_switchboard(MsnSession *session); /** + * Changes the status of the user. + * + * @param session The MSN session. + * @param state The new state. + */ +gboolean msn_session_change_status(MsnSession *session, const char *state); + +/** * Finds a switch with the given passport. * * @param session The MSN session. diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/user.c --- a/src/protocols/msn/user.c Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/user.c Sat Nov 22 00:47:24 2003 +0000 @@ -29,7 +29,8 @@ user = msn_users_find_with_passport(session->users, passport); - if (user == NULL) { + if (user == NULL) + { user = g_new0(MsnUser, 1); user->session = session; @@ -138,6 +139,82 @@ } void +msn_user_set_buddy_icon(MsnUser *user, const char *filename) +{ + struct stat st; + FILE *fp; + MsnObject *msnobj = msn_user_get_object(user); + + g_return_if_fail(user != NULL); + + if (filename == NULL || stat(filename, &st) == -1) + msn_user_set_object(user, NULL); + else if ((fp = fopen(filename, "rb")) != NULL) + { + unsigned char *buf; + SHA_CTX ctx; + size_t len; + char *base64; + unsigned char digest[20]; + + if (msnobj == NULL) + { + msnobj = msn_object_new(); + msn_object_set_type(msnobj, MSN_OBJECT_EMOTICON); + msn_object_set_location(msnobj, "TFR2C.tmp"); + msn_object_set_creator(msnobj, msn_user_get_passport(user)); + + msn_user_set_object(user, msnobj); + } + + buf = g_malloc(st.st_size); + len = fread(buf, 1, st.st_size, fp); + + fclose(fp); + + /* Compute the SHA1D field. */ + memset(digest, 0, sizeof(digest)); + + shaInit(&ctx); + shaUpdate(&ctx, buf, st.st_size); + shaFinal(&ctx, digest); + g_free(buf); + + base64 = gaim_base64_encode(digest, sizeof(digest)); + msn_object_set_sha1d(msnobj, base64); + g_free(base64); + + msn_object_set_size(msnobj, st.st_size); + + /* Compute the SHA1C field. */ + buf = g_strdup_printf( + "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s", + msn_object_get_creator(msnobj), + msn_object_get_size(msnobj), + msn_object_get_type(msnobj), + msn_object_get_location(msnobj), + msn_object_get_friendly(msnobj), + msn_object_get_sha1d(msnobj)); + + memset(digest, 0, sizeof(digest)); + + shaInit(&ctx); + shaUpdate(&ctx, buf, strlen(buf)); + shaFinal(&ctx, digest); + g_free(buf); + + base64 = gaim_base64_encode(digest, sizeof(digest)); + msn_object_set_sha1c(msnobj, base64); + g_free(base64); + } + else + { + gaim_debug_error("msn", "Unable to open buddy icon %s!\n", filename); + msn_user_set_object(user, NULL); + } +} + +void msn_user_set_group_ids(MsnUser *user, GList *ids) { g_return_if_fail(user != NULL); diff -r 59c1cee97cbb -r 3a48ade4f510 src/protocols/msn/user.h --- a/src/protocols/msn/user.h Fri Nov 21 18:12:55 2003 +0000 +++ b/src/protocols/msn/user.h Sat Nov 22 00:47:24 2003 +0000 @@ -129,6 +129,14 @@ void msn_user_set_name(MsnUser *user, const char *name); /** + * Sets the buddy icon for a local user. + * + * @param user The user. + * @param filename The path to the buddy icon. + */ +void msn_user_set_buddy_icon(MsnUser *user, const char *filename); + +/** * Sets the group ID list for a user. * * @param user The user.