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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2