From 5bc547b1217224fb0632a33031f2adc6942a0836 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Sat, 22 Apr 2023 15:56:41 +0200 Subject: [PATCH 1/5] add better connection information --- src/connectionstartframe.h | 17 ++++++--- src/platformname.h | 69 +++++++++++++++++++++++++++++++++++ src/programname.h | 75 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 src/platformname.h create mode 100644 src/programname.h diff --git a/src/connectionstartframe.h b/src/connectionstartframe.h index a203046..27701bf 100644 --- a/src/connectionstartframe.h +++ b/src/connectionstartframe.h @@ -5,9 +5,15 @@ * is opened. It contains the initial connection properties, and the protocol * number. * - * @copyright 2014 - 2022 Copernica BV + * @copyright 2014 - 2023 Copernica BV */ +/** + * Dependencies + */ +#include "programname.h" +#include "platformname.h" + /** * Set up namespace */ @@ -200,11 +206,11 @@ public: capabilities["consumer_cancel_notify"] = true; // fill the peer properties - if (!properties.contains("product")) properties["product"] = "Copernica AMQP library"; + if (!properties.contains("product")) properties["product"] = ProgramName(); if (!properties.contains("version")) properties["version"] = "Unknown"; - if (!properties.contains("platform")) properties["platform"] = "Unknown"; - if (!properties.contains("copyright")) properties["copyright"] = "Copyright 2015 - 2018 Copernica BV"; - if (!properties.contains("information")) properties["information"] = "https://www.copernica.com"; + if (!properties.contains("platform")) properties["platform"] = PlatformName(); + if (!properties.contains("copyright")) properties["copyright"] = "Copernica AMQP-CPP library :: Copyright 2015-2023 Copernica BV"; + if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP"; if (!properties.contains("capabilities")) properties["capabilities"] = capabilities; // send back a connection start ok frame @@ -213,6 +219,7 @@ public: // done return true; } + }; /** diff --git a/src/platformname.h b/src/platformname.h new file mode 100644 index 0000000..af89410 --- /dev/null +++ b/src/platformname.h @@ -0,0 +1,69 @@ +/** + * PlatformName.h + * + * Class to extract the platform name (operating system, etc) + * + * @author Emiel Bruijntjes + * @copyright 2023 Copernica BV + */ + +/** + * Include guard + */ +#pragma once + +/** + * Dependencies + */ +#include + +/** + * Begin of namespace + */ +namespace AMQP { + +/** + * Class definition + */ +class PlatformName +{ +private: + /** + * The string holding all info + * @var std::string + */ + std::string _value; + +public: + /** + * Constructor + */ + PlatformName() + { + // all information + struct utsname sysinfo; + + // retrieve system info + if (uname(&sysinfo) != 0) return; + + // add all info + _value.append(sysinfo.sysname).append(" ").append(sysinfo.version).append(" ").append(sysinfo.release).append(" running on ").append(sysinfo.nodename); + } + + /** + * Destructor + */ + virtual ~PlatformName() = default; + + /** + * Cast to a const char * + * @return const char * + */ + operator const char * () const { return _value.data(); } +}; + +/** + * End of namespace + */ +} + diff --git a/src/programname.h b/src/programname.h new file mode 100644 index 0000000..3fd892d --- /dev/null +++ b/src/programname.h @@ -0,0 +1,75 @@ +/** + * ProgramName.h + * + * Helper class that detects the name of the program + * + * @author Emiel Bruijntjes + * @copyright 2023 Copernica BV + */ + +/** + * Include guard + */ +#pragma once + +/** + * Dependencies + */ +#include +#include + +/** + * Begin of namespace + */ +namespace AMQP { + +/** + * Class definition + */ +class ProgramName +{ +private: + /** + * Path of the program + * @var char[] + */ + char _path[PATH_MAX]; + + /** + * Is the _path valid? + * @var bool + */ + bool _valid; + +public: + /** + * Constructor + */ + ProgramName() : _valid(readlink("/proc/self/exe", _path, PATH_MAX) == 0) {} + + /** + * Destructor + */ + virtual ~ProgramName() = default; + + /** + * Cast to a const char * + * @return const char * + */ + operator const char * () const + { + // empty string when not valid + if (!_valid) return ""; + + // locate the last slash + auto *slash = strrchr(_path, '/'); + + // if not found return entire path, otherwise just the program name + return slash ? slash + 1 : _path; + } +}; + +/** + * End of namespace + */ +} From d8550894ba193e5dd39ee687f1bef7106d8982fd Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Sat, 22 Apr 2023 16:33:31 +0200 Subject: [PATCH 2/5] include version number of amqp-cpp, longer product name, change order of platform info --- Makefile | 10 +++++----- src/Makefile | 2 +- src/connectionstartframe.h | 14 +++++++++++++- src/platformname.h | 6 +++--- src/programname.h | 19 +++++++++++++------ 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index d460001..6f9254c 100644 --- a/Makefile +++ b/Makefile @@ -6,19 +6,19 @@ export SONAME = 4.3 export VERSION = 4.3.24 all: - $(MAKE) -C src all + $(MAKE) VERSION=${VERSION} -C src all pure: - $(MAKE) -C src pure + $(MAKE) VERSION=${VERSION} -C src pure release: - $(MAKE) -C src release + $(MAKE) VERSION=${VERSION} -C src release static: - $(MAKE) -C src static + $(MAKE) VERSION=${VERSION} -C src static shared: - $(MAKE) -C src shared + $(MAKE) VERSION=${VERSION} -C src shared clean: $(MAKE) -C src clean diff --git a/src/Makefile b/src/Makefile index c8c4401..d96674e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ CPP = g++ RM = rm -f -CPPFLAGS = -Wall -c -I../include -std=c++17 -MD -Wno-class-conversion +CPPFLAGS = -Wall -c -I../include -std=c++17 -MD -Wno-class-conversion -DVERSION=${VERSION} LD = g++ LD_FLAGS = -Wall -shared SHARED_LIB = lib$(LIBRARY_NAME).so.$(VERSION) diff --git a/src/connectionstartframe.h b/src/connectionstartframe.h index 27701bf..a7658e9 100644 --- a/src/connectionstartframe.h +++ b/src/connectionstartframe.h @@ -14,6 +14,18 @@ #include "programname.h" #include "platformname.h" +/** + * Cause we want to print out version string that is passed to compiled with -D + * flag. Why 2 macros? https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/ + */ +#define STR_EXPAND(s) #s +#define STR(s) STR_EXPAND(s) + +/** + * The version and distro names + */ +#define VERSION_NAME STR(VERSION) + /** * Set up namespace */ @@ -207,7 +219,7 @@ public: // fill the peer properties if (!properties.contains("product")) properties["product"] = ProgramName(); - if (!properties.contains("version")) properties["version"] = "Unknown"; + if (!properties.contains("version")) properties["version"] = "AMQP-CPP " VERSION_NAME; if (!properties.contains("platform")) properties["platform"] = PlatformName(); if (!properties.contains("copyright")) properties["copyright"] = "Copernica AMQP-CPP library :: Copyright 2015-2023 Copernica BV"; if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP"; diff --git a/src/platformname.h b/src/platformname.h index af89410..a1bccf2 100644 --- a/src/platformname.h +++ b/src/platformname.h @@ -41,13 +41,13 @@ public: PlatformName() { // all information - struct utsname sysinfo; + struct utsname info; // retrieve system info - if (uname(&sysinfo) != 0) return; + if (uname(&info) != 0) return; // add all info - _value.append(sysinfo.sysname).append(" ").append(sysinfo.version).append(" ").append(sysinfo.release).append(" running on ").append(sysinfo.nodename); + _value.append(info.sysname).append(" ").append(info.nodename).append(" ").append(info.release).append(" ").append(info.version); } /** diff --git a/src/programname.h b/src/programname.h index 3fd892d..edae22d 100644 --- a/src/programname.h +++ b/src/programname.h @@ -45,7 +45,17 @@ public: /** * Constructor */ - ProgramName() : _valid(readlink("/proc/self/exe", _path, PATH_MAX) == 0) {} + ProgramName() + { + // read the link target + auto size = readlink("/proc/self/exe", _path, PATH_MAX); + + // -1 is returned on error, otherwise the size + _valid = size >= 0; + + // set trailing null byte + _path[size == PATH_MAX ? PATH_MAX-1 : size] = '\0'; + } /** * Destructor @@ -61,11 +71,8 @@ public: // empty string when not valid if (!_valid) return ""; - // locate the last slash - auto *slash = strrchr(_path, '/'); - - // if not found return entire path, otherwise just the program name - return slash ? slash + 1 : _path; + // return path to executable + return _path; } }; From 4ef552ba391bf3ea3cf88c3a2b30b7385ae0e4b8 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Sat, 22 Apr 2023 16:42:51 +0200 Subject: [PATCH 3/5] pass version number to source files --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5ac66f..69deeaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,9 +24,11 @@ option(AMQP-CPP_BUILD_SHARED "Build shared library. If off, build will be static option(AMQP-CPP_LINUX_TCP "Build linux sockets implementation." OFF) option(AMQP-CPP_BUILD_EXAMPLES "Build amqpcpp examples" OFF) +# pass version number to source files as macro +add_compile_definitions(VERSION=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + # ensure c++11 on all compilers -set (CMAKE_CXX_STANDARD 17 -) +set (CMAKE_CXX_STANDARD 17) # add source files # ------------------------------------------------------------------------------------------------------ From 89a245a05be6c088e18557ca17a8476a31dcd07c Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 24 Apr 2023 11:04:09 +0200 Subject: [PATCH 4/5] fix compiling on win32 --- src/connectionstartframe.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/connectionstartframe.h b/src/connectionstartframe.h index a7658e9..42a23a6 100644 --- a/src/connectionstartframe.h +++ b/src/connectionstartframe.h @@ -11,8 +11,10 @@ /** * Dependencies */ +#ifndef _WIN32 #include "programname.h" #include "platformname.h" +#endif /** * Cause we want to print out version string that is passed to compiled with -D @@ -218,13 +220,21 @@ public: capabilities["consumer_cancel_notify"] = true; // fill the peer properties - if (!properties.contains("product")) properties["product"] = ProgramName(); if (!properties.contains("version")) properties["version"] = "AMQP-CPP " VERSION_NAME; - if (!properties.contains("platform")) properties["platform"] = PlatformName(); if (!properties.contains("copyright")) properties["copyright"] = "Copernica AMQP-CPP library :: Copyright 2015-2023 Copernica BV"; if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP"; if (!properties.contains("capabilities")) properties["capabilities"] = capabilities; - + +#ifdef _WIN32 + // i don't know that much about win32, so let's use hardcoded string + if (!properties.contains("product")) properties["product"] = "application based on AMQP-CPP"; + if (!properties.contains("platform")) properties["platform"] = "windows"; +#else + // on unix-like systems I know how to retrieve application and platform info + if (!properties.contains("product")) properties["product"] = ProgramName(); + if (!properties.contains("platform")) properties["platform"] = PlatformName(); +#endif + // send back a connection start ok frame connection->send(ConnectionStartOKFrame(properties, "PLAIN", connection->login().saslPlain(), "en_US")); From dcde4caca4e628b0f9b97f9ec004dcdbf84cf120 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 24 Apr 2023 11:06:42 +0200 Subject: [PATCH 5/5] fix compiling on win32 --- src/connectionstartframe.h | 4 ++-- src/programname.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connectionstartframe.h b/src/connectionstartframe.h index 42a23a6..6c1d46b 100644 --- a/src/connectionstartframe.h +++ b/src/connectionstartframe.h @@ -11,7 +11,7 @@ /** * Dependencies */ -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(_WIN64) #include "programname.h" #include "platformname.h" #endif @@ -225,7 +225,7 @@ public: if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP"; if (!properties.contains("capabilities")) properties["capabilities"] = capabilities; -#ifdef _WIN32 +#if defined(_WIN32) || defined(_WIN64) // i don't know that much about win32, so let's use hardcoded string if (!properties.contains("product")) properties["product"] = "application based on AMQP-CPP"; if (!properties.contains("platform")) properties["platform"] = "windows"; diff --git a/src/programname.h b/src/programname.h index edae22d..4a16c35 100644 --- a/src/programname.h +++ b/src/programname.h @@ -15,8 +15,8 @@ /** * Dependencies */ -#include #include +#include /** * Begin of namespace