Beispiel #1
0
xmlnode *xmlnode_copy(xmlnode *src)
{
	xmlnode *ret;
	xmlnode *child;
	xmlnode *sibling = NULL;

	if(!src)
		return NULL;

	ret = new_node(src->name, src->type);
	if(src->data) {
		if(src->data_sz) {
			ret->data = g_memdup(src->data, src->data_sz);
			ret->data_sz = src->data_sz;
		} else {
			ret->data = g_strdup(src->data);
		}
	}

	for(child = src->child; child; child = child->next) {
		if(sibling) {
			sibling->next = xmlnode_copy(child);
			sibling = sibling->next;
		} else {
			ret->child = xmlnode_copy(child);
			sibling = ret->child;
		}
		sibling->parent = ret;
	}

	return ret;
}
Beispiel #2
0
static void twitter_send_xml_request_with_cursor_cb(TwitterRequestor * r, xmlnode * node, gpointer user_data)
{
    TwitterRequestWithCursorData *request_data = user_data;
    gchar          *next_cursor_str;

    next_cursor_str = xmlnode_get_child_data(node, "next_cursor");
    if (next_cursor_str) {
        request_data->next_cursor = strtoll(next_cursor_str, NULL, 10);
        g_free(next_cursor_str);
    } else {
        request_data->next_cursor = 0;
    }

    purple_debug_info(purple_account_get_protocol_id(r->account), "%s next_cursor: %lld\n", G_STRFUNC, request_data->next_cursor);

	request_data->nodes = g_list_prepend(request_data->nodes, xmlnode_copy(node));

    if (request_data->next_cursor) {
        int             len = request_data->params->len;
        twitter_request_params_add(request_data->params, twitter_request_param_new_ll("cursor", request_data->next_cursor));

        twitter_send_xml_request(r, FALSE, request_data->url, request_data->params, twitter_send_xml_request_with_cursor_cb, twitter_send_xml_request_with_cursor_error_cb, request_data);

        twitter_request_params_set_size(request_data->params, len);
    } else {
        request_data->success_callback(r, request_data->nodes, request_data->user_data);
        twitter_request_with_cursor_data_free(request_data);
    }
}
static gboolean
google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
{
	const gchar *xmlns;
	GoogleAVSessionData *session_data =
		(GoogleAVSessionData *) session->session_data;
	
	if (session->state != UNINIT) {
		purple_debug_error("jabber", "Received initiate for active session.\n");
		return FALSE;
	}

	session->description = xmlnode_copy(xmlnode_get_child(sess, "description"));
	xmlns = xmlnode_get_namespace(session->description);

	if (purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE))
		session_data->video = FALSE;
	else if (purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO))
		session_data->video = TRUE;
	else {
		purple_debug_error("jabber", "Received initiate with "
				"invalid namespace %s.\n", xmlns);
		return FALSE;
	}

	session_data->media = purple_media_manager_create_media(
			purple_media_manager_get(),
			purple_connection_get_account(js->gc),
			"fsrtpconference", session->remote_jid, FALSE);

	purple_media_set_prpl_data(session_data->media, session);

	g_signal_connect_swapped(G_OBJECT(session_data->media),
			"candidates-prepared",
			G_CALLBACK(google_session_ready), session);
	g_signal_connect_swapped(G_OBJECT(session_data->media), "codecs-changed",
			G_CALLBACK(google_session_ready), session);
	g_signal_connect(G_OBJECT(session_data->media), "state-changed",
			G_CALLBACK(google_session_state_changed_cb), session);
	g_signal_connect(G_OBJECT(session_data->media), "stream-info",
			G_CALLBACK(google_session_stream_info_cb), session);

	session->iq_id = g_strdup(iq_id);
	
	if (js->google_relay_host && js->google_relay_token) {
		jabber_google_do_relay_request(js, session, 
			jabber_google_relay_response_session_handle_initiate_cb);
	} else {
		jabber_google_relay_response_session_handle_initiate_cb(session, NULL,
			0, 0, 0, NULL, NULL);
	}

	return TRUE;
}
Beispiel #4
0
static gboolean twitter_send_request_multipage_all_success_cb(PurpleAccount *acct, xmlnode *node, gboolean last_page, gpointer user_data)
{
	TwitterMultiPageAllRequestData *request_data_all = user_data;
	request_data_all->nodes = g_list_append(request_data_all->nodes, xmlnode_copy(node)); //TODO: update
	if (last_page)
	{
		request_data_all->success_callback(acct, request_data_all->nodes, request_data_all->user_data);
		twitter_multipage_all_request_data_free(request_data_all);
	}
	return TRUE;
}
Beispiel #5
0
xmlnode *
xmlnode_copy(const xmlnode *src)
{
	xmlnode *ret;
	xmlnode *child;
	xmlnode *sibling = NULL;

	g_return_val_if_fail(src != NULL, NULL);

	ret = new_node(src->name, src->type);
	ret->xmlns = g_strdup(src->xmlns);
	if (src->data) {
		if (src->data_sz) {
			ret->data = g_memdup(src->data, src->data_sz);
			ret->data_sz = src->data_sz;
		} else {
			ret->data = g_strdup(src->data);
		}
	}
	ret->prefix = g_strdup(src->prefix);
	if (src->namespace_map) {
		ret->namespace_map = g_hash_table_new_full(g_str_hash, g_str_equal,
		                                           g_free, g_free);
		g_hash_table_foreach(src->namespace_map, xmlnode_copy_foreach_ns, ret->namespace_map);
	}

	for (child = src->child; child; child = child->next) {
		if (sibling) {
			sibling->next = xmlnode_copy(child);
			sibling = sibling->next;
		} else {
			ret->child = xmlnode_copy(child);
			sibling = ret->child;
		}
		sibling->parent = ret;
	}

	ret->lastchild = sibling;

	return ret;
}
Beispiel #6
0
/**
 * Create and insert an identical twin
 *
 * Creates a copy of the specified node and inserts it right after
 * this original node.
 *
 * @param node	The node to clone
 * @return	A pointer to the new, cloned twin if successful
 *		or NULL otherwise.
 */
static xmlnode *
xmlnode_insert_twin_copy(xmlnode *node) {
	xmlnode *copy;

	g_return_val_if_fail(node != NULL, NULL);

	copy = xmlnode_copy(node);
	g_return_val_if_fail(copy != NULL, NULL);

	copy->next = node->next;
	node->next = copy;

	return copy;
}
Beispiel #7
0
void
xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
{
	const char *type, *from, *iq_id, *sid;
	xmlnode *query, *streamhost;
	BonjourData *bd;
	PurpleXfer *xfer;

	g_return_if_fail(pc != NULL);
	g_return_if_fail(packet != NULL);
	g_return_if_fail(pb != NULL);

	bd = (BonjourData*) pc->proto_data;
	if(bd == NULL)
		return;

	purple_debug_info("bonjour", "xep-bytestreams-parse.\n");

	type = xmlnode_get_attrib(packet, "type");
	from = purple_buddy_get_name(pb);
	query = xmlnode_get_child(packet,"query");
	if(!type)
		return;

	query = xmlnode_copy(query);
	if (!query)
		return;

	if(!purple_strequal(type, "set")) {
		purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type);
		return;
	}

	purple_debug_info("bonjour", "bytestream offer Message type - SET.\n");

	iq_id = xmlnode_get_attrib(packet, "id");

	sid = xmlnode_get_attrib(query, "sid");
	xfer = bonjour_si_xfer_find(bd, sid, from);
	streamhost = xmlnode_get_child(query, "streamhost");

	if(xfer && streamhost && __xep_bytestreams_parse(pb, xfer, streamhost, iq_id))
		return; /* success */

	purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n");

	if (iq_id && xfer != NULL)
		xep_ft_si_reject(bd, iq_id, xfer->who, "404", "cancel");
}
Beispiel #8
0
static gboolean
msn_oim_request_helper(MsnOimRequestData *data)
{
	MsnSession *session = data->oim->session;

	if (data->send) {
		/* The Sending of OIM's uses a different token for some reason. */
		xmlnode *ticket;
		ticket = xmlnode_get_child(data->body, "Header/Ticket");
		xmlnode_set_attrib(ticket, "passport",
			msn_nexus_get_token_str(session->nexus, MSN_AUTH_LIVE_SECURE));
	}
	else
	{
		xmlnode *passport;
		xmlnode *xml_t;
		xmlnode *xml_p;
		GHashTable *token;
		const char *msn_t;
		const char *msn_p;

		token = msn_nexus_get_token(session->nexus, MSN_AUTH_MESSENGER_WEB);
		g_return_val_if_fail(token != NULL, FALSE);

		msn_t = g_hash_table_lookup(token, "t");
		msn_p = g_hash_table_lookup(token, "p");

		g_return_val_if_fail(msn_t != NULL, FALSE);
		g_return_val_if_fail(msn_p != NULL, FALSE);

		passport = xmlnode_get_child(data->body, "Header/PassportCookie");
		xml_t = xmlnode_get_child(passport, "t");
		xml_p = xmlnode_get_child(passport, "p");

		/* frees old token text, or the 'EMPTY' text if first time */
		xmlnode_free(xml_t->child);
		xmlnode_free(xml_p->child);

		xmlnode_insert_data(xml_t, msn_t, -1);
		xmlnode_insert_data(xml_p, msn_p, -1);
	}

	msn_soap_message_send(session,
		msn_soap_message_new(data->action, xmlnode_copy(data->body)),
		data->host, data->url, FALSE,
		msn_oim_request_cb, data);

	return FALSE;
}
Beispiel #9
0
static gboolean twitter_send_xml_request_multipage_all_success_cb(TwitterRequestor * r, xmlnode * node, gboolean last_page, TwitterMultiPageRequestData * request_multi, gpointer user_data)
{
    TwitterMultiPageAllRequestData *request_data_all = user_data;

    purple_debug_info(purple_account_get_protocol_id(r->account), "%s\n", G_STRFUNC);

    request_data_all->nodes = g_list_prepend(request_data_all->nodes, xmlnode_copy(node));  //TODO: update
    request_data_all->current_count += xmlnode_child_count(node);

    purple_debug_info(purple_account_get_protocol_id(r->account), "%s last_page: %d current_count: %d max_count: %d count: %d\n", G_STRFUNC, last_page ? 1 : 0, request_data_all->current_count, request_data_all->max_count, request_multi->expected_count);
    if (last_page || (request_data_all->max_count > 0 && request_data_all->current_count >= request_data_all->max_count)) {
        request_data_all->success_callback(r, request_data_all->nodes, request_data_all->user_data);
        twitter_multipage_all_request_data_free(request_data_all);
        return FALSE;
    } else if (request_data_all->max_count > 0 && (request_data_all->current_count + request_multi->expected_count > request_data_all->max_count)) {
        request_multi->expected_count = request_data_all->max_count - request_data_all->current_count;
    }
    return TRUE;
}
Beispiel #10
0
void jabber_iq_parse(JabberStream *js, xmlnode *packet)
{
	JabberCallbackData *jcd;
	xmlnode *query, *error, *x;
	const char *xmlns;
	const char *type, *id, *from;
	JabberIqHandler *jih;

	query = xmlnode_get_child(packet, "query");
	type = xmlnode_get_attrib(packet, "type");
	from = xmlnode_get_attrib(packet, "from");
	id = xmlnode_get_attrib(packet, "id");

	if(type == NULL || !(!strcmp(type, "get") || !strcmp(type, "set")
			|| !strcmp(type, "result") || !strcmp(type, "error"))) {
		purple_debug_error("jabber", "IQ with invalid type ('%s') - ignoring.\n",
						   type ? type : "(null)");
		return;
	}

	/* All IQs must have an ID, so send an error for a set/get that doesn't */
	if(!id || !*id) {

		if(!strcmp(type, "set") || !strcmp(type, "get")) {
			JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR);

			xmlnode_free(iq->node);
			iq->node = xmlnode_copy(packet);
			xmlnode_set_attrib(iq->node, "to", from);
			xmlnode_remove_attrib(iq->node, "from");
			xmlnode_set_attrib(iq->node, "type", "error");
			/* This id is clearly not useful, but we must put something there for a valid stanza */
			iq->id = jabber_get_next_id(js);
			xmlnode_set_attrib(iq->node, "id", iq->id);
			error = xmlnode_new_child(iq->node, "error");
			xmlnode_set_attrib(error, "type", "modify");
			x = xmlnode_new_child(error, "bad-request");
			xmlnode_set_namespace(x, "urn:ietf:params:xml:ns:xmpp-stanzas");

			jabber_iq_send(iq);
		} else
			purple_debug_error("jabber", "IQ of type '%s' missing id - ignoring.\n", type);

		return;
	}

	/* First, lets see if a special callback got registered */

	if(!strcmp(type, "result") || !strcmp(type, "error")) {
		if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) {
			jcd->callback(js, packet, jcd->data);
			jabber_iq_remove_callback_by_id(js, id);
			return;
		}
	}

	/* Apparently not, so lets see if we have a pre-defined handler */

	if(query && (xmlns = xmlnode_get_namespace(query))) {
		if((jih = g_hash_table_lookup(iq_handlers, xmlns))) {
			jih(js, packet);
			return;
		}
	}

	if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) {
		jabber_si_parse(js, packet);
		return;
	}

	if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) {
		jabber_gmail_poke(js, packet);
		return;
	}

	purple_debug_info("jabber", "jabber_iq_parse\n");

	if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) {
		jabber_ping_parse(js, packet);
		return;
	}

	if (xmlnode_get_child_with_namespace(packet, "data", XEP_0231_NAMESPACE)) {
		jabber_data_parse(js, packet);
		return;
	}

	/* If we get here, send the default error reply mandated by XMPP-CORE */
	if(!strcmp(type, "set") || !strcmp(type, "get")) {
		JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR);

		xmlnode_free(iq->node);
		iq->node = xmlnode_copy(packet);
		xmlnode_set_attrib(iq->node, "to", from);
		xmlnode_remove_attrib(iq->node, "from");
		xmlnode_set_attrib(iq->node, "type", "error");
		error = xmlnode_new_child(iq->node, "error");
		xmlnode_set_attrib(error, "type", "cancel");
		xmlnode_set_attrib(error, "code", "501");
		x = xmlnode_new_child(error, "feature-not-implemented");
		xmlnode_set_namespace(x, "urn:ietf:params:xml:ns:xmpp-stanzas");

		jabber_iq_send(iq);
	}
}