📄 slp.c
字号:
"ICF: false\r\n" ); header = g_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0", slplink->remote_user); slpmsg = msn_slp_sipmsg_new(slpcall, 0, header, branch, "application/x-msnmsgr-transreqbody", content);#ifdef MSN_DEBUG_SLP slpmsg->info = "SLP INVITE"; slpmsg->text_body = TRUE;#endif msn_slplink_send_slpmsg(slplink, slpmsg); g_free(header); g_free(content); g_free(branch); } else { msn_slp_call_session_init(slpcall); }#else msn_slp_call_session_init(slpcall);#endif } else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) { /* Do we get this? */ purple_debug_info("msn", "OK with transreqbody\n"); } else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) {#if 0 char *ip_addrs; char *temp; char *nonce; int port; nonce = get_token(content, "Nonce: {", "}\r\n"); ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); if (temp != NULL) port = atoi(temp); else port = -1; g_free(temp); if (ip_addrs == NULL) return; if (port > 0) got_transresp(slpcall, nonce, ip_addrs, port); g_free(nonce); g_free(ip_addrs);#endif }}MsnSlpCall *msn_slp_sip_recv(MsnSlpLink *slplink, const char *body){ MsnSlpCall *slpcall; if (body == NULL) { purple_debug_warning("msn", "received bogus message\n"); return NULL; } if (!strncmp(body, "INVITE", strlen("INVITE"))) { char *branch; char *content; char *content_type; slpcall = msn_slp_call_new(slplink); /* From: <msnmsgr:buddy@hotmail.com> */#if 0 slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");#endif branch = get_token(body, ";branch={", "}"); slpcall->id = get_token(body, "Call-ID: {", "}");#if 0 long content_len = -1; temp = get_token(body, "Content-Length: ", "\r\n"); if (temp != NULL) content_len = atoi(temp); g_free(temp);#endif content_type = get_token(body, "Content-Type: ", "\r\n"); content = get_token(body, "\r\n\r\n", NULL); got_invite(slpcall, branch, content_type, content); g_free(branch); g_free(content_type); g_free(content); } else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 "))) { char *content; char *content_type; /* Make sure this is "OK" */ const char *status = body + strlen("MSNSLP/1.0 "); char *call_id; call_id = get_token(body, "Call-ID: {", "}"); slpcall = msn_slplink_find_slp_call(slplink, call_id); g_free(call_id); g_return_val_if_fail(slpcall != NULL, NULL); if (strncmp(status, "200 OK", 6)) { /* It's not valid. Kill this off. */ char temp[32]; const char *c; /* Eww */ if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) || (c = strchr(status, '\0'))) { size_t offset = c - status; if (offset >= sizeof(temp)) offset = sizeof(temp) - 1; strncpy(temp, status, offset); temp[offset] = '\0'; } purple_debug_error("msn", "Received non-OK result: %s\n", temp); slpcall->wasted = TRUE; /* msn_slp_call_destroy(slpcall); */ return slpcall; } content_type = get_token(body, "Content-Type: ", "\r\n"); content = get_token(body, "\r\n\r\n", NULL); got_ok(slpcall, content_type, content); g_free(content_type); g_free(content); } else if (!strncmp(body, "BYE", strlen("BYE"))) { char *call_id; call_id = get_token(body, "Call-ID: {", "}"); slpcall = msn_slplink_find_slp_call(slplink, call_id); g_free(call_id); if (slpcall != NULL) slpcall->wasted = TRUE; /* msn_slp_call_destroy(slpcall); */ } else slpcall = NULL; return slpcall;}/************************************************************************** * Msg Callbacks **************************************************************************/voidmsn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg){ MsnSession *session; MsnSlpLink *slplink; session = cmdproc->servconn->session; slplink = msn_session_get_slplink(session, msg->remote_user); if (slplink->swboard == NULL) { /* We will need this in order to change its flags. */ slplink->swboard = (MsnSwitchBoard *)cmdproc->data; /* If swboard is NULL, something has probably gone wrong earlier on * I didn't want to do this, but MSN 7 is somehow causing us to crash * here, I couldn't reproduce it to debug more, and people are * reporting bugs. Hopefully this doesn't cause more crashes. Stu. */ if (slplink->swboard != NULL) slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink); else purple_debug_error("msn", "msn_p2p_msg, swboard is NULL, ouch!\n"); } msn_slplink_process_msg(slplink, msg);}static voidgot_emoticon(MsnSlpCall *slpcall, const guchar *data, gsize size){ PurpleConversation *conv; PurpleConnection *gc; const char *who; gc = slpcall->slplink->session->account->gc; who = slpcall->slplink->remote_user; if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, gc->account))) { /* FIXME: it would be better if we wrote the data as we received it instead of all at once, calling write multiple times and close once at the very end */ purple_conv_custom_smiley_write(conv, slpcall->data_info, data, size); purple_conv_custom_smiley_close(conv, slpcall->data_info); }#ifdef MSN_DEBUG_UD purple_debug_info("msn", "Got smiley: %s\n", slpcall->data_info);#endif}voidmsn_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->servconn->session; if (!purple_account_get_bool(session->account, "custom_smileys", TRUE)) 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]; 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); 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 gbooleanbuddy_icon_cached(PurpleConnection *gc, MsnObject *obj){ PurpleAccount *account; PurpleBuddy *buddy; const char *old; const char *new; g_return_val_if_fail(obj != NULL, FALSE); account = purple_connection_get_account(gc); buddy = purple_find_buddy(account, msn_object_get_creator(obj)); if (buddy == NULL) return FALSE; old = purple_buddy_icons_get_checksum_for_user(buddy); new = msn_object_get_sha1(obj); if (new == NULL) return FALSE; /* If the old and new checksums are the same, and the file actually exists, * then return TRUE */ if (old != NULL && !strcmp(old, new)) return TRUE; return FALSE;}static voidmsn_release_buddy_icon_request(MsnUserList *userlist){ MsnUser *user; g_return_if_fail(userlist != NULL);#ifdef MSN_DEBUG_UD purple_debug_info("msn", "Releasing buddy icon request\n");#endif if (userlist->buddy_icon_window > 0) { GQueue *queue; PurpleAccount *account; const char *username; queue = userlist->buddy_icon_requests; if (g_queue_is_empty(userlist->buddy_icon_requests)) return; user = g_queue_pop_head(queue); account = userlist->session->account; username = user->passport; userlist->buddy_icon_window--; msn_request_user_display(user);#ifdef MSN_DEBUG_UD purple_debug_info("msn", "msn_release_buddy_icon_request(): buddy_icon_window-- yields =%d\n", userlist->buddy_icon_window);#endif }}/* * Called on a timeout from end_user_display(). Frees a buddy icon window slow and dequeues the next * buddy icon request if there is one. */static gbooleanmsn_release_buddy_icon_request_timeout(gpointer data){ MsnUserList *userlist = (MsnUserList *)data; /* Free one window slot */ userlist->buddy_icon_window++; /* Clear the tag for our former request timer */ userlist->buddy_icon_request_timer = 0; msn_release_buddy_icon_request(userlist); return FALSE;}voidmsn_queue_buddy_icon_request(MsnUser *user){ PurpleAccount *account; MsnObject *obj; GQueue *queue; g_return_if_fail(user != NULL); account = user->userlist->session->account; obj = msn_user_get_object(user); if (obj == NULL) { purple_buddy_icons_set_for_user(account, user->passport, NULL, 0, NULL); return; } if (!buddy_icon_cached(account->gc, obj)) { MsnUserList *userlist; userlist = user->userlist; queue = userlist->buddy_icon_requests;#ifdef MSN_DEBUG_UD purple_debug_info("msn", "Queueing buddy icon request for %s (buddy_icon_window = %i)\n", user->passport, userlist->buddy_icon_window);#endif g_queue_push_tail(queue, user); if (userlist->buddy_icon_window > 0) msn_release_buddy_icon_request(userlist); }}static voidgot_user_display(MsnSlpCall *slpcall, const guchar *data, gsize size){ MsnUserList *userlist; const char *info; PurpleAccount *account; g_return_if_fail(slpcall != NULL); info = slpcall->data_info;#ifdef MSN_DEBUG_UD purple_debug_info("msn", "Got User Display: %s\n", slpcall->slplink->remote_user);#endif userlist = slpcall->slplink->session->userlist; account = slpcall->slplink->session->account; purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user, g_memdup(data, size), size, info);#if 0 /* Free one window slot */ userlist->buddy_icon_window++; purple_debug_info("msn", "got_user_display(): buddy_icon_window++ yields =%d\n", userlist->buddy_icon_window); msn_release_buddy_icon_request(userlist);#endif}static voidend_user_display(MsnSlpCall *slpcall, MsnSession *session){ MsnUserList *userlist; g_return_if_fail(session != NULL);#ifdef MSN_DEBUG_UD purple_debug_info("msn", "End User Display\n");#endif userlist = session->userlist; /* If the session is being destroyed we better stop doing anything. */ if (session->destroying) return; /* Delay before freeing a buddy icon window slot and requesting the next icon, if appropriate. * If we don't delay, we'll rapidly hit the MSN equivalent of AIM's rate limiting; the server will * send us an error 800 like so: * * C: NS 000: XFR 21 SB * S: NS 000: 800 21 */ if (userlist->buddy_icon_request_timer) { /* Free the window slot used by this previous request */ userlist->buddy_icon_window++; /* Clear our pending timeout */ purple_timeout_remove(userlist->buddy_icon_request_timer); } /* Wait BUDDY_ICON_DELAY ms before freeing our window slot and requesting the next icon. */ userlist->buddy_icon_request_timer = purple_timeout_add(BUDDY_ICON_DELAY, msn_release_buddy_icon_request_timeout, userlist);}voidmsn_request_user_display(MsnUser *user){ PurpleAccount *account; MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; const char *info; session = user->userlist->session; account = session->account; slplink = msn_session_get_slplink(session, user->passport); obj = msn_user_get_object(user); info = msn_object_get_sha1(obj); if (g_ascii_strcasecmp(user->passport, purple_account_get_username(account))) { msn_slplink_request_object(slplink, info, got_user_display, end_user_display, obj); } else { MsnObject *my_obj = NULL; gconstpointer data = NULL; size_t len = 0;#ifdef MSN_DEBUG_UD purple_debug_info("msn", "Requesting our own user display\n");#endif my_obj = msn_user_get_object(session->user); if (my_obj != NULL) { PurpleStoredImage *img = msn_object_get_image(my_obj); data = purple_imgstore_get_data(img); len = purple_imgstore_get_size(img); } purple_buddy_icons_set_for_user(account, user->passport, g_memdup(data, len), len, info); /* Free one window slot */ session->userlist->buddy_icon_window++;#ifdef MSN_DEBUG_UD purple_debug_info("msn", "msn_request_user_display(): buddy_icon_window++ yields =%d\n", session->userlist->buddy_icon_window);#endif msn_release_buddy_icon_request(session->userlist); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -