diff --git a/src/command.c b/src/command.c index c9110e4b..f8c5b1e9 100644 --- a/src/command.c +++ b/src/command.c @@ -718,8 +718,9 @@ _cmd_sub(const char * const inp, struct cmd_help_t help) char *user, *lower; user = strndup(inp+5, strlen(inp)-5); lower = g_utf8_strdown(user, -1); - + jabber_subscribe(lower); + cons_show("Sent subscription request to %s.", user); result = TRUE; } @@ -824,16 +825,16 @@ _cmd_who(const char * const inp, struct cmd_help_t help) // get show strtok(inp_cpy, " "); - char *show = strtok(NULL, " "); + char *presence = strtok(NULL, " "); // bad arg - if ((show != NULL) - && (strcmp(show, "online") != 0) - && (strcmp(show, "offline") != 0) - && (strcmp(show, "away") != 0) - && (strcmp(show, "chat") != 0) - && (strcmp(show, "xa") != 0) - && (strcmp(show, "dnd") != 0)) { + if ((presence != NULL) + && (strcmp(presence, "online") != 0) + && (strcmp(presence, "offline") != 0) + && (strcmp(presence, "away") != 0) + && (strcmp(presence, "chat") != 0) + && (strcmp(presence, "xa") != 0) + && (strcmp(presence, "dnd") != 0)) { cons_show("Usage: %s", help.usage); // valid arg @@ -841,23 +842,23 @@ _cmd_who(const char * const inp, struct cmd_help_t help) GSList *list = get_contact_list(); // no arg, show all contacts - if (show == NULL) { + if (presence == NULL) { cons_show("All contacts:"); cons_show_contacts(list); // online, show all status that indicate online - } else if (strcmp("online", show) == 0) { - cons_show("Contacts (%s):", show); + } else if (strcmp("online", presence) == 0) { + cons_show("Contacts (%s):", presence); GSList *filtered = NULL; while (list != NULL) { PContact contact = list->data; - const char * const contact_show = (p_contact_show(contact)); - if ((strcmp(contact_show, "online") == 0) - || (strcmp(contact_show, "away") == 0) - || (strcmp(contact_show, "dnd") == 0) - || (strcmp(contact_show, "xa") == 0) - || (strcmp(contact_show, "chat") == 0)) { + const char * const contact_presence = (p_contact_presence(contact)); + if ((strcmp(contact_presence, "online") == 0) + || (strcmp(contact_presence, "away") == 0) + || (strcmp(contact_presence, "dnd") == 0) + || (strcmp(contact_presence, "xa") == 0) + || (strcmp(contact_presence, "chat") == 0)) { filtered = g_slist_append(filtered, contact); } list = g_slist_next(list); @@ -867,12 +868,12 @@ _cmd_who(const char * const inp, struct cmd_help_t help) // show specific status } else { - cons_show("Contacts (%s):", show); + cons_show("Contacts (%s):", presence); GSList *filtered = NULL; while (list != NULL) { PContact contact = list->data; - if (strcmp(p_contact_show(contact), show) == 0) { + if (strcmp(p_contact_presence(contact), presence) == 0) { filtered = g_slist_append(filtered, contact); } list = g_slist_next(list); diff --git a/src/contact.c b/src/contact.c index 12a2e500..d217f4c8 100644 --- a/src/contact.c +++ b/src/contact.c @@ -28,22 +28,31 @@ #include "contact.h" struct p_contact_t { + char *jid; char *name; - char *show; + char *presence; char *status; + char *subscription; }; PContact -p_contact_new(const char * const name, const char * const show, - const char * const status) +p_contact_new(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription) { PContact contact = malloc(sizeof(struct p_contact_t)); - contact->name = strdup(name); + contact->jid = strdup(jid); - if (show == NULL || (strcmp(show, "") == 0)) - contact->show = strdup("online"); + if (name != NULL) { + contact->name = strdup(name); + } else { + contact->name = NULL; + } + + if (presence == NULL || (strcmp(presence, "") == 0)) + contact->presence = strdup("online"); else - contact->show = strdup(show); + contact->presence = strdup(presence); if (status != NULL) contact->status = strdup(status); @@ -57,8 +66,15 @@ PContact p_contact_copy(PContact contact) { PContact copy = malloc(sizeof(struct p_contact_t)); - copy->name = strdup(contact->name); - copy->show = strdup(contact->show); + copy->jid = strdup(contact->jid); + + if (contact->name != NULL) { + copy->name = strdup(contact->name); + } else { + copy->name = NULL; + } + + copy->presence = strdup(contact->presence); if (contact->status != NULL) copy->status = strdup(contact->status); @@ -71,12 +87,21 @@ p_contact_copy(PContact contact) void p_contact_free(PContact contact) { - free(contact->name); - - if (contact->show != NULL) { - free(contact->show); - contact->show = NULL; + if (contact->jid != NULL) { + free(contact->jid); + contact->jid = NULL; } + + if (contact->name != NULL) { + free(contact->name); + contact->name = NULL; + } + + if (contact->presence != NULL) { + free(contact->presence); + contact->presence = NULL; + } + if (contact->status != NULL) { free(contact->status); contact->status = NULL; @@ -86,6 +111,12 @@ p_contact_free(PContact contact) contact = NULL; } +const char * +p_contact_jid(const PContact contact) +{ + return contact->jid; +} + const char * p_contact_name(const PContact contact) { @@ -93,9 +124,9 @@ p_contact_name(const PContact contact) } const char * -p_contact_show(const PContact contact) +p_contact_presence(const PContact contact) { - return contact->show; + return contact->presence; } const char * @@ -107,9 +138,10 @@ p_contact_status(const PContact contact) int p_contacts_equal_deep(const PContact c1, const PContact c2) { + int jid_eq = (g_strcmp0(c1->jid, c2->jid) == 0); int name_eq = (g_strcmp0(c1->name, c2->name) == 0); - int show_eq = (g_strcmp0(c1->show, c2->show) == 0); + int presence_eq = (g_strcmp0(c1->presence, c2->presence) == 0); int status_eq = (g_strcmp0(c1->status, c2->status) == 0); - return (name_eq && show_eq && status_eq); + return (jid_eq && name_eq && presence_eq && status_eq); } diff --git a/src/contact.h b/src/contact.h index 8f778ca9..45c9780f 100644 --- a/src/contact.h +++ b/src/contact.h @@ -25,12 +25,14 @@ typedef struct p_contact_t *PContact; -PContact p_contact_new(const char * const name, const char * const show, - const char * const status); +PContact p_contact_new(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription); PContact p_contact_copy(PContact contact); void p_contact_free(PContact contact); +const char * p_contact_jid(PContact contact); const char * p_contact_name(PContact contact); -const char * p_contact_show(PContact contact); +const char * p_contact_presence(PContact contact); const char * p_contact_status(PContact contact); int p_contacts_equal_deep(const PContact c1, const PContact c2); diff --git a/src/contact_list.c b/src/contact_list.c index e266e25e..81611818 100644 --- a/src/contact_list.c +++ b/src/contact_list.c @@ -30,7 +30,7 @@ static PAutocomplete ac; void contact_list_init(void) { - ac = p_obj_autocomplete_new((PStrFunc)p_contact_name, + ac = p_obj_autocomplete_new((PStrFunc)p_contact_jid, (PCopyFunc)p_contact_copy, (PEqualDeepFunc)p_contacts_equal_deep, (GDestroyNotify)p_contact_free); @@ -55,10 +55,12 @@ contact_list_remove(const char * const name) } gboolean -contact_list_add(const char * const name, const char * const show, - const char * const status) +contact_list_add(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription) { - return p_autocomplete_add(ac, p_contact_new(name, show, status)); + return p_autocomplete_add(ac, p_contact_new(jid, name, presence, status, + subscription)); } GSList * diff --git a/src/contact_list.h b/src/contact_list.h index bc239111..e76a2ec9 100644 --- a/src/contact_list.h +++ b/src/contact_list.h @@ -30,8 +30,9 @@ void contact_list_init(void); void contact_list_clear(void); void contact_list_reset_search_attempts(void); -gboolean contact_list_add(const char * const name, const char * const show, - const char * const status); +gboolean contact_list_add(const char * const jid, const char * const name, + const char * const presence, const char * const status, + const char * const subscription); gboolean contact_list_remove(const char * const name); GSList * get_contact_list(void); char * contact_list_find_contact(char *search_str); diff --git a/src/jabber.c b/src/jabber.c index f3e3fa27..f9c4f0c7 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -26,6 +26,7 @@ #include #include "common.h" +#include "contact_list.h" #include "jabber.h" #include "log.h" #include "preferences.h" @@ -49,6 +50,8 @@ static void _xmpp_file_logger(void * const userdata, const char * const msg); static xmpp_log_t * _xmpp_get_file_logger(); +static void _jabber_roster_request(void); + // XMPP event handlers static void _connection_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, const int error, @@ -164,26 +167,6 @@ jabber_send(const char * const msg, const char * const recipient) free(coded_msg3); } -void -jabber_roster_request(void) -{ - xmpp_stanza_t *iq, *query; - - iq = xmpp_stanza_new(jabber_conn.ctx); - xmpp_stanza_set_name(iq, "iq"); - xmpp_stanza_set_type(iq, "get"); - xmpp_stanza_set_id(iq, "roster"); - - query = xmpp_stanza_new(jabber_conn.ctx); - xmpp_stanza_set_name(query, "query"); - xmpp_stanza_set_ns(query, XMPP_NS_ROSTER); - - xmpp_stanza_add_child(iq, query); - xmpp_stanza_release(query); - xmpp_send(jabber_conn.conn, iq); - xmpp_stanza_release(iq); -} - void jabber_subscribe(const char * const recipient) { @@ -192,7 +175,7 @@ jabber_subscribe(const char * const recipient) presence = xmpp_stanza_new(jabber_conn.ctx); xmpp_stanza_set_name(presence, "presence"); xmpp_stanza_set_type(presence, "subscribe"); - xmpp_stanza_set_attribute(presence, "to", recipient); + xmpp_stanza_set_attribute(presence, "to", recipient); xmpp_send(jabber_conn.conn, presence); xmpp_stanza_release(presence); } @@ -266,6 +249,26 @@ jabber_free_resources(void) xmpp_shutdown(); } +static void +_jabber_roster_request(void) +{ + xmpp_stanza_t *iq, *query; + + iq = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(iq, "iq"); + xmpp_stanza_set_type(iq, "get"); + xmpp_stanza_set_id(iq, "roster"); + + query = xmpp_stanza_new(jabber_conn.ctx); + xmpp_stanza_set_name(query, "query"); + xmpp_stanza_set_ns(query, XMPP_NS_ROSTER); + + xmpp_stanza_add_child(iq, query); + xmpp_stanza_release(query); + xmpp_send(jabber_conn.conn, iq); + xmpp_stanza_release(iq); +} + static int _message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) @@ -333,20 +336,14 @@ _connection_handler(xmpp_conn_t * const conn, const char *jid = xmpp_conn_get_jid(conn); prof_handle_login_success(jid); - xmpp_stanza_t* pres; xmpp_handler_add(conn, _message_handler, NULL, "message", NULL, ctx); xmpp_handler_add(conn, _presence_handler, NULL, "presence", NULL, ctx); xmpp_id_handler_add(conn, _roster_handler, "roster", ctx); xmpp_timed_handler_add(conn, _ping_timed_handler, PING_INTERVAL, ctx); - pres = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(pres, "presence"); - xmpp_send(conn, pres); - xmpp_stanza_release(pres); - + _jabber_roster_request(); jabber_conn.conn_status = JABBER_CONNECTED; jabber_conn.presence = PRESENCE_ONLINE; - jabber_roster_request(); } else { // received close stream response from server after disconnect @@ -375,6 +372,7 @@ static int _roster_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 *query, *item; char *type = xmpp_stanza_get_type(stanza); @@ -382,27 +380,29 @@ _roster_handler(xmpp_conn_t * const conn, log_error("Roster query failed"); else { query = xmpp_stanza_get_child_by_name(stanza, "query"); - GSList *roster = NULL; item = xmpp_stanza_get_children(query); while (item != NULL) { - const char *name = xmpp_stanza_get_attribute(item, "name"); const char *jid = xmpp_stanza_get_attribute(item, "jid"); + const char *name = xmpp_stanza_get_attribute(item, "name"); + const char *sub = xmpp_stanza_get_attribute(item, "subscription"); - jabber_roster_entry *entry = malloc(sizeof(jabber_roster_entry)); + if (sub != NULL) { + if (strcmp(sub, "none") != 0) { - if (name != NULL) { - entry->name = strdup(name); - } else { - entry->name = NULL; + contact_list_add(jid, name, "offline", NULL, sub); + + } } - entry->jid = strdup(jid); - - roster = g_slist_append(roster, entry); item = xmpp_stanza_get_next(item); } - - prof_handle_roster(roster); +/* + xmpp_stanza_t* pres; + pres = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(pres, "presence"); + xmpp_send(conn, pres); + xmpp_stanza_release(pres); +*/ } return 1; @@ -449,13 +449,14 @@ _presence_handler(xmpp_conn_t * const conn, char *type = xmpp_stanza_get_attribute(stanza, "type"); if (type != NULL) { + // allow all subscription requests for now if (strcmp(type, "subscribe") == 0) { xmpp_stanza_t *presence; presence = xmpp_stanza_new(jabber_conn.ctx); xmpp_stanza_set_name(presence, "presence"); xmpp_stanza_set_type(presence, "subscribed"); - xmpp_stanza_set_attribute(presence, "to", short_from); + xmpp_stanza_set_attribute(presence, "to", short_from); xmpp_send(jabber_conn.conn, presence); xmpp_stanza_release(presence); return 1; diff --git a/src/jabber.h b/src/jabber.h index f1ca99e5..726fb1a5 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -44,7 +44,6 @@ void jabber_init(const int disable_tls); jabber_conn_status_t jabber_connect(const char * const user, const char * const passwd); void jabber_disconnect(void); -void jabber_roster_request(void); void jabber_process_events(void); void jabber_subscribe(const char * const recipient); void jabber_send(const char * const msg, const char * const recipient); diff --git a/src/profanity.c b/src/profanity.c index 71c11be0..2953c4ba 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -41,7 +41,6 @@ static log_level_t _get_log_level(char *log_level); static gboolean _process_input(char *inp); static void _create_config_directory(); -static void _free_roster_entry(jabber_roster_entry *entry); static void _init(const int disable_tls, char *log_level); static void _shutdown(void); @@ -166,7 +165,7 @@ prof_handle_failed_login(void) void prof_handle_contact_online(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, show, status); + gboolean result = contact_list_add(contact, NULL, show, status, NULL); if (result) { win_contact_online(contact, show, status); } @@ -176,30 +175,13 @@ prof_handle_contact_online(char *contact, char *show, char *status) void prof_handle_contact_offline(char *contact, char *show, char *status) { - gboolean result = contact_list_add(contact, "offline", status); + gboolean result = contact_list_add(contact, NULL, "offline", status, NULL); if (result) { win_contact_offline(contact, show, status); } win_page_off(); } -void -prof_handle_roster(GSList *roster) -{ - while (roster != NULL) { - jabber_roster_entry *entry = roster->data; - - // if contact not in contact list add them as offline - if (contact_list_find_contact(entry->jid) == NULL) { - contact_list_add(entry->jid, "offline", NULL); - } - - roster = g_slist_next(roster); - } - - g_slist_free_full(roster, (GDestroyNotify)_free_roster_entry); -} - static void _create_config_directory(void) { @@ -209,16 +191,6 @@ _create_config_directory(void) g_string_free(dir, TRUE); } -static void -_free_roster_entry(jabber_roster_entry *entry) -{ - if (entry->name != NULL) { - free(entry->name); - entry->name = NULL; - } - free(entry->jid); -} - static log_level_t _get_log_level(char *log_level) { diff --git a/src/profanity.h b/src/profanity.h index 430148e2..a67fb2df 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -23,11 +23,6 @@ #ifndef PROFANITY_H #define PROFANITY_H -typedef struct roster_entry_t { - char *name; - char *jid; -} jabber_roster_entry; - void prof_run(const int disable_tls, char *log_level); void prof_handle_login_success(const char *jid); diff --git a/src/windows.c b/src/windows.c index f1c8f0fe..276d1eb8 100644 --- a/src/windows.c +++ b/src/windows.c @@ -427,8 +427,8 @@ win_show_outgoing_msg(const char * const from, const char * const to, } if (contact != NULL) { - if (strcmp(p_contact_show(contact), "offline") == 0) { - const char const *show = p_contact_show(contact); + if (strcmp(p_contact_presence(contact), "offline") == 0) { + const char const *show = p_contact_presence(contact); const char const *status = p_contact_status(contact); _show_status_string(win, to, show, status, "--", "offline"); } @@ -703,41 +703,41 @@ cons_show_contacts(GSList *list) while(curr) { PContact contact = curr->data; - const char *show = p_contact_show(contact); + const char *presence = p_contact_presence(contact); _win_show_time(_cons_win); - if (strcmp(show, "online") == 0) { + if (strcmp(presence, "online") == 0) { wattron(_cons_win, COLOUR_ONLINE); - } else if (strcmp(show, "away") == 0) { + } else if (strcmp(presence, "away") == 0) { wattron(_cons_win, COLOUR_AWAY); - } else if (strcmp(show, "chat") == 0) { + } else if (strcmp(presence, "chat") == 0) { wattron(_cons_win, COLOUR_CHAT); - } else if (strcmp(show, "dnd") == 0) { + } else if (strcmp(presence, "dnd") == 0) { wattron(_cons_win, COLOUR_DND); - } else if (strcmp(show, "xa") == 0) { + } else if (strcmp(presence, "xa") == 0) { wattron(_cons_win, COLOUR_XA); } else { wattron(_cons_win, COLOUR_OFFLINE); } - wprintw(_cons_win, "%s", p_contact_name(contact)); - wprintw(_cons_win, " is %s", show); + wprintw(_cons_win, "%s", p_contact_jid(contact)); + wprintw(_cons_win, " is %s", presence); if (p_contact_status(contact)) wprintw(_cons_win, ", \"%s\"", p_contact_status(contact)); wprintw(_cons_win, "\n"); - if (strcmp(show, "online") == 0) { + if (strcmp(presence, "online") == 0) { wattroff(_cons_win, COLOUR_ONLINE); - } else if (strcmp(show, "away") == 0) { + } else if (strcmp(presence, "away") == 0) { wattroff(_cons_win, COLOUR_AWAY); - } else if (strcmp(show, "chat") == 0) { + } else if (strcmp(presence, "chat") == 0) { wattroff(_cons_win, COLOUR_CHAT); - } else if (strcmp(show, "dnd") == 0) { + } else if (strcmp(presence, "dnd") == 0) { wattroff(_cons_win, COLOUR_DND); - } else if (strcmp(show, "xa") == 0) { + } else if (strcmp(presence, "xa") == 0) { wattroff(_cons_win, COLOUR_XA); } else { wattroff(_cons_win, COLOUR_OFFLINE);