MsnObject * msn_object_new_from_string(const gchar *str) { MsnObject *obj; gchar *tag, *c; g_return_val_if_fail(str != NULL, NULL); if (strncmp(str, "<msnobj ", 8)) return NULL; obj = msn_object_new(); GET_STRING_TAG(creator, "Creator"); GET_INT_TAG(size, "Size"); GET_INT_TAG(type, "Type"); GET_STRING_TAG(location, "Location"); GET_STRING_TAG(friendly, "Friendly"); GET_STRING_TAG(sha1d, "SHA1D"); GET_STRING_TAG(sha1c, "SHA1C"); /* If we are missing any of the required elements then discard the object */ /* SHA1C is not always sent anymore */ if (obj->creator == NULL || obj->size == 0 || obj->type == 0 || obj->location == NULL || obj->friendly == NULL || obj->sha1d == NULL /*|| obj->sha1c == NULL*/) { pecan_error ("discarding: str=[%s]", str); msn_object_destroy(obj); obj = NULL; } return obj; }
void msn_user_destroy(MsnUser *user) { g_return_if_fail(user != NULL); if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); if (user->group_ids != NULL) g_list_free(user->group_ids); if (user->msnobj != NULL) msn_object_destroy(user->msnobj); if (user->passport != NULL) g_free(user->passport); if (user->friendly_name != NULL) g_free(user->friendly_name); if (user->store_name != NULL) g_free(user->store_name); if (user->phone.home != NULL) g_free(user->phone.home); if (user->phone.work != NULL) g_free(user->phone.work); if (user->phone.mobile != NULL) g_free(user->phone.mobile); g_free(user); }
MsnObject * msn_object_new_from_string(const char *str) { MsnObject *obj; char *tag, *c; g_return_val_if_fail(str != NULL, NULL); if (strncmp(str, "<msnobj ", 8)) return NULL; obj = msn_object_new(); GET_STRING_TAG(creator, "Creator"); GET_INT_TAG(size, "Size"); GET_INT_TAG(type, "Type"); GET_STRING_TAG(location, "Location"); GET_STRING_TAG(friendly, "Friendly"); GET_STRING_TAG(sha1d, "SHA1D"); GET_STRING_TAG(sha1c, "SHA1C"); GET_STRING_TAG(url, "Url"); GET_STRING_TAG(url1, "Url1"); /* If we are missing any of the required elements then discard the object */ if (obj->creator == NULL || obj->size == 0 || obj->type == 0 || obj->sha1d == NULL) { purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str); msn_object_destroy(obj, FALSE); return NULL; } if (obj->location == NULL || obj->friendly == NULL) { /* Location/friendly are required for non-buddyicon objects */ if (obj->type != MSN_OBJECT_USERTILE) { purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str); msn_object_destroy(obj, FALSE); return NULL; /* Buddy icon object can contain Url/Url1 instead */ } else if (obj->url == NULL || obj->url1 == NULL) { purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str); msn_object_destroy(obj, FALSE); return NULL; } } return obj; }
void msn_user_set_object(MsnUser *user, MsnObject *obj) { g_return_if_fail(user != NULL); if (user->msnobj != NULL) msn_object_destroy(user->msnobj); user->msnobj = obj; if (user->list_op & MSN_LIST_FL_OP) msn_queue_buddy_icon_request(user); }
/*destroy a user object*/ void msn_user_destroy(MsnUser *user) { g_return_if_fail(user != NULL); if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); if (user->group_ids != NULL) { GList *l; for (l = user->group_ids; l != NULL; l = l->next) { g_free(l->data); } g_list_free(user->group_ids); } if (user->msnobj != NULL) msn_object_destroy(user->msnobj); g_free(user->passport); g_free(user->friendly_name); g_free(user->uid); if (user->extinfo) { g_free(user->extinfo->media_album); g_free(user->extinfo->media_artist); g_free(user->extinfo->media_title); g_free(user->extinfo->phone_home); g_free(user->extinfo->phone_mobile); g_free(user->extinfo->phone_work); g_free(user->extinfo); } g_free(user->statusline); g_free(user->invite_message); g_free(user); }
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSession *session; MsnSlpLink *slplink; MsnSwitchBoard *swboard; MsnObject *obj; char **tokens; char *smile, *body_str; const char *body, *who, *sha1; guint tok; size_t body_len; PurpleConversation *conv; session = cmdproc->servconn->session; if (!purple_account_get_bool(session->account, "custom_smileys", TRUE)) return; swboard = cmdproc->data; conv = swboard->conv; body = msn_message_get_bin_data(msg, &body_len); if (!body || !body_len) return; body_str = g_strndup(body, body_len); /* MSN Messenger 7 may send more than one MSNObject in a single message... * Maybe 10 tokens is a reasonable max value. */ tokens = g_strsplit(body_str, "\t", 10); g_free(body_str); for (tok = 0; tok < 9; tok += 2) { if (tokens[tok] == NULL || tokens[tok + 1] == NULL) { break; } smile = tokens[tok]; obj = msn_object_new_from_string(purple_url_decode(tokens[tok + 1])); if (obj == NULL) break; who = msn_object_get_creator(obj); sha1 = msn_object_get_sha1(obj); slplink = msn_session_get_slplink(session, who); if (slplink->swboard != swboard) { if (slplink->swboard != NULL) /* * Apparently we're using a different switchboard now or * something? I don't know if this is normal, but it * definitely happens. So make sure the old switchboard * doesn't still have a reference to us. */ slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink); slplink->swboard = swboard; slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink); } /* If the conversation doesn't exist then this is a custom smiley * used in the first message in a MSN conversation: we need to create * the conversation now, otherwise the custom smiley won't be shown. * This happens because every GtkIMHtml has its own smiley tree: if * the conversation doesn't exist then we cannot associate the new * smiley with its GtkIMHtml widget. */ if (!conv) { conv = PURPLE_CONVERSATION(purple_im_conversation_new(session->account, who)); } if (purple_conversation_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); } msn_object_destroy(obj, FALSE); obj = NULL; who = NULL; sha1 = NULL; } g_strfreev(tokens); }
void msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { GHashTable *body; const char *id; body = msn_message_get_hashtable_from_body(msg); id = g_hash_table_lookup(body, "ID"); if (!strcmp(id, "1")) { /* Nudge */ PurpleAccount *account; const char *user; PurpleConnection *gc; account = cmdproc->session->account; user = msg->remote_user; gc = purple_account_get_connection(account); if (cmdproc->servconn->type == MSN_SERVCONN_SB) { MsnSwitchBoard *swboard = cmdproc->data; if (swboard->current_users > 1 || ((swboard->conv != NULL) && PURPLE_IS_CHAT_CONVERSATION(swboard->conv))) purple_prpl_got_attention_in_chat(gc, swboard->chat_id, user, MSN_NUDGE); else purple_prpl_got_attention(gc, user, MSN_NUDGE); } else { purple_prpl_got_attention(gc, user, MSN_NUDGE); } } else if (!strcmp(id, "2")) { /* Wink */ MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; const char *who; const char *data; session = cmdproc->session; data = g_hash_table_lookup(body, "Data"); obj = msn_object_new_from_string(data); who = msn_object_get_creator(obj); slplink = msn_session_get_slplink(session, who); msn_slplink_request_object(slplink, data, got_wink_cb, NULL, obj); msn_object_destroy(obj, FALSE); } else if (!strcmp(id, "3")) { /* Voiceclip */ MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; const char *who; const char *data; session = cmdproc->session; data = g_hash_table_lookup(body, "Data"); obj = msn_object_new_from_string(data); who = msn_object_get_creator(obj); slplink = msn_session_get_slplink(session, who); msn_slplink_request_object(slplink, data, got_voiceclip_cb, NULL, obj); msn_object_destroy(obj, FALSE); } else if (!strcmp(id, "4")) { /* Action */ } else { purple_debug_warning("msn", "Got unknown datacast with ID %s.\n", id); } g_hash_table_destroy(body); }
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; char **tokens; char *smile, *body_str; const char *body, *who, *sha1; guint tok; size_t body_len; PurpleConversation *conv; session = cmdproc->session; if (!purple_account_get_bool_without_default_value(session->account, "custom_smileys")) return; body = msn_message_get_bin_data(msg, &body_len); body_str = g_strndup(body, body_len); /* MSN Messenger 7 may send more than one MSNObject in a single message... * Maybe 10 tokens is a reasonable max value. */ tokens = g_strsplit(body_str, "\t", 10); g_free(body_str); for (tok = 0; tok < 9; tok += 2) { if (tokens[tok] == NULL || tokens[tok + 1] == NULL) { break; } smile = tokens[tok]; { gchar *tmp; tmp = pecan_url_decode (tokens[tok + 1]); obj = msn_object_new_from_string(tmp); g_free(tmp); } if (obj == NULL) break; who = msn_object_get_creator(obj); sha1 = msn_object_get_sha1(obj); slplink = msn_session_get_slplink(session, who); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, session->account); /* If the conversation doesn't exist then this is a custom smiley * used in the first message in a MSN conversation: we need to create * the conversation now, otherwise the custom smiley won't be shown. * This happens because every GtkIMHtml has its own smiley tree: if * the conversation doesn't exist then we cannot associate the new * smiley with its GtkIMHtml widget. */ if (!conv) { //conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who); } if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); } msn_object_destroy(obj); obj = NULL; who = NULL; sha1 = NULL; } g_strfreev(tokens); }
static void got_sessionreq(MsnSlpCall *slpcall, const char *branch, const char *euf_guid, const char *context) { pecan_debug ("euf_guid=[%s]", euf_guid); if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6")) { /* Emoticon or UserDisplay */ char *content; gsize len; MsnSlpSession *slpsession; MsnSlpLink *slplink; MsnSlpMessage *slpmsg; MsnObject *obj; char *msnobj_data; PecanBuffer *image; int type; /* Send Ok */ content = pecan_strdup_printf("SessionID: %lu\r\n\r\n", slpcall->session_id); send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody", content); g_free(content); slplink = slpcall->slplink; msnobj_data = (char *)purple_base64_decode(context, &len); obj = msn_object_new_from_string(msnobj_data); type = msn_object_get_type(obj); g_free(msnobj_data); if (type == MSN_OBJECT_USERTILE) { /* image is owned by a local object, not obj */ image = msn_object_get_image(obj); } #if PURPLE_VERSION_CHECK(2,5,0) else if (type == MSN_OBJECT_EMOTICON) { PurpleStoredImage *img; char *path; path = g_build_filename(purple_smileys_get_storing_dir(), msn_object_get_location(obj), NULL); img = purple_imgstore_new_from_file(path); image = pecan_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img), purple_imgstore_get_size (img)); purple_imgstore_unref(img); g_free(path); } #endif /* PURPLE_VERSION_CHECK(2,5,0) */ else { pecan_error ("Wrong object?"); msn_object_destroy(obj); g_return_if_reached(); } if (!image) { pecan_error ("Wrong object"); msn_object_destroy (obj); g_return_if_reached (); } msn_object_destroy(obj); { gchar *tmp; tmp = msn_object_to_string (obj); pecan_info ("object requested: %s", tmp); g_free (tmp); } slpsession = msn_slplink_find_slp_session(slplink, slpcall->session_id); /* DATA PREP */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->session_id = slpsession->id; msn_slpmsg_set_body(slpmsg, NULL, 4); #ifdef PECAN_DEBUG_SLP slpmsg->info = "SLP DATA PREP"; #endif msn_slplink_queue_slpmsg(slplink, slpmsg); /* DATA */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->flags = 0x20; #ifdef PECAN_DEBUG_SLP slpmsg->info = "SLP DATA"; #endif msn_slpmsg_set_image (slpmsg, image); msn_slplink_queue_slpmsg(slplink, slpmsg); } else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) { /* File Transfer */ PurpleAccount *account; PurpleXfer *xfer; char *bin; gsize bin_len; guint32 file_size; char *file_name; gunichar2 *uni_name; account = slpcall->slplink->session->account; slpcall->cb = msn_xfer_completed_cb; slpcall->end_cb = msn_xfer_end_cb; slpcall->progress_cb = msn_xfer_progress_cb; slpcall->branch = g_strdup(branch); slpcall->pending = TRUE; xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, slpcall->slplink->remote_user); if (xfer) { bin = (char *)purple_base64_decode(context, &bin_len); file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8)); uni_name = (gunichar2 *)(bin + 20); while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) { *uni_name = GUINT16_FROM_LE(*uni_name); uni_name++; } file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1, NULL, NULL, NULL); g_free(bin); purple_xfer_set_filename(xfer, file_name); purple_xfer_set_size(xfer, file_size); purple_xfer_set_init_fnc(xfer, msn_xfer_init); purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); xfer->data = slpcall; purple_xfer_request(xfer); } } }