LCOV - code coverage report
Current view: top level - okssystem/src - Host.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 40.2 % 112 45
Test Date: 2026-10-11 15:05:20 Functions: 25.8 % 31 8

            Line data    Source code
       1              : // DUNE DAQ modification notice:
       2              : // This file has been modified from the original ATLAS system source for the DUNE DAQ project.
       3              : // Fork baseline commit: system-00-00-20 (2020-09-25).
       4              : // Renamed since fork: yes (from src/Host.cxx to src/Host.cpp).
       5              : 
       6              : /*
       7              :  *  Host.cxx
       8              :  *  OksSystem
       9              :  *
      10              :  *  Created by Matthias Wiesmann on 03.02.05.
      11              :  *  Copyright 2005 CERN. All rights reserved.
      12              :  *
      13              :  */
      14              : 
      15              : #include <netdb.h>
      16              : #include <sys/socket.h>
      17              : #include <sys/types.h>
      18              : #include <sys/utsname.h>
      19              : 
      20              : #include <unistd.h>
      21              : 
      22              : #include <iostream>
      23              : #include <sstream>
      24              : #include <strings.h>
      25              : 
      26              : #include "okssystem/Host.hpp"
      27              : 
      28              : #define BUFFER_SIZE 256
      29              : 
      30              : /** Translates an hostname into an ip address
      31              :  * \param name hostname to translate
      32              :  * \return the ip addrress, 0.0.0.0 if name not found.
      33              :  * \note only returns the first ip address associated with name
      34              :  */
      35              : 
      36              : struct sockaddr_in
      37           19 : OksSystem::Host::resolve(const std::string& name) throw()
      38              : {
      39           19 :   struct addrinfo* info_ptr;
      40           19 :   const char* str = name.c_str();
      41           19 :   const int status = getaddrinfo(str, 0, 0, &info_ptr);
      42           19 :   struct sockaddr_in address;
      43           19 :   bzero(&address, sizeof(address));
      44           19 :   address.sin_family = AF_INET;
      45           19 :   address.sin_addr.s_addr = 0;
      46           19 :   if (status == 0) {
      47           19 :     struct sockaddr_in* ptr = (sockaddr_in*)info_ptr->ai_addr;
      48           19 :     address = *ptr;
      49           19 :     freeaddrinfo(info_ptr);
      50              :   } // if
      51           19 :   return address;
      52              : } // resolve
      53              : 
      54              : /** Translates an ip address into an hostname
      55              :  * \param address the address to translate
      56              :  * \return the hostname an empty string if the hostname could not be resolved
      57              :  */
      58              : 
      59              : std::string
      60           19 : OksSystem::Host::resolve(struct sockaddr_in address) throw()
      61              : {
      62           19 :   char buffer[NI_MAXHOST];
      63           19 :   const struct sockaddr* ptr = (const struct sockaddr*)&address;
      64           19 :   const int status = getnameinfo(ptr, sizeof(address), buffer, sizeof(buffer), 0, 0, 0);
      65           19 :   if (status != 0)
      66            0 :     return to_string(address);
      67           19 :   return std::string(buffer);
      68              : } // resolve
      69              : 
      70              : /** Tries to build a fully qualified name.
      71              :  * This is done first by converting the name to ip then the ip to a name.
      72              :  * If this fails (basically, we cannot do DNS resolves)
      73              :  * the non fully qualified name is returned
      74              :  * \param name the (partial) name
      75              :  * \return fullname
      76              :  */
      77              : 
      78              : std::string
      79           19 : OksSystem::Host::expand(const std::string& name) throw()
      80              : {
      81           19 :   const struct sockaddr_in address = resolve(name);
      82           19 :   if (address.sin_addr.s_addr != 0)
      83           19 :     return resolve(address);
      84            0 :   return std::string(name);
      85              : } // expand
      86              : 
      87              : /** Transliterate an ip address into the canonical dotted text version (w.x.y.z).
      88              :  * \param ip_addr the address to translate
      89              :  * \return string containing the text version
      90              :  * \note Should use addr2ascii
      91              :  */
      92              : 
      93              : std::string
      94            0 : OksSystem::Host::to_string(struct sockaddr_in ip_addr)
      95              : {
      96            0 :   const char* s = inet_ntoa(ip_addr.sin_addr);
      97            0 :   return std::string(s);
      98              : } // to_string
      99              : 
     100              : // Constructors, destructors
     101              : // --------------------------
     102              : 
     103              : /** Constructors for the local host
     104              :  */
     105              : 
     106           19 : OksSystem::Host::Host() throw() {} // Host
     107              : 
     108            0 : OksSystem::Host::Host(const OksSystem::Host& other)
     109              : {
     110            0 :   m_name = other.m_name;
     111            0 :   if (!other.m_full_name.empty()) {
     112            0 :     m_full_name = other.m_full_name;
     113              :   } // if
     114            0 : } // Host
     115              : 
     116              : /** Constructor for host by name
     117              :  * \param name name of the host
     118              :  */
     119              : 
     120            0 : OksSystem::Host::Host(const std::string& s_name)
     121              : {
     122            0 :   m_name = s_name;
     123            0 : } // Host
     124              : 
     125            0 : OksSystem::Host::Host(struct sockaddr_in ip_addr)
     126              : {
     127            0 :   m_name = resolve(ip_addr);
     128            0 :   m_full_name = m_name;
     129            0 : } // Host
     130              : 
     131            0 : OksSystem::Host::~Host() throw() {} // OksSystem
     132              : 
     133              : // Operator
     134              : // --------------------------
     135              : 
     136              : /** Cast conversion into ip address
     137              :  * \return ip address
     138              :  */
     139              : 
     140            0 : OksSystem::Host::operator struct sockaddr_in() const throw()
     141              : {
     142            0 :   return ip();
     143              : } // struct sockaddr_in
     144              : 
     145              : /** Comparison method
     146              :  * We try to expand both name and compare those
     147              :  * \param other the host to compare to
     148              :  * \return \c true if both have the same fully qualified name
     149              :  */
     150              : 
     151              : bool
     152            0 : OksSystem::Host::equals(const Host& other) const throw()
     153              : {
     154            0 :   return full_name() == other.full_name();
     155              : } // equals
     156              : 
     157              : // Methods
     158              : // --------------------------
     159              : 
     160              : /** Name (this might be non fully qualified name)
     161              :  * \return name of the host
     162              :  */
     163              : 
     164              : const std::string&
     165            0 : OksSystem::Host::name() const throw()
     166              : {
     167            0 :   return m_name;
     168              : }
     169              : 
     170              : /** IP address of the host
     171              :  * \return IP address of the host, or 0.0.0.0 if it cannot be resolved
     172              :  */
     173              : 
     174              : struct sockaddr_in
     175            0 : OksSystem::Host::ip() const throw()
     176              : {
     177            0 :   return resolve(m_name);
     178              : }
     179              : 
     180              : /** Fully qualified name of the host
     181              :  * \return Fully qualified name of the host, or the string \"0.0.0.0\"
     182              :  */
     183              : 
     184              : const std::string&
     185           19 : OksSystem::Host::full_name() const throw()
     186              : {
     187           19 :   if (m_full_name.empty()) {
     188           19 :     m_full_name = expand(m_name);
     189              :   } // if
     190           19 :   return m_full_name;
     191              : } // full_name
     192              : 
     193              : /** The IP Address of the host, as a string
     194              :  * \return a string containing the IP address of the host in w.x.y.z format
     195              :  */
     196              : 
     197              : std::string
     198            0 : OksSystem::Host::ip_string() const throw()
     199              : {
     200            0 :   const struct sockaddr_in address = ip();
     201            0 :   return to_string(address);
     202              : } // ip_string
     203              : 
     204              : bool
     205            0 : OksSystem::operator==(const Host& a, const Host& b) throw()
     206              : {
     207            0 :   return a.equals(b);
     208              : } // operator ==
     209              : 
     210              : bool
     211            0 : OksSystem::operator!=(const Host& a, const Host& b) throw()
     212              : {
     213            0 :   return !a.equals(b);
     214              : } // operator ≠
     215              : 
     216              : // Local Host
     217              : // --------------------------
     218              : 
     219              : /** Instance of local host
     220              :  * \brief LocalHost singleton
     221              :  */
     222              : 
     223              : OksSystem::LocalHost* OksSystem::LocalHost::s_instance = 0;
     224              : 
     225              : /** Short-cut method - gives the local hostname
     226              :  * This name is not guaranteed to be a fully qualified name.
     227              :  * \return hostname
     228              :  * \see OksSystem::LocalHost::name()
     229              :  */
     230              : 
     231              : const std::string&
     232            0 : OksSystem::LocalHost::local_name() throw()
     233              : {
     234            0 :   return instance()->name();
     235              : } // localhostname
     236              : 
     237              : /** Short-cut method - gives the fully qualified local hostname
     238              :  * \return fully qualified hostname
     239              :  * \see OksSystem::LocalHost::full_name()
     240              :  */
     241              : 
     242              : const std::string&
     243           19 : OksSystem::LocalHost::full_local_name() throw()
     244              : {
     245           19 :   return instance()->full_name();
     246              : } // fulllocalhostname
     247              : 
     248              : /** This method returns a pointer to the singleton instance.
     249              :  * There is no need to ever create any instance of LocalHost
     250              :  * \return pointer to singleton instance
     251              :  * \note utility methods like \c full_local_name use this instance class
     252              :  */
     253              : 
     254              : const OksSystem::LocalHost*
     255           38 : OksSystem::LocalHost::instance() throw()
     256              : {
     257           38 :   if (0 == s_instance) {
     258           19 :     s_instance = new LocalHost();
     259              :   } //
     260           38 :   return s_instance;
     261              : } // instance
     262              : 
     263              : /** Constructor
     264              :  * You should \b not construct new instances, use \c instance to get the
     265              :  * singleton instance.
     266              :  */
     267              : 
     268           19 : OksSystem::LocalHost::LocalHost() throw()
     269           19 :   : Host()
     270              : {
     271           19 :   struct utsname u_name_data;
     272           19 :   const int status = ::uname(&u_name_data);
     273           19 :   if (status == 0) {
     274           19 :     m_name = u_name_data.nodename;
     275           19 :     m_os_name = u_name_data.sysname;
     276           19 :     m_release = u_name_data.release;
     277           19 :     m_version = u_name_data.version;
     278           19 :     m_machine = u_name_data.machine;
     279              :   } else {
     280            0 :     char buffer[NI_MAXHOST];
     281            0 :     const int host_status = gethostname(buffer, sizeof(buffer));
     282            0 :     if (host_status == 0) {
     283            0 :       m_name = buffer;
     284              :     } else { // both uname and gethostname screwed
     285            0 :       m_name.clear();
     286              :     } // check for host_name
     287              :   } // uname failed.
     288           19 : } // LocalHost
     289              : 
     290            0 : OksSystem::LocalHost::~LocalHost() throw()
     291              : {
     292              :   //  delete s_instance;
     293            0 : }
     294              : 
     295              : /** \return Operating OksSystem name */
     296              : 
     297              : const std::string&
     298            0 : OksSystem::LocalHost::os_name() const throw()
     299              : {
     300            0 :   return m_os_name;
     301              : } // os_name
     302              : 
     303              : /** \return Operating OksSystem release */
     304              : 
     305              : const std::string&
     306            0 : OksSystem::LocalHost::os_release() const throw()
     307              : {
     308            0 :   return m_release;
     309              : } // os_release
     310              : 
     311              : /** \return Operating OksSystem version */
     312              : 
     313              : const std::string&
     314            0 : OksSystem::LocalHost::os_version() const throw()
     315              : {
     316            0 :   return m_version;
     317              : } // os_version
     318              : 
     319              : /** \return machine name */
     320              : 
     321              : const std::string&
     322            0 : OksSystem::LocalHost::machine() const throw()
     323              : {
     324            0 :   return m_machine;
     325              : } // machine
     326              : 
     327              : /** This method builds a description of the localhost
     328              :  * This contains all the of the information handled by this class.
     329              :  * \return description text
     330              :  */
     331              : 
     332              : const std::string&
     333            0 : OksSystem::LocalHost::description() const throw()
     334              : {
     335            0 :   if (m_description.empty()) {
     336            0 :     std::ostringstream stream;
     337            0 :     stream << m_os_name << " " << m_release << "/" << m_machine;
     338            0 :     m_description = stream.str();
     339            0 :   }
     340            0 :   return m_description;
     341              : } // description
     342              : 
     343              : /** Convenience method, finds the fully qualified host name for this node
     344              :  * \return c-string with fully qualified hostname
     345              :  * \note the string is owned by the singleton object it should not be deleted
     346              :  * \note if resolve fails (typically because there is no network) this method might return
     347              :  *       the short (unqualified) host name.
     348              :  */
     349              : 
     350              : const char*
     351            0 : OksSystem::getfullhost() throw()
     352              : {
     353            0 :   const std::string& str = OksSystem::LocalHost::full_local_name();
     354            0 :   return str.c_str();
     355              : } // full_host_name
     356              : 
     357              : /** Comparison operator
     358              :  * Simple optimisation - if we compare two localhost instances, they are always equal
     359              :  * \param a first instance
     360              :  * \param b second instance
     361              :  */
     362              : 
     363              : bool
     364            0 : OksSystem::operator==(const LocalHost&, const LocalHost&) throw()
     365              : {
     366            0 :   return true;
     367              : }
     368              : 
     369              : /** Comparison operator
     370              :  * Simple optimisation - if we compare two localhost instances, they are always equal
     371              :  * \param a first instance
     372              :  * \param b second instance
     373              :  */
     374              : 
     375              : bool
     376            0 : OksSystem::operator!=(const LocalHost&, const LocalHost&) throw()
     377              : {
     378            0 :   return false;
     379              : }
     380              : 
     381              : std::ostream&
     382            0 : operator<<(std::ostream& stream, const OksSystem::Host& host)
     383              : {
     384            0 :   stream << host.full_name();
     385            0 :   return stream;
     386              : } // operator<<
        

Generated by: LCOV version 2.0-1