Ignore:
Timestamp:
2015-11-21T03:01:05Z (8 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
2f8e3ca
Parents:
8fdeaa5
git-author:
dequis <dx@…> (21-11-15 02:04:06)
git-committer:
dequis <dx@…> (21-11-15 03:01:05)
Message:

jabber: Implement carbons (XEP-0280)

"Message carbons" (XEP-0280) is a server feature to get copies of
outgoing messages sent from other clients connected to the same account.
It's not widely supported by most public XMPP servers (easier if you
host your own), but this will probably change in the next few years.

This is enabled by default if the server supports it. It can also be
disabled with the "carbons" account setting.

Loosely based on a patch by kormat from trac ticket 1021. (Thanks!)
I moved stuff around, simplified things, fixed a few bugs, and used the
new self-messages feature.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/message.c

    r8fdeaa5 rfa8f57b  
    2424#include "jabber.h"
    2525
    26 xt_status jabber_pkt_message(struct xt_node *node, gpointer data)
     26static xt_status jabber_pkt_message_normal(struct xt_node *node, gpointer data, gboolean carbons_sent)
    2727{
    2828        struct im_connection *ic = data;
    29         char *from = xt_find_attr(node, "from");
     29        char *from = xt_find_attr(node, carbons_sent ? "to" : "from");
    3030        char *type = xt_find_attr(node, "type");
    3131        char *id = xt_find_attr(node, "id");
     
    3939        }
    4040
    41         if (request && id && g_strcmp0(type, "groupchat") != 0) {
     41        if (request && id && g_strcmp0(type, "groupchat") != 0 && !carbons_sent) {
    4242                /* Send a message receipt (XEP-0184), looking like this:
    4343                 * <message from='...' id='...' to='...'>
     
    128128                if (fullmsg->len > 0) {
    129129                        imcb_buddy_msg(ic, from, fullmsg->str,
    130                                        0, jabber_get_timestamp(node));
     130                                       carbons_sent ? OPT_SELFMESSAGE : 0, jabber_get_timestamp(node));
    131131                }
    132132                if (room) {
     
    137137
    138138                /* Handling of incoming typing notifications. */
    139                 if (bud == NULL) {
    140                         /* Can't handle these for unknown buddies. */
     139                if (bud == NULL || carbons_sent) {
     140                        /* Can't handle these for unknown buddies.
     141                           And ignore them if it's just carbons */
    141142                } else if (xt_find_node(node->children, "composing")) {
    142143                        bud->flags |= JBFLAG_DOES_XEP85;
     
    162163        return XT_HANDLED;
    163164}
     165
     166static xt_status jabber_carbons_message(struct xt_node *node, gpointer data)
     167{
     168        struct im_connection *ic = data;
     169        struct xt_node *wrap, *fwd, *msg;
     170        gboolean carbons_sent;
     171
     172        if ((wrap = xt_find_node(node->children, "received"))) {
     173                carbons_sent = FALSE;
     174        } else if ((wrap = xt_find_node(node->children, "sent"))) {
     175                carbons_sent = TRUE;
     176        }
     177
     178        if (wrap == NULL || g_strcmp0(xt_find_attr(wrap, "xmlns"), XMLNS_CARBONS) != 0) {
     179                return XT_NEXT;
     180        }
     181
     182        if (!(fwd = xt_find_node(wrap->children, "forwarded")) ||
     183             (g_strcmp0(xt_find_attr(fwd, "xmlns"), XMLNS_FORWARDING) != 0) ||
     184            !(msg = xt_find_node(fwd->children, "message"))) {
     185                imcb_log(ic, "Error: Invalid carbons message received");
     186                return XT_ABORT;
     187        }
     188
     189        return jabber_pkt_message_normal(msg, data, carbons_sent);
     190}
     191
     192xt_status jabber_pkt_message(struct xt_node *node, gpointer data)
     193{
     194        struct im_connection *ic = data;
     195        struct jabber_data *jd = ic->proto_data;
     196        char *from = xt_find_attr(node, "from");
     197
     198        if (jabber_compare_jid(jd->me, from)) {    /* Probably a Carbons message */
     199                xt_status st = jabber_carbons_message(node, data);
     200                if (st == XT_HANDLED || st == XT_ABORT) {
     201                        return st;
     202                }
     203        }
     204        return jabber_pkt_message_normal(node, data, FALSE);
     205}
Note: See TracChangeset for help on using the changeset viewer.