mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Merge pull request #1383 from profanity-im/cleanup/messagec
Cleanup carbons/chat handling in message.c
This commit is contained in:
commit
7cd135512b
@ -84,8 +84,9 @@ static void _handle_muc_private_message(xmpp_stanza_t *const stanza);
|
|||||||
static void _handle_conference(xmpp_stanza_t *const stanza);
|
static void _handle_conference(xmpp_stanza_t *const stanza);
|
||||||
static void _handle_captcha(xmpp_stanza_t *const stanza);
|
static void _handle_captcha(xmpp_stanza_t *const stanza);
|
||||||
static void _handle_receipt_received(xmpp_stanza_t *const stanza);
|
static void _handle_receipt_received(xmpp_stanza_t *const stanza);
|
||||||
static void _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam);
|
static void _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam, gboolean is_carbon);
|
||||||
static void _handle_ox_chat(xmpp_stanza_t *const stanza, ProfMessage *message, gboolean is_mam);
|
static void _handle_ox_chat(xmpp_stanza_t *const stanza, ProfMessage *message, gboolean is_mam);
|
||||||
|
static xmpp_stanza_t* _handle_carbons(xmpp_stanza_t *const stanza);
|
||||||
static void _send_message_stanza(xmpp_stanza_t *const stanza);
|
static void _send_message_stanza(xmpp_stanza_t *const stanza);
|
||||||
static gboolean _handle_mam(xmpp_stanza_t *const stanza);
|
static gboolean _handle_mam(xmpp_stanza_t *const stanza);
|
||||||
static void _handle_pubsub(xmpp_stanza_t *const stanza, xmpp_stanza_t *const event);
|
static void _handle_pubsub(xmpp_stanza_t *const stanza, xmpp_stanza_t *const event);
|
||||||
@ -206,7 +207,32 @@ _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *con
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_handle_chat(stanza, FALSE);
|
xmpp_stanza_t *msg_stanza = stanza;
|
||||||
|
gboolean is_carbon = FALSE;
|
||||||
|
|
||||||
|
// XEP-0280: Message Carbons
|
||||||
|
xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS);
|
||||||
|
if (carbons) {
|
||||||
|
|
||||||
|
// carbon must come from ourselves
|
||||||
|
char *mybarejid = connection_get_barejid();
|
||||||
|
const char *const stanza_from = xmpp_stanza_get_from(stanza);
|
||||||
|
|
||||||
|
if (g_strcmp0(mybarejid, stanza_from) != 0) {
|
||||||
|
log_warning("Invalid carbon received, from: %s", stanza_from);
|
||||||
|
msg_stanza = NULL;
|
||||||
|
} else {
|
||||||
|
is_carbon = TRUE;
|
||||||
|
// returns NULL if it was a carbon that was invalid, so that we dont parse later
|
||||||
|
msg_stanza = _handle_carbons(carbons);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mybarejid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg_stanza) {
|
||||||
|
_handle_chat(msg_stanza, FALSE, is_carbon);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// none of the allowed types
|
// none of the allowed types
|
||||||
char *text;
|
char *text;
|
||||||
@ -1155,143 +1181,44 @@ out:
|
|||||||
message_free(message);
|
message_free(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static xmpp_stanza_t*
|
||||||
_handle_carbons(xmpp_stanza_t *const stanza)
|
_handle_carbons(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS);
|
const char *name = xmpp_stanza_get_name(stanza);
|
||||||
if (!carbons) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *name = xmpp_stanza_get_name(carbons);
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
log_error("Unable to retrieve stanza name for Carbon");
|
log_error("Unable to retrieve stanza name for Carbon");
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: private shouldn't arrive at the client, should it?
|
||||||
if (g_strcmp0(name, "private") == 0) {
|
if (g_strcmp0(name, "private") == 0) {
|
||||||
log_info("Carbon received with private element.");
|
log_info("Carbon received with private element.");
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if ((g_strcmp0(name, "received") != 0) && (g_strcmp0(name, "sent") != 0)) {
|
if ((g_strcmp0(name, "received") != 0) && (g_strcmp0(name, "sent") != 0)) {
|
||||||
log_warning("Carbon received with unrecognised stanza name: %s", name);
|
log_warning("Carbon received with unrecognised stanza name: %s", name);
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD);
|
xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_FORWARD);
|
||||||
if (!forwarded) {
|
if (!forwarded) {
|
||||||
log_warning("Carbon received with no forwarded element");
|
log_warning("Carbon received with no forwarded element");
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_t *message_stanza = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);
|
xmpp_stanza_t *message_stanza = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);
|
||||||
if (!message_stanza) {
|
if (!message_stanza) {
|
||||||
log_warning("Carbon received with no message element");
|
log_warning("Carbon received with no message element");
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *mybarejid = connection_get_barejid();
|
return message_stanza;
|
||||||
const char *const stanza_from = xmpp_stanza_get_from(stanza);
|
|
||||||
if (g_strcmp0(mybarejid, stanza_from) != 0) {
|
|
||||||
log_warning("Invalid carbon received, from: %s", stanza_from);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfMessage *message = message_init();
|
|
||||||
message->type = PROF_MSG_TYPE_CHAT;
|
|
||||||
|
|
||||||
// check whether message was a MUC PM
|
|
||||||
xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_MUC_USER);
|
|
||||||
if (mucuser) {
|
|
||||||
message->type = PROF_MSG_TYPE_MUCPM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// id
|
|
||||||
const char *id = xmpp_stanza_get_id(message_stanza);
|
|
||||||
if (id) {
|
|
||||||
message->id = strdup(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace id
|
|
||||||
xmpp_stanza_t *replace_id_stanza = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_LAST_MESSAGE_CORRECTION);
|
|
||||||
if (replace_id_stanza) {
|
|
||||||
const char *replace_id = xmpp_stanza_get_id(replace_id_stanza);
|
|
||||||
if (replace_id) {
|
|
||||||
message->replace_id = strdup(replace_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check omemo encryption
|
|
||||||
#ifdef HAVE_OMEMO
|
|
||||||
message->plain = omemo_receive_message(message_stanza, &message->trusted);
|
|
||||||
if (message->plain != NULL) {
|
|
||||||
message->enc = PROF_MSG_ENC_OMEMO;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const gchar *to = xmpp_stanza_get_to(message_stanza);
|
|
||||||
const gchar *from = xmpp_stanza_get_from(message_stanza);
|
|
||||||
|
|
||||||
// happens when receive a carbon of a self sent message
|
|
||||||
// really? maybe some servers do this, but it's not required.
|
|
||||||
if (!to) to = from;
|
|
||||||
|
|
||||||
Jid *jid_from = jid_create(from);
|
|
||||||
Jid *jid_to = jid_create(to);
|
|
||||||
|
|
||||||
message->body = xmpp_message_get_body(message_stanza);
|
|
||||||
|
|
||||||
if (!message->plain && !message->body) {
|
|
||||||
log_error("Message received without body from: %s", jid_from->fulljid);
|
|
||||||
jid_destroy(jid_from);
|
|
||||||
jid_destroy(jid_to);
|
|
||||||
goto out;
|
|
||||||
} else if (!message->plain) {
|
|
||||||
message->plain = strdup(message->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for pgp encrypted message
|
|
||||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_ENCRYPTED);
|
|
||||||
if (x) {
|
|
||||||
message->encrypted = xmpp_stanza_get_text(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// OX
|
|
||||||
xmpp_stanza_t *ox = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_OPENPGP_0);
|
|
||||||
if (ox) {
|
|
||||||
_handle_ox_chat(message_stanza, message, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: maybe also add is_carbon maybe even an enum with outgoing/incoming
|
|
||||||
if (message->plain || message->encrypted || message->body) {
|
|
||||||
message->from_jid = jid_from;
|
|
||||||
message->to_jid = jid_to;
|
|
||||||
|
|
||||||
// if we are the recipient, treat as standard incoming message
|
|
||||||
if (g_strcmp0(mybarejid, jid_to->barejid) == 0) {
|
|
||||||
sv_ev_incoming_carbon(message);
|
|
||||||
// else treat as a sent message
|
|
||||||
} else {
|
|
||||||
sv_ev_outgoing_carbon(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
message_free(message);
|
|
||||||
free(mybarejid);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam)
|
_handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam, gboolean is_carbon)
|
||||||
{
|
{
|
||||||
// check if carbon message
|
|
||||||
gboolean res = _handle_carbons(stanza);
|
|
||||||
if (res) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// some clients send the mucuser namespace with private messages
|
// some clients send the mucuser namespace with private messages
|
||||||
// if the namespace exists, and the stanza contains a body element, assume its a private message
|
// if the namespace exists, and the stanza contains a body element, assume its a private message
|
||||||
// otherwise exit the handler
|
// otherwise exit the handler
|
||||||
@ -1307,17 +1234,34 @@ _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam)
|
|||||||
}
|
}
|
||||||
Jid *jid = jid_create(from);
|
Jid *jid = jid_create(from);
|
||||||
|
|
||||||
|
Jid *to_jid = NULL;
|
||||||
|
const gchar *to = xmpp_stanza_get_to(stanza);
|
||||||
|
if (to) {
|
||||||
|
to_jid = jid_create(to);
|
||||||
|
}
|
||||||
|
|
||||||
// private message from chat room use full jid (room/nick)
|
// private message from chat room use full jid (room/nick)
|
||||||
if (muc_active(jid->barejid)) {
|
if (muc_active(jid->barejid)) {
|
||||||
_handle_muc_private_message(stanza);
|
_handle_muc_private_message(stanza);
|
||||||
jid_destroy(jid);
|
jid_destroy(jid);
|
||||||
|
jid_destroy(to_jid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// standard chat message, use jid without resource
|
// standard chat message, use jid without resource
|
||||||
ProfMessage *message = message_init();
|
ProfMessage *message = message_init();
|
||||||
message->from_jid = jid;
|
|
||||||
message->is_mam = is_mam;
|
message->is_mam = is_mam;
|
||||||
|
message->from_jid = jid;
|
||||||
|
if (to_jid) {
|
||||||
|
message->to_jid = to_jid;
|
||||||
|
} else {
|
||||||
|
if (is_carbon) {
|
||||||
|
// happens when receive a carbon of a self sent message
|
||||||
|
// really? maybe some servers do this, but it's not required.
|
||||||
|
Jid *from_jid = jid_create(from);
|
||||||
|
message->to_jid = from_jid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mucuser) {
|
if (mucuser) {
|
||||||
message->type = PROF_MSG_TYPE_MUCPM;
|
message->type = PROF_MSG_TYPE_MUCPM;
|
||||||
@ -1374,10 +1318,23 @@ _handle_chat(xmpp_stanza_t *const stanza, gboolean is_mam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message->plain || message->body || message->encrypted) {
|
if (message->plain || message->body || message->encrypted) {
|
||||||
sv_ev_incoming_message(message);
|
if (is_carbon) {
|
||||||
|
char *mybarejid = connection_get_barejid();
|
||||||
|
|
||||||
|
// if we are the recipient, treat as standard incoming message
|
||||||
|
if (g_strcmp0(mybarejid, message->to_jid->barejid) == 0) {
|
||||||
|
sv_ev_incoming_carbon(message);
|
||||||
|
// else treat as a sent message
|
||||||
|
} else {
|
||||||
|
sv_ev_outgoing_carbon(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(mybarejid);
|
||||||
|
} else {
|
||||||
|
sv_ev_incoming_message(message);
|
||||||
_receipt_request_handler(stanza);
|
_receipt_request_handler(stanza);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 0085 works only with resource
|
// 0085 works only with resource
|
||||||
if (jid->resourcepart) {
|
if (jid->resourcepart) {
|
||||||
@ -1435,7 +1392,7 @@ _handle_mam(xmpp_stanza_t *const stanza)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_t *message_stanza = xmpp_stanza_get_child_by_ns(forwarded, "jabber:client");
|
xmpp_stanza_t *message_stanza = xmpp_stanza_get_child_by_ns(forwarded, "jabber:client");
|
||||||
_handle_chat(message_stanza, TRUE);
|
_handle_chat(message_stanza, TRUE, FALSE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user