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

📄 oscar.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * gaim * * 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-2004, Mark Doliner <thekingant@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 "conversation.h"#include "core.h"#include "debug.h"#include "ft.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 "aim.h"#include "md5.h"#define UC_AOL		0x02#define UC_ADMIN	0x04#define UC_UNCONFIRMED	0x08#define UC_NORMAL	0x10#define UC_AB		0x20#define UC_WIRELESS	0x40#define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3"#define OSCAR_CONNECT_STEPS 6#define OSCAR_DEFAULT_CUSTOM_ENCODING "ISO-8859-1"static GaimPlugin *my_protocol = NULL;static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;static fu8_t features_aim[] = {0x01, 0x01, 0x01, 0x02};static fu8_t features_icq[] = {0x01, 0x06};static fu8_t ck[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};typedef struct _OscarData OscarData;struct _OscarData {	aim_session_t *sess;	aim_conn_t *conn;	guint cnpa;	guint paspa;	guint emlpa;	guint icopa;	gboolean iconconnecting;	gboolean set_icon;	GSList *create_rooms;	gboolean conf;	gboolean reqemail;	gboolean setemail;	char *email;	gboolean setnick;	char *newsn;	gboolean chpass;	char *oldp;	char *newp;		GSList *oscar_chats;	GSList *direct_ims;	GSList *file_transfers;	GHashTable *buddyinfo;	GSList *requesticon;	gboolean killme;	gboolean icq;	guint icontimer;	guint getblisttimer;	guint getinfotimer;	struct {		guint maxwatchers; /* max users who can watch you */		guint maxbuddies; /* max users you can watch */		guint maxgroups; /* max groups in server list */		guint maxpermits; /* max users on permit list */		guint maxdenies; /* max users on deny list */		guint maxsiglen; /* max size (bytes) of profile */		guint maxawaymsglen; /* max size (bytes) of posted away message */	} rights;};struct create_room {	char *name;	int exchange;};struct chat_connection {	char *name;	char *show; /* AOL did something funny to us */	fu16_t exchange;	fu16_t instance;	int fd; /* this is redundant since we have the conn below */	aim_conn_t *conn;	int inpa;	int id;	GaimConnection *gc; /* i hate this. */	GaimConversation *conv; /* bah. */	int maxlen;	int maxvis;};struct oscar_direct_im {	GaimConnection *gc;	char name[80];	int watcher;	aim_conn_t *conn;	gboolean connected;	gboolean gpc_pend;	gboolean killme;	gboolean donttryagain;};struct ask_direct {	GaimConnection *gc;	char *sn;	char ip[64];	fu8_t cookie[8];	gboolean donttryagain;};/* * 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 */struct buddyinfo {	gboolean typingnot;	gchar *availmsg;	fu32_t 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 {	GaimConnection *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->gaim callback functions */static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);static int gaim_info_change      (aim_session_t *, aim_frame_t *, ...);static int gaim_account_confirm  (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_oncoming   (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_offgoing   (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_incoming_im(aim_session_t *, aim_frame_t *, ...);static int gaim_parse_misses     (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_userinfo   (aim_session_t *, aim_frame_t *, ...);static int gaim_reqinfo_timeout  (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_motd       (aim_session_t *, aim_frame_t *, ...);static int gaim_chatnav_info     (aim_session_t *, aim_frame_t *, ...);static int gaim_conv_chat_join        (aim_session_t *, aim_frame_t *, ...);static int gaim_conv_chat_leave       (aim_session_t *, aim_frame_t *, ...);static int gaim_conv_chat_info_update (aim_session_t *, aim_frame_t *, ...);static int gaim_conv_chat_incoming_msg(aim_session_t *, aim_frame_t *, ...);static int gaim_email_parseupdate(aim_session_t *, aim_frame_t *, ...);static int gaim_icon_error       (aim_session_t *, aim_frame_t *, ...);static int gaim_icon_parseicon   (aim_session_t *, aim_frame_t *, ...);static int oscar_icon_req        (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_msgack     (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...);static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...);static int gaim_bosrights        (aim_session_t *, aim_frame_t *, ...);static int gaim_connerr          (aim_session_t *, aim_frame_t *, ...);static int conninitdone_admin    (aim_session_t *, aim_frame_t *, ...);static int conninitdone_bos      (aim_session_t *, aim_frame_t *, ...);static int conninitdone_chatnav  (aim_session_t *, aim_frame_t *, ...);static int conninitdone_chat     (aim_session_t *, aim_frame_t *, ...);static int conninitdone_email    (aim_session_t *, aim_frame_t *, ...);static int conninitdone_icon     (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_msgerr     (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_mtn        (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...);static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...);static int gaim_parse_locerr     (aim_session_t *, aim_frame_t *, ...);static int gaim_icbm_param_info  (aim_session_t *, aim_frame_t *, ...);static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...);static int gaim_memrequest       (aim_session_t *, aim_frame_t *, ...);static int gaim_selfinfo         (aim_session_t *, aim_frame_t *, ...);static int gaim_offlinemsg       (aim_session_t *, aim_frame_t *, ...);static int gaim_offlinemsgdone   (aim_session_t *, aim_frame_t *, ...);static int gaim_icqalias         (aim_session_t *, aim_frame_t *, ...);static int gaim_icqinfo          (aim_session_t *, aim_frame_t *, ...);static int gaim_popup            (aim_session_t *, aim_frame_t *, ...);#ifndef NOSSIstatic int gaim_ssi_parseerr     (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_parserights  (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_parselist    (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_parseack     (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_parseadd     (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_authgiven    (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_authrequest  (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_authreply    (aim_session_t *, aim_frame_t *, ...);static int gaim_ssi_gotadded     (aim_session_t *, aim_frame_t *, ...);#endif/* for DirectIM/image transfer */static int gaim_odc_initiate     (aim_session_t *, aim_frame_t *, ...);static int gaim_odc_incoming     (aim_session_t *, aim_frame_t *, ...);static int gaim_odc_typing       (aim_session_t *, aim_frame_t *, ...);static int gaim_odc_update_ui    (aim_session_t *, aim_frame_t *, ...);/* for file transfer */static int oscar_sendfile_estblsh(aim_session_t *, aim_frame_t *, ...);static int oscar_sendfile_prompt (aim_session_t *, aim_frame_t *, ...);static int oscar_sendfile_ack    (aim_session_t *, aim_frame_t *, ...);static int oscar_sendfile_done   (aim_session_t *, aim_frame_t *, ...);/* for icons */static gboolean gaim_icon_timerfunc(gpointer data);/* just because */static void oscar_callback(gpointer data, gint source, GaimInputCondition condition);static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const char *cookie);/* remove these at some point? *//* Because I don't like forward declarations?  I think that was why... */static void oscar_set_info(GaimConnection *gc, const char *text);static void oscar_set_away(GaimConnection *gc, const char *state, const char *message);static void oscar_free_name_data(struct name_data *data) {	g_free(data->name);	g_free(data->nick);	g_free(data);}static void oscar_free_buddyinfo(void *data) {	struct buddyinfo *bi = data;	g_free(bi->availmsg);	g_free(bi);}static fu32_t oscar_charset_check(const char *utf8){	int i = 0;	int charset = AIM_CHARSET_ASCII;	/* 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. */	while (utf8[i]) {		if ((unsigned char)utf8[i] > 0x7f) {			/* not ASCII! */			charset = AIM_CHARSET_CUSTOM;			break;		}		i++;	}	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. */static 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))		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;}static gchar *oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen){	gchar *utf8 = NULL;	if ((encoding == NULL) || encoding[0] == '\0') {		gaim_debug_info("oscar", "Empty encoding, assuming UTF-8\n");	} else if (!strcmp(encoding, "iso-8859-1")                   || !strcmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1")) {		utf8 = g_convert(text, textlen, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);	} else if (!strcmp(encoding, "unicode-2-0")) {		utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);	} else if (strcmp(encoding, "us-ascii") && strcmp(encoding, "utf-8")) {		gaim_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 us-ascii/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 to most likely has a buggy client.)"));		else			utf8 = g_strndup(text, textlen);	}	return utf8;}static gchar *gaim_plugin_oscar_convert_to_utf8(const fu8_t *data, fu16_t datalen, const char *charsetstr, gboolean fallback){	gchar *ret = NULL;	GError *err = NULL;	if ((charsetstr == NULL) || (*charsetstr == '\0'))		return NULL;	if (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) {			gaim_debug_warning("oscar", "Conversation 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);

⌨️ 快捷键说明

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