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

Use one stanza handler per type (message, iq, presence)

Allows plugins to stop stanza processing
This commit is contained in:
James Booth 2016-03-28 01:25:48 +01:00
parent 8933d59b03
commit d39e48ba18
8 changed files with 457 additions and 638 deletions

View File

@ -635,6 +635,7 @@ python_on_message_stanza_receive_hook(ProfPlugin *plugin, const char *const text
} }
} }
allow_python_threads();
return TRUE; return TRUE;
} }
@ -699,6 +700,7 @@ python_on_presence_stanza_receive_hook(ProfPlugin *plugin, const char *const tex
} }
} }
allow_python_threads();
return TRUE; return TRUE;
} }
@ -763,6 +765,7 @@ python_on_iq_stanza_receive_hook(ProfPlugin *plugin, const char *const text)
} }
} }
allow_python_threads();
return TRUE; return TRUE;
} }

View File

@ -64,22 +64,16 @@ static Autocomplete bookmark_ac;
static GList *bookmark_list; static GList *bookmark_list;
// id handlers // id handlers
static int _bookmark_result_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static int _bookmark_result_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
// scheduled
static int _bookmark_handle_delete(xmpp_conn_t *const conn, void *const userdata);
static void _bookmark_item_destroy(gpointer item); static void _bookmark_item_destroy(gpointer item);
static int _match_bookmark_by_jid(gconstpointer a, gconstpointer b); static int _match_bookmark_by_jid(gconstpointer a, gconstpointer b);
static void _send_bookmarks(void); static void _send_bookmarks(void);
static void _send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
void void
bookmark_request(void) bookmark_request(void)
{ {
char *id; char *id;
xmpp_conn_t *conn = connection_get_conn();
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_stanza_t *iq; xmpp_stanza_t *iq;
@ -92,12 +86,11 @@ bookmark_request(void)
bookmark_list = NULL; bookmark_list = NULL;
} }
xmpp_timed_handler_add(conn, _bookmark_handle_delete, BOOKMARK_TIMEOUT, id); id_handler_add(id, _bookmark_result_id_handler, id);
xmpp_id_handler_add(conn, _bookmark_result_id_handler, id, id);
iq = stanza_create_bookmarks_storage_request(ctx); iq = stanza_create_bookmarks_storage_request(ctx);
xmpp_stanza_set_id(iq, id); xmpp_stanza_set_id(iq, id);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
@ -247,11 +240,8 @@ bookmark_autocomplete_reset(void)
} }
static int static int
_bookmark_result_id_handler(xmpp_conn_t *const conn, _bookmark_result_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
xmpp_stanza_t *const stanza, void *const userdata)
{ {
log_debug("iq stanza bookmark result id handler fired");
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
char *id = (char *)userdata; char *id = (char *)userdata;
xmpp_stanza_t *ptr; xmpp_stanza_t *ptr;
@ -265,7 +255,6 @@ _bookmark_result_id_handler(xmpp_conn_t *const conn,
Jid *my_jid; Jid *my_jid;
Bookmark *item; Bookmark *item;
xmpp_timed_handler_delete(conn, _bookmark_handle_delete);
g_free(id); g_free(id);
name = xmpp_stanza_get_name(stanza); name = xmpp_stanza_get_name(stanza);
@ -366,22 +355,6 @@ _bookmark_result_id_handler(xmpp_conn_t *const conn,
return 0; return 0;
} }
static int
_bookmark_handle_delete(xmpp_conn_t *const conn,
void *const userdata)
{
char *id = (char *)userdata;
assert(id != NULL);
log_debug("Timeout for handler with id=%s", id);
xmpp_id_handler_delete(conn, _bookmark_result_id_handler, id);
g_free(id);
return 0;
}
static void static void
_bookmark_item_destroy(gpointer item) _bookmark_item_destroy(gpointer item)
{ {
@ -409,7 +382,6 @@ _match_bookmark_by_jid(gconstpointer a, gconstpointer b)
static void static void
_send_bookmarks(void) _send_bookmarks(void)
{ {
xmpp_conn_t *conn = connection_get_conn();
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_stanza_t *iq = xmpp_stanza_new(ctx); xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
@ -481,21 +453,6 @@ _send_bookmarks(void)
xmpp_stanza_release(storage); xmpp_stanza_release(storage);
xmpp_stanza_release(query); xmpp_stanza_release(query);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
static void
_send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
{
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
char *plugin_text = plugins_on_iq_stanza_send(text);
if (plugin_text) {
xmpp_send_raw_string(conn, "%s", plugin_text);
} else {
xmpp_send_raw_string(conn, "%s", text);
}
}

View File

@ -644,7 +644,6 @@ _connection_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status, con
chat_sessions_init(); chat_sessions_init();
roster_add_handlers();
message_add_handlers(); message_add_handlers();
presence_add_handlers(); presence_add_handlers();
iq_add_handlers(); iq_add_handlers();

View File

@ -46,6 +46,8 @@
#include "resource.h" #include "resource.h"
typedef int(*ProfIdCallback)(xmpp_stanza_t *const stanza, void *const userdata);
xmpp_conn_t* connection_get_conn(void); xmpp_conn_t* connection_get_conn(void);
xmpp_ctx_t* connection_get_ctx(void); xmpp_ctx_t* connection_get_ctx(void);
void connection_set_priority(int priority); void connection_set_priority(int priority);
@ -53,4 +55,10 @@ void connection_set_presence_message(const char *const message);
void connection_add_available_resource(Resource *resource); void connection_add_available_resource(Resource *resource);
void connection_remove_available_resource(const char *const resource); void connection_remove_available_resource(const char *const resource);
void send_iq_stanza(xmpp_stanza_t *const stanza);
void roster_set_handler(xmpp_stanza_t *const stanza);
void roster_result_handler(xmpp_stanza_t *const stanza);
void id_handler_add(const char *const id, ProfIdCallback func, void *userdata);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -60,33 +60,72 @@
#include "pgp/gpg.h" #include "pgp/gpg.h"
#include "plugins/plugins.h" #include "plugins/plugins.h"
#define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_MESSAGE, type, ctx) static int _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
// regular handlers static void _handle_error(xmpp_stanza_t *const stanza);
static int _groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_groupchat(xmpp_stanza_t *const stanza);
static int _chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handel_muc_user(xmpp_stanza_t *const stanza);
static int _muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_conference(xmpp_stanza_t *const stanza);
static int _conference_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_captcha(xmpp_stanza_t *const stanza);
static int _captcha_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_receipt_received(xmpp_stanza_t *const stanza);
static int _message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_chat(xmpp_stanza_t *const stanza);
static int _receipt_received_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
static void _send_message_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza); static void _send_message_stanza(xmpp_stanza_t *const stanza);
static gboolean _receive_message_stanza(xmpp_stanza_t *const stanza);
static int
_message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata)
{
log_debug("Message stanza handler fired");
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
gboolean cont = plugins_on_message_stanza_receive(text);
if (!cont) {
return 1;
}
char *type = xmpp_stanza_get_type(stanza);
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
_handle_error(stanza);
}
if (g_strcmp0(type, STANZA_TYPE_GROUPCHAT) == 0) {
_handle_groupchat(stanza);
}
xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (mucuser) {
_handel_muc_user(stanza);
}
xmpp_stanza_t *conference = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
if (conference) {
_handle_conference(stanza);
}
xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA);
if (captcha) {
_handle_captcha(stanza);
}
xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS);
if (receipts) {
_handle_receipt_received(stanza);
}
_handle_chat(stanza);
return 1;
}
void void
message_add_handlers(void) message_add_handlers(void)
{ {
xmpp_conn_t * const conn = connection_get_conn(); xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_handler_add(conn, _message_handler, NULL, STANZA_NAME_MESSAGE, NULL, ctx);
HANDLE(NULL, STANZA_TYPE_ERROR, _message_error_handler);
HANDLE(NULL, STANZA_TYPE_GROUPCHAT, _groupchat_handler);
HANDLE(NULL, NULL, _chat_handler);
HANDLE(STANZA_NS_MUC_USER, NULL, _muc_user_handler);
HANDLE(STANZA_NS_CONFERENCE, NULL, _conference_handler);
HANDLE(STANZA_NS_CAPTCHA, NULL, _captcha_handler);
HANDLE(STANZA_NS_RECEIPTS, NULL, _receipt_received_handler);
} }
static char* static char*
@ -126,7 +165,6 @@ _session_state(const char *const barejid)
char* char*
message_send_chat(const char *const barejid, const char *const msg) message_send_chat(const char *const barejid, const char *const msg)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *state = _session_state(barejid); char *state = _session_state(barejid);
@ -144,7 +182,7 @@ message_send_chat(const char *const barejid, const char *const msg)
stanza_attach_receipt_request(ctx, message); stanza_attach_receipt_request(ctx, message);
} }
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
return id; return id;
@ -153,7 +191,6 @@ message_send_chat(const char *const barejid, const char *const msg)
char* char*
message_send_chat_pgp(const char *const barejid, const char *const msg) message_send_chat_pgp(const char *const barejid, const char *const msg)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *state = _session_state(barejid); char *state = _session_state(barejid);
@ -200,7 +237,7 @@ message_send_chat_pgp(const char *const barejid, const char *const msg)
stanza_attach_receipt_request(ctx, message); stanza_attach_receipt_request(ctx, message);
} }
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
return id; return id;
@ -209,7 +246,6 @@ message_send_chat_pgp(const char *const barejid, const char *const msg)
char* char*
message_send_chat_otr(const char *const barejid, const char *const msg) message_send_chat_otr(const char *const barejid, const char *const msg)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *state = _session_state(barejid); char *state = _session_state(barejid);
@ -231,7 +267,7 @@ message_send_chat_otr(const char *const barejid, const char *const msg)
stanza_attach_receipt_request(ctx, message); stanza_attach_receipt_request(ctx, message);
} }
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
return id; return id;
@ -240,37 +276,34 @@ message_send_chat_otr(const char *const barejid, const char *const msg)
void void
message_send_private(const char *const fulljid, const char *const msg) message_send_private(const char *const fulljid, const char *const msg)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *id = create_unique_id("prv"); char *id = create_unique_id("prv");
xmpp_stanza_t *message = stanza_create_message(ctx, id, fulljid, STANZA_TYPE_CHAT, msg); xmpp_stanza_t *message = stanza_create_message(ctx, id, fulljid, STANZA_TYPE_CHAT, msg);
free(id); free(id);
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
} }
void void
message_send_groupchat(const char *const roomjid, const char *const msg) message_send_groupchat(const char *const roomjid, const char *const msg)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *id = create_unique_id("muc"); char *id = create_unique_id("muc");
xmpp_stanza_t *message = stanza_create_message(ctx, id, roomjid, STANZA_TYPE_GROUPCHAT, msg); xmpp_stanza_t *message = stanza_create_message(ctx, id, roomjid, STANZA_TYPE_GROUPCHAT, msg);
free(id); free(id);
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
} }
void void
message_send_groupchat_subject(const char *const roomjid, const char *const subject) message_send_groupchat_subject(const char *const roomjid, const char *const subject)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *message = stanza_create_room_subject_message(ctx, roomjid, subject); xmpp_stanza_t *message = stanza_create_room_subject_message(ctx, roomjid, subject);
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
} }
@ -278,11 +311,9 @@ void
message_send_invite(const char *const roomjid, const char *const contact, message_send_invite(const char *const roomjid, const char *const contact,
const char *const reason) const char *const reason)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *stanza; xmpp_stanza_t *stanza;
muc_member_type_t member_type = muc_member_type(roomjid); muc_member_type_t member_type = muc_member_type(roomjid);
if (member_type == MUC_MEMBER_TYPE_PUBLIC) { if (member_type == MUC_MEMBER_TYPE_PUBLIC) {
log_debug("Sending direct invite to %s, for %s", contact, roomjid); log_debug("Sending direct invite to %s, for %s", contact, roomjid);
@ -293,18 +324,17 @@ message_send_invite(const char *const roomjid, const char *const contact,
stanza = stanza_create_mediated_invite(ctx, roomjid, contact, reason); stanza = stanza_create_mediated_invite(ctx, roomjid, contact, reason);
} }
_send_message_stanza(conn, stanza); _send_message_stanza(stanza);
xmpp_stanza_release(stanza); xmpp_stanza_release(stanza);
} }
void void
message_send_composing(const char *const jid) message_send_composing(const char *const jid)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_COMPOSING); xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_COMPOSING);
_send_message_stanza(conn, stanza); _send_message_stanza(stanza);
xmpp_stanza_release(stanza); xmpp_stanza_release(stanza);
} }
@ -312,39 +342,34 @@ message_send_composing(const char *const jid)
void void
message_send_paused(const char *const jid) message_send_paused(const char *const jid)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_PAUSED); xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_PAUSED);
_send_message_stanza(conn, stanza); _send_message_stanza(stanza);
xmpp_stanza_release(stanza); xmpp_stanza_release(stanza);
} }
void void
message_send_inactive(const char *const jid) message_send_inactive(const char *const jid)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_INACTIVE); xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_INACTIVE);
_send_message_stanza(conn, stanza); _send_message_stanza(stanza);
xmpp_stanza_release(stanza); xmpp_stanza_release(stanza);
} }
void void
message_send_gone(const char *const jid) message_send_gone(const char *const jid)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_GONE); xmpp_stanza_t *stanza = stanza_create_chat_state(ctx, jid, STANZA_NAME_GONE);
_send_message_stanza(conn, stanza); _send_message_stanza(stanza);
xmpp_stanza_release(stanza); xmpp_stanza_release(stanza);
} }
static int static void
_message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_error(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza error handler fired");
char *id = xmpp_stanza_get_id(stanza); char *id = xmpp_stanza_get_id(stanza);
char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
@ -388,39 +413,35 @@ _message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, voi
} }
free(err_msg); free(err_msg);
return 1;
} }
static int static void
_muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handel_muc_user(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza muc user handler fired");
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_stanza_t *xns_muc_user = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); xmpp_stanza_t *xns_muc_user = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
char *room = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *room = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (!room) { if (!room) {
log_warning("Message received with no from attribute, ignoring"); log_warning("Message received with no from attribute, ignoring");
return 1; return;
} }
// XEP-0045 // XEP-0045
xmpp_stanza_t *invite = xmpp_stanza_get_child_by_name(xns_muc_user, STANZA_NAME_INVITE); xmpp_stanza_t *invite = xmpp_stanza_get_child_by_name(xns_muc_user, STANZA_NAME_INVITE);
if (!invite) { if (!invite) {
return 1; return;
} }
char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM); char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM);
if (!invitor_jid) { if (!invitor_jid) {
log_warning("Chat room invite received with no from attribute"); log_warning("Chat room invite received with no from attribute");
return 1; return;
} }
Jid *jidp = jid_create(invitor_jid); Jid *jidp = jid_create(invitor_jid);
if (!jidp) { if (!jidp) {
return 1; return;
} }
char *invitor = jidp->barejid; char *invitor = jidp->barejid;
@ -444,33 +465,29 @@ _muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *co
if (password) { if (password) {
xmpp_free(ctx, password); xmpp_free(ctx, password);
} }
return 1;
} }
static int static void
_conference_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_conference(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza conference handler fired");
xmpp_stanza_t *xns_conference = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *xns_conference = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (!from) { if (!from) {
log_warning("Message received with no from attribute, ignoring"); log_warning("Message received with no from attribute, ignoring");
return 1; return;
} }
Jid *jidp = jid_create(from); Jid *jidp = jid_create(from);
if (!jidp) { if (!jidp) {
return 1; return;
} }
// XEP-0249 // XEP-0249
char *room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID); char *room = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_JID);
if (!room) { if (!room) {
jid_destroy(jidp); jid_destroy(jidp);
return 1; return;
} }
char *reason = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_REASON); char *reason = xmpp_stanza_get_attribute(xns_conference, STANZA_ATTR_REASON);
@ -478,45 +495,37 @@ _conference_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *
sv_ev_room_invite(INVITE_DIRECT, jidp->barejid, room, reason, password); sv_ev_room_invite(INVITE_DIRECT, jidp->barejid, room, reason, password);
jid_destroy(jidp); jid_destroy(jidp);
return 1;
} }
static int static void
_captcha_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_captcha(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza captcha handler fired");
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (!from) { if (!from) {
log_warning("Message received with no from attribute, ignoring"); log_warning("Message received with no from attribute, ignoring");
return 1; return;
} }
// XEP-0158 // XEP-0158
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
if (!body) { if (!body) {
return 1; return;
} }
char *message = xmpp_stanza_get_text(body); char *message = xmpp_stanza_get_text(body);
if (!message) { if (!message) {
return 1; return;
} }
sv_ev_room_broadcast(from, message); sv_ev_room_broadcast(from, message);
xmpp_free(ctx, message); xmpp_free(ctx, message);
return 1;
} }
static int static void
_groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_groupchat(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza groupchat handler fired");
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
char *message = NULL; char *message = NULL;
char *room_jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *room_jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
@ -530,7 +539,7 @@ _groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
xmpp_free(ctx, message); xmpp_free(ctx, message);
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
// handle room broadcasts // handle room broadcasts
@ -538,33 +547,33 @@ _groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
if (!body) { if (!body) {
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
message = xmpp_stanza_get_text(body); message = xmpp_stanza_get_text(body);
if (!message) { if (!message) {
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
sv_ev_room_broadcast(room_jid, message); sv_ev_room_broadcast(room_jid, message);
xmpp_free(ctx, message); xmpp_free(ctx, message);
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
if (!jid_is_valid_room_form(jid)) { if (!jid_is_valid_room_form(jid)) {
log_error("Invalid room JID: %s", jid->str); log_error("Invalid room JID: %s", jid->str);
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
// room not active in profanity // room not active in profanity
if (!muc_active(jid->barejid)) { if (!muc_active(jid->barejid)) {
log_error("Message received for inactive chat room: %s", jid->str); log_error("Message received for inactive chat room: %s", jid->str);
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
@ -572,13 +581,13 @@ _groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
// check for and deal with message // check for and deal with message
if (!body) { if (!body) {
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
message = xmpp_stanza_get_text(body); message = xmpp_stanza_get_text(body);
if (!message) { if (!message) {
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
// determine if the notifications happened whilst offline // determine if the notifications happened whilst offline
@ -592,14 +601,11 @@ _groupchat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
xmpp_free(ctx, message); xmpp_free(ctx, message);
jid_destroy(jid); jid_destroy(jid);
return 1;
} }
void void
_message_send_receipt(const char *const fulljid, const char *const message_id) _message_send_receipt(const char *const fulljid, const char *const message_id)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *message = xmpp_stanza_new(ctx); xmpp_stanza_t *message = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE); xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE);
@ -616,36 +622,32 @@ _message_send_receipt(const char *const fulljid, const char *const message_id)
xmpp_stanza_add_child(message, receipt); xmpp_stanza_add_child(message, receipt);
xmpp_stanza_release(receipt); xmpp_stanza_release(receipt);
_send_message_stanza(conn, message); _send_message_stanza(message);
xmpp_stanza_release(message); xmpp_stanza_release(message);
} }
static int static void
_receipt_received_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_receipt_received(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza receipt received handler fired");
xmpp_stanza_t *receipt = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); xmpp_stanza_t *receipt = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS);
char *name = xmpp_stanza_get_name(receipt); char *name = xmpp_stanza_get_name(receipt);
if (g_strcmp0(name, "received") != 0) { if (g_strcmp0(name, "received") != 0) {
return 1; return;
} }
char *id = xmpp_stanza_get_attribute(receipt, STANZA_ATTR_ID); char *id = xmpp_stanza_get_attribute(receipt, STANZA_ATTR_ID);
if (!id) { if (!id) {
return 1; return;
} }
char *fulljid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *fulljid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (!fulljid) { if (!fulljid) {
return 1; return;
} }
Jid *jidp = jid_create(fulljid); Jid *jidp = jid_create(fulljid);
sv_ev_message_receipt(jidp->barejid, id); sv_ev_message_receipt(jidp->barejid, id);
jid_destroy(jidp); jid_destroy(jidp);
return 1;
} }
void void
@ -761,33 +763,26 @@ _handle_carbons(xmpp_stanza_t *const stanza)
return FALSE; return FALSE;
} }
static int static void
_chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _handle_chat(xmpp_stanza_t *const stanza)
{ {
log_debug("Message stanza chat handler fired");
gboolean cont = _receive_message_stanza(stanza);
if (!cont) {
return 1;
}
// ignore if type not chat or absent // ignore if type not chat or absent
char *type = xmpp_stanza_get_type(stanza); char *type = xmpp_stanza_get_type(stanza);
if (!(g_strcmp0(type, "chat") == 0 || type == NULL)) { if (!(g_strcmp0(type, "chat") == 0 || type == NULL)) {
return 1; return;
} }
// check if carbon message // check if carbon message
gboolean res = _handle_carbons(stanza); gboolean res = _handle_carbons(stanza);
if (res) { if (res) {
return 1; return;
} }
// ignore handled namespaces // ignore handled namespaces
xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA); xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA);
if (conf || captcha) { if (conf || captcha) {
return 1; return;
} }
// some clients send the mucuser namespace with private messages // some clients send the mucuser namespace with private messages
@ -796,7 +791,7 @@ _chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const
xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
if (mucuser && body == NULL) { if (mucuser && body == NULL) {
return 1; return;
} }
gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
@ -806,7 +801,7 @@ _chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const
if (muc_active(jid->barejid)) { if (muc_active(jid->barejid)) {
_private_chat_handler(stanza, jid->fulljid); _private_chat_handler(stanza, jid->fulljid);
jid_destroy(jid); jid_destroy(jid);
return 1; return;
} }
// standard chat message, use jid without resource // standard chat message, use jid without resource
@ -852,16 +847,16 @@ _chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const
if (timestamp) g_date_time_unref(timestamp); if (timestamp) g_date_time_unref(timestamp);
jid_destroy(jid); jid_destroy(jid);
return 1;
} }
static void static void
_send_message_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza) _send_message_stanza(xmpp_stanza_t *const stanza)
{ {
char *text; char *text;
size_t text_size; size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size); xmpp_stanza_to_text(stanza, &text, &text_size);
xmpp_conn_t *conn = connection_get_conn();
char *plugin_text = plugins_on_message_stanza_send(text); char *plugin_text = plugins_on_message_stanza_send(text);
if (plugin_text) { if (plugin_text) {
xmpp_send_raw_string(conn, "%s", plugin_text); xmpp_send_raw_string(conn, "%s", plugin_text);
@ -869,13 +864,3 @@ _send_message_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
xmpp_send_raw_string(conn, "%s", text); xmpp_send_raw_string(conn, "%s", text);
} }
} }
static gboolean
_receive_message_stanza(xmpp_stanza_t *const stanza)
{
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
return plugins_on_message_stanza_receive(text);
}

View File

@ -63,23 +63,20 @@
static Autocomplete sub_requests_ac; static Autocomplete sub_requests_ac;
#define HANDLE(ns, type, func) xmpp_handler_add(conn, func, ns, STANZA_NAME_PRESENCE, type, ctx) static int _presence_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
// regular handlers static void _presence_error_handler(xmpp_stanza_t *const stanza);
static int _unavailable_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _unavailable_handler(xmpp_stanza_t *const stanza);
static int _subscribe_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _subscribe_handler(xmpp_stanza_t *const stanza);
static int _subscribed_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _subscribed_handler(xmpp_stanza_t *const stanza);
static int _unsubscribed_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _unsubscribed_handler(xmpp_stanza_t *const stanza);
static int _available_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _muc_user_handler(xmpp_stanza_t *const stanza);
static int _muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _available_handler(xmpp_stanza_t *const stanza);
static int _presence_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
void _send_caps_request(char *node, char *caps_key, char *id, char *from); void _send_caps_request(char *node, char *caps_key, char *id, char *from);
static void _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence); static void _send_room_presence(xmpp_stanza_t *presence);
static void _send_presence_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza); static void _send_presence_stanza(xmpp_stanza_t *const stanza);
static void _send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
static gboolean _receive_presence_stanza(xmpp_stanza_t *const stanza);
void void
presence_sub_requests_init(void) presence_sub_requests_init(void)
@ -87,19 +84,57 @@ presence_sub_requests_init(void)
sub_requests_ac = autocomplete_new(); sub_requests_ac = autocomplete_new();
} }
static int
_presence_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata)
{
log_debug("Presence stanza handler fired");
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
gboolean cont = plugins_on_presence_stanza_receive(text);
if (!cont) {
return 1;
}
char *type = xmpp_stanza_get_type(stanza);
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
_presence_error_handler(stanza);
}
if (g_strcmp0(type, STANZA_TYPE_UNAVAILABLE) == 0) {
_unavailable_handler(stanza);
}
if (g_strcmp0(type, STANZA_TYPE_SUBSCRIBE) == 0) {
_subscribe_handler(stanza);
}
if (g_strcmp0(type, STANZA_TYPE_SUBSCRIBED) == 0) {
_subscribed_handler(stanza);
}
if (g_strcmp0(type, STANZA_TYPE_UNSUBSCRIBED) == 0) {
_unsubscribed_handler(stanza);
}
xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (mucuser) {
_muc_user_handler(stanza);
}
_available_handler(stanza);
return 1;
}
void void
presence_add_handlers(void) presence_add_handlers(void)
{ {
xmpp_conn_t * const conn = connection_get_conn(); xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_handler_add(conn, _presence_handler, NULL, STANZA_NAME_PRESENCE, NULL, ctx);
HANDLE(NULL, STANZA_TYPE_ERROR, _presence_error_handler);
HANDLE(STANZA_NS_MUC_USER, NULL, _muc_user_handler);
HANDLE(NULL, STANZA_TYPE_UNAVAILABLE, _unavailable_handler);
HANDLE(NULL, STANZA_TYPE_SUBSCRIBE, _subscribe_handler);
HANDLE(NULL, STANZA_TYPE_SUBSCRIBED, _subscribed_handler);
HANDLE(NULL, STANZA_TYPE_UNSUBSCRIBED, _unsubscribed_handler);
HANDLE(NULL, NULL, _available_handler);
} }
void void
@ -108,7 +143,6 @@ presence_subscription(const char *const jid, const jabber_subscr_t action)
assert(jid != NULL); assert(jid != NULL);
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_conn_t * const conn = connection_get_conn();
const char *type = NULL; const char *type = NULL;
Jid *jidp = jid_create(jid); Jid *jidp = jid_create(jid);
@ -140,7 +174,7 @@ presence_subscription(const char *const jid, const jabber_subscr_t action)
xmpp_stanza_set_name(presence, STANZA_NAME_PRESENCE); xmpp_stanza_set_name(presence, STANZA_NAME_PRESENCE);
xmpp_stanza_set_type(presence, type); xmpp_stanza_set_type(presence, type);
xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, jidp->barejid); xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, jidp->barejid);
_send_presence_stanza(conn, presence); _send_presence_stanza(presence);
xmpp_stanza_release(presence); xmpp_stanza_release(presence);
jid_destroy(jidp); jid_destroy(jidp);
@ -214,7 +248,6 @@ presence_send(const resource_presence_t presence_type, const char *const msg, co
} }
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_conn_t * const conn = connection_get_conn();
const int pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), presence_type); const int pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), presence_type);
const char *show = stanza_get_presence_string_from_type(presence_type); const char *show = stanza_get_presence_string_from_type(presence_type);
@ -245,8 +278,8 @@ presence_send(const resource_presence_t presence_type, const char *const msg, co
stanza_attach_last_activity(ctx, presence, idle); stanza_attach_last_activity(ctx, presence, idle);
} }
stanza_attach_caps(ctx, presence); stanza_attach_caps(ctx, presence);
_send_presence_stanza(conn, presence); _send_presence_stanza(presence);
_send_room_presence(conn, presence); _send_room_presence(presence);
xmpp_stanza_release(presence); xmpp_stanza_release(presence);
// set last presence for account // set last presence for account
@ -261,7 +294,7 @@ presence_send(const resource_presence_t presence_type, const char *const msg, co
} }
static void static void
_send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence) _send_room_presence(xmpp_stanza_t *presence)
{ {
GList *rooms_p = muc_rooms(); GList *rooms_p = muc_rooms();
GList *rooms = rooms_p; GList *rooms = rooms_p;
@ -275,7 +308,7 @@ _send_room_presence(xmpp_conn_t *conn, xmpp_stanza_t *presence)
xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, full_room_jid); xmpp_stanza_set_attribute(presence, STANZA_ATTR_TO, full_room_jid);
log_debug("Sending presence to room: %s", full_room_jid); log_debug("Sending presence to room: %s", full_room_jid);
_send_presence_stanza(conn, presence); _send_presence_stanza(presence);
free(full_room_jid); free(full_room_jid);
} }
@ -294,7 +327,6 @@ presence_join_room(char *room, char *nick, char * passwd)
log_debug("Sending room join presence to: %s", jid->fulljid); log_debug("Sending room join presence to: %s", jid->fulljid);
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_conn_t *conn = connection_get_conn();
resource_presence_t presence_type = resource_presence_t presence_type =
accounts_get_last_presence(jabber_get_account_name()); accounts_get_last_presence(jabber_get_account_name());
const char *show = stanza_get_presence_string_from_type(presence_type); const char *show = stanza_get_presence_string_from_type(presence_type);
@ -308,7 +340,7 @@ presence_join_room(char *room, char *nick, char * passwd)
stanza_attach_priority(ctx, presence, pri); stanza_attach_priority(ctx, presence, pri);
stanza_attach_caps(ctx, presence); stanza_attach_caps(ctx, presence);
_send_presence_stanza(conn, presence); _send_presence_stanza(presence);
xmpp_stanza_release(presence); xmpp_stanza_release(presence);
jid_destroy(jid); jid_destroy(jid);
@ -322,7 +354,6 @@ presence_change_room_nick(const char *const room, const char *const nick)
log_debug("Sending room nickname change to: %s, nick: %s", room, nick); log_debug("Sending room nickname change to: %s, nick: %s", room, nick);
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_conn_t *conn = connection_get_conn();
resource_presence_t presence_type = resource_presence_t presence_type =
accounts_get_last_presence(jabber_get_account_name()); accounts_get_last_presence(jabber_get_account_name());
const char *show = stanza_get_presence_string_from_type(presence_type); const char *show = stanza_get_presence_string_from_type(presence_type);
@ -338,7 +369,7 @@ presence_change_room_nick(const char *const room, const char *const nick)
stanza_attach_priority(ctx, presence, pri); stanza_attach_priority(ctx, presence, pri);
stanza_attach_caps(ctx, presence); stanza_attach_caps(ctx, presence);
_send_presence_stanza(conn, presence); _send_presence_stanza(presence);
xmpp_stanza_release(presence); xmpp_stanza_release(presence);
free(full_room_jid); free(full_room_jid);
@ -351,23 +382,18 @@ presence_leave_chat_room(const char *const room_jid)
log_debug("Sending room leave presence to: %s", room_jid); log_debug("Sending room leave presence to: %s", room_jid);
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_conn_t *conn = connection_get_conn();
char *nick = muc_nick(room_jid); char *nick = muc_nick(room_jid);
if (nick) { if (nick) {
xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, nick);
nick); _send_presence_stanza(presence);
_send_presence_stanza(conn, presence);
xmpp_stanza_release(presence); xmpp_stanza_release(presence);
} }
} }
static int static void
_presence_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, _presence_error_handler(xmpp_stanza_t *const stanza)
void *const userdata)
{ {
log_debug("Presence stanza error handler fired");
char *id = xmpp_stanza_get_id(stanza); char *id = xmpp_stanza_get_id(stanza);
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
@ -400,7 +426,7 @@ _presence_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
} }
cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond); cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond);
jid_destroy(fulljid); jid_destroy(fulljid);
return 1; return;
} }
// stanza_get_error never returns NULL // stanza_get_error never returns NULL
@ -433,17 +459,12 @@ _presence_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
} }
free(err_msg); free(err_msg);
return 1;
} }
static int static void
_unsubscribed_handler(xmpp_conn_t *const conn, _unsubscribed_handler(xmpp_stanza_t *const stanza)
xmpp_stanza_t *const stanza, void *const userdata)
{ {
log_debug("Presence stanza unsubscribed handler fired");
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
Jid *from_jid = jid_create(from); Jid *from_jid = jid_create(from);
log_debug("Unsubscribed presence handler fired for %s", from); log_debug("Unsubscribed presence handler fired for %s", from);
@ -452,16 +473,11 @@ _unsubscribed_handler(xmpp_conn_t *const conn,
autocomplete_remove(sub_requests_ac, from_jid->barejid); autocomplete_remove(sub_requests_ac, from_jid->barejid);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1;
} }
static int static void
_subscribed_handler(xmpp_conn_t *const conn, _subscribed_handler(xmpp_stanza_t *const stanza)
xmpp_stanza_t *const stanza, void *const userdata)
{ {
log_debug("Presence stanza subscribed handler fired");
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
Jid *from_jid = jid_create(from); Jid *from_jid = jid_create(from);
log_debug("Subscribed presence handler fired for %s", from); log_debug("Subscribed presence handler fired for %s", from);
@ -470,40 +486,31 @@ _subscribed_handler(xmpp_conn_t *const conn,
autocomplete_remove(sub_requests_ac, from_jid->barejid); autocomplete_remove(sub_requests_ac, from_jid->barejid);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1;
} }
static int static void
_subscribe_handler(xmpp_conn_t *const conn, _subscribe_handler(xmpp_stanza_t *const stanza)
xmpp_stanza_t *const stanza, void *const userdata)
{ {
log_debug("Presence stanza subscribe handler fired");
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
log_debug("Subscribe presence handler fired for %s", from); log_debug("Subscribe presence handler fired for %s", from);
Jid *from_jid = jid_create(from); Jid *from_jid = jid_create(from);
if (from_jid == NULL) { if (from_jid == NULL) {
return 1; return;
} }
sv_ev_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE); sv_ev_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE);
autocomplete_add(sub_requests_ac, from_jid->barejid); autocomplete_add(sub_requests_ac, from_jid->barejid);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1;
} }
static int static void
_unavailable_handler(xmpp_conn_t *const conn, _unavailable_handler(xmpp_stanza_t *const stanza)
xmpp_stanza_t *const stanza, void *const userdata)
{ {
log_debug("Presence stanza unavailale handler fired");
inp_nonblocking(TRUE); inp_nonblocking(TRUE);
xmpp_conn_t *conn = connection_get_conn();
const char *jid = xmpp_conn_get_jid(conn); const char *jid = xmpp_conn_get_jid(conn);
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
log_debug("Unavailable presence handler fired for %s", from); log_debug("Unavailable presence handler fired for %s", from);
@ -513,7 +520,7 @@ _unavailable_handler(xmpp_conn_t *const conn,
if (my_jid == NULL || from_jid == NULL) { if (my_jid == NULL || from_jid == NULL) {
jid_destroy(my_jid); jid_destroy(my_jid);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1; return;
} }
char *status_str = stanza_get_status(stanza, NULL); char *status_str = stanza_get_status(stanza, NULL);
@ -535,8 +542,6 @@ _unavailable_handler(xmpp_conn_t *const conn,
free(status_str); free(status_str);
jid_destroy(my_jid); jid_destroy(my_jid);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1;
} }
static void static void
@ -575,21 +580,14 @@ _handle_caps(char *jid, XMPPCaps *caps)
} }
} }
static int static void
_available_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _available_handler(xmpp_stanza_t *const stanza)
{ {
log_debug("Presence stanza available handler fired");
gboolean cont = _receive_presence_stanza(stanza);
if (!cont) {
return 1;
}
inp_nonblocking(TRUE); inp_nonblocking(TRUE);
// handler still fires if error // handler still fires if error
if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) { if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) {
return 1; return;
} }
// handler still fires if other types // handler still fires if other types
@ -597,12 +595,12 @@ _available_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
(g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBE) == 0) || (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBE) == 0) ||
(g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBED) == 0) || (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBED) == 0) ||
(g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNSUBSCRIBED) == 0)) { (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNSUBSCRIBED) == 0)) {
return 1; return;
} }
// handler still fires for muc presence // handler still fires for muc presence
if (stanza_is_muc_presence(stanza)) { if (stanza_is_muc_presence(stanza)) {
return 1; return;
} }
int err = 0; int err = 0;
@ -622,12 +620,13 @@ _available_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
log_warning("Available presence handler fired, could not parse stanza."); log_warning("Available presence handler fired, could not parse stanza.");
break; break;
} }
return 1; return;
} else { } else {
char *jid = jid_fulljid_or_barejid(xmpp_presence->jid); char *jid = jid_fulljid_or_barejid(xmpp_presence->jid);
log_debug("Presence available handler fired for: %s", jid); log_debug("Presence available handler fired for: %s", jid);
} }
xmpp_conn_t *conn = connection_get_conn();
const char *my_jid_str = xmpp_conn_get_jid(conn); const char *my_jid_str = xmpp_conn_get_jid(conn);
Jid *my_jid = jid_create(my_jid_str); Jid *my_jid = jid_create(my_jid_str);
@ -656,22 +655,19 @@ _available_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *c
jid_destroy(my_jid); jid_destroy(my_jid);
stanza_free_presence(xmpp_presence); stanza_free_presence(xmpp_presence);
return 1;
} }
void void
_send_caps_request(char *node, char *caps_key, char *id, char *from) _send_caps_request(char *node, char *caps_key, char *id, char *from)
{ {
xmpp_ctx_t *ctx = connection_get_ctx(); xmpp_ctx_t *ctx = connection_get_ctx();
xmpp_conn_t *conn = connection_get_conn();
if (node) { if (node) {
log_debug("Node string: %s.", node); log_debug("Node string: %s.", node);
if (!caps_contains(caps_key)) { if (!caps_contains(caps_key)) {
log_debug("Capabilities not cached for '%s', sending discovery IQ.", from); log_debug("Capabilities not cached for '%s', sending discovery IQ.", from);
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, from, node); xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, from, node);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} else { } else {
log_debug("Capabilities already cached, for %s", caps_key); log_debug("Capabilities already cached, for %s", caps_key);
@ -681,11 +677,9 @@ _send_caps_request(char *node, char *caps_key, char *id, char *from)
} }
} }
static int static void
_muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) _muc_user_handler(xmpp_stanza_t *const stanza)
{ {
log_debug("Presence stanza muc user handler fired");
inp_nonblocking(TRUE); inp_nonblocking(TRUE);
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
@ -693,14 +687,14 @@ _muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *co
// handler still fires if error // handler still fires if error
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
return 1; return;
} }
// invalid from attribute // invalid from attribute
Jid *from_jid = jid_create(from); Jid *from_jid = jid_create(from);
if (from_jid == NULL || from_jid->resourcepart == NULL) { if (from_jid == NULL || from_jid->resourcepart == NULL) {
jid_destroy(from_jid); jid_destroy(from_jid);
return 1; return;
} }
char *room = from_jid->barejid; char *room = from_jid->barejid;
@ -832,17 +826,16 @@ _muc_user_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *co
free(show_str); free(show_str);
free(status_str); free(status_str);
jid_destroy(from_jid); jid_destroy(from_jid);
return 1;
} }
static void static void
_send_presence_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza) _send_presence_stanza(xmpp_stanza_t *const stanza)
{ {
char *text; char *text;
size_t text_size; size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size); xmpp_stanza_to_text(stanza, &text, &text_size);
xmpp_conn_t *conn = connection_get_conn();
char *plugin_text = plugins_on_presence_stanza_send(text); char *plugin_text = plugins_on_presence_stanza_send(text);
if (plugin_text) { if (plugin_text) {
xmpp_send_raw_string(conn, "%s", plugin_text); xmpp_send_raw_string(conn, "%s", plugin_text);
@ -850,29 +843,3 @@ _send_presence_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
xmpp_send_raw_string(conn, "%s", text); xmpp_send_raw_string(conn, "%s", text);
} }
} }
static void
_send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
{
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
char *plugin_text = plugins_on_iq_stanza_send(text);
if (plugin_text) {
xmpp_send_raw_string(conn, "%s", plugin_text);
} else {
xmpp_send_raw_string(conn, "%s", text);
}
}
static gboolean
_receive_presence_stanza(xmpp_stanza_t *const stanza)
{
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
return plugins_on_presence_stanza_receive(text);
}

View File

@ -62,78 +62,56 @@
#include "xmpp/xmpp.h" #include "xmpp/xmpp.h"
#include "plugins/plugins.h" #include "plugins/plugins.h"
#define HANDLE(type, func) xmpp_handler_add(conn, func, XMPP_NS_ROSTER, STANZA_NAME_IQ, type, ctx)
// callback data for group commands // callback data for group commands
typedef struct _group_data { typedef struct _group_data {
char *name; char *name;
char *group; char *group;
} GroupData; } GroupData;
// event handlers
static int _roster_set_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
static int _roster_result_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
// id handlers // id handlers
static int _group_add_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static int _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
static int _group_remove_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static int _group_remove_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
static void _send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
// helper functions // helper functions
GSList* _get_groups_from_item(xmpp_stanza_t *item); GSList* _get_groups_from_item(xmpp_stanza_t *item);
void
roster_add_handlers(void)
{
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx();
HANDLE(STANZA_TYPE_SET, _roster_set_handler);
HANDLE(STANZA_TYPE_RESULT, _roster_result_handler);
}
void void
roster_request(void) roster_request(void)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *iq = stanza_create_roster_iq(ctx); xmpp_stanza_t *iq = stanza_create_roster_iq(ctx);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
void void
roster_send_add_new(const char *const barejid, const char *const name) roster_send_add_new(const char *const barejid, const char *const name)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *id = create_unique_id("roster"); char *id = create_unique_id("roster");
xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, name, NULL); xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, name, NULL);
free(id); free(id);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
void void
roster_send_remove(const char *const barejid) roster_send_remove(const char *const barejid)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_stanza_t *iq = stanza_create_roster_remove_set(ctx, barejid); xmpp_stanza_t *iq = stanza_create_roster_remove_set(ctx, barejid);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
void void
roster_send_name_change(const char *const barejid, const char *const new_name, GSList *groups) roster_send_name_change(const char *const barejid, const char *const new_name, GSList *groups)
{ {
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
char *id = create_unique_id("roster"); char *id = create_unique_id("roster");
xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, new_name, groups); xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, new_name, groups);
free(id); free(id);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
} }
@ -158,22 +136,18 @@ roster_send_add_to_group(const char *const group, PContact contact)
data->name = strdup(p_contact_barejid(contact)); data->name = strdup(p_contact_barejid(contact));
} }
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
xmpp_id_handler_add(conn, _group_add_id_handler, unique_id, data); id_handler_add(unique_id, _group_add_id_handler, data);
xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact), xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),
p_contact_name(contact), new_groups); p_contact_name(contact), new_groups);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
free(unique_id); free(unique_id);
} }
static int static int
_group_add_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
void *const userdata)
{ {
log_debug("iq stanza group add id handler fired");
if (userdata) { if (userdata) {
GroupData *data = userdata; GroupData *data = userdata;
ui_group_added(data->name, data->group); ui_group_added(data->name, data->group);
@ -196,7 +170,6 @@ roster_send_remove_from_group(const char *const group, PContact contact)
groups = g_slist_next(groups); groups = g_slist_next(groups);
} }
xmpp_conn_t * const conn = connection_get_conn();
xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_ctx_t * const ctx = connection_get_ctx();
// add an id handler to handle the response // add an id handler to handle the response
@ -209,20 +182,17 @@ roster_send_remove_from_group(const char *const group, PContact contact)
data->name = strdup(p_contact_barejid(contact)); data->name = strdup(p_contact_barejid(contact));
} }
xmpp_id_handler_add(conn, _group_remove_id_handler, unique_id, data); id_handler_add(unique_id, _group_remove_id_handler, data);
xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact), xmpp_stanza_t *iq = stanza_create_roster_set(ctx, unique_id, p_contact_barejid(contact),
p_contact_name(contact), new_groups); p_contact_name(contact), new_groups);
_send_iq_stanza(conn, iq); send_iq_stanza(iq);
xmpp_stanza_release(iq); xmpp_stanza_release(iq);
free(unique_id); free(unique_id);
} }
static int static int
_group_remove_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, _group_remove_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
void *const userdata)
{ {
log_debug("iq stanza group remove id handler fired");
if (userdata) { if (userdata) {
GroupData *data = userdata; GroupData *data = userdata;
ui_group_removed(data->name, data->group); ui_group_removed(data->name, data->group);
@ -233,19 +203,16 @@ _group_remove_id_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
return 0; return 0;
} }
static int void
_roster_set_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, roster_set_handler(xmpp_stanza_t *const stanza)
void *const userdata)
{ {
log_debug("iq stanza roster set handler fired");
xmpp_stanza_t *query = xmpp_stanza_t *query =
xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
xmpp_stanza_t *item = xmpp_stanza_t *item =
xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM); xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM);
if (item == NULL) { if (item == NULL) {
return 1; return;
} }
// if from attribute exists and it is not current users barejid, ignore push // if from attribute exists and it is not current users barejid, ignore push
@ -253,7 +220,7 @@ _roster_set_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
if (from && (strcmp(from, my_jid->barejid) != 0)) { if (from && (strcmp(from, my_jid->barejid) != 0)) {
jid_destroy(my_jid); jid_destroy(my_jid);
return 1; return;
} }
jid_destroy(my_jid); jid_destroy(my_jid);
@ -302,18 +269,16 @@ _roster_set_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
g_free(barejid_lower); g_free(barejid_lower);
return 1; return;
} }
static int void
_roster_result_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) roster_result_handler(xmpp_stanza_t *const stanza)
{ {
log_debug("iq stanza roster result handler fired");
const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
if (g_strcmp0(id, "roster") != 0) { if (g_strcmp0(id, "roster") != 0) {
return 1; return;
} }
// handle initial roster response // handle initial roster response
@ -348,7 +313,7 @@ _roster_result_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, voi
sv_ev_roster_received(); sv_ev_roster_received();
return 1; return;
} }
GSList* GSList*
@ -369,18 +334,3 @@ _get_groups_from_item(xmpp_stanza_t *item)
return groups; return groups;
} }
static void
_send_iq_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
{
char *text;
size_t text_size;
xmpp_stanza_to_text(stanza, &text, &text_size);
char *plugin_text = plugins_on_iq_stanza_send(text);
if (plugin_text) {
xmpp_send_raw_string(conn, "%s", plugin_text);
} else {
xmpp_send_raw_string(conn, "%s", text);
}
}