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: 2025-12-21 13:07:08 Functions: 25.8 % 31 8

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

Generated by: LCOV version 2.0-1