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

📄 bonjour.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * purple - Bonjour Protocol Plugin * * Purple 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 <glib.h>#ifndef _WIN32#include <pwd.h>#else#define UNICODE#include <windows.h>#include <lm.h>#endif#include "internal.h"#include "account.h"#include "accountopt.h"#include "debug.h"#include "util.h"#include "version.h"#include "bonjour.h"#include "mdns_common.h"#include "jabber.h"#include "buddy.h"/* * TODO: Should implement an add_buddy callback that removes the buddy *       from the local list.  Bonjour manages buddies for you, and *       adding someone locally by hand is stupid.  Or, maybe even better, *       if a PRPL does not have an add_buddy callback then do not allow *       users to add buddies. */static char *default_firstname;static char *default_lastname;static char *default_hostname;static voidbonjour_removeallfromlocal(PurpleConnection *gc){	PurpleAccount *account = purple_connection_get_account(gc);	PurpleBuddyList *blist;	PurpleBlistNode *gnode, *cnode, *cnodenext, *bnode, *bnodenext;	PurpleBuddy *buddy;	blist = purple_get_blist();	if (blist == NULL)		return;	/* Go through and remove all buddies that belong to this account */	for (gnode = blist->root; gnode; gnode = gnode->next)	{		if (!PURPLE_BLIST_NODE_IS_GROUP(gnode))			continue;		for (cnode = gnode->child; cnode; cnode = cnodenext)		{			cnodenext = cnode->next;			if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))				continue;			for (bnode = cnode->child; bnode; bnode = bnodenext)			{				bnodenext = bnode->next;				if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))					continue;				buddy = (PurpleBuddy *)bnode;				if (buddy->account != account)					continue;				purple_prpl_got_user_status(account, buddy->name, "offline", NULL);				purple_blist_remove_buddy(buddy);			}		}	}}static voidbonjour_login(PurpleAccount *account){	PurpleConnection *gc = purple_account_get_connection(account);	PurpleGroup *bonjour_group;	BonjourData *bd;	PurpleStatus *status;	PurplePresence *presence;	gc->flags |= PURPLE_CONNECTION_HTML;	gc->proto_data = bd = g_new0(BonjourData, 1);	/* Start waiting for jabber connections (iChat style) */	bd->jabber_data = g_new(BonjourJabber, 1);	bd->jabber_data->port = BONJOUR_DEFAULT_PORT_INT;	bd->jabber_data->account = account;	if (bonjour_jabber_start(bd->jabber_data) == -1) {		/* Send a message about the connection error */		purple_connection_error(gc, _("Unable to listen for incoming IM connections\n"));		return;	}	/* Connect to the mDNS daemon looking for buddies in the LAN */	bd->dns_sd_data = bonjour_dns_sd_new();	bd->dns_sd_data->first = g_strdup(purple_account_get_string(account, "first", default_firstname));	bd->dns_sd_data->last = g_strdup(purple_account_get_string(account, "last", default_lastname));	bd->dns_sd_data->port_p2pj = bd->jabber_data->port;	/* Not engaged in AV conference */	bd->dns_sd_data->vc = g_strdup("!");	status = purple_account_get_active_status(account);	presence = purple_account_get_presence(account);	if (purple_presence_is_available(presence))		bd->dns_sd_data->status = g_strdup("avail");	else if (purple_presence_is_idle(presence))		bd->dns_sd_data->status = g_strdup("away");	else		bd->dns_sd_data->status = g_strdup("dnd");	bd->dns_sd_data->msg = g_strdup(purple_status_get_attr_string(status, "message"));	bd->dns_sd_data->account = account;	if (!bonjour_dns_sd_start(bd->dns_sd_data))	{		purple_connection_error(gc, _("Unable to establish connection with the local mDNS server.  Is it running?"));		return;	}	/* Create a group for bonjour buddies */	bonjour_group = purple_group_new(BONJOUR_GROUP_NAME);	purple_blist_add_group(bonjour_group, NULL);	/* Show the buddy list by telling Purple we have already connected */	purple_connection_set_state(gc, PURPLE_CONNECTED);}static voidbonjour_close(PurpleConnection *connection){	PurpleGroup *bonjour_group;	BonjourData *bd = connection->proto_data;	/* Stop looking for buddies in the LAN */	if (bd->dns_sd_data != NULL)	{		bonjour_dns_sd_stop(bd->dns_sd_data);		bonjour_dns_sd_free(bd->dns_sd_data);	}	if (bd->jabber_data != NULL)	{		/* Stop waiting for conversations */		bonjour_jabber_stop(bd->jabber_data);		g_free(bd->jabber_data);	}	/* Remove all the bonjour buddies */	bonjour_removeallfromlocal(connection);	/* Delete the bonjour group */	bonjour_group = purple_find_group(BONJOUR_GROUP_NAME);	if (bonjour_group != NULL)		purple_blist_remove_group(bonjour_group);}static const char *bonjour_list_icon(PurpleAccount *account, PurpleBuddy *buddy){	return BONJOUR_ICON_NAME;}static intbonjour_send_im(PurpleConnection *connection, const char *to, const char *msg, PurpleMessageFlags flags){	if(!to || !msg)		return 0;	return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg);}static voidbonjour_set_status(PurpleAccount *account, PurpleStatus *status){	PurpleConnection *gc;	BonjourData *bd;	gboolean disconnected;	PurpleStatusType *type;	int primitive;	PurplePresence *presence;	const char *message, *bonjour_status;	gchar *stripped;	gc = purple_account_get_connection(account);	bd = gc->proto_data;	disconnected = purple_account_is_disconnected(account);	type = purple_status_get_type(status);	primitive = purple_status_type_get_primitive(type);	presence = purple_account_get_presence(account);	message = purple_status_get_attr_string(status, "message");	if (message == NULL)		message = "";	stripped = purple_markup_strip_html(message);	/*	 * The three possible status for Bonjour are	 *   -available ("avail")	 *   -idle ("away")	 *   -away ("dnd")	 * Each of them can have an optional message.	 */	if (purple_presence_is_available(presence))		bonjour_status = "avail";	else if (purple_presence_is_idle(presence))		bonjour_status = "away";	else		bonjour_status = "dnd";	bonjour_dns_sd_send_status(bd->dns_sd_data, bonjour_status, stripped);	g_free(stripped);}static GList *bonjour_status_types(PurpleAccount *account){	GList *status_types = NULL;	PurpleStatusType *type;	g_return_val_if_fail(account != NULL, NULL);	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,										   BONJOUR_STATUS_ID_AVAILABLE,										   NULL, TRUE, TRUE, FALSE,										   "message", _("Message"),										   purple_value_new(PURPLE_TYPE_STRING), NULL);	status_types = g_list_append(status_types, type);	type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,										   BONJOUR_STATUS_ID_AWAY,										   NULL, TRUE, TRUE, FALSE,										   "message", _("Message"),										   purple_value_new(PURPLE_TYPE_STRING), NULL);	status_types = g_list_append(status_types, type);	type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,									 BONJOUR_STATUS_ID_OFFLINE,									 NULL, TRUE, TRUE, FALSE);	status_types = g_list_append(status_types, type);	return status_types;}static voidbonjour_convo_closed(PurpleConnection *connection, const char *who){	PurpleBuddy *buddy = purple_find_buddy(connection->account, who);	BonjourBuddy *bb;	if (buddy == NULL)	{		/*		 * This buddy is not in our buddy list, and therefore does not really		 * exist, so we won't have any data about them.		 */		return;	}	bb = buddy->proto_data;	bonjour_jabber_close_conversation(bb->conversation);	bb->conversation = NULL;}static char *bonjour_status_text(PurpleBuddy *buddy){	PurplePresence *presence;	presence = purple_buddy_get_presence(buddy);	if (purple_presence_is_online(presence) && !purple_presence_is_available(presence))		return g_strdup(_("Away"));	return NULL;}static voidbonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full){	PurplePresence *presence;	PurpleStatus *status;

⌨️ 快捷键说明

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