mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Merge branch 'master' into osx-functional
This commit is contained in:
commit
9f14e2c0aa
@ -681,11 +681,33 @@ _handle_carbons(xmpp_stanza_t *const stanza)
|
||||
}
|
||||
|
||||
const char *name = xmpp_stanza_get_name(carbons);
|
||||
if ((g_strcmp0(name, "received") == 0) || (g_strcmp0(name, "sent")) == 0) {
|
||||
xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD);
|
||||
xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);
|
||||
if (!name) {
|
||||
log_error("Unable to retrieve stanza name for Carbon");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
if ((g_strcmp0(name, "received") != 0) && (g_strcmp0(name, "sent") != 0)) {
|
||||
log_warning("Carbon received with unrecognised stanza name: %s", name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD);
|
||||
if (!forwarded) {
|
||||
log_warning("Carbon received with no forwarded element");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);
|
||||
if (!message) {
|
||||
log_warning("Carbon received with no message element");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *message_txt = xmpp_message_get_body(message);
|
||||
if (!message_txt) {
|
||||
log_warning("Carbon received with no message.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const gchar *to = xmpp_stanza_get_to(message);
|
||||
const gchar *from = xmpp_stanza_get_from(message);
|
||||
@ -697,9 +719,6 @@ _handle_carbons(xmpp_stanza_t *const stanza)
|
||||
Jid *jid_to = jid_create(to);
|
||||
Jid *my_jid = jid_create(connection_get_fulljid());
|
||||
|
||||
// check for and deal with message
|
||||
char *message_txt = xmpp_message_get_body(message);
|
||||
if (message_txt) {
|
||||
// check for pgp encrypted message
|
||||
char *enc_message = NULL;
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(message, STANZA_NS_ENCRYPTED);
|
||||
@ -715,9 +734,10 @@ _handle_carbons(xmpp_stanza_t *const stanza)
|
||||
} else {
|
||||
sv_ev_outgoing_carbon(jid_to->barejid, message_txt, enc_message);
|
||||
}
|
||||
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
xmpp_free(ctx, message_txt);
|
||||
xmpp_free(ctx, enc_message);
|
||||
}
|
||||
|
||||
jid_destroy(jid_from);
|
||||
jid_destroy(jid_to);
|
||||
@ -726,9 +746,6 @@ _handle_carbons(xmpp_stanza_t *const stanza)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_chat(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
|
@ -78,7 +78,6 @@ static void _available_handler(xmpp_stanza_t *const stanza);
|
||||
|
||||
void _send_caps_request(char *node, char *caps_key, char *id, char *from);
|
||||
static void _send_room_presence(xmpp_stanza_t *presence);
|
||||
|
||||
static void _send_presence_stanza(xmpp_stanza_t *const stanza);
|
||||
|
||||
void
|
||||
@ -87,14 +86,283 @@ presence_sub_requests_init(void)
|
||||
sub_requests_ac = autocomplete_new();
|
||||
}
|
||||
|
||||
void
|
||||
presence_handlers_init(void)
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_handler_add(conn, _presence_handler, NULL, STANZA_NAME_PRESENCE, NULL, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
presence_subscription(const char *const jid, const jabber_subscr_t action)
|
||||
{
|
||||
assert(jid != NULL);
|
||||
|
||||
Jid *jidp = jid_create(jid);
|
||||
autocomplete_remove(sub_requests_ac, jidp->barejid);
|
||||
|
||||
const char *type = NULL;
|
||||
switch (action)
|
||||
{
|
||||
case PRESENCE_SUBSCRIBE:
|
||||
log_debug("Sending presence subscribe: %s", jid);
|
||||
type = STANZA_TYPE_SUBSCRIBE;
|
||||
break;
|
||||
case PRESENCE_SUBSCRIBED:
|
||||
log_debug("Sending presence subscribed: %s", jid);
|
||||
type = STANZA_TYPE_SUBSCRIBED;
|
||||
break;
|
||||
case PRESENCE_UNSUBSCRIBED:
|
||||
log_debug("Sending presence usubscribed: %s", jid);
|
||||
type = STANZA_TYPE_UNSUBSCRIBED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!type) {
|
||||
log_error("Attempt to send unknown subscription action: %s", jid);
|
||||
return;
|
||||
}
|
||||
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *presence = xmpp_presence_new(ctx);
|
||||
|
||||
char *id = create_unique_id("sub");
|
||||
xmpp_stanza_set_id(presence, id);
|
||||
free(id);
|
||||
|
||||
xmpp_stanza_set_type(presence, type);
|
||||
xmpp_stanza_set_to(presence, jidp->barejid);
|
||||
jid_destroy(jidp);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
|
||||
xmpp_stanza_release(presence);
|
||||
}
|
||||
|
||||
GSList*
|
||||
presence_get_subscription_requests(void)
|
||||
{
|
||||
return autocomplete_create_list(sub_requests_ac);
|
||||
}
|
||||
|
||||
gint
|
||||
presence_sub_request_count(void)
|
||||
{
|
||||
return autocomplete_length(sub_requests_ac);
|
||||
}
|
||||
|
||||
void
|
||||
presence_clear_sub_requests(void)
|
||||
{
|
||||
autocomplete_clear(sub_requests_ac);
|
||||
}
|
||||
|
||||
char*
|
||||
presence_sub_request_find(const char *const search_str)
|
||||
{
|
||||
return autocomplete_complete(sub_requests_ac, search_str, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
presence_sub_request_exists(const char *const bare_jid)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
GSList *requests = autocomplete_create_list(sub_requests_ac);
|
||||
GSList *curr = requests;
|
||||
while (curr) {
|
||||
if (strcmp(curr->data, bare_jid) == 0) {
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
curr = g_slist_next(curr);
|
||||
}
|
||||
g_slist_free_full(requests, free);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
presence_reset_sub_request_search(void)
|
||||
{
|
||||
autocomplete_reset(sub_requests_ac);
|
||||
}
|
||||
|
||||
void
|
||||
presence_send(const resource_presence_t presence_type, const char *const msg, const int idle, char *signed_status)
|
||||
{
|
||||
if (connection_get_status() != JABBER_CONNECTED) {
|
||||
log_warning("Error setting presence, not connected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
log_debug("Updating presence: %s, \"%s\"", string_from_resource_presence(presence_type), msg);
|
||||
} else {
|
||||
log_debug("Updating presence: %s", string_from_resource_presence(presence_type));
|
||||
}
|
||||
|
||||
connection_set_presence_msg(msg);
|
||||
|
||||
const int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
|
||||
connection_set_priority(pri);
|
||||
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *presence = xmpp_presence_new(ctx);
|
||||
|
||||
char *id = create_unique_id("presence");
|
||||
xmpp_stanza_set_id(presence, id);
|
||||
free(id);
|
||||
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
|
||||
stanza_attach_status(ctx, presence, msg);
|
||||
|
||||
if (signed_status) {
|
||||
xmpp_stanza_t *x = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(x, STANZA_NAME_X);
|
||||
xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);
|
||||
|
||||
xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_text(signed_text, signed_status);
|
||||
|
||||
xmpp_stanza_add_child(x, signed_text);
|
||||
xmpp_stanza_release(signed_text);
|
||||
|
||||
xmpp_stanza_add_child(presence, x);
|
||||
xmpp_stanza_release(x);
|
||||
}
|
||||
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
|
||||
if (idle > 0) {
|
||||
stanza_attach_last_activity(ctx, presence, idle);
|
||||
}
|
||||
|
||||
stanza_attach_caps(ctx, presence);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
_send_room_presence(presence);
|
||||
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
// set last presence for account
|
||||
const char *last = show;
|
||||
if (last == NULL) {
|
||||
last = STANZA_TEXT_ONLINE;
|
||||
}
|
||||
|
||||
char *account = session_get_account_name();
|
||||
accounts_set_last_presence(account, last);
|
||||
accounts_set_last_status(account, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_room_presence(xmpp_stanza_t *presence)
|
||||
{
|
||||
GList *rooms = muc_rooms();
|
||||
GList *curr = rooms;
|
||||
while (curr) {
|
||||
const char *room = curr->data;
|
||||
const char *nick = muc_nick(room);
|
||||
|
||||
if (nick) {
|
||||
char *full_room_jid = create_fulljid(room, nick);
|
||||
xmpp_stanza_set_to(presence, full_room_jid);
|
||||
log_debug("Sending presence to room: %s", full_room_jid);
|
||||
free(full_room_jid);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
}
|
||||
|
||||
curr = g_list_next(curr);
|
||||
}
|
||||
g_list_free(rooms);
|
||||
}
|
||||
|
||||
void
|
||||
presence_join_room(const char *const room, const char *const nick, const char *const passwd)
|
||||
{
|
||||
Jid *jid = jid_create_from_bare_and_resource(room, nick);
|
||||
log_debug("Sending room join presence to: %s", jid->fulljid);
|
||||
|
||||
resource_presence_t presence_type = accounts_get_last_presence(session_get_account_name());
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
char *status = connection_get_presence_msg();
|
||||
int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
|
||||
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *presence = stanza_create_room_join_presence(ctx, jid->fulljid, passwd);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
stanza_attach_status(ctx, presence, status);
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
stanza_attach_caps(ctx, presence);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
|
||||
xmpp_stanza_release(presence);
|
||||
jid_destroy(jid);
|
||||
}
|
||||
|
||||
void
|
||||
presence_change_room_nick(const char *const room, const char *const nick)
|
||||
{
|
||||
assert(room != NULL);
|
||||
assert(nick != NULL);
|
||||
|
||||
log_debug("Sending room nickname change to: %s, nick: %s", room, nick);
|
||||
resource_presence_t presence_type = accounts_get_last_presence(session_get_account_name());
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
char *status = connection_get_presence_msg();
|
||||
int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
|
||||
char *full_room_jid = create_fulljid(room, nick);
|
||||
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *presence = stanza_create_room_newnick_presence(ctx, full_room_jid);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
stanza_attach_status(ctx, presence, status);
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
stanza_attach_caps(ctx, presence);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
|
||||
xmpp_stanza_release(presence);
|
||||
free(full_room_jid);
|
||||
}
|
||||
|
||||
void
|
||||
presence_leave_chat_room(const char *const room_jid)
|
||||
{
|
||||
assert(room_jid != NULL);
|
||||
|
||||
char *nick = muc_nick(room_jid);
|
||||
if (!nick) {
|
||||
log_error("Could not get nickname for room: %s", room_jid);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("Sending room leave presence to: %s", room_jid);
|
||||
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, nick);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
|
||||
xmpp_stanza_release(presence);
|
||||
}
|
||||
|
||||
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;
|
||||
char *text = NULL;
|
||||
size_t text_size;
|
||||
xmpp_stanza_to_text(stanza, &text, &text_size);
|
||||
|
||||
gboolean cont = plugins_on_presence_stanza_receive(text);
|
||||
xmpp_free(connection_get_ctx(), text);
|
||||
if (!cont) {
|
||||
@ -133,285 +401,20 @@ _presence_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *co
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
presence_handlers_init(void)
|
||||
{
|
||||
xmpp_conn_t * const conn = connection_get_conn();
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_handler_add(conn, _presence_handler, NULL, STANZA_NAME_PRESENCE, NULL, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
presence_subscription(const char *const jid, const jabber_subscr_t action)
|
||||
{
|
||||
assert(jid != NULL);
|
||||
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
const char *type = NULL;
|
||||
|
||||
Jid *jidp = jid_create(jid);
|
||||
|
||||
autocomplete_remove(sub_requests_ac, jidp->barejid);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case PRESENCE_SUBSCRIBE:
|
||||
log_debug("Sending presence subscribe: %s", jid);
|
||||
type = STANZA_TYPE_SUBSCRIBE;
|
||||
break;
|
||||
case PRESENCE_SUBSCRIBED:
|
||||
log_debug("Sending presence subscribed: %s", jid);
|
||||
type = STANZA_TYPE_SUBSCRIBED;
|
||||
break;
|
||||
case PRESENCE_UNSUBSCRIBED:
|
||||
log_debug("Sending presence usubscribed: %s", jid);
|
||||
type = STANZA_TYPE_UNSUBSCRIBED;
|
||||
break;
|
||||
default:
|
||||
log_warning("Attempt to send unknown subscription action: %s", jid);
|
||||
break;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *presence = xmpp_presence_new(ctx);
|
||||
char *id = create_unique_id("sub");
|
||||
xmpp_stanza_set_id(presence, id);
|
||||
xmpp_stanza_set_type(presence, type);
|
||||
xmpp_stanza_set_to(presence, jidp->barejid);
|
||||
_send_presence_stanza(presence);
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
jid_destroy(jidp);
|
||||
free(id);
|
||||
}
|
||||
|
||||
GSList*
|
||||
presence_get_subscription_requests(void)
|
||||
{
|
||||
return autocomplete_create_list(sub_requests_ac);
|
||||
}
|
||||
|
||||
gint
|
||||
presence_sub_request_count(void)
|
||||
{
|
||||
return autocomplete_length(sub_requests_ac);
|
||||
}
|
||||
|
||||
void
|
||||
presence_clear_sub_requests(void)
|
||||
{
|
||||
autocomplete_clear(sub_requests_ac);
|
||||
}
|
||||
|
||||
char*
|
||||
presence_sub_request_find(const char *const search_str)
|
||||
{
|
||||
return autocomplete_complete(sub_requests_ac, search_str, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
presence_sub_request_exists(const char *const bare_jid)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GSList *requests_p = autocomplete_create_list(sub_requests_ac);
|
||||
GSList *requests = requests_p;
|
||||
|
||||
while (requests) {
|
||||
if (strcmp(requests->data, bare_jid) == 0) {
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
requests = g_slist_next(requests);
|
||||
}
|
||||
|
||||
if (requests_p) {
|
||||
g_slist_free_full(requests_p, free);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
presence_reset_sub_request_search(void)
|
||||
{
|
||||
autocomplete_reset(sub_requests_ac);
|
||||
}
|
||||
|
||||
void
|
||||
presence_send(const resource_presence_t presence_type, const char *const msg, const int idle, char *signed_status)
|
||||
{
|
||||
if (connection_get_status() != JABBER_CONNECTED) {
|
||||
log_warning("Error setting presence, not connected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
log_debug("Updating presence: %s, \"%s\"", string_from_resource_presence(presence_type), msg);
|
||||
} else {
|
||||
log_debug("Updating presence: %s", string_from_resource_presence(presence_type));
|
||||
}
|
||||
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
const int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
|
||||
connection_set_presence_msg(msg);
|
||||
connection_set_priority(pri);
|
||||
|
||||
xmpp_stanza_t *presence = xmpp_presence_new(ctx);
|
||||
char *id = create_unique_id("presence");
|
||||
xmpp_stanza_set_id(presence, id);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
|
||||
stanza_attach_status(ctx, presence, msg);
|
||||
|
||||
if (signed_status) {
|
||||
xmpp_stanza_t *x = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(x, STANZA_NAME_X);
|
||||
xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);
|
||||
xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_text(signed_text, signed_status);
|
||||
xmpp_stanza_add_child(x, signed_text);
|
||||
xmpp_stanza_release(signed_text);
|
||||
xmpp_stanza_add_child(presence, x);
|
||||
xmpp_stanza_release(x);
|
||||
}
|
||||
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
if (idle > 0) {
|
||||
stanza_attach_last_activity(ctx, presence, idle);
|
||||
}
|
||||
stanza_attach_caps(ctx, presence);
|
||||
_send_presence_stanza(presence);
|
||||
_send_room_presence(presence);
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
// set last presence for account
|
||||
const char *last = show;
|
||||
if (last == NULL) {
|
||||
last = STANZA_TEXT_ONLINE;
|
||||
}
|
||||
char *account = session_get_account_name();
|
||||
accounts_set_last_presence(account, last);
|
||||
accounts_set_last_status(account, msg);
|
||||
free(id);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_room_presence(xmpp_stanza_t *presence)
|
||||
{
|
||||
GList *rooms = muc_rooms();
|
||||
GList *curr = rooms;
|
||||
|
||||
while (curr) {
|
||||
const char *room = curr->data;
|
||||
const char *nick = muc_nick(room);
|
||||
|
||||
if (nick) {
|
||||
char *full_room_jid = create_fulljid(room, nick);
|
||||
|
||||
xmpp_stanza_set_to(presence, full_room_jid);
|
||||
log_debug("Sending presence to room: %s", full_room_jid);
|
||||
_send_presence_stanza(presence);
|
||||
free(full_room_jid);
|
||||
}
|
||||
|
||||
curr = g_list_next(curr);
|
||||
}
|
||||
|
||||
g_list_free(rooms);
|
||||
}
|
||||
|
||||
void
|
||||
presence_join_room(const char *const room, const char *const nick, const char *const passwd)
|
||||
{
|
||||
Jid *jid = jid_create_from_bare_and_resource(room, nick);
|
||||
|
||||
log_debug("Sending room join presence to: %s", jid->fulljid);
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
resource_presence_t presence_type =
|
||||
accounts_get_last_presence(session_get_account_name());
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
char *status = connection_get_presence_msg();
|
||||
int pri = accounts_get_priority_for_presence_type(session_get_account_name(),
|
||||
presence_type);
|
||||
|
||||
xmpp_stanza_t *presence = stanza_create_room_join_presence(ctx, jid->fulljid, passwd);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
stanza_attach_status(ctx, presence, status);
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
stanza_attach_caps(ctx, presence);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
jid_destroy(jid);
|
||||
}
|
||||
|
||||
void
|
||||
presence_change_room_nick(const char *const room, const char *const nick)
|
||||
{
|
||||
assert(room != NULL);
|
||||
assert(nick != NULL);
|
||||
|
||||
log_debug("Sending room nickname change to: %s, nick: %s", room, nick);
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
resource_presence_t presence_type =
|
||||
accounts_get_last_presence(session_get_account_name());
|
||||
const char *show = stanza_get_presence_string_from_type(presence_type);
|
||||
char *status = connection_get_presence_msg();
|
||||
int pri = accounts_get_priority_for_presence_type(session_get_account_name(),
|
||||
presence_type);
|
||||
|
||||
char *full_room_jid = create_fulljid(room, nick);
|
||||
xmpp_stanza_t *presence =
|
||||
stanza_create_room_newnick_presence(ctx, full_room_jid);
|
||||
stanza_attach_show(ctx, presence, show);
|
||||
stanza_attach_status(ctx, presence, status);
|
||||
stanza_attach_priority(ctx, presence, pri);
|
||||
stanza_attach_caps(ctx, presence);
|
||||
|
||||
_send_presence_stanza(presence);
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
free(full_room_jid);
|
||||
}
|
||||
|
||||
void
|
||||
presence_leave_chat_room(const char *const room_jid)
|
||||
{
|
||||
assert(room_jid != NULL);
|
||||
|
||||
log_debug("Sending room leave presence to: %s", room_jid);
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
char *nick = muc_nick(room_jid);
|
||||
|
||||
if (nick) {
|
||||
xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, nick);
|
||||
_send_presence_stanza(presence);
|
||||
xmpp_stanza_release(presence);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_presence_error_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
const char *id = xmpp_stanza_get_id(stanza);
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
|
||||
const char *xmlns = NULL;
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
|
||||
if (x) {
|
||||
xmlns = xmpp_stanza_get_ns(x);
|
||||
}
|
||||
const char *type = NULL;
|
||||
if (error_stanza) {
|
||||
type = xmpp_stanza_get_type(error_stanza);
|
||||
}
|
||||
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
|
||||
|
||||
// handle MUC join errors
|
||||
if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
|
||||
Jid *fulljid = jid_create(from);
|
||||
|
||||
const char *error_cond = NULL;
|
||||
xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
|
||||
if (reason_st) {
|
||||
@ -421,19 +424,19 @@ _presence_error_handler(xmpp_stanza_t *const stanza)
|
||||
error_cond = "unknown";
|
||||
}
|
||||
|
||||
Jid *fulljid = jid_create(from);
|
||||
log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
|
||||
if (muc_active(fulljid->barejid)) {
|
||||
muc_leave(fulljid->barejid);
|
||||
}
|
||||
cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond);
|
||||
jid_destroy(fulljid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// stanza_get_error never returns NULL
|
||||
char *err_msg = stanza_get_error_message(stanza);
|
||||
|
||||
GString *log_msg = g_string_new("presence stanza error received");
|
||||
const char *id = xmpp_stanza_get_id(stanza);
|
||||
if (id) {
|
||||
g_string_append(log_msg, " id=");
|
||||
g_string_append(log_msg, id);
|
||||
@ -442,10 +445,18 @@ _presence_error_handler(xmpp_stanza_t *const stanza)
|
||||
g_string_append(log_msg, " from=");
|
||||
g_string_append(log_msg, from);
|
||||
}
|
||||
|
||||
const char *type = NULL;
|
||||
if (error_stanza) {
|
||||
type = xmpp_stanza_get_type(error_stanza);
|
||||
}
|
||||
if (type) {
|
||||
g_string_append(log_msg, " type=");
|
||||
g_string_append(log_msg, type);
|
||||
}
|
||||
|
||||
// stanza_get_error never returns NULL
|
||||
char *err_msg = stanza_get_error_message(stanza);
|
||||
g_string_append(log_msg, " error=");
|
||||
g_string_append(log_msg, err_msg);
|
||||
|
||||
@ -462,14 +473,17 @@ _presence_error_handler(xmpp_stanza_t *const stanza)
|
||||
free(err_msg);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_unsubscribed_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
Jid *from_jid = jid_create(from);
|
||||
if (!from) {
|
||||
log_warning("Unsubscribed presence handler received with no from attribute");
|
||||
return;
|
||||
}
|
||||
log_debug("Unsubscribed presence handler fired for %s", from);
|
||||
|
||||
Jid *from_jid = jid_create(from);
|
||||
sv_ev_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED);
|
||||
autocomplete_remove(sub_requests_ac, from_jid->barejid);
|
||||
|
||||
@ -480,9 +494,13 @@ static void
|
||||
_subscribed_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
Jid *from_jid = jid_create(from);
|
||||
if (!from) {
|
||||
log_warning("Subscribed presence handler received with no from attribute");
|
||||
return;
|
||||
}
|
||||
log_debug("Subscribed presence handler fired for %s", from);
|
||||
|
||||
Jid *from_jid = jid_create(from);
|
||||
sv_ev_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED);
|
||||
autocomplete_remove(sub_requests_ac, from_jid->barejid);
|
||||
|
||||
@ -493,6 +511,9 @@ static void
|
||||
_subscribe_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
if (!from) {
|
||||
log_warning("Subscribe presence handler received with no from attribute", from);
|
||||
}
|
||||
log_debug("Subscribe presence handler fired for %s", from);
|
||||
|
||||
Jid *from_jid = jid_create(from);
|
||||
@ -514,6 +535,9 @@ _unavailable_handler(xmpp_stanza_t *const stanza)
|
||||
xmpp_conn_t *conn = connection_get_conn();
|
||||
const char *jid = xmpp_conn_get_jid(conn);
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
if (!from) {
|
||||
log_warning("Unavailable presence received with no from attribute");
|
||||
}
|
||||
log_debug("Unavailable presence handler fired for %s", from);
|
||||
|
||||
Jid *my_jid = jid_create(jid);
|
||||
@ -524,9 +548,8 @@ _unavailable_handler(xmpp_stanza_t *const stanza)
|
||||
return;
|
||||
}
|
||||
|
||||
char *status_str = stanza_get_status(stanza, NULL);
|
||||
|
||||
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
||||
char *status_str = stanza_get_status(stanza, NULL);
|
||||
if (from_jid->resourcepart) {
|
||||
sv_ev_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str);
|
||||
|
||||
@ -534,13 +557,13 @@ _unavailable_handler(xmpp_stanza_t *const stanza)
|
||||
} else {
|
||||
sv_ev_contact_offline(from_jid->barejid, "__prof_default", status_str);
|
||||
}
|
||||
free(status_str);
|
||||
} else {
|
||||
if (from_jid->resourcepart) {
|
||||
connection_remove_available_resource(from_jid->resourcepart);
|
||||
}
|
||||
}
|
||||
|
||||
free(status_str);
|
||||
jid_destroy(my_jid);
|
||||
jid_destroy(from_jid);
|
||||
}
|
||||
@ -661,74 +684,45 @@ _available_handler(xmpp_stanza_t *const stanza)
|
||||
void
|
||||
_send_caps_request(char *node, char *caps_key, char *id, char *from)
|
||||
{
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
|
||||
if (node) {
|
||||
log_debug("Node string: %s.", node);
|
||||
if (!caps_cache_contains(caps_key)) {
|
||||
log_debug("Capabilities not cached for '%s', sending discovery IQ.", from);
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, from, node);
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
} else {
|
||||
log_debug("Capabilities already cached, for %s", caps_key);
|
||||
}
|
||||
} else {
|
||||
if (!node) {
|
||||
log_debug("No node string, not sending discovery IQ.");
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("Node string: %s.", node);
|
||||
if (caps_cache_contains(caps_key)) {
|
||||
log_debug("Capabilities already cached, for %s", caps_key);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("Capabilities not cached for '%s', sending discovery IQ.", from);
|
||||
xmpp_ctx_t *ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, from, node);
|
||||
|
||||
iq_send_stanza(iq);
|
||||
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
|
||||
static void
|
||||
_muc_user_handler(xmpp_stanza_t *const stanza)
|
||||
_muc_user_self_handler(xmpp_stanza_t *stanza)
|
||||
{
|
||||
inp_nonblocking(TRUE);
|
||||
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
|
||||
// handler still fires if error
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// invalid from attribute
|
||||
Jid *from_jid = jid_create(from);
|
||||
if (from_jid == NULL || from_jid->resourcepart == NULL) {
|
||||
jid_destroy(from_jid);
|
||||
return;
|
||||
}
|
||||
|
||||
char *room = from_jid->barejid;
|
||||
char *nick = from_jid->resourcepart;
|
||||
|
||||
char *show_str = stanza_get_show(stanza, "online");
|
||||
char *status_str = stanza_get_status(stanza, NULL);
|
||||
|
||||
const char *jid = NULL;
|
||||
const char *role = NULL;
|
||||
const char *affiliation = NULL;
|
||||
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
|
||||
if (x) {
|
||||
xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM);
|
||||
if (item) {
|
||||
jid = xmpp_stanza_get_attribute(item, "jid");
|
||||
role = xmpp_stanza_get_attribute(item, "role");
|
||||
affiliation = xmpp_stanza_get_attribute(item, "affiliation");
|
||||
}
|
||||
}
|
||||
|
||||
// handle self presence
|
||||
if (stanza_is_muc_self_presence(stanza, connection_get_fulljid())) {
|
||||
log_debug("Room self presence received from %s", from_jid->fulljid);
|
||||
|
||||
// self unavailable
|
||||
char *room = from_jid->barejid;
|
||||
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
if (g_strcmp0(type, STANZA_TYPE_UNAVAILABLE) == 0) {
|
||||
|
||||
// handle nickname change
|
||||
const char *new_nick = stanza_get_new_nick(stanza);
|
||||
if (new_nick) {
|
||||
muc_nick_change_start(room, new_nick);
|
||||
|
||||
// handle left room
|
||||
} else {
|
||||
GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER);
|
||||
|
||||
@ -762,20 +756,45 @@ _muc_user_handler(xmpp_stanza_t *const stanza)
|
||||
|
||||
g_slist_free_full(status_codes, free);
|
||||
}
|
||||
|
||||
// self online
|
||||
} else {
|
||||
gboolean config_required = stanza_muc_requires_config(stanza);
|
||||
const char *actor = stanza_get_actor(stanza);
|
||||
char *reason = stanza_get_reason(stanza);
|
||||
char *nick = from_jid->resourcepart;
|
||||
char *show_str = stanza_get_show(stanza, "online");
|
||||
char *status_str = stanza_get_status(stanza, NULL);
|
||||
const char *jid = NULL;
|
||||
const char *role = NULL;
|
||||
const char *affiliation = NULL;
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
|
||||
if (x) {
|
||||
xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM);
|
||||
if (item) {
|
||||
jid = xmpp_stanza_get_attribute(item, "jid");
|
||||
role = xmpp_stanza_get_attribute(item, "role");
|
||||
affiliation = xmpp_stanza_get_attribute(item, "affiliation");
|
||||
}
|
||||
}
|
||||
sv_ev_muc_self_online(room, nick, config_required, role, affiliation, actor, reason, jid, show_str, status_str);
|
||||
free(show_str);
|
||||
free(status_str);
|
||||
free(reason);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_muc_user_occupant_handler(xmpp_stanza_t *stanza)
|
||||
{
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
Jid *from_jid = jid_create(from);
|
||||
|
||||
// handle presence from room members
|
||||
} else {
|
||||
log_debug("Room presence received from %s", from_jid->fulljid);
|
||||
|
||||
char *room = from_jid->barejid;
|
||||
char *nick = from_jid->resourcepart;
|
||||
char *status_str = stanza_get_status(stanza, NULL);
|
||||
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
if (g_strcmp0(type, STANZA_TYPE_UNAVAILABLE) == 0) {
|
||||
|
||||
// handle nickname change
|
||||
@ -820,15 +839,58 @@ _muc_user_handler(xmpp_stanza_t *const stanza)
|
||||
stanza_free_caps(caps);
|
||||
|
||||
const char *actor = stanza_get_actor(stanza);
|
||||
char *show_str = stanza_get_show(stanza, "online");
|
||||
char *reason = stanza_get_reason(stanza);
|
||||
const char *jid = NULL;
|
||||
const char *role = NULL;
|
||||
const char *affiliation = NULL;
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
|
||||
if (x) {
|
||||
xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM);
|
||||
if (item) {
|
||||
jid = xmpp_stanza_get_attribute(item, "jid");
|
||||
role = xmpp_stanza_get_attribute(item, "role");
|
||||
affiliation = xmpp_stanza_get_attribute(item, "affiliation");
|
||||
}
|
||||
}
|
||||
sv_ev_muc_occupant_online(room, nick, jid, role, affiliation, actor, reason, show_str, status_str);
|
||||
free(show_str);
|
||||
free(reason);
|
||||
}
|
||||
|
||||
free(status_str);
|
||||
}
|
||||
|
||||
free(show_str);
|
||||
free(status_str);
|
||||
static void
|
||||
_muc_user_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
inp_nonblocking(TRUE);
|
||||
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
// handler still fires if error
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
if (!from) {
|
||||
log_warning("MUC User stanza received with no from attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
Jid *from_jid = jid_create(from);
|
||||
if (from_jid == NULL || from_jid->resourcepart == NULL) {
|
||||
log_warning("MUC User stanza received with invalid from attribute: %s", from);
|
||||
jid_destroy(from_jid);
|
||||
return;
|
||||
}
|
||||
jid_destroy(from_jid);
|
||||
|
||||
if (stanza_is_muc_self_presence(stanza, connection_get_fulljid())) {
|
||||
_muc_user_self_handler(stanza);
|
||||
} else {
|
||||
_muc_user_occupant_handler(stanza);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user