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

📄 silc.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  silcpurple.c  Author: Pekka Riikonen <priikone@silcnet.org>  Copyright (C) 2004 - 2005 Pekka Riikonen  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; version 2 of the License.  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.*/#include "silcincludes.h"#include "silcclient.h"#include "silcpurple.h"#include "version.h"#include "wb.h"extern SilcClientOperations ops;static PurplePlugin *silc_plugin = NULL;static const char *silcpurple_list_icon(PurpleAccount *a, PurpleBuddy *b){	return (const char *)"silc";}static GList *silcpurple_away_states(PurpleAccount *account){	PurpleStatusType *type;	GList *types = NULL;	type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_AVAILABLE, NULL, FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_HYPER, _("Hyper Active"), FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_AWAY, NULL, FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, SILCPURPLE_STATUS_ID_BUSY, _("Busy"), FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_INDISPOSED, _("Indisposed"), FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_PAGE, _("Wake Me Up"), FALSE, TRUE, FALSE);	types = g_list_append(types, type);	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, SILCPURPLE_STATUS_ID_OFFLINE, NULL, FALSE, TRUE, FALSE);	types = g_list_append(types, type);	return types;}static voidsilcpurple_set_status(PurpleAccount *account, PurpleStatus *status){	PurpleConnection *gc = purple_account_get_connection(account);	SilcPurple sg = NULL;	SilcUInt32 mode;	SilcBuffer idp;	unsigned char mb[4];	const char *state;	if (gc != NULL)		sg = gc->proto_data;	if (status == NULL)		return;	state = purple_status_get_id(status);	if (state == NULL)		return;	if ((sg == NULL) || (sg->conn == NULL))		return;	mode = sg->conn->local_entry->mode;	mode &= ~(SILC_UMODE_GONE |		  SILC_UMODE_HYPER |		  SILC_UMODE_BUSY |		  SILC_UMODE_INDISPOSED |		  SILC_UMODE_PAGE);	if (!strcmp(state, "hyper"))		mode |= SILC_UMODE_HYPER;	else if (!strcmp(state, "away"))		mode |= SILC_UMODE_GONE;	else if (!strcmp(state, "busy"))		mode |= SILC_UMODE_BUSY;	else if (!strcmp(state, "indisposed"))		mode |= SILC_UMODE_INDISPOSED;	else if (!strcmp(state, "page"))		mode |= SILC_UMODE_PAGE;	/* Send UMODE */	idp = silc_id_payload_encode(sg->conn->local_id, SILC_ID_CLIENT);	SILC_PUT32_MSB(mode, mb);	silc_client_command_send(sg->client, sg->conn, SILC_COMMAND_UMODE,				 ++sg->conn->cmd_ident, 2,				 1, idp->data, idp->len,				 2, mb, sizeof(mb));	silc_buffer_free(idp);}/*************************** Connection Routines *****************************/static voidsilcpurple_keepalive(PurpleConnection *gc){	SilcPurple sg = gc->proto_data;	silc_client_send_packet(sg->client, sg->conn, SILC_PACKET_HEARTBEAT,				NULL, 0);}static gbooleansilcpurple_scheduler(gpointer *context){	SilcPurple sg = (SilcPurple)context;	silc_client_run_one(sg->client);	return TRUE;}static voidsilcpurple_nickname_parse(const char *nickname,			char **ret_nickname){	silc_parse_userfqdn(nickname, ret_nickname, NULL);}static voidsilcpurple_login_connected(gpointer data, gint source, const gchar *error_message){	PurpleConnection *gc = data;	SilcPurple sg;	SilcClient client;	SilcClientConnection conn;	PurpleAccount *account;	SilcClientConnectionParams params;	SilcUInt32 mask;	const char *dfile, *tmp;#ifdef SILC_ATTRIBUTE_USER_ICON	PurpleStoredImage *img;#endif#ifdef HAVE_SYS_UTSNAME_H	struct utsname u;#endif	g_return_if_fail(gc != NULL);	sg = gc->proto_data;	if (source < 0) {		purple_connection_error(gc, _("Connection failed"));		return;	}	client = sg->client;	account = sg->account;	/* Get session detachment data, if available */	memset(&params, 0, sizeof(params));	dfile = silcpurple_session_file(purple_account_get_username(sg->account));	params.detach_data = (unsigned char *)silc_file_readfile(dfile, &params.detach_data_len);	if (params.detach_data)		params.detach_data[params.detach_data_len] = 0;	/* Add connection to SILC client library */	conn = silc_client_add_connection(			  sg->client, &params,			  (char *)purple_account_get_string(account, "server",							  "silc.silcnet.org"),			  purple_account_get_int(account, "port", 706), sg);	if (!conn) {		purple_connection_error(gc, _("Cannot initialize SILC Client connection"));		gc->proto_data = NULL;		return;	}	sg->conn = conn;	/* Progress */	if (params.detach_data) {		purple_connection_update_progress(gc, _("Resuming session"), 2, 5);		sg->resuming = TRUE;	} else {		purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5);	}	/* Perform SILC Key Exchange.  The "silc_connected" will be called	   eventually. */	silc_client_start_key_exchange(sg->client, sg->conn, source);	/* Set default attributes */	mask = SILC_ATTRIBUTE_MOOD_NORMAL;	silc_client_attribute_add(client, conn,				  SILC_ATTRIBUTE_STATUS_MOOD,				  SILC_32_TO_PTR(mask),				  sizeof(SilcUInt32));	mask = SILC_ATTRIBUTE_CONTACT_CHAT;	silc_client_attribute_add(client, conn,				  SILC_ATTRIBUTE_PREFERRED_CONTACT,				  SILC_32_TO_PTR(mask),				  sizeof(SilcUInt32));#ifdef HAVE_SYS_UTSNAME_H	if (!uname(&u)) {		SilcAttributeObjDevice dev;		memset(&dev, 0, sizeof(dev));		dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;		dev.version = u.release;		dev.model = u.sysname;		silc_client_attribute_add(client, conn,					  SILC_ATTRIBUTE_DEVICE_INFO,					  (void *)&dev, sizeof(dev));	}#endif#ifdef _WIN32	tmp = _tzname[0];#else	tmp = tzname[0];#endif	silc_client_attribute_add(client, conn,				  SILC_ATTRIBUTE_TIMEZONE,				  (void *)tmp, strlen(tmp));#ifdef SILC_ATTRIBUTE_USER_ICON	/* Set our buddy icon */	img = purple_buddy_icons_find_account_icon(account);	silcpurple_buddy_set_icon(gc, img);	purple_imgstore_unref(img);#endif	silc_free(params.detach_data);}static voidsilcpurple_login(PurpleAccount *account){	SilcPurple sg;	SilcClient client;	SilcClientParams params;	PurpleConnection *gc;	char pkd[256], prd[256];	const char *cipher, *hmac;	char *realname;	int i;	gc = account->gc;	if (!gc)		return;	gc->proto_data = NULL;	memset(&params, 0, sizeof(params));	strcat(params.nickname_format, "%n@%h%a");	params.nickname_parse = silcpurple_nickname_parse;	params.ignore_requested_attributes = FALSE;	/* Allocate SILC client */	client = silc_client_alloc(&ops, &params, gc, NULL);	if (!client) {		purple_connection_error(gc, _("Out of memory"));		return;	}	/* Get username, real name and local hostname for SILC library */	if (purple_account_get_username(account)) {		const char *u = purple_account_get_username(account);		char **up = g_strsplit(u, "@", 2);		client->username = strdup(up[0]);		g_strfreev(up);	} else {		client->username = silc_get_username();		purple_account_set_username(account, client->username);	}	realname = silc_get_real_name();	if (purple_account_get_user_info(account)) {		client->realname = strdup(purple_account_get_user_info(account));		free(realname);	} else if ((silc_get_real_name() != NULL) && (*realname != '\0')) {		client->realname = realname;		purple_account_set_user_info(account, client->realname);	} else {		free(realname);		client->realname = strdup(_("John Noname"));	}	client->hostname = silc_net_localhost();	purple_connection_set_display_name(gc, client->username);	/* Register requested cipher and HMAC */	cipher = purple_account_get_string(account, "cipher", SILC_DEFAULT_CIPHER);	for (i = 0; silc_default_ciphers[i].name; i++)		if (!strcmp(silc_default_ciphers[i].name, cipher)) {			silc_cipher_register(&(silc_default_ciphers[i]));			break;		}	hmac = purple_account_get_string(account, "hmac", SILC_DEFAULT_HMAC);	for (i = 0; silc_default_hmacs[i].name; i++)		if (!strcmp(silc_default_hmacs[i].name, hmac)) {			silc_hmac_register(&(silc_default_hmacs[i]));			break;		}	/* Init SILC client */	if (!silc_client_init(client)) {		gc->wants_to_die = TRUE;		purple_connection_error(gc, _("Cannot initialize SILC protocol"));		return;	}	/* Check the ~/.silc dir and create it, and new key pair if necessary. */	if (!silcpurple_check_silc_dir(gc)) {		gc->wants_to_die = TRUE;		purple_connection_error(gc, _("Cannot find/access ~/.silc directory"));		return;	}	/* Progress */	purple_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5);	/* Load SILC key pair */	g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());	g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());	if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd),							(char *)purple_account_get_string(account, "private-key", prd),				(gc->password == NULL) ? "" : gc->password, &client->pkcs,				&client->public_key, &client->private_key)) {		g_snprintf(pkd, sizeof(pkd), _("Could not load SILC key pair: %s"), strerror(errno));		purple_connection_error(gc, pkd);		return;	}	sg = silc_calloc(1, sizeof(*sg));	if (!sg)		return;	memset(sg, 0, sizeof(*sg));	sg->client = client;	sg->gc = gc;	sg->account = account;	gc->proto_data = sg;	/* Connect to the SILC server */	if (purple_proxy_connect(gc, account,			       purple_account_get_string(account, "server",						       "silc.silcnet.org"),			       purple_account_get_int(account, "port", 706),			       silcpurple_login_connected, gc) == NULL)	{		purple_connection_error(gc, _("Unable to create connection"));		return;	}	/* Schedule SILC using Glib's event loop */	sg->scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, sg);}static intsilcpurple_close_final(gpointer *context){	SilcPurple sg = (SilcPurple)context;	silc_client_stop(sg->client);	silc_client_free(sg->client);#ifdef HAVE_SILCMIME_H	if (sg->mimeass)		silc_mime_assembler_free(sg->mimeass);#endif	silc_free(sg);	return 0;}static voidsilcpurple_close(PurpleConnection *gc){	SilcPurple sg = gc->proto_data;	g_return_if_fail(sg != NULL);

⌨️ 快捷键说明

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