(file) Return to System.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

   1 martin 1.71 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.72 //
   3 martin 1.71 // Licensed to The Open Group (TOG) under one or more contributor license
   4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   5             // this work for additional information regarding copyright ownership.
   6             // Each contributor licenses this file to you under the OpenPegasus Open
   7             // Source License; you may not use this file except in compliance with the
   8             // License.
   9 martin 1.72 //
  10 martin 1.71 // Permission is hereby granted, free of charge, to any person obtaining a
  11             // copy of this software and associated documentation files (the "Software"),
  12             // to deal in the Software without restriction, including without limitation
  13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14             // and/or sell copies of the Software, and to permit persons to whom the
  15             // Software is furnished to do so, subject to the following conditions:
  16 martin 1.72 //
  17 martin 1.71 // The above copyright notice and this permission notice shall be included
  18             // in all copies or substantial portions of the Software.
  19 martin 1.72 //
  20 martin 1.71 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.72 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.71 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 martin 1.72 //
  28 martin 1.71 //////////////////////////////////////////////////////////////////////////
  29 mike   1.6  //
  30             //%/////////////////////////////////////////////////////////////////////////////
  31 mike   1.8  
  32 r.kieninger 1.21 #include <Pegasus/Common/Config.h>
  33 sage        1.12 
  34 mike        1.8  #include <fstream>
  35 kumpf       1.13 #include <cctype>  // for tolower()
  36 kumpf       1.14 #include <cstring>
  37 mike        1.6  #include "System.h"
  38 r.kieninger 1.21 #include "Socket.h"
  39 mike        1.39 #include "Network.h"
  40 kumpf       1.10 #include <Pegasus/Common/PegasusVersion.h>
  41 mateus.baur 1.50 #include <Pegasus/Common/FileSystem.h>
  42 dave.sudlik 1.52 #include <Pegasus/Common/HostAddress.h>
  43                  #include <Pegasus/Common/Array.h>
  44 kumpf       1.10 
  45 mike        1.6  #if defined(PEGASUS_OS_TYPE_WINDOWS)
  46                  # include "SystemWindows.cpp"
  47 john.eisenbraun 1.74 #elif defined(PEGASUS_OS_TYPE_UNIX)
  48 mike            1.40 # include "SystemPOSIX.cpp"
  49 john.eisenbraun 1.74 # include "SystemUnix.cpp"
  50                      #elif defined(PEGASUS_OS_VMS)
  51                      # include "SystemPOSIX.cpp"
  52                      # include "SystemVms.cpp"
  53 mike            1.6  #else
  54                      # error "Unsupported platform"
  55                      #endif
  56 mike            1.8  
  57                      PEGASUS_USING_STD;
  58                      
  59                      PEGASUS_NAMESPACE_BEGIN
  60                      
  61 kumpf           1.20 Boolean System::bindVerbose = false;
  62                      
  63 mike            1.8  Boolean System::copyFile(const char* fromPath, const char* toPath)
  64                      {
  65 ramnath         1.9      ifstream is(fromPath PEGASUS_IOS_BINARY);
  66 mateus.baur     1.50     fstream os(toPath, ios::out  PEGASUS_OR_IOS_BINARY);
  67 mike            1.8  
  68                          char c;
  69                      
  70                          while (is.get(c))
  71                          {
  72 kumpf           1.44         if (!os.put(c))
  73                                  return false;
  74 mike            1.8      }
  75                      
  76 mateus.baur     1.50     FileSystem::syncWithDirectoryUpdates(os);
  77 kumpf           1.42     return is.eof();
  78 kumpf           1.13 }
  79                      
  80 kumpf           1.44 static const Uint8 _toLowerTable[256] =
  81 mike            1.32 {
  82                          0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  83                          0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  84                          0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
  85                          0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
  86                          0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
  87                          0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
  88                          0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
  89                          0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
  90                          0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
  91                          0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
  92                          0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
  93                          0x78,0x79,0x7A,0x5B,0x5C,0x5D,0x5E,0x5F,
  94                          0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
  95                          0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
  96                          0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
  97                          0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
  98                          0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
  99                          0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
 100                          0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
 101                          0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
 102 mike            1.32     0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
 103                          0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
 104                          0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
 105                          0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
 106                          0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
 107                          0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
 108                          0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
 109                          0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
 110                          0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
 111                          0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
 112                          0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
 113                          0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
 114                      };
 115                      
 116 kumpf           1.13 Sint32 System::strcasecmp(const char* s1, const char* s2)
 117                      {
 118 mike            1.32     // Note: this is faster than glibc strcasecmp().
 119                      
 120                          Uint8* p = (Uint8*)s1;
 121                          Uint8* q = (Uint8*)s2;
 122                          int r;
 123                      
 124                          for (;;)
 125 kumpf           1.13     {
 126 kumpf           1.44         if ((r = _toLowerTable[p[0]] - _toLowerTable[q[0]]) || !p[0] ||
 127                                  (r = _toLowerTable[p[1]] - _toLowerTable[q[1]]) || !p[1] ||
 128                                  (r = _toLowerTable[p[2]] - _toLowerTable[q[2]]) || !p[2] ||
 129                                  (r = _toLowerTable[p[3]] - _toLowerTable[q[3]]) || !p[3])
 130                                  break;
 131 kumpf           1.13 
 132 kumpf           1.44         p += 4;
 133                              q += 4;
 134 kumpf           1.13     }
 135                      
 136 mike            1.32     return r;
 137 mike            1.8  }
 138                      
 139 thilo.boehm     1.77 bool System::strncasecmp(
 140                          const char* s1,
 141                          size_t s1_l,
 142                          const char* s2,
 143                          size_t s2_l)
 144                      {
 145                          // Function is even faster than System::strcasecmp()
 146                          if (s1_l != s2_l)
 147                          {
 148                              return false;
 149                          }
 150                          Uint8* p = (Uint8*)s1;
 151                          Uint8* q = (Uint8*)s2;
 152                          register int len = s1_l;
 153                         // lets do a loop-unrolling optimized compare here
 154                          while (len >= 8)
 155                          {
 156                              if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]) ||
 157                                  (_toLowerTable[p[1]]-_toLowerTable[q[1]]) ||
 158                                  (_toLowerTable[p[2]]-_toLowerTable[q[2]]) ||
 159                                  (_toLowerTable[p[3]]-_toLowerTable[q[3]]) ||
 160 thilo.boehm     1.77             (_toLowerTable[p[4]]-_toLowerTable[q[4]]) ||
 161                                  (_toLowerTable[p[5]]-_toLowerTable[q[5]]) ||
 162                                  (_toLowerTable[p[6]]-_toLowerTable[q[6]]) ||
 163                                  (_toLowerTable[p[7]]-_toLowerTable[q[7]]))
 164                              {
 165                                  return false;
 166                              }
 167                              len -= 8;
 168                              p += 8;
 169                              q += 8;
 170                          }
 171                          while (len >= 4)
 172                          {
 173                              if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]) ||
 174                                  (_toLowerTable[p[1]]-_toLowerTable[q[1]]) ||
 175                                  (_toLowerTable[p[2]]-_toLowerTable[q[2]]) ||
 176                                  (_toLowerTable[p[3]]-_toLowerTable[q[3]]))
 177                              {
 178                                  return false;
 179                              }
 180                              len -= 4;
 181 thilo.boehm     1.77         p += 4;
 182                              q += 4;
 183                          }
 184                          while (len--)
 185                          {
 186                              if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]))
 187                              {
 188                                  return false;
 189                              }
 190                              p++;
 191                              q++;
 192                          }
 193                          return true;
 194                      }
 195                      
 196                      
 197 tony            1.15 // Return the just the file name from the path into basename
 198                      char *System::extract_file_name(const char *fullpath, char *basename)
 199                      {
 200 kumpf           1.44     if (fullpath == NULL)
 201                          {
 202                              basename[0] = '\0';
 203                              return basename;
 204                          }
 205 kumpf           1.31 
 206 kumpf           1.44     for (const char* p = fullpath + strlen(fullpath) - 1; p >= fullpath; p--)
 207                          {
 208                              if (*p == '\\' || *p == '/')
 209                              {
 210                                  strcpy(basename, p+1);
 211                                  return basename;
 212                              }
 213                          }
 214                      
 215                          strcpy(basename, fullpath);
 216                          return basename;
 217 tony            1.15 }
 218                      
 219                      // Return the just the path to the file name into dirname
 220                      char *System::extract_file_path(const char *fullpath, char *dirname)
 221                      {
 222 kumpf           1.44     char *p;
 223                          char buff[4096];
 224                          if (fullpath == NULL)
 225                          {
 226                              dirname[0] = '\0';
 227                              return dirname;
 228                          }
 229                          strncpy(buff, fullpath, sizeof(buff)-1);
 230                          buff[sizeof(buff)-1] =  '\0';
 231                          for (p = buff + strlen(buff); p >= buff; p--)
 232 tony            1.15     {
 233 kumpf           1.44         if (*p == '\\' || *p == '/')
 234 tony            1.15         {
 235                                strncpy(dirname, buff, p+1 - buff);
 236                                dirname[p+1 - buff] = '\0';
 237                                return dirname;
 238                              }
 239                          }
 240 kumpf           1.44     strcpy(dirname, fullpath);
 241                          return dirname;
 242 tony            1.15 }
 243                      
 244 kumpf           1.66 String System::getHostName()
 245                      {
 246                          static String _hostname;
 247                          static MutexType _mutex = PEGASUS_MUTEX_INITIALIZER;
 248                      
 249                          // Use double-checked locking pattern to avoid overhead of
 250                          // mutex on subsequent calls.
 251                      
 252                          if (0 == _hostname.size())
 253                          {
 254                              mutex_lock(&_mutex);
 255                      
 256                              if (0 == _hostname.size())
 257                              {
 258                                  char hostname[PEGASUS_MAXHOSTNAMELEN + 1];
 259                                  // If gethostname() fails, an empty or truncated value is used.
 260                                  hostname[0] = 0;
 261                                  gethostname(hostname, sizeof(hostname));
 262                                  hostname[sizeof(hostname)-1] = 0;
 263                                  _hostname.assign(hostname);
 264                              }
 265 kumpf           1.66 
 266                              mutex_unlock(&_mutex);
 267                          }
 268                      
 269                          return _hostname;
 270                      }
 271                      
 272                      static String _getFullyQualifiedHostName()
 273                      {
 274                          char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
 275                      
 276                          // Get the short name of the local host.
 277                          // If gethostname() fails, an empty or truncated value is used.
 278                          hostName[0] = 0;
 279                          gethostname(hostName, sizeof(hostName));
 280                          hostName[sizeof(hostName)-1] = 0;
 281                      
 282                      #if defined(PEGASUS_OS_ZOS)|| \
 283                          defined(PEGASUS_OS_VMS)
 284                      
 285                          String fqName;
 286 kumpf           1.66     struct addrinfo *resolv;
 287                          struct addrinfo hint;
 288                          struct hostent *he;
 289                      
 290                          memset (&hint, 0, sizeof(struct addrinfo));
 291                          hint.ai_flags = AI_CANONNAME;
 292                          hint.ai_family = AF_UNSPEC; // any family
 293                          hint.ai_socktype = 0;       // any socket type
 294                          hint.ai_protocol = 0;       // any protocol
 295 carson.hovey    1.68     int success = System::getAddrInfo(hostName, NULL, &hint, &resolv);
 296 kumpf           1.66     if (success==0)
 297                          {
 298                              // assign fully qualified hostname
 299                              fqName.assign(resolv->ai_canonname);
 300                          }
 301                          else
 302                          {
 303 carson.hovey    1.68         if ((he = System::getHostByName(hostName)))
 304 kumpf           1.66         {
 305                                  strncpy(hostName, he->h_name, sizeof(hostName) - 1);
 306                              }
 307                              // assign hostName
 308                              // if gethostbyname was successful assign that result
 309                              // else assign unqualified hostname
 310                              fqName.assign(hostName);
 311                          }
 312                          if (resolv)
 313                          {
 314                              freeaddrinfo(resolv);
 315                          }
 316                      
 317                          return fqName;
 318                      
 319                      #else /* !PEGASUS_OS_ZOS && !PEGASUS_OS_VMS */
 320                      
 321                          char hostEntryBuffer[8192];
 322                          struct hostent hostEntryStruct;
 323                          struct hostent* hostEntry = System::getHostByName(
 324                              hostName, &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
 325 kumpf           1.66 
 326                          if (hostEntry)
 327                          {
 328                              strncpy(hostName, hostEntry->h_name, sizeof(hostName) - 1);
 329                          }
 330                          return String(hostName);
 331                      
 332                      #endif
 333                      }
 334                      
 335                      String System::getFullyQualifiedHostName()
 336                      {
 337                          static String _hostname;
 338                          static MutexType _mutex = PEGASUS_MUTEX_INITIALIZER;
 339                      
 340                          // Use double-checked locking pattern to avoid overhead of
 341                          // mutex on subsequent calls.
 342                      
 343                          if (0 == _hostname.size())
 344                          {
 345                              mutex_lock(&_mutex);
 346 kumpf           1.66 
 347                              if (0 == _hostname.size())
 348                              {
 349                                  try
 350                                  {
 351                                      _hostname = _getFullyQualifiedHostName();
 352                                  }
 353                                  catch (...)
 354                                  {
 355                                      mutex_unlock(&_mutex);
 356                                      throw;
 357                                  }
 358                              }
 359                      
 360                              mutex_unlock(&_mutex);
 361                          }
 362                      
 363                          return _hostname;
 364                      }
 365                      
 366 dave.sudlik     1.52 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
 367 marek           1.24 {
 368 dave.sudlik     1.52 #ifdef PEGASUS_ENABLE_IPV6
 369                          struct addrinfo *info, hints;
 370                          memset (&hints, 0, sizeof(struct addrinfo));
 371                      
 372                          // Check for valid IPV4 address, if found return ipv4 address
 373                          *af = AF_INET;
 374                          hints.ai_family = *af;
 375 kumpf           1.73     hints.ai_protocol = IPPROTO_TCP;
 376 dave.sudlik     1.52     hints.ai_socktype = SOCK_STREAM;
 377 dmitry.mikulin  1.59     if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
 378 dave.sudlik     1.52     {
 379                              char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
 380 kumpf           1.73         HostAddress::convertBinaryToText(info->ai_family,
 381 kumpf           1.54             &(reinterpret_cast<struct sockaddr_in*>(info->ai_addr))->sin_addr,
 382                                  ipAddress,
 383 dave.sudlik     1.52             PEGASUS_INET_ADDRSTR_LEN);
 384                              hostIP = ipAddress;
 385                              freeaddrinfo(info);
 386                              return true;
 387                          }
 388                      
 389 kumpf           1.73     // Check for valid IPV6 Address.
 390 dave.sudlik     1.52     *af = AF_INET6;
 391                          hints.ai_family = *af;
 392                          hints.ai_protocol = IPPROTO_TCP;
 393                          hints.ai_socktype = SOCK_STREAM;
 394 dmitry.mikulin  1.59     if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
 395 dave.sudlik     1.52     {
 396                              char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
 397                              HostAddress::convertBinaryToText(info->ai_family,
 398 kumpf           1.54             &(reinterpret_cast<struct sockaddr_in6*>(info->ai_addr))->sin6_addr,
 399                                  ipAddress,
 400 dave.sudlik     1.52             PEGASUS_INET6_ADDRSTR_LEN);
 401                              hostIP = ipAddress;
 402                              freeaddrinfo(info);
 403                              return true;
 404                          }
 405                      
 406                          return false;
 407                      #else
 408                          *af = AF_INET;
 409 kumpf           1.36     struct hostent* hostEntry;
 410                          struct in_addr inaddr;
 411                          String ipAddress;
 412                          CString hostNameCString = hostName.getCString();
 413                          const char* hostNamePtr = hostNameCString;
 414                      
 415                          char hostEntryBuffer[8192];
 416                          struct hostent hostEntryStruct;
 417 kumpf           1.73     hostEntry = getHostByName(hostNamePtr, &hostEntryStruct,
 418 dmitry.mikulin  1.59         hostEntryBuffer, sizeof (hostEntryBuffer));
 419 kumpf           1.36 
 420                          if (hostEntry)
 421 marek           1.24     {
 422 kumpf           1.36         ::memcpy( &inaddr, hostEntry->h_addr,4);
 423 marek           1.24         ipAddress = ::inet_ntoa( inaddr );
 424 dmitry.mikulin  1.59         hostIP = ipAddress;
 425                              return true;
 426 marek           1.24     }
 427 dmitry.mikulin  1.59     return false;
 428 dave.sudlik     1.52 #endif
 429 marek           1.24 }
 430 r.kieninger     1.21 
 431 venkat.puvvada  1.56 
 432                      #ifdef PEGASUS_ENABLE_IPV6
 433                      Boolean System::isIPv6StackActive()
 434                      {
 435                          SocketHandle ip6Socket;
 436                          if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
 437                              == PEGASUS_INVALID_SOCKET)
 438                          {
 439                              if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
 440                              {
 441                                  return false;
 442                              }
 443                          }
 444                          else
 445                          {
 446 carson.hovey    1.64 #if defined(PEGASUS_OS_VMS)
 447                              // vms has tcpipv6 support in the kernel so socket
 448                              // will always work so a call to "bind" is needed
 449                              // to complete this test.
 450                      
 451                              struct sockaddr_storage listenAddress;
 452                              memset(&listenAddress, 0, sizeof (listenAddress));
 453                              SocketLength addressLength;
 454                      
 455                              HostAddress::convertTextToBinary(
 456                                  HostAddress::AT_IPV6,
 457                                  "::1",
 458                                  &reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_addr);
 459                              listenAddress.ss_family = AF_INET6;
 460                              reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_port = 0;
 461                      
 462                              addressLength = sizeof(struct sockaddr_in6);
 463                      
 464                              if (::bind(
 465                                  ip6Socket,
 466                                  reinterpret_cast<struct sockaddr*>(&listenAddress),
 467 carson.hovey    1.64             addressLength) < 0)
 468                              {
 469                                  Socket::close(ip6Socket);
 470                                  return false;
 471                              }
 472                      #endif  // PEGASUS_OS_VMS
 473                      
 474 venkat.puvvada  1.56         Socket::close(ip6Socket);
 475                          }
 476                      
 477                          return true;
 478                      }
 479                      #endif
 480                      
 481 r.kieninger     1.21 // ------------------------------------------------------------------------
 482                      // Convert a hostname into a a single host unique integer representation
 483                      // ------------------------------------------------------------------------
 484 marek           1.63 Boolean System::acquireIP(const char* hostname, int *af, void *dst)
 485 dave.sudlik     1.52 {
 486                      #ifdef PEGASUS_ENABLE_IPV6
 487                          String ipAddress;
 488                          if(getHostIP(hostname, af, ipAddress))
 489 dmitry.mikulin  1.59     {
 490 dave.sudlik     1.52         HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
 491                              return true;
 492                          }
 493                          return false;
 494                      #else
 495                          *af = AF_INET;
 496 kumpf           1.44     Uint32 ip = 0xFFFFFFFF;
 497 marek           1.65     if (!hostname)
 498 kumpf           1.73     {
 499 marek           1.65         *af = 0xFFFFFFFF;
 500                              return false;
 501                          }
 502 r.kieninger     1.21 
 503 dave.sudlik     1.22 ////////////////////////////////////////////////////////////////////////////////
 504                      // This code used to check if the first character of "hostname" was alphabetic
 505 kumpf           1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
 506                      // relaxed this requirement to alphabetic character *or* digit. So bug 1462
 507                      // changed the flow here to call inet_addr first to check for a valid IP
 508                      // address in dotted decimal notation. If it's not a valid IP address, then
 509                      // try to validate it as a hostname.
 510                      // RFC 1123 states: The host SHOULD check the string syntactically for a
 511                      // dotted-decimal number before looking it up in the Domain Name System.
 512 dave.sudlik     1.22 // Hence the call to inet_addr() first.
 513                      ////////////////////////////////////////////////////////////////////////////////
 514                      
 515 kumpf           1.44     Uint32 tmp_addr = inet_addr((char *) hostname);
 516 kumpf           1.36     struct hostent* hostEntry;
 517 r.kieninger     1.21 
 518 dave.sudlik     1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
 519                      //       A better solution would be to use inet_aton() or equivalent, as
 520                      //       inet_addr() is now considered "obsolete".
 521                      
 522                          if (tmp_addr == 0xFFFFFFFF)  // if hostname is not an IP address
 523 kumpf           1.36     {
 524                              char hostEntryBuffer[8192];
 525                              struct hostent hostEntryStruct;
 526 kumpf           1.73         hostEntry = getHostByName(hostname, &hostEntryStruct,
 527 dmitry.mikulin  1.59             hostEntryBuffer, sizeof (hostEntryBuffer));
 528 kumpf           1.36 
 529                              if (!hostEntry)
 530 kumpf           1.44         {
 531 dave.sudlik     1.52             // error, couldn't resolve the ip
 532                                  memcpy(dst, &ip, sizeof (Uint32));
 533                                  return false;
 534 kumpf           1.44         }
 535                              unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
 536                      
 537                              ip_part1 = hostEntry->h_addr[0];
 538                              ip_part2 = hostEntry->h_addr[1];
 539                              ip_part3 = hostEntry->h_addr[2];
 540                              ip_part4 = hostEntry->h_addr[3];
 541                              ip = ip_part1;
 542                              ip = (ip << 8) + ip_part2;
 543                              ip = (ip << 8) + ip_part3;
 544                              ip = (ip << 8) + ip_part4;
 545                          }
 546 dave.sudlik     1.22     else    // else hostname *is* a dotted-decimal IP address
 547 kumpf           1.44     {
 548                              // resolve hostaddr to a real host entry
 549                              // casting to (const char *) as (char *) will work as (void *) too,
 550                              // those it fits all platforms
 551 ms.aruran       1.45         char hostEntryBuffer[8192];
 552                              struct hostent hostEntryStruct;
 553 kumpf           1.73         hostEntry =
 554                                  getHostByAddr((const char*) &tmp_addr, sizeof(tmp_addr), AF_INET,
 555 dmitry.mikulin  1.59                 &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
 556 ms.aruran       1.45 
 557 kumpf           1.44         if (hostEntry == 0)
 558                              {
 559                                  // error, couldn't resolve the ip
 560 dave.sudlik     1.52             memcpy(dst, &ip, sizeof (Uint32));
 561                                  return false;
 562 kumpf           1.44         }
 563                              else
 564                              {
 565                                  unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
 566 r.kieninger     1.21 
 567 kumpf           1.44             ip_part1 = hostEntry->h_addr[0];
 568                                  ip_part2 = hostEntry->h_addr[1];
 569                                  ip_part3 = hostEntry->h_addr[2];
 570                                  ip_part4 = hostEntry->h_addr[3];
 571                                  ip = ip_part1;
 572                                  ip = (ip << 8) + ip_part2;
 573                                  ip = (ip << 8) + ip_part3;
 574                                  ip = (ip << 8) + ip_part4;
 575                              }
 576                          }
 577 dave.sudlik     1.52     memcpy(dst, &ip, sizeof (Uint32));
 578 carolann.graves 1.29 
 579                          return true;
 580 dave.sudlik     1.52 #endif
 581 carolann.graves 1.29 }
 582                      
 583 kumpf           1.44 Boolean System::resolveHostNameAtDNS(
 584                          const char* hostname,
 585                          Uint32* resolvedNameIP)
 586 marek           1.43 {
 587 dmitry.mikulin  1.59     struct hostent* hostEntry;
 588                      
 589 marek           1.43     // ask the DNS for hostname resolution to IP address
 590                          // this can mean a time delay for as long as the DNS
 591 kumpf           1.44     // takes to answer
 592                          char hostEntryBuffer[8192];
 593                          struct hostent hostEntryStruct;
 594 kumpf           1.73     hostEntry = getHostByName(hostname, &hostEntryStruct,
 595 dmitry.mikulin  1.59         hostEntryBuffer, sizeof (hostEntryBuffer));
 596 marek           1.43 
 597                          if (hostEntry == 0)
 598                          {
 599                              // error, couldn't resolve the hostname to an ip address
 600                              return false;
 601 kumpf           1.44     }
 602                          else
 603 marek           1.43     {
 604                              unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
 605                              ip_part1 = hostEntry->h_addr[0];
 606                              ip_part2 = hostEntry->h_addr[1];
 607                              ip_part3 = hostEntry->h_addr[2];
 608                              ip_part4 = hostEntry->h_addr[3];
 609                              *resolvedNameIP = ip_part1;
 610                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
 611                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
 612                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
 613                          }
 614                          return true;
 615                      }
 616                      
 617                      Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
 618                      {
 619 kumpf           1.44     struct hostent *entry;
 620 marek           1.43 
 621 dmitry.mikulin  1.59     entry = getHostByAddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
 622 kumpf           1.73 
 623 kumpf           1.44     if (entry == 0)
 624                          {
 625                              // error, couldn't resolve the ip
 626                              return false;
 627                          }
 628                          else
 629                          {
 630                              unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
 631                              ip_part1 = entry->h_addr[0];
 632                              ip_part2 = entry->h_addr[1];
 633                              ip_part3 = entry->h_addr[2];
 634                              ip_part4 = entry->h_addr[3];
 635                              *resolvedIP = ip_part1;
 636                              *resolvedIP = (*resolvedIP << 8) + ip_part2;
 637                              *resolvedIP = (*resolvedIP << 8) + ip_part3;
 638                              *resolvedIP = (*resolvedIP << 8) + ip_part4;
 639                          }
 640                          return true;
 641 marek           1.43 }
 642                      
 643                      
 644 dave.sudlik     1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
 645                      {
 646                      #ifdef PEGASUS_ENABLE_IPV6
 647                          struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
 648                      #endif
 649                          switch (af)
 650                          {
 651                      #ifdef PEGASUS_ENABLE_IPV6
 652                              case AF_INET6:
 653                                  return !memcmp(&ip6, binIPAddress, sizeof (ip6));
 654                      #endif
 655                              case AF_INET:
 656 karl            1.69         {
 657                                  Uint32 tmp;
 658                                  memcpy(&tmp, binIPAddress, sizeof(Uint32));
 659                                  Uint32 n = ntohl(tmp);
 660 venkat.puvvada  1.75             return n >= PEGASUS_IPV4_LOOPBACK_RANGE_START && 
 661                                      n <= PEGASUS_IPV4_LOOPBACK_RANGE_END;
 662 karl            1.69         }
 663 dave.sudlik     1.52     }
 664                      
 665                          return false;
 666                      }
 667                      
 668 marek           1.43 Boolean System::isLocalHost(const String &hostName)
 669                      {
 670 dave.sudlik     1.52 // Get all ip addresses on the node and compare them with the given hostname.
 671                      #ifdef PEGASUS_ENABLE_IPV6
 672                          CString csName = hostName.getCString();
 673 dave.sudlik     1.53     struct addrinfo hints, *res1, *res2, *res1root, *res2root;
 674 dave.sudlik     1.52     char localHostName[PEGASUS_MAXHOSTNAMELEN];
 675                          gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
 676                          Boolean isLocal = false;
 677                      
 678                          memset(&hints, 0, sizeof(hints));
 679                          hints.ai_family = AF_INET;
 680                          hints.ai_socktype = SOCK_STREAM;
 681                          hints.ai_protocol = IPPROTO_TCP;
 682 dave.sudlik     1.53     res1root = res2root = 0;
 683 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
 684                          getAddrInfo(localHostName, 0, &hints, &res2root);
 685 dave.sudlik     1.52 
 686 dave.sudlik     1.53     res1 = res1root;
 687 dave.sudlik     1.52     while (res1 && !isLocal)
 688                          {
 689                              if (isLoopBack(AF_INET,
 690 kumpf           1.54             &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
 691 dave.sudlik     1.52         {
 692                                  isLocal = true;
 693                                  break;
 694                              }
 695                      
 696 dave.sudlik     1.53         res2 = res2root;
 697 kumpf           1.73         while (res2)
 698 dave.sudlik     1.52         {
 699 kumpf           1.54             if (!memcmp(
 700                                          &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
 701                                              sin_addr,
 702                                          &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
 703                                              sin_addr,
 704                                          sizeof (struct in_addr)))
 705 dave.sudlik     1.52             {
 706                                      isLocal = true;
 707                                      break;
 708                                  }
 709 dave.sudlik     1.53             res2 = res2->ai_next;
 710 dave.sudlik     1.52         }
 711                              res1 = res1->ai_next;
 712 kumpf           1.73     }
 713 kumpf           1.62     if (res1root)
 714                          {
 715                              freeaddrinfo(res1root);
 716                          }
 717                          if (res2root)
 718                          {
 719                              freeaddrinfo(res2root);
 720                          }
 721 dave.sudlik     1.52     if (isLocal)
 722                          {
 723                              return true;
 724 kumpf           1.73     }
 725 dave.sudlik     1.52 
 726                          hints.ai_family = AF_INET6;
 727 dave.sudlik     1.53     res1root = res2root = 0;
 728 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
 729                          getAddrInfo(localHostName, 0, &hints, &res2root);
 730 dave.sudlik     1.53 
 731                          res1 = res1root;
 732 dave.sudlik     1.52     while (res1 && !isLocal)
 733                          {
 734 kumpf           1.54         if (isLoopBack(
 735                                      AF_INET6,
 736                                      &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
 737                                          sin6_addr))
 738 dave.sudlik     1.52         {
 739                                  isLocal = true;
 740                                  break;
 741                              }
 742                      
 743 dave.sudlik     1.53         res2 = res2root;
 744                              while (res2)
 745 dave.sudlik     1.52         {
 746 kumpf           1.54             if (!memcmp(
 747                                          &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
 748                                              sin6_addr,
 749                                          &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
 750                                              sin6_addr,
 751                                          sizeof (struct in6_addr)))
 752 dave.sudlik     1.52             {
 753                                      isLocal = true;
 754                                      break;
 755                                  }
 756 dave.sudlik     1.53             res2 = res2->ai_next;
 757 dave.sudlik     1.52         }
 758                              res1 = res1->ai_next;
 759                          }
 760 kumpf           1.62     if (res1root)
 761                          {
 762                              freeaddrinfo(res1root);
 763                          }
 764                          if (res2root)
 765                          {
 766                              freeaddrinfo(res2root);
 767                          }
 768 dave.sudlik     1.52     return isLocal;
 769                      #else
 770                      
 771 marek           1.43     // differentiate between a dotted IP address given
 772                          // and a real hostname given
 773                          CString csName = hostName.getCString();
 774 marek           1.46     char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
 775                          strcpy(cc_hostname, (const char*) csName);
 776 marek           1.43     Uint32 tmp_addr = 0xFFFFFFFF;
 777                          Boolean hostNameIsIPNotation;
 778                      
 779                          // Note: Platforms already supporting the inet_aton()
 780                          //       should define their platform here,
 781                          //        as this is the superior way to work
 782 kumpf           1.54 #if defined(PEGASUS_OS_LINUX) || \
 783                          defined(PEGASUS_OS_AIX) || \
 784 ouyang.jian     1.55     defined(PEGASUS_OS_HPUX) || \
 785 carson.hovey    1.60     defined(PEGASUS_OS_PASE) || \
 786                          defined(PEGASUS_OS_VMS)
 787 kumpf           1.44 
 788 marek           1.43     struct in_addr inaddr;
 789                          // if inet_aton failed(return=0),
 790                          // we do not have a valip IP address (x.x.x.x)
 791                          int atonSuccess = inet_aton(cc_hostname, &inaddr);
 792                          if (atonSuccess == 0) hostNameIsIPNotation = false;
 793                          else
 794                          {
 795                              hostNameIsIPNotation = true;
 796                              tmp_addr = inaddr.s_addr;
 797                          }
 798                      #else
 799                          // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
 800                          //       A better solution would be to use inet_aton() or equivalent, as
 801                          //       inet_addr() is now considered "obsolete".
 802                          // Note: inet_aton() not yet supported on all Pegasus platforms
 803 kumpf           1.44     tmp_addr = inet_addr((char *) cc_hostname);
 804 marek           1.43     if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
 805                          else hostNameIsIPNotation = true;
 806                      #endif
 807 kumpf           1.44 
 808 marek           1.43     if (!hostNameIsIPNotation)  // if hostname is not an IP address
 809 kumpf           1.44     {
 810 marek           1.43         // localhost ?
 811                              if (String::equalNoCase(hostName,String("localhost"))) return true;
 812 marek           1.46         char localHostName[PEGASUS_MAXHOSTNAMELEN];
 813 marek           1.47         CString cstringLocalHostName = System::getHostName().getCString();
 814 kumpf           1.73         strcpy(localHostName, (const char*) cstringLocalHostName);
 815 marek           1.43         // given hostname equals what system returns as local hostname ?
 816                              if (String::equalNoCase(hostName,localHostName)) return true;
 817                              Uint32 hostIP;
 818                              // bail out if hostname unresolveable
 819                              if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
 820                              // lets see if the IP is defined on one of the network interfaces
 821                              // this can help us avoid another call to DNS
 822                              if (System::isIpOnNetworkInterface(hostIP)) return true;
 823                              // need to check if the local hosts name is possibly
 824                              // registered at the DNS with the IP address equal resolvedNameIP
 825                              Uint32 localHostIP;
 826 kumpf           1.44         if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
 827                                  return false;
 828 marek           1.43         if (localHostIP == hostIP) return true;
 829 kumpf           1.44     }
 830                          else
 831 marek           1.43     {   // hostname is an IP address
 832                              // 127.0.0.1 is always the loopback
 833                              // inet_addr returns network byte order
 834                              if (tmp_addr == htonl(0x7F000001)) return true;
 835                              // IP defined on a local AF_INET network interface
 836                              if (System::isIpOnNetworkInterface(tmp_addr)) return true;
 837                              // out of luck so far, lets ask the DNS what our IP is
 838                              // and check against what we got
 839                              Uint32 localHostIP;
 840 kumpf           1.44         if (!System::resolveHostNameAtDNS(
 841                                      (const char*) System::getHostName().getCString(), &localHostIP))
 842                                  return false;
 843 marek           1.43         if (localHostIP == tmp_addr) return true;
 844                              // not yet, sometimes resolving the IP address we got against the DNS
 845                              // can solve the problem
 846 kumpf           1.44         // casting to (const char *) as (char *) will work as (void *) too,
 847                              // those it fits all platforms
 848 marek           1.43         Uint32 hostIP;
 849                              if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
 850                              if (hostIP == localHostIP) return true;
 851                          }
 852                          return false;
 853 dave.sudlik     1.52 #endif
 854 marek           1.43 }
 855                      
 856 dmitry.mikulin  1.59 struct hostent* System::getHostByName(
 857 kumpf           1.73     const char* name,
 858                          struct hostent* he,
 859                          char* buf,
 860 dmitry.mikulin  1.59     size_t len)
 861                      {
 862                          int hostEntryErrno = 0;
 863                          struct hostent* hostEntry = 0;
 864                          unsigned int maxTries = 5;
 865                      
 866                          do
 867                          {
 868                      #if defined(PEGASUS_OS_LINUX)
 869 kumpf           1.73         gethostbyname_r(name,
 870                                  he,
 871                                  buf,
 872                                  len,
 873                                  &hostEntry,
 874 dmitry.mikulin  1.59             &hostEntryErrno);
 875                      #elif defined(PEGASUS_OS_SOLARIS)
 876 kumpf           1.73         hostEntry = gethostbyname_r((char *)name,
 877                                              he,
 878                                              buf,
 879                                              len,
 880 dmitry.mikulin  1.59                         &hostEntryErrno);
 881                      #elif defined(PEGASUS_OS_ZOS)
 882                              char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
 883                              if (String::equalNoCase("localhost", String(name)))
 884                              {
 885                                  gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
 886                                  hostName[sizeof(hostName) - 1] = 0;
 887                                  hostEntry = gethostbyname(hostName);
 888                              }
 889                              else
 890                              {
 891                                  hostEntry = gethostbyname((char *)name);
 892                              }
 893                              hostEntryErrno = h_errno;
 894                      #else
 895                              hostEntry = gethostbyname((char *)name);
 896                              hostEntryErrno = h_errno;
 897                      #endif
 898                          } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
 899                                   maxTries-- > 0);
 900                      
 901 dmitry.mikulin  1.59     return hostEntry;
 902                      }
 903                      
 904                      struct hostent* System::getHostByAddr(
 905 kumpf           1.73     const char *addr,
 906                          int len,
 907 dmitry.mikulin  1.59     int type,
 908 kumpf           1.73     struct hostent* he,
 909                          char* buf,
 910 dmitry.mikulin  1.59     size_t buflen)
 911                      {
 912                          int hostEntryErrno = 0;
 913                          struct hostent* hostEntry = 0;
 914                          unsigned int maxTries = 5;
 915                      
 916                          do
 917                          {
 918                      #if defined(PEGASUS_OS_LINUX)
 919 kumpf           1.73         gethostbyaddr_r(addr,
 920                                  len,
 921                                  type,
 922                                  he,
 923                                  buf,
 924                                  buflen,
 925                                  &hostEntry,
 926 dmitry.mikulin  1.59             &hostEntryErrno);
 927                      #elif defined(PEGASUS_OS_SOLARIS)
 928                              char hostEntryBuffer[8192];
 929                              struct hostent hostEntryStruct;
 930                      
 931 kumpf           1.73         hostEntry = gethostbyaddr_r(addr,
 932                                              len,
 933                                              type,
 934                                              he,
 935                                              buf,
 936                                              buflen,
 937 dmitry.mikulin  1.59                         &hostEntryErrno);
 938                      #else
 939 kumpf           1.73         hostEntry = gethostbyaddr(addr,
 940                                              len,
 941 dmitry.mikulin  1.59                         type);
 942                              hostEntryErrno = h_errno;
 943                      #endif
 944                          } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
 945                                   maxTries-- > 0);
 946                      
 947                          return hostEntry;
 948                      }
 949                      
 950 dmitry.mikulin  1.61 #if defined(PEGASUS_OS_ZOS) || \
 951                          defined(PEGASUS_OS_VMS) || \
 952                          defined(PEGASUS_ENABLE_IPV6)
 953                      
 954 dmitry.mikulin  1.59 int System::getAddrInfo(
 955 kumpf           1.73     const char *hostname,
 956 dmitry.mikulin  1.59     const char *servname,
 957 kumpf           1.73     const struct addrinfo *hints,
 958 dmitry.mikulin  1.59     struct addrinfo **res)
 959                      {
 960                          int rc = 0;
 961 kumpf           1.73     unsigned int maxTries = 5;
 962 dmitry.mikulin  1.59 
 963 ouyang.jian     1.67 #ifdef PEGASUS_OS_PASE
 964                          CString hostNameCString;
 965                          if (String::equalNoCase(hostname, "localhost"))
 966                          {
 967                              hostNameCString = getHostName().getCString();
 968                              hostname = (const char*)hostNameCString;
 969                          }
 970                      #endif
 971                      
 972 kumpf           1.73     while ((rc = getaddrinfo(hostname,
 973                                           servname,
 974                                           hints,
 975 dmitry.mikulin  1.59                      res)) == EAI_AGAIN &&
 976                                 maxTries-- > 0)
 977                              ;
 978                          return rc;
 979                      }
 980                      
 981                      int System::getNameInfo(
 982 kumpf           1.73     const struct sockaddr *sa,
 983 dmitry.mikulin  1.59     size_t salen,
 984 kumpf           1.73     char *host,
 985                          size_t hostlen,
 986                          char *serv,
 987                          size_t servlen,
 988 dmitry.mikulin  1.59     int flags)
 989                      {
 990                          int rc = 0;
 991 kumpf           1.73     unsigned int maxTries = 5;
 992 dmitry.mikulin  1.59 
 993 kumpf           1.73     while ((rc = getnameinfo(sa,
 994                                           salen,
 995                                           host,
 996                                           hostlen,
 997                                           serv,
 998                                           servlen,
 999 dmitry.mikulin  1.59                      flags)) == EAI_AGAIN &&
1000                                 maxTries-- > 0)
1001                              ;
1002                          return rc;
1003                      }
1004                      
1005 dmitry.mikulin  1.61 #endif
1006 dmitry.mikulin  1.59 
1007 tony            1.17 // System ID constants for Logger::put and Logger::trace
1008 s.kodali        1.76 #ifdef PEGASUS_FLAVOR
1009                      const String System::CIMLISTENER = "cimlistener" PEGASUS_FLAVOR;
1010                      #else
1011 tony            1.17 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
1012 s.kodali        1.76 #endif
1013 tony            1.17 
1014 mike            1.8  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2