コード例 #1
0
static void ggp_libgaduw_debug_handler(int level, const char * format,
	va_list args)
{
	PurpleDebugLevel purple_level;
	char *msg;

	if ((level & GG_DEBUG_NET) || (level & GG_DEBUG_FUNCTION) ||
		(level & GG_DEBUG_VERBOSE))
	{
		if (!purple_debug_is_verbose())
			return;
	}

	if ((level & GG_DEBUG_DUMP) || /* GG session protocol packets */
		(level & GG_DEBUG_TRAFFIC)) /* HTTP traffic */
	{
		if (!purple_debug_is_verbose() || !purple_debug_is_unsafe())
			return;
	}

	msg = g_strdup_vprintf(format, args);

	if (level & GG_DEBUG_ERROR)
		purple_level = PURPLE_DEBUG_ERROR;
	else if (level & GG_DEBUG_WARNING)
		purple_level = PURPLE_DEBUG_WARNING;
	else
		purple_level = PURPLE_DEBUG_MISC;

	purple_debug(purple_level, "gg", "%s", msg);
	g_free(msg);
}
コード例 #2
0
ファイル: bosh.c プロジェクト: Lilitana/Pidgin
static void
http_connection_send_request(PurpleHTTPConnection *conn, const GString *req)
{
	char *data;
	int ret;
	size_t len;

	/* Sending something to the server, restart the inactivity timer */
	jabber_stream_restart_inactivity_timer(conn->bosh->js);

	data = g_strdup_printf("POST %s HTTP/1.1\r\n"
	                       "Host: %s\r\n"
	                       "User-Agent: %s\r\n"
	                       "Content-Encoding: text/xml; charset=utf-8\r\n"
	                       "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n"
	                       "%s",
	                       conn->bosh->path, conn->bosh->host, bosh_useragent,
	                       req->len, req->str);

	len = strlen(data);

	++conn->requests;
	++conn->bosh->requests;

	if (purple_debug_is_unsafe() && purple_debug_is_verbose())
		/* Will contain passwords for SASL PLAIN and is verbose */
		purple_debug_misc("jabber", "BOSH (%p): Sending %s\n", conn, data);
	else if (purple_debug_is_verbose())
		purple_debug_misc("jabber", "BOSH (%p): Sending request of "
		                            "%" G_GSIZE_FORMAT " bytes.\n", conn, len);

	if (conn->writeh == 0)
		ret = http_connection_do_send(conn, data, len);
	else {
		ret = -1;
		errno = EAGAIN;
	}

	if (ret < 0 && errno != EAGAIN) {
		/*
		 * TODO: Handle this better. Probably requires a PurpleBOSHConnection
		 * buffer that stores what is "being sent" until the
		 * PurpleHTTPConnection reports it is fully sent.
		 */
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
				g_strerror(errno));
		purple_connection_error_reason(conn->bosh->js->gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				tmp);
		g_free(tmp);
		return;
	} else if (ret < len) {
		if (ret < 0)
			ret = 0;
		if (conn->writeh == 0)
			conn->writeh = purple_input_add(conn->psc ? conn->psc->fd : conn->fd,
					PURPLE_INPUT_WRITE, http_connection_send_cb, conn);
		purple_circ_buffer_append(conn->write_buf, data + ret, len - ret);
	}
}
コード例 #3
0
ファイル: util.c プロジェクト: N8Fear/purple-facebook
void
fb_util_vdebug(PurpleDebugLevel level, const gchar *format, va_list ap)
{
	gboolean unsafe;
	gboolean verbose;
	gchar *str;

	g_return_if_fail(format != NULL);

	unsafe = (level & FB_UTIL_DEBUG_FLAG_UNSAFE) != 0;
	verbose = (level & FB_UTIL_DEBUG_FLAG_VERBOSE) != 0;

	if ((unsafe && !purple_debug_is_unsafe()) ||
	    (verbose && !purple_debug_is_verbose()))
	{
		return;
	}

	/* Ensure all local flags are removed */
	level &= ~FB_UTIL_DEBUG_FLAG_ALL;

	str = g_strdup_vprintf(format, ap);
	purple_debug(level, "facebook", "%s\n", str);
	g_free(str);
}
コード例 #4
0
ファイル: bosh.c プロジェクト: ArmoredPidgin/pidgin-hardened
static void
jabber_bosh_connection_send_now(PurpleJabberBOSHConnection *conn)
{
	PurpleHttpRequest *req;
	GString *data;

	g_return_if_fail(conn != NULL);

	if (conn->send_timer != 0) {
		purple_timeout_remove(conn->send_timer);
		conn->send_timer = 0;
	}

	if (conn->sid == NULL)
		return;

	data = g_string_new(NULL);

	/* missing parameters: route, from, ack */
	g_string_printf(data, "<body "
		"rid='%" G_GUINT64_FORMAT "' "
		"sid='%s' "
		"xmlns='" NS_BOSH "' "
		"xmlns:xmpp='" NS_XMPP_BOSH "' ",
		++conn->rid, conn->sid);

	if (conn->js->reinit && !conn->is_terminating) {
		g_string_append(data, "xmpp:restart='true'/>");
		conn->js->reinit = FALSE;
	} else {
		if (conn->is_terminating)
			g_string_append(data, "type='terminate' ");
		g_string_append_c(data, '>');
		g_string_append_len(data, conn->send_buff->str,
			conn->send_buff->len);
		g_string_append(data, "</body>");
		g_string_set_size(conn->send_buff, 0);
	}

	if (purple_debug_is_verbose() && purple_debug_is_unsafe())
		purple_debug_misc("jabber-bosh", "sending: %s\n", data->str);

	req = jabber_bosh_connection_http_request_new(conn, data);
	g_string_free(data, TRUE);

	if (conn->is_terminating) {
		purple_http_request(NULL, req, NULL, NULL);
		g_free(conn->sid);
		conn->sid = NULL;
	} else {
		purple_http_connection_set_add(conn->payload_reqs,
			purple_http_request(conn->js->gc, req,
				jabber_bosh_connection_recv, conn));
	}

	purple_http_request_unref(req);
}
コード例 #5
0
ファイル: edisc.c プロジェクト: N8Fear/purple-facebook
void ggp_edisc_xfer_ticket_changed(PurpleConnection *gc, const char *data)
{
	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
	PurpleXfer *xfer;
	JsonParser *parser;
	JsonObject *ticket;
	const gchar *ticket_id, *send_status;
	ggp_edisc_xfer_ack_status ack_status;
	gboolean is_completed;

	g_return_if_fail(sdata != NULL);

	parser = ggp_json_parse(data);
	ticket = json_node_get_object(json_parser_get_root(parser));
	ticket_id = json_object_get_string_member(ticket, "id");
	ack_status = ggp_edisc_xfer_parse_ack_status(
		json_object_get_string_member(ticket, "ack_status"));
	send_status = json_object_get_string_member(ticket, "send_status");

	if (ticket_id == NULL)
		ticket_id = "";
	xfer = g_hash_table_lookup(sdata->xfers_initialized, ticket_id);
	if (xfer == NULL) {
		purple_debug_misc("gg", "ggp_edisc_event_ticket_changed: "
			"ticket %s not found, updating it...\n",
			purple_debug_is_unsafe() ? ticket_id : "");
		ggp_edisc_xfer_recv_ticket_got(gc, ticket_id);
		g_object_unref(parser);
		return;
	}

	is_completed = FALSE;
	if (g_strcmp0("in_progress", send_status) == 0) {
		/* do nothing */
	} else if (g_strcmp0("completed", send_status) == 0) {
		is_completed = TRUE;
	} else if (g_strcmp0("expired", send_status) == 0)
		ggp_edisc_xfer_error(xfer, _("File transfer expired."));
	else {
		purple_debug_warning("gg", "ggp_edisc_event_ticket_changed: "
			"unknown send_status=%s\n", send_status);
		g_object_unref(parser);
		return;
	}

	g_object_unref(parser);

	if (purple_xfer_get_xfer_type(xfer) == PURPLE_XFER_TYPE_RECEIVE) {
		if (is_completed)
			ggp_edisc_xfer_recv_ticket_completed(xfer);
	} else {
		if (ack_status != GGP_EDISC_XFER_ACK_STATUS_UNKNOWN)
			ggp_edisc_xfer_send_ticket_changed(gc, xfer, ack_status
				== GGP_EDISC_XFER_ACK_STATUS_ALLOWED);
	}

}
コード例 #6
0
ファイル: soap.c プロジェクト: Draghtnod/pidgin
static void
msn_soap_read_cb(gpointer data, gint fd, PurpleInputCondition cond)
{
	MsnSoapConnection *conn = data;
	int count = 0, cnt, perrno;
	/* This buffer needs to be larger than any packets received from
		login.live.com or Adium will fail to receive the packet
		(something weird with the login.live.com server). With NSS it works
		fine, so I believe it's some bug with OS X */
	char buf[16 * 1024];
	gsize cursor;

	if (conn->message == NULL) {
		conn->message = msn_soap_message_new(NULL, NULL);
	}

	if (conn->buf == NULL) {
		conn->buf = g_string_new_len(buf, 0);
	}

	cursor = conn->buf->len;
	while ((cnt = purple_ssl_read(conn->ssl, buf, sizeof(buf))) > 0) {
		purple_debug_info("soap", "read %d bytes\n", cnt);
		count += cnt;
		g_string_append_len(conn->buf, buf, cnt);
	}

	perrno = errno;
	if (cnt < 0 && perrno != EAGAIN)
		purple_debug_info("soap", "read: %s\n", g_strerror(perrno));

	if (conn->current_request && conn->current_request->secure &&
		!purple_debug_is_unsafe())
		purple_debug_misc("soap", "Received secure request.\n");
	else if (count != 0)
		purple_debug_misc("soap", "current %s\n", conn->buf->str + cursor);

	/* && count is necessary for Adium, on OS X the last read always
	   return an error, so we want to proceed anyway. See #5212 for
	   discussion on this and the above buffer size issues */
	if(cnt < 0 && errno == EAGAIN && count == 0)
		return;

	/* msn_soap_process could alter errno */
	msn_soap_process(conn);

	if ((cnt < 0 && perrno != EAGAIN) || cnt == 0) {
		/* It's possible msn_soap_process closed the ssl connection */
		if (conn->ssl) {
			purple_ssl_close(conn->ssl);
			conn->ssl = NULL;
			msn_soap_connection_handle_next(conn);
		}
	}
}
コード例 #7
0
ファイル: pubdir-prpl.c プロジェクト: N8Fear/purple-facebook
static void ggp_pubdir_set_info_got_token(PurpleConnection *gc,
	const gchar *token, gpointer _record)
{
	PurpleHttpRequest *req;
	ggp_pubdir_record *record = _record;
	gchar *request_data;
	gchar *name, *surname, *city;
	uin_t uin = record->uin;

	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);

	if (!token) {
		/* TODO: notify about failure */
		ggp_pubdir_record_free(record, 1);
		return;
	}

	name = g_uri_escape_string(record->first_name, NULL, FALSE);
	surname = g_uri_escape_string(record->last_name, NULL, FALSE);
	city = g_uri_escape_string(record->city, NULL, FALSE);

	request_data = g_strdup_printf(
		"name=%s&"
		"surname=%s&"
		"birth=%sT10:00:00%%2B00:00&"
		"birth_priv=2&"
		"gender=%d&"
		"gender_priv=2&"
		"city=%s&"
		"province=%d",
		name, surname,
		ggp_date_strftime("%Y-%m-%d", record->birth),
		record->gender,
		city,
		record->province);

	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
		purple_debug_misc("gg", "ggp_pubdir_set_info_got_token: "
			"query [%s]\n", request_data);
	}

	req = purple_http_request_new(NULL);
	purple_http_request_set_method(req, "PUT");
	purple_http_request_set_url_printf(req,
		"http://api.gadu-gadu.pl/users/%u.xml", uin);
	purple_http_request_header_set(req, "Authorization", token);
	purple_http_request_header_set(req, "Content-Type",
		"application/x-www-form-urlencoded");
	purple_http_request_set_contents(req, request_data, -1);
	purple_http_request(gc, req, ggp_pubdir_set_info_got_response, NULL);
	purple_http_request_unref(req);

	g_free(request_data);
	ggp_pubdir_record_free(record, 1);
}
コード例 #8
0
ファイル: edisc.c プロジェクト: N8Fear/purple-facebook
static void ggp_ggdrive_auth_done(PurpleHttpConnection *hc,
	PurpleHttpResponse *response, gpointer user_data)
{
	PurpleConnection *gc = purple_http_conn_get_purple_connection(hc);
	ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc);
	JsonParser *parser;
	JsonObject *result;
	int status = -1;

	g_return_if_fail(sdata != NULL);

	sdata->auth_request = NULL;

	if (!purple_http_response_is_successful(response)) {
		purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication "
			"failed due to unsuccessful request (code = %d)\n",
			purple_http_response_get_code(response));
		ggp_ggdrive_auth_results(gc, FALSE);
		return;
	}

	parser = ggp_json_parse(purple_http_response_get_data(response, NULL));
	result = json_node_get_object(json_parser_get_root(parser));
	result = json_object_get_object_member(result, "result");
	if (json_object_has_member(result, "status"))
		status = json_object_get_int_member(result, "status");
	g_object_unref(parser);

	if (status != 0 ) {
		purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication "
			"failed due to bad result (status=%d)\n", status);
		if (purple_debug_is_verbose())
			purple_debug_misc("gg", "ggp_ggdrive_auth_done: "
				"result = %s\n",
				purple_http_response_get_data(response, NULL));
		ggp_ggdrive_auth_results(gc, FALSE);
		return;
	}

	sdata->security_token = g_strdup(purple_http_response_get_header(
		response, "X-gged-security-token"));
	if (!sdata->security_token) {
		purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication "
			"failed due to missing security token header\n");
		ggp_ggdrive_auth_results(gc, FALSE);
		return;
	}

	if (purple_debug_is_unsafe())
		purple_debug_misc("gg", "ggp_ggdrive_auth_done: "
			"security_token=%s\n", sdata->security_token);
	ggp_ggdrive_auth_results(gc, TRUE);
}
コード例 #9
0
ファイル: bosh.c プロジェクト: ArmoredPidgin/pidgin-hardened
static void
jabber_bosh_connection_recv(PurpleHttpConnection *http_conn,
	PurpleHttpResponse *response, gpointer _bosh_conn)
{
	PurpleJabberBOSHConnection *bosh_conn = _bosh_conn;
	PurpleXmlNode *node, *child;

	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
		purple_debug_misc("jabber-bosh", "received: %s\n",
			purple_http_response_get_data(response, NULL));
	}

	node = jabber_bosh_connection_parse(bosh_conn, response);
	if (node == NULL)
		return;

	child = node->child;
	while (child != NULL) {
		/* jabber_process_packet might free child */
		PurpleXmlNode *next = child->next;
		const gchar *xmlns;

		if (child->type != PURPLE_XMLNODE_TYPE_TAG) {
			child = next;
			continue;
		}

		/* Workaround for non-compliant servers that don't stamp
		 * the right xmlns on these packets. See #11315.
		 */
		xmlns = purple_xmlnode_get_namespace(child);
		if ((xmlns == NULL || g_strcmp0(xmlns, NS_BOSH) == 0) &&
			(g_strcmp0(child->name, "iq") == 0 ||
			g_strcmp0(child->name, "message") == 0 ||
			g_strcmp0(child->name, "presence") == 0))
		{
			purple_xmlnode_set_namespace(child, NS_XMPP_CLIENT);
		}

		jabber_process_packet(bosh_conn->js, &child);

		child = next;
	}

	jabber_bosh_connection_send(bosh_conn, NULL);
}
コード例 #10
0
ファイル: soap.c プロジェクト: Draghtnod/pidgin
static gboolean
msn_soap_connection_run(gpointer data)
{
	MsnSoapConnection *conn = data;
	MsnSoapRequest *req = g_queue_peek_head(conn->queue);

	conn->run_timer = 0;

	if (req) {
		if (conn->ssl == NULL) {
			conn->ssl = purple_ssl_connect(conn->session->account, conn->host,
				443, msn_soap_connected_cb, msn_soap_error_cb, conn);
		} else if (conn->connected) {
			int len = -1;
			char *body = xmlnode_to_str(req->message->xml, &len);
			GSList *iter;

			g_queue_pop_head(conn->queue);

			conn->buf = g_string_new("");

			g_string_append_printf(conn->buf,
				"POST /%s HTTP/1.1\r\n"
				"SOAPAction: %s\r\n"
				"Content-Type:text/xml; charset=utf-8\r\n"
				"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n"
				"Accept: */*\r\n"
				"Host: %s\r\n"
				"Content-Length: %d\r\n"
				"Connection: Keep-Alive\r\n"
				"Cache-Control: no-cache\r\n",
				req->path, req->message->action ? req->message->action : "",
				conn->host, len);

			for (iter = req->message->headers; iter; iter = iter->next) {
				g_string_append(conn->buf, (char *)iter->data);
				g_string_append(conn->buf, "\r\n");
			}

			g_string_append(conn->buf, "\r\n");
			g_string_append(conn->buf, body);

			if (req->secure && !purple_debug_is_unsafe())
				purple_debug_misc("soap", "Sending secure request.\n");
			else
				purple_debug_misc("soap", "%s\n", conn->buf->str);

			conn->handled_len = 0;
			conn->current_request = req;

			if (conn->event_handle)
				purple_input_remove(conn->event_handle);
			conn->event_handle = purple_input_add(conn->ssl->fd,
				PURPLE_INPUT_WRITE, msn_soap_write_cb, conn);
			if (!msn_soap_write_cb_internal(conn, conn->ssl->fd, PURPLE_INPUT_WRITE, TRUE)) {
				/* Not connected => reconnect and retry */
				purple_debug_info("soap", "not connected, reconnecting\n");

				conn->connected = FALSE;
				conn->current_request = NULL;
				msn_soap_connection_sanitize(conn, FALSE);

				g_queue_push_head(conn->queue, req);
				conn->run_timer = purple_timeout_add(0, msn_soap_connection_run, conn);
			}

			g_free(body);
		}
	}

	return FALSE;
}
コード例 #11
0
ファイル: pubdir-prpl.c プロジェクト: N8Fear/purple-facebook
static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn,
	PurpleHttpResponse *response, gpointer _request)
{
	ggp_pubdir_request *request = _request;
	PurpleConnection *gc = request->gc;
	gboolean succ = TRUE;
	PurpleXmlNode *xml;
	const gchar *xml_raw;
	unsigned int status, next_offset;
	int record_count, i;
	ggp_pubdir_record *records;

	xml_raw = purple_http_response_get_data(response, NULL);

	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
		purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%s]\n",
			xml_raw);
	}

	xml = purple_xmlnode_from_str(xml_raw, -1);
	if (xml == NULL) {
		purple_debug_error("gg", "ggp_pubdir_got_data: "
			"invalid xml\n");
		request->cb(gc, -1, NULL, 0, request->user_data);
		ggp_pubdir_request_free(request);
		return;
	}

	succ &= ggp_xml_get_uint(xml, "status", &status);
	if (!ggp_xml_get_uint(xml, "nextOffset", &next_offset))
		next_offset = 0;
	xml = purple_xmlnode_get_child(xml, "users");
	if (!succ || status != 0 || !xml) {
		purple_debug_error("gg", "ggp_pubdir_got_data: "
			"invalid reply\n");
		request->cb(gc, -1, NULL, 0, request->user_data);
		ggp_pubdir_request_free(request);
		return;
	}

	record_count = ggp_xml_child_count(xml, "user");
	records = g_new0(ggp_pubdir_record, record_count);

	xml = purple_xmlnode_get_child(xml, "user");
	i = 0;
	while (xml) {
		ggp_pubdir_record *record = &records[i++];
		gchar *city = NULL, *birth_s = NULL;
		unsigned int gender = 0;
		const gchar *uin_s;

		g_assert(i <= record_count);

		record->uin = ggp_str_to_uin(purple_xmlnode_get_attrib(xml, "uin"));
		if (record->uin == 0)
			ggp_xml_get_uint(xml, "uin", &record->uin);
		if (record->uin == 0)
			purple_debug_error("gg", "ggp_pubdir_got_data:"
				" invalid uin\n");
		uin_s = ggp_uin_to_str(record->uin);

		ggp_xml_get_string(xml, "label", &record->label);
		ggp_xml_get_string(xml, "nick", &record->nickname);
		ggp_xml_get_string(xml, "name", &record->first_name);
		ggp_xml_get_string(xml, "surname", &record->last_name);
		ggp_xml_get_string(xml, "city", &city);
		ggp_xml_get_string(xml, "birth", &birth_s);
		ggp_xml_get_uint(xml, "gender", &gender);
		ggp_xml_get_uint(xml, "age", &record->age);
		ggp_xml_get_uint(xml, "province", &record->province);

		record->label = ggp_free_if_equal(record->label, uin_s);
		record->label = ggp_free_if_equal(record->label, "");
		record->nickname = ggp_free_if_equal(record->nickname, uin_s);
		record->nickname = ggp_free_if_equal(record->nickname, "");
		record->first_name = ggp_free_if_equal(record->first_name, "");
		record->last_name = ggp_free_if_equal(record->last_name, "");

		if (record->label) {}
		else if (record->nickname)
			record->label = g_strdup(record->nickname);
		else if (record->first_name && record->last_name)
			record->label = g_strdup_printf("%s %s",
				record->first_name, record->last_name);
		else if (record->first_name)
			record->label = g_strdup(record->first_name);
		else if (record->last_name)
			record->label = g_strdup(record->last_name);
		if (record->label)
			g_strstrip(record->label);
		if (record->nickname)
			g_strstrip(record->nickname);

		if (gender == 1)
			record->gender = GGP_PUBDIR_GENDER_FEMALE;
		else if (gender == 2)
			record->gender = GGP_PUBDIR_GENDER_MALE;
		else
			record->gender = GGP_PUBDIR_GENDER_UNSPECIFIED;

		if (city && city[0] != '\0')
			record->city = g_strdup(city);
		if (record->city)
			g_strstrip(record->city);
		if (!record->city) {
			g_free(record->city);
			record->city = NULL;
		}

		record->birth = ggp_date_from_iso8601(birth_s);
		/*TODO: calculate age from birth */

		if (purple_debug_is_verbose()) {
			purple_debug_misc("gg", "ggp_pubdir_got_data: [uin:%d] "
				"[label:%s] [nick:%s] [first name:%s] "
				"[last name:%s] [city:%s] [gender:%d] [age:%d] "
				"[birth:%lu]\n", record->uin, record->label,
				record->nickname, record->first_name,
				record->last_name, record->city, record->gender,
				record->age, record->birth);
		}

		g_free(city);

		xml = purple_xmlnode_get_next_twin(xml);
	}

	request->cb(gc, record_count, records, next_offset, request->user_data);

	ggp_pubdir_request_free(request);
	ggp_pubdir_record_free(records, record_count);
}
コード例 #12
0
ファイル: bosh.c プロジェクト: ArmoredPidgin/pidgin-hardened
static void
jabber_bosh_connection_session_created(PurpleHttpConnection *http_conn,
	PurpleHttpResponse *response, gpointer _bosh_conn)
{
	PurpleJabberBOSHConnection *bosh_conn = _bosh_conn;
	PurpleXmlNode *node, *features;
	const gchar *sid, *ver, *inactivity_str;
	int inactivity = 0;

	bosh_conn->sc_req = NULL;

	if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
		purple_debug_misc("jabber-bosh",
			"received (session creation): %s\n",
			purple_http_response_get_data(response, NULL));
	}

	node = jabber_bosh_connection_parse(bosh_conn, response);
	if (node == NULL)
		return;

	sid = purple_xmlnode_get_attrib(node, "sid");
	ver = purple_xmlnode_get_attrib(node, "ver");
	inactivity_str = purple_xmlnode_get_attrib(node, "inactivity");
	/* requests = purple_xmlnode_get_attrib(node, "requests"); */

	if (!sid) {
		purple_connection_error(bosh_conn->js->gc,
			PURPLE_CONNECTION_ERROR_OTHER_ERROR,
			_("No BOSH session ID given"));
		purple_xmlnode_free(node);
		return;
	}

	if (ver == NULL) {
		purple_debug_info("jabber-bosh", "Missing version in BOSH initiation\n");
	} else if (!jabber_bosh_version_check(ver, 1, 6)) {
		purple_debug_error("jabber-bosh",
			"Unsupported BOSH version: %s\n", ver);
		purple_connection_error(bosh_conn->js->gc,
			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
			_("Unsupported version of BOSH protocol"));
		purple_xmlnode_free(node);
		return;
	}

	purple_debug_misc("jabber-bosh", "Session created for %p\n", bosh_conn);

	bosh_conn->sid = g_strdup(sid);

	if (inactivity_str)
		inactivity = atoi(inactivity_str);
	if (inactivity < 0 || inactivity > 3600) {
		purple_debug_warning("jabber-bosh", "Ignoring invalid "
			"inactivity value: %s\n", inactivity_str);
		inactivity = 0;
	}
	if (inactivity > 0) {
		inactivity -= 5; /* rounding */
		if (inactivity <= 0)
			inactivity = 1;
		bosh_conn->js->max_inactivity = inactivity;
		if (bosh_conn->js->inactivity_timer == 0) {
			purple_debug_misc("jabber-bosh", "Starting inactivity "
				"timer for %d secs (compensating for "
				"rounding)\n", inactivity);
			jabber_stream_restart_inactivity_timer(bosh_conn->js);
		}
	}

	jabber_stream_set_state(bosh_conn->js, JABBER_STREAM_AUTHENTICATING);

	/* FIXME: Depending on receiving features might break with some hosts */
	features = purple_xmlnode_get_child(node, "features");
	jabber_stream_features_parse(bosh_conn->js, features);

	purple_xmlnode_free(node);

	jabber_bosh_connection_send(bosh_conn, NULL);
}
コード例 #13
0
ファイル: edisc.c プロジェクト: N8Fear/purple-facebook
static void ggp_edisc_xfer_recv_ticket_update_got(PurpleHttpConnection *hc,
	PurpleHttpResponse *response, gpointer user_data)
{
	PurpleConnection *gc = purple_http_conn_get_purple_connection(hc);
	PurpleXfer *xfer;
	ggp_edisc_xfer *edisc_xfer;
	JsonParser *parser;
	JsonObject *result;
	int status = -1;
	ggp_edisc_session_data *sdata;

	const gchar *ticket_id, *file_name, *send_mode_str;
	uin_t sender, recipient;
	int file_size;

	if (!purple_http_response_is_successful(response)) {
		purple_debug_error("gg",
			"ggp_edisc_xfer_recv_ticket_update_got: "
			"cannot fetch update for ticket (code=%d)\n",
			purple_http_response_get_code(response));
		return;
	}

	sdata = ggp_edisc_get_sdata(gc);
	g_return_if_fail(sdata != NULL);

	parser = ggp_json_parse(purple_http_response_get_data(response, NULL));
	result = json_node_get_object(json_parser_get_root(parser));
	result = json_object_get_object_member(result, "result");
	if (json_object_has_member(result, "status"))
		status = json_object_get_int_member(result, "status");
	result = json_object_get_object_member(result, "send_ticket");

	if (status != 0) {
		purple_debug_warning("gg",
			"ggp_edisc_xfer_recv_ticket_update_got: failed to get "
			"update (status=%d)\n", status);
		g_object_unref(parser);
		return;
	}

	ticket_id = json_object_get_string_member(result, "id");
	sender = ggp_str_to_uin(json_object_get_string_member(result,
		"sender"));
	recipient = ggp_str_to_uin(json_object_get_string_member(result,
		"recipient"));
	file_size = g_ascii_strtoll(json_object_get_string_member(result,
		"file_size"), NULL, 10);
	file_name = json_object_get_string_member(result, "file_name");

	/* GG11: normal
	 * AQQ 2.4.2.10: direct_inbox
	 */
	send_mode_str = json_object_get_string_member(result, "send_mode");

	/* more fields:
	 * send_progress (float), ack_status, send_status
	 */

	if (purple_debug_is_verbose() && purple_debug_is_unsafe())
		purple_debug_info("gg", "Got ticket update: id=%s, sender=%u, "
			"recipient=%u, file name=\"%s\", file size=%d, "
			"send mode=%s)\n",
			ticket_id,
			sender, recipient,
			file_name, file_size,
			send_mode_str);

	xfer = g_hash_table_lookup(sdata->xfers_initialized, ticket_id);
	if (xfer != NULL) {
		purple_debug_misc("gg", "ggp_edisc_xfer_recv_ticket_update_got:"
			" ticket %s already updated\n",
			purple_debug_is_unsafe() ? ticket_id : "");
		g_object_unref(parser);
		return;
	}

	if (recipient != ggp_get_my_uin(gc)) {
		purple_debug_misc("gg", "ggp_edisc_xfer_recv_ticket_update_got:"
			" ticket %s is not for incoming transfer "
			"(its from %u to %u)\n",
			purple_debug_is_unsafe() ? ticket_id : "",
			sender, recipient);
		g_object_unref(parser);
		return;
	}

	xfer = ggp_edisc_xfer_recv_new(gc, ggp_uin_to_str(sender));
	purple_xfer_set_filename(xfer, file_name);
	purple_xfer_set_size(xfer, file_size);
	purple_xfer_request(xfer);
	edisc_xfer = purple_xfer_get_protocol_data(xfer);
	edisc_xfer->ticket_id = g_strdup(ticket_id);
	g_hash_table_insert(sdata->xfers_initialized,
		edisc_xfer->ticket_id, xfer);
	g_hash_table_insert(sdata->xfers_history,
		g_strdup(ticket_id), GINT_TO_POINTER(1));

	g_object_unref(parser);
}