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

Reply via email to