Skip to content

Commit

Permalink
Merge pull request #497 from CopernicaMarketingSoftware/better-connec…
Browse files Browse the repository at this point in the history
…tion-info

Add more information to the ConnectionStartFrame
  • Loading branch information
thomaskamps authored Apr 24, 2023
2 parents 4fcbd19 + dcde4ca commit f205256
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 15 deletions.
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ------------------------------------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
43 changes: 36 additions & 7 deletions src/connectionstartframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,29 @@
* is opened. It contains the initial connection properties, and the protocol
* number.
*
* @copyright 2014 - 2022 Copernica BV
* @copyright 2014 - 2023 Copernica BV
*/

/**
* Dependencies
*/
#if !defined(_WIN32) && !defined(_WIN64)
#include "programname.h"
#include "platformname.h"
#endif

/**
* 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
*/
Expand Down Expand Up @@ -200,19 +220,28 @@ class ConnectionStartFrame : public ConnectionFrame
capabilities["consumer_cancel_notify"] = true;

// fill the peer properties
if (!properties.contains("product")) properties["product"] = "Copernica AMQP library";
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("version")) properties["version"] = "AMQP-CPP " VERSION_NAME;
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;


#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";
#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"));

// done
return true;
}

};

/**
Expand Down
69 changes: 69 additions & 0 deletions src/platformname.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* PlatformName.h
*
* Class to extract the platform name (operating system, etc)
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2023 Copernica BV
*/

/**
* Include guard
*/
#pragma once

/**
* Dependencies
*/
#include <sys/utsname.h>

/**
* 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 info;

// retrieve system info
if (uname(&info) != 0) return;

// add all info
_value.append(info.sysname).append(" ").append(info.nodename).append(" ").append(info.release).append(" ").append(info.version);
}

/**
* Destructor
*/
virtual ~PlatformName() = default;

/**
* Cast to a const char *
* @return const char *
*/
operator const char * () const { return _value.data(); }
};

/**
* End of namespace
*/
}

82 changes: 82 additions & 0 deletions src/programname.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* ProgramName.h
*
* Helper class that detects the name of the program
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2023 Copernica BV
*/

/**
* Include guard
*/
#pragma once

/**
* Dependencies
*/
#include <limits.h>
#include <unistd.h>

/**
* 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()
{
// 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
*/
virtual ~ProgramName() = default;

/**
* Cast to a const char *
* @return const char *
*/
operator const char * () const
{
// empty string when not valid
if (!_valid) return "";

// return path to executable
return _path;
}
};

/**
* End of namespace
*/
}

0 comments on commit f205256

Please sign in to comment.