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

  1 karl  1.37 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.6  //
  3 karl  1.23 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.19 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.23 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.25 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.37 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.6  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15 kumpf 1.11 // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18 mike  1.6  // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 karl  1.23 // 
 21 kumpf 1.11 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.6  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24 kumpf 1.11 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27 mike  1.6  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //
 32            //%/////////////////////////////////////////////////////////////////////////////
 33 mike  1.8  
 34 sage  1.12 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
 35 r.kieninger 1.21 #include <Pegasus/Common/Config.h>
 36                  #endif
 37 sage        1.12 
 38 mike        1.8  #include <fstream>
 39 kumpf       1.13 #include <cctype>  // for tolower()
 40 kumpf       1.14 #include <cstring>
 41 mike        1.6  #include "System.h"
 42 r.kieninger 1.21 #include "Socket.h"
 43 mike        1.39 #include "Network.h"
 44 kumpf       1.10 #include <Pegasus/Common/PegasusVersion.h>
 45 mateus.baur 1.50 #include <Pegasus/Common/FileSystem.h>
 46 dave.sudlik 1.52 #include <Pegasus/Common/HostAddress.h>
 47                  #include <Pegasus/Common/Array.h>
 48 kumpf       1.10 
 49 mike        1.6  #if defined(PEGASUS_OS_TYPE_WINDOWS)
 50                  # include "SystemWindows.cpp"
 51 kumpf       1.41 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
 52 mike        1.40 # include "SystemPOSIX.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 tony        1.15 // Return the just the file name from the path into basename
140                  char *System::extract_file_name(const char *fullpath, char *basename)
141                  {
142 kumpf       1.44     if (fullpath == NULL)
143                      {
144                          basename[0] = '\0';
145                          return basename;
146                      }
147 kumpf       1.31 
148 kumpf       1.44     for (const char* p = fullpath + strlen(fullpath) - 1; p >= fullpath; p--)
149                      {
150                          if (*p == '\\' || *p == '/')
151                          {
152                              strcpy(basename, p+1);
153                              return basename;
154                          }
155                      }
156                  
157                      strcpy(basename, fullpath);
158                      return basename;
159 tony        1.15 }
160                  
161                  // Return the just the path to the file name into dirname
162                  char *System::extract_file_path(const char *fullpath, char *dirname)
163                  {
164 kumpf       1.44     char *p;
165                      char buff[4096];
166                      if (fullpath == NULL)
167                      {
168                          dirname[0] = '\0';
169                          return dirname;
170                      }
171                      strncpy(buff, fullpath, sizeof(buff)-1);
172                      buff[sizeof(buff)-1] =  '\0';
173                      for (p = buff + strlen(buff); p >= buff; p--)
174 tony        1.15     {
175 kumpf       1.44         if (*p == '\\' || *p == '/')
176 tony        1.15         {
177                            strncpy(dirname, buff, p+1 - buff);
178                            dirname[p+1 - buff] = '\0';
179                            return dirname;
180                          }
181                      }
182 kumpf       1.44     strcpy(dirname, fullpath);
183                      return dirname;
184 tony        1.15 }
185                  
186 kumpf       1.66 String System::getHostName()
187                  {
188                      static String _hostname;
189                      static MutexType _mutex = PEGASUS_MUTEX_INITIALIZER;
190                  
191                      // Use double-checked locking pattern to avoid overhead of
192                      // mutex on subsequent calls.
193                  
194                      if (0 == _hostname.size())
195                      {
196                          mutex_lock(&_mutex);
197                  
198                          if (0 == _hostname.size())
199                          {
200                              char hostname[PEGASUS_MAXHOSTNAMELEN + 1];
201                              // If gethostname() fails, an empty or truncated value is used.
202                              hostname[0] = 0;
203                              gethostname(hostname, sizeof(hostname));
204                              hostname[sizeof(hostname)-1] = 0;
205                              _hostname.assign(hostname);
206                          }
207 kumpf       1.66 
208                          mutex_unlock(&_mutex);
209                      }
210                  
211                      return _hostname;
212                  }
213                  
214                  static String _getFullyQualifiedHostName()
215                  {
216                      char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
217                  
218                      // Get the short name of the local host.
219                      // If gethostname() fails, an empty or truncated value is used.
220                      hostName[0] = 0;
221                      gethostname(hostName, sizeof(hostName));
222                      hostName[sizeof(hostName)-1] = 0;
223                  
224                  #if defined(PEGASUS_OS_ZOS)|| \
225                      defined(PEGASUS_OS_VMS)
226                  
227                      String fqName;
228 kumpf       1.66     struct addrinfo *resolv;
229                      struct addrinfo hint;
230                      struct hostent *he;
231                  
232                      memset (&hint, 0, sizeof(struct addrinfo));
233                      hint.ai_flags = AI_CANONNAME;
234                      hint.ai_family = AF_UNSPEC; // any family
235                      hint.ai_socktype = 0;       // any socket type
236                      hint.ai_protocol = 0;       // any protocol
237 carson.hovey 1.68     int success = System::getAddrInfo(hostName, NULL, &hint, &resolv);
238 kumpf        1.66     if (success==0)
239                       {
240                           // assign fully qualified hostname
241                           fqName.assign(resolv->ai_canonname);
242                       }
243                       else
244                       {
245 carson.hovey 1.68         if ((he = System::getHostByName(hostName)))
246 kumpf        1.66         {
247                               strncpy(hostName, he->h_name, sizeof(hostName) - 1);
248                           }
249                           // assign hostName
250                           // if gethostbyname was successful assign that result
251                           // else assign unqualified hostname
252                           fqName.assign(hostName);
253                       }
254                       if (resolv)
255                       {
256                           freeaddrinfo(resolv);
257                       }
258                   
259                       return fqName;
260                   
261                   #else /* !PEGASUS_OS_ZOS && !PEGASUS_OS_VMS */
262                   
263                       char hostEntryBuffer[8192];
264                       struct hostent hostEntryStruct;
265                       struct hostent* hostEntry = System::getHostByName(
266                           hostName, &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
267 kumpf        1.66 
268                       if (hostEntry)
269                       {
270                           strncpy(hostName, hostEntry->h_name, sizeof(hostName) - 1);
271                       }
272                       return String(hostName);
273                   
274                   #endif
275                   }
276                   
277                   String System::getFullyQualifiedHostName()
278                   {
279                       static String _hostname;
280                       static MutexType _mutex = PEGASUS_MUTEX_INITIALIZER;
281                   
282                       // Use double-checked locking pattern to avoid overhead of
283                       // mutex on subsequent calls.
284                   
285                       if (0 == _hostname.size())
286                       {
287                           mutex_lock(&_mutex);
288 kumpf        1.66 
289                           if (0 == _hostname.size())
290                           {
291                               try
292                               {
293                                   _hostname = _getFullyQualifiedHostName();
294                               }
295                               catch (...)
296                               {
297                                   mutex_unlock(&_mutex);
298                                   throw;
299                               }
300                           }
301                   
302                           mutex_unlock(&_mutex);
303                       }
304                   
305                       return _hostname;
306                   }
307                   
308 dave.sudlik  1.52 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
309 marek        1.24 {
310 dave.sudlik  1.52 #ifdef PEGASUS_ENABLE_IPV6
311                       struct addrinfo *info, hints;
312                       memset (&hints, 0, sizeof(struct addrinfo));
313                   
314                       // Check for valid IPV4 address, if found return ipv4 address
315                       *af = AF_INET;
316                       hints.ai_family = *af;
317                       hints.ai_protocol = IPPROTO_TCP;   
318                       hints.ai_socktype = SOCK_STREAM;
319 dmitry.mikulin 1.59     if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
320 dave.sudlik    1.52     {
321                             char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
322                             HostAddress::convertBinaryToText(info->ai_family, 
323 kumpf          1.54             &(reinterpret_cast<struct sockaddr_in*>(info->ai_addr))->sin_addr,
324                                 ipAddress,
325 dave.sudlik    1.52             PEGASUS_INET_ADDRSTR_LEN);
326                             hostIP = ipAddress;
327                             freeaddrinfo(info);
328                             return true;
329                         }
330                     
331                         // Check for valid IPV6 Address. 
332                         *af = AF_INET6;
333                         hints.ai_family = *af;
334                         hints.ai_protocol = IPPROTO_TCP;
335                         hints.ai_socktype = SOCK_STREAM;
336 dmitry.mikulin 1.59     if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
337 dave.sudlik    1.52     {
338                             char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
339                             HostAddress::convertBinaryToText(info->ai_family,
340 kumpf          1.54             &(reinterpret_cast<struct sockaddr_in6*>(info->ai_addr))->sin6_addr,
341                                 ipAddress,
342 dave.sudlik    1.52             PEGASUS_INET6_ADDRSTR_LEN);
343                             hostIP = ipAddress;
344                             freeaddrinfo(info);
345                             return true;
346                         }
347                     
348                         return false;
349                     #else
350                         *af = AF_INET;
351 kumpf          1.36     struct hostent* hostEntry;
352                         struct in_addr inaddr;
353                         String ipAddress;
354                         CString hostNameCString = hostName.getCString();
355                         const char* hostNamePtr = hostNameCString;
356                     
357                         char hostEntryBuffer[8192];
358                         struct hostent hostEntryStruct;
359 dmitry.mikulin 1.59     hostEntry = getHostByName(hostNamePtr, &hostEntryStruct, 
360                             hostEntryBuffer, sizeof (hostEntryBuffer));
361 kumpf          1.36 
362                         if (hostEntry)
363 marek          1.24     {
364 kumpf          1.36         ::memcpy( &inaddr, hostEntry->h_addr,4);
365 marek          1.24         ipAddress = ::inet_ntoa( inaddr );
366 dmitry.mikulin 1.59         hostIP = ipAddress;
367                             return true;
368 marek          1.24     }
369 dmitry.mikulin 1.59     return false;
370 dave.sudlik    1.52 #endif
371 marek          1.24 }
372 r.kieninger    1.21 
373 venkat.puvvada 1.56 
374                     #ifdef PEGASUS_ENABLE_IPV6
375                     Boolean System::isIPv6StackActive()
376                     {
377                         SocketHandle ip6Socket;
378                         if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
379                             == PEGASUS_INVALID_SOCKET)
380                         {
381                             if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
382                             {
383                                 return false;
384                             }
385                         }
386                         else
387                         {
388 carson.hovey   1.64 #if defined(PEGASUS_OS_VMS)
389                             // vms has tcpipv6 support in the kernel so socket
390                             // will always work so a call to "bind" is needed
391                             // to complete this test.
392                     
393                             struct sockaddr_storage listenAddress;
394                             memset(&listenAddress, 0, sizeof (listenAddress));
395                             SocketLength addressLength;
396                     
397                             HostAddress::convertTextToBinary(
398                                 HostAddress::AT_IPV6,
399                                 "::1",
400                                 &reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_addr);
401                             listenAddress.ss_family = AF_INET6;
402                             reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_port = 0;
403                     
404                             addressLength = sizeof(struct sockaddr_in6);
405                     
406                             if (::bind(
407                                 ip6Socket,
408                                 reinterpret_cast<struct sockaddr*>(&listenAddress),
409 carson.hovey   1.64             addressLength) < 0)
410                             {
411                                 Socket::close(ip6Socket);
412                                 return false;
413                             }
414                     #endif  // PEGASUS_OS_VMS
415                     
416 venkat.puvvada 1.56         Socket::close(ip6Socket);
417                         }
418                     
419                         return true;
420                     }
421                     #endif
422                     
423 r.kieninger    1.21 // ------------------------------------------------------------------------
424                     // Convert a hostname into a a single host unique integer representation
425                     // ------------------------------------------------------------------------
426 marek          1.63 Boolean System::acquireIP(const char* hostname, int *af, void *dst)
427 dave.sudlik    1.52 {
428                     #ifdef PEGASUS_ENABLE_IPV6
429                         String ipAddress;
430                         if(getHostIP(hostname, af, ipAddress))
431 dmitry.mikulin 1.59     {
432 dave.sudlik    1.52         HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
433                             return true;
434                         }
435                         return false;
436                     #else
437                         *af = AF_INET;
438 kumpf          1.44     Uint32 ip = 0xFFFFFFFF;
439 marek          1.65     if (!hostname)
440                         { 
441                             *af = 0xFFFFFFFF;
442                             return false;
443                         }
444 r.kieninger    1.21 
445 dave.sudlik    1.22 ////////////////////////////////////////////////////////////////////////////////
446                     // This code used to check if the first character of "hostname" was alphabetic
447 kumpf          1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
448                     // relaxed this requirement to alphabetic character *or* digit. So bug 1462
449                     // changed the flow here to call inet_addr first to check for a valid IP
450                     // address in dotted decimal notation. If it's not a valid IP address, then
451                     // try to validate it as a hostname.
452                     // RFC 1123 states: The host SHOULD check the string syntactically for a
453                     // dotted-decimal number before looking it up in the Domain Name System.
454 dave.sudlik    1.22 // Hence the call to inet_addr() first.
455                     ////////////////////////////////////////////////////////////////////////////////
456                     
457 kumpf          1.44     Uint32 tmp_addr = inet_addr((char *) hostname);
458 kumpf          1.36     struct hostent* hostEntry;
459 r.kieninger    1.21 
460 dave.sudlik    1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
461                     //       A better solution would be to use inet_aton() or equivalent, as
462                     //       inet_addr() is now considered "obsolete".
463                     
464                         if (tmp_addr == 0xFFFFFFFF)  // if hostname is not an IP address
465 kumpf          1.36     {
466                             char hostEntryBuffer[8192];
467                             struct hostent hostEntryStruct;
468 dmitry.mikulin 1.59         hostEntry = getHostByName(hostname, &hostEntryStruct, 
469                                 hostEntryBuffer, sizeof (hostEntryBuffer));
470 kumpf          1.36 
471                             if (!hostEntry)
472 kumpf          1.44         {
473 dave.sudlik    1.52             // error, couldn't resolve the ip
474                                 memcpy(dst, &ip, sizeof (Uint32));
475                                 return false;
476 kumpf          1.44         }
477                             unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
478                     
479                             ip_part1 = hostEntry->h_addr[0];
480                             ip_part2 = hostEntry->h_addr[1];
481                             ip_part3 = hostEntry->h_addr[2];
482                             ip_part4 = hostEntry->h_addr[3];
483                             ip = ip_part1;
484                             ip = (ip << 8) + ip_part2;
485                             ip = (ip << 8) + ip_part3;
486                             ip = (ip << 8) + ip_part4;
487                         }
488 dave.sudlik    1.22     else    // else hostname *is* a dotted-decimal IP address
489 kumpf          1.44     {
490                             // resolve hostaddr to a real host entry
491                             // casting to (const char *) as (char *) will work as (void *) too,
492                             // those it fits all platforms
493 ms.aruran      1.45         char hostEntryBuffer[8192];
494                             struct hostent hostEntryStruct;
495 dmitry.mikulin 1.59         hostEntry = 
496                                 getHostByAddr((const char*) &tmp_addr, sizeof(tmp_addr), AF_INET, 
497                                     &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
498 ms.aruran      1.45 
499 kumpf          1.44         if (hostEntry == 0)
500                             {
501                                 // error, couldn't resolve the ip
502 dave.sudlik    1.52             memcpy(dst, &ip, sizeof (Uint32));
503                                 return false;
504 kumpf          1.44         }
505                             else
506                             {
507                                 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
508 r.kieninger    1.21 
509 kumpf          1.44             ip_part1 = hostEntry->h_addr[0];
510                                 ip_part2 = hostEntry->h_addr[1];
511                                 ip_part3 = hostEntry->h_addr[2];
512                                 ip_part4 = hostEntry->h_addr[3];
513                                 ip = ip_part1;
514                                 ip = (ip << 8) + ip_part2;
515                                 ip = (ip << 8) + ip_part3;
516                                 ip = (ip << 8) + ip_part4;
517                             }
518                         }
519 dave.sudlik    1.52     memcpy(dst, &ip, sizeof (Uint32));
520 carolann.graves 1.29 
521                          return true;
522 dave.sudlik     1.52 #endif
523 carolann.graves 1.29 }
524                      
525 kumpf           1.44 Boolean System::resolveHostNameAtDNS(
526                          const char* hostname,
527                          Uint32* resolvedNameIP)
528 marek           1.43 {
529 dmitry.mikulin  1.59     struct hostent* hostEntry;
530                      
531 marek           1.43     // ask the DNS for hostname resolution to IP address
532                          // this can mean a time delay for as long as the DNS
533 kumpf           1.44     // takes to answer
534                          char hostEntryBuffer[8192];
535                          struct hostent hostEntryStruct;
536 dmitry.mikulin  1.59     hostEntry = getHostByName(hostname, &hostEntryStruct, 
537                              hostEntryBuffer, sizeof (hostEntryBuffer));
538 marek           1.43 
539                          if (hostEntry == 0)
540                          {
541                              // error, couldn't resolve the hostname to an ip address
542                              return false;
543 kumpf           1.44     }
544                          else
545 marek           1.43     {
546                              unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
547                              ip_part1 = hostEntry->h_addr[0];
548                              ip_part2 = hostEntry->h_addr[1];
549                              ip_part3 = hostEntry->h_addr[2];
550                              ip_part4 = hostEntry->h_addr[3];
551                              *resolvedNameIP = ip_part1;
552                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
553                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
554                              *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
555                          }
556                          return true;
557                      }
558                      
559                      Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
560                      {
561 kumpf           1.44     struct hostent *entry;
562 marek           1.43 
563 dmitry.mikulin  1.59     entry = getHostByAddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
564 ouyang.jian     1.51     
565 kumpf           1.44     if (entry == 0)
566                          {
567                              // error, couldn't resolve the ip
568                              return false;
569                          }
570                          else
571                          {
572                              unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
573                              ip_part1 = entry->h_addr[0];
574                              ip_part2 = entry->h_addr[1];
575                              ip_part3 = entry->h_addr[2];
576                              ip_part4 = entry->h_addr[3];
577                              *resolvedIP = ip_part1;
578                              *resolvedIP = (*resolvedIP << 8) + ip_part2;
579                              *resolvedIP = (*resolvedIP << 8) + ip_part3;
580                              *resolvedIP = (*resolvedIP << 8) + ip_part4;
581                          }
582                          return true;
583 marek           1.43 }
584                      
585                      
586 dave.sudlik     1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
587                      {
588                      #ifdef PEGASUS_ENABLE_IPV6
589                          struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
590                      #endif
591                          Uint32 ip4 = PEGASUS_IPV4_LOOPBACK_INIT;
592                          switch (af)
593                          {
594                      #ifdef PEGASUS_ENABLE_IPV6
595                              case AF_INET6:
596                                  return !memcmp(&ip6, binIPAddress, sizeof (ip6));
597                      #endif
598                              case AF_INET:
599                                  Uint32 n = ntohl( *(Uint32*)binIPAddress);
600                                  return !memcmp(&ip4, &n, sizeof (ip4));       
601                          }
602                      
603                          return false;
604                      }
605                      
606 marek           1.43 Boolean System::isLocalHost(const String &hostName)
607                      {
608 dave.sudlik     1.52 // Get all ip addresses on the node and compare them with the given hostname.
609                      #ifdef PEGASUS_ENABLE_IPV6
610                          CString csName = hostName.getCString();
611 dave.sudlik     1.53     struct addrinfo hints, *res1, *res2, *res1root, *res2root;
612 dave.sudlik     1.52     char localHostName[PEGASUS_MAXHOSTNAMELEN];
613                          gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
614                          Boolean isLocal = false;
615                      
616                          memset(&hints, 0, sizeof(hints));
617                          hints.ai_family = AF_INET;
618                          hints.ai_socktype = SOCK_STREAM;
619                          hints.ai_protocol = IPPROTO_TCP;
620 dave.sudlik     1.53     res1root = res2root = 0;
621 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
622                          getAddrInfo(localHostName, 0, &hints, &res2root);
623 dave.sudlik     1.52 
624 dave.sudlik     1.53     res1 = res1root;
625 dave.sudlik     1.52     while (res1 && !isLocal)
626                          {
627                              if (isLoopBack(AF_INET,
628 kumpf           1.54             &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
629 dave.sudlik     1.52         {
630                                  isLocal = true;
631                                  break;
632                              }
633                      
634 dave.sudlik     1.53         res2 = res2root;
635                              while (res2) 
636 dave.sudlik     1.52         {
637 kumpf           1.54             if (!memcmp(
638                                          &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
639                                              sin_addr,
640                                          &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
641                                              sin_addr,
642                                          sizeof (struct in_addr)))
643 dave.sudlik     1.52             {
644                                      isLocal = true;
645                                      break;
646                                  }
647 dave.sudlik     1.53             res2 = res2->ai_next;
648 dave.sudlik     1.52         }
649                              res1 = res1->ai_next;
650                          }   
651 kumpf           1.62     if (res1root)
652                          {
653                              freeaddrinfo(res1root);
654                          }
655                          if (res2root)
656                          {
657                              freeaddrinfo(res2root);
658                          }
659 dave.sudlik     1.52     if (isLocal)
660                          {
661                              return true;
662                          } 
663                      
664                          hints.ai_family = AF_INET6;
665 dave.sudlik     1.53     res1root = res2root = 0;
666 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
667                          getAddrInfo(localHostName, 0, &hints, &res2root);
668 dave.sudlik     1.53 
669                          res1 = res1root;
670 dave.sudlik     1.52     while (res1 && !isLocal)
671                          {
672 kumpf           1.54         if (isLoopBack(
673                                      AF_INET6,
674                                      &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
675                                          sin6_addr))
676 dave.sudlik     1.52         {
677                                  isLocal = true;
678                                  break;
679                              }
680                      
681 dave.sudlik     1.53         res2 = res2root;
682                              while (res2)
683 dave.sudlik     1.52         {
684 kumpf           1.54             if (!memcmp(
685                                          &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
686                                              sin6_addr,
687                                          &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
688                                              sin6_addr,
689                                          sizeof (struct in6_addr)))
690 dave.sudlik     1.52             {
691                                      isLocal = true;
692                                      break;
693                                  }
694 dave.sudlik     1.53             res2 = res2->ai_next;
695 dave.sudlik     1.52         }
696                              res1 = res1->ai_next;
697                          }
698 kumpf           1.62     if (res1root)
699                          {
700                              freeaddrinfo(res1root);
701                          }
702                          if (res2root)
703                          {
704                              freeaddrinfo(res2root);
705                          }
706 dave.sudlik     1.52     return isLocal;
707                      #else
708                      
709 marek           1.43     // differentiate between a dotted IP address given
710                          // and a real hostname given
711                          CString csName = hostName.getCString();
712 marek           1.46     char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
713                          strcpy(cc_hostname, (const char*) csName);
714 marek           1.43     Uint32 tmp_addr = 0xFFFFFFFF;
715                          Boolean hostNameIsIPNotation;
716                      
717                          // Note: Platforms already supporting the inet_aton()
718                          //       should define their platform here,
719                          //        as this is the superior way to work
720 kumpf           1.54 #if defined(PEGASUS_OS_LINUX) || \
721                          defined(PEGASUS_OS_AIX) || \
722 ouyang.jian     1.55     defined(PEGASUS_OS_HPUX) || \
723 carson.hovey    1.60     defined(PEGASUS_OS_PASE) || \
724                          defined(PEGASUS_OS_VMS)
725 kumpf           1.44 
726 marek           1.43     struct in_addr inaddr;
727                          // if inet_aton failed(return=0),
728                          // we do not have a valip IP address (x.x.x.x)
729                          int atonSuccess = inet_aton(cc_hostname, &inaddr);
730                          if (atonSuccess == 0) hostNameIsIPNotation = false;
731                          else
732                          {
733                              hostNameIsIPNotation = true;
734                              tmp_addr = inaddr.s_addr;
735                          }
736                      #else
737                          // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
738                          //       A better solution would be to use inet_aton() or equivalent, as
739                          //       inet_addr() is now considered "obsolete".
740                          // Note: inet_aton() not yet supported on all Pegasus platforms
741 kumpf           1.44     tmp_addr = inet_addr((char *) cc_hostname);
742 marek           1.43     if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
743                          else hostNameIsIPNotation = true;
744                      #endif
745 kumpf           1.44 
746 marek           1.43     if (!hostNameIsIPNotation)  // if hostname is not an IP address
747 kumpf           1.44     {
748 marek           1.43         // localhost ?
749                              if (String::equalNoCase(hostName,String("localhost"))) return true;
750 marek           1.46         char localHostName[PEGASUS_MAXHOSTNAMELEN];
751 marek           1.47         CString cstringLocalHostName = System::getHostName().getCString();
752 marek           1.46         strcpy(localHostName, (const char*) cstringLocalHostName); 
753 marek           1.43         // given hostname equals what system returns as local hostname ?
754                              if (String::equalNoCase(hostName,localHostName)) return true;
755                              Uint32 hostIP;
756                              // bail out if hostname unresolveable
757                              if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
758                              // lets see if the IP is defined on one of the network interfaces
759                              // this can help us avoid another call to DNS
760                              if (System::isIpOnNetworkInterface(hostIP)) return true;
761                              // need to check if the local hosts name is possibly
762                              // registered at the DNS with the IP address equal resolvedNameIP
763                              Uint32 localHostIP;
764 kumpf           1.44         if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
765                                  return false;
766 marek           1.43         if (localHostIP == hostIP) return true;
767 kumpf           1.44     }
768                          else
769 marek           1.43     {   // hostname is an IP address
770                              // 127.0.0.1 is always the loopback
771                              // inet_addr returns network byte order
772                              if (tmp_addr == htonl(0x7F000001)) return true;
773                              // IP defined on a local AF_INET network interface
774                              if (System::isIpOnNetworkInterface(tmp_addr)) return true;
775                              // out of luck so far, lets ask the DNS what our IP is
776                              // and check against what we got
777                              Uint32 localHostIP;
778 kumpf           1.44         if (!System::resolveHostNameAtDNS(
779                                      (const char*) System::getHostName().getCString(), &localHostIP))
780                                  return false;
781 marek           1.43         if (localHostIP == tmp_addr) return true;
782                              // not yet, sometimes resolving the IP address we got against the DNS
783                              // can solve the problem
784 kumpf           1.44         // casting to (const char *) as (char *) will work as (void *) too,
785                              // those it fits all platforms
786 marek           1.43         Uint32 hostIP;
787                              if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
788                              if (hostIP == localHostIP) return true;
789                          }
790                          return false;
791 dave.sudlik     1.52 #endif
792 marek           1.43 }
793                      
794 dmitry.mikulin  1.59 struct hostent* System::getHostByName(
795                          const char* name, 
796                          struct hostent* he, 
797                          char* buf, 
798                          size_t len)
799                      {
800                          int hostEntryErrno = 0;
801                          struct hostent* hostEntry = 0;
802                          unsigned int maxTries = 5;
803                      
804                          do
805                          {
806                      #if defined(PEGASUS_OS_LINUX)
807                              gethostbyname_r(name, 
808                                  he, 
809                                  buf, 
810                                  len, 
811                                  &hostEntry, 
812                                  &hostEntryErrno);
813                      #elif defined(PEGASUS_OS_SOLARIS)
814                              hostEntry = gethostbyname_r((char *)name, 
815 dmitry.mikulin  1.59                         he, 
816                                              buf, 
817                                              len, 
818                                              &hostEntryErrno);
819                      #elif defined(PEGASUS_OS_ZOS)
820                              char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
821                              if (String::equalNoCase("localhost", String(name)))
822                              {
823                                  gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
824                                  hostName[sizeof(hostName) - 1] = 0;
825                                  hostEntry = gethostbyname(hostName);
826                              }
827                              else
828                              {
829                                  hostEntry = gethostbyname((char *)name);
830                              }
831                              hostEntryErrno = h_errno;
832                      #else
833                              hostEntry = gethostbyname((char *)name);
834                              hostEntryErrno = h_errno;
835                      #endif
836 dmitry.mikulin  1.59     } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
837                                   maxTries-- > 0);
838                      
839                          return hostEntry;
840                      }
841                      
842                      struct hostent* System::getHostByAddr(
843                          const char *addr, 
844                          int len, 
845                          int type,
846                          struct hostent* he, 
847                          char* buf, 
848                          size_t buflen)
849                      {
850                          int hostEntryErrno = 0;
851                          struct hostent* hostEntry = 0;
852                          unsigned int maxTries = 5;
853                      
854                          do
855                          {
856                      #if defined(PEGASUS_OS_LINUX)
857 dmitry.mikulin  1.59         gethostbyaddr_r(addr, 
858                                  len, 
859                                  type, 
860                                  he, 
861                                  buf, 
862                                  buflen, 
863                                  &hostEntry, 
864                                  &hostEntryErrno);
865                      #elif defined(PEGASUS_OS_SOLARIS)
866                              char hostEntryBuffer[8192];
867                              struct hostent hostEntryStruct;
868                      
869                              hostEntry = gethostbyaddr_r(addr, 
870                                              len, 
871                                              type, 
872                                              he, 
873                                              buf, 
874                                              buflen, 
875                                              &hostEntryErrno);
876                      #else
877                              hostEntry = gethostbyaddr(addr, 
878 dmitry.mikulin  1.59                         len, 
879                                              type);
880                              hostEntryErrno = h_errno;
881                      #endif
882                          } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
883                                   maxTries-- > 0);
884                      
885                          return hostEntry;
886                      }
887                      
888 dmitry.mikulin  1.61 #if defined(PEGASUS_OS_ZOS) || \
889                          defined(PEGASUS_OS_VMS) || \
890                          defined(PEGASUS_ENABLE_IPV6)
891                      
892 dmitry.mikulin  1.59 int System::getAddrInfo(
893                          const char *hostname, 
894                          const char *servname,
895                          const struct addrinfo *hints, 
896                          struct addrinfo **res)
897                      {
898                          int rc = 0;
899                          unsigned int maxTries = 5; 
900                      
901 ouyang.jian     1.67 #ifdef PEGASUS_OS_PASE
902                          CString hostNameCString;
903                          if (String::equalNoCase(hostname, "localhost"))
904                          {
905                              hostNameCString = getHostName().getCString();
906                              hostname = (const char*)hostNameCString;
907                          }
908                      #endif
909                      
910 dmitry.mikulin  1.59     while ((rc = getaddrinfo(hostname, 
911                                           servname, 
912                                           hints, 
913                                           res)) == EAI_AGAIN &&
914                                 maxTries-- > 0)
915                              ;
916                          return rc;
917                      }
918                      
919                      int System::getNameInfo(
920                          const struct sockaddr *sa, 
921                          size_t salen,
922                          char *host, 
923                          size_t hostlen, 
924                          char *serv, 
925                          size_t servlen, 
926                          int flags)
927                      {
928                          int rc = 0;
929                          unsigned int maxTries = 5; 
930                      
931 dmitry.mikulin  1.59     while ((rc = getnameinfo(sa, 
932                                           salen, 
933                                           host, 
934                                           hostlen, 
935                                           serv, 
936                                           servlen, 
937                                           flags)) == EAI_AGAIN &&
938                                 maxTries-- > 0)
939                              ;
940                          return rc;
941                      }
942                      
943 dmitry.mikulin  1.61 #endif
944 dmitry.mikulin  1.59 
945 tony            1.17 // System ID constants for Logger::put and Logger::trace
946                      const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
947                      
948 mike            1.8  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2