📄 slp.c
字号:
/** * @file msnslp.c MSNSLP support * * gaim * * Gaim is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "msn.h"#include "slp.h"#include "slpcall.h"#include "slpmsg.h"#include "slpsession.h"#include "object.h"#include "user.h"#include "switchboard.h"/* #include "slplink.h" *//* #include "directconn.h" */static void send_ok(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content);static void send_decline(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content);void msn_request_user_display(MsnUser *user);/************************************************************************** * Util **************************************************************************/char *get_token(const char *str, const char *start, const char *end){ const char *c, *c2; if ((c = strstr(str, start)) == NULL) return NULL; c += strlen(start); if (end != NULL) { if ((c2 = strstr(c, end)) == NULL) return NULL; return g_strndup(c, c2 - c); } else { /* This has to be changed */ return g_strdup(c); }}/************************************************************************** * Xfer **************************************************************************/static voidmsn_xfer_init(GaimXfer *xfer){ MsnSlpCall *slpcall; /* MsnSlpLink *slplink; */ char *content; gaim_debug_info("msn", "xfer_init\n"); slpcall = xfer->data; /* Send Ok */ content = g_strdup_printf("SessionID: %lu\r\n\r\n", slpcall->session_id); send_ok(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", content); g_free(content); msn_slplink_unleash(slpcall->slplink);}voidmsn_xfer_cancel(GaimXfer *xfer){ MsnSlpCall *slpcall; char *content; g_return_if_fail(xfer != NULL); g_return_if_fail(xfer->data != NULL); slpcall = xfer->data; if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) { if (slpcall->started) { msn_slp_call_close(slpcall); } else { content = g_strdup_printf("SessionID: %lu\r\n\r\n", slpcall->session_id); send_decline(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", content); g_free(content); msn_slplink_unleash(slpcall->slplink); } }}voidmsn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset){ GaimXfer *xfer; xfer = slpcall->xfer; xfer->bytes_sent = (offset + len); xfer->bytes_remaining = total_length - (offset + len); gaim_xfer_update_progress(xfer);}voidmsn_xfer_end_cb(MsnSlpCall *slpcall){ if (gaim_xfer_get_status(slpcall->xfer) != GAIM_XFER_STATUS_DONE) { gaim_xfer_cancel_remote(slpcall->xfer); }}voidmsn_xfer_completed_cb(MsnSlpCall *slpcall, const char *body, long long size){ gaim_xfer_set_completed(slpcall->xfer, TRUE);}/************************************************************************** * SLP Control **************************************************************************/#if 0static voidgot_transresp(MsnSlpCall *slpcall, const char *nonce, const char *ips_str, int port){ MsnDirectConn *directconn; char **ip_addrs, **c; directconn = msn_directconn_new(slpcall->slplink); directconn->initial_call = slpcall; /* msn_directconn_parse_nonce(directconn, nonce); */ directconn->nonce = g_strdup(nonce); ip_addrs = g_strsplit(ips_str, " ", -1); for (c = ip_addrs; *c != NULL; c++) { gaim_debug_info("msn", "ip_addr = %s\n", *c); if (msn_directconn_connect(directconn, *c, port)) break; } g_strfreev(ip_addrs);}#endifstatic voidsend_ok(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content){ MsnSlpLink *slplink; MsnSlpMessage *slpmsg; slplink = slpcall->slplink; /* 200 OK */ slpmsg = msn_slpmsg_sip_new(slpcall, 1, "MSNSLP/1.0 200 OK", branch, type, content);#ifdef DEBUG_SLP slpmsg->info = "SLP 200 OK"; slpmsg->text_body = TRUE;#endif msn_slplink_queue_slpmsg(slplink, slpmsg); msn_slp_call_session_init(slpcall);}static voidsend_decline(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content){ MsnSlpLink *slplink; MsnSlpMessage *slpmsg; slplink = slpcall->slplink; /* 603 Decline */ slpmsg = msn_slpmsg_sip_new(slpcall, 1, "MSNSLP/1.0 603 Decline", branch, type, content);#ifdef DEBUG_SLP slpmsg->info = "SLP 603 Decline"; slpmsg->text_body = TRUE;#endif msn_slplink_queue_slpmsg(slplink, slpmsg);}#define MAX_FILE_NAME_LEN 0x226static voidgot_sessionreq(MsnSlpCall *slpcall, const char *branch, const char *euf_guid, const char *context){ if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6")) { /* Emoticon or UserDisplay */ MsnSlpSession *slpsession; MsnSlpLink *slplink; MsnSlpMessage *slpmsg; MsnObject *obj; char *msnobj_data; const char *sha1c; const char *file_name; char *content; int len; int type; /* Send Ok */ content = g_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; gaim_base64_decode(context, &msnobj_data, &len); obj = msn_object_new_from_string(msnobj_data); type = msn_object_get_type(obj); sha1c = msn_object_get_sha1c(obj); g_free(msnobj_data); if (!(type == MSN_OBJECT_USERTILE)) { gaim_debug_error("msn", "Wrong object?\n"); msn_object_destroy(obj); g_return_if_reached(); } file_name = msn_object_get_real_location(obj); if (file_name == NULL) { gaim_debug_error("msn", "Wrong object.\n"); msn_object_destroy(obj); g_return_if_reached(); } slpsession = msn_slplink_find_slp_session(slplink, slpcall->session_id); /* DATA PREP */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpsession = slpsession; slpmsg->session_id = slpsession->id; msn_slpmsg_set_body(slpmsg, NULL, 4);#ifdef DEBUG_SLP slpmsg->info = "SLP DATA PREP";#endif msn_slplink_queue_slpmsg(slplink, slpmsg); /* DATA */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpsession = slpsession; slpmsg->flags = 0x20;#ifdef DEBUG_SLP slpmsg->info = "SLP DATA";#endif msn_slpmsg_open_file(slpmsg, file_name); msn_slplink_queue_slpmsg(slplink, slpmsg); } else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) { /* File Transfer */ GaimAccount *account; GaimXfer *xfer; char *bin; int 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); xfer = gaim_xfer_new(account, GAIM_XFER_RECEIVE, slpcall->slplink->remote_user); gaim_base64_decode(context, &bin, &bin_len); file_size = GUINT32_FROM_LE(*((gsize *)bin + 2)); 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); gaim_xfer_set_filename(xfer, file_name); gaim_xfer_set_size(xfer, file_size); gaim_xfer_set_init_fnc(xfer, msn_xfer_init); gaim_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); slpcall->xfer = xfer; xfer->data = slpcall; gaim_xfer_request(xfer); }}voidsend_bye(MsnSlpCall *slpcall, const char *type){ MsnSlpLink *slplink; MsnSlpMessage *slpmsg; char *header; slplink = slpcall->slplink; g_return_if_fail(slplink != NULL); header = g_strdup_printf("BYE MSNMSGR:%s MSNSLP/1.0", slplink->local_user); slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, "A0D624A6-6C0C-4283-A9E0-BC97B4B46D32", type, "\r\n"); g_free(header);#ifdef DEBUG_SLP slpmsg->info = "SLP BYE"; slpmsg->text_body = TRUE;#endif msn_slplink_queue_slpmsg(slplink, slpmsg);}static voidgot_invite(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content){ MsnSlpLink *slplink; slplink = slpcall->slplink; if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) { char *euf_guid, *context; char *temp; euf_guid = get_token(content, "EUF-GUID: {", "}\r\n"); temp = get_token(content, "SessionID: ", "\r\n"); if (temp != NULL) slpcall->session_id = atoi(temp); g_free(temp); temp = get_token(content, "AppID: ", "\r\n"); if (temp != NULL) slpcall->app_id = atoi(temp); g_free(temp); context = get_token(content, "Context: ", "\r\n"); got_sessionreq(slpcall, branch, euf_guid, context); g_free(context); g_free(euf_guid); } else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) { /* A direct connection? */ char *listening, *nonce; char *content; if (FALSE) {#if 0 MsnDirectConn *directconn; /* const char *ip_addr; */ char *ip_port; int port; /* ip_addr = gaim_prefs_get_string("/core/ft/public_ip"); */ ip_port = "5190"; listening = "true"; nonce = rand_guid(); directconn = msn_directconn_new(slplink); /* msn_directconn_parse_nonce(directconn, nonce); */ directconn->nonce = g_strdup(nonce); msn_directconn_listen(directconn); port = directconn->port; content = g_strdup_printf( "Bridge: TCPv1\r\n" "Listening: %s\r\n" "Nonce: {%s}\r\n" "Ipv4Internal-Addrs: 192.168.0.82\r\n" "Ipv4Internal-Port: %d\r\n" "\r\n", listening, nonce, port);#endif } else { listening = "false"; nonce = g_strdup("00000000-0000-0000-0000-000000000000"); content = g_strdup_printf( "Bridge: TCPv1\r\n" "Listening: %s\r\n" "Nonce: {%s}\r\n" "\r\n", listening, nonce); } send_ok(slpcall, branch, "application/x-msnmsgr-transrespbody", content); g_free(content);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -