Skip to content

Commit

Permalink
Implement XEP-0280: Message Carbons
Browse files Browse the repository at this point in the history
  • Loading branch information
singpolyma committed Nov 18, 2015
1 parent 11d7a90 commit 563b255
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/core/Makefile
Expand Up @@ -12,6 +12,7 @@ SRCS= xmpp-commands.c \
stanzas.c \
tools.c \
popenRWE.c \
xep/carbons.c \
xep/chatstates.c \
xep/composing.c \
xep/datetime.c \
Expand Down
122 changes: 122 additions & 0 deletions src/core/xep/carbons.c
@@ -0,0 +1,122 @@
/*
* XEP-0280: Message Carbons
*/

#include "module.h"
#include "misc.h"
#include "settings.h"
#include "signals.h"

#include "rosters-tools.h"
#include "xmpp-servers.h"
#include "disco.h"
#include "tools.h"
#include "muc.h"

#define XMLNS_CARBONS "urn:xmpp:carbons:2"

static void
sig_server_features(XMPP_SERVER_REC *server)
{
if (disco_have_feature(server->server_features, XMLNS_CARBONS)) {
LmMessage *lmsg;
LmMessageNode *node;

lmsg = lm_message_new_with_sub_type(NULL,
LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET);
node = lm_message_node_add_child(lmsg->node, "enable", NULL);
lm_message_node_set_attribute(node, XMLNS, XMLNS_CARBONS);
signal_emit("xmpp send iq", 2, server, lmsg);
lm_message_unref(lmsg);
}
}

static void
sig_recv_message(XMPP_SERVER_REC *server, LmMessage *lmsg, const int type,
const char *id, const char *from, const char *to)
{
LmMessageNode *node = NULL;
LmMessageNode *forwarded = NULL;
LmMessageNode *message = NULL;
char *ffrom, *fto;

node = lm_find_node(lmsg->node, "received", "xmlns", XMLNS_CARBONS);
if(node) {
forwarded = lm_find_node(node, "forwarded", "xmlns", "urn:xmpp:forward:0");
if(forwarded) message = lm_find_node(forwarded, "message", "xmlns", "jabber:client");
if(message) {
ffrom = xmpp_recode_in(lm_message_node_get_attribute(message, "from"));
if (from == NULL)
from = g_strdup("");
fto = xmpp_recode_in(lm_message_node_get_attribute(message, "to"));
if (to == NULL)
to = g_strdup("");

node = lmsg->node;
lmsg->node = message;
signal_emit("xmpp recv message", 6, server, lmsg, type, id, ffrom, fto);
lmsg->node = node;
goto done;
}
}

node = lm_find_node(lmsg->node, "sent", "xmlns", XMLNS_CARBONS);
if(!node) return; // Not for us

forwarded = lm_find_node(node, "forwarded", "xmlns", "urn:xmpp:forward:0");
if(forwarded) message = lm_find_node(forwarded, "message", "xmlns", "jabber:client");
if(message) {
MUC_REC *channel;
char *nick, *str;
node = lm_message_node_get_child(message, "body");
if(node == NULL || node->value == NULL || *node->value == '\0') return;
str = xmpp_recode_in(node->value);

ffrom = xmpp_recode_in(lm_message_node_get_attribute(message, "from"));
if (from == NULL)
from = g_strdup("");
fto = xmpp_recode_in(lm_message_node_get_attribute(message, "to"));
if (to == NULL)
to = g_strdup("");

nick = rosters_resolve_name(server, fto);
if(nick) fto = nick;

if (type == LM_MESSAGE_SUB_TYPE_GROUPCHAT
&& (channel = get_muc(server, fto)) != NULL
&& (nick = muc_extract_nick(ffrom)) != NULL) {
signal_emit("message xmpp carbons sent", 6, server,
str, nick, channel->name,
GINT_TO_POINTER(SEND_TARGET_CHANNEL));
g_free(nick);
} else if ((type == LM_MESSAGE_SUB_TYPE_NOT_SET
|| type == LM_MESSAGE_SUB_TYPE_HEADLINE
|| type == LM_MESSAGE_SUB_TYPE_NORMAL
|| type == LM_MESSAGE_SUB_TYPE_CHAT)) {
signal_emit("message xmpp carbons sent", 6, server,
str, ffrom, fto,
GINT_TO_POINTER(SEND_TARGET_NICK));
}

g_free(str);
}

done:
g_free(fto);
g_free(ffrom);
signal_stop();
}

void
carbons_init(void)
{
signal_add("xmpp server features", sig_server_features);
signal_add_first("xmpp recv message", sig_recv_message);
}

void
carbons_deinit(void)
{
signal_remove("xmpp server features", sig_server_features);
signal_remove("xmpp recv message", sig_recv_message);
}
9 changes: 9 additions & 0 deletions src/core/xep/carbons.h
@@ -0,0 +1,9 @@
#ifndef __CARBONS_H
#define __CARBONS_H

__BEGIN_DECLS
void carbons_init(void);
void carbons_deinit(void);
__END_DECLS

#endif
3 changes: 3 additions & 0 deletions src/core/xep/xep.c
Expand Up @@ -17,6 +17,7 @@

#include "module.h"

#include "carbons.h"
#include "chatstates.h"
#include "composing.h"
#include "delay.h"
Expand All @@ -32,6 +33,7 @@ void
xep_init(void)
{
disco_init(); /* init sevice discovery first */
carbons_init();
chatstates_init();
composing_init();
delay_init();
Expand All @@ -47,6 +49,7 @@ void
xep_deinit(void)
{
disco_deinit();
carbons_deinit();
chatstates_deinit();
composing_deinit();
delay_deinit();
Expand Down
1 change: 1 addition & 0 deletions src/fe-common/Makefile
Expand Up @@ -9,6 +9,7 @@ SRCS= fe-xmpp-messages.c \
module-formats.c \
xmpp-completion.c \
xmpp-formats.c \
xep/fe-carbons.c \
xep/fe-composing.c \
xep/fe-delay.c \
xep/fe-muc.c \
Expand Down
63 changes: 63 additions & 0 deletions src/fe-common/xep/fe-carbons.c
@@ -0,0 +1,63 @@
#include "module.h"
#include "levels.h"
#include "module-formats.h"
#include "printtext.h"
#include "settings.h"
#include "signals.h"
#include "window-items.h"
#include "fe-messages.h"
#include "fe-queries.h"
#include "fe-common/core/module-formats.h"
#include "fe-common/core/fe-messages.h"
#include "fe-common/irc/module-formats.h"

#include "xmpp-servers.h"
#include "rosters-tools.h"
#include "xep/muc.h"

static void
sig_message_carbons_sent(SERVER_REC *server, const char *msg, const char *nick,
const char *target, gpointer gpointer_type)
{
void *item;
char *freemsg = NULL;
int level, type;

g_return_if_fail(server != NULL);
g_return_if_fail(msg != NULL);
g_return_if_fail(nick != NULL);
g_return_if_fail(target != NULL);

type = GPOINTER_TO_INT(gpointer_type);
level = MSGLEVEL_NO_ACT | MSGLEVEL_NOHILIGHT
| (type == SEND_TARGET_CHANNEL ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS);
item = type == SEND_TARGET_CHANNEL ?
(void *)get_muc((XMPP_SERVER_REC *)server, target) :
query_find(server, target);

if (settings_get_bool("emphasis"))
msg = freemsg = expand_emphasis(item, msg);

if (type == SEND_TARGET_CHANNEL) {
char *nickmode = channel_get_nickmode(item, nick);
printformat_module(CORE_MODULE_NAME, server, target,
level, TXT_OWN_MSG_CHANNEL, nick, target, msg, nickmode);
} else if(item) { // If no query, why do we want to see carbons?
printformat_module(CORE_MODULE_NAME, server, target,
level, TXT_OWN_MSG_PRIVATE_QUERY, target, msg, nick);
}

g_free_not_null(freemsg);
}

void
fe_carbons_init(void)
{
signal_add("message xmpp carbons sent", sig_message_carbons_sent);
}

void
fe_carbons_deinit(void)
{
signal_remove("message xmpp carbons sent", sig_message_carbons_sent);
}
9 changes: 9 additions & 0 deletions src/fe-common/xep/fe-carbons.h
@@ -0,0 +1,9 @@
#ifndef __FE_CARBONS_H
#define __FE_CARBONS_H

__BEGIN_DECLS
void fe_carbons_init(void);
void fe_carbons_deinit(void);
__END_DECLS

#endif
3 changes: 3 additions & 0 deletions src/fe-common/xep/fe-xep.c
Expand Up @@ -17,6 +17,7 @@

#include "module.h"

#include "fe-carbons.h"
#include "fe-composing.h"
#include "fe-delay.h"
#include "fe-muc.h"
Expand All @@ -28,6 +29,7 @@
void
fe_xep_init(void)
{
fe_carbons_init();
fe_composing_init();
fe_delay_init();
fe_muc_init();
Expand All @@ -40,6 +42,7 @@ fe_xep_init(void)
void
fe_xep_deinit(void)
{
fe_carbons_deinit();
fe_composing_deinit();
fe_delay_deinit();
fe_muc_deinit();
Expand Down

0 comments on commit 563b255

Please sign in to comment.