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

  1 martin 1.71 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.72 //
  3 martin 1.71 // Licensed to The Open Group (TOG) under one or more contributor license
  4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5             // this work for additional information regarding copyright ownership.
  6             // Each contributor licenses this file to you under the OpenPegasus Open
  7             // Source License; you may not use this file except in compliance with the
  8             // License.
  9 martin 1.72 //
 10 martin 1.71 // Permission is hereby granted, free of charge, to any person obtaining a
 11             // copy of this software and associated documentation files (the "Software"),
 12             // to deal in the Software without restriction, including without limitation
 13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14             // and/or sell copies of the Software, and to permit persons to whom the
 15             // Software is furnished to do so, subject to the following conditions:
 16 martin 1.72 //
 17 martin 1.71 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.72 //
 20 martin 1.71 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.72 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.71 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 martin 1.72 //
 28 martin 1.71 //////////////////////////////////////////////////////////////////////////
 29 mike   1.6  //
 30             //%/////////////////////////////////////////////////////////////////////////////
 31 mike   1.8  
 32 r.kieninger 1.21 #include <Pegasus/Common/Config.h>
 33 sage        1.12 
 34 mike        1.8  #include <fstream>
 35 kumpf       1.13 #include <cctype>  // for tolower()
 36 kumpf       1.14 #include <cstring>
 37 mike        1.6  #include "System.h"
 38 r.kieninger 1.21 #include "Socket.h"
 39 mike        1.39 #include "Network.h"
 40 kumpf       1.10 #include <Pegasus/Common/PegasusVersion.h>
 41 mateus.baur 1.50 #include <Pegasus/Common/FileSystem.h>
 42 dave.sudlik 1.52 #include <Pegasus/Common/HostAddress.h>
 43                  #include <Pegasus/Common/Array.h>
 44 kumpf       1.10 
 45 mike        1.6  #if defined(PEGASUS_OS_TYPE_WINDOWS)
 46                  # include "SystemWindows.cpp"
 47 john.eisenbraun 1.74 #elif defined(PEGASUS_OS_TYPE_UNIX)
 48 mike            1.40 # include "SystemPOSIX.cpp"
 49 john.eisenbraun 1.74 # include "SystemUnix.cpp"
 50                      #elif defined(PEGASUS_OS_VMS)
 51                      # include "SystemPOSIX.cpp"
 52                      # include "SystemVms.cpp"
 53 mike            1.6  #else
 54                      # error "Unsupported platform"
 55                      #endif
 56 mike            1.8  
 57                      PEGASUS_USING_STD;
 58                      
 59                      PEGASUS_NAMESPACE_BEGIN
 60                      
 61 kumpf           1.20 Boolean System::bindVerbose = false;
 62                      
 63 mike            1.8  Boolean System::copyFile(const char* fromPath, const char* toPath)
 64                      {
 65 ramnath         1.9      ifstream is(fromPath PEGASUS_IOS_BINARY);
 66 mateus.baur     1.50     fstream os(toPath, ios::out  PEGASUS_OR_IOS_BINARY);
 67 mike            1.8  
 68                          char c;
 69                      
 70                          while (is.get(c))
 71                          {
 72 kumpf           1.44         if (!os.put(c))
 73                                  return false;
 74 mike            1.8      }
 75                      
 76 mateus.baur     1.50     FileSystem::syncWithDirectoryUpdates(os);
 77 kumpf           1.42     return is.eof();
 78 kumpf           1.13 }
 79                      
 80 kumpf           1.44 static const Uint8 _toLowerTable[256] =
 81 mike            1.32 {
 82                          0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
 83                          0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
 84                          0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
 85                          0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
 86                          0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
 87                          0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
 88                          0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
 89                          0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
 90                          0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
 91                          0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
 92                          0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
 93                          0x78,0x79,0x7A,0x5B,0x5C,0x5D,0x5E,0x5F,
 94                          0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
 95                          0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
 96                          0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
 97                          0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
 98                          0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
 99                          0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
100                          0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
101                          0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
102 mike            1.32     0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
103                          0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
104                          0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
105                          0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
106                          0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
107                          0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
108                          0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
109                          0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
110                          0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
111                          0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
112                          0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
113                          0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
114                      };
115                      
116 kumpf           1.13 Sint32 System::strcasecmp(const char* s1, const char* s2)
117                      {
118 mike            1.32     // Note: this is faster than glibc strcasecmp().
119                      
120                          Uint8* p = (Uint8*)s1;
121                          Uint8* q = (Uint8*)s2;
122                          int r;
123                      
124                          for (;;)
125 kumpf           1.13     {
126 kumpf           1.44         if ((r = _toLowerTable[p[0]] - _toLowerTable[q[0]]) || !p[0] ||
127                                  (r = _toLowerTable[p[1]] - _toLowerTable[q[1]]) || !p[1] ||
128                                  (r = _toLowerTable[p[2]] - _toLowerTable[q[2]]) || !p[2] ||
129                                  (r = _toLowerTable[p[3]] - _toLowerTable[q[3]]) || !p[3])
130                                  break;
131 kumpf           1.13 
132 kumpf           1.44         p += 4;
133                              q += 4;
134 kumpf           1.13     }
135                      
136 mike            1.32     return r;
137 mike            1.8  }
138                      
139 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 kumpf           1.73     hints.ai_protocol = IPPROTO_TCP;
318 dave.sudlik     1.52     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 kumpf           1.73         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 kumpf           1.73     // Check for valid IPV6 Address.
332 dave.sudlik     1.52     *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 kumpf           1.73     hostEntry = getHostByName(hostNamePtr, &hostEntryStruct,
360 dmitry.mikulin  1.59         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 kumpf           1.73     {
441 marek           1.65         *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 kumpf           1.73         hostEntry = getHostByName(hostname, &hostEntryStruct,
469 dmitry.mikulin  1.59             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 kumpf           1.73         hostEntry =
496                                  getHostByAddr((const char*) &tmp_addr, sizeof(tmp_addr), AF_INET,
497 dmitry.mikulin  1.59                 &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 kumpf           1.73     hostEntry = getHostByName(hostname, &hostEntryStruct,
537 dmitry.mikulin  1.59         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 kumpf           1.73 
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                          switch (af)
592                          {
593                      #ifdef PEGASUS_ENABLE_IPV6
594                              case AF_INET6:
595                                  return !memcmp(&ip6, binIPAddress, sizeof (ip6));
596                      #endif
597                              case AF_INET:
598 karl            1.69         {
599                                  Uint32 tmp;
600                                  memcpy(&tmp, binIPAddress, sizeof(Uint32));
601                                  Uint32 n = ntohl(tmp);
602 venkat.puvvada  1.75             return n >= PEGASUS_IPV4_LOOPBACK_RANGE_START && 
603                                      n <= PEGASUS_IPV4_LOOPBACK_RANGE_END;
604 karl            1.69         }
605 dave.sudlik     1.52     }
606                      
607                          return false;
608                      }
609                      
610 marek           1.43 Boolean System::isLocalHost(const String &hostName)
611                      {
612 dave.sudlik     1.52 // Get all ip addresses on the node and compare them with the given hostname.
613                      #ifdef PEGASUS_ENABLE_IPV6
614                          CString csName = hostName.getCString();
615 dave.sudlik     1.53     struct addrinfo hints, *res1, *res2, *res1root, *res2root;
616 dave.sudlik     1.52     char localHostName[PEGASUS_MAXHOSTNAMELEN];
617                          gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
618                          Boolean isLocal = false;
619                      
620                          memset(&hints, 0, sizeof(hints));
621                          hints.ai_family = AF_INET;
622                          hints.ai_socktype = SOCK_STREAM;
623                          hints.ai_protocol = IPPROTO_TCP;
624 dave.sudlik     1.53     res1root = res2root = 0;
625 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
626                          getAddrInfo(localHostName, 0, &hints, &res2root);
627 dave.sudlik     1.52 
628 dave.sudlik     1.53     res1 = res1root;
629 dave.sudlik     1.52     while (res1 && !isLocal)
630                          {
631                              if (isLoopBack(AF_INET,
632 kumpf           1.54             &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
633 dave.sudlik     1.52         {
634                                  isLocal = true;
635                                  break;
636                              }
637                      
638 dave.sudlik     1.53         res2 = res2root;
639 kumpf           1.73         while (res2)
640 dave.sudlik     1.52         {
641 kumpf           1.54             if (!memcmp(
642                                          &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
643                                              sin_addr,
644                                          &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
645                                              sin_addr,
646                                          sizeof (struct in_addr)))
647 dave.sudlik     1.52             {
648                                      isLocal = true;
649                                      break;
650                                  }
651 dave.sudlik     1.53             res2 = res2->ai_next;
652 dave.sudlik     1.52         }
653                              res1 = res1->ai_next;
654 kumpf           1.73     }
655 kumpf           1.62     if (res1root)
656                          {
657                              freeaddrinfo(res1root);
658                          }
659                          if (res2root)
660                          {
661                              freeaddrinfo(res2root);
662                          }
663 dave.sudlik     1.52     if (isLocal)
664                          {
665                              return true;
666 kumpf           1.73     }
667 dave.sudlik     1.52 
668                          hints.ai_family = AF_INET6;
669 dave.sudlik     1.53     res1root = res2root = 0;
670 dmitry.mikulin  1.59     getAddrInfo(csName, 0, &hints, &res1root);
671                          getAddrInfo(localHostName, 0, &hints, &res2root);
672 dave.sudlik     1.53 
673                          res1 = res1root;
674 dave.sudlik     1.52     while (res1 && !isLocal)
675                          {
676 kumpf           1.54         if (isLoopBack(
677                                      AF_INET6,
678                                      &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
679                                          sin6_addr))
680 dave.sudlik     1.52         {
681                                  isLocal = true;
682                                  break;
683                              }
684                      
685 dave.sudlik     1.53         res2 = res2root;
686                              while (res2)
687 dave.sudlik     1.52         {
688 kumpf           1.54             if (!memcmp(
689                                          &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
690                                              sin6_addr,
691                                          &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
692                                              sin6_addr,
693                                          sizeof (struct in6_addr)))
694 dave.sudlik     1.52             {
695                                      isLocal = true;
696                                      break;
697                                  }
698 dave.sudlik     1.53             res2 = res2->ai_next;
699 dave.sudlik     1.52         }
700                              res1 = res1->ai_next;
701                          }
702 kumpf           1.62     if (res1root)
703                          {
704                              freeaddrinfo(res1root);
705                          }
706                          if (res2root)
707                          {
708                              freeaddrinfo(res2root);
709                          }
710 dave.sudlik     1.52     return isLocal;
711                      #else
712                      
713 marek           1.43     // differentiate between a dotted IP address given
714                          // and a real hostname given
715                          CString csName = hostName.getCString();
716 marek           1.46     char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
717                          strcpy(cc_hostname, (const char*) csName);
718 marek           1.43     Uint32 tmp_addr = 0xFFFFFFFF;
719                          Boolean hostNameIsIPNotation;
720                      
721                          // Note: Platforms already supporting the inet_aton()
722                          //       should define their platform here,
723                          //        as this is the superior way to work
724 kumpf           1.54 #if defined(PEGASUS_OS_LINUX) || \
725                          defined(PEGASUS_OS_AIX) || \
726 ouyang.jian     1.55     defined(PEGASUS_OS_HPUX) || \
727 carson.hovey    1.60     defined(PEGASUS_OS_PASE) || \
728                          defined(PEGASUS_OS_VMS)
729 kumpf           1.44 
730 marek           1.43     struct in_addr inaddr;
731                          // if inet_aton failed(return=0),
732                          // we do not have a valip IP address (x.x.x.x)
733                          int atonSuccess = inet_aton(cc_hostname, &inaddr);
734                          if (atonSuccess == 0) hostNameIsIPNotation = false;
735                          else
736                          {
737                              hostNameIsIPNotation = true;
738                              tmp_addr = inaddr.s_addr;
739                          }
740                      #else
741                          // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
742                          //       A better solution would be to use inet_aton() or equivalent, as
743                          //       inet_addr() is now considered "obsolete".
744                          // Note: inet_aton() not yet supported on all Pegasus platforms
745 kumpf           1.44     tmp_addr = inet_addr((char *) cc_hostname);
746 marek           1.43     if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
747                          else hostNameIsIPNotation = true;
748                      #endif
749 kumpf           1.44 
750 marek           1.43     if (!hostNameIsIPNotation)  // if hostname is not an IP address
751 kumpf           1.44     {
752 marek           1.43         // localhost ?
753                              if (String::equalNoCase(hostName,String("localhost"))) return true;
754 marek           1.46         char localHostName[PEGASUS_MAXHOSTNAMELEN];
755 marek           1.47         CString cstringLocalHostName = System::getHostName().getCString();
756 kumpf           1.73         strcpy(localHostName, (const char*) cstringLocalHostName);
757 marek           1.43         // given hostname equals what system returns as local hostname ?
758                              if (String::equalNoCase(hostName,localHostName)) return true;
759                              Uint32 hostIP;
760                              // bail out if hostname unresolveable
761                              if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
762                              // lets see if the IP is defined on one of the network interfaces
763                              // this can help us avoid another call to DNS
764                              if (System::isIpOnNetworkInterface(hostIP)) return true;
765                              // need to check if the local hosts name is possibly
766                              // registered at the DNS with the IP address equal resolvedNameIP
767                              Uint32 localHostIP;
768 kumpf           1.44         if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
769                                  return false;
770 marek           1.43         if (localHostIP == hostIP) return true;
771 kumpf           1.44     }
772                          else
773 marek           1.43     {   // hostname is an IP address
774                              // 127.0.0.1 is always the loopback
775                              // inet_addr returns network byte order
776                              if (tmp_addr == htonl(0x7F000001)) return true;
777                              // IP defined on a local AF_INET network interface
778                              if (System::isIpOnNetworkInterface(tmp_addr)) return true;
779                              // out of luck so far, lets ask the DNS what our IP is
780                              // and check against what we got
781                              Uint32 localHostIP;
782 kumpf           1.44         if (!System::resolveHostNameAtDNS(
783                                      (const char*) System::getHostName().getCString(), &localHostIP))
784                                  return false;
785 marek           1.43         if (localHostIP == tmp_addr) return true;
786                              // not yet, sometimes resolving the IP address we got against the DNS
787                              // can solve the problem
788 kumpf           1.44         // casting to (const char *) as (char *) will work as (void *) too,
789                              // those it fits all platforms
790 marek           1.43         Uint32 hostIP;
791                              if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
792                              if (hostIP == localHostIP) return true;
793                          }
794                          return false;
795 dave.sudlik     1.52 #endif
796 marek           1.43 }
797                      
798 dmitry.mikulin  1.59 struct hostent* System::getHostByName(
799 kumpf           1.73     const char* name,
800                          struct hostent* he,
801                          char* buf,
802 dmitry.mikulin  1.59     size_t len)
803                      {
804                          int hostEntryErrno = 0;
805                          struct hostent* hostEntry = 0;
806                          unsigned int maxTries = 5;
807                      
808                          do
809                          {
810                      #if defined(PEGASUS_OS_LINUX)
811 kumpf           1.73         gethostbyname_r(name,
812                                  he,
813                                  buf,
814                                  len,
815                                  &hostEntry,
816 dmitry.mikulin  1.59             &hostEntryErrno);
817                      #elif defined(PEGASUS_OS_SOLARIS)
818 kumpf           1.73         hostEntry = gethostbyname_r((char *)name,
819                                              he,
820                                              buf,
821                                              len,
822 dmitry.mikulin  1.59                         &hostEntryErrno);
823                      #elif defined(PEGASUS_OS_ZOS)
824                              char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
825                              if (String::equalNoCase("localhost", String(name)))
826                              {
827                                  gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
828                                  hostName[sizeof(hostName) - 1] = 0;
829                                  hostEntry = gethostbyname(hostName);
830                              }
831                              else
832                              {
833                                  hostEntry = gethostbyname((char *)name);
834                              }
835                              hostEntryErrno = h_errno;
836                      #else
837                              hostEntry = gethostbyname((char *)name);
838                              hostEntryErrno = h_errno;
839                      #endif
840                          } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
841                                   maxTries-- > 0);
842                      
843 dmitry.mikulin  1.59     return hostEntry;
844                      }
845                      
846                      struct hostent* System::getHostByAddr(
847 kumpf           1.73     const char *addr,
848                          int len,
849 dmitry.mikulin  1.59     int type,
850 kumpf           1.73     struct hostent* he,
851                          char* buf,
852 dmitry.mikulin  1.59     size_t buflen)
853                      {
854                          int hostEntryErrno = 0;
855                          struct hostent* hostEntry = 0;
856                          unsigned int maxTries = 5;
857                      
858                          do
859                          {
860                      #if defined(PEGASUS_OS_LINUX)
861 kumpf           1.73         gethostbyaddr_r(addr,
862                                  len,
863                                  type,
864                                  he,
865                                  buf,
866                                  buflen,
867                                  &hostEntry,
868 dmitry.mikulin  1.59             &hostEntryErrno);
869                      #elif defined(PEGASUS_OS_SOLARIS)
870                              char hostEntryBuffer[8192];
871                              struct hostent hostEntryStruct;
872                      
873 kumpf           1.73         hostEntry = gethostbyaddr_r(addr,
874                                              len,
875                                              type,
876                                              he,
877                                              buf,
878                                              buflen,
879 dmitry.mikulin  1.59                         &hostEntryErrno);
880                      #else
881 kumpf           1.73         hostEntry = gethostbyaddr(addr,
882                                              len,
883 dmitry.mikulin  1.59                         type);
884                              hostEntryErrno = h_errno;
885                      #endif
886                          } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
887                                   maxTries-- > 0);
888                      
889                          return hostEntry;
890                      }
891                      
892 dmitry.mikulin  1.61 #if defined(PEGASUS_OS_ZOS) || \
893                          defined(PEGASUS_OS_VMS) || \
894                          defined(PEGASUS_ENABLE_IPV6)
895                      
896 dmitry.mikulin  1.59 int System::getAddrInfo(
897 kumpf           1.73     const char *hostname,
898 dmitry.mikulin  1.59     const char *servname,
899 kumpf           1.73     const struct addrinfo *hints,
900 dmitry.mikulin  1.59     struct addrinfo **res)
901                      {
902                          int rc = 0;
903 kumpf           1.73     unsigned int maxTries = 5;
904 dmitry.mikulin  1.59 
905 ouyang.jian     1.67 #ifdef PEGASUS_OS_PASE
906                          CString hostNameCString;
907                          if (String::equalNoCase(hostname, "localhost"))
908                          {
909                              hostNameCString = getHostName().getCString();
910                              hostname = (const char*)hostNameCString;
911                          }
912                      #endif
913                      
914 kumpf           1.73     while ((rc = getaddrinfo(hostname,
915                                           servname,
916                                           hints,
917 dmitry.mikulin  1.59                      res)) == EAI_AGAIN &&
918                                 maxTries-- > 0)
919                              ;
920                          return rc;
921                      }
922                      
923                      int System::getNameInfo(
924 kumpf           1.73     const struct sockaddr *sa,
925 dmitry.mikulin  1.59     size_t salen,
926 kumpf           1.73     char *host,
927                          size_t hostlen,
928                          char *serv,
929                          size_t servlen,
930 dmitry.mikulin  1.59     int flags)
931                      {
932                          int rc = 0;
933 kumpf           1.73     unsigned int maxTries = 5;
934 dmitry.mikulin  1.59 
935 kumpf           1.73     while ((rc = getnameinfo(sa,
936                                           salen,
937                                           host,
938                                           hostlen,
939                                           serv,
940                                           servlen,
941 dmitry.mikulin  1.59                      flags)) == EAI_AGAIN &&
942                                 maxTries-- > 0)
943                              ;
944                          return rc;
945                      }
946                      
947 dmitry.mikulin  1.61 #endif
948 dmitry.mikulin  1.59 
949 tony            1.17 // System ID constants for Logger::put and Logger::trace
950                      const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
951                      
952 mike            1.8  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2