the aspect manouvre

master
bqv 2 years ago
parent afedd306ea
commit 5c3305976c
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -1,19 +1,23 @@
.plugin.o: plugin.cpp plugin.hh config.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.plugin.o: plugin.cpp plugin.hh config.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h \
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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 connection.hh command.hh input.hh buffer.hh \
completion.hh
/usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh \
strophe.hh user.hh command.hh input.hh buffer.hh completion.hh
plugin.hh:
config.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
account.hh:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -23,19 +27,23 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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:
.account.o: account.cpp /usr/include/libxml2/libxml/xmlwriter.h \
.account.o: account.cpp deps/fmt/include/fmt/core.h \
/usr/include/libxml2/libxml/xmlwriter.h \
/usr/include/libxml2/libxml/xmlversion.h \
/usr/include/libxml2/libxml/xmlexports.h \
/usr/include/libxml2/libxml/xmlIO.h \
@ -53,18 +61,18 @@ completion.hh:
/usr/include/libxml2/libxml/SAX2.h /usr/include/libxml2/libxml/xlink.h \
/usr/include/libxml2/libxml/xmlmemory.h \
/usr/include/libxml2/libxml/threads.h plugin.hh xmpp/stanza.hh config.hh \
input.hh omemo.hh /usr/include/signal/signal_protocol.h \
/usr/include/signal/ratchet.h \
deps/optional/include/tl/optional.hpp 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 account.hh connection.hh user.hh \
deps/optional/include/tl/optional.hpp channel.hh buffer.hh
/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:
/usr/include/libxml2/libxml/xmlwriter.h:
/usr/include/libxml2/libxml/xmlversion.h:
/usr/include/libxml2/libxml/xmlexports.h:
@ -89,6 +97,7 @@ completion.hh:
plugin.hh:
xmpp/stanza.hh:
config.hh:
deps/optional/include/tl/optional.hpp:
input.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
@ -99,7 +108,6 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/usr/include/signal/key_helper.h:
/usr/include/signal/session_builder.h:
/usr/include/signal/session_cipher.h:
@ -107,24 +115,31 @@ deps/fmt/include/fmt/core.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:
deps/optional/include/tl/optional.hpp:
channel.hh:
buffer.hh:
.buffer.o: buffer.cpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.buffer.o: buffer.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 buffer.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh buffer.hh
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -134,18 +149,23 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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.hh:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
buffer.hh:
.channel.o: channel.cpp deps/fmt/include/fmt/core.h \
deps/optional/include/tl/optional.hpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
deps/optional/include/tl/optional.hpp plugin.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 \
@ -153,14 +173,15 @@ buffer.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 user.hh channel.hh input.hh buffer.hh pgp.hh \
util.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
/usr/include/signal/curve.h config.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:
deps/optional/include/tl/optional.hpp:
plugin.hh:
account.hh:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -176,15 +197,17 @@ signal.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/protocol.h:
/usr/include/signal/curve.h:
user.hh:
config.hh:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
input.hh:
buffer.hh:
pgp.hh:
util.hh:
xmpp/node.hh:
xmpp/xep-0027.inl:
xmpp/ns.hh:
xmpp/xep-0030.inl:
xmpp/xep-0045.inl:
xmpp/xep-0049.inl:
@ -192,22 +215,25 @@ xmpp/xep-0115.inl:
xmpp/xep-0280.inl:
xmpp/xep-0319.inl:
xmpp/rfc-6121.inl:
.command.o: command.cpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.command.o: command.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 user.hh \
deps/optional/include/tl/optional.hpp channel.hh buffer.hh message.hh \
command.hh sexp/driver.hh sexp/scanner.hh sexp/parser.tab.hh \
sexp/location.hh
/usr/include/signal/curve.h config.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
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -217,16 +243,18 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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:
user.hh:
deps/optional/include/tl/optional.hpp:
config.hh:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
buffer.hh:
message.hh:
command.hh:
@ -234,21 +262,25 @@ sexp/driver.hh:
sexp/scanner.hh:
sexp/parser.tab.hh:
sexp/location.hh:
.completion.o: completion.cpp plugin.hh config.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.completion.o: completion.cpp plugin.hh config.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h \
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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 user.hh \
deps/optional/include/tl/optional.hpp buffer.hh completion.hh
/usr/include/signal/curve.h channel.hh connection.hh xmpp/ns.hh \
strophe.hh user.hh buffer.hh completion.hh
plugin.hh:
config.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
account.hh:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -258,7 +290,6 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/usr/include/signal/key_helper.h:
/usr/include/signal/session_builder.h:
/usr/include/signal/session_cipher.h:
@ -266,23 +297,30 @@ deps/fmt/include/fmt/core.h:
/usr/include/signal/protocol.h:
/usr/include/signal/curve.h:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
deps/optional/include/tl/optional.hpp:
buffer.hh:
completion.hh:
.config.o: config.cpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.config.o: config.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -292,7 +330,6 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/usr/include/signal/key_helper.h:
/usr/include/signal/session_builder.h:
/usr/include/signal/session_cipher.h:
@ -300,6 +337,11 @@ deps/fmt/include/fmt/core.h:
/usr/include/signal/protocol.h:
/usr/include/signal/curve.h:
config.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 \
@ -324,8 +366,8 @@ config.hh:
deps/optional/include/tl/optional.hpp 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 account.hh omemo.hh /usr/include/signal/signal_protocol.h \
/usr/include/signal/ratchet.h \
config.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 \
@ -333,7 +375,7 @@ config.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 user.hh channel.hh connection.hh pgp.hh \
/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:
@ -375,6 +417,7 @@ xmpp/rfc-6121.inl:
xmpp/stanza.hh:
config.hh:
account.hh:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -390,25 +433,30 @@ signal.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/protocol.h:
/usr/include/signal/curve.h:
user.hh:
channel.hh:
connection.hh:
pgp.hh:
strophe.hh:
user.hh:
util.hh:
deps/diff/diff.h:
.input.o: input.cpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.input.o: input.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 buffer.hh message.hh input.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh buffer.hh message.hh input.hh
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -418,31 +466,39 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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.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 omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.message.o: message.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 user.hh \
deps/optional/include/tl/optional.hpp message.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh message.hh
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -452,16 +508,18 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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.hh:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
deps/optional/include/tl/optional.hpp:
message.hh:
.omemo.o: omemo.cpp deps/fmt/include/fmt/core.h \
deps/optional/include/tl/optional.hpp \
@ -738,7 +796,7 @@ message.hh:
deps/range-v3/include/range/v3/view/trim.hpp \
deps/range-v3/include/range/v3/view/unbounded.hpp \
deps/range-v3/include/range/v3/view/unique.hpp plugin.hh xmpp/stanza.hh \
account.hh omemo.hh /usr/include/signal/signal_protocol.h \
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 \
@ -747,7 +805,8 @@ message.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 gcrypt.hh util.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh gcrypt.hh util.hh
deps/fmt/include/fmt/core.h:
deps/optional/include/tl/optional.hpp:
deps/range-v3/include/range/v3/all.hpp:
@ -1026,6 +1085,7 @@ deps/range-v3/include/range/v3/view/unique.hpp:
plugin.hh:
xmpp/stanza.hh:
account.hh:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -1041,26 +1101,36 @@ signal.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/protocol.h:
/usr/include/signal/curve.h:
config.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:
plugin.hh:
pgp.hh:
.user.o: user.cpp plugin.hh account.hh omemo.hh \
/usr/include/signal/signal_protocol.h /usr/include/signal/ratchet.h \
.user.o: user.cpp plugin.hh account.hh \
deps/optional/include/tl/optional.hpp deps/fmt/include/fmt/core.h 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 \
/usr/include/signal/sender_key_record.h signal.hh \
deps/fmt/include/fmt/core.h /usr/include/signal/key_helper.h \
/usr/include/signal/session_builder.h \
/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 user.hh \
deps/optional/include/tl/optional.hpp channel.hh
/usr/include/signal/curve.h config.hh channel.hh connection.hh \
xmpp/ns.hh strophe.hh user.hh
plugin.hh:
account.hh:
deps/optional/include/tl/optional.hpp:
deps/fmt/include/fmt/core.h:
pgp.hh:
omemo.hh:
/usr/include/signal/signal_protocol.h:
/usr/include/signal/ratchet.h:
@ -1070,16 +1140,18 @@ omemo.hh:
/usr/include/signal/session_pre_key.h:
/usr/include/signal/sender_key_record.h:
signal.hh:
deps/fmt/include/fmt/core.h:
/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:
user.hh:
deps/optional/include/tl/optional.hpp:
config.hh:
channel.hh:
connection.hh:
xmpp/ns.hh:
strophe.hh:
user.hh:
.util.o: util.cpp plugin.hh util.hh
plugin.hh:
util.hh:

@ -4,7 +4,17 @@
((c-mode
(eval . (setq-local flycheck-clang-include-path
(list (expand-file-name "libstrophe" (projectile-project-root))
(expand-file-name "json-c" (projectile-project-root)))))
(expand-file-name "json-c" (projectile-project-root))
(string-trim-right
(substring
(shell-command-to-string "xml2-config --cflags") 2))
(string-trim-right
(substring
(shell-command-to-string "pkg-config --cflags libsignal-protocol-c") 2))
"/usr/include/libxml2/" "/usr/include/signal"
(expand-file-name "deps/fmt/include" (projectile-project-root))
(expand-file-name "deps/optional/include" (projectile-project-root))
(expand-file-name "deps/range-v3/include" (projectile-project-root)))))
(eval . (setq-local company-clang-arguments
(list (concat "-I" (expand-file-name "libstrophe" (projectile-project-root)))
(concat "-I" (expand-file-name "json-c" (projectile-project-root))))))
@ -17,6 +27,6 @@
"'; /debug tags"))
" ")))
(flycheck-clang-warnings . ("all" "extra" "error-implicit-function-declaration" "no-missing-field-initializers"))
(flycheck-clang-language-standard . "gnu99")
(flycheck-clang-language-standard . "c++20")
(flycheck-checker . c/c++-clang)
(projectile-project-compilation-cmd . "bear -- make -j8")))

1
.gitignore vendored

@ -1,6 +1,7 @@
.direnv
*~
compile_commands.json
launch.json
.cache
cscope*
*.d

@ -8,6 +8,7 @@
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <fmt/core.h>
#include <libxml/xmlwriter.h>
#include <weechat/weechat-plugin.h>
@ -22,291 +23,12 @@
#include "channel.hh"
#include "buffer.hh"
std::unordered_map<std::string, struct t_account *> accounts;
char *account_options[ACCOUNT_NUM_OPTIONS][2] =
{ { (char*)"jid", (char*)"" },
{ (char*)"password", (char*)"" },
{ (char*)"tls", (char*)"normal" },
{ (char*)"nickname", (char*)"" },
{ (char*)"autoconnect", (char*)"" },
{ (char*)"resource", (char*)"" },
{ (char*)"status", (char*)"probably about to segfault" },
{ (char*)"pgp_path", (char*)"" },
{ (char*)"pgp_keyid", (char*)"" },
};
struct t_account *account__search(const char *name)
{
if (!name)
return NULL;
auto ptr_account = accounts.find(name);
if (ptr_account != accounts.end())
{
return ptr_account->second;
}
/* account not found */
return NULL;
}
struct t_account *account__casesearch(const char *name)
{
if (!name)
return NULL;
for (auto ptr_account : accounts)
{
if (weechat_strcasecmp(ptr_account.second->name, name) == 0)
return ptr_account.second;
}
/* account not found */
return NULL;
}
int account__search_option(const char *option_name)
{
int i;
if (!option_name)
return -1;
for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
{
if (weechat_strcasecmp(account_options[i][0], option_name) == 0)
return i;
}
/* account option not found */
return -1;
}
struct t_account_device *account__search_device(struct t_account *account, uint32_t id)
{
struct t_account_device *ptr_device;
if (!account)
return NULL;
for (ptr_device = account->devices; ptr_device;
ptr_device = ptr_device->next_device)
{
if (ptr_device->id == id)
return ptr_device;
}
return NULL;
}
void account__add_device(struct t_account *account,
struct t_account_device *device)
{
struct t_account_device *new_device;
new_device = account__search_device(account, device->id);
if (!new_device)
{
new_device = new struct t_account_device;
new_device->id = device->id;
new_device->name = strdup(device->name);
new_device->label = device->label ? strdup(device->label) : NULL;
new_device->prev_device = account->last_device;
new_device->next_device = NULL;
if (account->last_device)
(account->last_device)->next_device = new_device;
else
account->devices = new_device;
account->last_device = new_device;
}
}
void account__free_device(struct t_account *account, struct t_account_device *device)
{
struct t_account_device *new_devices;
if (!account || !device)
return;
/* remove device from devices list */
if (account->last_device == device)
account->last_device = device->prev_device;
if (device->prev_device)
{
(device->prev_device)->next_device = device->next_device;
new_devices = account->devices;
}
else
new_devices = device->next_device;
if (device->next_device)
(device->next_device)->prev_device = device->prev_device;
/* free device data */
if (device->label)
free(device->label);
if (device->name)
free(device->name);
delete device;
account->devices = new_devices;
}
std::unordered_map<std::string, weechat::account> weechat::accounts;
void account__free_device_all(struct t_account *account)
void weechat::log_emit(void *const userdata, const xmpp_log_level_t level,
const char *const area, const char *const msg)
{
while (account->devices)
account__free_device(account, account->devices);
}
xmpp_stanza_t *account__get_devicelist(struct t_account *account)
{
xmpp_stanza_t *parent, **children;
struct t_account_device *device;
const char *ns, *node;
char id[64] = {0};
int i = 0;
device = new struct t_account_device;
device->id = account->omemo.device_id;
snprintf(id, sizeof(id), "%u", device->id);
device->name = strdup(id);
device->label = strdup("weechat");
children = (xmpp_stanza_t **)malloc(sizeof(xmpp_stanza_t *) * 128);
children[i++] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(device->name), NULL);
free(device->label);
free(device->name);
delete device;
for (device = account->devices; device;
device = device->next_device)
{
if (device->id != account->omemo.device_id)
children[i++] = stanza__iq_pubsub_publish_item_list_device(
account->context, NULL, with_noop(device->name), NULL);
}
children[i] = NULL;
node = "eu.siacs.conversations.axolotl";
children[0] = stanza__iq_pubsub_publish_item_list(
account->context, NULL, children, with_noop(node));
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item(
account->context, NULL, children, with_noop("current"));
node = "eu.siacs.conversations.axolotl.devicelist";
children[0] = stanza__iq_pubsub_publish(account->context,
NULL, children,
with_noop(node));
ns = "http://jabber.org/protocol/pubsub";
children[0] = stanza__iq_pubsub(account->context, NULL,
children, with_noop(ns));
parent = stanza__iq(account->context, NULL,
children, NULL, strdup("announce1"),
NULL, NULL, strdup("set"));
free(children);
return parent;
}
struct t_account_mam_query *account__add_mam_query(struct t_account *account,
struct t_channel *channel,
const char *id,
time_t *start, time_t *end)
{
struct t_account_mam_query *mam_query;
if (!(mam_query = account__mam_query_search(account, id)))
{
mam_query = (struct t_account_mam_query*)malloc(sizeof(struct t_account_mam_query));
mam_query->id = strdup(id);
mam_query->with = strdup(channel->id);
mam_query->has_start = start != NULL;
if (mam_query->has_start)
mam_query->start = *start;
mam_query->has_end = end != NULL;
if (mam_query->has_end)
mam_query->end = *end;
mam_query->prev_mam_query = account->last_mam_query;
mam_query->next_mam_query = NULL;
if (account->last_mam_query)
(account->last_mam_query)->next_mam_query = mam_query;
else
account->mam_queries = mam_query;
account->last_mam_query = mam_query;
}
return mam_query;
}
struct t_account_mam_query *account__mam_query_search(struct t_account *account,
const char *id)
{
struct t_account_mam_query *ptr_mam_query;
if (!account || !id)
return NULL;
for (ptr_mam_query = account->mam_queries; ptr_mam_query;
ptr_mam_query = ptr_mam_query->next_mam_query)
{
if (weechat_strcasecmp(ptr_mam_query->id, id) == 0)
return ptr_mam_query;
}
return NULL;
}
void account__mam_query_free(struct t_account *account,
struct t_account_mam_query *mam_query)
{
struct t_account_mam_query *new_mam_queries;
if (!account || !mam_query)
return;
/* remove mam_query from mam_queries list */
if (account->last_mam_query == mam_query)
account->last_mam_query = mam_query->prev_mam_query;
if (mam_query->prev_mam_query)
{
(mam_query->prev_mam_query)->next_mam_query = mam_query->next_mam_query;
new_mam_queries = account->mam_queries;
}
else
new_mam_queries = mam_query->next_mam_query;
if (mam_query->next_mam_query)
(mam_query->next_mam_query)->prev_mam_query = mam_query->prev_mam_query;
/* free mam_query data */
if (mam_query->id)
free(mam_query->id);
if (mam_query->with)
free(mam_query->with);
free(mam_query);
account->mam_queries = new_mam_queries;
}
void account__mam_query_free_all(struct t_account *account)
{
while (account->mam_queries)
account__mam_query_free(account, account->mam_queries);
}
void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t level,
const char *const area, const char *const msg)
{
struct t_account *account = (struct t_account*)userdata;
auto account = static_cast<weechat::account*>(userdata);
static const char *log_level_name[4] = {"debug", "info", "warn", "error"};
@ -389,331 +111,338 @@ void account__log_emit_weechat(void *const userdata, const xmpp_log_level_t leve
}
}
struct t_account *account__alloc(const char *name)
bool weechat::account::search(weechat::account* &out,
const std::string name, bool casesensitive)
{
struct t_account *new_account;
int i, length;
char *option_name;
if (name.empty())
return false;
if (account__casesearch(name))
return NULL;
if (casesensitive)
{
for (auto& account : weechat::accounts)
{
if (weechat_strcasecmp(account.second.name.data(), name.data()) == 0)
{
out = &account.second;
return true;
}
}
}
else if (auto account = accounts.find(name); account != accounts.end())
{
out = &account->second;
return true;
}
(void) out;
return false;
}
/* alloc memory for new account */
new_account = new struct t_account;
std::memset(&new_account->omemo, 0, sizeof(new_account->omemo));
if (!new_account)
bool weechat::account::search_device(weechat::account::device* out, std::uint32_t id)
{
if (id == 0)
return false;
if (auto device = devices.find(id); device != devices.end())
{
weechat_printf(NULL,
_("%s%s: error when allocating new account"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME);
return NULL;
out = &device->second;
return true;
}
accounts[name] = new_account;
(void) out;
return NULL;
}
/* set name */
new_account->name = strdup(name);
void weechat::account::add_device(weechat::account::device *device)
{
if (!devices.contains(device->id))
{
devices[device->id].id = device->id;
devices[device->id].name = device->name;
devices[device->id].label = device->label;
}
}
/* internal vars */
new_account->reloading_from_config = 0;
void weechat::account::device_free_all()
{
devices.clear();
}
new_account->is_connected = 0;
new_account->disconnected = 0;
xmpp_stanza_t *weechat::account::get_devicelist()
{
int i = 0;
new_account->current_retry = 0;
new_account->reconnect_delay = 0;
new_account->reconnect_start = 0;
account::device device;
new_account->logger.handler = &account__log_emit_weechat;
new_account->logger.userdata = new_account;
new_account->memory.alloc = [](const size_t size, void *const) {
return calloc(1, size);
};
new_account->memory.free = [](void *ptr, void *const) {
free(ptr);
};
new_account->memory.realloc = [](void *ptr, const size_t size, void *const) {
return realloc(ptr, size);
};
new_account->memory.userdata = new_account;
new_account->context = xmpp_ctx_new(&new_account->memory, &new_account->logger);
new_account->connection = NULL;
new_account->buffer = NULL;
new_account->buffer_as_string = NULL;
new_account->devices = NULL;
new_account->last_device = NULL;
new_account->mam_queries = NULL;
new_account->last_mam_query = NULL;
new_account->users = NULL;
new_account->last_user = NULL;
new_account->channels = NULL;
new_account->last_channel = NULL;
/* create options with null value */
for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
device.id = omemo.device_id;
device.name = fmt::format("%u", device.id);
device.label = "weechat";
auto children = (xmpp_stanza_t **)malloc(sizeof(xmpp_stanza_t *) * 128);
children[i++] = stanza__iq_pubsub_publish_item_list_device(
context, NULL, with_noop(device.name.data()), NULL);
for (auto& device : devices)
{
new_account->options[i] = NULL;
length = strlen(new_account->name) + 1 +
strlen(account_options[i][0]) +
512 + /* inherited option name(xmpp.account_default.xxx) */
1;
option_name = (char*)malloc(length);
if (option_name)
{
snprintf(option_name, length, "%s.%s << xmpp.account_default.%s",
new_account->name,
account_options[i][0],
account_options[i][0]);
new_account->options[i] = config__account_new_option(
config_file,
config_section_account,
i,
option_name,
account_options[i][1],
account_options[i][1],
0,
&config__account_check_value_cb,
account_options[i][0],
NULL,
&config__account_change_cb,
account_options[i][0],
NULL);
config__account_change_cb(account_options[i][0], NULL,
new_account->options[i]);
free(option_name);
}
if (device.first != omemo.device_id)
children[i++] = stanza__iq_pubsub_publish_item_list_device(
context, NULL, with_noop(device.second.name.data()), NULL);
}
return new_account;
children[i] = NULL;
const char *node = "eu.siacs.conversations.axolotl";
children[0] = stanza__iq_pubsub_publish_item_list(
context, NULL, children, with_noop(node));
children[1] = NULL;
children[0] = stanza__iq_pubsub_publish_item(
context, NULL, children, with_noop("current"));
node = "eu.siacs.conversations.axolotl.devicelist";
children[0] = stanza__iq_pubsub_publish(context, NULL, children, with_noop(node));
const char *ns = "http://jabber.org/protocol/pubsub";
children[0] = stanza__iq_pubsub(context, NULL, children, with_noop(ns));
xmpp_stanza_t * parent = stanza__iq(context, NULL,
children, NULL, strdup("announce1"),
NULL, NULL, strdup("set"));
free(children);
return parent;
}
void account__free_data(struct t_account *account)
void weechat::account::add_mam_query(const std::string id, const std::string with,
tl::optional<time_t> start, tl::optional<time_t> end)
{
//int i;
if (!mam_queries.contains(id))
{
mam_queries[id].id = id;
mam_queries[id].with = with;
if (!account)
return;
mam_queries[id].start = start;
mam_queries[id].end = end;
}
}
/* free linked lists */
/*
for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++)
bool weechat::account::mam_query_search(weechat::account::mam_query* out,
const std::string id)
{
if (id.empty())
return false;
if (auto mam_query = mam_queries.find(id); mam_query != mam_queries.end())
{
account__outqueue_free_all(account, i);
out = &mam_query->second;
return true;
}
xmpp_redirect_free_all(account);
xmpp_notify_free_all(account);
*/
account__free_device_all(account);
account__mam_query_free_all(account);
channel__free_all(account);
user__free_all(account);
/* free hashtables */
/*
weechat_hashtable_free(account->join_manual);
weechat_hashtable_free(account->join_channel_key);
weechat_hashtable_free(account->join_noswitch);
*/
/* close xmpp context */
if (account->connection)
xmpp_conn_release(account->connection);
if (account->context)
xmpp_ctx_free(account->context);
(void) out;
return false;
}
/* free account data */
//for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
//{
// if (account->options[i])
// weechat_config_option_free(account->options[i]);
//}
void weechat::account::mam_query_remove(const std::string id)
{
mam_queries.erase(id);
}
if (account->name)
free(account->name);
void weechat::account::mam_query_free_all()
{
mam_queries.clear();
}
if (account->buffer_as_string)
free(account->buffer_as_string);
xmpp_log_t make_logger(void *userdata)
{
xmpp_log_t logger = { nullptr };
logger.handler = &weechat::log_emit;
logger.userdata = userdata;
return logger;
}
//channel__free_all(account);
//user__free_all(account);
xmpp_mem_t make_memory(void *userdata)
{
xmpp_mem_t memory = { nullptr };
memory.alloc = [](const size_t size, void *const) {
return calloc(1, size);
};
memory.free = [](void *ptr, void *const) {
free(ptr);
};
memory.realloc = [](void *ptr, const size_t size, void *const) {
return realloc(ptr, size);
};
memory.userdata = userdata;
return memory;
}
void account__free(struct t_account *account)
weechat::account::account(config_file& config_file, const std::string name)
: name(name), memory(make_memory(this)), logger(make_logger(this))
, context(&memory, &logger), connection(*this, context)
, config_account(config_file, config_file.configuration.section_account, name.data())
{
if (!account)
return;
if (account* result = nullptr; account::search(result, name))
throw std::invalid_argument("account already exists");
this->jid(config_file.configuration.account_default.option_jid.string().data());
this->password(config_file.configuration.account_default.option_password.string().data());
this->tls(config_file.configuration.account_default.option_tls.string().data());
this->nickname(config_file.configuration.account_default.option_nickname.string().data());
this->autoconnect(config_file.configuration.account_default.option_autoconnect.string().data());
this->resource(config_file.configuration.account_default.option_resource.string().data());
this->status(config_file.configuration.account_default.option_status.string().data());
this->pgp_path(config_file.configuration.account_default.option_pgp_path.string().data());
this->pgp_keyid(config_file.configuration.account_default.option_pgp_keyid.string().data());
}
weechat::account::~account()
{
/*
* close account buffer (and all channels/privates)
* (only if we are not in a /upgrade, because during upgrade we want to
* keep connections and closing account buffer would disconnect from account)
*/
if (account->buffer)
weechat_buffer_close(account->buffer);
if (buffer)
weechat_buffer_close(buffer);
accounts.erase(account->name);
accounts.erase(name);
account__free_data(account);
delete account;
}
/* close xmpp context */
if (connection)
xmpp_conn_release(connection);
if (context)
xmpp_ctx_free(context);
void account__free_all()
{
for (auto account : accounts)
{
account__free(account.second);
}
delete this;
}
void account__disconnect(struct t_account *account, int reconnect)
void weechat::account::disconnect(int reconnect)
{
(void) reconnect;
struct t_channel *ptr_channel;
if (account->is_connected)
if (is_connected)
{
/*
* remove all nicks and write disconnection message on each
* channel/private buffer
*/
user__free_all(account);
weechat_nicklist_remove_all(account->buffer);
for (ptr_channel = account->channels; ptr_channel;
ptr_channel = ptr_channel->next_channel)
//user::free_all(this); // TOFIX
weechat_nicklist_remove_all(buffer);
for (auto& ptr_channel : channels)
{
weechat_nicklist_remove_all(ptr_channel->buffer);
weechat_nicklist_remove_all(ptr_channel.second.buffer);
weechat_printf(
ptr_channel->buffer,
ptr_channel.second.buffer,
_("%s%s: disconnected from account"),
weechat_prefix("network"), WEECHAT_XMPP_PLUGIN_NAME);
}
/* remove away status on account buffer */
//weechat_buffer_set(account->buffer, "localvar_del_away", "");
//weechat_buffer_set(buffer, "localvar_del_away", "");
}
account__close_connection(account);
reset();
if (account->buffer)
if (buffer)
{
weechat_printf(
account->buffer,
buffer,
_("%s%s: disconnected from account"),
weechat_prefix ("network"), WEECHAT_XMPP_PLUGIN_NAME);
}
if (reconnect)
{
if (account->current_retry++ == 0)
if (current_retry++ == 0)
{
account->reconnect_delay = 5;
account->reconnect_start = time(NULL) + account->reconnect_delay;
reconnect_delay = 5;
reconnect_start = time(NULL) + reconnect_delay;
}
account->current_retry %= 5;
current_retry %= 5;
}
else
{
account->current_retry = 0;
account->reconnect_delay = 0;
account->reconnect_start = 0;
current_retry = 0;
reconnect_delay = 0;
reconnect_start = 0;
}
/*
account->lag = 0;
account->lag_displayed = -1;
account->lag_check_time.tv_sec = 0;
account->lag_check_time.tv_usec = 0;
account->lag_next_check = time(NULL) +
lag = 0;
lag_displayed = -1;
lag_check_time.tv_sec = 0;
lag_check_time.tv_usec = 0;
lag_next_check = time(NULL) +
weechat_config_integer(xmpp_config_network_lag_check);
account->lag_last_refresh = 0;
lag_last_refresh = 0;
account__set_lag(account);
*/ // lag based on xmpp ping
account->disconnected = !reconnect;
disconnected = !reconnect;
/* send signal "account_disconnected" with account name */
(void) weechat_hook_signal_send("xmpp_account_disconnected",
WEECHAT_HOOK_SIGNAL_STRING, account->name);
WEECHAT_HOOK_SIGNAL_STRING, name.data());
}
void account__disconnect_all()
void weechat::account::disconnect_all()
{
for (auto ptr_account : accounts)
for (auto& account : accounts)
{
account__disconnect(ptr_account.second, 0);
account.second.disconnect(0);
}
}
struct t_gui_buffer *account__create_buffer(struct t_account *account)
struct t_gui_buffer *weechat::account::create_buffer()
{
char buffer_name[256], charset_modifier[256];
snprintf(buffer_name, sizeof(buffer_name),
"account.%s", account->name);
account->buffer = weechat_buffer_new(buffer_name,
&input__data_cb, NULL, NULL,
&buffer__close_cb, NULL, NULL);
if (!account->buffer)
buffer = weechat_buffer_new(fmt::format("account.{}", name).data(),
&input__data_cb, NULL, NULL,
&buffer__close_cb, NULL, NULL);
if (!buffer)
return NULL;
weechat_printf(account->buffer, "xmpp: %s", account->name);
if (!weechat_buffer_get_integer(account->buffer, "short_name_is_set"))
weechat_buffer_set(account->buffer, "short_name", account->name);
weechat_buffer_set(account->buffer, "localvar_set_type", "server");
weechat_buffer_set(account->buffer, "localvar_set_account", account->name);
snprintf(charset_modifier, sizeof (charset_modifier),
"account.%s", account->name);
weechat_buffer_set(account->buffer, "localvar_set_charset_modifier",
charset_modifier);
weechat_buffer_set(account->buffer, "title",
(account->name) ? account->name : "");
weechat_buffer_set(account->buffer, "nicklist", "1");
weechat_buffer_set(account->buffer, "nicklist_display_groups", "0");
weechat_buffer_set_pointer(account->buffer, "nicklist_callback",
weechat_printf(buffer, "xmpp: %s", name.data());
if (!weechat_buffer_get_integer(buffer, "short_name_is_set"))
weechat_buffer_set(buffer, "short_name", name.data());
weechat_buffer_set(buffer, "localvar_set_type", "server");
weechat_buffer_set(buffer, "localvar_set_account", name.data());
weechat_buffer_set(buffer, "localvar_set_charset_modifier",
fmt::format("account.{}", name).data());
weechat_buffer_set(buffer, "title", name.data());
weechat_buffer_set(buffer, "nicklist", "1");
weechat_buffer_set(buffer, "nicklist_display_groups", "0");
weechat_buffer_set_pointer(buffer, "nicklist_callback",
(void*)&buffer__nickcmp_cb);
weechat_buffer_set_pointer(account->buffer, "nicklist_callback_pointer",
account);
weechat_buffer_set_pointer(buffer, "nicklist_callback_pointer",
this);
return account->buffer;
return buffer;
}
void account__close_connection(struct t_account *account)
void weechat::account::reset()
{
if (account->connection)
if (connection)
{
if (xmpp_conn_is_connected(account->connection))
xmpp_disconnect(account->connection);
if (xmpp_conn_is_connected(connection))
xmpp_disconnect(connection);
}
account->is_connected = 0;
is_connected = 0;
}
int account__connect(struct t_account *account)
int weechat::account::connect()
{
if (!account->buffer)
if (!buffer)
{
if (!account__create_buffer(account))
if (!create_buffer())
return 0;
weechat_buffer_set(account->buffer, "display", "auto");
weechat_buffer_set(buffer, "display", "auto");
}
account__close_connection(account);
reset();
account->is_connected =
connection__connect(account, &account->connection, account_jid(account),
account_password(account), account_tls(account));
is_connected = connection.connect(std::string(jid()), std::string(password()), tls());
(void) weechat_hook_signal_send("xmpp_account_connecting",
WEECHAT_HOOK_SIGNAL_STRING, account->name);
WEECHAT_HOOK_SIGNAL_STRING, name.data());
return account->is_connected;
return is_connected;
}
int account__timer_cb(const void *pointer, void *data, int remaining_calls)
int weechat::account::timer_cb(const void *pointer, void *data, int remaining_calls)
{
(void) pointer;
(void) data;
@ -723,17 +452,17 @@ int account__timer_cb(const void *pointer, void *data, int remaining_calls)
{
if (accounts.empty()) return WEECHAT_RC_ERROR;
for (auto ptr_account : accounts)
for (auto& ptr_account : accounts)
{
if (ptr_account.second->is_connected
&& (xmpp_conn_is_connecting(ptr_account.second->connection)
|| xmpp_conn_is_connected(ptr_account.second->connection)))
connection__process(ptr_account.second->context, ptr_account.second->connection, 10);
else if (ptr_account.second->disconnected);
else if (ptr_account.second->reconnect_start > 0
&& ptr_account.second->reconnect_start < time(NULL))
if (ptr_account.second.is_connected
&& (xmpp_conn_is_connecting(ptr_account.second.connection)
|| xmpp_conn_is_connected(ptr_account.second.connection)))
ptr_account.second.connection.process(ptr_account.second.context, 10);
else if (ptr_account.second.disconnected);
else if (ptr_account.second.reconnect_start > 0
&& ptr_account.second.reconnect_start < time(NULL))
{
account__connect(ptr_account.second);
ptr_account.second.connect();
}
}

@ -7,155 +7,144 @@
#include <ctime>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <strophe.h>
#include <tl/optional.hpp>
#include "fmt/core.h"
#include "strophe.h"
#include "pgp.hh"
#include "omemo.hh"
#include "config.hh"
#include "channel.hh"
#include "connection.hh"
#include "user.hh"
extern std::unordered_map<std::string, struct t_account *> accounts;
enum t_account_option
{
ACCOUNT_OPTION_JID,
ACCOUNT_OPTION_PASSWORD,
ACCOUNT_OPTION_TLS,
ACCOUNT_OPTION_NICKNAME,
ACCOUNT_OPTION_AUTOCONNECT,
ACCOUNT_OPTION_RESOURCE,
ACCOUNT_OPTION_STATUS,
ACCOUNT_OPTION_PGP_PATH,
ACCOUNT_OPTION_PGP_KEYID,
ACCOUNT_NUM_OPTIONS,
};
#define account__option_string(account, option) \
weechat_config_string(account->options[ACCOUNT_OPTION_ ## option])
#define account__option_integer(account, option) \
weechat_config_integer(account->options[ACCOUNT_OPTION_ ## option])
#define account__option_boolean(account, option) \
weechat_config_boolean(account->options[ACCOUNT_OPTION_ ## option])
#define account_option_set(account, option, value) \
weechat_config_option_set(account->options[option], value, 1)
#define account_jid(account) \
account->connection && xmpp_conn_is_connected(account->connection) ? \
xmpp_jid_bare(account->context, xmpp_conn_get_bound_jid(account->connection)) : \
weechat_config_string(account->options[ACCOUNT_OPTION_JID])
#define account_jid_device(account) \
account->connection && xmpp_conn_is_connected(account->connection) ? \
xmpp_conn_get_bound_jid(account->connection) : \
xmpp_jid_new(account->context, \
xmpp_jid_node(account->context, \
weechat_config_string(account->options[ACCOUNT_OPTION_JID])), \
xmpp_jid_domain(account->context, \
weechat_config_string(account->options[ACCOUNT_OPTION_JID])), \
"weechat")
#define account_password(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_PASSWORD])
#define account_tls(account) \
weechat_config_integer(account->options[ACCOUNT_OPTION_TLS])
#define account_nickname(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_NICKNAME])
#define account_autoconnect(account) \
weechat_config_boolean(account->options[ACCOUNT_OPTION_AUTOCONNECT])
#define account_resource(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_RESOURCE])
#define account_status(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_STATUS])
#define account_pgp_path(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_PATH])
#define account_pgp_keyid(account) \
weechat_config_string(account->options[ACCOUNT_OPTION_PGP_KEYID])
struct t_account_device
{
uint32_t id;
char *name;
char *label;
struct t_account_device *prev_device;
struct t_account_device *next_device;
};
struct t_account_mam_query
{
char *id;
char *with;
int has_start;
time_t start;
int has_end;
time_t end;
struct t_account_mam_query *prev_mam_query;
struct t_account_mam_query *next_mam_query;
};
struct t_account
namespace weechat
{
char *name;
struct t_config_option *options[ACCOUNT_NUM_OPTIONS];
int reloading_from_config;
int is_connected;
int disconnected;
int current_retry;
int reconnect_delay;
int reconnect_start;
xmpp_mem_t memory;
xmpp_log_t logger;
xmpp_ctx_t *context;
xmpp_conn_t *connection;
struct t_gui_buffer *buffer;
char *buffer_as_string;
weechat::xmpp::omemo omemo;
struct t_pgp *pgp;
struct t_account_device *devices;
struct t_account_device *last_device;
struct t_account_mam_query *mam_queries;
struct t_account_mam_query *last_mam_query;
struct t_user *users;
struct t_user *last_user;
struct t_channel *channels;
struct t_channel *last_channel;
struct t_account *prev_account;
struct t_account *next_account;
};
extern char *account_options[][2];
struct t_account *account__search(const char *account_name);
struct t_account *account__casesearch (const char *account_name);
int account__search_option(const char *option_name);
struct t_account_device *account__search_device(struct t_account *account,
uint32_t id);
void account__add_device(struct t_account *account,
struct t_account_device *device);
void account__free_device(struct t_account *account,
struct t_account_device *device);
void account__free_device_all(struct t_account *account);
xmpp_stanza_t *account__get_devicelist(struct t_account *account);
struct t_account_mam_query *account__add_mam_query(struct t_account *account,
struct t_channel *channel,
const char *id,
time_t *start, time_t *end);
struct t_account_mam_query *account__mam_query_search(struct t_account *account,
const char *id);
void account__mam_query_free(struct t_account *account,
struct t_account_mam_query *mam_query);
void account__mam_query_free_all(struct t_account *account);
struct t_account *account__alloc(const char *name);
void account__free_data(struct t_account *account);
void account__free(struct t_account *account);
void account__free_all();
void account__disconnect(struct t_account *account, int reconnect);
void account__disconnect_all();
void account__close_connection(struct t_account *account);
int account__connect(struct t_account *account);
int account__timer_cb(const void *pointer, void *data, int remaining_calls);
class channel;
class user;
void log_emit(void *const userdata, const xmpp_log_level_t level,
const char *const area, const char *const msg);
class account : public config_account
{
public:
struct device
{
std::uint32_t id;
std::string name;
std::string label;
};
struct mam_query
{
std::string id;
std::string with;
tl::optional<time_t> start;
tl::optional<time_t> end;
};
public:
bool disconnected = false;
std::unordered_map<std::uint32_t, device> devices;
std::unordered_map<std::string, mam_query> mam_queries;
private:
bool is_connected = false;
int current_retry = 0;
int reconnect_delay = 0;
int reconnect_start = 0;
xmpp_mem_t memory = { nullptr };
xmpp_log_t logger = { nullptr };
std::string buffer_as_string;
friend void log_emit(void *const userdata, const xmpp_log_level_t level,
const char *const area, const char *const msg);
public:
std::string name;
weechat::xmpp::pgp pgp;
weechat::xmpp::omemo omemo;
libstrophe::context context;
weechat::connection connection;
struct t_gui_buffer *buffer = nullptr;
std::unordered_map<std::string, weechat::channel> channels;
std::unordered_map<std::string, weechat::user> users;
std::unordered_map<std::string, struct t_config_option *> options;
int reloading_from_config = 0;
public:
account(config_file& config_file, const std::string name);
~account();
static bool search(account* &out,
const std::string name, bool casesensitive = false);
static int timer_cb(const void *pointer, void *data, int remaining_calls);
static void disconnect_all();
bool connected() { return is_connected; }
bool search_device(device* out, std::uint32_t id);
void add_device(device *device);
void device_free_all();
xmpp_stanza_t *get_devicelist();
void add_mam_query(const std::string id, const std::string with,
tl::optional<time_t> start, tl::optional<time_t> end);
bool mam_query_search(mam_query* out, const std::string id);
void mam_query_remove(const std::string id);
void mam_query_free_all();
struct t_gui_buffer* create_buffer();
void disconnect(int reconnect);
void reset();
int connect();
std::string_view jid() {
if (connection && xmpp_conn_is_connected(connection))
return xmpp_jid_bare(context, xmpp_conn_get_bound_jid(connection));
else
return this->option_jid.string();
}
void jid(std::string jid) { this->option_jid = jid; }
std::string_view jid_device() {
if (connection && xmpp_conn_is_connected(connection))
return xmpp_conn_get_bound_jid(connection);
else
return xmpp_jid_new(context,
xmpp_jid_node(context, this->option_jid.string().data()),
xmpp_jid_domain(context, this->option_jid.string().data()),
"weechat");
}
std::string_view password() { return this->option_password.string(); }
void password(std::string password) { this->option_password = password; }
tls_policy tls() { return static_cast<tls_policy>(this->option_tls.integer()); }
void tls(tls_policy tls) { this->option_tls = fmt::format("%d", static_cast<int>(tls)); }
void tls(std::string tls) { this->option_tls = tls; }
std::string_view nickname() { return this->option_nickname.string(); }
void nickname(std::string nickname) { this->option_nickname = nickname; }
bool autoconnect() { return this->option_autoconnect.boolean(); }
void autoconnect(bool autoconnect) { this->option_autoconnect = autoconnect ? "on" : "off"; }
void autoconnect(std::string autoconnect) { this->option_autoconnect = autoconnect; }
std::string_view resource() { return this->option_resource.string(); }
void resource(std::string resource) { this->option_resource = resource; }
std::string_view status() { return this->option_status.string(); }
void status(std::string status) { this->option_status = status; }
std::string_view pgp_path() { return this->option_pgp_path.string(); }
void pgp_path(std::string pgp_path) { this->option_pgp_path = pgp_path; }
std::string_view pgp_keyid() { return this->option_pgp_keyid.string(); }
void pgp_keyid(std::string pgp_keyid) { this->option_pgp_keyid = pgp_keyid; }
};
extern std::unordered_map<std::string, account> accounts;
}

@ -13,37 +13,33 @@
#include "buffer.hh"
void buffer__get_account_and_channel(struct t_gui_buffer *buffer,
struct t_account **account,
struct t_channel **channel)
weechat::account **account,
weechat::channel **channel)
{
struct t_account *ptr_account;
struct t_channel *ptr_channel;
if (!buffer)
return;
*account = NULL;
*channel = NULL;
*account = nullptr;
*channel = nullptr;
/* look for a account or channel using this buffer */
for (auto ptr_account : accounts)
for (auto& ptr_account : weechat::accounts)
{
if (ptr_account.second->buffer == buffer)
if (ptr_account.second.buffer == buffer)
{
if (account)
*account = ptr_account.second;
*account = &ptr_account.second;
return;
}
for (ptr_channel = ptr_account.second->channels; ptr_channel;
ptr_channel = ptr_channel->next_channel)
for (auto& ptr_channel : ptr_account.second.channels)
{
if (ptr_channel->buffer == buffer)
if (ptr_channel.second.buffer == buffer)
{
if (account)
*account = ptr_account.second;
*account = &ptr_account.second;
if (channel)
*channel = ptr_channel;
*channel = &ptr_channel.second;
return;
}
}
@ -56,9 +52,8 @@ char *buffer__typing_bar_cb(const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_hashtable *extra_info)
{
struct t_channel_typing *ptr_typing;
struct t_account *account;
struct t_channel *channel;
weechat::account *account;
weechat::channel *channel;
char notification[256];
unsigned typecount;
@ -78,17 +73,16 @@ char *buffer__typing_bar_cb(const void *pointer, void *data,
typecount = 0;
for (ptr_typing = channel->typings; ptr_typing;
ptr_typing = ptr_typing->next_typing)
for (auto& ptr_typing : channel->typings)
{
switch (++typecount)
{
case 1:
strcpy(notification, ptr_typing->name);
strcpy(notification, ptr_typing.name);
break;
case 2:
strcat(notification, ", ");
strcat(notification, ptr_typing->name);
strcat(notification, ptr_typing.name);
break;
case 3:
default:
@ -115,12 +109,12 @@ int buffer__nickcmp_cb(const void *pointer, void *data,
const char *nick1,
const char *nick2)
{
struct t_account *account;
weechat::account *account;
(void) data;
if (pointer)
account = (struct t_account *)pointer;
account = (weechat::account *)pointer;
else
buffer__get_account_and_channel(buffer, &account, NULL);
@ -138,8 +132,8 @@ int buffer__close_cb(const void *pointer, void *data,
struct t_gui_buffer *buffer)
{
struct t_weechat_plugin *buffer_plugin = NULL;
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
(void) pointer;
(void) data;
@ -155,9 +149,9 @@ int buffer__close_cb(const void *pointer, void *data,
{
if (ptr_account)
{
if (ptr_account->is_connected)
if (ptr_account->connected())
{
account__disconnect(ptr_account, 0);
ptr_account->disconnect(0);
}
ptr_account->buffer = NULL;
@ -167,9 +161,9 @@ int buffer__close_cb(const void *pointer, void *data,
{
if (ptr_account && ptr_channel)
{
if (ptr_account->is_connected)
if (ptr_account->connected())
{
channel__free(ptr_account, ptr_channel);
ptr_account->channels.erase(ptr_channel->name);
}
}
}
@ -177,9 +171,9 @@ int buffer__close_cb(const void *pointer, void *data,
{
if (ptr_account && ptr_channel)
{
if (ptr_account->is_connected)
if (ptr_account->connected())
{
channel__free(ptr_account, ptr_channel);
ptr_account->channels.erase(ptr_channel->name);
}
}
}

@ -5,8 +5,8 @@
#pragma once
void buffer__get_account_and_channel(struct t_gui_buffer *buffer,
struct t_account **account,
struct t_channel **channel);
weechat::account **account,
weechat::channel **channel);
char *buffer__typing_bar_cb(const void *pointer, void *data,
struct t_gui_bar_item *item,

File diff suppressed because it is too large Load Diff

@ -5,212 +5,165 @@
#pragma once
#include <ctime>
#include <unordered_set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <tl/optional.hpp>
#define CHANNEL_MEMBERS_SPEAKING_LIMIT 128
enum t_channel_type
{
CHANNEL_TYPE_MUC,
CHANNEL_TYPE_PM,
};
enum t_channel_transport
namespace weechat
{
CHANNEL_TRANSPORT_PLAIN,
CHANNEL_TRANSPORT_OMEMO,
CHANNEL_TRANSPORT_PGP,
CHANNEL_TRANSPORT_OTR,
CHANNEL_TRANSPORT_OX,
};
struct t_channel_typing
{
union {
char *id;
struct t_user *user;
class account;
class user;
class channel
{
public:
enum class chat_type { MUC, PM };
enum class transport { PLAIN, OMEMO, PGP, OTR, OX };
static const char *transport_name(enum transport transport)
{
switch (transport)
{
case transport::PLAIN:
return "PLAINTEXT";
case transport::OMEMO:
return "OMEMO";
case transport::PGP:
return "PGP";
case transport::OTR:
return "OTR";
default:
return NULL;
}
}
struct typing
{
union {
char *id;
weechat::user *user;
};
char *name;
time_t ts;
};
struct member
{
char *id;
char *role;
char *affiliation;
};
struct topic
{
char *value = nullptr;
char *creator = nullptr;
time_t last_set = 0;
};
struct unread
{
char *id;
char *thread;
};
private:
topic topic;
/* mpim */
char *creator = nullptr;
double last_read = 0.0;
int unread_count = 0;
int unread_count_display = 0;
struct t_hook *typing_hook_timer = nullptr;
struct t_hook *self_typing_hook_timer = nullptr;
public:
std::vector<weechat::channel::unread> unreads;
public:
std::string id;
std::string name;
enum chat_type type;
enum transport transport = weechat::channel::transport::PLAIN;
struct {
int enabled;
struct t_hashtable *devicelist_requests;
struct t_hashtable *bundle_requests;
} omemo;
struct {
int enabled = 1;
std::unordered_set<std::string> ids;
} pgp;
struct {
int enabled = 0;
} otr;
struct t_weelist *members_speaking[2] = { nullptr };
std::vector<typing> self_typings;
std::vector<typing> typings;
std::unordered_map<std::string, member> members;
public:
struct t_gui_buffer *buffer;
public:
channel(weechat::account& account, enum chat_type type, const char *id, const char *name);
~channel();
void set_transport(enum weechat::channel::transport transport, int force);
struct t_gui_buffer *search_buffer(weechat::channel::chat_type type,
const char *name);
struct t_gui_buffer *create_buffer(weechat::channel::chat_type type,
const char *name);
void add_nicklist_groups();
void member_speaking_add_to_list(const char *nick, int highlight);
void member_speaking_add(const char *nick, int highlight);
void member_speaking_rename(const char *old_nick, const char *new_nick);
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);
int add_typing(weechat::user *user);
static int self_typing_cb(const void *pointer, void *data, int remaining_calls);
typing *self_typing_search(weechat::user *user);
int add_self_typing(weechat::user *user);
static int hotlist_update_cb(const void *pointer, void *data,
const char *signal, const char *type_data,
void *signal_data);
void free(channel *channel);
void free_all();
void update_topic(const char* title, const char* creator, int last_set);
void update_name(const char* name);
void update_purpose(const char* purpose, const char* creator, int last_set);
member *add_member(const char *id, const char *client);
member *member_search(const char *id);
member *remove_member(const char *id, const char *reason);
int send_message(std::string to, std::string body,
tl::optional<std::string> oob = {});
int send_message(const char *to, const char *body);
void send_reads();
void send_typing(weechat::user *user);
void send_paused(weechat::user *user);
void fetch_mam(const char *id, time_t *start, time_t *end, const char *after);
weechat::account& account;
};
char *name;
time_t ts;
struct t_channel_typing *prev_typing;
struct t_channel_typing *next_typing;
};
struct t_channel_member
{
char *id;
char *role;
char *affiliation;
struct t_channel_member *prev_member;
struct t_channel_member *next_member;
};
struct t_channel_topic
{
char *value;
char *creator;
time_t last_set;
};
struct t_channel_unread
{
char *id;
char *thread;
};
struct t_channel
{
enum t_channel_type type;
char *id;
char *name;
enum t_channel_transport transport;
struct {
int enabled;
struct t_hashtable *devicelist_requests;
struct t_hashtable *bundle_requests;
} omemo;
struct {
int enabled;
std::unordered_set<std::string> *ids;
} pgp;
struct {
int enabled;
} otr;
struct t_channel_topic topic;
/* mpim */
char *creator;
double last_read;
int unread_count;
int unread_count_display;
struct t_hook *typing_hook_timer;
struct t_hook *self_typing_hook_timer;
struct t_weelist *members_speaking[2];
struct t_weelist *unreads;
struct t_channel_typing *self_typings;
struct t_channel_typing *last_self_typing;
struct t_channel_typing *typings;
struct t_channel_typing *last_typing;
struct t_channel_member *members;
struct t_channel_member *last_member;
struct t_gui_buffer *buffer;
char *buffer_as_string;
struct t_channel *prev_channel;
struct t_channel *next_channel;
};
const char *channel__transport_name(enum t_channel_transport transport);
void channel__set_transport(struct t_channel *channel,
enum t_channel_transport transport, int force);
struct t_account *channel__account(struct t_channel *channel);
struct t_channel *channel__search(struct t_account *account,
const char *id);
void channel__add_nicklist_groups(struct t_account *account,
struct t_channel *channel);
struct t_channel *channel__new(struct t_account *account,
enum t_channel_type type,
const char *id, const char *name);
void channel__member_speaking_add(struct t_channel *channel,
const char *nick, int highlight);
void channel__member_speaking_rename(struct t_channel *channel,
const char *old_nick,
const char *new_nick);
void channel__member_speaking_rename_if_present(struct t_account *account,
struct t_channel *channel,
const char *nick);
void channel__typing_free(struct t_channel *channel,
struct t_channel_typing *typing);
void channel__typing_free_all(struct t_channel *channel);
int channel__typing_cb(const void *pointer,
void *data,
int remaining_calls);
struct t_channel_typing *channel__typing_search(struct t_channel *channel,
const char *id);
int channel__add_typing(struct t_channel *channel,
struct t_user *user);
void channel__self_typing_free(struct t_channel *channel,
struct t_channel_typing *typing);
void channel__self_typing_free_all(struct t_channel *channel);
int channel__self_typing_cb(const void *pointer,
void *data,
int remaining_calls);
struct t_channel_typing *channel__self_typing_search(struct t_channel *channel,
struct t_user *user);
int channel__add_self_typing(struct t_channel *channel,
struct t_user *user);
int channel__hotlist_update_cb(const void *pointer, void *data,
const char *signal, const char *type_data,
void *signal_data);
void channel__unread_free(struct t_channel_unread *unread);
void channel__unread_free_all(struct t_channel *channel);
void channel__free(struct t_account *account,
struct t_channel *channel);
void channel__free_all(struct t_account *account);
void channel__update_topic(struct t_channel *channel,
const char* title,
const char* creator,
int last_set);
void channel__update_name(struct t_channel *channel,
const char* name);
void channel__update_purpose(struct t_channel *channel,
const char* purpose,
const char* creator,
int last_set);
struct t_channel_member *channel__add_member(struct t_account *account,
struct t_channel *channel,
const char *id, const char *client);
struct t_channel_member *channel__member_search(struct t_channel *channel,
const char *id);
struct t_channel_member *channel__remove_member(struct t_account *account,
struct t_channel *channel,
const char *id, const char *reason);
int channel__send_message(struct t_account *account, struct t_channel *channel,
const char *to, const char *body);
void channel__send_reads(struct t_account *account, struct t_channel *channel);
void channel__send_typing(struct t_account *account, struct t_channel *channel,
struct t_user *user);
void channel__send_paused(struct t_account *account, struct t_channel *channel,
struct t_user *user);
void channel__fetch_mam(struct t_account *account, struct t_channel *channel,
const char *id, time_t *start, time_t *end, const char *after);
}

@ -10,6 +10,7 @@
#include <errno.h>
#include <iostream>
#include <sstream>
#include <utility>
#include <weechat/weechat-plugin.h>
#include "plugin.hh"
@ -24,27 +25,27 @@
#define MAM_DEFAULT_DAYS 2
#define STR(X) #X
void command__display_account(struct t_account *account)
void command__display_account(weechat::account *account)
{
int num_channels, num_pv;
if (account->is_connected)
if (account->connected())
{
num_channels = 0;//xmpp_account_get_channel_count(account);
num_pv = 0;//xmpp_account_get_pv_count(account);
weechat_printf(
NULL,
" %s %s%s%s %s(%s%s%s) [%s%s%s]%s, %d %s, %d pv",
(account->is_connected) ? "*" : " ",
(account->connected()) ? "*" : " ",
weechat_color("chat_server"),
account->name,
account->name.data(),
weechat_color("reset"),
weechat_color("chat_delimiters"),
weechat_color("chat_server"),
account_jid(account),
account->jid().data(),
weechat_color("chat_delimiters"),
weechat_color("reset"),
(account->is_connected) ? _("connected") : _("not connected"),
(account->connected()) ? _("connected") : _("not connected"),
weechat_color("chat_delimiters"),
weechat_color("reset"),
num_channels,
@ -57,11 +58,11 @@ void command__display_account(struct t_account *account)
NULL,
" %s%s%s %s(%s%s%s)%s",
weechat_color("chat_server"),
account->name,
account->name.data(),
weechat_color("reset"),
weechat_color("chat_delimiters"),
weechat_color("chat_server"),
account_jid(account),
account->jid().data(),
weechat_color("chat_delimiters"),
weechat_color("reset"));
}
@ -70,7 +71,6 @@ void command__display_account(struct t_account *account)
void command__account_list(int argc, char **argv)
{
int i, one_account_found;
struct t_account *ptr_account2;
char *account_name = NULL;
for (i = 2; i < argc; i++)
@ -80,13 +80,13 @@ void command__account_list(int argc, char **argv)
}
if (!account_name)
{
if (!accounts.empty())
if (!weechat::accounts.empty())
{
weechat_printf(NULL, "");
weechat_printf(NULL, _("All accounts:"));
for (auto ptr_account2 : accounts)
for (auto& ptr_account2 : weechat::accounts)
{
command__display_account(ptr_account2.second);
command__display_account(&ptr_account2.second);
}
}
else
@ -95,9 +95,9 @@ void command__account_list(int argc, char **argv)
else
{
one_account_found = 0;
for (auto ptr_account2 : accounts)
for (auto& ptr_account2 : weechat::accounts)
{
if (weechat_strcasestr(ptr_account2.second->name, account_name))
if (weechat_strcasestr(ptr_account2.second.name.data(), account_name))
{
if (!one_account_found)
{
@ -107,7 +107,7 @@ void command__account_list(int argc, char **argv)
account_name);
}
one_account_found = 1;
command__display_account(ptr_account2.second);
command__display_account(&ptr_account2.second);
}
}
if (!one_account_found)
@ -119,10 +119,8 @@ void command__account_list(int argc, char **argv)
void command__add_account(const char *name, const char *jid, const char *password)
{
struct t_account *account;
account = account__casesearch(name);
if (account)
weechat::account *account = nullptr;
if (weechat::account::search(account, name, true))
{
weechat_printf(
NULL,
@ -132,7 +130,10 @@ void command__add_account(const char *name, const char *jid, const char *passwor
return;
}
account = account__alloc(name);
;
account = &weechat::accounts.emplace(
std::piecewise_construct, std::forward_as_tuple(name),
std::forward_as_tuple(weechat::config::instance->file, name)).first->second;
if (!account)
{
weechat_printf(
@ -144,19 +145,18 @@ void command__add_account(const char *name, const char *jid, const char *passwor
account->name = strdup(name);
if (jid)
account_option_set(account, ACCOUNT_OPTION_JID, strdup(jid));
account->jid(jid);
if (password)
account_option_set(account, ACCOUNT_OPTION_PASSWORD, strdup(password));
account->password(password);
if (jid)
account_option_set(account, ACCOUNT_OPTION_NICKNAME,
strdup(xmpp_jid_node(account->context, jid)));
account->nickname(xmpp_jid_node(account->context, jid));
weechat_printf(
NULL,
_("%s: account %s%s%s %s(%s%s%s)%s added"),
WEECHAT_XMPP_PLUGIN_NAME,
weechat_color("chat_server"),
account->name,
account->name.data(),
weechat_color("reset"),
weechat_color("chat_delimiters"),
weechat_color("chat_server"),
@ -189,21 +189,21 @@ void command__account_add(struct t_gui_buffer *buffer, int argc, char **argv)
}
}
int command__connect_account(struct t_account *account)
int command__connect_account(weechat::account *account)
{
if (!account)
return 0;
if (account->is_connected)
if (account->connected())
{
weechat_printf(
NULL,
_("%s%s: already connected to account \"%s\"!"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME,
account->name);
account->name.data());
}
account__connect(account);
account->connect();
return 1;
}
@ -211,7 +211,7 @@ int command__connect_account(struct t_account *account)
int command__account_connect(struct t_gui_buffer *buffer, int argc, char **argv)
{
int i, nb_connect, connect_ok;
struct t_account *ptr_account;
weechat::account *ptr_account = nullptr;
(void) buffer;
(void) argc;
@ -223,8 +223,7 @@ int command__account_connect(struct t_gui_buffer *buffer, int argc, char **argv)
for (i = 2; i < argc; i++)
{
nb_connect++;
ptr_account = account__search(argv[i]);
if (ptr_account)
if (weechat::account::search(ptr_account, argv[i]))
{
if (!command__connect_account(ptr_account))
{
@ -245,21 +244,21 @@ int command__account_connect(struct t_gui_buffer *buffer, int argc, char **argv)
return (connect_ok) ? WEECHAT_RC_OK : WEECHAT_RC_ERROR;
}
int command__disconnect_account(struct t_account *account)
int command__disconnect_account(weechat::account *account)
{
if (!account)
return 0;
if (!account->is_connected)
if (!account->connected())
{
weechat_printf(
NULL,
_("%s%s: not connected to account \"%s\"!"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME,
account->name);
account->name.data());
}
account__disconnect(account, 0);
account->disconnect(0);
return 1;
}
@ -267,7 +266,7 @@ int command__disconnect_account(struct t_account *account)
int command__account_disconnect(struct t_gui_buffer *buffer, int argc, char **argv)
{
int i, nb_disconnect, disconnect_ok;
struct t_account *ptr_account;
weechat::account *ptr_account;
(void) argc;
(void) argv;
@ -277,7 +276,7 @@ int command__account_disconnect(struct t_gui_buffer *buffer, int argc, char **ar
nb_disconnect = 0;
if (argc < 2)
{
struct t_channel *ptr_channel;
weechat::channel *ptr_channel;
buffer__get_account_and_channel(buffer, &ptr_account, &ptr_channel);
@ -292,8 +291,7 @@ int command__account_disconnect(struct t_gui_buffer *buffer, int argc, char **ar
for (i = 2; i < argc; i++)
{
nb_disconnect++;
ptr_account = account__search(argv[i]);
if (ptr_account)
if (weechat::account::search(ptr_account, argv[i]))
{
if (!command__disconnect_account(ptr_account))
{
@ -323,9 +321,6 @@ void command__account_delete(struct t_gui_buffer *buffer, int argc, char **argv)
{
(void) buffer;
struct t_account *account;
char *account_name;
if (argc < 3)
{
weechat_printf(
@ -337,8 +332,9 @@ void command__account_delete(struct t_gui_buffer *buffer, int argc, char **argv)
return;
}
account = account__search(argv[2]);
if (!account)
weechat::account *account = nullptr;
if (!weechat::account::search(account, argv[2]))
{
weechat_printf(
NULL,
@ -347,7 +343,7 @@ void command__account_delete(struct t_gui_buffer *buffer, int argc, char **argv)
argv[2], "xmpp delete");
return;
}
if (account->is_connected)
if (account->connected())
{
weechat_printf(
NULL,
@ -358,17 +354,15 @@ void command__account_delete(struct t_gui_buffer *buffer, int argc, char **argv)
return;
}
account_name = strdup(account->name);
account__free(account);
std::string account_name = account->name;
weechat::accounts.erase(account->name);
weechat_printf(
NULL,
_("%s: account %s%s%s has been deleted"),
WEECHAT_XMPP_PLUGIN_NAME,
weechat_color("chat_server"),
(account_name) ? account_name : "???",
!account_name.empty() ? account_name.data() : "???",
weechat_color("reset"));
if (account_name)
free(account_name);
}
int command__account(const void *pointer, void *data,
@ -428,8 +422,8 @@ int command__enter(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
xmpp_stanza_t *pres;
char *jid, *pres_jid, *text;
@ -442,7 +436,7 @@ int command__enter(const void *pointer, void *data,
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_account->is_connected)
if (!ptr_account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -464,19 +458,21 @@ int command__enter(const void *pointer, void *data,
ptr_account->context,
xmpp_jid_node(ptr_account->context, jid),
xmpp_jid_domain(ptr_account->context, jid),
account_nickname(ptr_account)
&& strlen(account_nickname(ptr_account))
? account_nickname(ptr_account)
ptr_account->nickname().data()
&& strlen(ptr_account->nickname().data())
? ptr_account->nickname().data()
: xmpp_jid_node(ptr_account->context,
account_jid(ptr_account)));
ptr_account->jid().data()));
ptr_channel = channel__search(ptr_account, jid);
if (!ptr_channel)
ptr_channel = channel__new(ptr_account, CHANNEL_TYPE_MUC, jid, jid);
if (!ptr_account->channels.contains(jid))
ptr_channel = &ptr_account->channels.emplace(
std::make_pair(jid, weechat::channel {
*ptr_account, weechat::channel::chat_type::MUC, jid, jid
})).first->second;
pres = xmpp_presence_new(ptr_account->context);
xmpp_stanza_set_to(pres, pres_jid);
xmpp_stanza_set_from(pres, account_jid(ptr_account));
xmpp_stanza_set_from(pres, ptr_account->jid().data());
xmpp_stanza_t *pres__x = xmpp_stanza_new(ptr_account->context);
xmpp_stanza_set_name(pres__x, "x");
@ -491,7 +487,7 @@ int command__enter(const void *pointer, void *data,
{
text = argv_eol[2];
channel__send_message(ptr_account, ptr_channel, jid, text);
ptr_channel->send_message(jid, text);
}
char buf[16];
@ -511,13 +507,15 @@ int command__enter(const void *pointer, void *data,
xmpp_jid_domain(ptr_account->context, buffer_jid),
weechat_buffer_get_string(buffer, "localvar_nick"));
ptr_channel = channel__search(ptr_account, buffer_jid);
if (!ptr_channel)
ptr_channel = channel__new(ptr_account, CHANNEL_TYPE_MUC, buffer_jid, buffer_jid);
if (!ptr_account->channels.contains(buffer_jid))
ptr_channel = &ptr_account->channels.emplace(
std::make_pair(jid, weechat::channel {
*ptr_account, weechat::channel::chat_type::MUC, buffer_jid, buffer_jid
})).first->second;
pres = xmpp_presence_new(ptr_account->context);
xmpp_stanza_set_to(pres, pres_jid);
xmpp_stanza_set_from(pres, account_jid(ptr_account));
xmpp_stanza_set_from(pres, ptr_account->jid().data());
xmpp_stanza_t *pres__x = xmpp_stanza_new(ptr_account->context);
xmpp_stanza_set_name(pres__x, "x");
@ -536,8 +534,8 @@ int command__open(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
xmpp_stanza_t *pres;
char *jid, *text;
@ -550,7 +548,7 @@ int command__open(const void *pointer, void *data,
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_account->is_connected)
if (!ptr_account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -569,30 +567,33 @@ int command__open(const void *pointer, void *data,
{
jid = xmpp_jid_new(
ptr_account->context,
xmpp_jid_node(ptr_account->context, ptr_channel->name),
xmpp_jid_domain(ptr_account->context, ptr_channel->name),
xmpp_jid_node(ptr_account->context, ptr_channel->name.data()),
xmpp_jid_domain(ptr_account->context, ptr_channel->name.data()),
jid);
}
pres = xmpp_presence_new(ptr_account->context);
xmpp_stanza_set_to(pres, jid);
xmpp_stanza_set_from(pres, account_jid(ptr_account));
xmpp_stanza_set_from(pres, ptr_account->jid().data());
xmpp_send(ptr_account->connection, pres);
xmpp_stanza_release(pres);
struct t_channel *channel = channel__search(ptr_account, jid);
if (!channel)
channel = channel__new(ptr_account, CHANNEL_TYPE_PM, jid, jid);
auto channel = ptr_account->channels.find(jid);
if (channel == ptr_account->channels.end())
channel = ptr_account->channels.emplace(
std::make_pair(jid, weechat::channel {
*ptr_account, weechat::channel::chat_type::PM, jid, jid
})).first;
if (argc > 2)
{
text = argv_eol[2];
channel__send_message(ptr_account, channel, jid, text);
channel->second.send_message(jid, text);
}
char buf[16];
int num = weechat_buffer_get_integer(channel->buffer, "number");
int num = weechat_buffer_get_integer(channel->second.buffer, "number");
snprintf(buf, sizeof(buf), "/buffer %d", num);
weechat_command(ptr_account->buffer, buf);
}
@ -606,8 +607,8 @@ int command__msg(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
xmpp_stanza_t *message;
char *text;
@ -629,7 +630,7 @@ int command__msg(const void *pointer, void *data,
return WEECHAT_RC_OK;
}
if (!ptr_account->is_connected)
if (!ptr_account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -642,16 +643,17 @@ int command__msg(const void *pointer, void *data,
text = argv_eol[1];
message = xmpp_message_new(ptr_account->context,
ptr_channel->type == CHANNEL_TYPE_MUC ? "groupchat" : "chat",
ptr_channel->name, NULL);
ptr_channel->type == weechat::channel::chat_type::MUC ? "groupchat" : "chat",
ptr_channel->name.data(), NULL);
xmpp_message_set_body(message, text);
xmpp_send(ptr_account->connection, message);
xmpp_stanza_release(message);
if (ptr_channel->type != CHANNEL_TYPE_MUC)
if (ptr_channel->type != weechat::channel::chat_type::MUC)
weechat_printf_date_tags(ptr_channel->buffer, 0,
"xmpp_message,message,private,notify_none,self_msg,log1",
"%s\t%s",
user__as_prefix_raw(ptr_account, account_jid(ptr_account)), text);
weechat::user::search(ptr_account, ptr_account->jid().data())->as_prefix_raw().data(),
text);
}
return WEECHAT_RC_OK;
@ -661,8 +663,8 @@ int command__me(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
xmpp_stanza_t *message;
char *text;
@ -684,7 +686,7 @@ int command__me(const void *pointer, void *data,
return WEECHAT_RC_OK;
}
if (!ptr_account->is_connected)
if (!ptr_account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -697,17 +699,17 @@ int command__me(const void *pointer, void *data,
text = argv_eol[0];
message = xmpp_message_new(ptr_account->context,
ptr_channel->type == CHANNEL_TYPE_MUC ? "groupchat" : "chat",
ptr_channel->name, NULL);
ptr_channel->type == weechat::channel::chat_type::MUC ? "groupchat" : "chat",
ptr_channel->name.data(), NULL);
xmpp_message_set_body(message, text);
xmpp_send(ptr_account->connection, message);
xmpp_stanza_release(message);
if (ptr_channel->type != CHANNEL_TYPE_MUC)
if (ptr_channel->type != weechat::channel::chat_type::MUC)
weechat_printf_date_tags(ptr_channel->buffer, 0,
"xmpp_message,message,action,private,notify_none,self_msg,log1",
"%s%s %s",
weechat_prefix("action"),
user__as_prefix_raw(ptr_account, account_jid(ptr_account)),
weechat::user::search(ptr_account, ptr_account->jid().data())->as_prefix_raw().data(),
strlen(text) > strlen("/me ") ? text+4 : "");
}
@ -718,8 +720,8 @@ int command__mam(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
int days;
(void) pointer;
@ -761,7 +763,7 @@ int command__mam(const void *pointer, void *data,
else
ago->tm_mday -= MAM_DEFAULT_DAYS;
start = mktime(ago);
channel__fetch_mam(ptr_account, ptr_channel, NULL, &start, NULL, NULL);
ptr_channel->fetch_mam(NULL, &start, NULL, NULL);
return WEECHAT_RC_OK;
}
@ -770,8 +772,8 @@ int command__omemo(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
(void) pointer;
(void) data;
@ -796,7 +798,7 @@ int command__omemo(const void *pointer, void *data,
ptr_channel->omemo.enabled = 1;
ptr_channel->pgp.enabled = 0;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_OMEMO, 0);
ptr_channel->set_transport(weechat::channel::transport::OMEMO, 0);
return WEECHAT_RC_OK;
}
@ -805,8 +807,8 @@ int command__pgp(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
char *keyid;
(void) pointer;
@ -831,12 +833,12 @@ int command__pgp(const void *pointer, void *data,
{
keyid = argv_eol[1];
ptr_channel->pgp.ids->emplace(keyid);
ptr_channel->pgp.ids.emplace(keyid);
}
ptr_channel->omemo.enabled = 0;
ptr_channel->pgp.enabled = 1;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_PGP, 0);
ptr_channel->set_transport(weechat::channel::transport::PGP, 0);
return WEECHAT_RC_OK;
}
@ -845,8 +847,8 @@ int command__plain(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
(void) pointer;
(void) data;
@ -871,7 +873,7 @@ int command__plain(const void *pointer, void *data,
ptr_channel->omemo.enabled = 0;
ptr_channel->pgp.enabled = 0;
channel__set_transport(ptr_channel, CHANNEL_TRANSPORT_PLAIN, 0);
ptr_channel->set_transport(weechat::channel::transport::PLAIN, 0);
return WEECHAT_RC_OK;
}
@ -880,8 +882,8 @@ int command__xml(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
weechat::account *ptr_account = NULL;
weechat::channel *ptr_channel = NULL;
xmpp_stanza_t *stanza;
(void) pointer;
@ -893,7 +895,7 @@ int command__xml(const void *pointer, void *data,
if (!ptr_account)
return WEECHAT_RC_ERROR;
if (!ptr_account->is_connected)
if (!ptr_account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -947,13 +949,12 @@ int command__xmpp(const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol)
{
struct t_account *ptr_account = NULL;
struct t_channel *ptr_channel = NULL;
xmpp_stanza_t *stanza;
(void) pointer;
(void) data;
(void) buffer;
(void) argc;
(void) argv;
(void) argv_eol;
weechat_printf(nullptr,
_("%s%s %s [%s]"),

@ -18,11 +18,11 @@
#include "completion.hh"
void completion__channel_nicks_add_speakers(struct t_gui_completion *completion,
struct t_account *account,
struct t_channel *channel,
weechat::account *account,
weechat::channel *channel,
int highlight)
{
struct t_user *user;
weechat::user *user;
const char *member;
int list_size, i;
@ -35,7 +35,7 @@ void completion__channel_nicks_add_speakers(struct t_gui_completion *completion,
weechat_list_get(channel->members_speaking[highlight], i));
if (member)
{
user = user__search(account, member);
user = weechat::user::search(account, member);
if (user)
weechat_hook_completion_list_add(completion,
user->profile.display_name,
@ -50,10 +50,9 @@ int completion__channel_nicks_cb(const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_account *ptr_account;
struct t_channel *ptr_channel;
struct t_channel_member *ptr_member;
struct t_user *ptr_user;
weechat::account *ptr_account;
weechat::channel *ptr_channel;
weechat::user *ptr_user;
/* make C compiler happy */
(void) pointer;
@ -68,30 +67,29 @@ int completion__channel_nicks_cb(const void *pointer, void *data,
{
switch (ptr_channel->type)
{
case CHANNEL_TYPE_MUC:
case CHANNEL_TYPE_PM:
for (ptr_member = ptr_channel->members; ptr_member;
ptr_member = ptr_member->next_member)
case weechat::channel::chat_type::MUC:
case weechat::channel::chat_type::PM:
for (auto& ptr_member : ptr_channel->members)
{
ptr_user = user__search(ptr_account, ptr_member->id);
ptr_user = weechat::user::search(ptr_account, ptr_member.second.id);
if (ptr_user)
weechat_hook_completion_list_add(completion,
ptr_user->profile.display_name,
1, WEECHAT_LIST_POS_SORT);
}
/* add recent speakers on channel */
if (weechat_config_integer(config_look_nick_completion_smart) == CONFIG_NICK_COMPLETION_SMART_SPEAKERS)
if (weechat_config_integer(weechat::config::instance->look.nick_completion_smart) == static_cast<int>(weechat::config::nick_completion::SMART_SPEAKERS))
{
completion__channel_nicks_add_speakers(completion, ptr_account, ptr_channel, 0);
}
/* add members whose make highlights on me recently on this channel */
if (weechat_config_integer(config_look_nick_completion_smart) == CONFIG_NICK_COMPLETION_SMART_SPEAKERS_HIGHLIGHTS)
if (weechat_config_integer(weechat::config::instance->look.nick_completion_smart) == static_cast<int>(weechat::config::nick_completion::SMART_SPEAKERS_HIGHLIGHTS))
{
completion__channel_nicks_add_speakers(completion, ptr_account, ptr_channel, 1);
}
/* add self member at the end */
weechat_hook_completion_list_add(completion,
ptr_account->name,
ptr_account->name.data(),
1, WEECHAT_LIST_POS_END);
break;
}
@ -105,17 +103,15 @@ int completion__accounts_cb(const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_account *ptr_account;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) completion_item;
(void) buffer;
for (auto ptr_account : accounts)
for (auto& ptr_account : weechat::accounts)
{
weechat_hook_completion_list_add(completion, account_jid(ptr_account.second),
weechat_hook_completion_list_add(completion, ptr_account.second.jid().data(),
0, WEECHAT_LIST_POS_SORT);
}

@ -5,478 +5,150 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <strophe.h>
#include <sstream>
#include <weechat/weechat-plugin.h>
#include "strophe.h"
#include "plugin.hh"
#include "account.hh"
#include "config.hh"
struct t_config_file *config_file;
struct t_config_section *config_section_account_default;
struct t_config_section *config_section_account;
struct t_config_option *config_look_nick_completion_smart;
struct t_config_option *config_account_default[ACCOUNT_NUM_OPTIONS];
int config__account_check_value_cb(const void *pointer, void *data,
struct t_config_option *option,
const char *value)
{
(void) pointer;
(void) data;
(void) option;
(void) value;
return 1;
}
void config__account_change_cb(const void *pointer, void *data,
struct t_config_option *option)
int account_read_cb(weechat::config_section& section,
const char *option_name, const char *value)
{
(void) pointer;
(void) data;
const char *name =
weechat_config_option_get_string(option, "name");
const char *value =
weechat_config_option_get_string(option, "value");
int split_num;
char **split = weechat_string_split(name, ".", NULL, 0, 2, &split_num);
struct t_account *account = account__search(split[0]);
if (split_num >= 2 && account)
if (!option_name)
return WEECHAT_CONFIG_READ_MEMORY_ERROR;
std::istringstream breadcrumbs(option_name);
std::string account_name, option_id;
std::getline(breadcrumbs, account_name, '.');
std::getline(breadcrumbs, option_id, '.');
if (account_name.empty())
return WEECHAT_CONFIG_READ_MEMORY_ERROR;
int rc = WEECHAT_CONFIG_READ_OK;
weechat::account* account = nullptr;
if (!weechat::account::search(account, account_name))
account = &weechat::accounts.emplace(
std::piecewise_construct, std::forward_as_tuple(account_name),
std::forward_as_tuple(weechat::config::instance->file, account_name)).first->second;
if (account)
{
const char *key = split[1];
(void) key;
(void) value;
}
weechat_string_free_split(split);
}
auto options = {
std::ref(account->option_jid),
std::ref(account->option_password),
std::ref(account->option_tls),
std::ref(account->option_nickname),
std::ref(account->option_autoconnect),
std::ref(account->option_resource),
std::ref(account->option_status),
std::ref(account->option_pgp_path),
std::ref(account->option_pgp_keyid),
};
if (!account->reloading_from_config++)
{
for (auto option : options)
option.get().clear();
}
void config__account_default_change_cb(const void *pointer, void *data,
struct t_config_option *option)
{
(void) pointer;
(void) data;
(void) option;
}
account->reloading_from_config %= options.size();
struct t_config_option *
config__account_new_option (struct t_config_file *config_file,
struct t_config_section *section,
int index_option,
const char *option_name,
const char *default_value,
const char *value,
int null_value_allowed,
int (*callback_check_value)(const void *pointer,
void *data,
struct t_config_option *option,
const char *value),
const void *callback_check_value_pointer,
void *callback_check_value_data,
void (*callback_change)(const void *pointer,
void *data,
struct t_config_option *option),
const void *callback_change_pointer,
void *callback_change_data)
{
struct t_config_option *new_option;
if (option_id == "jid") rc |= (account->option_jid = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "password") rc |= (account->option_password = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "tls") rc |= (account->option_tls = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "nickname") rc |= (account->option_nickname = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "autoconnect") rc |= (account->option_autoconnect = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "resource") rc |= (account->option_resource = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "status") rc |= (account->option_status = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "pgp_path") rc |= (account->option_pgp_path = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_id == "pgp_keyid") rc |= (account->option_pgp_keyid = value) == WEECHAT_CONFIG_OPTION_SET_ERROR;
new_option = NULL;
switch (index_option)
{
case ACCOUNT_OPTION_JID:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account JID"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_PASSWORD:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account Password"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_TLS:
new_option = weechat_config_new_option (
config_file, section,
option_name, "integer",
N_("XMPP Server TLS Policy"),
"disable|normal|trust", 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_NICKNAME:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account Nickname"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_AUTOCONNECT:
new_option = weechat_config_new_option (
config_file, section,
option_name, "boolean",
N_("Autoconnect XMPP Account"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_RESOURCE:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account Resource"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_STATUS:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account Login Status"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_PGP_PATH:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account PGP Keyring Dir"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_OPTION_PGP_KEYID:
new_option = weechat_config_new_option (
config_file, section,
option_name, "string",
N_("XMPP Account PGP Key ID"),
NULL, 0, 0,
default_value, value,
null_value_allowed,
callback_check_value,
callback_check_value_pointer,
callback_check_value_data,
callback_change,
callback_change_pointer,
callback_change_data,
NULL, NULL, NULL);
break;
case ACCOUNT_NUM_OPTIONS:
break;
if (!account->reloading_from_config)
{
bool ac_global = std::stoul(std::unique_ptr<char>(
weechat_info_get("auto_connect", NULL)).get());
bool ac_local = account->autoconnect();
if (ac_local && ac_global)
account->connect();
}
}
return new_option;
}
void config__account_create_default_options(struct t_config_section *section)
{
int i;
for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
else
{
config_account_default[i] = config__account_new_option(
config_file,
section,
i,
account_options[i][0],
account_options[i][1],
account_options[i][1],
0,
&config__account_check_value_cb,
account_options[i][0],
weechat_printf(
NULL,
&config__account_default_change_cb,
account_options[i][0],
NULL);
}
}
int config__account_read_cb (const void *pointer, void *data,
struct t_config_file *config_file,
struct t_config_section *section,
const char *option_name, const char *value)
{
struct t_account *ptr_account;
int index_option, rc, i;
char *pos_option, *account_name;
(void) pointer;
(void) data;
(void) config_file;
(void) section;
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
if (option_name)
{
pos_option = const_cast<char*>(strrchr(option_name, '.'));
if (pos_option)
{
account_name = weechat_strndup(option_name,
pos_option - option_name);
pos_option++;
if (account_name)
{
index_option = account__search_option(pos_option);
if (index_option >= 0)
{
ptr_account = account__search(account_name);
if (!ptr_account)
ptr_account = account__alloc(account_name);
if (ptr_account)
{
if (!ptr_account->reloading_from_config++)
{
for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
{
weechat_config_option_set(
ptr_account->options[i], NULL, 1);
}
}
ptr_account->reloading_from_config %=
ACCOUNT_NUM_OPTIONS;
rc = weechat_config_option_set(
ptr_account->options[index_option], value, 1);
if (!ptr_account->reloading_from_config)
{
const char *ac_global = weechat_info_get("auto_connect", NULL);
int ac_local = weechat_config_boolean(
ptr_account->options[ACCOUNT_OPTION_AUTOCONNECT]);
if (ac_local && (strcmp(ac_global, "1") == 0))
account__connect(ptr_account);
}
}
else
{
weechat_printf(
NULL,
_("%s%s: error adding account \"%s\""),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME,
account_name);
}
}
free(account_name);
}
}
_("%s%s: error adding account \"%s\""),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME,
account_name.data());
}
if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR)
if (rc != WEECHAT_CONFIG_READ_OK)
{
weechat_printf(
NULL,
_("%s%s: error creating account option \"%s\""),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME, option_name);
}
return rc;
}
int config__account_write_cb(const void *pointer, void *data,
struct t_config_file *config_file,
const char *section_name)
int account_write_cb(weechat::config_section& section, const char *section_name)
{
struct t_account *ptr_account;
int i;
(void) pointer;
(void) data;
if (!weechat_config_write_line(config_file, section_name, NULL))
if (!weechat_config_write_line(section.file, section_name, NULL))
return WEECHAT_CONFIG_WRITE_ERROR;
for (auto ptr_account : accounts)
for (auto& account : weechat::accounts)
{
for (i = 0; i < ACCOUNT_NUM_OPTIONS; i++)
{
if (!weechat_config_write_option(config_file,
ptr_account.second->options[i]))
return WEECHAT_CONFIG_WRITE_ERROR;
}
if (!account.second.write())
return WEECHAT_CONFIG_WRITE_ERROR;
}
return WEECHAT_CONFIG_WRITE_OK;
}
int config__reload (const void *pointer, void *data,
struct t_config_file *config_file)
int config_reload(weechat::config_file &file)
{
(void) pointer;
(void) data;
weechat_config_section_free_options(config_section_account_default);
weechat_config_section_free_options(config_section_account);
account__free_all();
//weechat_config_section_free_options(file.configuration.section_account_default);
//weechat_config_section_free_options(file.configuration.section_account);
weechat::accounts.clear();
return weechat_config_reload(config_file);
return weechat_config_reload(file);
}
int config__init()
bool weechat::config_account::write()
{
struct t_config_section *ptr_section;
config_file = weechat_config_new(WEECHAT_XMPP_CONFIG_NAME,
&config__reload, NULL, NULL);
if(!config_file)
return 0;
ptr_section = weechat_config_new_section(
config_file, "look",
0, 0,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
if (!ptr_section)
{
weechat_config_free(config_file);
config_file = NULL;
return 0;
}
config_look_nick_completion_smart = weechat_config_new_option (
config_file, ptr_section,
"nick_completion_smart", "integer",
N_("smart completion for nicks (completes first with last speakers): "
"speakers = all speakers (including highlights), "
"speakers_highlights = only speakers with highlight"),
"off|speakers|speakers_highlights", 0, 0, "speakers", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
ptr_section = weechat_config_new_section(
config_file, "account_default",
0, 0,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
if (!ptr_section)
{
weechat_config_free(config_file);
config_file = NULL;
return 0;
}
config_section_account_default = ptr_section;
config__account_create_default_options(ptr_section);
ptr_section = weechat_config_new_section(
config_file, "account",
0, 0,
&config__account_read_cb, NULL, NULL,
&config__account_write_cb, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
if (!ptr_section)
{
weechat_config_free(config_file);
config_file = NULL;
return 0;
}
config_section_account = ptr_section;
return 1;
if (!option_jid.write()) return false;
if (!option_password.write()) return false;
if (!option_tls.write()) return false;
if (!option_nickname.write()) return false;
if (!option_autoconnect.write()) return false;
if (!option_resource.write()) return false;
if (!option_status.write()) return false;
if (!option_pgp_path.write()) return false;
if (!option_pgp_keyid.write()) return false;
return true;
}
int config__read()
weechat::config::config()
: file{*this, "xmpp", &config_reload}
, section_account_default{file, "account_default", 0, 0, {}, {}, {}, {}, {}}
, section_account{file, "account", 0, 0, &account_read_cb, &account_write_cb, {}, {}, {}}
, section_look{file, "look", 0, 0, {}, {}, {}, {}, {}}
, account_default{file, section_account_default}
, look{
.nick_completion_smart{file, section_look, "nick_completion_smart", "integer",
("smart completion for nicks (completes first with last speakers): "
"speakers = all speakers (including highlights), "
"speakers_highlights = only speakers with highlight"),
"off|speakers|speakers_highlights", 0, 0,
"speakers", nullptr, false,
{}, {}, {}}}
{
int rc;
rc = weechat_config_read(config_file);
return rc;
}
int config__write()
{
return weechat_config_write(config_file);
}
weechat::config::~config() {}
void config__free()
{
}
tl::optional<weechat::config> weechat::config::instance;
bool weechat::config::init() { instance.emplace(); return true; }
bool weechat::config::read() { return instance->file.read(); }
bool weechat::config::write() { return instance->file.read(); }

@ -4,52 +4,362 @@
#pragma once
#define WEECHAT_XMPP_CONFIG_NAME "xmpp"
#include <memory>
#include <stdexcept>
#include <string>
#include <functional>
#include <unordered_map>
#include <tl/optional.hpp>
#include <weechat/weechat-plugin.h>
#include "fmt/core.h"
#include "plugin.hh"
enum t_config_nick_completion
using namespace std::placeholders;
namespace weechat
{
CONFIG_NICK_COMPLETION_SMART_OFF = 0,
CONFIG_NICK_COMPLETION_SMART_SPEAKERS,
CONFIG_NICK_COMPLETION_SMART_SPEAKERS_HIGHLIGHTS,
};
extern struct t_config_file *config_file;
extern struct t_config_section *config_section_account_default;
extern struct t_config_section *config_section_account;
extern struct t_config_option *config_look_nick_completion_smart;
extern struct t_config_option *config_account_default[];
int config__account_check_value_cb(const void *pointer, void *data,
struct t_config_option *option,
const char *value);
void config__account_change_cb(const void *pointer, void *data,
struct t_config_option *option);
struct t_config_option *config__account_new_option (
struct t_config_file *config_file,
struct t_config_section *section,
int index_option,
const char *option_name,
const char *default_value,
const char *value,
int null_value_allowed,
int (*callback_check_value)(const void *pointer,
void *data,
struct t_config_option *option,
const char *value),
const void *callback_check_value_pointer,
void *callback_check_value_data,
void (*callback_change)(const void *pointer,
void *data,
struct t_config_option *option),
const void *callback_change_pointer,
void *callback_change_data);
extern int config__init();
extern int config__read();
extern int config__write();
extern void config__free();
enum class tls_policy
{
disable = 0,
normal,
trust,
};
class config;
struct config_file;
struct config_section;
struct config_option;
struct config_breadcrumb {
config_breadcrumb(std::string name)
: name(name), parent(tl::nullopt) {}
config_breadcrumb(std::string name, config_breadcrumb& parent)
: name(name), parent(parent) {}
std::string name;
tl::optional<config_breadcrumb&> parent;
};
struct config_free { void operator() (struct t_config_file *ptr) { weechat_config_free(ptr); } };
struct config_file : public std::unique_ptr<struct t_config_file, config_free>, public config_breadcrumb {
config_file(struct t_config_file *ptr, config& config, std::string name)
: std::unique_ptr<struct t_config_file, config_free>(ptr)
, config_breadcrumb(name)
, configuration(config) {
if (ptr == nullptr) throw std::runtime_error("weechat_config_new");
}
config_file(config& config, std::string name, std::function<int(config_file&)> cb_reload)
: config_file(weechat_config_new(
name.data(),
[](const void *, void *data, struct t_config_file *config_file) {
auto& file = *reinterpret_cast<struct config_file*>(data);
if (file != config_file) throw std::invalid_argument("file != config_file");
if (!file.reload) return 1;
return file.reload() ? 1 : 0;
}, nullptr, this), config, name) {
this->reload = std::bind(cb_reload, std::ref(*this));
}
operator struct t_config_file *() { return get(); }
std::function<int()> reload;
config& configuration;
std::unordered_map<struct t_config_section *, config_section&> sections;
bool read() { return weechat_config_read(*this); }
bool write() { return weechat_config_write(*this); }
};
struct config_section_free { void operator() (struct t_config_section *ptr) { weechat_config_section_free(ptr); } };
struct config_section : public std::unique_ptr<struct t_config_section, config_section_free>, public config_breadcrumb {
config_section(struct t_config_section *ptr, config_file& file, std::string name)
: std::unique_ptr<struct t_config_section, config_section_free>(ptr)
, config_breadcrumb(name)
, file(file) {
if (ptr == nullptr) throw std::runtime_error("weechat_config_new_section");
}
config_section(config_file& config_file, std::string name,
bool user_can_add_options, bool user_can_delete_options,
std::function<bool(config_section&, const char *, const char *)> cb_read,
std::function<bool(config_section&, const char *)> cb_write,
std::function<bool(config_section&, const char *)> cb_write_default,
std::function<bool(config_section&, const char *, const char *)> cb_create_option,
std::function<bool(config_section&, config_option &)> 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,
struct t_config_section *sect, const char *option_name, const char *value) {
auto& section = *reinterpret_cast<config_section*>(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 0;
return section.read(option_name, value) ? 0 : -1;
}, nullptr, this,
[](const void *, void *data, struct t_config_file *config_file,
const char *section_name) {
auto& section = *reinterpret_cast<config_section*>(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;
}, nullptr, this,
[](const void *, void *data, struct t_config_file *config_file,
const char *section_name) {
auto& section = *reinterpret_cast<config_section*>(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;
}, nullptr, this,
[](const void *, void *data, struct t_config_file *config_file,
struct t_config_section *sect, const char *option_name, const char *value) {
auto& section = *reinterpret_cast<config_section*>(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 0;
return section.create_option(option_name, value) ? 0 : -1;
}, nullptr, this,
[](const void *, void *data, struct t_config_file *config_file,
struct t_config_section *sect, struct t_config_option *opt) {
auto& section = *reinterpret_cast<config_section*>(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;
auto option = section.options.find(opt);
if (option == section.options.end()) throw std::invalid_argument("unknown option");
return section.delete_option(option->second) ? 0 : -1;
}, nullptr, this), config_file, name) {
if (cb_read)
this->read = std::bind(cb_read, std::ref(*this), _1, _2);
if (cb_write)
this->write = std::bind(cb_write, std::ref(*this), _1);
if (cb_write_default)
this->write_default = std::bind(cb_write_default, std::ref(*this), _1);
if (cb_create_option)
this->create_option = std::bind(cb_create_option, std::ref(*this), _1, _2);
if (cb_delete_option)
this->delete_option = std::bind(cb_delete_option, std::ref(*this), _1);
}
operator struct t_config_section *() { return get(); }
std::function<bool(const char *, const char *)> read;
std::function<bool(const char *)> write;
std::function<bool(const char *)> write_default;
std::function<bool(const char *, const char *)> create_option;
std::function<bool(config_option&)> delete_option;
config_file& file;
std::unordered_map<struct t_config_option *, config_option&> options;
};
struct config_option_free { void operator() (struct t_config_option *ptr) { weechat_config_option_free(ptr); } };
struct config_option : public std::unique_ptr<struct t_config_option, config_option_free>, public config_breadcrumb {
config_option(struct t_config_option *ptr, config_section& section, std::string name)
: std::unique_ptr<struct t_config_option, config_option_free>(ptr)
, config_breadcrumb(name, section)
, section(section) {
if (ptr == nullptr) throw std::runtime_error("weechat_config_new_option");
}
config_option(config_file& config_file, config_section& section,
std::string name, const char *type, const char *description, const char *string_values,
int min, int max, const char *default_value, const char *value, bool null_value_allowed,
std::function<bool(config_option&, const char *)> cb_check_value,
std::function<void(config_option&)> cb_change,
std::function<void(config_option&)> cb_delete)
: config_option(weechat_config_new_option(
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<config_option*>(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<config_option*>(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<config_option*>(data);
if (option != opt) throw std::invalid_argument("option != opt");
if (option.on_deleted) option.on_deleted();
}, nullptr, this), section, name) {
if (cb_check_value)
this->check_value = std::bind(cb_check_value, std::ref(*this), _1);
if (cb_change)
this->on_changed = std::bind(cb_change, std::ref(*this));
if (cb_delete)
this->on_deleted = std::bind(cb_delete, std::ref(*this));
}
operator struct t_config_option *() { return get(); }
std::function<bool(const char *)> check_value;
std::function<void()> on_changed;
std::function<void()> on_deleted;
config_section& section;
int operator =(std::string value) { return weechat_config_option_set(*this, value.data(), 1); }
int clear() { return weechat_config_option_set(*this, nullptr, 1); }
std::string_view string() { return weechat_config_string(*this); }
int integer() { return weechat_config_integer(*this); }
bool boolean() { return weechat_config_boolean(*this); }
bool write() { return weechat_config_write_option(section.file, *this); }
};
class config_account {
public:
config_account(config_file& config_file, config_section& section_account, const char *name)
: section(section_account)
, option_jid(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "jid"),
"string", "XMPP Account JID", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_password(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "password"),
"string", "XMPP Account Password", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_tls(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "tls"),
"integer", "XMPP Server TLS Policy", "disable|normal|trust", 0, 0,
"normal", "normal", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_nickname(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "nickname"),
"string", "XMPP Account Nickname", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_autoconnect(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "autoconnect"),
"boolean", "Autoconnect XMPP Account", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_resource(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "resource"),
"string", "XMPP Account Resource", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_status(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "status"),
"string", "XMPP Account Login Status", nullptr, 0, 0,
"probably about to segfault", "probably about to segfault", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_pgp_path(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "pgp_path"),
"string", "XMPP Account PGP Keyring Dir", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_pgp_keyid(config_file, section_account,
fmt::format("{0}.{1} << xmpp.account_default.{1}", name, "pgp_keyid"),
"string", "XMPP Account PGP Key ID", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
{
}
config_account(config_file& config_file, config_section& section_account_default)
: section(section_account_default)
, option_jid(config_file, section_account_default,
"jid", "string", "XMPP Account JID", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_password(config_file, section_account_default,
"password", "string", "XMPP Account Password", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_tls(config_file, section_account_default,
"tls", "integer", "XMPP Server TLS Policy", "disable|normal|trust", 0, 0,
"normal", "normal", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_nickname(config_file, section_account_default,
"nickname", "string", "XMPP Account Nickname", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_autoconnect(config_file, section_account_default,
"autoconnect", "boolean", "Autoconnect XMPP Account", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_resource(config_file, section_account_default,
"resource", "string", "XMPP Account Resource", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_status(config_file, section_account_default,
"status", "string", "XMPP Account Login Status", nullptr, 0, 0,
"probably about to segfault", "probably about to segfault", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_pgp_path(config_file, section_account_default,
"pgp_path", "string", "XMPP Account PGP Keyring Dir", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
, option_pgp_keyid(config_file, section_account_default,
"pgp_keyid", "string", "XMPP Account PGP Key ID", nullptr, 0, 0, "", "", false,
[&](config_option&, const char *) { return true; },
[&](config_option&) {},
[&](config_option&) {})
{
}
config_section& section;
config_option option_jid;
config_option option_password;
config_option option_tls;
config_option option_nickname;
config_option option_autoconnect;
config_option option_resource;
config_option option_status;
config_option option_pgp_path;
config_option option_pgp_keyid;
bool read(const char *, const char *);
bool write();
};
class config {
public:
enum class nick_completion
{
SMART_OFF = 0,
SMART_SPEAKERS,
SMART_SPEAKERS_HIGHLIGHTS,
};
config_file file;
config_section section_account_default;
config_section section_account;
config_section section_look;
config_account account_default;
struct {
config_option nick_completion_smart;
} look;
public:
config();
~config();
static tl::optional<config> instance;
public:
static bool init();
static bool read();
static bool write();
};
}

File diff suppressed because it is too large Load Diff

@ -4,12 +4,74 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <strophe.h>
#include "xmpp/ns.hh"
#include "strophe.hh"
#include "config.hh"
void connection__init();
namespace weechat {
class account;
int connection__connect(struct t_account *account, xmpp_conn_t **connection,
const char* jid, const char* password, int tls);
class connection
{
private:
libstrophe::connection m_conn;
void connection__process(xmpp_ctx_t *context, xmpp_conn_t *connection,
const unsigned long timeout);
enum class event {
connect = XMPP_CONN_CONNECT,
raw_connect = XMPP_CONN_RAW_CONNECT,
disconnect = XMPP_CONN_DISCONNECT,
fail = XMPP_CONN_FAIL,
};
public:
weechat::account &account;
connection(weechat::account &acc, libstrophe::context &ctx)
: m_conn(ctx), account(acc) {
}
inline operator xmpp_conn_t*() {
return m_conn;
}
inline auto send(xmpp_stanza_t *stanza) {
m_conn.send(stanza);
}
inline auto context() {
return m_conn.get_context();
}
inline bool connect_client(const char* altdomain, unsigned short altport, xmpp_conn_handler callback) {
return m_conn.connect_client(altdomain, altport, callback, this) == XMPP_EOK;
}
inline auto handler_add(const char *name, const char *type, xmpp_handler callback) {
return m_conn.handler_add(callback, nullptr, name, type, this);
}
template <typename X, std::enable_if_t<std::is_base_of<xmlns,X>::value, int> = 0>
inline auto handler_add(const char *name, const char *type, xmpp_handler callback) {
return m_conn.handler_add(callback, X(), name, type, this);
}
static void init();
int connect(std::string jid, std::string password, weechat::tls_policy tls);
void process(xmpp_ctx_t *context, const unsigned long timeout);
bool version_handler(xmpp_stanza_t *stanza);
bool presence_handler(xmpp_stanza_t *stanza);
bool message_handler(xmpp_stanza_t *stanza);
bool iq_handler(xmpp_stanza_t *stanza);
bool conn_handler(event status, int error, xmpp_stream_error_t *stream_error);
xmpp_stanza_t *get_caps(xmpp_stanza_t *reply, char **hash);
};
}

@ -16,8 +16,8 @@
int input__data(struct t_gui_buffer *buffer, const char *text)
{
struct t_account *account = NULL;
struct t_channel *channel = NULL;
weechat::account *account = NULL;
weechat::channel *channel = NULL;
buffer__get_account_and_channel(buffer, &account, &channel);
@ -26,7 +26,7 @@ int input__data(struct t_gui_buffer *buffer, const char *text)
if (channel)
{
if (!account->is_connected)
if (!account->connected())
{
weechat_printf(buffer,
_("%s%s: you are not connected to server"),
@ -34,7 +34,7 @@ int input__data(struct t_gui_buffer *buffer, const char *text)
return WEECHAT_RC_OK;
}
if (channel__send_message(account, channel, channel->id, text) == WEECHAT_RC_OK)
if (channel->send_message(channel->id, text) == WEECHAT_RC_OK)
return WEECHAT_RC_OK;
else
{
@ -62,15 +62,15 @@ int input__data_cb(const void *pointer, void *data,
int input__typing(struct t_gui_buffer *buffer)
{
struct t_account *account = NULL;
struct t_channel *channel = NULL;
weechat::account *account = NULL;
weechat::channel *channel = NULL;
buffer__get_account_and_channel(buffer, &account, &channel);
if (account && account->is_connected && channel)
if (account && account->connected() && channel)
{
channel__send_reads(account, channel);
channel__send_typing(account, channel, NULL);
channel->send_reads();
channel->send_typing(NULL);
}
return WEECHAT_RC_OK;

@ -108,7 +108,7 @@ release: xmpp.so
cp xmpp.so .xmpp.so.$(SUFFIX)
ln -sf .xmpp.so.$(SUFFIX) .xmpp.so
xmpp.so: $(OBJS) $(DEPS) $(HDRS)
xmpp.so: $(DEPS) $(OBJS) $(HDRS)
$(CXX) $(LDFLAGS) -o $@ $(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

@ -19,11 +19,11 @@
static const char format_regex[] = "<([^>]*?)>";
static const size_t max_groups = 2;
char *message__translate_code(struct t_account *account,
char *message__translate_code(weechat::account *account,
const char *code)
{
struct t_channel *channel;
struct t_user *user;
decltype(account->channels)::iterator channel;
weechat::user *user;
size_t resultlen;
char *identifier, *alttext, *result, *symbol, *prefix;
@ -42,11 +42,11 @@ char *message__translate_code(struct t_account *account,
}
else
{
channel = channel__search(account, identifier+1);
if (channel)
channel = account->channels.find(identifier+1);
if (channel != account->channels.end())
{
prefix = (char*)"#";
symbol = strdup(channel->name);
symbol = strdup(channel->second.name.data());
}
else
{
@ -63,7 +63,7 @@ char *message__translate_code(struct t_account *account,
}
else
{
user = user__search(account, identifier+1);
user = weechat::user::search(account, identifier+1);
if (user)
{
prefix = (char*)"@";
@ -148,7 +148,7 @@ void message__htmldecode(char *dest, const char *src, size_t n)
return;
}
char *message__decode(struct t_account *account,
char *message__decode(weechat::account *account,
const char *text)
{
int rc;

@ -6,5 +6,5 @@
#define MESSAGE_MAX_LENGTH 40000
char *message__decode(struct t_account *account,
char *message__decode(weechat::account *account,
const char *text);

@ -2125,7 +2125,7 @@ void omemo::handle_bundle(const char *jid, uint32_t device_id,
key_signature, identity_key, omemo);
}
char *omemo::decode(struct t_account *account, const char *jid,
char *omemo::decode(weechat::account *account, const char *jid,
xmpp_stanza_t *encrypted)
{
auto omemo = &account->omemo;
@ -2267,7 +2267,7 @@ char *omemo::decode(struct t_account *account, const char *jid,
return NULL;
}
xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid,
xmpp_stanza_t *omemo::encode(weechat::account *account, const char *jid,
const char *unencrypted)
{
auto omemo = &account->omemo;
@ -2362,7 +2362,7 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid,
session_cipher_free(cipher);
}
signal_int_list_free(devicelist);
target = account_jid(account);
target = account->jid().data();
}
free(key_and_tag);

@ -13,67 +13,68 @@
#include <signal_protocol.h>
#include "signal.hh"
struct t_account;
extern const char *OMEMO_ADVICE;
namespace weechat::xmpp {
namespace weechat {
class account;
struct t_pre_key {
const char *id;
const char *public_key;
};
namespace xmpp {
struct t_pre_key {
const char *id;
const char *public_key;
};
struct omemo
{
libsignal::context context;
libsignal::store_context store_context;
struct omemo
{
libsignal::context context;
libsignal::store_context store_context;
lmdb::env db_env = nullptr;
struct dbi {
lmdb::dbi omemo;
} dbi;
std::string db_path;
lmdb::env db_env = nullptr;
struct dbi {
lmdb::dbi omemo;
} dbi;
std::string db_path;
libsignal::identity_key_pair identity;
libsignal::identity_key_pair identity;
std::uint32_t device_id;
std::uint32_t device_id;
class bundle_request
{
public:
std::string id;
std::string jid;
std::string device;
std::string message_text;
};
class bundle_request
{
public:
std::string id;
std::string jid;
std::string device;
std::string message_text;
};
class devicelist_request
{
public:
std::string id;
bundle_request bundle_req;
};
class devicelist_request
{
public:
std::string id;
bundle_request bundle_req;
};
~omemo();
~omemo();
inline operator bool() { return this->context && this->store_context &&
this->identity && this->device_id != 0; }
inline operator bool() { return this->context && this->store_context &&
this->identity && this->device_id != 0; }
xmpp_stanza_t *get_bundle(xmpp_ctx_t *context, char *from, char *to);
xmpp_stanza_t *get_bundle(xmpp_ctx_t *context, char *from, char *to);
void init(struct t_gui_buffer *buffer, const char *account_name);
void init(struct t_gui_buffer *buffer, const char *account_name);
void handle_devicelist(const char *jid, xmpp_stanza_t *items);
void handle_devicelist(const char *jid, xmpp_stanza_t *items);
void handle_bundle(const char *jid, std::uint32_t device_id,
xmpp_stanza_t *items);
void handle_bundle(const char *jid, std::uint32_t device_id,
xmpp_stanza_t *items);
char *decode(struct t_account *account, const char *jid,
xmpp_stanza_t *encrypted);
xmpp_stanza_t *encode(struct t_account *account, const char *jid,
const char *unencrypted);
};
char *decode(weechat::account *account, const char *jid,
xmpp_stanza_t *encrypted);
xmpp_stanza_t *encode(weechat::account *account, const char *jid,
const char *unencrypted);
};
}
}

@ -15,10 +15,10 @@
#include "plugin.hh"
#include "pgp.hh"
std::string format_key(struct t_pgp *pgp, std::string_view keyid)
std::string format_key(weechat::xmpp::pgp &pgp, std::string_view keyid)
{
gpgme_key_t key = nullptr;
gpgme_error_t err = gpgme_get_key(pgp->gpgme, keyid.data(), &key, false);
gpgme_error_t err = gpgme_get_key(pgp.gpgme, keyid.data(), &key, false);
if (err) {
return fmt::format("{} (none)", keyid);
}
@ -54,37 +54,34 @@ std::string format_key(struct t_pgp *pgp, std::string_view keyid)
#define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----\r\n"
#define PGP_SIGNATURE_FOOTER "\r\n-----END PGP SIGNATURE-----"
const char *PGP_ADVICE = "[PGP encrypted message (XEP-0027)]";
const char *weechat::xmpp::PGP_ADVICE = "[PGP encrypted message (XEP-0027)]";
void pgp__init(struct t_pgp **pgp)
weechat::xmpp::pgp::pgp()
{
struct t_pgp *new_pgp;
gpgme_error_t err;
//gpgme_data_t keydata;
gpgme_check_version(NULL);
new_pgp = (struct t_pgp*)calloc(1, sizeof(**pgp));
err = gpgme_new(&new_pgp->gpgme);
err = gpgme_new(&this->gpgme);
if (err) {
weechat_printf(nullptr, "gpg (error): %s - %s",
gpgme_strsource(err), gpgme_strerror(err));
return;
throw nullptr;
}
gpgme_set_armor(new_pgp->gpgme, true);
gpgme_set_armor(this->gpgme, true);
//err = gpgme_data_new_from_file(&keydata, pub, true);
//if (err) {
// return;
//}
//err = gpgme_op_import(new_pgp->gpgme, keydata);
//err = gpgme_op_import(this->gpgme, keydata);
//if (err) {
// return;
//}
//gpgme_import_result_t impRes = gpgme_op_import_result(new_pgp->gpgme);
//gpgme_import_result_t impRes = gpgme_op_import_result(this->gpgme);
//weechat_printf(nullptr, "(gpg) imported %d keys", impRes->imported);
//err = gpgme_data_new_from_file(&keydata, sec, true);
@ -92,28 +89,21 @@ void pgp__init(struct t_pgp **pgp)
// return;
//}
//err = gpgme_op_import(new_pgp->gpgme, keydata);
//err = gpgme_op_import(this->gpgme, keydata);
//if (err) {
// return;
//}
//impRes = gpgme_op_import_result(new_pgp->gpgme);
//impRes = gpgme_op_import_result(this->gpgme);
//weechat_printf(nullptr, "(gpg) imported %d secret keys", impRes->imported);
*pgp = new_pgp;
}
void pgp__free(struct t_pgp *pgp)
weechat::xmpp::pgp::~pgp()
{
if (pgp)
{
if (pgp->gpgme)
gpgme_release(pgp->gpgme);
free(pgp);
}
gpgme_release(this->gpgme);
}
char *pgp__encrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, std::vector<std::string>&& targets, const char *message)
char *weechat::xmpp::pgp::encrypt(struct t_gui_buffer *buffer, const char *source, std::vector<std::string>&& targets, const char *message)
{
std::string encrypted;
gpgme_key_t keys[3] = {NULL,NULL,NULL};
@ -138,20 +128,20 @@ char *pgp__encrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *s
/* Encrypt data. */
for (const std::string& target : targets)
{
err = gpgme_get_key(pgp->gpgme, target.data(), &keys[0], false);
err = gpgme_get_key(this->gpgme, target.data(), &keys[0], false);
if (err) {
goto encrypt_finish;
}
}
err = gpgme_get_key(pgp->gpgme, source, &keys[1], false);
err = gpgme_get_key(this->gpgme, source, &keys[1], false);
if (err) {
goto encrypt_finish;
}
err = gpgme_op_encrypt(pgp->gpgme, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
err = gpgme_op_encrypt(this->gpgme, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
if (err) {
goto encrypt_finish;
}
if (gpgme_encrypt_result_t enc_result = gpgme_op_encrypt_result(pgp->gpgme);
if (gpgme_encrypt_result_t enc_result = gpgme_op_encrypt_result(this->gpgme);
enc_result->invalid_recipients)
{
goto encrypt_finish;
@ -177,7 +167,7 @@ encrypt_finish:
}
//"hQIMAzlgcSFDGLKEAQ//cGG3DFughC5xBF7xeXz1RdayOfhBAPfoZIq62MVuSnfS\nMfig65Zxz1LtAnnFq90TZY7hiHPBtVlYqg47AbSoYweMdpXsKgbUrd3NNf6k2nsZ\nUkChCtyGuHi8pTzclfle7gT0nNXJ1WcLCZ4ORZCrg3D5A+YTO9tdmE8GQsTT6TdV\nbbxF5yR4JF5SzFhuFL3ZoXPXrWylcwKXarYfoOTa6M2vSsCwApVIXQgJ/FI46sLT\nb0B/EVCjFvcvjkNr7+K7mQtth+x0a0pC4BtEhRvnIRAe/sdGp8NY+DP76clx4U+k\nIDG4H92F632pR6eEIoZttnBoaj0O4sTVAJCao5AoecR4w2FDqBWWtIyQp5vbo17/\nMtzungkk5vQP6Jhu36wa+JKpbHoxomVpHPZfAtIoyaY6pzQ0bUomIlSVpbZDvF68\nZKTlFd89Pm5x0JO5gsVYvf+N9Ed33d34n/0CFz5K5Tgu4Bk0v4LWEy3wtNsuQB4p\nkBSZJk7I2BakcRwP0zwld6rRHFIX1pb7zqThBPZGB9RkWPltiktUTibOII12tWhi\nksFpQJ8l1A8h9vM5kUXIeD6H2yP0CBUEIZF3Sf+jiSRZ/1/n3KoUrKEzkf/y4xgv\n1LA4pMjNLEr6J2fqGyYRFv4Bxv3PIvF17V5CwOtguxGRJHJXdIzm1BSHSqXxHezS\nYAFXMUb9fw3QX7Ed23KiyZjzd/LRsQBqMs9RsYyZB2PqF9x84lQYYbE8lErrryvK\nUEtmJKPw3Hvb7kgGox5vl5+KCg9q64EU9TgQpufYNShKtDz7Fsvc+ncgZoshDUeo\npw==\n=euIB"
char *pgp__decrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *ciphertext)
char *weechat::xmpp::pgp::decrypt(struct t_gui_buffer *buffer, const char *ciphertext)
{
std::string decrypted;
uint8_t * buf = NULL;
@ -207,14 +197,14 @@ char *pgp__decrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *c
}
/* Decrypt data. */
err = gpgme_op_decrypt(pgp->gpgme, in, out);
if (gpgme_decrypt_result_t dec_result = gpgme_op_decrypt_result(pgp->gpgme);
err = gpgme_op_decrypt(this->gpgme, in, out);
if (gpgme_decrypt_result_t dec_result = gpgme_op_decrypt_result(this->gpgme);
dec_result)
{
for (auto recip = dec_result->recipients; recip; recip = recip->next)
{
if (!keyids.empty()) keyids += ", ";
keyids += format_key(pgp, recip->keyid);
keyids += format_key(*this, recip->keyid);
}
if (dec_result->unsupported_algorithm)
{
@ -243,7 +233,7 @@ decrypt_finish:
return result;
}
char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *certificate)
char *weechat::xmpp::pgp::verify(struct t_gui_buffer *buffer, const char *certificate)
{
uint8_t * buf = NULL;
size_t buf_len = 0;
@ -271,11 +261,11 @@ char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *ce
}
/* Verify data. */
err = gpgme_op_verify(pgp->gpgme, in, out, nullptr);
err = gpgme_op_verify(this->gpgme, in, out, nullptr);
if (err) {
goto verify_finish;
}
if (vrf_result = gpgme_op_verify_result(pgp->gpgme);
if (vrf_result = gpgme_op_verify_result(this->gpgme);
!(vrf_result->signatures->summary & GPGME_SIGSUM_VALID))
{
//goto verify_finish;
@ -283,10 +273,10 @@ char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *ce
result = strdup(vrf_result->signatures->fpr);
err = gpgme_get_key(pgp->gpgme, result, &key, false);
err = gpgme_get_key(this->gpgme, result, &key, false);
if (err) {
const char *keyids[2] = { result, nullptr };
err = gpgme_op_receive_keys(pgp->gpgme, keyids);
err = gpgme_op_receive_keys(this->gpgme, keyids);
}
verify_finish:
@ -297,7 +287,7 @@ verify_finish:
return result;
}
char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message)
char *weechat::xmpp::pgp::sign(struct t_gui_buffer *buffer, const char *source, const char *message)
{
std::string signature;
char * result = NULL;
@ -321,33 +311,33 @@ char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *sour
/* Include signature within key. */
{
gpgme_keylist_mode_t kmode = gpgme_get_keylist_mode(pgp->gpgme);
gpgme_keylist_mode_t kmode = gpgme_get_keylist_mode(this->gpgme);
kmode |= GPGME_KEYLIST_MODE_LOCATE;
kmode |= GPGME_KEYLIST_MODE_SIGS;
err = gpgme_set_keylist_mode(pgp->gpgme, kmode);
err = gpgme_set_keylist_mode(this->gpgme, kmode);
}
if (err) {
goto sign_finish;
}
err = gpgme_get_key(pgp->gpgme, source, &key, false);
err = gpgme_get_key(this->gpgme, source, &key, false);
if (err) {
weechat_printf(nullptr, "(gpg) get key fail for %s", source);
goto sign_finish;
}
err = gpgme_signers_add(pgp->gpgme, key);
err = gpgme_signers_add(this->gpgme, key);
if (err) {
weechat_printf(nullptr, "(gpg) add key fail for %s", source);
goto sign_finish;
}
/* Sign data. */
err = gpgme_op_sign(pgp->gpgme, in, out, GPGME_SIG_MODE_DETACH);
err = gpgme_op_sign(this->gpgme, in, out, GPGME_SIG_MODE_DETACH);
if (err) {
weechat_printf(nullptr, "(gpg) sign fail for %s", source);
goto sign_finish;
}
if (gpgme_sign_result_t sgn_result = gpgme_op_sign_result(pgp->gpgme);
if (gpgme_sign_result_t sgn_result = gpgme_op_sign_result(this->gpgme);
!sgn_result->signatures)
{
weechat_printf(nullptr, "(gpg) signature fail for %s", source);

@ -7,22 +7,27 @@
#include <string>
#include <vector>
extern const char *PGP_ADVICE;
struct t_pgp
namespace weechat::xmpp
{
struct gpgme_context *gpgme;
const char *keyid;
};
extern const char *PGP_ADVICE;
class pgp
{
public:
struct gpgme_context *gpgme;
const char *keyid;
void pgp__init(struct t_pgp **pgp);
public:
pgp();
void pgp__free(struct t_pgp *pgp);
~pgp();
char *pgp__decrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *ciphertext);
char *decrypt(struct t_gui_buffer *buffer, const char *ciphertext);
char *pgp__encrypt(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, std::vector<std::string>&& target, const char *message);
char *encrypt(struct t_gui_buffer *buffer, const char *source, std::vector<std::string>&& target, const char *message);
char *pgp__verify(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *certificate);
char *verify(struct t_gui_buffer *buffer, const char *certificate);
char *pgp__sign(struct t_gui_buffer *buffer, struct t_pgp *pgp, const char *source, const char *message);
char *sign(struct t_gui_buffer *buffer, const char *source, const char *message);
};
}

@ -51,19 +51,19 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
weechat_xmpp_plugin = plugin;
if (!config__init())
if (!weechat::config::init())
return WEECHAT_RC_ERROR;
config__read();
weechat::config::read();
connection__init();
weechat::connection::init();
command__init();
completion__init();
weechat_xmpp_process_timer = weechat_hook_timer(TIMER_INTERVAL_SEC * 1000, 0, 0,
&account__timer_cb,
&weechat::account::timer_cb,
NULL, NULL);
if (!weechat_bar_search("typing"))
@ -95,11 +95,11 @@ int weechat_plugin_end(struct t_weechat_plugin *plugin)
if (weechat_xmpp_process_timer)
weechat_unhook(weechat_xmpp_process_timer);
config__write();
weechat::config::write();
account__disconnect_all();
weechat::account::disconnect_all();
account__free_all();
weechat::accounts.clear();
xmpp_shutdown();

@ -0,0 +1,207 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#pragma once
#include <fmt/core.h>
#include <memory>
#include <functional>
#include <type_traits>
#include <strophe.h>
namespace libstrophe {
template<typename T, typename CFun, typename DFun,
CFun &f_create, DFun &f_destroy, typename Base = T>
class type {
private:
T *_ptr;
protected:
typedef T* pointer_type;
inline type(T *ptr) : _ptr(ptr) {
}
template<typename Fun, Fun &func, int success = 0, typename... Args,
typename = std::enable_if_t<std::is_same_v<int, std::invoke_result_t<Fun, pointer_type, std::decay_t<Args>...>>>>
inline void call_checked(Args&&... args) {
int ret = func(*this, std::forward<Args>(args)...);
if (ret != success) throw std::runtime_error(
fmt::format("Strophe Error: expected {}, was {}", success, ret));
}
template<typename Fun, Fun &func, int success = 0, typename... Args,
typename = std::enable_if_t<std::is_same_v<void, std::invoke_result_t<Fun, pointer_type, std::decay_t<Args>...>>>>
inline void call(Args&&... args) {
func(*this, std::forward<Args>(args)...);
}
template<typename Fun, Fun &func, typename... Args,
typename = std::enable_if_t<!std::is_same_v<void, std::invoke_result_t<Fun, pointer_type, std::decay_t<std::decay_t<Args>>...>>>>
inline typename std::invoke_result_t<Fun, pointer_type, std::decay_t<std::decay_t<Args>>...>
call(Args&&... args) {
return func(*this, std::forward<Args>(args)...);
}
public:
inline explicit type() : _ptr(nullptr) {
}
template<typename... Args>
inline explicit type(Args&&... args) : type() {
_ptr = f_create(std::forward<Args>(args)...);
}
inline ~type() {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = nullptr;
}
type(const type &other) = delete; /* no copy construction */
type(type &&other) = default;
template<typename... Args>
inline void create(Args&&... args) {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = f_create(std::forward<Args>(args)...);
}
type& operator =(const type &other) = delete; /* no copy assignment */
type& operator =(type &&other) = default;
inline operator bool() const { return _ptr; }
inline T* operator *() { return _ptr; }
inline operator T*() { return _ptr; }
inline operator const T*() const { return _ptr; }
};
inline auto initialize = xmpp_initialize;
typedef type<xmpp_ctx_t,
decltype(xmpp_ctx_new), decltype(xmpp_ctx_free),
xmpp_ctx_new, xmpp_ctx_free> context_type;
class context : public context_type {
public:
using context_type::context_type;
inline auto set_verbosity(auto &&...args) {
return call<decltype(xmpp_ctx_set_verbosity),
xmpp_ctx_set_verbosity>(args...);
}
};
typedef type<xmpp_conn_t,
decltype(xmpp_conn_new), decltype(xmpp_conn_release),
xmpp_conn_new, xmpp_conn_release> connection_type;
class connection : public connection_type {
public:
using connection_type::connection_type;
inline connection(context& ctx) {
create(*ctx);
}
inline auto get_context(auto &&...args) {
return call<decltype(xmpp_conn_get_context),
xmpp_conn_get_context>(args...);
}
inline auto get_flags(auto &&...args) {
return call<decltype(xmpp_conn_get_flags),
xmpp_conn_get_flags>(args...);
}
inline auto set_keepalive(auto &&...args) {
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return call<decltype(xmpp_conn_set_keepalive),
xmpp_conn_set_keepalive>(args...);
#pragma GCC diagnostic pop
}
inline auto set_jid(auto &&...args) {
return call<decltype(xmpp_conn_set_jid),
xmpp_conn_set_jid>(args...);
}
inline auto set_pass(auto &&...args) {
return call<decltype(xmpp_conn_set_pass),
xmpp_conn_set_pass>(args...);
}
inline auto set_flags(auto &&...args) {
return call<decltype(xmpp_conn_set_flags),
xmpp_conn_set_flags>(args...);
}
inline auto send(auto &&...args) {
return call<decltype(xmpp_send), xmpp_send>(args...);
}
inline auto connect_client(auto &&...args) {
return call<decltype(xmpp_connect_client), xmpp_connect_client>(args...);
}
inline auto handler_add(auto &&...args) {
return call<decltype(xmpp_handler_add), xmpp_handler_add>(args...);
}
};
typedef type<xmpp_stanza_t,
decltype(xmpp_stanza_new), decltype(xmpp_stanza_release),
xmpp_stanza_new, xmpp_stanza_release> stanza_type;
class stanza : public stanza_type {
public:
using stanza_type::stanza_type;
inline static stanza reply(auto &&...args) {
return stanza(xmpp_stanza_reply(args...));
}
inline stanza get_name(auto &&...args) {
return call<decltype(xmpp_stanza_get_name),
xmpp_stanza_get_name>(args...);
}
inline stanza get_ns(auto &&...args) {
return call<decltype(xmpp_stanza_get_ns),
xmpp_stanza_get_ns>(args...);
}
inline stanza add_child(auto &&...args) {
call<decltype(xmpp_stanza_add_child),
xmpp_stanza_add_child>(args...);
return std::move(*this);
}
inline stanza set_name(auto &&...args) {
call<decltype(xmpp_stanza_set_name),
xmpp_stanza_set_name>(args...);
return std::move(*this);
}
inline stanza set_ns(auto &&...args) {
call<decltype(xmpp_stanza_set_ns),
xmpp_stanza_set_ns>(args...);
return std::move(*this);
}
inline stanza set_text(auto &&...args) {
call<decltype(xmpp_stanza_set_text),
xmpp_stanza_set_text>(args...);
return std::move(*this);
}
inline stanza set_type(auto &&...args) {
call<decltype(xmpp_stanza_set_type),
xmpp_stanza_set_type>(args...);
return std::move(*this);
}
};
}

@ -5,8 +5,8 @@
TEST_CASE("weechat")
{
std::string current("20211106-01");
std::string current("20220312-01");
SUBCASE("plugin api match")
{
CHECK(current == WEECHAT_PLUGIN_API_VERSION);

@ -14,22 +14,34 @@
#include "user.hh"
#include "channel.hh"
const char *user__get_colour(struct t_user *user)
std::string weechat::user::get_colour()
{
return weechat_info_get("nick_color", user->profile.display_name);
return weechat::user::get_colour(this->profile.display_name);
}
const char *user__get_colour_for_nicklist(struct t_user *user)
std::string weechat::user::get_colour(const char *name)
{
return weechat_info_get("nick_color_name", user->profile.display_name);
return weechat_info_get("nick_color", name);
}
const char *user__as_prefix_raw(struct t_account *account,
const char *name)
std::string weechat::user::get_colour_for_nicklist()
{
static char result[2048];
return weechat::user::get_colour_for_nicklist(this->profile.display_name);
}
std::string weechat::user::get_colour_for_nicklist(const char *name)
{
return weechat_info_get("nick_color_name", name);
}
std::string weechat::user::as_prefix_raw()
{
return weechat::user::as_prefix_raw(this->profile.display_name);
}
(void) account;
std::string weechat::user::as_prefix_raw(const char *name)
{
static char result[2048];
snprintf(result, sizeof(result), "%s%s%s",
weechat_info_get("nick_color", name),
@ -38,214 +50,126 @@ const char *user__as_prefix_raw(struct t_account *account,
return result;
}
const char *user__as_prefix(struct t_account *account,
struct t_user *user,
const char *name)
std::string weechat::user::as_prefix()
{
static char result[2048];
return weechat::user::as_prefix(this->profile.display_name);
}
(void) account;
std::string weechat::user::as_prefix(const char *name)
{
static char result[2048];
snprintf(result, sizeof(result), "%s%s\t",
user__get_colour(user),
name ? name : user->profile.display_name);
weechat::user::get_colour(name).data(), name);
return result;
}
struct t_user *user__bot_search(struct t_account *account,
const char *pgp_id)
weechat::user *weechat::user::bot_search(weechat::account *account,
const char *pgp_id)
{
struct t_user *ptr_user;
if (!account || !pgp_id)
return NULL;
return nullptr;
for (ptr_user = account->users; ptr_user;
ptr_user = ptr_user->next_user)
for (auto& ptr_user : account->users)
{
if (ptr_user->profile.pgp_id &&
weechat_strcasecmp(ptr_user->profile.pgp_id, pgp_id) == 0)
return ptr_user;
if (ptr_user.second.profile.pgp_id &&
ptr_user.second.profile.pgp_id == pgp_id)
return &ptr_user.second;
}
return NULL;
return nullptr;
}
struct t_user *user__search(struct t_account *account,
const char *id)
weechat::user *weechat::user::search(weechat::account *account,
const char *id)
{
struct t_user *ptr_user;
if (!account || !id)
return NULL;
return nullptr;
for (ptr_user = account->users; ptr_user;
ptr_user = ptr_user->next_user)
{
if (weechat_strcasecmp(ptr_user->id, id) == 0)
return ptr_user;
}
if (auto user = account->users.find(id); user != account->users.end())
return &user->second;
return NULL;
return nullptr;
}
void user__nicklist_add(struct t_account *account,
struct t_channel *channel,
struct t_user *user)
void weechat::user::nicklist_add(weechat::account *account,
weechat::channel *channel)
{
struct t_gui_nick_group *ptr_group;
struct t_gui_buffer *ptr_buffer;
char *name = channel ? user->profile.display_name : user->id;
char *name = channel ? this->profile.display_name : this->id;
if (channel && weechat_strcasecmp(xmpp_jid_bare(account->context, name),
channel->id) == 0)
channel->id.data()) == 0)
name = xmpp_jid_resource(account->context, name);
ptr_buffer = channel ? channel->buffer : account->buffer;
char *group = (char*)"...";
if (weechat_strcasecmp(user->profile.affiliation, (char*)"outcast") == 0)
if (this->profile.affiliation ? this->profile.affiliation == std::string("outcast") : false)
group = (char*)"!";
if (weechat_strcasecmp(user->profile.role, (char*)"visitor") == 0)
if (this->profile.role ? this->profile.role == std::string("visitor") : false)
group = (char*)"?";
if (weechat_strcasecmp(user->profile.role, (char*)"participant") == 0)
if (this->profile.role ? this->profile.role == std::string("participant") : false)
group = (char*)"+";
if (weechat_strcasecmp(user->profile.affiliation, (char*)"member") == 0)
if (this->profile.affiliation ? this->profile.affiliation == std::string("member") : false)
group = (char*)"%";
if (weechat_strcasecmp(user->profile.role, (char*)"moderator") == 0)
if (this->profile.role ? this->profile.role == std::string("moderator") : false)
group = (char*)"@";
if (weechat_strcasecmp(user->profile.affiliation, (char*)"admin") == 0)
if (this->profile.affiliation ? this->profile.affiliation == std::string("admin") : false)
group = (char*)"&";
if (weechat_strcasecmp(user->profile.affiliation, (char*)"owner") == 0)
if (this->profile.affiliation ? this->profile.affiliation == std::string("owner") : false)
group = (char*)"~";
ptr_group = weechat_nicklist_search_group(ptr_buffer, NULL, group);
ptr_group = weechat_nicklist_search_group(ptr_buffer, nullptr, group);
weechat_nicklist_add_nick(ptr_buffer, ptr_group,
name,
user->is_away ?
this->is_away ?
"weechat.color.nicklist_away" :
user__get_colour_for_nicklist(user),
get_colour_for_nicklist().data(),
group,
"bar_fg",
1);
}
void user__nicklist_remove(struct t_account *account,
struct t_channel *channel,
struct t_user *user)
void weechat::user::nicklist_remove(weechat::account *account,
weechat::channel *channel)
{
struct t_gui_nick *ptr_nick;
struct t_gui_buffer *ptr_buffer;
char *name = user->profile.display_name;
char *name = this->profile.display_name;
if (channel && weechat_strcasecmp(xmpp_jid_bare(account->context, name),
channel->id) == 0)
channel->id.data()) == 0)
name = xmpp_jid_resource(account->context, name);
ptr_buffer = channel ? channel->buffer : account->buffer;
if (name && (ptr_nick = weechat_nicklist_search_nick(ptr_buffer, NULL, name)))
if (name && (ptr_nick = weechat_nicklist_search_nick(ptr_buffer, nullptr, name)))
weechat_nicklist_remove_nick(ptr_buffer, ptr_nick);
}
struct t_user *user__new(struct t_account *account,
const char *id, const char *display_name)
weechat::user::user(weechat::account *account,
const char *id, const char *display_name)
{
struct t_user *new_user, *ptr_user;
if (!account || !id)
{
return NULL;
throw nullptr;
}
if (!account->users)
channel__add_nicklist_groups(account, NULL);
//if (account->users.empty())
// channel::add_nicklist_groups(account, nullptr);
ptr_user = user__search(account, id);
weechat::user *ptr_user = user::search(account, id);
if (ptr_user)
{
user__nicklist_add(account, NULL, ptr_user);
return ptr_user;
throw nullptr;
}
new_user = new struct t_user;
new_user->prev_user = account->last_user;
new_user->next_user = NULL;
if (account->last_user)
(account->last_user)->next_user = new_user;
else
account->users = new_user;
account->last_user = new_user;
//account->users += this;
new_user->id = strdup(id);
new_user->name = NULL;
this->id = strdup(id);
new_user->profile.avatar_hash = NULL;
new_user->profile.status_text = NULL;
new_user->profile.status = NULL;
new_user->profile.display_name = display_name ?
this->profile.display_name = display_name ?
strdup(display_name) : strdup("");
new_user->profile.affiliation = NULL;
new_user->profile.email = NULL;
new_user->profile.role = NULL;
new_user->profile.pgp_id = NULL;
new_user->profile.omemo = 0;
new_user->updated = 0;
new_user->is_away = 0;
user__nicklist_add(account, NULL, new_user);
return new_user;
}
void user__free(struct t_account *account,
struct t_user *user)
{
struct t_user *new_users;
if (!account || !user)
return;
/* remove user from users list */
if (account->last_user == user)
account->last_user = user->prev_user;
if (user->prev_user)
{
(user->prev_user)->next_user = user->next_user;
new_users = account->users;
}
else
new_users = user->next_user;
if (user->next_user)
(user->next_user)->prev_user = user->prev_user;
/* free user data */
if (user->id)
free(user->id);
if (user->name)
free(user->name);
if (user->profile.avatar_hash)
free(user->profile.avatar_hash);
if (user->profile.status_text)
free(user->profile.status_text);
if (user->profile.status)
free(user->profile.status);
if (user->profile.display_name)
free(user->profile.display_name);
if (user->profile.affiliation)
free(user->profile.affiliation);
if (user->profile.email)
free(user->profile.email);
if (user->profile.role)
free(user->profile.role);
delete user;
account->users = new_users;
}
void user__free_all(struct t_account *account)
{
while (account->users)
user__free(account, account->users);
nicklist_add(account, nullptr);
}

@ -4,60 +4,67 @@
#pragma once
#include <optional>
#include <memory>
#include <string>
#include <tl/optional.hpp>
struct t_user_profile
namespace weechat
{
char *avatar_hash;
char *status_text;
char *status;
tl::optional<std::string> idle;
char *display_name;
char *email;
char *role;
char *affiliation;
char *pgp_id;
int omemo;
};
struct t_user
{
char *id;
char *name;
struct t_user_profile profile;
int updated;
int is_away;
struct t_user *prev_user;
struct t_user *next_user;
};
class account;
class channel;
struct t_channel;
class user
{
private:
struct profile
{
char *avatar_hash = nullptr;
char *status_text = nullptr;
char *status = nullptr;
tl::optional<std::string> idle;
char *display_name = nullptr;
char *email = nullptr;
char *role = nullptr;
char *affiliation = nullptr;
char *pgp_id = nullptr;
int omemo = 0;
};
const char *user__get_colour(struct t_user *user);
private:
char *name = nullptr;
const char *user__as_prefix_raw(struct t_account *account,
const char *name);
bool updated = false;
const char *user__as_prefix(struct t_account *account,
struct t_user *user,
const char *name);
public:
char *id = nullptr;
bool is_away = false;
struct profile profile;
struct t_user *user__search(struct t_account *account,
const char *id);
public:
user(weechat::account *account, const char *id, const char *display_name);
struct t_user *user__new(struct t_account *account,
const char *id, const char *display_name);
static std::string get_colour(const char *name);
static std::string get_colour_for_nicklist(const char *name);
std::string get_colour();
std::string get_colour_for_nicklist();
static std::string as_prefix_raw(const char *name);
static std::string as_prefix(const char *name);
std::string as_prefix_raw();
std::string as_prefix();
void user__free_all(struct t_account *account);
static std::string as_prefix_raw(weechat::account *account, const char *id) {
auto found = std::unique_ptr<user>(search(account, id));
return found ? found->as_prefix_raw() : "";
}
static std::string as_prefix(weechat::account *account, const char *id) {
auto found = std::unique_ptr<user>(search(account, id));
return found ? found->as_prefix() : "";
}
void user__nicklist_add(struct t_account *account,
struct t_channel *channel,
struct t_user *user);
static weechat::user *bot_search(weechat::account *account, const char *pgp_id);
static weechat::user *search(weechat::account *account, const char *id);
void user__nicklist_remove(struct t_account *account,
struct t_channel *channel,
struct t_user *user);
void nicklist_add(weechat::account *account, weechat::channel *channel);
void nicklist_remove(weechat::account *account, weechat::channel *channel);
};
}

@ -15,8 +15,8 @@
#include <chrono>
#include <variant>
#include <fmt/core.h>
#include <strophe.h>
#include <tl/optional.hpp>
#include <strophe.h>
std::string get_name(xmpp_stanza_t *stanza);

Loading…
Cancel
Save