📄 msn.c
字号:
/** * @file msn.c The MSN protocol plugin * * 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 */#define PHOTO_SUPPORT 1#include <glib.h>#include "msn.h"#include "accountopt.h"#include "msg.h"#include "page.h"#include "pluginpref.h"#include "prefs.h"#include "session.h"#include "state.h"#include "utils.h"#include "prpl.h"#include "util.h"#include "version.h"#include "switchboard.h"#include "notification.h"#include "sync.h"#include "slplink.h"#if PHOTO_SUPPORT#include "imgstore.h"#endif#define BUDDY_ALIAS_MAXLEN 387static GaimPlugin *my_protocol = NULL;typedef struct{ GaimConnection *gc; const char *passport;} MsnMobileData;typedef struct{ GaimConnection *gc; char *name;} MsnGetInfoData;typedef struct{ MsnGetInfoData *info_data; char *stripped; char *url_buffer; GString *s; char *photo_url_text; char *tooltip_text; const char *title;} MsnGetInfoStepTwoData;static const char *msn_normalize(const GaimAccount *account, const char *str){ static char buf[BUF_LEN]; char *tmp; g_return_val_if_fail(str != NULL, NULL); g_snprintf(buf, sizeof(buf), "%s%s", str, (strchr(str, '@') ? "" : "@hotmail.com")); tmp = g_utf8_strdown(buf, -1); strncpy(buf, tmp, sizeof(buf)); g_free(tmp); return buf;}static voidmsn_act_id(GaimConnection *gc, const char *entry){ MsnCmdProc *cmdproc; MsnSession *session; GaimAccount *account; const char *alias; session = gc->proto_data; cmdproc = session->notification->cmdproc; account = gaim_connection_get_account(gc); alias = (entry && *entry) ? entry : ""; if (strlen(alias) > BUDDY_ALIAS_MAXLEN) { gaim_notify_error(gc, NULL, _("Your new MSN friendly name is too long."), NULL); return; } msn_cmdproc_send(cmdproc, "REA", "%s %s", gaim_account_get_username(account), gaim_url_encode(alias));}static voidmsn_set_prp(GaimConnection *gc, const char *type, const char *entry){ MsnCmdProc *cmdproc; MsnSession *session; session = gc->proto_data; cmdproc = session->notification->cmdproc; if (entry == NULL || *entry == '\0') { msn_cmdproc_send(cmdproc, "PRP", "%s", type); } else { msn_cmdproc_send(cmdproc, "PRP", "%s %s", type, gaim_url_encode(entry)); }}static voidmsn_set_home_phone_cb(GaimConnection *gc, const char *entry){ msn_set_prp(gc, "PHH", entry);}static voidmsn_set_work_phone_cb(GaimConnection *gc, const char *entry){ msn_set_prp(gc, "PHW", entry);}static voidmsn_set_mobile_phone_cb(GaimConnection *gc, const char *entry){ msn_set_prp(gc, "PHM", entry);}static voidenable_msn_pages_cb(GaimConnection *gc){ msn_set_prp(gc, "MOB", "Y");}static voiddisable_msn_pages_cb(GaimConnection *gc){ msn_set_prp(gc, "MOB", "N");}static voidsend_to_mobile(GaimConnection *gc, const char *who, const char *entry){ MsnTransaction *trans; MsnSession *session; MsnCmdProc *cmdproc; MsnPage *page; char *payload; size_t payload_len; session = gc->proto_data; cmdproc = session->notification->cmdproc; page = msn_page_new(); msn_page_set_body(page, entry); payload = msn_page_gen_payload(page, &payload_len); trans = msn_transaction_new("PGD", "%s 1 %d", who, payload_len); msn_transaction_set_payload(trans, payload, payload_len); msn_page_destroy(page); msn_cmdproc_send_trans(cmdproc, trans);}static voidsend_to_mobile_cb(MsnMobileData *data, const char *entry){ send_to_mobile(data->gc, data->passport, entry); g_free(data);}static voidclose_mobile_page_cb(MsnMobileData *data, const char *entry){ g_free(data);}/* -- */static voidmsn_show_set_friendly_name(GaimPluginAction *action){ GaimConnection *gc; gc = (GaimConnection *) action->context; gaim_request_input(gc, NULL, _("Set your friendly name."), _("This is the name that other MSN buddies will " "see you as."), gaim_connection_get_display_name(gc), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_act_id), _("Cancel"), NULL, gc);}static voidmsn_show_set_home_phone(GaimPluginAction *action){ GaimConnection *gc; MsnSession *session; gc = (GaimConnection *) action->context; session = gc->proto_data; gaim_request_input(gc, NULL, _("Set your home phone number."), NULL, msn_user_get_home_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_home_phone_cb), _("Cancel"), NULL, gc);}static voidmsn_show_set_work_phone(GaimPluginAction *action){ GaimConnection *gc; MsnSession *session; gc = (GaimConnection *) action->context; session = gc->proto_data; gaim_request_input(gc, NULL, _("Set your work phone number."), NULL, msn_user_get_work_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_work_phone_cb), _("Cancel"), NULL, gc);}static voidmsn_show_set_mobile_phone(GaimPluginAction *action){ GaimConnection *gc; MsnSession *session; gc = (GaimConnection *) action->context; session = gc->proto_data; gaim_request_input(gc, NULL, _("Set your mobile phone number."), NULL, msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL, _("OK"), G_CALLBACK(msn_set_mobile_phone_cb), _("Cancel"), NULL, gc);}static voidmsn_show_set_mobile_pages(GaimPluginAction *action){ GaimConnection *gc; gc = (GaimConnection *) action->context; gaim_request_action(gc, NULL, _("Allow MSN Mobile pages?"), _("Do you want to allow or disallow people on " "your buddy list to send you MSN Mobile pages " "to your cell phone or other mobile device?"), -1, gc, 3, _("Allow"), G_CALLBACK(enable_msn_pages_cb), _("Disallow"), G_CALLBACK(disable_msn_pages_cb), _("Cancel"), NULL);}static voidshow_send_to_mobile_cb(GaimBlistNode *node, gpointer ignored){ GaimBuddy *buddy; GaimConnection *gc; MsnSession *session; MsnMobileData *data; g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); buddy = (GaimBuddy *) node; gc = gaim_account_get_connection(buddy->account); session = gc->proto_data; data = g_new0(MsnMobileData, 1); data->gc = gc; data->passport = buddy->name; gaim_request_input(gc, NULL, _("Send a mobile message."), NULL, NULL, TRUE, FALSE, NULL, _("Page"), G_CALLBACK(send_to_mobile_cb), _("Close"), G_CALLBACK(close_mobile_page_cb), data);}static voidinitiate_chat_cb(GaimBlistNode *node, gpointer data){ GaimBuddy *buddy; GaimConnection *gc; MsnSession *session; MsnSwitchBoard *swboard; g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); buddy = (GaimBuddy *) node; gc = gaim_account_get_connection(buddy->account); session = gc->proto_data; swboard = msn_switchboard_new(session); msn_switchboard_request(swboard); msn_switchboard_request_add_user(swboard, buddy->name); /* TODO: This might move somewhere else, after USR might be */ swboard->chat_id = session->conv_seq++; swboard->conv = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat"); gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), gaim_account_get_username(buddy->account), NULL, GAIM_CBFLAGS_NONE, TRUE);}static voidt_msn_xfer_init(GaimXfer *xfer){ MsnSlpLink *slplink; const char *filename; FILE *fp; filename = gaim_xfer_get_local_filename(xfer); slplink = xfer->data; if ((fp = fopen(filename, "rb")) == NULL) { GaimAccount *account; GaimConnection *gc; const char *who; char *msg; account = slplink->session->account; gc = gaim_account_get_connection(account); who = slplink->remote_user; msg = g_strdup_printf(_("Error reading %s: \n%s.\n"), filename, strerror(errno)); gaim_xfer_error(gaim_xfer_get_type(xfer), who, msg); gaim_xfer_cancel_local(xfer); g_free(msg); return; } fclose(fp); msn_slplink_request_ft(slplink, xfer);}static voidmsn_send_file(GaimConnection *gc, const char *who, const char *file){ MsnSession *session; MsnSlpLink *slplink; GaimXfer *xfer; session = gc->proto_data; xfer = gaim_xfer_new(gc->account, GAIM_XFER_SEND, who); slplink = msn_session_get_slplink(session, who); xfer->data = slplink; gaim_xfer_set_init_fnc(xfer, t_msn_xfer_init); if (file) gaim_xfer_request_accepted(xfer, file); else gaim_xfer_request(xfer);}static gbooleanmsn_can_receive_file(GaimConnection *gc, const char *who){ GaimAccount *account; char *normal; gboolean ret; account = gaim_connection_get_account(gc); normal = g_strdup(msn_normalize(account, gaim_account_get_username(account))); ret = strcmp(normal, msn_normalize(account, who)); g_free(normal); return ret;}/************************************************************************** * Protocol Plugin ops **************************************************************************/static const char *msn_list_icon(GaimAccount *a, GaimBuddy *b){ return "msn";}static voidmsn_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne){ MsnUser *user; char *emblems[4] = { NULL, NULL, NULL, NULL }; int away_type = MSN_AWAY_TYPE(b->uc); int i = 0; user = b->proto_data; if (b->present == GAIM_BUDDY_OFFLINE) emblems[i++] = "offline"; else if (away_type == MSN_BUSY || away_type == MSN_PHONE) emblems[i++] = "occupied"; else if (away_type != 0) emblems[i++] = "away"; if (user == NULL) { emblems[0] = "offline"; } else if (user->mobile) emblems[i++] = "wireless"; *se = emblems[0]; *sw = emblems[1]; *nw = emblems[2]; *ne = emblems[3];}static char *msn_status_text(GaimBuddy *b){ if (b->uc & UC_UNAVAILABLE) return g_strdup(msn_away_get_text(MSN_AWAY_TYPE(b->uc))); return NULL;}static char *msn_tooltip_text(GaimBuddy *b){ GString *s; MsnUser *user; s = g_string_new(""); if (GAIM_BUDDY_IS_ONLINE(b)) { g_string_append_printf(s, _("\n<b>%s:</b> %s"), _("Status"), msn_away_get_text(MSN_AWAY_TYPE(b->uc))); } user = b->proto_data; if (user != NULL) { g_string_append_printf(s, _("\n<b>%s:</b> %s"), _("Has you"), (user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No")); } return g_string_free(s, FALSE);}static GList *msn_away_states(GaimConnection *gc){ GList *m = NULL; m = g_list_append(m, _("Available")); m = g_list_append(m, _("Away From Computer")); m = g_list_append(m, _("Be Right Back")); m = g_list_append(m, _("Busy")); m = g_list_append(m, _("On The Phone")); m = g_list_append(m, _("Out To Lunch")); m = g_list_append(m, _("Hidden")); return m;}static GList *msn_actions(GaimPlugin *plugin, gpointer context){ GList *m = NULL; GaimPluginAction *act; act = gaim_plugin_action_new(_("Set Friendly Name"), msn_show_set_friendly_name); m = g_list_append(m, act); m = g_list_append(m, NULL); act = gaim_plugin_action_new(_("Set Home Phone Number"), msn_show_set_home_phone); m = g_list_append(m, act); act = gaim_plugin_action_new(_("Set Work Phone Number"), msn_show_set_work_phone); m = g_list_append(m, act); act = gaim_plugin_action_new(_("Set Mobile Phone Number"), msn_show_set_mobile_phone); m = g_list_append(m, act); m = g_list_append(m, NULL);#if 0 act = gaim_plugin_action_new(_("Enable/Disable Mobile Devices"), msn_show_set_mobile_support); m = g_list_append(m, act);#endif act = gaim_plugin_action_new(_("Allow/Disallow Mobile Pages"), msn_show_set_mobile_pages); m = g_list_append(m, act); return m;}static GList *msn_buddy_menu(GaimBuddy *buddy){ MsnUser *user; GList *m = NULL; GaimBlistNodeAction *act; g_return_val_if_fail(buddy != NULL, NULL); user = buddy->proto_data; if (user != NULL) { if (user->mobile) { act = gaim_blist_node_action_new(_("Send to Mobile"), show_send_to_mobile_cb, NULL); m = g_list_append(m, act); } } if (g_ascii_strcasecmp(buddy->name, gaim_account_get_username(buddy->account))) { act = gaim_blist_node_action_new(_("Initiate Chat"), initiate_chat_cb, NULL); m = g_list_append(m, act); } return m;}static GList *msn_blist_node_menu(GaimBlistNode *node){ if(GAIM_BLIST_NODE_IS_BUDDY(node)) { return msn_buddy_menu((GaimBuddy *) node); } else { return NULL; }}static voidmsn_login(GaimAccount *account){ GaimConnection *gc; MsnSession *session; const char *username; const char *host; gboolean http_method = FALSE; int port; gc = gaim_account_get_connection(account); if (!gaim_ssl_is_supported()) { gaim_connection_error(gc, _("SSL support is needed for MSN. Please install a supported " "SSL library. See http://gaim.sf.net/faq-ssl.php for more " "information.")); return; } if (gaim_account_get_bool(account, "http_method", FALSE)) { http_method = TRUE; gaim_debug_info("msn", "using http method\n"); host = "gateway.messenger.hotmail.com"; port = 80; } else { host = gaim_account_get_string(account, "server", MSN_SERVER); port = gaim_account_get_int(account, "port", MSN_PORT); } session = msn_session_new(account, host, port, http_method); session->prpl = my_protocol; if (session->http_method) msn_http_session_init(session);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -