edit diffs

v1
Tony Olagbaiye 3 years ago
parent 55626cd08f
commit f5d97c4bd8
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

3
.gitmodules vendored

@ -4,3 +4,6 @@
[submodule "omemo"]
path = omemo
url = https://github.com/gkdr/libomemo
[submodule "diff"]
path = diff
url = https://github.com/kristapsdz/libdiff

@ -27,7 +27,7 @@ SRCS=plugin.c \
xmpp/presence.c \
xmpp/iq.c \
DEPS=omemo/build/libomemo-conversations.a axc/build/libaxc.a
DEPS=omemo/build/libomemo-conversations.a axc/build/libaxc.a diff/libdiff.a
OBJS=$(subst .c,.o,$(SRCS))
all: weechat-xmpp
@ -47,6 +47,11 @@ axc/build/libaxc.a:
$(MAKE) -C axc
axc: axc/build/libaxc.a
diff/libdiff.a:
cd diff && ./configure
$(MAKE) -C diff CFLAGS=-fPIC
diff: diff/libdiff.a
test: xmpp.so
env LD_PRELOAD=$(DEBUG) \
weechat -a -P 'alias,buflist,irc' -r '/plugin load ./xmpp.so'
@ -68,6 +73,7 @@ clean:
$(RM) -f $(OBJS)
$(MAKE) -C omemo clean || true
$(MAKE) -C axc clean || true
$(MAKE) -C diff clean || true
git submodule foreach --recursive git clean -xfd || true
git submodule foreach --recursive git reset --hard || true
git submodule update --init --recursive || true

@ -106,6 +106,7 @@
* [X] [#B] Displaying
* [X] [#B] Tagging
* [ ] [#B] Making
* [X] [#C] Diff highlighting
* [ ] [#B] Handle errors gracefully
* [X] [#B] Presence/nicklist
* [X] [#B] Enters

@ -168,6 +168,8 @@ void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t leve
static const char *log_level_name[4] = {"debug", "info", "warn", "error"};
const char *tags = level > XMPP_LEVEL_DEBUG ? "no_log" : NULL;
char *xml;
if ((level == XMPP_LEVEL_DEBUG) && ((xml = strchr(msg, '<')) != NULL))
{
@ -219,14 +221,16 @@ void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t leve
0, 0, &size);
if (lines[size-1][0] == 0)
lines[--size] = 0;
weechat_printf(
weechat_printf_date_tags(
account ? account->buffer : NULL,
0, tags,
_("%s%s (%s): %s"),
weechat_prefix("network"), area,
log_level_name[level], header);
for (int i = 1; i < size; i++)
weechat_printf(
weechat_printf_date_tags(
account ? account->buffer : NULL,
0, tags,
_("%s%s"), colour, lines[i]);
weechat_string_free_split(lines);
@ -234,8 +238,9 @@ void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t leve
}
else
{
weechat_printf(
weechat_printf_date_tags(
account ? account->buffer : NULL,
0, tags,
_("%s%s (%s): %s"),
weechat_prefix("network"), area,
log_level_name[level], msg);

@ -86,7 +86,7 @@ struct t_gui_buffer *channel__create_buffer(struct t_account *account,
buffer_created = 0;
snprintf(buffer_name, sizeof(buffer_name),
"%s.%s", account->name, name);
"xmpp.%s.%s", account->name, name);
ptr_buffer = channel__search_buffer(account, type, name);
if (ptr_buffer)
@ -586,7 +586,8 @@ void channel__update_topic(struct t_channel *channel,
struct t_channel_member *channel__add_member(struct t_account *account,
struct t_channel *channel,
const char *id)
const char *id, const char *client,
const char *status)
{
struct t_channel_member *member;
struct t_user *user;
@ -611,23 +612,35 @@ struct t_channel_member *channel__add_member(struct t_account *account,
char *jid_bare = xmpp_jid_bare(account->context, user->id);
char *jid_resource = xmpp_jid_resource(account->context, user->id);
if (weechat_strcasecmp(jid_bare, channel->id) == 0
if (weechat_strcasecmp(user->id, channel->id) == 0
&& channel->type == CHANNEL_TYPE_MUC)
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s %sentered%s %s",
weechat_printf_date_tags(channel->buffer, 0, "log2", "%sMUC: %s",
weechat_prefix("network"),
user->id);
else if (weechat_strcasecmp(jid_bare, channel->id) == 0
&& channel->type == CHANNEL_TYPE_MUC)
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s %s%s%s %sentered%s %s %s%s%s",
weechat_prefix("join"),
user__as_prefix_raw(account, jid_resource),
client ? "(" : "", client, client ? ")" : "",
weechat_color("irc.color.message_join"),
weechat_color("reset"),
channel->id);
channel->id,
status ? "[" : "",
status ? status : "",
status ? "]" : "");
else
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s (%s) %sentered%s %s",
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,enter,log4", "%s%s (%s) %sentered%s %s %s%s%s",
weechat_prefix("join"),
user__as_prefix_raw(account,
xmpp_jid_bare(account->context, user->id)),
xmpp_jid_resource(account->context, user->id),
weechat_color("irc.color.message_join"),
weechat_color("reset"),
channel->id);
channel->id,
status ? "[" : "",
status ? status : "",
status ? "]" : "");
return member;
}
@ -692,7 +705,7 @@ int channel__set_member_affiliation(struct t_account *account,
struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel,
const char *id)
const char *id, const char *status)
{
struct t_channel_member *member;
struct t_user *user;
@ -709,20 +722,26 @@ struct t_channel_member *channel__remove_member(struct t_account *account,
char *jid_resource = xmpp_jid_resource(account->context, user->id);
if (weechat_strcasecmp(jid_bare, channel->id) == 0
&& channel->type == CHANNEL_TYPE_MUC)
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,leave,log4", "%s%s %sleft%s %s",
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,leave,log4", "%s%s %sleft%s %s %s%s%s",
weechat_prefix("quit"),
jid_resource,
weechat_color("irc.color.message_quit"),
weechat_color("reset"),
channel->id);
channel->id,
status ? "[" : "",
status ? status : "",
status ? "]" : "");
else
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,leave,log4", "%s%s (%s) %sleft%s %s",
weechat_printf_date_tags(channel->buffer, 0, "xmpp_presence,leave,log4", "%s%s (%s) %sleft%s %s %s%s%s",
weechat_prefix("quit"),
xmpp_jid_bare(account->context, user->id),
xmpp_jid_resource(account->context, user->id),
weechat_color("irc.color.message_quit"),
weechat_color("reset"),
channel->id);
channel->id,
status ? "[" : "",
status ? status : "",
status ? "]" : "");
return member;
}
@ -761,7 +780,9 @@ void channel__send_message(struct t_account *account, struct t_channel *channel,
xmpp_send(account->connection, message);
xmpp_stanza_release(message);
if (channel->type != CHANNEL_TYPE_MUC)
weechat_printf(channel->buffer, "%s\t%s",
user__as_prefix_raw(account, account_jid(account)),
body);
weechat_printf_date_tags(channel->buffer, 0,
"xmpp_message,message,notify_none,self_msg,log1",
"%s\t%s",
user__as_prefix_raw(account, account_jid(account)),
body);
}

@ -121,7 +121,8 @@ void channel__update_purpose(struct t_channel *channel,
struct t_channel_member *channel__add_member(struct t_account *account,
struct t_channel *channel,
const char *id);
const char *id, const char *client,
const char *status);
int channel__set_member_role(struct t_account *account,
struct t_channel *channel,
@ -133,7 +134,7 @@ int channel__set_member_affiliation(struct t_account *account,
struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel,
const char *id);
const char *id, const char *status);
void channel__send_message(struct t_account *account, struct t_channel *channel,
const char *to, const char *body);

@ -11,6 +11,7 @@
#include <weechat/weechat-plugin.h>
#include "plugin.h"
#include "diff/diff.h"
#include "xmpp/stanza.h"
#include "config.h"
#include "account.h"
@ -82,8 +83,10 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
struct t_account *account = (struct t_account *)userdata;
struct t_user *user;
struct t_channel *channel;
xmpp_stanza_t *iq__x, *iq__x__item;
const char *from, *from_bare, *role = NULL, *affiliation = NULL;
xmpp_stanza_t *iq__x, *iq__x__item, *iq__c, *iq__status;
const char *from, *from_bare, *role = NULL, *affiliation = NULL, *jid = NULL;
const char *node = NULL, *ver = NULL;
char *clientid = NULL, *status;
from = xmpp_stanza_get_from(stanza);
if (from == NULL)
@ -96,7 +99,25 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
iq__x__item = xmpp_stanza_get_child_by_name(iq__x, "item");
role = xmpp_stanza_get_attribute(iq__x__item, "role");
affiliation = xmpp_stanza_get_attribute(iq__x__item, "affiliation");
jid = xmpp_stanza_get_attribute(iq__x__item, "jid");
}
iq__c = xmpp_stanza_get_child_by_name_and_ns(
stanza, "c", "http://jabber.org/protocol/caps");
if (iq__c)
{
node = xmpp_stanza_get_attribute(iq__c, "node");
ver = xmpp_stanza_get_attribute(iq__c, "ver");
if (jid)
clientid = strdup(jid);
else if (node && ver)
{
int len = strlen(node)+1+strlen(ver);
clientid = malloc(sizeof(char)*len);
snprintf(clientid, len, "%s#%s", node, ver);
}
}
iq__status = xmpp_stanza_get_child_by_name(stanza, "status");
status = iq__status ? xmpp_stanza_get_text(iq__status) : NULL;
user = user__search(account, from);
if (!user)
@ -107,18 +128,21 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
{
if (!channel)
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
channel__add_member(account, channel, from);
channel__add_member(account, channel, from, clientid, status);
}
else if (channel)
{
channel__set_member_role(account, channel, from, role);
channel__set_member_affiliation(account, channel, from, affiliation);
if (weechat_strcasecmp(role, "none") == 0)
channel__remove_member(account, channel, from);
channel__remove_member(account, channel, from, status);
else
channel__add_member(account, channel, from);
channel__add_member(account, channel, from, clientid, status);
}
if (clientid)
free(clientid);
return 1;
}
@ -130,7 +154,7 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
struct t_channel *channel;
xmpp_stanza_t *body, *delay, *topic, *replace;
const char *type, *from, *nick, *from_bare, *to, *id, *replace_id, *timestamp;
char *intext;
char *intext, *difftext = NULL;
struct tm time = {0};
time_t date = 0;
@ -171,6 +195,80 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
channel = channel__search(account, from_bare);
if (!channel)
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
if (replace)
{
const char *orig = NULL;
void *lines = weechat_hdata_pointer(weechat_hdata_get("buffer"),
channel->buffer, "lines");
if (lines)
{
void *last_line = weechat_hdata_pointer(weechat_hdata_get("lines"),
lines, "last_line");
while (last_line && !orig)
{
void *line_data = weechat_hdata_pointer(weechat_hdata_get("line"),
last_line, "data");
if (line_data)
{
int tags_count = weechat_hdata_integer(weechat_hdata_get("line_data"),
line_data, "tags_count");
char str_tag[20] = {0};
for (int n_tag = 0; n_tag < tags_count; n_tag++)
{
snprintf(str_tag, sizeof(str_tag), "%d|tags_array", n_tag);
const char *tag = weechat_hdata_string(weechat_hdata_get("line_data"),
line_data, str_tag);
if (strlen(tag) > strlen("id_") &&
weechat_strcasecmp(tag+strlen("id_"), replace_id) == 0)
{
orig = weechat_hdata_string(weechat_hdata_get("line_data"),
line_data, "message");
break;
}
}
}
last_line = weechat_hdata_pointer(weechat_hdata_get("line"),
last_line, "prev_line");
}
}
if (orig)
{
struct diff result;
if (diff(&result, char_cmp, 1, orig, strlen(orig), intext, strlen(intext)) > 0)
{
char **visual = weechat_string_dyn_alloc(256);
char ch[2] = {0};
for (size_t i = 0; i < result.sessz; i++)
switch (result.ses[i].type)
{
case DIFF_ADD:
weechat_string_dyn_concat(visual, weechat_color("green"), -1);
*ch = *(const char *)result.ses[i].e;
weechat_string_dyn_concat(visual, ch, -1);
break;
case DIFF_DELETE:
weechat_string_dyn_concat(visual, weechat_color("red"), -1);
*ch = *(const char *)result.ses[i].e;
weechat_string_dyn_concat(visual, ch, -1);
break;
case DIFF_COMMON:
default:
weechat_string_dyn_concat(visual, weechat_color("resetcolor"), -1);
*ch = *(const char *)result.ses[i].e;
weechat_string_dyn_concat(visual, ch, -1);
break;
}
free(result.ses);
free(result.lcs);
difftext = strdup(*visual);
weechat_string_dyn_free(visual, 1);
}
}
}
nick = NULL;
if (weechat_strcasecmp(type, "groupchat") == 0)
@ -225,20 +323,22 @@ int connection__message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *
if (strcmp(to, channel->id) == 0)
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s\t[to %s]: %s",
edit, user__as_prefix_raw(account, nick),
to, intext ? intext : "");
to, difftext ? difftext : intext ? intext : "");
else if (weechat_string_match(intext, "/me *", 0))
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s\t%s %s",
edit, weechat_prefix("action"), nick,
intext ? intext+4 : "");
difftext ? difftext+4 : intext ? intext+4 : "");
else
weechat_printf_date_tags(channel->buffer, date, *dyn_tags, "%s%s\t%s",
edit, user__as_prefix_raw(account, nick),
intext ? intext : "");
difftext ? difftext : intext ? intext : "");
weechat_string_dyn_free(dyn_tags, 1);
if (intext)
xmpp_free(account->context, intext);
if (difftext)
free(difftext);
return 1;
}
@ -248,7 +348,7 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
(void) conn;
struct t_account *account = (struct t_account *)userdata;
xmpp_stanza_t *reply, *query, *identity, *feature, *x, *field, *value, *text;
xmpp_stanza_t *reply, *query, *identity, *feature, *enable, *x, *field, *value, *text;
xmpp_stanza_t *pubsub, *items, *item, *list, *device, **children;
xmpp_stanza_t *storage, *conference, *nick;
static struct utsname osinfo;
@ -315,6 +415,12 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
FEATURE("urn:xmpp:time");
#undef FEATURE
enable = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(enable, "enable");
xmpp_stanza_set_ns(enable, "urn:xmpp:carbons:2");
xmpp_stanza_add_child(query, enable);
xmpp_stanza_release(enable);
x = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(x, "x");
xmpp_stanza_set_ns(x, "jabber:x:data");
@ -710,15 +816,15 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
NULL, variables, NULL);
weechat_hashtable_free(variables);
uint32_t dev_id = dev_str[0] ? atoi(dev_str) : 0;
uint8_t identity[128];
if (b64_id)
uint8_t identity[128] = {0};
if (b64_id && *b64_id)
weechat_string_base_decode(64, b64_id, (char*)identity);
struct t_identity id_key = {
.key = b64_id ? identity : NULL,
.key = identity,
.length = 4,
};
omemo__init(&account->omemo, dev_id, &id_key);
omemo__init(&account->omemo, dev_id, b64_id && *b64_id ? &id_key : NULL);
char account_id[64] = {0};
snprintf(account_id, sizeof(account_id), "%d", account->omemo->device_id);
@ -735,16 +841,15 @@ void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
}
char account_key[64] = {0};
weechat_string_base_encode(64, (char*)account->omemo->identity.key,
account->omemo->identity.length, account_key);
if (memcmp(identity, account->omemo->identity.key,
account->omemo->identity.length) != 0)
account->omemo->identity.length, account_key);
if (weechat_strcasecmp(b64_id, account_key) != 0)
{
char **command = weechat_string_dyn_alloc(256);
weechat_string_dyn_concat(command, "/secure set ", -1);
weechat_string_dyn_concat(command, "xmpp_identity_", -1);
weechat_string_dyn_concat(command, account->name, -1);
weechat_string_dyn_concat(command, " ", -1);
weechat_string_dyn_concat(command, account_id, -1);
weechat_string_dyn_concat(command, account_key, -1);
weechat_command(account->buffer, *command);
weechat_string_dyn_free(command, 1);
}

@ -13,4 +13,10 @@ int connection__connect(struct t_account *account, xmpp_conn_t **connection,
void connection__process(xmpp_ctx_t *context, xmpp_conn_t *connection,
const unsigned long timeout);
static inline int
char_cmp(const void *p1, const void *p2)
{
return *(const char *)p1 == *(const char *)p2;
}
#endif /*WEECHAT_XMPP_CONNECTION_H*/

@ -0,0 +1 @@
Subproject commit aadb3d7fe4dcb4b212c77e4fc6c2599826aeb50a
Loading…
Cancel
Save