⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oscar.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * purple * * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> * Some code copyright (C) 1999-2001, Eric Warmenhoven * Some code copyright (C) 2001-2003, Sean Egan * Some code copyright (C) 2001-2005, Mark Doliner <thekingant@users.sourceforge.net> * Some code copyright (C) 2005, Jonathan Clark <ardentlygnarly@users.sourceforge.net> * * Most libfaim code copyright (C) 1998-2001 Adam Fritzler <afritz@auk.cx> * Some libfaim code copyright (C) 2001-2004 Mark Doliner <thekingant@users.sourceforge.net> * * 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 "internal.h"#include "account.h"#include "accountopt.h"#include "buddyicon.h"#include "cipher.h"#include "conversation.h"#include "core.h"#include "debug.h"#include "imgstore.h"#include "network.h"#include "notify.h"#include "privacy.h"#include "prpl.h"#include "proxy.h"#include "request.h"#include "util.h"#include "version.h"#include "oscarcommon.h"#include "oscar.h"#include "peer.h"#define OSCAR_STATUS_ID_INVISIBLE   "invisible"#define OSCAR_STATUS_ID_OFFLINE     "offline"#define OSCAR_STATUS_ID_AVAILABLE   "available"#define OSCAR_STATUS_ID_AWAY        "away"#define OSCAR_STATUS_ID_DND         "dnd"#define OSCAR_STATUS_ID_NA          "na"#define OSCAR_STATUS_ID_OCCUPIED    "occupied"#define OSCAR_STATUS_ID_FREE4CHAT   "free4chat"#define OSCAR_STATUS_ID_CUSTOM      "custom"#define OSCAR_STATUS_ID_MOBILE	    "mobile"#define AIMHASHDATA "http://pidgin.im/aim_data.php3"#define OSCAR_CONNECT_STEPS 6static OscarCapability purple_caps = OSCAR_CAPABILITY_CHAT | OSCAR_CAPABILITY_BUDDYICON | OSCAR_CAPABILITY_DIRECTIM | OSCAR_CAPABILITY_SENDFILE | OSCAR_CAPABILITY_UNICODE | OSCAR_CAPABILITY_INTEROPERATE | OSCAR_CAPABILITY_ICHAT;static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02};static guint8 features_icq[] = {0x01, 0x06};static guint8 features_icq_offline[] = {0x01};static guint8 ck[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};struct create_room {	char *name;	int exchange;};struct oscar_ask_directim_data{	OscarData *od;	char *who;};/* * Various PRPL-specific buddy info that we want to keep track of * Some other info is maintained by locate.c, and I'd like to move * the rest of this to libfaim, mostly im.c * * TODO: More of this should use the status API. */struct buddyinfo {	gboolean typingnot;	guint32 ipaddr;	unsigned long ico_me_len;	unsigned long ico_me_csum;	time_t ico_me_time;	gboolean ico_informed;	unsigned long ico_len;	unsigned long ico_csum;	time_t ico_time;	gboolean ico_need;	gboolean ico_sent;};struct name_data {	PurpleConnection *gc;	gchar *name;	gchar *nick;};static char *msgerrreason[] = {	N_("Invalid error"),	N_("Invalid SNAC"),	N_("Rate to host"),	N_("Rate to client"),	N_("Not logged in"),	N_("Service unavailable"),	N_("Service not defined"),	N_("Obsolete SNAC"),	N_("Not supported by host"),	N_("Not supported by client"),	N_("Refused by client"),	N_("Reply too big"),	N_("Responses lost"),	N_("Request denied"),	N_("Busted SNAC payload"),	N_("Insufficient rights"),	N_("In local permit/deny"),	N_("Too evil (sender)"),	N_("Too evil (receiver)"),	N_("User temporarily unavailable"),	N_("No match"),	N_("List overflow"),	N_("Request ambiguous"),	N_("Queue full"),	N_("Not while on AOL")};static int msgerrreasonlen = 25;/* All the libfaim->purple callback functions */static int purple_parse_auth_resp  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_login      (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_auth_securid_request(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_handle_redirect  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_info_change      (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_account_confirm  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_oncoming   (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_offgoing   (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_incoming_im(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_misses     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_userinfo   (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_got_infoblock    (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_motd       (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_chatnav_info     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_conv_chat_join        (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_conv_chat_leave       (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_conv_chat_info_update (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_conv_chat_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_icon_error       (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_icon_parseicon   (OscarData *, FlapConnection *, FlapFrame *, ...);static int oscar_icon_req        (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_msgack     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_ratechange (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_bosrights        (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_connerr          (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_msgerr     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_mtn        (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_locaterights(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_locerr     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_icbm_param_info  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_memrequest       (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_selfinfo         (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_offlinemsg       (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_offlinemsgdone   (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_icqalias         (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_icqinfo          (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_popup            (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_parseerr     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_parserights  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_parselist    (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_parseack     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_parseadd     (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_authgiven    (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_authrequest  (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_authreply    (OscarData *, FlapConnection *, FlapFrame *, ...);static int purple_ssi_gotadded     (OscarData *, FlapConnection *, FlapFrame *, ...);static gboolean purple_icon_timerfunc(gpointer data);static void recent_buddies_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data);void oscar_set_info(PurpleConnection *gc, const char *info);static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status);static void oscar_set_extendedstatus(PurpleConnection *gc);static void oscar_format_screenname(PurpleConnection *gc, const char *nick); static gboolean purple_ssi_rerequestdata(gpointer data);static void oscar_free_name_data(struct name_data *data) {	g_free(data->name);	g_free(data->nick);	g_free(data);}#ifdef _WIN32const char *oscar_get_locale_charset(void) {	static const char *charset = NULL;	if (charset == NULL)		g_get_charset(&charset);	return charset;}#endif/** * Determine how we can send this message.  Per the warnings elsewhere * in this file, these little checks determine the simplest encoding * we can use for a given message send using it. */static guint32oscar_charset_check(const char *utf8){	int i = 0;	int charset = AIM_CHARSET_ASCII;	/*	 * Can we get away with using our custom encoding?	 */	while (utf8[i])	{		if ((unsigned char)utf8[i] > 0x7f) {			/* not ASCII! */			charset = AIM_CHARSET_CUSTOM;			break;		}		i++;	}	/*	 * Must we send this message as UNICODE (in the UCS-2BE encoding)?	 */	while (utf8[i])	{		/* ISO-8859-1 is 0x00-0xbf in the first byte		 * followed by 0xc0-0xc3 in the second */		if ((unsigned char)utf8[i] < 0x80) {			i++;			continue;		} else if (((unsigned char)utf8[i] & 0xfc) == 0xc0 &&				   ((unsigned char)utf8[i + 1] & 0xc0) == 0x80) {			i += 2;			continue;		}		charset = AIM_CHARSET_UNICODE;		break;	}	return charset;}/** * Take a string of the form charset="bleh" where bleh is * one of us-ascii, utf-8, iso-8859-1, or unicode-2-0, and * return a newly allocated string containing bleh. */gchar *oscar_encoding_extract(const char *encoding){	gchar *ret = NULL;	char *begin, *end;	g_return_val_if_fail(encoding != NULL, NULL);	/* Make sure encoding begins with charset= */	if (strncmp(encoding, "text/aolrtf; charset=", 21) &&		strncmp(encoding, "text/x-aolrtf; charset=", 23) &&		strncmp(encoding, "text/plain; charset=", 20))	{		return NULL;	}	begin = strchr(encoding, '"');	end = strrchr(encoding, '"');	if ((begin == NULL) || (end == NULL) || (begin >= end))		return NULL;	ret = g_strndup(begin+1, (end-1) - begin);	return ret;}gchar *oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen){	gchar *utf8 = NULL;	if ((encoding == NULL) || encoding[0] == '\0') {		purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");	} else if (!g_ascii_strcasecmp(encoding, "iso-8859-1")) {		utf8 = g_convert(text, textlen, "UTF-8", "iso-8859-1", NULL, NULL, NULL);	} else if (!g_ascii_strcasecmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1") ||	           !g_ascii_strcasecmp(encoding, "us-ascii"))	{		utf8 = g_convert(text, textlen, "UTF-8", "Windows-1252", NULL, NULL, NULL);	} else if (!g_ascii_strcasecmp(encoding, "unicode-2-0")) {		/* Some official ICQ clients are apparently total crack,		 * and have been known to save a UTF-8 string converted		 * from the locale character set to UCS-2 (not from UTF-8		 * to UCS-2!) in the away message.  This hack should find		 * and do something (un)reasonable with that, and not		 * mess up too much else. */		const gchar *charset = purple_account_get_string(account, "encoding", NULL);		if (charset) {			gsize len;			utf8 = g_convert(text, textlen, charset, "UCS-2BE", &len, NULL, NULL);			if (!utf8 || len != textlen || !g_utf8_validate(utf8, -1, NULL)) {				g_free(utf8);				utf8 = NULL;			} else {				purple_debug_info("oscar", "Used broken ICQ fallback encoding\n");			}		}		if (!utf8)			utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);	} else if (g_ascii_strcasecmp(encoding, "utf-8")) {		purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", "						   "attempting to convert to UTF-8 anyway\n", encoding);		utf8 = g_convert(text, textlen, "UTF-8", encoding, NULL, NULL, NULL);	}	/*	 * If utf8 is still NULL then either the encoding is utf-8 or	 * we have been unable to convert the text to utf-8 from the encoding	 * that was specified.  So we check if the text is valid utf-8 then	 * just copy it.	 */	if (utf8 == NULL) {		if (textlen != 0 && *text != '\0'				&& !g_utf8_validate(text, textlen, NULL))			utf8 = g_strdup(_("(There was an error receiving this message.  The buddy you are speaking with is probably using a different encoding than expected.  If you know what encoding he is using, you can specify it in the advanced account options for your AIM/ICQ account.)"));		else			utf8 = g_strndup(text, textlen);	}	return utf8;}static gchar *oscar_utf8_try_convert(PurpleAccount *account, const gchar *msg){	const char *charset = NULL;	char *ret = NULL;	if(aim_sn_is_icq(purple_account_get_username(account)))		charset = purple_account_get_string(account, "encoding", NULL);	if(charset && *charset)		ret = g_convert(msg, -1, "UTF-8", charset, NULL, NULL, NULL);	if(!ret)		ret = purple_utf8_try_convert(msg);	return ret;}static gchar *purple_plugin_oscar_convert_to_utf8(const gchar *data, gsize datalen, const char *charsetstr, gboolean fallback){	gchar *ret = NULL;	GError *err = NULL;	if ((charsetstr == NULL) || (*charsetstr == '\0'))		return NULL;	if (g_ascii_strcasecmp("UTF-8", charsetstr)) {		if (fallback)			ret = g_convert_with_fallback(data, datalen, "UTF-8", charsetstr, "?", NULL, NULL, &err);		else			ret = g_convert(data, datalen, "UTF-8", charsetstr, NULL, NULL, &err);		if (err != NULL) {			purple_debug_warning("oscar", "Conversion from %s failed: %s.\n",							   charsetstr, err->message);			g_error_free(err);		}	} else {		if (g_utf8_validate(data, datalen, NULL))			ret = g_strndup(data, datalen);		else			purple_debug_warning("oscar", "String is not valid UTF-8.\n");	}	return ret;}/** * This attemps to decode an incoming IM into a UTF8 string. * * We try decoding using two different character sets.  The charset * specified in the IM determines the order in which we attempt to * decode.  We do this because there are lots of broken ICQ clients * that don't correctly send non-ASCII messages.  And if Purple isn't * able to deal with that crap, then people complain like banshees. * charsetstr1 is always set to what the correct encoding should be. */gchar *purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcesn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -