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