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

📄 chat.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * purple - Jabber Protocol Plugin * * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> * * 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 "debug.h"#include "prpl.h" /* for proto_chat_entry */#include "notify.h"#include "request.h"#include "roomlist.h"#include "util.h"#include "chat.h"#include "iq.h"#include "message.h"#include "presence.h"#include "xdata.h"GList *jabber_chat_info(PurpleConnection *gc){	GList *m = NULL;	struct proto_chat_entry *pce;	pce = g_new0(struct proto_chat_entry, 1);	pce->label = _("_Room:");	pce->identifier = "room";	pce->required = TRUE;	m = g_list_append(m, pce);	pce = g_new0(struct proto_chat_entry, 1);	pce->label = _("_Server:");	pce->identifier = "server";	pce->required = TRUE;	m = g_list_append(m, pce);	pce = g_new0(struct proto_chat_entry, 1);	pce->label = _("_Handle:");	pce->identifier = "handle";	pce->required = TRUE;	m = g_list_append(m, pce);	pce = g_new0(struct proto_chat_entry, 1);	pce->label = _("_Password:");	pce->identifier = "password";	pce->secret = TRUE;	m = g_list_append(m, pce);	return m;}GHashTable *jabber_chat_info_defaults(PurpleConnection *gc, const char *chat_name){	GHashTable *defaults;	JabberStream *js = gc->proto_data;	defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);	g_hash_table_insert(defaults, "handle", g_strdup(js->user->node));	if (js->chat_servers)		g_hash_table_insert(defaults, "server", g_strdup(js->chat_servers->data));	if (chat_name != NULL) {		JabberID *jid = jabber_id_new(chat_name);		if(jid) {			g_hash_table_insert(defaults, "room", g_strdup(jid->node));			if(jid->domain)				g_hash_table_replace(defaults, "server", g_strdup(jid->domain));			if(jid->resource)				g_hash_table_replace(defaults, "handle", g_strdup(jid->resource));			jabber_id_free(jid);		}	}	return defaults;}JabberChat *jabber_chat_find(JabberStream *js, const char *room,		const char *server){	JabberChat *chat = NULL;	char *room_jid;	if(NULL != js->chats)	{		room_jid = g_strdup_printf("%s@%s", room, server);		chat = g_hash_table_lookup(js->chats, jabber_normalize(NULL, room_jid));		g_free(room_jid);	}	return chat;}struct _find_by_id_data {	int id;	JabberChat *chat;};static void find_by_id_foreach_cb(gpointer key, gpointer value, gpointer user_data){	JabberChat *chat = value;	struct _find_by_id_data *fbid = user_data;	if(chat->id == fbid->id)		fbid->chat = chat;}JabberChat *jabber_chat_find_by_id(JabberStream *js, int id){	JabberChat *chat;	struct _find_by_id_data *fbid = g_new0(struct _find_by_id_data, 1);	fbid->id = id;	g_hash_table_foreach(js->chats, find_by_id_foreach_cb, fbid);	chat = fbid->chat;	g_free(fbid);	return chat;}JabberChat *jabber_chat_find_by_conv(PurpleConversation *conv){	PurpleAccount *account = purple_conversation_get_account(conv);	PurpleConnection *gc = purple_account_get_connection(account);	JabberStream *js = gc->proto_data;	int id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));	return jabber_chat_find_by_id(js, id);}void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,		const char *name){	JabberStream *js = gc->proto_data;	JabberChat *chat;	xmlnode *message, *body, *x, *invite;	char *room_jid;	chat = jabber_chat_find_by_id(js, id);	if(!chat)		return;	message = xmlnode_new("message");	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);	if(chat->muc) {		xmlnode_set_attrib(message, "to", room_jid);		x = xmlnode_new_child(message, "x");		xmlnode_set_namespace(x, "http://jabber.org/protocol/muc#user");		invite = xmlnode_new_child(x, "invite");		xmlnode_set_attrib(invite, "to", name);		body = xmlnode_new_child(invite, "reason");		xmlnode_insert_data(body, msg, -1);	} else {		xmlnode_set_attrib(message, "to", name);		body = xmlnode_new_child(message, "body");		xmlnode_insert_data(body, msg, -1);		x = xmlnode_new_child(message, "x");		xmlnode_set_attrib(x, "jid", room_jid);		xmlnode_set_namespace(x, "jabber:x:conference");	}	jabber_send(js, message);	xmlnode_free(message);	g_free(room_jid);}void jabber_chat_member_free(JabberChatMember *jcm);char *jabber_get_chat_name(GHashTable *data) {	char *room, *server, *chat_name = NULL;	room = g_hash_table_lookup(data, "room");	server = g_hash_table_lookup(data, "server");	if (room && server) {		chat_name = g_strdup_printf("%s@%s", room, server);	}	return chat_name;}void jabber_chat_join(PurpleConnection *gc, GHashTable *data){	JabberChat *chat;	char *room, *server, *handle, *passwd;	xmlnode *presence, *x;	char *tmp, *room_jid, *full_jid;	JabberStream *js = gc->proto_data;	PurplePresence *gpresence;	PurpleStatus *status;	JabberBuddyState state;	char *msg;	int priority;	room = g_hash_table_lookup(data, "room");	server = g_hash_table_lookup(data, "server");	handle = g_hash_table_lookup(data, "handle");	passwd = g_hash_table_lookup(data, "password");	if(!room || !server)		return;	if(!handle)		handle = js->user->node;	if(!jabber_nodeprep_validate(room)) {		char *buf = g_strdup_printf(_("%s is not a valid room name"), room);		purple_notify_error(gc, _("Invalid Room Name"), _("Invalid Room Name"),				buf);		g_free(buf);		return;	} else if(!jabber_nameprep_validate(server)) {		char *buf = g_strdup_printf(_("%s is not a valid server name"), server);		purple_notify_error(gc, _("Invalid Server Name"),				_("Invalid Server Name"), buf);		g_free(buf);		return;	} else if(!jabber_resourceprep_validate(handle)) {		char *buf = g_strdup_printf(_("%s is not a valid room handle"), handle);		purple_notify_error(gc, _("Invalid Room Handle"),				_("Invalid Room Handle"), buf);	}	if(jabber_chat_find(js, room, server))		return;	tmp = g_strdup_printf("%s@%s", room, server);	room_jid = g_strdup(jabber_normalize(NULL, tmp));	g_free(tmp);	chat = g_new0(JabberChat, 1);	chat->js = gc->proto_data;	chat->room = g_strdup(room);	chat->server = g_strdup(server);	chat->handle = g_strdup(handle);	chat->members = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,			(GDestroyNotify)jabber_chat_member_free);	g_hash_table_insert(js->chats, room_jid, chat);	gpresence = purple_account_get_presence(gc->account);	status = purple_presence_get_active_status(gpresence);	purple_status_to_jabber(status, &state, &msg, &priority);	presence = jabber_presence_create(state, msg, priority);	full_jid = g_strdup_printf("%s/%s", room_jid, handle);	xmlnode_set_attrib(presence, "to", full_jid);	g_free(full_jid);	g_free(msg);	x = xmlnode_new_child(presence, "x");	xmlnode_set_namespace(x, "http://jabber.org/protocol/muc");	if(passwd && *passwd) {		xmlnode *password = xmlnode_new_child(x, "password");		xmlnode_insert_data(password, passwd, -1);	}	jabber_send(js, presence);	xmlnode_free(presence);}void jabber_chat_leave(PurpleConnection *gc, int id){	JabberStream *js = gc->proto_data;	JabberChat *chat = jabber_chat_find_by_id(js, id);	if(!chat)		return;	jabber_chat_part(chat, NULL);	chat->conv = NULL;}void jabber_chat_destroy(JabberChat *chat){	JabberStream *js = chat->js;	char *room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);	g_hash_table_remove(js->chats, jabber_normalize(NULL, room_jid));	g_free(room_jid);}void jabber_chat_free(JabberChat *chat){	if(chat->config_dialog_handle)		purple_request_close(chat->config_dialog_type, chat->config_dialog_handle);	g_free(chat->room);	g_free(chat->server);	g_free(chat->handle);	g_hash_table_destroy(chat->members);	g_free(chat);}gboolean jabber_chat_find_buddy(PurpleConversation *conv, const char *name){	return purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), name);}char *jabber_chat_buddy_real_name(PurpleConnection *gc, int id, const char *who){	JabberStream *js = gc->proto_data;	JabberChat *chat;	chat = jabber_chat_find_by_id(js, id);	if(!chat)		return NULL;	return g_strdup_printf("%s@%s/%s", chat->room, chat->server, who);}static void jabber_chat_room_configure_x_data_cb(JabberStream *js, xmlnode *result, gpointer data){	JabberChat *chat = data;	xmlnode *query;	JabberIq *iq;	char *to = g_strdup_printf("%s@%s", chat->room, chat->server);	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "http://jabber.org/protocol/muc#owner");	xmlnode_set_attrib(iq->node, "to", to);	g_free(to);	query = xmlnode_get_child(iq->node, "query");	xmlnode_insert_child(query, result);	jabber_iq_send(iq);}static void jabber_chat_room_configure_cb(JabberStream *js, xmlnode *packet, gpointer data){	xmlnode *query, *x;	const char *type = xmlnode_get_attrib(packet, "type");	const char *from = xmlnode_get_attrib(packet, "from");	char *msg;	JabberChat *chat;	JabberID *jid;	if(!type || !from)		return;	if(!strcmp(type, "result")) {		jid = jabber_id_new(from);		if(!jid)			return;		chat = jabber_chat_find(js, jid->node, jid->domain);		jabber_id_free(jid);		if(!chat)			return;		if(!(query = xmlnode_get_child(packet, "query")))			return;		for(x = xmlnode_get_child(query, "x"); x; x = xmlnode_get_next_twin(x)) {			const char *xmlns;			if(!(xmlns = xmlnode_get_namespace(x)))				continue;			if(!strcmp(xmlns, "jabber:x:data")) {				chat->config_dialog_type = PURPLE_REQUEST_FIELDS;				chat->config_dialog_handle = jabber_x_data_request(js, x, jabber_chat_room_configure_x_data_cb, chat);				return;			}		}	} else if(!strcmp(type, "error")) {		char *msg = jabber_parse_error(js, packet);		purple_notify_error(js->gc, _("Configuration error"), _("Configuration error"), msg);		if(msg)			g_free(msg);		return;	}	msg = g_strdup_printf("Unable to configure room %s", from);	purple_notify_info(js->gc, _("Unable to configure"), _("Unable to configure"), msg);	g_free(msg);}void jabber_chat_request_room_configure(JabberChat *chat) {	JabberIq *iq;	char *room_jid;	if(!chat)		return;	chat->config_dialog_handle = NULL;	if(!chat->muc) {		purple_notify_error(chat->js->gc, _("Room Configuration Error"), _("Room Configuration Error"),				_("This room is not capable of being configured"));		return;	}	iq = jabber_iq_new_query(chat->js, JABBER_IQ_GET,			"http://jabber.org/protocol/muc#owner");	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);	xmlnode_set_attrib(iq->node, "to", room_jid);	jabber_iq_set_callback(iq, jabber_chat_room_configure_cb, NULL);	jabber_iq_send(iq);	g_free(room_jid);}void jabber_chat_create_instant_room(JabberChat *chat) {	JabberIq *iq;	xmlnode *query, *x;	char *room_jid;	if(!chat)		return;	chat->config_dialog_handle = NULL;	iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET,			"http://jabber.org/protocol/muc#owner");	query = xmlnode_get_child(iq->node, "query");	x = xmlnode_new_child(query, "x");	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);	xmlnode_set_attrib(iq->node, "to", room_jid);	xmlnode_set_namespace(x, "jabber:x:data");	xmlnode_set_attrib(x, "type", "submit");	jabber_iq_send(iq);	g_free(room_jid);}static void jabber_chat_register_x_data_result_cb(JabberStream *js, xmlnode *packet, gpointer data){	const char *type = xmlnode_get_attrib(packet, "type");	if(type && !strcmp(type, "error")) {		char *msg = jabber_parse_error(js, packet);		purple_notify_error(js->gc, _("Registration error"), _("Registration error"), msg);		if(msg)			g_free(msg);		return;	}}static void jabber_chat_register_x_data_cb(JabberStream *js, xmlnode *result, gpointer data){	JabberChat *chat = data;	xmlnode *query;	JabberIq *iq;	char *to = g_strdup_printf("%s@%s", chat->room, chat->server);	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register");	xmlnode_set_attrib(iq->node, "to", to);	g_free(to);	query = xmlnode_get_child(iq->node, "query");	xmlnode_insert_child(query, result);	jabber_iq_set_callback(iq, jabber_chat_register_x_data_result_cb, NULL);	jabber_iq_send(iq);}static void jabber_chat_register_cb(JabberStream *js, xmlnode *packet, gpointer data){	xmlnode *query, *x;	const char *type = xmlnode_get_attrib(packet, "type");	const char *from = xmlnode_get_attrib(packet, "from");	char *msg;	JabberChat *chat;	JabberID *jid;	if(!type || !from)

⌨️ 快捷键说明

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