Skip to content

Commit f205256

Browse files
authored
Merge pull request #497 from CopernicaMarketingSoftware/better-connection-info
Add more information to the ConnectionStartFrame
2 parents 4fcbd19 + dcde4ca commit f205256

File tree

6 files changed

+197
-15
lines changed

6 files changed

+197
-15
lines changed

CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ option(AMQP-CPP_BUILD_SHARED "Build shared library. If off, build will be static
2424
option(AMQP-CPP_LINUX_TCP "Build linux sockets implementation." OFF)
2525
option(AMQP-CPP_BUILD_EXAMPLES "Build amqpcpp examples" OFF)
2626

27+
# pass version number to source files as macro
28+
add_compile_definitions(VERSION=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
29+
2730
# ensure c++11 on all compilers
28-
set (CMAKE_CXX_STANDARD 17
29-
)
31+
set (CMAKE_CXX_STANDARD 17)
3032

3133
# add source files
3234
# ------------------------------------------------------------------------------------------------------

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ export SONAME = 4.3
66
export VERSION = 4.3.24
77

88
all:
9-
$(MAKE) -C src all
9+
$(MAKE) VERSION=${VERSION} -C src all
1010

1111
pure:
12-
$(MAKE) -C src pure
12+
$(MAKE) VERSION=${VERSION} -C src pure
1313

1414
release:
15-
$(MAKE) -C src release
15+
$(MAKE) VERSION=${VERSION} -C src release
1616

1717
static:
18-
$(MAKE) -C src static
18+
$(MAKE) VERSION=${VERSION} -C src static
1919

2020
shared:
21-
$(MAKE) -C src shared
21+
$(MAKE) VERSION=${VERSION} -C src shared
2222

2323
clean:
2424
$(MAKE) -C src clean

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CPP = g++
22
RM = rm -f
3-
CPPFLAGS = -Wall -c -I../include -std=c++17 -MD -Wno-class-conversion
3+
CPPFLAGS = -Wall -c -I../include -std=c++17 -MD -Wno-class-conversion -DVERSION=${VERSION}
44
LD = g++
55
LD_FLAGS = -Wall -shared
66
SHARED_LIB = lib$(LIBRARY_NAME).so.$(VERSION)

src/connectionstartframe.h

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,29 @@
55
* is opened. It contains the initial connection properties, and the protocol
66
* number.
77
*
8-
* @copyright 2014 - 2022 Copernica BV
8+
* @copyright 2014 - 2023 Copernica BV
99
*/
1010

11+
/**
12+
* Dependencies
13+
*/
14+
#if !defined(_WIN32) && !defined(_WIN64)
15+
#include "programname.h"
16+
#include "platformname.h"
17+
#endif
18+
19+
/**
20+
* Cause we want to print out version string that is passed to compiled with -D
21+
* flag. Why 2 macros? https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/
22+
*/
23+
#define STR_EXPAND(s) #s
24+
#define STR(s) STR_EXPAND(s)
25+
26+
/**
27+
* The version and distro names
28+
*/
29+
#define VERSION_NAME STR(VERSION)
30+
1131
/**
1232
* Set up namespace
1333
*/
@@ -200,19 +220,28 @@ class ConnectionStartFrame : public ConnectionFrame
200220
capabilities["consumer_cancel_notify"] = true;
201221

202222
// fill the peer properties
203-
if (!properties.contains("product")) properties["product"] = "Copernica AMQP library";
204-
if (!properties.contains("version")) properties["version"] = "Unknown";
205-
if (!properties.contains("platform")) properties["platform"] = "Unknown";
206-
if (!properties.contains("copyright")) properties["copyright"] = "Copyright 2015 - 2018 Copernica BV";
207-
if (!properties.contains("information")) properties["information"] = "https://www.copernica.com";
223+
if (!properties.contains("version")) properties["version"] = "AMQP-CPP " VERSION_NAME;
224+
if (!properties.contains("copyright")) properties["copyright"] = "Copernica AMQP-CPP library :: Copyright 2015-2023 Copernica BV";
225+
if (!properties.contains("information")) properties["information"] = "https://github.com/CopernicaMarketingSoftware/AMQP-CPP";
208226
if (!properties.contains("capabilities")) properties["capabilities"] = capabilities;
209-
227+
228+
#if defined(_WIN32) || defined(_WIN64)
229+
// i don't know that much about win32, so let's use hardcoded string
230+
if (!properties.contains("product")) properties["product"] = "application based on AMQP-CPP";
231+
if (!properties.contains("platform")) properties["platform"] = "windows";
232+
#else
233+
// on unix-like systems I know how to retrieve application and platform info
234+
if (!properties.contains("product")) properties["product"] = ProgramName();
235+
if (!properties.contains("platform")) properties["platform"] = PlatformName();
236+
#endif
237+
210238
// send back a connection start ok frame
211239
connection->send(ConnectionStartOKFrame(properties, "PLAIN", connection->login().saslPlain(), "en_US"));
212240

213241
// done
214242
return true;
215243
}
244+
216245
};
217246

218247
/**

src/platformname.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* PlatformName.h
3+
*
4+
* Class to extract the platform name (operating system, etc)
5+
*
6+
* @author Emiel Bruijntjes <[email protected]>
7+
* @copyright 2023 Copernica BV
8+
*/
9+
10+
/**
11+
* Include guard
12+
*/
13+
#pragma once
14+
15+
/**
16+
* Dependencies
17+
*/
18+
#include <sys/utsname.h>
19+
20+
/**
21+
* Begin of namespace
22+
*/
23+
namespace AMQP {
24+
25+
/**
26+
* Class definition
27+
*/
28+
class PlatformName
29+
{
30+
private:
31+
/**
32+
* The string holding all info
33+
* @var std::string
34+
*/
35+
std::string _value;
36+
37+
public:
38+
/**
39+
* Constructor
40+
*/
41+
PlatformName()
42+
{
43+
// all information
44+
struct utsname info;
45+
46+
// retrieve system info
47+
if (uname(&info) != 0) return;
48+
49+
// add all info
50+
_value.append(info.sysname).append(" ").append(info.nodename).append(" ").append(info.release).append(" ").append(info.version);
51+
}
52+
53+
/**
54+
* Destructor
55+
*/
56+
virtual ~PlatformName() = default;
57+
58+
/**
59+
* Cast to a const char *
60+
* @return const char *
61+
*/
62+
operator const char * () const { return _value.data(); }
63+
};
64+
65+
/**
66+
* End of namespace
67+
*/
68+
}
69+

src/programname.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* ProgramName.h
3+
*
4+
* Helper class that detects the name of the program
5+
*
6+
* @author Emiel Bruijntjes <[email protected]>
7+
* @copyright 2023 Copernica BV
8+
*/
9+
10+
/**
11+
* Include guard
12+
*/
13+
#pragma once
14+
15+
/**
16+
* Dependencies
17+
*/
18+
#include <limits.h>
19+
#include <unistd.h>
20+
21+
/**
22+
* Begin of namespace
23+
*/
24+
namespace AMQP {
25+
26+
/**
27+
* Class definition
28+
*/
29+
class ProgramName
30+
{
31+
private:
32+
/**
33+
* Path of the program
34+
* @var char[]
35+
*/
36+
char _path[PATH_MAX];
37+
38+
/**
39+
* Is the _path valid?
40+
* @var bool
41+
*/
42+
bool _valid;
43+
44+
public:
45+
/**
46+
* Constructor
47+
*/
48+
ProgramName()
49+
{
50+
// read the link target
51+
auto size = readlink("/proc/self/exe", _path, PATH_MAX);
52+
53+
// -1 is returned on error, otherwise the size
54+
_valid = size >= 0;
55+
56+
// set trailing null byte
57+
_path[size == PATH_MAX ? PATH_MAX-1 : size] = '\0';
58+
}
59+
60+
/**
61+
* Destructor
62+
*/
63+
virtual ~ProgramName() = default;
64+
65+
/**
66+
* Cast to a const char *
67+
* @return const char *
68+
*/
69+
operator const char * () const
70+
{
71+
// empty string when not valid
72+
if (!_valid) return "";
73+
74+
// return path to executable
75+
return _path;
76+
}
77+
};
78+
79+
/**
80+
* End of namespace
81+
*/
82+
}

0 commit comments

Comments
 (0)