Changeset 3d31618 for protocols


Ignore:
Timestamp:
2015-05-28T04:10:55Z (4 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
a1d30c5, dd43c62
Parents:
24f113b
git-author:
dequis <dx@…> (24-07-14 10:41:47)
git-committer:
dequis <dx@…> (28-05-15 04:10:55)
Message:

jabber: Refactor conference message handling

  • Improve handling of "unknown 'from'"
  • Try a bit harder to detect the source of the message, and fall back to messages sent from a fake temporary user.
  • Fix receiving topic when it was set by someone who left the room.
  • Add jabber_get_bare_jid() utility function
Location:
protocols/jabber
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/conference.c

    r24f113b r3d31618  
    354354        struct xt_node *subject = xt_find_node(node->children, "subject");
    355355        struct xt_node *body = xt_find_node(node->children, "body");
    356         struct groupchat *chat = bud ? jabber_chat_by_jid(ic, bud->bare_jid) : NULL;
    357         struct jabber_chat *jc = chat ? chat->data : NULL;
    358         char *s;
     356        struct groupchat *chat = NULL;
     357        struct jabber_chat *jc = NULL;
     358        char *from = NULL;
     359        char *nick = NULL;
     360        char *final_from = NULL;
     361        char *bare_jid = NULL;
     362
     363        from = (bud) ? bud->full_jid : xt_find_attr(node, "from");
     364
     365        if (from) {
     366                nick = strchr(from, '/');
     367                if (nick) {
     368                        *nick = 0;
     369                }
     370                chat = jabber_chat_by_jid(ic, from);
     371                if (nick) {
     372                        *nick = '/';
     373                        nick++;
     374                }
     375        }
     376
     377        jc = (chat) ? chat->data : NULL;
     378
     379        if (!bud) {
     380                struct xt_node *c;
     381                char *s;
     382
     383                /* Try some clever stuff to find out the real JID here */
     384                c = xt_find_node_by_attr(node->children, "delay", "xmlns", XMLNS_DELAY);
     385
     386                if (c && ((s = xt_find_attr(c, "from")) ||
     387                          (s = xt_find_attr(c, "from_jid")))) {
     388                        /* This won't be useful if it's the MUC JID */
     389                        if (!(jc && jabber_compare_jid(s, jc->name))) {
     390                                /* Hopefully this one makes more sense! */
     391                                bud = jabber_buddy_by_jid(ic, s, GET_BUDDY_FIRST | GET_BUDDY_CREAT);
     392                        }
     393                }
     394
     395        }
    359396
    360397        if (subject && chat) {
    361                 s = (bud && bud->ext_jid) ? strchr(bud->ext_jid, '/') : NULL;
    362                 if (s) {
    363                         *s = 0;
    364                 }
    365                 imcb_chat_topic(chat, bud ? bud->ext_jid : NULL, subject->text_len > 0 ?
    366                                 subject->text : NULL, jabber_get_timestamp(node));
    367                 if (s) {
    368                         *s = '/';
    369                 }
    370         }
    371 
    372         if (bud == NULL || (jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me)) {
    373                 char *nick;
    374 
    375                 if (body == NULL || body->text_len == 0) {
    376                         /* Meh. Empty messages aren't very interesting, no matter
    377                            how much some servers love to send them. */
    378                         return;
    379                 }
    380 
    381                 s = xt_find_attr(node, "from");   /* pkt_message() already NULL-checked this one. */
    382                 nick = strchr(s, '/');
    383                 if (nick) {
    384                         /* If this message included a resource/nick we don't know,
    385                            we might still know the groupchat itself. */
    386                         *nick = 0;
    387                         chat = jabber_chat_by_jid(ic, s);
    388                         *nick = '/';
    389 
    390                         nick++;
     398                char *subject_text = subject->text_len > 0 ? subject->text : NULL;
     399                if (g_strcmp0(chat->topic, subject_text) != 0) {
     400                        bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL;
     401                        imcb_chat_topic(chat, bare_jid, subject_text,
     402                                        jabber_get_timestamp(node));
     403                        g_free(bare_jid);
     404                }
     405        }
     406
     407        if (body == NULL || body->text_len == 0) {
     408                /* Meh. Empty messages aren't very interesting, no matter
     409                   how much some servers love to send them. */
     410                return;
     411        }
     412
     413        if (chat == NULL) {
     414                if (nick == NULL) {
     415                        imcb_log(ic, "System message from unknown groupchat %s: %s", from, body->text);
    391416                } else {
    392                         /* message.c uses the EXACT_JID option, so bud should
    393                            always be NULL here for bare JIDs. */
    394                         chat = jabber_chat_by_jid(ic, s);
    395                 }
    396 
    397                 if (nick == NULL) {
    398                         /* This is fine, the groupchat itself isn't in jd->buddies. */
    399                         if (chat) {
    400                                 imcb_chat_log(chat, "From conference server: %s", body->text);
    401                         } else {
    402                                 imcb_log(ic, "System message from unknown groupchat %s: %s", s, body->text);
    403                         }
    404                 } else {
    405                         /* This can happen too, at least when receiving a backlog when
    406                            just joining a channel. */
    407                         if (chat) {
    408                                 imcb_chat_log(chat, "Message from unknown participant %s: %s", nick, body->text);
    409                         } else {
    410                                 imcb_log(ic, "Groupchat message from unknown JID %s: %s", s, body->text);
    411                         }
     417                        imcb_log(ic, "Groupchat message from unknown JID %s: %s", from, body->text);
    412418                }
    413419
    414420                return;
    415         } else if (chat == NULL) {
    416                 /* How could this happen?? We could do kill( self, 11 )
    417                    now or just wait for the OS to do it. :-) */
     421        } else if (chat != NULL && bud == NULL && nick == NULL) {
     422                imcb_chat_log(chat, "From conference server: %s", body->text);
    418423                return;
    419         }
    420         if (body && body->text_len > 0) {
    421                 s = (bud->ext_jid) ? strchr(bud->ext_jid, '/') : NULL;
    422                 if (s) {
    423                         *s = 0;
    424                 }
    425                 imcb_chat_msg(chat, bud->ext_jid, body->text, 0, jabber_get_timestamp(node));
    426                 if (s) {
    427                         *s = '/';
    428                 }
    429         }
    430 }
     424        } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me) {
     425                /* exclude self-messages since they would get filtered out
     426                 * but not the ones in the backlog */
     427                return;
     428        }
     429
     430        if (bud && jc && bud != jc->me) {
     431                bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid);
     432                final_from = bare_jid;
     433        } else {
     434                final_from = nick;
     435        }
     436
     437        imcb_chat_msg(chat, final_from, body->text, 0, jabber_get_timestamp(node));
     438
     439        g_free(bare_jid);
     440}
  • protocols/jabber/jabber.h

    r24f113b r3d31618  
    312312void jabber_error_free(struct jabber_error *err);
    313313gboolean jabber_set_me(struct im_connection *ic, const char *me);
     314char *jabber_get_bare_jid(char *jid);
    314315
    315316extern const struct jabber_away_state jabber_away_state_list[];
  • protocols/jabber/jabber_util.c

    r24f113b r3d31618  
    820820        return TRUE;
    821821}
     822
     823/* Returns new reference! g_free() afterwards. */
     824char *jabber_get_bare_jid(char *jid)
     825{
     826        char *s = NULL;
     827
     828        if (jid == NULL) {
     829                return NULL;
     830        }
     831
     832        if ((s = strchr(jid, '/'))) {
     833                return g_strndup(jid, s - jid);
     834        } else {
     835                return g_strdup(jid);
     836        }
     837}
Note: See TracChangeset for help on using the changeset viewer.