src/base/Makefile.am | 2 +
src/base/conf.cc | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/base/conf.h | 106 +++++++++++++++++++++++++++++++++++
3 files changed, 260 insertions(+), 0 deletions(-)
Add a new class called Conf the contains methods for reading the fully qualified
domain name, the short host name and the configured OpenSAF node name.
diff --git a/src/base/Makefile.am b/src/base/Makefile.am
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -32,6 +32,7 @@ lib_libopensaf_core_la_LDFLAGS += \
lib_libopensaf_core_la_SOURCES += \
src/base/condition_variable.cc \
+ src/base/conf.cc \
src/base/daemon.c \
src/base/file_descriptor.cc \
src/base/file_notify.cc \
@@ -77,6 +78,7 @@ nodist_EXTRA_lib_libopensaf_core_la_SOUR
noinst_HEADERS += \
src/base/buffer.h \
src/base/condition_variable.h \
+ src/base/conf.h \
src/base/daemon.h \
src/base/file_descriptor.h \
src/base/file_notify.h \
diff --git a/src/base/conf.cc b/src/base/conf.cc
new file mode 100644
--- /dev/null
+++ b/src/base/conf.cc
@@ -0,0 +1,152 @@
+/* -*- OpenSAF -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ */
+
+#include "base/conf.h"
+#include <ifaddrs.h>
+#include <limits.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include "base/logtrace.h"
+#include "base/osaf_utility.h"
+#include "osaf/configmake.h"
+
+namespace base {
+
+pthread_once_t Conf::once_control_ = PTHREAD_ONCE_INIT;
+Conf* Conf::instance_ = nullptr;
+
+Conf::Conf() :
+ fully_qualified_domain_name_{},
+ node_name_{},
+ short_host_name_{},
+ fully_qualified_domain_name_initialized_{false},
+ node_name_initialized_{false},
+ short_host_name_initialized_{false},
+ mutex_{} {
+}
+
+Conf::~Conf() {
+ Lock lock(instance_->mutex_);
+ assert(instance_ == this);
+ instance_ = nullptr;
+}
+
+void Conf::InitFullyQualifiedDomainName() {
+ InitShortHostName();
+ Conf* i = GetOrCreateInstance();
+ Lock lock(i->mutex_);
+ if (i->fully_qualified_domain_name_initialized_ == false) {
+ i->fully_qualified_domain_name_ =
+ GetFullyQualifiedDomainName(i->short_host_name_);
+ i->fully_qualified_domain_name_initialized_ = true;
+ }
+}
+
+void Conf::InitNodeName() {
+ InitShortHostName();
+ Conf* i = GetOrCreateInstance();
+ Lock lock(i->mutex_);
+ if (i->node_name_initialized_ == false) {
+ i->node_name_ = GetNodeName(i->short_host_name_);
+ i->node_name_initialized_ = true;
+ }
+}
+
+void Conf::InitShortHostName() {
+ Conf* i = GetOrCreateInstance();
+ Lock lock(i->mutex_);
+ if (i->short_host_name_initialized_ == false) {
+ i->short_host_name_ = GetShortHostName();
+ i->short_host_name_initialized_ = true;
+ }
+}
+
+Conf* Conf::GetOrCreateInstance() {
+ int result = pthread_once(&once_control_, PthreadOnceInitRoutine);
+ if (result != 0) osaf_abort(result);
+ return instance_;
+}
+
+void Conf::PthreadOnceInitRoutine() {
+ assert(instance_ == nullptr);
+ instance_ = new Conf();
+ if (instance_ == nullptr) osaf_abort(0);
+}
+
+std::string Conf::GetFullyQualifiedDomainName(
+ const std::string& short_host_name) {
+ char host[NI_MAXHOST];
+ std::string fqdn{short_host_name};
+ ifaddrs* ifa;
+ if (getifaddrs(&ifa) == 0) {
+ for (ifaddrs* i = ifa; i != nullptr; i = i->ifa_next) {
+ sockaddr* addr = i->ifa_addr;
+ sockaddr_in6* addr_ipv6 = reinterpret_cast<sockaddr_in6*>(addr);
+ if (addr != nullptr &&
+ (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) &&
+ (i->ifa_flags & IFF_LOOPBACK) == 0 &&
+ (i->ifa_flags & IFF_UP) != 0 &&
+ (addr->sa_family != AF_INET6 ||
+ (!IN6_IS_ADDR_LOOPBACK(&addr_ipv6->sin6_addr) &&
+ !IN6_IS_ADDR_LINKLOCAL(&addr_ipv6->sin6_addr) &&
+ !IN6_IS_ADDR_MC_LINKLOCAL(&addr_ipv6->sin6_addr))) &&
+ getnameinfo(addr, addr->sa_family == AF_INET6 ?
+ sizeof(sockaddr_in6) : sizeof(sockaddr_in),
+ host, sizeof(host), nullptr, 0, 0) == 0 &&
+ strncmp(short_host_name.c_str(), host, short_host_name.size()) == 0
&&
+ host[short_host_name.size()] == '.') {
+ fqdn = host;
+ break;
+ }
+ }
+ freeifaddrs(ifa);
+ } else {
+ LOG_ER("getifaddrs() failed, errno=%d", errno);
+ }
+ return fqdn;
+}
+
+std::string Conf::GetNodeName(const std::string& short_host_name) {
+ std::string node_name;
+ std::ifstream str;
+ str.width(255);
+ try {
+ str.open(PKGSYSCONFDIR "/node_name");
+ str >> node_name;
+ } catch (std::ifstream::failure) {
+ node_name.clear();
+ }
+ return (str.fail() || node_name.empty()) ? short_host_name : node_name;
+}
+
+std::string Conf::GetShortHostName() {
+ char short_host_name[HOST_NAME_MAX + 1];
+ if (gethostname(short_host_name, sizeof(short_host_name)) == 0) {
+ short_host_name[sizeof(short_host_name) - 1] = '\0';
+ } else {
+ LOG_ER("gethostname() failed, errno=%d", errno);
+ short_host_name[0] = '\0';
+ }
+ return short_host_name;
+}
+
+} // namespace base
diff --git a/src/base/conf.h b/src/base/conf.h
new file mode 100644
--- /dev/null
+++ b/src/base/conf.h
@@ -0,0 +1,106 @@
+/* -*- OpenSAF -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ */
+
+#ifndef BASE_CONF_H_
+#define BASE_CONF_H_
+
+#include <pthread.h>
+#include <cassert>
+#include <string>
+#include "base/macros.h"
+#include "base/mutex.h"
+
+namespace base {
+
+class Conf {
+ public:
+ // Read the fully qualified domain name and store a copy of it in this class.
+ // Must be called at least once before the FullyQualifiedDomainName() method
+ // is called. It is harmless to call this method multiple times (though it
+ // should be avoided for performance reasons). This method is thread-safe.
+ static void InitFullyQualifiedDomainName();
+
+ // Read the configured OpenSAF node name and store a copy of it in this
class.
+ // Must be called at least once before the NodeName() method is called. It is
+ // harmless to call this method multiple times (though it should be avoided
+ // for performance reasons). This method is thread-safe.
+ static void InitNodeName();
+
+ // Read the short host name (the host name cut at the first dot) and store a
+ // copy of it in this class. Must be called at least once before the
+ // ShortHostName() method is called. It is harmless to call this method
+ // multiple times (though it should be avoided for performance reasons). This
+ // method is thread-safe.
+ static void InitShortHostName();
+
+ // Returns the fully qualified domain name (FQDN) of this node. An empty
+ // string is returned if the the FQDN could not be determined. Note: you must
+ // call InitFullyQualifiedDomainName() at least once before calling this
+ // method. This method is thread-safe.
+ static const std::string& FullyQualifiedDomainName() {
+ const Conf* i = instance();
+ assert(i->fully_qualified_domain_name_initialized_);
+ return i->fully_qualified_domain_name_;
+ }
+
+ // Returns the configured OpenSAF node name of this node. If no name has been
+ // configured, or if the configuration could not be read, the short host name
+ // will be returned instead. If the short host name could not be determined
+ // either, an empty string is returned. Note: you must call InitNodeName() at
+ // least once before calling this method. This method is thread-safe.
+ static const std::string& NodeName() {
+ const Conf* i = instance();
+ assert(i->node_name_initialized_);
+ return i->node_name_;
+ }
+
+ // Returns the short host name (the host name cut at the first dot) of this
+ // node. If the short host name could not be determined, an empty string is
+ // returned. Note: you must call InitShortHostName() at least once before
+ // calling this method. This method is thread-safe.
+ static const std::string& ShortHostName() {
+ const Conf* i = instance();
+ assert(i->short_host_name_initialized_);
+ return i->short_host_name_;
+ }
+
+ private:
+ Conf();
+ ~Conf();
+ static const Conf* instance() {
+ return instance_;
+ }
+ static Conf* GetOrCreateInstance();
+ static void PthreadOnceInitRoutine();
+ static std::string GetFullyQualifiedDomainName(
+ const std::string& short_host_name);
+ static std::string GetNodeName(const std::string& short_host_name);
+ static std::string GetShortHostName();
+ static pthread_once_t once_control_;
+ static Conf* instance_;
+ std::string fully_qualified_domain_name_;
+ std::string node_name_;
+ std::string short_host_name_;
+ bool fully_qualified_domain_name_initialized_;
+ bool node_name_initialized_;
+ bool short_host_name_initialized_;
+ Mutex mutex_;
+
+ DELETE_COPY_AND_MOVE_OPERATORS(Conf);
+};
+
+} // namespace base
+
+#endif // BASE_CONF_H_
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel