diff --git a/src/command.c b/src/command.c index a36f5c23..39f6beae 100644 --- a/src/command.c +++ b/src/command.c @@ -276,20 +276,24 @@ static struct cmd_t main_commands[] = { "/sub", _cmd_sub, parse_args, 1, 2, - { "/sub [jid]", "Manage subscriptions.", - { "/sub [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.", + { "/sub [jid]", "Manage subscriptions.", + { "/sub [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.", + "sent : Show all sent subscription requests pending a response.", + "received : Show all received subscription requests awaiting your response.", "", - "If optional parameter 'jid' isn't set command belongs to the current window.", + "The optional 'jid' parameter only applys to 'request', 'allow', 'deny' and show", + "If it is ommited the contact of the current window is used.", "", "Example: /sub request myfriend@jabber.org", "Example: /sub allow myfriend@jabber.org", "Example: /sub request (whilst in chat with contact)", + "Example: /sub sent", NULL } } }, { "/tiny", @@ -628,6 +632,8 @@ cmd_init(void) p_autocomplete_add(sub_ac, strdup("allow")); p_autocomplete_add(sub_ac, strdup("deny")); p_autocomplete_add(sub_ac, strdup("show")); + p_autocomplete_add(sub_ac, strdup("sent")); + p_autocomplete_add(sub_ac, strdup("received")); log_ac = p_autocomplete_new(); p_autocomplete_add(log_ac, strdup("maxsize")); @@ -984,6 +990,28 @@ _cmd_sub(gchar **args, struct cmd_help_t help) return TRUE; } + if (strcmp(subcmd, "sent") == 0) { + cons_show("No pending requests sent."); + return TRUE; + } + + if (strcmp(subcmd, "received") == 0) { + GList *received = jabber_get_subscription_requests(); + + if (received == NULL) { + cons_show("No outstanding subscription requests."); + } else { + cons_show("%d outstanding subscription requests from:", + g_list_length(received)); + while (received != NULL) { + cons_show(received->data); + received = g_list_next(received); + } + } + + return TRUE; + } + if (!win_current_is_chat() && (jid == NULL)) { cons_show("You must specify a contact."); return TRUE; diff --git a/src/jabber.c b/src/jabber.c index 19457423..3dd4eb77 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -50,6 +50,7 @@ static struct _jabber_conn_t { static char *saved_user; static char *saved_password; static GTimer *reconnect_timer; +static GHashTable *sub_requests; static log_level_t _get_log_level(xmpp_log_level_t xmpp_level); static xmpp_log_level_t _get_xmpp_log_level(); @@ -87,6 +88,7 @@ jabber_init(const int disable_tls) jabber_conn.presence = PRESENCE_OFFLINE; jabber_conn.status = NULL; jabber_conn.tls_disabled = disable_tls; + sub_requests = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); } void @@ -277,6 +279,12 @@ jabber_subscription(const char * const jid, jabber_subscr_t action) free(jid_cpy); } +GList * +jabber_get_subscription_requests(void) +{ + return g_hash_table_get_keys(sub_requests); +} + void jabber_join(const char * const room, const char * const nick) { @@ -444,6 +452,7 @@ jabber_free_resources(void) saved_user = NULL; saved_password = NULL; chat_sessions_clear(); + g_hash_table_remove_all(sub_requests); xmpp_conn_release(jabber_conn.conn); xmpp_ctx_free(jabber_conn.ctx); xmpp_shutdown(); @@ -998,12 +1007,17 @@ _presence_handler(xmpp_conn_t * const conn, if (strcmp(short_jid, short_from) !=0) { prof_handle_contact_offline(short_from, "offline", status_str); } + + // subscriptions } else if (strcmp(type, STANZA_TYPE_SUBSCRIBE) == 0) { prof_handle_subscription(short_from, PRESENCE_SUBSCRIBE); + g_hash_table_insert(sub_requests, strdup(short_from), strdup(short_from)); } else if (strcmp(type, STANZA_TYPE_SUBSCRIBED) == 0) { prof_handle_subscription(short_from, PRESENCE_SUBSCRIBED); + g_hash_table_remove(sub_requests, short_from); } else if (strcmp(type, STANZA_TYPE_UNSUBSCRIBED) == 0) { prof_handle_subscription(short_from, PRESENCE_UNSUBSCRIBED); + g_hash_table_remove(sub_requests, short_from); } else { /* unknown type */ log_debug("Received presence with unknown type '%s'", type); } diff --git a/src/jabber.h b/src/jabber.h index 1d5509a4..0ccd12f7 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -55,6 +55,7 @@ void jabber_join(const char * const room, const char * const nick); void jabber_change_room_nick(const char * const room, const char * const nick); void jabber_leave_chat_room(const char * const room_jid); void jabber_subscription(const char * const jid, jabber_subscr_t action); +GList* jabber_get_subscription_requests(void); void jabber_send(const char * const msg, const char * const recipient); void jabber_send_groupchat(const char * const msg, const char * const recipient); void jabber_send_inactive(const char * const recipient);