mirror of
https://github.com/profanity-im/profanity.git
synced 2024-11-03 19:37:16 -05:00
Merge pull request #1567 from profanity-im/feature/1524-contact
Add support for XEP-0157 server contact information discovery
This commit is contained in:
commit
f30a9e1256
@ -869,7 +869,8 @@ static struct cmd_t command_defs[] = {
|
||||
"/disco items [<jid>]")
|
||||
CMD_DESC(
|
||||
"Find out information about an entities supported services. "
|
||||
"Calling with no arguments will query the server you are currently connected to.")
|
||||
"Calling with no arguments will query the server you are currently connected to. "
|
||||
"This includes discovering contact addresses for XMPP services (XEP-0157).")
|
||||
CMD_ARGS(
|
||||
{ "info [<jid>]", "List protocols and features supported by an entity." },
|
||||
{ "items [<jid>]", "List items associated with an entity." })
|
||||
|
@ -837,6 +837,26 @@ cons_show_disco_items(GSList* items, const char* const jid)
|
||||
cons_alert(NULL);
|
||||
}
|
||||
|
||||
static void _cons_print_contact_information_item(gpointer data, gpointer user_data)
|
||||
{
|
||||
cons_show(" %s", (char*)data);
|
||||
}
|
||||
|
||||
static void _cons_print_contact_information_hashlist_item(gpointer key, gpointer value, gpointer userdata)
|
||||
{
|
||||
cons_show(" %s:", (char*)key);
|
||||
g_slist_foreach((GSList*)value, _cons_print_contact_information_item, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cons_show_disco_contact_information(GHashTable* addresses)
|
||||
{
|
||||
cons_show("");
|
||||
cons_show("Server contact information:");
|
||||
|
||||
g_hash_table_foreach(addresses, _cons_print_contact_information_hashlist_item, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cons_show_status(const char* const barejid)
|
||||
{
|
||||
|
@ -276,6 +276,7 @@ void cons_show_bookmarks(const GList* list);
|
||||
void cons_show_bookmarks_ignore(gchar** list, gsize len);
|
||||
void cons_show_disco_items(GSList* items, const char* const jid);
|
||||
void cons_show_disco_info(const char* from, GSList* identities, GSList* features);
|
||||
void cons_show_disco_contact_information(GHashTable* addresses);
|
||||
void cons_show_room_invite(const char* const invitor, const char* const room, const char* const reason);
|
||||
void cons_check_version(gboolean not_available_msg);
|
||||
void cons_show_typing(const char* const barejid);
|
||||
|
@ -2308,6 +2308,8 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat
|
||||
GSList* features = NULL;
|
||||
while (child) {
|
||||
const char* stanza_name = xmpp_stanza_get_name(child);
|
||||
const char* child_type = xmpp_stanza_get_type(child);
|
||||
|
||||
if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) {
|
||||
const char* var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR);
|
||||
if (var) {
|
||||
@ -2315,10 +2317,9 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat
|
||||
}
|
||||
} else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) {
|
||||
const char* name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
|
||||
const char* type = xmpp_stanza_get_type(child);
|
||||
const char* category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY);
|
||||
|
||||
if (name || category || type) {
|
||||
if (name || category || child_type) {
|
||||
DiscoIdentity* identity = malloc(sizeof(struct disco_identity_t));
|
||||
|
||||
if (identity) {
|
||||
@ -2332,8 +2333,8 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat
|
||||
} else {
|
||||
identity->category = NULL;
|
||||
}
|
||||
if (type) {
|
||||
identity->type = strdup(type);
|
||||
if (child_type) {
|
||||
identity->type = strdup(child_type);
|
||||
} else {
|
||||
identity->type = NULL;
|
||||
}
|
||||
@ -2341,6 +2342,10 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat
|
||||
identities = g_slist_append(identities, identity);
|
||||
}
|
||||
}
|
||||
} else if (g_strcmp0(child_type, STANZA_TYPE_RESULT) == 0) {
|
||||
GHashTable *adr = stanza_get_service_contact_addresses(connection_get_ctx(), child);
|
||||
cons_show_disco_contact_information(adr);
|
||||
g_hash_table_destroy(adr);
|
||||
}
|
||||
|
||||
child = xmpp_stanza_get_next(child);
|
||||
|
@ -2838,3 +2838,54 @@ stanza_create_muc_register_nick(xmpp_ctx_t* ctx, const char* const id, const cha
|
||||
|
||||
return iq;
|
||||
}
|
||||
|
||||
static void
|
||||
_contact_addresses_list_free(GSList* list)
|
||||
{
|
||||
if (list) {
|
||||
g_slist_free_full(list, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
stanza_get_service_contact_addresses(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza)
|
||||
{
|
||||
GHashTable* addresses = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_contact_addresses_list_free);
|
||||
|
||||
xmpp_stanza_t* fields = xmpp_stanza_get_children(stanza);
|
||||
while (fields) {
|
||||
const char* child_name = xmpp_stanza_get_name(fields);
|
||||
const char* child_type = xmpp_stanza_get_type(fields);
|
||||
|
||||
if (g_strcmp0(child_name, STANZA_NAME_FIELD) == 0 && g_strcmp0(child_type, STANZA_TYPE_LIST_MULTI) == 0) {
|
||||
// extract key (eg 'admin-addresses')
|
||||
const char* var = xmpp_stanza_get_attribute(fields, STANZA_ATTR_VAR );
|
||||
|
||||
// extract values (a list of contact addresses eg mailto:xmpp@shakespeare.lit, xmpp:admins@shakespeare.lit)
|
||||
xmpp_stanza_t* values = xmpp_stanza_get_children(fields);
|
||||
GSList* val_list = NULL;
|
||||
while (values) {
|
||||
const char* value_name = xmpp_stanza_get_name(values);
|
||||
if (value_name && (g_strcmp0(value_name, STANZA_NAME_VALUE) == 0)) {
|
||||
char* value_text = xmpp_stanza_get_text(values);
|
||||
if (value_text) {
|
||||
val_list = g_slist_append(val_list, g_strdup(value_text));
|
||||
|
||||
xmpp_free(ctx, value_text);
|
||||
}
|
||||
}
|
||||
|
||||
values = xmpp_stanza_get_next(values);
|
||||
}
|
||||
|
||||
// add to list
|
||||
if (g_slist_length(val_list) > 0) {
|
||||
g_hash_table_insert(addresses, g_strdup(var), val_list);
|
||||
}
|
||||
}
|
||||
|
||||
fields = xmpp_stanza_get_next(fields);
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
@ -162,6 +162,7 @@
|
||||
#define STANZA_TYPE_SUBMIT "submit"
|
||||
#define STANZA_TYPE_CANCEL "cancel"
|
||||
#define STANZA_TYPE_MODIFY "modify"
|
||||
#define STANZA_TYPE_LIST_MULTI "list-multi"
|
||||
|
||||
#define STANZA_ATTR_TO "to"
|
||||
#define STANZA_ATTR_FROM "from"
|
||||
@ -388,6 +389,8 @@ char* stanza_get_muc_destroy_reason(xmpp_stanza_t* stanza);
|
||||
const char* stanza_get_actor(xmpp_stanza_t* stanza);
|
||||
char* stanza_get_reason(xmpp_stanza_t* stanza);
|
||||
|
||||
GHashTable* stanza_get_service_contact_addresses(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza);
|
||||
|
||||
Resource* stanza_resource_from_presence(XMPPPresence* presence);
|
||||
XMPPPresence* stanza_parse_presence(xmpp_stanza_t* stanza, int* err);
|
||||
void stanza_free_presence(XMPPPresence* presence);
|
||||
|
Loading…
Reference in New Issue
Block a user