Пример #1
0
const char *jabber_normalize(const GaimAccount *account, const char *in)
{
    GaimConnection *gc = account ? account->gc : NULL;
    JabberStream *js = gc ? gc->proto_data : NULL;
    static char buf[3072]; /* maximum legal length of a jabber jid */
    JabberID *jid;
    char *node, *domain;

    jid = jabber_id_new(in);

    if(!jid)
        return NULL;

    node = jid->node ? g_utf8_strdown(jid->node, -1) : NULL;
    domain = g_utf8_strdown(jid->domain, -1);


    if(js && node && jid->resource &&
            jabber_chat_find(js, node, domain))
        g_snprintf(buf, sizeof(buf), "%s@%s/%s", node, domain,
                   jid->resource);
    else
        g_snprintf(buf, sizeof(buf), "%s%s%s", node ? node : "",
                   node ? "@" : "", domain);

    jabber_id_free(jid);
    g_free(node);
    g_free(domain);

    return buf;
}
Пример #2
0
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);

}
Пример #3
0
static void jabber_chat_register_cb(JabberStream *js, const char *from,
                                    JabberIqType type, const char *id,
                                    xmlnode *packet, gpointer data)
{
	xmlnode *query, *x;
	char *msg;
	JabberChat *chat;
	JabberID *jid;

	if (!from)
		return;

	if (type == JABBER_IQ_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")) {
				jabber_x_data_request(js, x, jabber_chat_register_x_data_cb, chat);
				return;
			}
		}
	} else if (type == JABBER_IQ_ERROR) {
		char *msg = jabber_parse_error(js, packet, NULL);

		purple_notify_error(js->gc, _("Registration error"), _("Registration 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);

}
Пример #4
0
static JabberChat *jabber_chat_new(JabberStream *js, const char *room,
                                   const char *server, const char *handle,
                                   const char *password, GHashTable *data)
{
	JabberChat *chat;
	char *jid;

	if (jabber_chat_find(js, room, server) != NULL)
		return NULL;

	chat = g_new0(JabberChat, 1);
	chat->js = js;
	chat->joined = 0;

	chat->room = g_strdup(room);
	chat->server = g_strdup(server);
	chat->handle = g_strdup(handle);

	/* Copy the data hash table to chat->components */
	chat->components = g_hash_table_new_full(g_str_hash, g_str_equal,
			g_free, g_free);
	if (data == NULL) {
		g_hash_table_insert(chat->components, g_strdup("handle"), g_strdup(handle));
		g_hash_table_insert(chat->components, g_strdup("room"), g_strdup(room));
		g_hash_table_insert(chat->components, g_strdup("server"), g_strdup(server));
		/* g_hash_table_insert(chat->components, g_strdup("password"), g_strdup(server)); */
	} else {
		g_hash_table_foreach(data, insert_in_hash_table, chat->components);
	}

	chat->members = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
			(GDestroyNotify)jabber_chat_member_free);

	jid = g_strdup_printf("%s@%s", room, server);
	g_hash_table_insert(js->chats, jid, chat);

	return chat;
}
Пример #5
0
const char *jabber_normalize(const PurpleAccount *account, const char *in)
{
	PurpleConnection *gc = account ? account->gc : NULL;
	JabberStream *js = gc ? gc->proto_data : NULL;
	static char buf[3072]; /* maximum legal length of a jabber jid */
	JabberID *jid;

	jid = jabber_id_new_internal(in, TRUE);
	if(!jid)
		return NULL;

	if(js && jid->node && jid->resource &&
			jabber_chat_find(js, jid->node, jid->domain))
		g_snprintf(buf, sizeof(buf), "%s@%s/%s", jid->node, jid->domain,
				jid->resource);
	else
		g_snprintf(buf, sizeof(buf), "%s%s%s", jid->node ? jid->node : "",
				jid->node ? "@" : "", jid->domain);

	jabber_id_free(jid);

	return buf;
}
Пример #6
0
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
		PurpleGroup *group)
{
	JabberStream *js = gc->proto_data;
	char *who;
	JabberID *jid;
	JabberBuddy *jb;
	JabberBuddyResource *jbr;
	const char *name;

	/* If we haven't received the roster yet, ignore any adds */
	if (js->state != JABBER_STREAM_CONNECTED)
		return;

	name = purple_buddy_get_name(buddy);
	jid = jabber_id_new(name);
	if (jid == NULL) {
		/* TODO: Remove the buddy from the list? */
		return;
	}

	/* Adding a chat room or a chat buddy to the roster is *not* supported. */
	if (jid->node && jabber_chat_find(js, jid->node, jid->domain) != NULL) {
		/*
		 * This is the same thing Bonjour does. If it causes problems, move
		 * it to an idle callback.
		 */
		purple_debug_warning("jabber", "Cowardly refusing to add a MUC user "
		                     "to your buddy list and removing the buddy. "
		                     "Buddies can only be added by real (non-MUC) "
		                     "JID\n");
		purple_blist_remove_buddy(buddy);
		jabber_id_free(jid);
		return;
	}

	who = jabber_id_get_bare_jid(jid);
	if (jid->resource != NULL) {
		/*
		 * If the buddy name added contains a resource, strip that off and
		 * rename the buddy.
		 */
		purple_blist_rename_buddy(buddy, who);
	}

	jb = jabber_buddy_find(js, who, FALSE);

	purple_debug_info("jabber", "jabber_roster_add_buddy(): Adding %s\n", who);

	jabber_roster_update(js, who, NULL);

	if (jb == js->user_jb) {
		jabber_presence_fake_to_self(js, NULL);
	} else if(!jb || !(jb->subscription & JABBER_SUB_TO)) {
		jabber_presence_subscription_set(js, who, "subscribe");
	} else if((jbr =jabber_buddy_find_resource(jb, NULL))) {
		purple_prpl_got_user_status(gc->account, who,
				jabber_buddy_state_get_status_id(jbr->state),
				"priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL);
	}

	g_free(who);
}
Пример #7
0
void jabber_presence_parse(JabberStream *js, xmlnode *packet)
{
	const char *type;
	JabberBuddyResource *jbr = NULL;
	gboolean signal_return, ret;
	JabberPresence presence;
	xmlnode *child;

	memset(&presence, 0, sizeof(presence));
	/* defaults */
	presence.state = JABBER_BUDDY_STATE_UNKNOWN;
	presence.sent = time(NULL);
	/* interesting values */
	presence.from = xmlnode_get_attrib(packet, "from");
	presence.to   = xmlnode_get_attrib(packet, "to");
	type = xmlnode_get_attrib(packet, "type");
	presence.type = str_to_presence_type(type);

	presence.jb = jabber_buddy_find(js, presence.from, TRUE);
	g_return_if_fail(presence.jb != NULL);

	presence.jid_from = jabber_id_new(presence.from);
	if (presence.jid_from == NULL) {
		purple_debug_error("jabber", "Ignoring presence with malformed 'from' "
		                   "JID: %s\n", presence.from);
		return;
	}

	signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(purple_connection_get_prpl(js->gc),
			"jabber-receiving-presence", js->gc, type, presence.from, packet));
	if (signal_return) {
		goto out;
	}

	if (presence.jid_from->node)
		presence.chat = jabber_chat_find(js, presence.jid_from->node,
		                                 presence.jid_from->domain);
	if(presence.jb->error_msg) {
		g_free(presence.jb->error_msg);
		presence.jb->error_msg = NULL;
	}

	if (presence.type == JABBER_PRESENCE_AVAILABLE) {
		presence.state = JABBER_BUDDY_STATE_ONLINE;
	} else if (presence.type == JABBER_PRESENCE_ERROR) {
		/* TODO: Is this handled properly?  Should it be treated as per-jbr? */
		char *msg = jabber_parse_error(js, packet, NULL);
		presence.state = JABBER_BUDDY_STATE_ERROR;
		presence.jb->error_msg = msg ? msg : g_strdup(_("Unknown Error in presence"));
	} else if (presence.type == JABBER_PRESENCE_SUBSCRIBE) {
		/* TODO: Move to handle_subscribe() (so nick is extracted by the
		 * PresenceHandler */
		struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1);
		gboolean onlist = FALSE;
		PurpleAccount *account;
		PurpleBuddy *buddy;
		xmlnode *nick;

		account = purple_connection_get_account(js->gc);
		buddy = purple_find_buddy(account, presence.from);
		nick = xmlnode_get_child_with_namespace(packet, "nick", "http://jabber.org/protocol/nick");
		if (nick)
			presence.nickname = xmlnode_get_data(nick);

		if (buddy) {
			if ((presence.jb->subscription & (JABBER_SUB_TO | JABBER_SUB_PENDING)))
				onlist = TRUE;
		}

		jap->gc = js->gc;
		jap->who = g_strdup(presence.from);
		jap->js = js;

		purple_account_request_authorization(account, presence.from, NULL, presence.nickname,
				NULL, onlist, authorize_add_cb, deny_add_cb, jap);

		goto out;
	} else if (presence.type == JABBER_PRESENCE_SUBSCRIBED) {
Пример #8
0
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);
}