From df97397fc4adec3d13a23ab3571151d65973a7bc Mon Sep 17 00:00:00 2001 From: nmset Date: Sat, 14 Apr 2018 21:39:55 +0200 Subject: [PATCH] Add files via upload --- DBusSafWorkers.cpp | 59 ++++++ DBusSafWorkers.h | 72 +++++++ Makefile | 128 +++++++++++ README.md | 77 ++++++- SAF.cpp | 132 ++++++++++++ SAF.h | 107 ++++++++++ change.log | 25 +++ dbus_saf_adaptor.hpp | 107 ++++++++++ dbus_saf_proxy.hpp | 63 ++++++ gcc_version.h | 19 ++ globals.h | 26 +++ main.cpp | 200 ++++++++++++++++++ nbproject/Makefile-Debug.mk | 95 +++++++++ nbproject/Makefile-Release.mk | 95 +++++++++ nbproject/Makefile-impl.mk | 133 ++++++++++++ nbproject/Makefile-variables.mk | 35 +++ nbproject/Package-Debug.bash | 76 +++++++ nbproject/Package-Release.bash | 76 +++++++ nbproject/configurations.xml | 140 ++++++++++++ nbproject/private/Makefile-variables.mk | 7 + .../private/c_standard_headers_indexer.c | 75 +++++++ nbproject/private/configurations.xml | 80 +++++++ .../private/cpp_standard_headers_indexer.cpp | 135 ++++++++++++ nbproject/private/launcher.properties | 42 ++++ nbproject/private/private.xml | 11 + nbproject/project.xml | 31 +++ saf.xml | 12 ++ saf7-default.conf | 16 ++ saf7-default.rc.template | 23 ++ saf7-default.service | 14 ++ saf7_Quit.sh | 9 + saf7_SendMsg.sh | 18 ++ 32 files changed, 2136 insertions(+), 2 deletions(-) create mode 100644 DBusSafWorkers.cpp create mode 100644 DBusSafWorkers.h create mode 100644 Makefile create mode 100644 SAF.cpp create mode 100644 SAF.h create mode 100644 change.log create mode 100644 dbus_saf_adaptor.hpp create mode 100644 dbus_saf_proxy.hpp create mode 100644 gcc_version.h create mode 100644 globals.h create mode 100644 main.cpp create mode 100644 nbproject/Makefile-Debug.mk create mode 100644 nbproject/Makefile-Release.mk create mode 100644 nbproject/Makefile-impl.mk create mode 100644 nbproject/Makefile-variables.mk create mode 100644 nbproject/Package-Debug.bash create mode 100644 nbproject/Package-Release.bash create mode 100644 nbproject/configurations.xml create mode 100644 nbproject/private/Makefile-variables.mk create mode 100644 nbproject/private/c_standard_headers_indexer.c create mode 100644 nbproject/private/configurations.xml create mode 100644 nbproject/private/cpp_standard_headers_indexer.cpp create mode 100644 nbproject/private/launcher.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.xml create mode 100644 saf.xml create mode 100644 saf7-default.conf create mode 100644 saf7-default.rc.template create mode 100644 saf7-default.service create mode 100644 saf7_Quit.sh create mode 100644 saf7_SendMsg.sh diff --git a/DBusSafWorkers.cpp b/DBusSafWorkers.cpp new file mode 100644 index 0000000..9833d86 --- /dev/null +++ b/DBusSafWorkers.cpp @@ -0,0 +1,59 @@ +/* + * File: DBusSafWorkers.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 7 mai 2017, 15:18 + */ + +#include "gcc_version.h" +#include "DBusSafWorkers.h" +#include +#include + +using namespace std; + +extern bool g_verbose; + +DBusSafAdaptor::DBusSafAdaptor(DBus::Connection &connection, Connector * connector, SAFConnListener * saf) +: DBus::ObjectAdaptor(connection, "/xmpp/saf") +{ + m_connector = connector; + m_saf = saf; + thread t(Entry); + t.detach(); +} + +DBusSafAdaptor::~DBusSafAdaptor() +{ + DBus::default_dispatcher->leave(); +} + +int DBusSafAdaptor::Entry() +{ + DBus::default_dispatcher->enter(); // IS BLOCKING + return 0; +} + +void DBusSafAdaptor::Quit() +{ + // Handled in main.cpp + raise(SIGTERM); +} + +void DBusSafAdaptor::SendMsg(const std::string& recipient, const std::string& msg) +{ + const Message m(Message::MessageType::Chat, recipient, msg); + m_saf->GetClient()->send(m); +} + +DBusSafProxy::DBusSafProxy(DBus::Connection& connection, const char* service) +: DBus::ObjectProxy(connection, "/xmpp/saf", service) +{ +} + +DBusSafProxy::~DBusSafProxy() +{ + +} diff --git a/DBusSafWorkers.h b/DBusSafWorkers.h new file mode 100644 index 0000000..8f002fc --- /dev/null +++ b/DBusSafWorkers.h @@ -0,0 +1,72 @@ +/* + * File: DBusSafWorkers.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 7 mai 2017, 15:18 + */ + +#ifndef DBUSSAFWORKERS_H +#define DBUSSAFWORKERS_H + +#include "dbus_saf_adaptor.hpp" +#include "dbus_saf_proxy.hpp" +#include "SAF.h" +#include +#include + +using namespace gloox; + +/** + * The DBus application instance to which clients may talk. + * It is run in a thread and waits for messages to send. + */ +class DBusSafAdaptor : public xmpp::saf_adaptor, +public DBus::IntrospectableAdaptor, +public DBus::ObjectAdaptor +{ +public: + DBusSafAdaptor(DBus::Connection &connection, Connector * connector, SAFConnListener * saf); + virtual ~DBusSafAdaptor(); + + /** + * Sends a message to a recipient. + * @param recipient : a valid jid + * @param msg + */ + void SendMsg(const std::string& recipient, const std::string& msg) override; + + /** + * Sends SIGUSR1 signal, leading to disconnection from server + * and application exit. + */ + void Quit() override; + + /** + * Enters the DBus loop. + * @return + */ + static int Entry(); + +private: + /** + * gloox::Client object + */ + Connector * m_connector; + SAFConnListener * m_saf; +}; + +/** + * Unused proxy class. We don't need to talk to other application instances. + */ +class DBusSafProxy : public xmpp::saf_proxy, +public DBus::IntrospectableProxy, +public DBus::ObjectProxy +{ + DBusSafProxy(DBus::Connection &connection, const char * service); // Unused + virtual ~DBusSafProxy(); +}; + +#endif /* DBUSSAFWORKERS_H */ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..05de621 --- /dev/null +++ b/Makefile @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/README.md b/README.md index 969ba8b..45e92be 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,75 @@ -# saf7 -Send and Forget an XMPP message +SAF7 - Send And Forget an XMPP message. +License : GPL v2 + +This application is designed to send XMPP messages to arbitrary recipients +without expecting a reply. It is intended to run on servers to forward messages +to admins. Repeated problems with similar tools after system upgrade on Arch +Linux motivated writing this application. + +It uses gloox as XMPP library, and messages are sent to the application via +DBus. It runs on the system bus, and hence, must be run as root. + +USAGE +It must be started with two mandatory parameters : + --jid (-j) : a valid XMPP jid, the sender : ex. srv-admin@srv.domain.tld + --password (-w) : the sender's authotization token to connect to the server +Optional parameters may be used : + --resource (-r) : XMPP ressource label, default : SAF + --server (-s) : overrides the server part of the sender's jid + --port (-p) : overrides default XMPP 5222 port, default : 5222 nevertheless + --retry (-y) : Number of times to try to connect to server, default = 0 +(for ever) + --delay (-d) : Number of seconds between each connection attempt,default = +30 + --wsping (-g) : Number of seconds between each whitespace ping to the server +, default = 0 (never), at least 55 + --bustag (-t) : a suffix to the 'xmpp.saf-' bus name, default : default + --config (-c) : a simple key=value file, where above parameters can be +saved for simplicty + --verbose (-v) : Show messages. Command line only. + +DBUS CONSIDERATIONS +A policy file must be created in /etc/dbus-1/system.d/ , because the +application requests the system bus. A sample file is in the release package. +If --bustag is used, another policy file must be created to reflect this +parameter's significance. + +The default instance creates a DBus destination 'xmpp.saf-default', with path +/xmpp/saf. Two methods are available : Quit, and SendMsg. They can simply be +called as such : + +dbus-send --system --print-reply=literal --type=method_call +--dest=xmpp.saf-default /xmpp/saf xmpp.saf.SendMsg +string:recipient@srv.domain.tld string:"Server is about to crash!" + +dbus-send --system --print-reply=literal --type=method_call +--dest=xmpp.saf-default /xmpp/saf xmpp.saf.Quit + +If a bustag parameter is used, the created DBus destination is +'xmpp.saf-$(bustag)'. It is therefore possible to run multiple instances of the +application simultaneously, each instance having a different configuration file. + +XMPP NOTE +If the same sender's XMPP account is used in multiple instances, or on multiple +hosts, a different resource parameter MUST be used for each instance. + +FILES IN THE RELEASE ARCHIVE + -All project files as a NetBeans project. + -Convenience files : + saf7_SendMsg.sh : a bash script to send a message. It accepts the +recipient's address, the message, and optionally the bustag parameter if +relevant. + saf7_Quit.sh : a bash script to stop the application. Only root can do that, +as per applied DBus policy. It optionally accepts the bustag parameter. + saf7-default.rc.template : can simplify creating a configuration file. + saf7-default.conf : a DBus policy file for the default instance. Create +another one if bustag is used. + saf7-default.service : a systemd service file for the default instance. +Create another service file if bustag is used. + PKGBUILD : to create an Arch's package. After installation, create a +default /usr/local/etc/saf7/saf7-default.rc file with valid parameters. + +DISCLAIMER +I don't claim the application is fit for any purpose.Programming is just my hobby. + +Cheers ! diff --git a/SAF.cpp b/SAF.cpp new file mode 100644 index 0000000..97e86e7 --- /dev/null +++ b/SAF.cpp @@ -0,0 +1,132 @@ +/* + * File: SAF.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 6 mai 2017, 21:50 + */ + +#include "SAF.h" +#include "globals.h" +#include +#include + +extern bool g_verbose; +extern uint g_wsping; +extern Client * g_client; + +SAFConnListener::SAFConnListener(Client * client) +{ + m_client = client; + m_lastError = ConnectionError::ConnNotConnected; + + ConnErrorMap[ConnectionError::ConnNoError] = "Not really an error. Everything went just fine. "; + ConnErrorMap[ConnectionError::ConnStreamError] = "A stream error occured. The stream has been closed."; + ConnErrorMap[ConnectionError::ConnStreamVersionError] = "The incoming stream's version is not supported."; + ConnErrorMap[ConnectionError::ConnStreamClosed] = "The stream has been closed (by the server)."; + ConnErrorMap[ConnectionError::ConnProxyAuthRequired] = "The HTTP/SOCKS5 proxy requires authentication."; + ConnErrorMap[ConnectionError::ConnProxyAuthFailed] = "HTTP/SOCKS5 proxy authentication failed."; + ConnErrorMap[ConnectionError::ConnProxyNoSupportedAuth] = "The HTTP/SOCKS5 proxy requires an unsupported auth mechanism."; + ConnErrorMap[ConnectionError::ConnIoError] = "An I/O error occured. "; + ConnErrorMap[ConnectionError::ConnParseError] = "An XML parse error occurred. "; + ConnErrorMap[ConnectionError::ConnConnectionRefused] = "The connection was refused by the server (on the socket level)."; + ConnErrorMap[ConnectionError::ConnDnsError] = "Resolving the server's hostname failed."; + ConnErrorMap[ConnectionError::ConnOutOfMemory] = "Out of memory. Uhoh."; + ConnErrorMap[ConnectionError::ConnNoSupportedAuth] = "The auth mechanisms the server offers are not supported."; + ConnErrorMap[ConnectionError::ConnTlsFailed] = "The server's certificate could not be verified or the TLS handshake did not complete successfully."; + ConnErrorMap[ConnectionError::ConnTlsNotAvailable] = "The server didn't offer TLS while it was set to be required, or TLS was not compiled in."; + ConnErrorMap[ConnectionError::ConnCompressionFailed] = "Negotiating/initializing compression failed."; + ConnErrorMap[ConnectionError::ConnAuthenticationFailed] = "Authentication failed. Username/password wrong or account does not exist. Use ClientBase::authError() to find the reason."; + ConnErrorMap[ConnectionError::ConnUserDisconnected] = "The user (or higher-level protocol) requested a disconnect."; + ConnErrorMap[ConnectionError::ConnNotConnected] = "There is no active connection."; + + m_client->registerConnectionListener(this); + thread t(WhiteSpacePing, g_client, this); + t.detach(); +} + +SAFConnListener::~SAFConnListener() +{ +} + +void SAFConnListener::onConnect() +{ + m_lastError = ConnectionError::ConnNoError; + m_connector->ResetCounter(); + if (g_verbose) + cout << "Connected (" << m_client->jid().bare() << ")." << endl; +} + +void SAFConnListener::onDisconnect(ConnectionError e) +{ + m_lastError = e; + if (g_verbose) + cout << "Disconnected (" << m_client->jid().bare() << ")." << endl; + if (e == ConnNoError || e == ConnUserDisconnected) return; + cout << ConnErrorMap[e] << endl; +} + +bool SAFConnListener::onTLSConnect(const CertInfo& info) +{ + return true; +} + +void SAFConnListener::WhiteSpacePing(Client* client, SAFConnListener * saf) +{ + if (g_wsping == 0) return; + while (true) + { + sleep(g_wsping); + if (saf->GetLastError() == ConnectionError::ConnNoError) + client->whitespacePing(); + //cout << "Pinging the server." << endl; + } +} + +Connector::Connector(SAFConnListener * saf, const uint& retry, const uint& delay) +{ + m_saf = saf; + m_retry = retry; + m_delay = delay; + m_count = 0; + m_saf->SetConnector(this); +} + +Connector::~Connector() +{ + m_saf->GetClient()->disconnect(); +} + +void Connector::DoConnect() +{ + // At start, SAFConnListener has ConnNotConnected as last error + while (m_saf->GetLastError() != ConnectionError::ConnNoError) + { + bool res = m_saf->GetClient()->connect(); // Blocks on successful connect() + //If no connection is established, res can still be true ! + if (!res + /* If the server has been shutdown, we want to reconnect. + * Same thing if the server is not yet up. + */ + && m_saf->GetLastError() != ConnectionError::ConnConnectionRefused) + { + cout << "Cannot initiate a connection." + " Check network, server, or parameters." << endl; + break; + } + if (g_verbose) + cout << "Try " << m_count + << " : Waiting " << m_delay << " seconds" + << " before connecting..." << endl; + sleep(m_delay); + m_count++; + if (m_retry > 0 && m_count == m_retry) + { + if (g_verbose) + cout << "Giving up." << endl; + break; + } + } +} + diff --git a/SAF.h b/SAF.h new file mode 100644 index 0000000..6bbefd1 --- /dev/null +++ b/SAF.h @@ -0,0 +1,107 @@ +/* + * File: SAF.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 6 mai 2017, 21:50 + */ + +#ifndef SAF_H +#define SAF_H + +#include +using namespace std; +#include +#include +using namespace gloox; + +class Connector; +class SAFConnListener; + +/** + * gloox's connection listener. + */ +class SAFConnListener : public ConnectionListener +{ +public: + SAFConnListener(Client * client); + virtual ~SAFConnListener(); + + virtual void onConnect() override; + /** + * Shows significant error messages. + * @param e + */ + virtual void onDisconnect(ConnectionError e) override; + /** + * Mandatory. Always returns true. + * @param info + * @return + */ + virtual bool onTLSConnect(const CertInfo& info) override; + + ConnectionError GetLastError() + { + return m_lastError; + } + + Client * GetClient() const + { + return m_client; + } + + void SetConnector(Connector * connector) + { + m_connector = connector; + } + /** + * A server may disconnect an idle client. + * Prevents the application from being seen as idle. + * @param client + * @param saf + */ + static void WhiteSpacePing(Client * client, SAFConnListener * saf); +private: + typedef map mapErrors; + mapErrors ConnErrorMap; + + Client * m_client; + Connector * m_connector; + ConnectionError m_lastError; +}; + +/** + * Tries to connect to the server. + * Tries to reconnect if the server goes down, + * of if the server is not yet up. + * In all other cases where Client::connect fails, + * the application is allowed to exit. + */ +class Connector +{ +public: + Connector(SAFConnListener * saf, const uint& retry, const uint& delay); + /** + * Disconnects from server. + */ + virtual ~Connector(); + + void DoConnect(); + + /** + * Resets the number of times we have tried to (re)connect. + */ + void ResetCounter() + { + m_count = 0; + } +private: + SAFConnListener * m_saf; + uint m_retry; + uint m_delay; + uint m_count; +}; + +#endif /* SAF_H */ + diff --git a/change.log b/change.log new file mode 100644 index 0000000..e323ccb --- /dev/null +++ b/change.log @@ -0,0 +1,25 @@ +2018-04-14 +Move to github.com + +2017-06-02 +Version 4 +- Added a check for gcc version. Compile will succeed with gcc7.1 if +DBUS_HAS_RECURSIVE_MUTEX is defined. +- Added a DEVTIME preprocessor definition in the Debug config. This allows +contextual automatic selection of the bus to use when compiling. + +2017-05-16 +Version 3 +- Added an optional possibility to ping the server regularly. +- Tries to reconnect to the server if it goes down, or not yet up. Exits in all +other cases a connection cannot be completed. + +2017-05-12 +Version 2 +- Tries to connect many times on start. +- Tries to reconnect many times if server is shut down. +- Can exit immediately any time through signaling. +TODO : Detect and react to vanishing network link. + +2017-05-08 +Initial release, version 1. diff --git a/dbus_saf_adaptor.hpp b/dbus_saf_adaptor.hpp new file mode 100644 index 0000000..c213396 --- /dev/null +++ b/dbus_saf_adaptor.hpp @@ -0,0 +1,107 @@ + +/* + * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT! + */ + +#ifndef __dbusxx__dbus_saf_adaptor_hpp__ADAPTOR_MARSHAL_H +#define __dbusxx__dbus_saf_adaptor_hpp__ADAPTOR_MARSHAL_H + +#include +#include + +namespace xmpp { + +class saf_adaptor +: public ::DBus::InterfaceAdaptor +{ +public: + + saf_adaptor() + : ::DBus::InterfaceAdaptor("xmpp.saf") + { + register_method(saf_adaptor, Quit, _Quit_stub); + register_method(saf_adaptor, SendMsg, _SendMsg_stub); + } + + ::DBus::IntrospectedInterface *introspect() const + { + static ::DBus::IntrospectedArgument Quit_args[] = + { + { 0, "", false }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedArgument SendMsg_args[] = + { + { "recipient", "s", true }, + { "msg", "s", true }, + { 0, 0, 0 } + }; + static ::DBus::IntrospectedMethod saf_adaptor_methods[] = + { + { "Quit", Quit_args }, + { "SendMsg", SendMsg_args }, + { 0, 0 } + }; + static ::DBus::IntrospectedMethod saf_adaptor_signals[] = + { + { 0, 0 } + }; + static ::DBus::IntrospectedProperty saf_adaptor_properties[] = + { + { 0, 0, 0, 0 } + }; + static ::DBus::IntrospectedInterface saf_adaptor_interface = + { + "xmpp.saf", + saf_adaptor_methods, + saf_adaptor_signals, + saf_adaptor_properties + }; + return &saf_adaptor_interface; + } + +public: + + /* properties exposed by this interface, use + * property() and property(value) to get and set a particular property + */ + +public: + + /* methods exported by this interface, + * you will have to implement them in your ObjectAdaptor + */ + virtual void Quit() = 0; + virtual void SendMsg(const std::string& recipient, const std::string& msg) = 0; + +public: + + /* signal emitters for this interface + */ + +private: + + /* unmarshalers (to unpack the DBus message before calling the actual interface method) + */ + ::DBus::Message _Quit_stub(const ::DBus::CallMessage &call) + { + ::DBus::MessageIter ri = call.reader(); + + Quit(); + ::DBus::ReturnMessage reply(call); + return reply; + } + ::DBus::Message _SendMsg_stub(const ::DBus::CallMessage &call) + { + ::DBus::MessageIter ri = call.reader(); + + std::string argin1; ri >> argin1; + std::string argin2; ri >> argin2; + SendMsg(argin1, argin2); + ::DBus::ReturnMessage reply(call); + return reply; + } +}; + +} +#endif //__dbusxx__dbus_saf_adaptor_hpp__ADAPTOR_MARSHAL_H diff --git a/dbus_saf_proxy.hpp b/dbus_saf_proxy.hpp new file mode 100644 index 0000000..06d9e9f --- /dev/null +++ b/dbus_saf_proxy.hpp @@ -0,0 +1,63 @@ + +/* + * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT! + */ + +#ifndef __dbusxx__dbus_saf_proxy_hpp__PROXY_MARSHAL_H +#define __dbusxx__dbus_saf_proxy_hpp__PROXY_MARSHAL_H + +#include +#include + +namespace xmpp { + +class saf_proxy +: public ::DBus::InterfaceProxy +{ +public: + + saf_proxy() + : ::DBus::InterfaceProxy("xmpp.saf") + { + } + +public: + + /* properties exported by this interface */ +public: + + /* methods exported by this interface, + * this functions will invoke the corresponding methods on the remote objects + */ + void Quit() + { + ::DBus::CallMessage call; + call.member("Quit"); + ::DBus::Message ret = invoke_method (call); + } + + void SendMsg(const std::string& recipient, const std::string& msg) + { + ::DBus::CallMessage call; + ::DBus::MessageIter wi = call.writer(); + + wi << recipient; + wi << msg; + call.member("SendMsg"); + ::DBus::Message ret = invoke_method (call); + } + + +public: + + /* signal handlers for this interface + */ + +private: + + /* unmarshalers (to unpack the DBus message before calling the actual signal handler) + */ +}; + +} +#endif //__dbusxx__dbus_saf_proxy_hpp__PROXY_MARSHAL_H diff --git a/gcc_version.h b/gcc_version.h new file mode 100644 index 0000000..857dc99 --- /dev/null +++ b/gcc_version.h @@ -0,0 +1,19 @@ +/* + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 2 juin 2017, 17:35 + */ + +#ifndef GCC_VERSION_H +#define GCC_VERSION_H + +// Include at top of every file dealing with DBus + +#if __GNUC__ == 7 +#define DBUS_HAS_RECURSIVE_MUTEX +#endif + +#endif /* GCC_VERSION_H */ + diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..9a2f072 --- /dev/null +++ b/globals.h @@ -0,0 +1,26 @@ +/* + * File: globals.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 6 mai 2017, 18:23 + */ + +#ifndef GLOBALS_H +#define GLOBALS_H + +#include +using namespace std; + +#define _APPNAME_ "saf7" // Send and forget +#define _APP_DESCRIPTION_ "Send and forget an XMPP message" +#define _VERSION_ "4" +#define _AUTHOR_ "SET, M.D., nmset@netcourrier.com" +#define _ABOUT_ string(_APPNAME_) + string(" - version ") + string(_VERSION_) \ + + string(" - ") + string(_APP_DESCRIPTION_) \ + + string("\nAuthor : ") + string(_AUTHOR_) \ + + string("\nLicense : GPL v2") + +#endif /* GLOBALS_H */ + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..0ae4a0c --- /dev/null +++ b/main.cpp @@ -0,0 +1,200 @@ +/* + * File: main.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2017 + * + * Created on 6 mai 2017, 18:21 + */ + +#include "gcc_version.h" +#include +#include +#include "SAF.h" +#include "globals.h" +#include +#include +#include +#include +#include +#include +#include "DBusSafWorkers.h" + +using namespace std; +namespace po = boost::program_options; + +string g_config = ""; // A configuration file. +string g_jid = ""; +string g_password = ""; +string g_resource = "SAF"; +string g_server = ""; +string g_tag = "default"; +uint g_port = 5222; +uint g_retry = 0; +uint g_delay = 30; +uint g_wsping = 0; +bool g_verbose = false; + +gloox::Client * g_client = NULL; +DBus::BusDispatcher g_dispatcher; +SAFConnListener * g_saf = NULL; +Connector * g_connector = NULL; +DBusSafAdaptor * g_adaptor_worker = NULL; + +/** + * TODO : Detect and react to vanishing network link. + */ + +/* + * http://www.radmangames.com/programming/how-to-use-boost-program_options + * https://blog.knatten.org/2012/03/23/basic-gloox-tutorial/ + * https://camaya.net/api/gloox-1.0.20/ + */ + +/** + * Cleaup and exit. Return code is 0 because we want to exit this way. + * @param sn + */ +void signalhandler(int sn) +{ + delete g_connector; + /* Cant delete adaptor_worker without a seg fault, this function is called from there. + * Anyway, we are exiting. + */ + //delete adaptor_worker; + delete g_client; + delete g_saf; + if (g_verbose) + cout << "Signaled to exit." << endl; + exit(0); +} + +bool GetAndValidateParams(int argc, char** argv) +{ + try + { + po::options_description desc(_ABOUT_); + desc.add_options() + ("help,h", "Print help messages") + ("jid,j", po::value(&g_jid), "Full JID without resource") + ("password,w", po::value(&g_password), "Password") + ("resource,r", po::value(&g_resource), "Resource (optional)") + ("server,s", po::value(&g_server), "Server (optional)") + ("port,p", po::value(&g_port), "Port (optional), default = 5222") + ("retry,y", po::value(&g_retry), "Number of times to try to connect to server (optional), default = 0 (for ever)") + ("delay,d", po::value(&g_delay), "Number of seconds between each connection attempt (optional), default = 30") + ("wsping,g", po::value(&g_wsping), "Number of seconds between each whitespace ping to the server (optional), default = 0 (never), at least 55") + ("bustag,t", po::value(&g_tag), "Bus name tag (optional), default=default") + ("config,c", po::value(&g_config), "Use specified configuration file (optional), else, pass all parameters on the command line") + ("verbose,v", "Show messages (optional). Command line only."); + + po::variables_map vm; + po::variables_map vmc; + try + { + po::store(po::parse_command_line(argc, argv, desc), vm); + if (vm.count("help")) + { + cout << desc << endl; + return 0; + } + po::notify(vm); + if (vm.count("verbose")) + { + g_verbose = true; + } + /* + * If a config file is in the command line, + * its content overrides all other parameters. + */ + if (vm.count("config")) + { + ifstream f(g_config); + if (f.fail()) + { + cerr << "Failure with file : " << g_config << endl; + return 0; + } + po::store(po::parse_config_file(f, desc), vmc); + po::notify(vmc); + } + } + catch (po::error& eb) + { + cerr << "Error : " << eb.what() << endl; + return 0; + } + } + catch (exception& e) + { + cerr << "Error : " << e.what() << endl; + return 0; + } + + if (g_jid.empty()) + { + cout << "jid missing." << endl; + return 0; + } + if (g_password.empty()) + { + cout << "password missing." << endl; + return 0; + } + if (g_wsping > 0 && g_wsping < 55 ) + { + cout << "wsping must be at least 55 seconds." << endl; + return 0; + } + return true; +} + +DBusSafAdaptor* StartDBusAdaptor(Connector * connector, SAFConnListener * saf) +{ + DBus::_init_threading(); + DBus::default_dispatcher = &g_dispatcher; +#ifdef DEVTIME // Defined in Debug NetBeans configuration + DBus::Connection bus = DBus::Connection::SessionBus(); +#else + DBus::Connection bus = DBus::Connection::SystemBus(); +#endif + const string busName = string("xmpp.saf-") + g_tag; + bus.request_name(busName.data()); + DBusSafAdaptor * adaptor_worker = new DBusSafAdaptor(bus, connector, saf); + + return adaptor_worker; +} + +int main(int argc, char** argv) +{ + + if (!GetAndValidateParams(argc, argv)) + return 0; + + signal(SIGINT, signalhandler); + signal(SIGTERM, signalhandler); + + JID ajid(g_jid + "/" + g_resource); + g_client = new Client(ajid, g_password, g_port); + if (!g_server.empty()) + g_client->setServer(g_server); + g_client->setPort(g_port); + g_client->disco()->setIdentity("client", "7", "saf"); + + g_saf = new SAFConnListener(g_client); + g_connector = new Connector(g_saf, g_retry, g_delay); + // Listen on DBus + g_adaptor_worker = StartDBusAdaptor(g_connector, g_saf); + // Connect to server + g_connector->DoConnect(); // Blocks + + //cout << g_client->getStatistics().encryption << endl; + + delete g_adaptor_worker; + delete g_connector; + delete g_client; + delete g_saf; + + return 0; +} + diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk new file mode 100644 index 0000000..e93462a --- /dev/null +++ b/nbproject/Makefile-Debug.mk @@ -0,0 +1,95 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/DBusSafWorkers.o \ + ${OBJECTDIR}/SAF.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-pthread +CXXFLAGS=-pthread + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-lboost_program_options -lgloox -ldbus-c++-1 + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/DBusSafWorkers.o: DBusSafWorkers.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDBUS_API_SUBJECT_TO_CHANGE -DDEVTIME -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/DBusSafWorkers.o DBusSafWorkers.cpp + +${OBJECTDIR}/SAF.o: SAF.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDBUS_API_SUBJECT_TO_CHANGE -DDEVTIME -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/SAF.o SAF.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDBUS_API_SUBJECT_TO_CHANGE -DDEVTIME -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk new file mode 100644 index 0000000..8951135 --- /dev/null +++ b/nbproject/Makefile-Release.mk @@ -0,0 +1,95 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/DBusSafWorkers.o \ + ${OBJECTDIR}/SAF.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-pthread +CXXFLAGS=-pthread + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-lboost_program_options -lgloox -ldbus-c++-1 + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 ${OBJECTFILES} ${LDLIBSOPTIONS} -s + +${OBJECTDIR}/DBusSafWorkers.o: DBusSafWorkers.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/DBusSafWorkers.o DBusSafWorkers.cpp + +${OBJECTDIR}/SAF.o: SAF.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/SAF.o SAF.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/include/dbus-c++-1 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-impl.mk b/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..b0487eb --- /dev/null +++ b/nbproject/Makefile-impl.mk @@ -0,0 +1,133 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=saf7 + +# Active Configuration +DEFAULTCONF=Debug +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=Debug Release + + +# build +.build-impl: .build-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf + + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ + done + +# all +.all-impl: .all-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ + done + +# build tests +.build-tests-impl: .build-impl .build-tests-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf + +# run tests +.test-impl: .build-tests-impl .test-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf + +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi + +# configuration validation +.validate-impl: + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + echo ""; \ + echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ + echo "See 'make help' for details."; \ + echo "Current directory: " `pwd`; \ + echo ""; \ + fi + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + exit 1; \ + fi + + +# help +.help-impl: .help-pre + @echo "This makefile supports the following configurations:" + @echo " ${ALLCONFS}" + @echo "" + @echo "and the following targets:" + @echo " build (default target)" + @echo " clean" + @echo " clobber" + @echo " all" + @echo " help" + @echo "" + @echo "Makefile Usage:" + @echo " make [CONF=] [SUB=no] build" + @echo " make [CONF=] [SUB=no] clean" + @echo " make [SUB=no] clobber" + @echo " make [SUB=no] all" + @echo " make help" + @echo "" + @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," + @echo " also clean subprojects." + @echo "Target 'clobber' will remove all built files from all configurations and," + @echo " unless 'SUB=no', also from subprojects." + @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'help' prints this message." + @echo "" + diff --git a/nbproject/Makefile-variables.mk b/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..b400f26 --- /dev/null +++ b/nbproject/Makefile-variables.mk @@ -0,0 +1,35 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +CND_BUILDDIR=build +CND_DISTDIR=dist +# Debug configuration +CND_PLATFORM_Debug=GNU-Linux +CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux +CND_ARTIFACT_NAME_Debug=saf7 +CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux/saf7 +CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package +CND_PACKAGE_NAME_Debug=saf7.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/saf7.tar +# Release configuration +CND_PLATFORM_Release=GNU-Linux +CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux +CND_ARTIFACT_NAME_Release=saf7 +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/saf7 +CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package +CND_PACKAGE_NAME_Release=saf7.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/saf7.tar +# +# include compiler specific variables +# +# dmake command +ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \ + (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk) +# +# gmake command +.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)) +# +include nbproject/private/Makefile-variables.mk diff --git a/nbproject/Package-Debug.bash b/nbproject/Package-Debug.bash new file mode 100644 index 0000000..aee7d5a --- /dev/null +++ b/nbproject/Package-Debug.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 +OUTPUT_BASENAME=saf7 +PACKAGE_TOP_DIR=saf7/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/saf7/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/saf7.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/saf7.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/Package-Release.bash b/nbproject/Package-Release.bash new file mode 100644 index 0000000..354b304 --- /dev/null +++ b/nbproject/Package-Release.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/saf7 +OUTPUT_BASENAME=saf7 +PACKAGE_TOP_DIR=saf7/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/saf7/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/saf7.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/saf7.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..001bb6f --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,140 @@ + + + + + DBusSafWorkers.h + SAF.h + gcc_version.h + globals.h + + + + + DBusSafWorkers.cpp + SAF.cpp + dbus_saf_adaptor.hpp + dbus_saf_proxy.hpp + main.cpp + + + + + Makefile + PKGBUILD + change.log + saf.xml + saf7-default.conf + saf7-default.rc.template + saf7-default.service + saf7_Quit.sh + saf7_SendMsg.sh + + + Makefile + + + + default + true + false + + + + + /usr/include/dbus-1.0 + /usr/include/dbus-c++-1 + + -pthread + + DBUS_API_SUBJECT_TO_CHANGE + DEVTIME + + + + + boost_program_options + gloox + dbus-c++-1 + + + + + + + + + + + + + + + + + + + + + + + + + default + true + false + + + + 5 + true + + /usr/include/dbus-1.0 + /usr/include/dbus-c++-1 + + -pthread + + DBUS_API_SUBJECT_TO_CHANGE + + + + true + + boost_program_options + gloox + dbus-c++-1 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/private/Makefile-variables.mk b/nbproject/private/Makefile-variables.mk new file mode 100644 index 0000000..a64183e --- /dev/null +++ b/nbproject/private/Makefile-variables.mk @@ -0,0 +1,7 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +# Debug configuration +# Release configuration diff --git a/nbproject/private/c_standard_headers_indexer.c b/nbproject/private/c_standard_headers_indexer.c new file mode 100644 index 0000000..c2548d2 --- /dev/null +++ b/nbproject/private/c_standard_headers_indexer.c @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/c/header + +#include // Conditionally compiled macro that compares its argument to zero +#include // Functions to determine the type contained in character data +#include // Macros reporting error conditions +#include // Limits of float types +#include // Sizes of basic types +#include // Localization utilities +#include // Common mathematics functions +#include // Nonlocal jumps +#include // Signal handling +#include // Variable arguments +#include // Common macro definitions +#include // Input/output +#include // String handling +#include // General utilities: memory management, program utilities, string conversions, random numbers +#include // Time/date utilities +#include // (since C95) Alternative operator spellings +#include // (since C95) Extended multibyte and wide character utilities +#include // (since C95) Wide character classification and mapping utilities +#ifdef _STDC_C99 +#include // (since C99) Complex number arithmetic +#include // (since C99) Floating-point environment +#include // (since C99) Format conversion of integer types +#include // (since C99) Boolean type +#include // (since C99) Fixed-width integer types +#include // (since C99) Type-generic math (macros wrapping math.h and complex.h) +#endif +#ifdef _STDC_C11 +#include // (since C11) alignas and alignof convenience macros +#include // (since C11) Atomic types +#include // (since C11) noreturn convenience macros +#include // (since C11) Thread library +#include // (since C11) UTF-16 and UTF-32 character utilities +#endif diff --git a/nbproject/private/configurations.xml b/nbproject/private/configurations.xml new file mode 100644 index 0000000..9e0cd87 --- /dev/null +++ b/nbproject/private/configurations.xml @@ -0,0 +1,80 @@ + + + Makefile + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + "${OUTPUT_PATH}" -c /home/user/.xmpp-saf.rc + "${OUTPUT_PATH}" -c /home/user/saf7-default.rc + "${OUTPUT_PATH}" -c /home/user/.saf7-default.rc + "${OUTPUT_PATH}" -c /home/user/.saf7-pro.rc + "${OUTPUT_PATH}" -v -c /home/user/.saf7-pro.rc + + "${OUTPUT_PATH}" -v -c /home/user/.saf7-pro.rc + + true + 0 + 0 + + + + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + "${OUTPUT_PATH}" -c /home/user/.xmpp-saf.rc + "${OUTPUT_PATH}" -c /home/user/.saf7-defaultrc + "${OUTPUT_PATH}" -c /home/user/.saf7-default.rc + + "${OUTPUT_PATH}" -c /home/user/.saf7-default.rc + + true + 0 + 0 + + + + + + diff --git a/nbproject/private/cpp_standard_headers_indexer.cpp b/nbproject/private/cpp_standard_headers_indexer.cpp new file mode 100644 index 0000000..04f6fa6 --- /dev/null +++ b/nbproject/private/cpp_standard_headers_indexer.cpp @@ -0,0 +1,135 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/cpp/header + +#include // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search +#include // Functions and macro constants for signal management +#include // Macro (and function) that saves (and jumps) to an execution context +#include // Handling of variable length argument lists +#include // Runtime type information utilities +#include // std::bitset class template +#include // Function objects, designed for use with the standard algorithms +#include // Various utility components +#include // C-style time/date utilites +#include // typedefs for types such as size_t, NULL and others +#include // Low-level memory management utilities +#include // Higher level memory management utilities +#include // limits of integral types +#include // limits of float types +#include // standardized way to query properties of arithmetic types +#include // Exception handling utilities +#include // Standard exception objects +#include // Conditionally compiled macro that compares its argument to zero +#include // Macro containing the last error number +#include // functions to determine the type contained in character data +#include // functions for determining the type of wide character data +#include // various narrow character string handling functions +#include // various wide and multibyte string handling functions +#include // std::basic_string class template +#include // std::vector container +#include // std::deque container +#include // std::list container +#include // std::set and std::multiset associative containers +#include // std::map and std::multimap associative containers +#include // std::stack container adaptor +#include // std::queue and std::priority_queue container adaptors +#include // Algorithms that operate on containers +#include // Container iterators +#include // Common mathematics functions +#include // Complex number type +#include // Class for representing and manipulating arrays of values +#include // Numeric operations on values in containers +#include // forward declarations of all classes in the input/output library +#include // std::ios_base class, std::basic_ios class template and several typedefs +#include // std::basic_istream class template and several typedefs +#include // std::basic_ostream, std::basic_iostream class templates and several typedefs +#include // several standard stream objects +#include // std::basic_fstream, std::basic_ifstream, std::basic_ofstream class templates and several typedefs +#include // std::basic_stringstream, std::basic_istringstream, std::basic_ostringstream class templates and several typedefs +#include // std::strstream, std::istrstream, std::ostrstream(deprecated) +#include // Helper functions to control the format or input and output +#include // std::basic_streambuf class template +#include // C-style input-output functions +#include // Localization utilities +#include // C localization utilities +#include // empty header. The macros that appear in iso646.h in C are keywords in C++ +#if __cplusplus >= 201103L +#include // (since C++11) std::type_index +#include // (since C++11) Compile-time type information +#include // (since C++11) C++ time utilites +#include // (since C++11) std::initializer_list class template +#include // (since C++11) std::tuple class template +#include // (since C++11) Nested allocator class +#include // (since C++11) fixed-size types and limits of other types +#include // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions +#include // (since C++11) defines std::error_code, a platform-dependent error code +#include // (since C++11) C-style Unicode character conversion functions +#include // (since C++11) std::array container +#include // (since C++11) std::forward_list container +#include // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers +#include // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers +#include // (since C++11) Random number generators and distributions +#include // (since C++11) Compile-time rational arithmetic +#include // (since C++11) Floating-point environment access functions +#include // (since C++11) Unicode conversion facilities +#include // (since C++11) Classes, algorithms and iterators to support regular expression processing +#include // (since C++11) Atomic operations library +#include // (since C++11)(deprecated in C++17) simply includes the header +#include // (since C++11)(deprecated in C++17) simply includes the headers (until C++17) (since C++17) and : the overloads equivalent to the contents of the C header tgmath.h are already provided by those headers +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11) std::thread class and supporting functions +#include // (since C++11) mutual exclusion primitives +#include // (since C++11) primitives for asynchronous computations +#include // (since C++11) thread waiting conditions +#endif +#if __cplusplus >= 201300L +#include // (since C++14) shared mutual exclusion primitives +#endif +#if __cplusplus >= 201500L +#include // (since C++17) std::any class template +#include // (since C++17) std::optional class template +#include // (since C++17) std::variant class template +#include // (since C++17) Polymorphic allocators and memory resources +#include // (since C++17) std::basic_string_view class template +#include // (since C++17) Predefined execution policies for parallel versions of the algorithms +#include // (since C++17) std::path class and supporting functions +#endif diff --git a/nbproject/private/launcher.properties b/nbproject/private/launcher.properties new file mode 100644 index 0000000..3edc2d8 --- /dev/null +++ b/nbproject/private/launcher.properties @@ -0,0 +1,42 @@ +# Launchers File syntax: +# +# [Must-have property line] +# launcher1.runCommand= +# [Optional extra properties] +# launcher1.displayName= +# launcher1.hide= +# launcher1.buildCommand= +# launcher1.runDir= +# launcher1.runInOwnTab= +# launcher1.symbolFiles= +# launcher1.env.= +# (If this value is quoted with ` it is handled as a native command which execution result will become the value) +# [Common launcher properties] +# common.runDir= +# (This value is overwritten by a launcher specific runDir value if the latter exists) +# common.env.= +# (Environment variables from common launcher are merged with launcher specific variables) +# common.symbolFiles= +# (This value is overwritten by a launcher specific symbolFiles value if the latter exists) +# +# In runDir, symbolFiles and env fields you can use these macroses: +# ${PROJECT_DIR} - project directory absolute path +# ${OUTPUT_PATH} - linker output path (relative to project directory path) +# ${OUTPUT_BASENAME}- linker output filename +# ${TESTDIR} - test files directory (relative to project directory path) +# ${OBJECTDIR} - object files directory (relative to project directory path) +# ${CND_DISTDIR} - distribution directory (relative to project directory path) +# ${CND_BUILDDIR} - build directory (relative to project directory path) +# ${CND_PLATFORM} - platform name +# ${CND_CONF} - configuration name +# ${CND_DLIB_EXT} - dynamic library extension +# +# All the project launchers must be listed in the file! +# +# launcher1.runCommand=... +# launcher2.runCommand=... +# ... +# common.runDir=... +# common.env.KEY=VALUE + +# launcher1.runCommand= \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..aef7ea3 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,11 @@ + + + + 1 + 0 + + + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..d6249f9 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,31 @@ + + + org.netbeans.modules.cnd.makeproject + + + saf7 + + cpp + h,hpp + UTF-8 + + + + + Debug + 1 + + + Release + 1 + + + + true + Apache|Apache + Apache|Apache + Apache|Apache + + + + diff --git a/saf.xml b/saf.xml new file mode 100644 index 0000000..0ba7741 --- /dev/null +++ b/saf.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/saf7-default.conf b/saf7-default.conf new file mode 100644 index 0000000..d7265c7 --- /dev/null +++ b/saf7-default.conf @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/saf7-default.rc.template b/saf7-default.rc.template new file mode 100644 index 0000000..f0bb454 --- /dev/null +++ b/saf7-default.rc.template @@ -0,0 +1,23 @@ +jid=user@host.domain.tld +password=your_password + +#resource : Optional. Default : SAF +#resource=SAF + +#server : Optional +#server=host.domain.tld + +#port : Optional. Default : 5222 +#port=5222 + +#bustag : Optional. Default : default +#bustag=default + +#retry : Optional. Number of times to try a connection. Default = 0 (for ever) +#retry=0 + +#delay : Optional. Number of seconds between each connection attempt. Default = 30 +#delay=30 + +#wsping : Optional. Number of seconds between each whitespace ping to the server, default = 0 (never), at least 55 +#wsping=0 diff --git a/saf7-default.service b/saf7-default.service new file mode 100644 index 0000000..302d485 --- /dev/null +++ b/saf7-default.service @@ -0,0 +1,14 @@ +[Unit] +Description=XMPP send and forget : saf7 +Requires=network.target +After=network.target + +[Service] +Type=dbus +BusName=xmpp.saf-default +ExecStart=/usr/local/bin/saf7 -c /usr/local/etc/saf7/saf7-default.rc +User=root + +[Install] +WantedBy=multi-user.target + diff --git a/saf7_Quit.sh b/saf7_Quit.sh new file mode 100644 index 0000000..33dbb73 --- /dev/null +++ b/saf7_Quit.sh @@ -0,0 +1,9 @@ +#/bin/sh + +TAG="default" +[ -n "$1" ] && TAG="$1" + +dbus-send --system --type=method_call --dest=xmpp.saf-"$TAG" /xmpp/saf xmpp.saf.Quit + +exit 0 + diff --git a/saf7_SendMsg.sh b/saf7_SendMsg.sh new file mode 100644 index 0000000..6618410 --- /dev/null +++ b/saf7_SendMsg.sh @@ -0,0 +1,18 @@ +#/bin/sh + +if [ $# -lt 2 ];then + echo "Arg 1 : full jid without resource." + echo "Arg 2 : message." + echo "Arg 3 : bus name tag. Optional. Default = default ." + exit 0 +fi + +RECIPIENT="$1" +MSG="$2" +TAG="default" +[ -n "$3" ] && TAG="$3" + +dbus-send --system --print-reply=literal --type=method_call --dest=xmpp.saf-"$TAG" /xmpp/saf xmpp.saf.SendMsg string:"$RECIPIENT" string:"$MSG" + +exit 0 +