mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Handle roster subscription updates
This commit is contained in:
parent
2f2fa8de66
commit
a061b0d452
@ -276,18 +276,20 @@ static struct cmd_t main_commands[] =
|
||||
|
||||
{ "/sub",
|
||||
_cmd_sub, parse_args, 1, 2,
|
||||
{ "/sub <add|del|req|show> [jid]", "Manage subscriptions.",
|
||||
{ "/sub <add|del|req|show> [jid]",
|
||||
"-----------------------------",
|
||||
"add : Approve subscription to a contact.",
|
||||
"del : Remove subscription for a contact.",
|
||||
"req : Send a subscription request to the user to be informed of their",
|
||||
" : presence.",
|
||||
"show : Show subscriprion status for a contact.",
|
||||
{ "/sub <request|allow|deny|show> [jid]", "Manage subscriptions.",
|
||||
{ "/sub <request|allow|deny|show> [jid]",
|
||||
"------------------------------------",
|
||||
"request : Send a subscription request to the user to be informed of their",
|
||||
" : presence.",
|
||||
"allow : Approve contacts subscription reqeust to see your presence.",
|
||||
"deny : Remove subscription for a contact, or deny a request",
|
||||
"show : Show subscriprion status for a contact.",
|
||||
"",
|
||||
"If optional parameter 'jid' isn't set command belongs to the current window.",
|
||||
"",
|
||||
"Example: /sub add myfriend@jabber.org",
|
||||
"Example: /sub request myfriend@jabber.org",
|
||||
"Example: /sub allow myfriend@jabber.org",
|
||||
"Example: /sub request (whilst in chat with contact)",
|
||||
NULL } } },
|
||||
|
||||
{ "/tiny",
|
||||
@ -622,9 +624,9 @@ cmd_init(void)
|
||||
p_autocomplete_add(notify_ac, strdup("remind"));
|
||||
|
||||
sub_ac = p_autocomplete_new();
|
||||
p_autocomplete_add(sub_ac, strdup("add"));
|
||||
p_autocomplete_add(sub_ac, strdup("del"));
|
||||
p_autocomplete_add(sub_ac, strdup("req"));
|
||||
p_autocomplete_add(sub_ac, strdup("request"));
|
||||
p_autocomplete_add(sub_ac, strdup("allow"));
|
||||
p_autocomplete_add(sub_ac, strdup("deny"));
|
||||
p_autocomplete_add(sub_ac, strdup("show"));
|
||||
|
||||
log_ac = p_autocomplete_new();
|
||||
@ -995,15 +997,15 @@ _cmd_sub(gchar **args, struct cmd_help_t help)
|
||||
|
||||
bare_jid = strtok(jid, "/");
|
||||
|
||||
if (strcmp(subcmd, "add") == 0) {
|
||||
if (strcmp(subcmd, "allow") == 0) {
|
||||
jabber_subscription(bare_jid, PRESENCE_SUBSCRIBED);
|
||||
cons_show("Accepted subscription for %s", bare_jid);
|
||||
log_info("Accepted subscription for %s", bare_jid);
|
||||
} else if (strcmp(subcmd, "del") == 0) {
|
||||
} else if (strcmp(subcmd, "deny") == 0) {
|
||||
jabber_subscription(bare_jid, PRESENCE_UNSUBSCRIBED);
|
||||
cons_show("Deleted subscription for %s", bare_jid);
|
||||
log_info("Deleted subscription for %s", bare_jid);
|
||||
} else if (strcmp(subcmd, "req") == 0) {
|
||||
cons_show("Deleted/denied subscription for %s", bare_jid);
|
||||
log_info("Deleted/denied subscription for %s", bare_jid);
|
||||
} else if (strcmp(subcmd, "request") == 0) {
|
||||
jabber_subscription(bare_jid, PRESENCE_SUBSCRIBE);
|
||||
cons_show("Sent subscription request to %s.", bare_jid);
|
||||
log_info("Sent subscription request to %s.", bare_jid);
|
||||
|
@ -195,6 +195,27 @@ p_contact_set_status(const PContact contact, const char * const status)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
p_contact_set_subscription(const PContact contact, const char * const subscription)
|
||||
{
|
||||
if (contact->subscription != NULL) {
|
||||
free(contact->subscription);
|
||||
contact->subscription = NULL;
|
||||
}
|
||||
|
||||
if (subscription == NULL) {
|
||||
contact->subscription = strdup("none");
|
||||
} else {
|
||||
contact->subscription = strdup(subscription);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
p_contact_set_pending_out(const PContact contact, gboolean pending_out)
|
||||
{
|
||||
contact->pending_out = pending_out;
|
||||
}
|
||||
|
||||
int
|
||||
p_contacts_equal_deep(const PContact c1, const PContact c2)
|
||||
{
|
||||
|
@ -38,6 +38,8 @@ const char * p_contact_subscription(const PContact contact);
|
||||
gboolean p_contact_pending_out(const PContact contact);
|
||||
void p_contact_set_presence(const PContact contact, const char * const presence);
|
||||
void p_contact_set_status(const PContact contact, const char * const status);
|
||||
void p_contact_set_subscription(const PContact contact, const char * const subscription);
|
||||
void p_contact_set_pending_out(const PContact contact, gboolean pending_out);
|
||||
int p_contacts_equal_deep(const PContact c1, const PContact c2);
|
||||
|
||||
#endif
|
||||
|
@ -96,6 +96,20 @@ contact_list_update_contact(const char * const jid, const char * const presence,
|
||||
return changed;
|
||||
}
|
||||
|
||||
void
|
||||
contact_list_update_subscription(const char * const jid,
|
||||
const char * const subscription, gboolean pending_out)
|
||||
{
|
||||
PContact contact = g_hash_table_lookup(contacts, jid);
|
||||
|
||||
if (contact == NULL) {
|
||||
return;
|
||||
} else {
|
||||
p_contact_set_subscription(contact, subscription);
|
||||
p_contact_set_pending_out(contact, pending_out);
|
||||
}
|
||||
}
|
||||
|
||||
GSList *
|
||||
get_contact_list(void)
|
||||
{
|
||||
|
@ -35,6 +35,8 @@ gboolean contact_list_add(const char * const jid, const char * const name,
|
||||
const char * const subscription, gboolean pending_out);
|
||||
gboolean contact_list_update_contact(const char * const jid, const char * const presence,
|
||||
const char * const status);
|
||||
void contact_list_update_subscription(const char * const jid,
|
||||
const char * const subscription, gboolean pending_out);
|
||||
GSList * get_contact_list(void);
|
||||
char * contact_list_find_contact(char *search_str);
|
||||
PContact contact_list_get_contact(const char const *jid);
|
||||
|
64
src/jabber.c
64
src/jabber.c
@ -71,6 +71,8 @@ static int _groupchat_message_handler(xmpp_stanza_t * const stanza);
|
||||
static int _error_handler(xmpp_stanza_t * const stanza);
|
||||
static int _chat_message_handler(xmpp_stanza_t * const stanza);
|
||||
|
||||
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 _presence_handler(xmpp_conn_t * const conn,
|
||||
@ -673,7 +675,7 @@ _connection_handler(xmpp_conn_t * const conn,
|
||||
|
||||
xmpp_handler_add(conn, _message_handler, NULL, STANZA_NAME_MESSAGE, NULL, ctx);
|
||||
xmpp_handler_add(conn, _presence_handler, NULL, STANZA_NAME_PRESENCE, NULL, ctx);
|
||||
xmpp_id_handler_add(conn, _roster_handler, "roster", ctx);
|
||||
xmpp_handler_add(conn, _iq_handler, NULL, STANZA_NAME_IQ, NULL, ctx);
|
||||
|
||||
if (prefs_get_autoping() != 0) {
|
||||
int millis = prefs_get_autoping() * 1000;
|
||||
@ -743,6 +745,66 @@ _connection_handler(xmpp_conn_t * const conn,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_iq_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata)
|
||||
{
|
||||
char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
|
||||
|
||||
// handle the initial roster request
|
||||
if ((id != NULL) && (strcmp(id, "roster") == 0)) {
|
||||
return _roster_handler(conn, stanza, userdata);
|
||||
|
||||
// handle roster updates
|
||||
} else {
|
||||
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
|
||||
if (type == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strcmp(type, "set") != 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *query =
|
||||
xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||
|
||||
if (query == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *xmlns = xmpp_stanza_get_attribute(query, STANZA_ATTR_XMLNS);
|
||||
|
||||
if (xmlns == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strcmp(xmlns, XMPP_NS_ROSTER) != 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *item =
|
||||
xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM);
|
||||
|
||||
if (item == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
|
||||
const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
|
||||
|
||||
gboolean pending_out = FALSE;
|
||||
const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
|
||||
if ((ask != NULL) && (strcmp(ask, "subscribe") == 0)) {
|
||||
pending_out = TRUE;
|
||||
}
|
||||
|
||||
contact_list_update_subscription(jid, sub, pending_out);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_roster_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata)
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define STANZA_ATTR_XMLNS "xmlns"
|
||||
#define STANZA_ATTR_NICK "nick"
|
||||
#define STANZA_ATTR_ASK "ask"
|
||||
#define STANZA_ATTR_ID "id"
|
||||
|
||||
#define STANZA_TEXT_AWAY "away"
|
||||
#define STANZA_TEXT_DND "dnd"
|
||||
|
Loading…
Reference in New Issue
Block a user