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

Generated by: LCOV version 2.0-1