1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Respond to iq requests for capabilities

This commit is contained in:
James Booth 2013-01-21 02:18:03 +00:00
parent 97a497c355
commit df790e247c
3 changed files with 145 additions and 7 deletions

View File

@ -39,8 +39,6 @@
#include "muc.h"
#include "stanza.h"
#include "ui.h"
static struct _jabber_conn_t {
xmpp_log_t *log;
xmpp_ctx_t *ctx;
@ -88,7 +86,9 @@ static int _iq_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
static int _roster_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
static int _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
static int _disco_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
void * const userdata);
static int _disco_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
void * const userdata);
static int _presence_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
@ -548,6 +548,51 @@ jabber_update_presence(jabber_presence_t status, const char * const msg,
xmpp_stanza_add_child(presence, query);
}
// add caps
xmpp_stanza_t *caps = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(caps, STANZA_NAME_C);
xmpp_stanza_set_ns(caps, STANZA_NS_CAPS);
xmpp_stanza_set_attribute(caps, STANZA_ATTR_HASH, "sha-1");
xmpp_stanza_set_attribute(caps, STANZA_ATTR_NODE, "http://www.profanity.im");
xmpp_stanza_t *query = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
xmpp_stanza_set_ns(query, XMPP_NS_DISCO_INFO);
xmpp_stanza_t *identity = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(identity, "identity");
xmpp_stanza_set_attribute(identity, "category", "client");
xmpp_stanza_set_attribute(identity, "type", "pc");
GString *name_str = g_string_new("Profanity ");
g_string_append(name_str, PACKAGE_VERSION);
if (strcmp(PACKAGE_STATUS, "development") == 0) {
g_string_append(name_str, "dev");
}
xmpp_stanza_set_attribute(identity, "name", name_str->str);
xmpp_stanza_t *feature_caps = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(feature_caps, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_caps, STANZA_ATTR_VAR, STANZA_NS_CAPS);
xmpp_stanza_t *feature_disoinfo = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(feature_disoinfo, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_disoinfo, STANZA_ATTR_VAR, XMPP_NS_DISCO_INFO);
xmpp_stanza_t *feature_muc = xmpp_stanza_new(jabber_conn.ctx);
xmpp_stanza_set_name(feature_muc, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_muc, STANZA_ATTR_VAR, STANZA_NS_MUC);
xmpp_stanza_add_child(query, identity);
xmpp_stanza_add_child(query, feature_muc);
xmpp_stanza_add_child(query, feature_disoinfo);
xmpp_stanza_add_child(query, feature_caps);
char *sha1 = sha1_caps_str(query);
xmpp_stanza_set_attribute(caps, STANZA_ATTR_VER, sha1);
xmpp_stanza_add_child(presence, caps);
xmpp_send(jabber_conn.conn, presence);
// send presence for each room
@ -923,9 +968,13 @@ _iq_handler(xmpp_conn_t * const conn,
if (g_strcmp0(id, "roster") == 0) {
return _roster_handler(conn, stanza, userdata);
// handle diso requests
// handle disco responses
} else if ((g_str_has_prefix(id, "disco")) && (g_strcmp0(type, "result") == 0)) {
return _disco_handler(conn, stanza, userdata);
return _disco_response_handler(conn, stanza, userdata);
// handle disco requests
} else if (stanza_is_caps_request(stanza)) {
return _disco_request_handler(conn, stanza, userdata);
// handle iq
} else {
@ -1060,7 +1109,67 @@ _roster_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
}
static int
_disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
_disco_request_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
void * const userdata)
{
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
xmpp_stanza_t *incoming_query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
char *node_str = xmpp_stanza_get_attribute(incoming_query, STANZA_ATTR_NODE);
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (from != NULL) {
xmpp_stanza_t *response = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(response, STANZA_NAME_IQ);
xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza));
xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
xmpp_stanza_set_ns(query, XMPP_NS_DISCO_INFO);
xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node_str);
xmpp_stanza_t *identity = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(identity, "identity");
xmpp_stanza_set_attribute(identity, "category", "client");
xmpp_stanza_set_attribute(identity, "type", "pc");
GString *name_str = g_string_new("Profanity ");
g_string_append(name_str, PACKAGE_VERSION);
if (strcmp(PACKAGE_STATUS, "development") == 0) {
g_string_append(name_str, "dev");
}
xmpp_stanza_set_attribute(identity, "name", name_str->str);
xmpp_stanza_t *feature_caps = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(feature_caps, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_caps, STANZA_ATTR_VAR, STANZA_NS_CAPS);
xmpp_stanza_t *feature_disoinfo = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(feature_disoinfo, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_disoinfo, STANZA_ATTR_VAR, XMPP_NS_DISCO_INFO);
xmpp_stanza_t *feature_muc = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(feature_muc, STANZA_NAME_FEATURE);
xmpp_stanza_set_attribute(feature_muc, STANZA_ATTR_VAR, STANZA_NS_MUC);
xmpp_stanza_add_child(query, identity);
xmpp_stanza_add_child(query, feature_muc);
xmpp_stanza_add_child(query, feature_disoinfo);
xmpp_stanza_add_child(query, feature_caps);
xmpp_stanza_add_child(response, query);
xmpp_send(conn, response);
}
return 1;
}
static int
_disco_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
void * const userdata)
{
char *type = xmpp_stanza_get_type(stanza);
@ -1094,7 +1203,6 @@ _disco_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
// non supported hash, or legacy caps
} else {
caps_key = id + 6;
cons_show(caps_key);
}
// already cached

View File

@ -431,6 +431,34 @@ stanza_contains_caps(xmpp_stanza_t * const stanza)
return TRUE;
}
gboolean
stanza_is_caps_request(xmpp_stanza_t * const stanza)
{
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
if (g_strcmp0(type, STANZA_TYPE_GET) != 0) {
return FALSE;
}
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
if (query == NULL) {
return FALSE;
}
char *ns = xmpp_stanza_get_ns(query);
if (ns == NULL) {
return FALSE;
}
if (strcmp(ns, XMPP_NS_DISCO_INFO) != 0) {
return FALSE;
}
return TRUE;
}
char *
stanza_caps_get_hash(xmpp_stanza_t * const stanza)
{

View File

@ -77,6 +77,7 @@
#define STANZA_ATTR_SECONDS "seconds"
#define STANZA_ATTR_NODE "node"
#define STANZA_ATTR_VER "ver"
#define STANZA_ATTR_VAR "var"
#define STANZA_ATTR_HASH "hash"
#define STANZA_TEXT_AWAY "away"
@ -141,6 +142,7 @@ int stanza_get_idle_time(xmpp_stanza_t * const stanza);
char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
gboolean stanza_contains_caps(xmpp_stanza_t * const stanza);
char * stanza_caps_get_hash(xmpp_stanza_t * const stanza);
gboolean stanza_is_caps_request(xmpp_stanza_t * const stanza);
DataForm * stanza_get_form(xmpp_stanza_t * const stanza);