1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-09-22 19:45:54 -04:00

Load roster before sending presence

This commit is contained in:
James Booth 2012-10-28 20:52:30 +00:00
parent 4b6002ae63
commit d13794bf60
10 changed files with 144 additions and 139 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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 *

View File

@ -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);

View File

@ -26,6 +26,7 @@
#include <strophe.h>
#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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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);