From 6b52e59a7945440ae2fd5a432436f66ea7350661 Mon Sep 17 00:00:00 2001 From: bqv Date: Mon, 2 Jan 2023 06:29:03 +0000 Subject: [PATCH] fix double frees on quit, add tests --- .depend | 379 +++++++++++++++++++++------------------------- .gitmodules | 3 - README.org | 2 + buffer.cpp | 4 +- channel.cpp | 52 ++++--- channel.hh | 9 +- command.cpp | 36 +++++ config.cpp | 2 + config/file.hh | 6 +- config/option.hh | 20 +-- config/section.hh | 32 ++-- connection.cpp | 3 +- deps/fmt | 1 - input.cpp | 2 +- makefile | 69 +++++---- plugin.cpp | 113 +++++++++----- plugin.hh | 38 ++++- strophe.hh | 1 + tests/plugin.inl | 112 +++++++++++++- 19 files changed, 532 insertions(+), 352 deletions(-) delete mode 160000 deps/fmt diff --git a/.depend b/.depend index 5ef6af3..7305661 100644 --- a/.depend +++ b/.depend @@ -1,6 +1,6 @@ -.plugin.o: plugin.cpp plugin.hh config.hh deps/fmt/include/fmt/core.h \ - config/file.hh config/breadcrumb.hh config/section.hh config/account.hh \ +.plugin.o: plugin.cpp plugin.hh strophe.hh config.hh config/file.hh \ + config/breadcrumb.hh config/section.hh config/account.hh \ config/option.hh account.hh pgp.hh omemo.hh \ /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ @@ -10,11 +10,11 @@ /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh \ - strophe.hh user.hh command.hh input.hh buffer.hh completion.hh + /usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh user.hh \ + command.hh input.hh buffer.hh completion.hh plugin.hh: +strophe.hh: config.hh: -deps/fmt/include/fmt/core.h: config/file.hh: config/breadcrumb.hh: config/section.hh: @@ -40,14 +40,12 @@ signal.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: command.hh: input.hh: buffer.hh: completion.hh: -.account.o: account.cpp deps/fmt/include/fmt/core.h \ - /usr/include/libxml2/libxml/xmlwriter.h \ +.account.o: account.cpp /usr/include/libxml2/libxml/xmlwriter.h \ /usr/include/libxml2/libxml/xmlversion.h \ /usr/include/libxml2/libxml/xmlexports.h \ /usr/include/libxml2/libxml/xmlIO.h \ @@ -64,10 +62,10 @@ completion.hh: /usr/include/libxml2/libxml/encoding.h \ /usr/include/libxml2/libxml/SAX2.h \ /usr/include/libxml2/libxml/xmlmemory.h \ - /usr/include/libxml2/libxml/threads.h plugin.hh xmpp/stanza.hh config.hh \ - config/file.hh config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh input.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ + /usr/include/libxml2/libxml/threads.h plugin.hh strophe.hh \ + xmpp/stanza.hh config.hh config/file.hh config/breadcrumb.hh \ + config/section.hh config/account.hh config/option.hh input.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -76,8 +74,7 @@ completion.hh: /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h account.hh pgp.hh channel.hh connection.hh \ - xmpp/ns.hh strophe.hh user.hh buffer.hh -deps/fmt/include/fmt/core.h: + xmpp/ns.hh user.hh buffer.hh /usr/include/libxml2/libxml/xmlwriter.h: /usr/include/libxml2/libxml/xmlversion.h: /usr/include/libxml2/libxml/xmlexports.h: @@ -99,6 +96,7 @@ deps/fmt/include/fmt/core.h: /usr/include/libxml2/libxml/xmlmemory.h: /usr/include/libxml2/libxml/threads.h: plugin.hh: +strophe.hh: xmpp/stanza.hh: config.hh: config/file.hh: @@ -127,12 +125,10 @@ pgp.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: buffer.hh: -.buffer.o: buffer.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.buffer.o: buffer.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -142,11 +138,10 @@ buffer.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - buffer.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh buffer.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -172,12 +167,10 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: buffer.hh: -.channel.o: channel.cpp deps/fmt/include/fmt/core.h plugin.hh account.hh \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.channel.o: channel.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -187,12 +180,12 @@ buffer.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - input.hh buffer.hh util.hh xmpp/node.hh xmpp/xep-0027.inl \ - xmpp/xep-0030.inl xmpp/xep-0045.inl xmpp/xep-0049.inl xmpp/xep-0115.inl \ - xmpp/xep-0280.inl xmpp/xep-0319.inl xmpp/rfc-6121.inl -deps/fmt/include/fmt/core.h: + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh input.hh \ + buffer.hh util.hh xmpp/node.hh xmpp/xep-0027.inl xmpp/xep-0030.inl \ + xmpp/xep-0045.inl xmpp/xep-0049.inl xmpp/xep-0115.inl xmpp/xep-0280.inl \ + xmpp/xep-0319.inl xmpp/rfc-6121.inl plugin.hh: +strophe.hh: account.hh: pgp.hh: omemo.hh: @@ -219,7 +212,6 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: input.hh: buffer.hh: @@ -233,9 +225,8 @@ xmpp/xep-0115.inl: xmpp/xep-0280.inl: xmpp/xep-0319.inl: xmpp/rfc-6121.inl: -.command.o: command.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.command.o: command.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -245,12 +236,12 @@ xmpp/rfc-6121.inl: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - buffer.hh message.hh command.hh sexp/driver.hh sexp/scanner.hh \ - sexp/parser.tab.hh sexp/location.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh buffer.hh \ + message.hh command.hh sexp/driver.hh sexp/scanner.hh sexp/parser.tab.hh \ + sexp/location.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -276,7 +267,6 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: buffer.hh: message.hh: @@ -285,11 +275,10 @@ sexp/driver.hh: sexp/scanner.hh: sexp/parser.tab.hh: sexp/location.hh: -.completion.o: completion.cpp plugin.hh config.hh \ - deps/fmt/include/fmt/core.h config/file.hh config/breadcrumb.hh \ - config/section.hh config/account.hh config/option.hh account.hh pgp.hh \ - omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.completion.o: completion.cpp plugin.hh strophe.hh config.hh \ + config/file.hh config/breadcrumb.hh config/section.hh config/account.hh \ + config/option.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -297,11 +286,11 @@ sexp/location.hh: /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh \ - strophe.hh user.hh buffer.hh completion.hh + /usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh user.hh \ + buffer.hh completion.hh plugin.hh: +strophe.hh: config.hh: -deps/fmt/include/fmt/core.h: config/file.hh: config/breadcrumb.hh: config/section.hh: @@ -327,13 +316,11 @@ signal.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: buffer.hh: completion.hh: -.config.o: config.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.config.o: config.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -343,10 +330,10 @@ completion.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -372,11 +359,8 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: -.connection.o: connection.cpp deps/fmt/include/fmt/core.h \ - deps/fmt/include/fmt/chrono.h deps/fmt/include/fmt/format.h \ - deps/fmt/include/fmt/core.h /usr/include/libxml2/libxml/uri.h \ +.connection.o: connection.cpp /usr/include/libxml2/libxml/uri.h \ /usr/include/libxml2/libxml/xmlversion.h \ /usr/include/libxml2/libxml/xmlexports.h \ /usr/include/libxml2/libxml/tree.h \ @@ -394,11 +378,11 @@ user.hh: /usr/include/libxml2/libxml/entities.h \ /usr/include/libxml2/libxml/encoding.h \ /usr/include/libxml2/libxml/xmlIO.h /usr/include/libxml2/libxml/SAX2.h \ - plugin.hh xmpp/node.hh xmpp/xep-0027.inl xmpp/ns.hh xmpp/xep-0030.inl \ - xmpp/xep-0045.inl xmpp/xep-0049.inl xmpp/xep-0115.inl xmpp/xep-0280.inl \ - xmpp/xep-0319.inl xmpp/rfc-6121.inl xmpp/stanza.hh config.hh \ - config/file.hh config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh account.hh pgp.hh omemo.hh \ + plugin.hh strophe.hh xmpp/node.hh xmpp/xep-0027.inl xmpp/ns.hh \ + xmpp/xep-0030.inl xmpp/xep-0045.inl xmpp/xep-0049.inl xmpp/xep-0115.inl \ + xmpp/xep-0280.inl xmpp/xep-0319.inl xmpp/rfc-6121.inl xmpp/stanza.hh \ + config.hh config/file.hh config/breadcrumb.hh config/section.hh \ + config/account.hh config/option.hh account.hh pgp.hh omemo.hh \ /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ @@ -407,12 +391,8 @@ user.hh: /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h channel.hh connection.hh strophe.hh user.hh \ - util.hh deps/diff/diff.h -deps/fmt/include/fmt/core.h: -deps/fmt/include/fmt/chrono.h: -deps/fmt/include/fmt/format.h: -deps/fmt/include/fmt/core.h: + /usr/include/signal/curve.h channel.hh connection.hh user.hh util.hh \ + deps/diff/diff.h /usr/include/libxml2/libxml/uri.h: /usr/include/libxml2/libxml/xmlversion.h: /usr/include/libxml2/libxml/xmlexports.h: @@ -434,6 +414,7 @@ deps/fmt/include/fmt/core.h: /usr/include/libxml2/libxml/xmlIO.h: /usr/include/libxml2/libxml/SAX2.h: plugin.hh: +strophe.hh: xmpp/node.hh: xmpp/xep-0027.inl: xmpp/ns.hh: @@ -470,13 +451,11 @@ signal.hh: /usr/include/signal/curve.h: channel.hh: connection.hh: -strophe.hh: user.hh: util.hh: deps/diff/diff.h: -.input.o: input.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.input.o: input.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -486,11 +465,11 @@ deps/diff/diff.h: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - buffer.hh message.hh input.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh buffer.hh \ + message.hh input.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -516,14 +495,12 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: buffer.hh: message.hh: input.hh: -.message.o: message.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h \ - pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.message.o: message.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -533,11 +510,10 @@ input.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - message.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh message.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -563,11 +539,10 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: message.hh: -.omemo.o: omemo.cpp deps/fmt/include/fmt/core.h plugin.hh xmpp/stanza.hh \ - account.hh pgp.hh omemo.hh /usr/include/signal/signal_protocol.h \ +.omemo.o: omemo.cpp plugin.hh strophe.hh xmpp/stanza.hh account.hh pgp.hh \ + omemo.hh /usr/include/signal/signal_protocol.h \ /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ @@ -578,10 +553,10 @@ message.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh \ - gcrypt.hh util.hh -deps/fmt/include/fmt/core.h: + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh gcrypt.hh \ + util.hh plugin.hh: +strophe.hh: xmpp/stanza.hh: account.hh: pgp.hh: @@ -609,17 +584,15 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: gcrypt.hh: util.hh: -.pgp.o: pgp.cpp deps/fmt/include/fmt/core.h plugin.hh pgp.hh -deps/fmt/include/fmt/core.h: +.pgp.o: pgp.cpp plugin.hh strophe.hh pgp.hh plugin.hh: +strophe.hh: pgp.hh: -.user.o: user.cpp plugin.hh account.hh deps/fmt/include/fmt/core.h pgp.hh \ - omemo.hh /usr/include/signal/signal_protocol.h \ - /usr/include/signal/ratchet.h \ +.user.o: user.cpp plugin.hh strophe.hh account.hh pgp.hh omemo.hh \ + /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ @@ -629,10 +602,10 @@ pgp.hh: /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ /usr/include/signal/curve.h config.hh config/file.hh \ config/breadcrumb.hh config/section.hh config/account.hh \ - config/option.hh channel.hh connection.hh xmpp/ns.hh strophe.hh user.hh + config/option.hh channel.hh connection.hh xmpp/ns.hh user.hh plugin.hh: +strophe.hh: account.hh: -deps/fmt/include/fmt/core.h: pgp.hh: omemo.hh: /usr/include/signal/signal_protocol.h: @@ -658,36 +631,36 @@ config/option.hh: channel.hh: connection.hh: xmpp/ns.hh: -strophe.hh: user.hh: -.util.o: util.cpp plugin.hh util.hh +.util.o: util.cpp plugin.hh strophe.hh util.hh plugin.hh: +strophe.hh: util.hh: config/.breadcrumb.o: config/breadcrumb.cpp config/breadcrumb.hh \ - deps/fmt/include/fmt/core.h config/./.plugin.hh + config/../plugin.hh config/../strophe.hh config/breadcrumb.hh: -deps/fmt/include/fmt/core.h: -config/./.plugin.hh: -config/.file.o: config/file.cpp config/../plugin.hh config/../account.hh \ - deps/fmt/include/fmt/core.h config/./.pgp.hh config/../omemo.hh \ +config/../plugin.hh: +config/../strophe.hh: +config/.file.o: config/file.cpp config/../plugin.hh config/../strophe.hh \ + config/../account.hh config/../pgp.hh config/../omemo.hh \ /usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ - /usr/include/signal/sender_key_record.h config/./.signal.hh \ + /usr/include/signal/sender_key_record.h config/../signal.hh \ /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h config/./.config.hh config/../config/file.hh \ - config/./.config/breadcrumb.hh config/../config/section.hh \ - config/./.config/account.hh config/../config/option.hh \ - config/./.channel.hh config/../connection.hh config/../xmpp/ns.hh \ - config/./.strophe.hh config/../user.hh -config/./.plugin.hh: -config/./.account.hh: -deps/fmt/include/fmt/core.h: -config/./.pgp.hh: -config/./.omemo.hh: + /usr/include/signal/curve.h config/../config.hh config/../config/file.hh \ + config/../config/breadcrumb.hh config/../config/section.hh \ + config/../config/account.hh config/../config/option.hh \ + config/../channel.hh config/../connection.hh config/../xmpp/ns.hh \ + config/../user.hh +config/../plugin.hh: +config/../strophe.hh: +config/../account.hh: +config/../pgp.hh: +config/../omemo.hh: /usr/include/signal/signal_protocol.h: /usr/include/signal/ratchet.h: /usr/include/signal/signal_protocol_types.h: @@ -695,45 +668,44 @@ config/./.omemo.hh: /usr/include/signal/session_record.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/sender_key_record.h: -config/./.signal.hh: +config/../signal.hh: /usr/include/signal/key_helper.h: /usr/include/signal/session_builder.h: /usr/include/signal/session_cipher.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/protocol.h: /usr/include/signal/curve.h: -config/./.config.hh: -config/./.config/file.hh: -config/./.config/breadcrumb.hh: -config/./.config/section.hh: -config/./.config/account.hh: -config/./.config/option.hh: -config/./.channel.hh: -config/./.connection.hh: -config/./.xmpp/ns.hh: -config/./.strophe.hh: -config/./.user.hh: +config/../config.hh: +config/../config/file.hh: +config/../config/breadcrumb.hh: +config/../config/section.hh: +config/../config/account.hh: +config/../config/option.hh: +config/../channel.hh: +config/../connection.hh: +config/../xmpp/ns.hh: +config/../user.hh: config/.section.o: config/section.cpp config/../plugin.hh \ - config/./.account.hh deps/fmt/include/fmt/core.h config/../pgp.hh \ - config/./.omemo.hh /usr/include/signal/signal_protocol.h \ + config/../strophe.hh config/../account.hh config/../pgp.hh \ + config/../omemo.hh /usr/include/signal/signal_protocol.h \ /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ - /usr/include/signal/sender_key_record.h config/./.signal.hh \ + /usr/include/signal/sender_key_record.h config/../signal.hh \ /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h config/./.config.hh config/../config/file.hh \ - config/./.config/breadcrumb.hh config/../config/section.hh \ - config/./.config/account.hh config/../config/option.hh \ - config/./.channel.hh config/../connection.hh config/../xmpp/ns.hh \ - config/./.strophe.hh config/../user.hh -config/./.plugin.hh: -config/./.account.hh: -deps/fmt/include/fmt/core.h: -config/./.pgp.hh: -config/./.omemo.hh: + /usr/include/signal/curve.h config/../config.hh config/../config/file.hh \ + config/../config/breadcrumb.hh config/../config/section.hh \ + config/../config/account.hh config/../config/option.hh \ + config/../channel.hh config/../connection.hh config/../xmpp/ns.hh \ + config/../user.hh +config/../plugin.hh: +config/../strophe.hh: +config/../account.hh: +config/../pgp.hh: +config/../omemo.hh: /usr/include/signal/signal_protocol.h: /usr/include/signal/ratchet.h: /usr/include/signal/signal_protocol_types.h: @@ -741,45 +713,44 @@ config/./.omemo.hh: /usr/include/signal/session_record.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/sender_key_record.h: -config/./.signal.hh: +config/../signal.hh: /usr/include/signal/key_helper.h: /usr/include/signal/session_builder.h: /usr/include/signal/session_cipher.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/protocol.h: /usr/include/signal/curve.h: -config/./.config.hh: -config/./.config/file.hh: -config/./.config/breadcrumb.hh: -config/./.config/section.hh: -config/./.config/account.hh: -config/./.config/option.hh: -config/./.channel.hh: -config/./.connection.hh: -config/./.xmpp/ns.hh: -config/./.strophe.hh: -config/./.user.hh: +config/../config.hh: +config/../config/file.hh: +config/../config/breadcrumb.hh: +config/../config/section.hh: +config/../config/account.hh: +config/../config/option.hh: +config/../channel.hh: +config/../connection.hh: +config/../xmpp/ns.hh: +config/../user.hh: config/.account.o: config/account.cpp config/../plugin.hh \ - config/./.account.hh deps/fmt/include/fmt/core.h config/../pgp.hh \ - config/./.omemo.hh /usr/include/signal/signal_protocol.h \ + config/../strophe.hh config/../account.hh config/../pgp.hh \ + config/../omemo.hh /usr/include/signal/signal_protocol.h \ /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ - /usr/include/signal/sender_key_record.h config/./.signal.hh \ + /usr/include/signal/sender_key_record.h config/../signal.hh \ /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h config/./.config.hh config/../config/file.hh \ - config/./.config/breadcrumb.hh config/../config/section.hh \ - config/./.config/account.hh config/../config/option.hh \ - config/./.channel.hh config/../connection.hh config/../xmpp/ns.hh \ - config/./.strophe.hh config/../user.hh -config/./.plugin.hh: -config/./.account.hh: -deps/fmt/include/fmt/core.h: -config/./.pgp.hh: -config/./.omemo.hh: + /usr/include/signal/curve.h config/../config.hh config/../config/file.hh \ + config/../config/breadcrumb.hh config/../config/section.hh \ + config/../config/account.hh config/../config/option.hh \ + config/../channel.hh config/../connection.hh config/../xmpp/ns.hh \ + config/../user.hh +config/../plugin.hh: +config/../strophe.hh: +config/../account.hh: +config/../pgp.hh: +config/../omemo.hh: /usr/include/signal/signal_protocol.h: /usr/include/signal/ratchet.h: /usr/include/signal/signal_protocol_types.h: @@ -787,45 +758,44 @@ config/./.omemo.hh: /usr/include/signal/session_record.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/sender_key_record.h: -config/./.signal.hh: +config/../signal.hh: /usr/include/signal/key_helper.h: /usr/include/signal/session_builder.h: /usr/include/signal/session_cipher.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/protocol.h: /usr/include/signal/curve.h: -config/./.config.hh: -config/./.config/file.hh: -config/./.config/breadcrumb.hh: -config/./.config/section.hh: -config/./.config/account.hh: -config/./.config/option.hh: -config/./.channel.hh: -config/./.connection.hh: -config/./.xmpp/ns.hh: -config/./.strophe.hh: -config/./.user.hh: +config/../config.hh: +config/../config/file.hh: +config/../config/breadcrumb.hh: +config/../config/section.hh: +config/../config/account.hh: +config/../config/option.hh: +config/../channel.hh: +config/../connection.hh: +config/../xmpp/ns.hh: +config/../user.hh: config/.option.o: config/option.cpp config/../plugin.hh \ - config/./.account.hh deps/fmt/include/fmt/core.h config/../pgp.hh \ - config/./.omemo.hh /usr/include/signal/signal_protocol.h \ + config/../strophe.hh config/../account.hh config/../pgp.hh \ + config/../omemo.hh /usr/include/signal/signal_protocol.h \ /usr/include/signal/ratchet.h \ /usr/include/signal/signal_protocol_types.h /usr/include/signal/curve.h \ /usr/include/signal/session_record.h \ /usr/include/signal/session_pre_key.h \ - /usr/include/signal/sender_key_record.h config/./.signal.hh \ + /usr/include/signal/sender_key_record.h config/../signal.hh \ /usr/include/signal/key_helper.h /usr/include/signal/session_builder.h \ /usr/include/signal/session_cipher.h \ /usr/include/signal/session_pre_key.h /usr/include/signal/protocol.h \ - /usr/include/signal/curve.h config/./.config.hh config/../config/file.hh \ - config/./.config/breadcrumb.hh config/../config/section.hh \ - config/./.config/account.hh config/../config/option.hh \ - config/./.channel.hh config/../connection.hh config/../xmpp/ns.hh \ - config/./.strophe.hh config/../user.hh -config/./.plugin.hh: -config/./.account.hh: -deps/fmt/include/fmt/core.h: -config/./.pgp.hh: -config/./.omemo.hh: + /usr/include/signal/curve.h config/../config.hh config/../config/file.hh \ + config/../config/breadcrumb.hh config/../config/section.hh \ + config/../config/account.hh config/../config/option.hh \ + config/../channel.hh config/../connection.hh config/../xmpp/ns.hh \ + config/../user.hh +config/../plugin.hh: +config/../strophe.hh: +config/../account.hh: +config/../pgp.hh: +config/../omemo.hh: /usr/include/signal/signal_protocol.h: /usr/include/signal/ratchet.h: /usr/include/signal/signal_protocol_types.h: @@ -833,34 +803,31 @@ config/./.omemo.hh: /usr/include/signal/session_record.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/sender_key_record.h: -config/./.signal.hh: +config/../signal.hh: /usr/include/signal/key_helper.h: /usr/include/signal/session_builder.h: /usr/include/signal/session_cipher.h: /usr/include/signal/session_pre_key.h: /usr/include/signal/protocol.h: /usr/include/signal/curve.h: -config/./.config.hh: -config/./.config/file.hh: -config/./.config/breadcrumb.hh: -config/./.config/section.hh: -config/./.config/account.hh: -config/./.config/option.hh: -config/./.channel.hh: -config/./.connection.hh: -config/./.xmpp/ns.hh: -config/./.strophe.hh: -config/./.user.hh: +config/../config.hh: +config/../config/file.hh: +config/../config/breadcrumb.hh: +config/../config/section.hh: +config/../config/account.hh: +config/../config/option.hh: +config/../channel.hh: +config/../connection.hh: +config/../xmpp/ns.hh: +config/../user.hh: xmpp/.presence.o: xmpp/presence.cpp xmpp/stanza.hh xmpp/stanza.hh: xmpp/.iq.o: xmpp/iq.cpp xmpp/stanza.hh xmpp/stanza.hh: -xmpp/.node.o: xmpp/node.cpp xmpp/node.hh deps/fmt/include/fmt/core.h \ - xmpp/xep-0027.inl xmpp/ns.hh xmpp/xep-0030.inl xmpp/xep-0045.inl \ - xmpp/xep-0049.inl xmpp/xep-0115.inl xmpp/xep-0280.inl xmpp/xep-0319.inl \ - xmpp/rfc-6121.inl +xmpp/.node.o: xmpp/node.cpp xmpp/node.hh xmpp/xep-0027.inl xmpp/ns.hh \ + xmpp/xep-0030.inl xmpp/xep-0045.inl xmpp/xep-0049.inl xmpp/xep-0115.inl \ + xmpp/xep-0280.inl xmpp/xep-0319.inl xmpp/rfc-6121.inl xmpp/node.hh: -deps/fmt/include/fmt/core.h: xmpp/xep-0027.inl: xmpp/ns.hh: xmpp/xep-0030.inl: diff --git a/.gitmodules b/.gitmodules index 537eb1e..d6c5fe2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "fmt"] - path = deps/fmt - url = https://github.com/fmtlib/fmt [submodule "diff"] path = deps/diff url = https://github.com/kristapsdz/libdiff diff --git a/README.org b/README.org index 49a1936..9d03b5f 100644 --- a/README.org +++ b/README.org @@ -51,6 +51,7 @@ - lmdb (dynamic, dependency) - libomemo-c (libsignal-protocol-c) (dynamic, dependency) - gpgme (dynamic, dependency) + - libfmt (dynamic, dependency) - g++ (build, >= GCC12) - bison (build) - flex (build) @@ -132,6 +133,7 @@ * [X] Single media on a line * [ ] [#D] Multiple media inline (protocol?) * [ ] [#C] Encrypted (pgp/omemo) + * [ ] Join and handle events asynchronously * [ ] Handle wide errors gracefully * [ ] [#C] Event-driven MUC entrance * [ ] XMPP Ping (xep-199) diff --git a/buffer.cpp b/buffer.cpp index 808f0a6..c1f1354 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -78,11 +78,11 @@ char *buffer__typing_bar_cb(const void *pointer, void *data, switch (++typecount) { case 1: - strcpy(notification, ptr_typing.name); + strcpy(notification, ptr_typing.name.data()); break; case 2: strcat(notification, ", "); - strcat(notification, ptr_typing.name); + strcat(notification, ptr_typing.name.data()); break; case 3: default: diff --git a/channel.cpp b/channel.cpp index bb2bd56..286dbc9 100644 --- a/channel.cpp +++ b/channel.cpp @@ -354,12 +354,14 @@ int weechat::channel::typing_cb(const void *pointer, void *data, int remaining_c typecount = 0; for (auto ptr_typing = channel->typings.begin(); - ptr_typing != channel->typings.end(); ptr_typing++) + ptr_typing != channel->typings.end();) { if (now - ptr_typing->ts > 5) { - channel->typings.erase(ptr_typing); + ptr_typing = channel->typings.erase(ptr_typing); } + else + ptr_typing++; typecount++; } @@ -373,14 +375,14 @@ int weechat::channel::typing_cb(const void *pointer, void *data, int remaining_c return WEECHAT_RC_OK; } -weechat::channel::typing *weechat::channel::typing_search(const char *id) +weechat::channel::typing *weechat::channel::typing_search(weechat::user *user) { - if (!id) + if (!user) return nullptr; for (auto& ptr_typing : typings) { - if (weechat_strcasecmp(ptr_typing.id, id) == 0) + if (user == ptr_typing.user) return &ptr_typing; } @@ -389,19 +391,20 @@ weechat::channel::typing *weechat::channel::typing_search(const char *id) int weechat::channel::add_typing(weechat::user *user) { - weechat::channel::typing *new_typing; + weechat::channel::typing *the_typing; int ret = 0; - new_typing = weechat::channel::typing_search(user->id); - if (!new_typing) + the_typing = weechat::channel::typing_search(user); + if (!the_typing) { - new_typing = new weechat::channel::typing(); - new_typing->id = strdup(user->id); - new_typing->name = strdup(user->profile.display_name); + weechat::channel::typing& new_typing = typings.emplace_back(); + new_typing.user = user; + new_typing.name = user->profile.display_name; + the_typing = &new_typing; ret = 1; } - new_typing->ts = time(nullptr); + the_typing->ts = time(nullptr); weechat::channel::typing_cb(this, nullptr, 0); @@ -423,13 +426,15 @@ int weechat::channel::self_typing_cb(const void *pointer, void *data, int remain now = time(NULL); for (auto ptr_typing = channel->self_typings.begin(); - ptr_typing != channel->self_typings.end(); ptr_typing++) + ptr_typing != channel->self_typings.end();) { if (now - ptr_typing->ts > 10) { channel->send_paused(ptr_typing->user); - channel->self_typings.erase(ptr_typing); + ptr_typing = channel->self_typings.erase(ptr_typing); } + else + ptr_typing++; } return WEECHAT_RC_OK; @@ -437,7 +442,7 @@ int weechat::channel::self_typing_cb(const void *pointer, void *data, int remain weechat::channel::typing *weechat::channel::self_typing_search(weechat::user *user) { - for (auto& ptr_typing : typings) + for (auto& ptr_typing : self_typings) { if (user == ptr_typing.user) return &ptr_typing; @@ -448,16 +453,17 @@ weechat::channel::typing *weechat::channel::self_typing_search(weechat::user *us int weechat::channel::add_self_typing(weechat::user *user) { - weechat::channel::typing *new_typing; + weechat::channel::typing *the_typing; int ret = 0; - new_typing = self_typing_search(user); - if (!new_typing) + the_typing = weechat::channel::self_typing_search(user); + if (!the_typing) { - new_typing = new weechat::channel::typing(); - new_typing->user = user; - new_typing->name = user ? strdup(user->profile.display_name) : NULL; + weechat::channel::typing& new_typing = self_typings.emplace_back(); + new_typing.user = user; + new_typing.name = user ? user->profile.display_name : ""; + the_typing = &new_typing; ret = 1; } @@ -1111,7 +1117,9 @@ void weechat::channel::fetch_mam(const char *id, time_t *start, time_t *end, con xmpp_stanza_release(set); } else - account.add_mam_query(id, xmpp_stanza_get_id(iq), { *start }, { *end }); + account.add_mam_query(id, xmpp_stanza_get_id(iq), + start ? std::optional(*start) : std::optional(), + end ? std::optional(*end) : std::optional()); xmpp_stanza_add_child(iq, query); xmpp_stanza_release(query); diff --git a/channel.hh b/channel.hh index 1c432f5..71b531e 100644 --- a/channel.hh +++ b/channel.hh @@ -44,11 +44,8 @@ namespace weechat struct typing { - union { - char *id; - weechat::user *user; - }; - char *name; + weechat::user *user; + std::string name; time_t ts; }; @@ -132,7 +129,7 @@ namespace weechat void member_speaking_rename_if_present(const char *nick); static int typing_cb(const void *pointer, void *data, int remaining_calls); - typing *typing_search(const char *id); + typing *typing_search(weechat::user *user); int add_typing(weechat::user *user); static int self_typing_cb(const void *pointer, void *data, int remaining_calls); diff --git a/command.cpp b/command.cpp index 838740f..aab95dc 100644 --- a/command.cpp +++ b/command.cpp @@ -469,6 +469,10 @@ int command__enter(const void *pointer, void *data, std::make_pair(jid, weechat::channel { *ptr_account, weechat::channel::chat_type::MUC, jid, jid })).first->second; + if (!ptr_channel) { + weechat_string_free_split(jids); // raii unique_ptr? + return WEECHAT_RC_ERROR; + } pres = xmpp_presence_new(ptr_account->context); xmpp_stanza_set_to(pres, pres_jid); @@ -964,6 +968,29 @@ int command__xmpp(const void *pointer, void *data, return WEECHAT_RC_OK; } +int command__trap(const void *pointer, void *data, + struct t_gui_buffer *buffer, int argc, + char **argv, char **argv_eol) +{ + (void) pointer; + (void) data; + (void) buffer; + (void) argc; + (void) argv; + (void) argv_eol; + + weechat::account *account = NULL; + weechat::channel *channel = NULL; + weechat::user *user = NULL; + + buffer__get_account_and_channel(buffer, &account, &channel); + weechat::user::search(account, account->jid_device().data()); + + __asm("int3"); + + return WEECHAT_RC_OK; +} + void command__init() { struct t_hook *hook; @@ -1082,4 +1109,13 @@ void command__init() NULL, &command__xmpp, NULL, NULL); if (!hook) weechat_printf(NULL, "Failed to setup command /xmpp"); + + hook = weechat_hook_command( + "trap", + N_("debug trap (int3)"), + N_(""), + N_(""), + NULL, &command__trap, NULL, NULL); + if (!hook) + weechat_printf(NULL, "Failed to setup command /trap"); } diff --git a/config.cpp b/config.cpp index 29cf83f..a44944e 100644 --- a/config.cpp +++ b/config.cpp @@ -13,6 +13,8 @@ #include "account.hh" #include "config.hh" +// TODO: don't free file?! + bool account_read_cb(weechat::config_section& section, const char *option_name, const char *value) { diff --git a/config/file.hh b/config/file.hh index 088ced3..e802955 100644 --- a/config/file.hh +++ b/config/file.hh @@ -31,15 +31,15 @@ namespace weechat config_file(config& config, std::string name, std::function cb_reload) : config_file(weechat_config_new( name.data(), - [](const void *, void *data, struct t_config_file *config_file) { - auto& file = *reinterpret_cast(data); + [](const void *data, void *, struct t_config_file *config_file) { + auto& file = *reinterpret_cast(const_cast(data)); if (file != config_file) throw std::invalid_argument("file != config_file"); if (!file.reload) return 1; return file.reload() ? 1 : 0; // WEECHAT_CONFIG_READ_OK == 0 // WEECHAT_CONFIG_READ_MEMORY_ERROR == -1 // WEECHAT_CONFIG_READ_FILE_NOT_FOUND == -2 - }, nullptr, this), config, name) { + }, this, nullptr), config, name) { this->reload = std::bind(cb_reload, std::ref(*this)); } operator struct t_config_file *() { return get(); } diff --git a/config/option.hh b/config/option.hh index 8d0c2b2..1e63638 100644 --- a/config/option.hh +++ b/config/option.hh @@ -22,7 +22,7 @@ namespace weechat struct config_file; struct config_section; - struct config_option_free { void operator() (struct t_config_option *ptr) { /* weechat_config_option_free(ptr); */ } }; + struct config_option_free { void operator() (struct t_config_option *ptr) { weechat_config_option_free(ptr); } }; struct config_option : public std::unique_ptr, public config_breadcrumb { config_option(struct t_config_option *ptr, config_section& section, std::string name) : std::unique_ptr(ptr) @@ -40,22 +40,22 @@ namespace weechat config_file, section, name.data(), type, description, string_values, min, max, default_value, value, null_value_allowed, - [](const void *, void *data, struct t_config_option *opt, const char *value) { - auto& option = *reinterpret_cast(data); + [](const void *data, void *, struct t_config_option *opt, const char *value) { + auto& option = *reinterpret_cast(const_cast(data)); if (option != opt) throw std::invalid_argument("option != opt"); if (!option.check_value) return 1; return option.check_value(value) ? 1 : 0; - }, nullptr, this, - [](const void *, void *data, struct t_config_option *opt) { - auto& option = *reinterpret_cast(data); + }, this, nullptr, + [](const void *data, void *, struct t_config_option *opt) { + auto& option = *reinterpret_cast(const_cast(data)); if (option != opt) throw std::invalid_argument("option != opt"); if (option.on_changed) option.on_changed(); - }, nullptr, this, - [](const void *, void *data, struct t_config_option *opt) { - auto& option = *reinterpret_cast(data); + }, this, nullptr, + [](const void *data, void *, struct t_config_option *opt) { + auto& option = *reinterpret_cast(const_cast(data)); if (option != opt) throw std::invalid_argument("option != opt"); if (option.on_deleted) option.on_deleted(); - }, nullptr, this), section, name) { + }, this, nullptr), section, name) { if (cb_check_value) this->check_value = std::bind(cb_check_value, std::ref(*this), _1); if (cb_change) diff --git a/config/section.hh b/config/section.hh index b40fbec..a6e7267 100644 --- a/config/section.hh +++ b/config/section.hh @@ -24,7 +24,7 @@ namespace weechat struct config_section; struct config_option; - struct config_section_free { void operator() (struct t_config_section *ptr) { weechat_config_section_free(ptr); } }; + struct config_section_free { void operator() (struct t_config_section *ptr) { weechat_config_section_free(ptr); } }; struct config_section : public std::unique_ptr, public config_breadcrumb { config_section(struct t_config_section *ptr, config_file& file, std::string name) : std::unique_ptr(ptr) @@ -41,9 +41,9 @@ namespace weechat std::function cb_delete_option) : config_section(weechat_config_new_section( config_file, name.data(), user_can_add_options, user_can_delete_options, - [](const void *, void *data, struct t_config_file *config_file, + [](const void *data, void *, struct t_config_file *config_file, struct t_config_section *sect, const char *option_name, const char *value) { - auto& section = *reinterpret_cast(data); + auto& section = *reinterpret_cast(const_cast(data)); if (section != sect) throw std::invalid_argument("section != sect"); if (section.file != config_file) throw std::invalid_argument("section.file != config_file"); if (!section.read) return 1; @@ -57,30 +57,30 @@ namespace weechat // WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE == 1 // WEECHAT_CONFIG_OPTION_SET_ERROR == 0 // WEECHAT_CONFIG_OPTION_SET_OPTION_NOT_FOUND == -1 - }, nullptr, this, - [](const void *, void *data, struct t_config_file *config_file, + }, this, nullptr, + [](const void *data, void *, struct t_config_file *config_file, const char *section_name) { - auto& section = *reinterpret_cast(data); + auto& section = *reinterpret_cast(const_cast(data)); if (section.file != config_file) throw std::invalid_argument("section.file != config_file"); if (!section.write) return 0; return section.write(section_name) ? 0 : -1; // WEECHAT_CONFIG_WRITE_OK == 0 // WEECHAT_CONFIG_WRITE_ERROR == -1 // WEECHAT_CONFIG_WRITE_FILE_NOT_FOUND == -2 - }, nullptr, this, - [](const void *, void *data, struct t_config_file *config_file, + }, this, nullptr, + [](const void *data, void *, struct t_config_file *config_file, const char *section_name) { - auto& section = *reinterpret_cast(data); + auto& section = *reinterpret_cast(const_cast(data)); if (section.file != config_file) throw std::invalid_argument("section.file != config_file"); if (!section.write_default) return 0; return section.write_default(section_name) ? 0 : -1; // WEECHAT_CONFIG_WRITE_OK == 0 // WEECHAT_CONFIG_WRITE_ERROR == -1 // WEECHAT_CONFIG_WRITE_FILE_NOT_FOUND == -2 - }, nullptr, this, - [](const void *, void *data, struct t_config_file *config_file, + }, this, nullptr, + [](const void *data, void *, struct t_config_file *config_file, struct t_config_section *sect, const char *option_name, const char *value) { - auto& section = *reinterpret_cast(data); + auto& section = *reinterpret_cast(const_cast(data)); if (section != sect) throw std::invalid_argument("section != sect"); if (section.file != config_file) throw std::invalid_argument("section.file != config_file"); if (!section.create_option) return 1; @@ -89,10 +89,10 @@ namespace weechat // WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE == 1 // WEECHAT_CONFIG_OPTION_SET_ERROR == 0 // WEECHAT_CONFIG_OPTION_SET_OPTION_NOT_FOUND == -1 - }, nullptr, this, - [](const void *, void *data, struct t_config_file *config_file, + }, this, nullptr, + [](const void *data, void *, struct t_config_file *config_file, struct t_config_section *sect, struct t_config_option *opt) { - auto& section = *reinterpret_cast(data); + auto& section = *reinterpret_cast(const_cast(data)); if (section != sect) throw std::invalid_argument("section != sect"); if (section.file != config_file) throw std::invalid_argument("section.file != config_file"); if (!section.delete_option) return 0; @@ -103,7 +103,7 @@ namespace weechat // WEECHAT_CONFIG_OPTION_UNSET_OK_RESET == 1 // WEECHAT_CONFIG_OPTION_UNSET_OK_REMOVED == 2 // WEECHAT_CONFIG_OPTION_UNSET_ERROR == -1 - }, nullptr, this), config_file, name) { + }, this, nullptr), config_file, name) { if (cb_read) this->read = std::bind(cb_read, std::ref(*this), _1, _2); if (cb_write) diff --git a/connection.cpp b/connection.cpp index 004dbed..3e930c6 100644 --- a/connection.cpp +++ b/connection.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -1128,7 +1127,7 @@ bool weechat::connection::iq_handler(xmpp_stanza_t *stanza) xmpp_stanza_release(children[0]); } - if (account.jid() == from) + if (from && account.jid() == from) { weechat::account::device dev; char id[64] = {0}; diff --git a/deps/fmt b/deps/fmt deleted file mode 160000 index 9a1beab..0000000 --- a/deps/fmt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9a1beab5747d5afadcc4d29bf8fe50f119484a5d diff --git a/input.cpp b/input.cpp index 628d429..d8e2e66 100644 --- a/input.cpp +++ b/input.cpp @@ -70,7 +70,7 @@ int input__typing(struct t_gui_buffer *buffer) if (account && account->connected() && channel) { channel->send_reads(); - channel->send_typing(NULL); + channel->send_typing(weechat::user::search(account, account->jid_device().data())); } return WEECHAT_RC_OK; diff --git a/makefile b/makefile index 4ff9690..05b7552 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ endif RM ?= rm -f FIND ?= find -INCLUDES=-Ilibstrophe -Ideps -Ideps/optional/include -Ideps/fmt/include \ +INCLUDES=-Ilibstrophe -Ideps \ $(shell xml2-config --cflags) \ $(shell pkg-config --cflags gpgme) \ $(shell pkg-config --cflags libsignal-protocol-c) @@ -20,12 +20,12 @@ CFLAGS+=$(DBGCFLAGS) \ -Wno-missing-field-initializers \ -D_XOPEN_SOURCE=700 \ $(INCLUDES) -ifeq ($(CC),gcc) - CFLAGS+= -fkeep-inline-functions -else ifeq ($(CC),clang) +ifeq ($(CC),clang) CFLAGS+= +else + CFLAGS+= -fkeep-inline-functions endif -CPPFLAGS+=$(DBGCFLAGS) -O0 \ +CPPFLAGS+=$(DBGCFLAGS) \ -fno-omit-frame-pointer -fPIC \ -fvisibility=hidden -fvisibility-inlines-hidden \ -std=c++23 -gdwarf-4 \ @@ -33,13 +33,14 @@ CPPFLAGS+=$(DBGCFLAGS) -O0 \ -Wno-missing-field-initializers \ $(INCLUDES) # -DDOCTEST_CONFIG_DISABLE -ifeq ($(CXX),g++) - CPPFLAGS+= -fkeep-inline-functions -else ifeq ($(CXX),clang) +ifeq ($(CXX),clang) CPPFLAGS+= +else + CPPFLAGS+= -fkeep-inline-functions endif LDFLAGS+=$(DBGLDFLAGS) \ - -shared -gdwarf-4 \ + -gdwarf-4 \ + -fuse-ld=mold \ $(DBGCFLAGS) LDLIBS=-lstrophe \ -lpthread \ @@ -47,7 +48,7 @@ LDLIBS=-lstrophe \ $(shell pkg-config --libs gpgme) \ $(shell pkg-config --libs libsignal-protocol-c) \ -lgcrypt \ - -llmdb -lfl + -llmdb -lfl -lfmt PREFIX ?= /usr/local LIBDIR ?= $(PREFIX)/lib @@ -99,7 +100,6 @@ SRCS=plugin.cpp \ xmpp/node.cpp \ DEPS=deps/diff/libdiff.a \ - deps/fmt/libfmt.a \ sexp/sexp.a \ OBJS=$(patsubst %.cpp,.%.o,$(patsubst %.c,.%.o,$(patsubst config/%.cpp,config/.%.o,$(patsubst xmpp/%.cpp,xmpp/.%.o,$(SRCS))))) @@ -119,7 +119,7 @@ release: xmpp.so ln -sf .xmpp.so.$(SUFFIX) .xmpp.so xmpp.so: $(DEPS) $(OBJS) $(HDRS) - $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(DEPS) $(LDLIBS) + $(CXX) -shared $(LDFLAGS) -o $@ -Wl,--as-needed $(OBJS) $(DEPS) $(LDLIBS) git ls-files | xargs ls -d | xargs tar cz | objcopy --add-section .source=/dev/stdin xmpp.so #objcopy --dump-section .source=/dev/stdout xmpp.so | tar tz @@ -146,46 +146,40 @@ sexp/driver.o: sexp/driver.cpp $(CXX) -DGIT_COMMIT=$(GIT_REF) $(CPPFLAGS) -c $< -o $@ .%.cov.o: %.cpp - @$(CXX) --coverage $(CPPFLAGS) -O0 -c $< -o $@ + @$(CXX) --coverage $(CPPFLAGS) -c $< -o $@ config/.%.o: config/%.cpp $(CXX) $(CPPFLAGS) -c $< -o $@ config/.%.cov.o: config/%.cpp - @$(CXX) --coverage $(CPPFLAGS) -O0 -c $< -o $@ + @$(CXX) --coverage $(CPPFLAGS) -c $< -o $@ xmpp/.%.o: xmpp/%.cpp $(CXX) $(CPPFLAGS) -c $< -o $@ xmpp/.%.cov.o: xmpp/%.cpp - @$(CXX) --coverage $(CPPFLAGS) -O0 -c $< -o $@ + @$(CXX) --coverage $(CPPFLAGS) -c $< -o $@ -.PHONY: diff fmt +.PHONY: diff deps/diff/libdiff.a: - git submodule update --init --recursive + git submodule update --init --recursive deps/diff cd deps/diff && env -u MAKEFLAGS ./configure $(MAKE) -C deps/diff CFLAGS=-fPIC diff: deps/diff/libdiff.a -deps/fmt/libfmt.a: - git submodule update --init --recursive - env -u MAKEFLAGS cmake -S deps/fmt -B deps/fmt \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON - $(MAKE) -C deps/fmt fmt -fmt: deps/fmt/libfmt.a tests/xmpp.cov.so: $(COVS) $(DEPS) $(HDRS) - $(CXX) --coverage -O0 $(LDFLAGS) -o tests/xmpp.cov.so $(COVS) $(DEPS) $(LDLIBS) -lstdc++ + $(CXX) --coverage -shared $(LDFLAGS) -o tests/xmpp.cov.so -Wl,--as-needed $(DEPS) $(LDLIBS) $(COVS) -tests/run: $(COVS) tests/main.cc tests/xmpp.cov.so - env --chdir tests $(CXX) $(CPPFLAGS) -o run ./xmpp.cov.so main.cc $(LDLIBS) +tests/run: $(COVS) tests/main.cc tests/xmpp.cov.so $(wildcard tests/*.inl) + env --chdir tests $(CXX) $(CPPFLAGS) $(LDFLAGS) -o run -Wl,--as-needed ./xmpp.cov.so main.cc $(patsubst %,../%,$(DEPS)) $(LDLIBS) -lstdc++ .PHONY: test test: tests/run - env --chdir tests ./run -s + env --chdir tests ./run -sm .PHONY: coverage coverage: tests/run - gcov -m -abcfu -rqk -i .*.gcda config/.*.gcda xmpp/.*.gcda + gcovr --txt -s .PHONY: debug debug: xmpp.so @@ -196,16 +190,22 @@ debug: xmpp.so depend: $(DEPS) $(SRCS) $(HDRS) $(RM) -f ./.depend echo > ./.depend - for src in $(SRCS) ; do \ + for src in $(SRCS) tests/main.cc; do \ + dir="$$(dirname $$src)"; \ + src="$$(basename $$src)"; \ if [[ $$src == *.cpp ]]; then \ + echo "g++ $(CPPFLAGS) -MM -MMD -MP -MF - \ + -MT $$dir/.$${src/.cpp/.o} $$dir/$$src >> ./.depend"; \ g++ $(CPPFLAGS) -MM -MMD -MP -MF - \ - -MT .$${src/.cpp/.o} $$src >> ./.depend || true ; \ + -MT $$dir/.$${src/.cpp/.o} $$dir/$$src >> ./.depend || true ; \ elif [[ $$src == *.c ]]; then \ + echo "gcc $(CFLAGS) -MM -MMD -MP -MF - \ + -MT $$dir/.$${src/.c/.o} $$dir/$$src >> ./.depend"; \ gcc $(CFLAGS) -MM -MMD -MP -MF - \ - -MT .$${src/.c/.o} $$src >> ./.depend || true ; \ - fi \ + -MT $$dir/.$${src/.c/.o} $$dir/$$src >> ./.depend || true ; \ + else continue; \ + fi; \ done - sed -i 's/\.\([a-z]*\/\)/\1./' .depend .PHONY: tidy tidy: @@ -214,14 +214,13 @@ tidy: $(FIND) . -name "*.gcda" -delete .PHONY: clean -clean: +clean: tidy $(RM) -f $(OBJS) $(COVS) \ sexp/parser.tab.cc sexp/parser.tab.hh \ sexp/location.hh sexp/position.hh \ sexp/stack.hh sexp/parser.output sexp/parser.o \ sexp/lexer.o sexp/lexer.yy.cc sexp/sexp.a $(MAKE) -C deps/diff clean || true - $(MAKE) -C deps/fmt clean || true git submodule foreach --recursive git clean -xfd || true git submodule foreach --recursive git reset --hard || true diff --git a/plugin.cpp b/plugin.cpp index ee1512d..4f4c562 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include "plugin.hh" @@ -19,11 +19,8 @@ #include "buffer.hh" #include "completion.hh" -struct t_weechat_plugin *weechat_xmpp_plugin = NULL; - -struct t_hook *weechat_xmpp_process_timer = NULL; - -struct t_gui_bar_item *weechat_xmpp_typing_bar_item = NULL; +#define WEECHAT_TIMER_INTERVAL_SEC 0.01 +#define WEECHAT_TIMER_SECONDS(IVL) (WEECHAT_TIMER_INTERVAL_SEC * IVL) #pragma GCC visibility push(default) extern "C" { @@ -35,73 +32,109 @@ WEECHAT_PLUGIN_LICENSE("MPL2"); WEECHAT_PLUGIN_PRIORITY(5500); } +void (* weechat_signal_handler)(int); + extern "C" -void weechat_signal_handler(int) -{ +void wrapped_signal_handler(int arg) +{ // wrap weechat's handler + weechat_signal_handler(arg); __asm__("int3"); } extern "C" int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]) { - (void) argc; - (void) argv; - - std::signal(SIGSEGV, weechat_signal_handler); + try { + weechat::plugin::instance = std::make_unique(plugin); + weechat::plugin::instance->init(argc, argv); + } + catch (std::exception const& ex) { + return WEECHAT_RC_ERROR; + } - weechat_xmpp_plugin = plugin; + return WEECHAT_RC_OK; +} - if (!weechat::config::init()) +extern "C" +int weechat_plugin_end(struct t_weechat_plugin *plugin) +{ + try { + if (plugin != *weechat::plugin::instance) + throw std::runtime_error("wrong plugin?"); + weechat::plugin::instance->end(); + weechat::plugin::instance.reset(); + } + catch (std::exception const& ex) { return WEECHAT_RC_ERROR; + } + + return WEECHAT_RC_OK; +} + +std::unique_ptr weechat::plugin::instance; + +weechat::plugin::plugin(struct t_weechat_plugin *plugin) + : m_plugin_ptr(plugin) +{ +} + +void weechat::plugin::init(int argc, char *argv[]) +{ + m_args = std::vector(argv, argv+argc); + + if (std::find(m_args.begin(), m_args.end(), "debug") != m_args.end()) + weechat_signal_handler = std::signal(SIGSEGV, wrapped_signal_handler); + + if (!weechat::config::init()) // TODO: bool -> exceptions + throw std::runtime_error("Config init failed"); weechat::config::read(); weechat::connection::init(); - command__init(); + command__init(); // TODO: port - completion__init(); + completion__init(); // TODO: port - weechat_xmpp_process_timer = weechat_hook_timer(TIMER_INTERVAL_SEC * 1000, 0, 0, - &weechat::account::timer_cb, - NULL, NULL); + m_process_timer = weechat_hook_timer(WEECHAT_TIMER_SECONDS(1000), 0, 0, + &weechat::account::timer_cb, + nullptr, nullptr); - if (!weechat_bar_search("typing")) + if (!weechat_bar_search(typing_bar_name.data())) { - weechat_bar_new("typing", "off", "400", "window", "${typing}", + weechat_bar_new(typing_bar_name.data(), "off", "400", "window", "${typing}", "bottom", "horizontal", "vertical", "1", "1", "default", "default", "default", "default", - "off", "xmpp_typing"); + "off", typing_bar_item_name.data()); } - weechat_xmpp_typing_bar_item = weechat_bar_item_new("xmpp_typing", - &buffer__typing_bar_cb, - NULL, NULL); - - weechat_hook_signal("input_text_changed", &input__text_changed_cb, NULL, NULL); + m_typing_bar_item = weechat_bar_item_new(typing_bar_item_name.data(), + &buffer__typing_bar_cb, // TODO: port + nullptr, nullptr); - return WEECHAT_RC_OK; + weechat_hook_signal("input_text_changed", + &input__text_changed_cb, // TODO: port + nullptr, nullptr); } -extern "C" -int weechat_plugin_end(struct t_weechat_plugin *plugin) -{ - // make C compiler happy - (void) plugin; - - if (weechat_xmpp_typing_bar_item) - weechat_bar_item_remove(weechat_xmpp_typing_bar_item); +void weechat::plugin::end() { + if (m_typing_bar_item) // raii? + weechat_bar_item_remove(m_typing_bar_item); - if (weechat_xmpp_process_timer) - weechat_unhook(weechat_xmpp_process_timer); + if (m_process_timer) // raii? + weechat_unhook(m_process_timer); weechat::config::write(); + weechat::config::instance.reset(); + weechat::account::disconnect_all(); weechat::accounts.clear(); - xmpp_shutdown(); + libstrophe::shutdown(); +} - return WEECHAT_RC_OK; +weechat::plugin::~plugin() +{ } diff --git a/plugin.hh b/plugin.hh index fc9a09d..8924f56 100644 --- a/plugin.hh +++ b/plugin.hh @@ -4,10 +4,17 @@ #pragma once +#include +#include + +#include "strophe.hh" + #define STR(X) #X #define XSTR(X) STR(X) -#define weechat_plugin weechat_xmpp_plugin + +#define weechat_plugin (&*weechat::plugin::instance->ptr()) #define WEECHAT_XMPP_PLUGIN_NAME "xmpp" + #ifdef GIT_COMMIT #define XMPP_PLUGIN_COMMIT XSTR(GIT_COMMIT) #define WEECHAT_XMPP_PLUGIN_VERSION "0.2.1@" XMPP_PLUGIN_COMMIT @@ -15,6 +22,31 @@ #define XMPP_PLUGIN_COMMIT "unknown" #define WEECHAT_XMPP_PLUGIN_VERSION "0.2.1" #endif//GIT_COMMIT -#define TIMER_INTERVAL_SEC 0.01 -extern struct t_weechat_plugin *weechat_xmpp_plugin; +namespace weechat { + class plugin { + private: + struct t_weechat_plugin *m_plugin_ptr; // packed first for hackery + + public: + plugin(struct t_weechat_plugin *plugin_ptr); + virtual ~plugin(); + + void init(int argc, char *argv[]); + void end(); + + static std::unique_ptr instance; + + inline struct t_weechat_plugin * ptr() { return m_plugin_ptr; }; + inline operator struct t_weechat_plugin *() { return m_plugin_ptr; }; + + private: + static constexpr std::string_view typing_bar_name = "typing"; + static constexpr std::string_view typing_bar_item_name = "xmpp_typing"; + + struct t_hook *m_process_timer; + struct t_gui_bar_item *m_typing_bar_item; + + std::vector m_args; + }; +}; diff --git a/strophe.hh b/strophe.hh index 07d16a4..e6e9d91 100644 --- a/strophe.hh +++ b/strophe.hh @@ -83,6 +83,7 @@ namespace libstrophe { }; inline auto initialize = xmpp_initialize; + inline auto shutdown = xmpp_shutdown; typedef type +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include "../deps/fdstream.hpp" #include "../plugin.hh" +std::vector weechat_read_lines(std::vector commands, bool echo = false) { + std::ostringstream args; + for (std::string_view arg : commands) { + args << arg << ';'; + } + + std::string invocation("timeout 5 weechat-headless --stdout -a -t -P buflist,relay,python -r '" + args.str() + "/quit'"); + FILE *pipe = popen(invocation.data(), "r"); + CHECK(pipe != nullptr); + + boost::fdistream pipestream(fileno(pipe)); + std::vector output; + for (std::string line; std::getline(pipestream, line); line.clear()) { + output.push_back(line); + } + + int exitcode = 0; + SUBCASE("unloads successfully") + { + /* thread-unsafe inside block */ { + int status = pclose(pipe); + if (WIFEXITED(status)) + exitcode = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) { + const char *signal = strsignal(WTERMSIG(status)); + throw std::runtime_error(signal); + } + } + + CHECK(exitcode == 0); + } + + CHECK(output.size() > 0); + + if (echo) { + std::cerr << "weechat (" << exitcode << "): " << args.str() << std::endl; + for (std::string line : output) { + std::cerr << line << std::endl; + } + } + + return output; +} + TEST_CASE("weechat") { - std::string current("20220312-01"); + std::string plugin_api_version("20220926-01"); SUBCASE("plugin api match") { - CHECK(current == WEECHAT_PLUGIN_API_VERSION); + CHECK(plugin_api_version == WEECHAT_PLUGIN_API_VERSION); + } + + SUBCASE("launches") + { + std::vector output = weechat_read_lines({ + "/print -stdout -escape TEST_OK\\n", + }, true); + + bool recieved_ok = std::find_if(output.begin(), output.end(), [](std::string& line){ + return line.find("TEST_OK") != std::string::npos; + }) != output.end(); + CHECK(recieved_ok); + } + + SUBCASE("plugin loads") + { + SUBCASE("without incursion") + { + const std::regex line_pattern("\\[[^\\]]*\\]\\s*line \\d*: (.*)"); + + std::vector output = weechat_read_lines({ + "/plugin load ../xmpp.so", + "/print -stdout -escape TEST_BufferStart\\n", + "/debug buffer", + "/print -stdout -escape TEST_BufferEnd\\n", + "/plugin listfull", + }, false); + + std::vector buffer; + + auto it = output.begin(); + while (it != output.end() && it->find("TEST_BufferStart") != std::string::npos) { + it++; + } + + while (it != output.end() && it->find("TEST_BufferEnd") == std::string::npos) { + std::string& line = *it++; + + std::smatch match; + if (std::regex_match(line, match, line_pattern, std::regex_constants::match_default)) { + buffer.push_back(match[1]); + } + } + + for (std::string line : buffer) { + std::cerr << line << std::endl; + } + + bool plugin_loaded = std::find_if(buffer.begin(), buffer.end(), [](std::string& line){ + return line.find("Plugin \"xmpp\" loaded") != std::string::npos; + }) != buffer.end(); + CHECK(plugin_loaded); + } } }