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 dave.sudlik 1.52 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
|
187 marek 1.24 {
|
188 dave.sudlik 1.52 #ifdef PEGASUS_ENABLE_IPV6
189 struct addrinfo *info, hints;
190 memset (&hints, 0, sizeof(struct addrinfo));
191
192 // Check for valid IPV4 address, if found return ipv4 address
193 *af = AF_INET;
194 hints.ai_family = *af;
195 hints.ai_protocol = IPPROTO_TCP;
196 hints.ai_socktype = SOCK_STREAM;
|
197 dmitry.mikulin 1.59 if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
|
198 dave.sudlik 1.52 {
199 char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
200 HostAddress::convertBinaryToText(info->ai_family,
|
201 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(info->ai_addr))->sin_addr,
202 ipAddress,
|
203 dave.sudlik 1.52 PEGASUS_INET_ADDRSTR_LEN);
204 hostIP = ipAddress;
205 freeaddrinfo(info);
206 return true;
207 }
208
209 // Check for valid IPV6 Address.
210 *af = AF_INET6;
211 hints.ai_family = *af;
212 hints.ai_protocol = IPPROTO_TCP;
213 hints.ai_socktype = SOCK_STREAM;
|
214 dmitry.mikulin 1.59 if (!getAddrInfo(hostName.getCString(), 0, &hints, &info))
|
215 dave.sudlik 1.52 {
216 char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
217 HostAddress::convertBinaryToText(info->ai_family,
|
218 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in6*>(info->ai_addr))->sin6_addr,
219 ipAddress,
|
220 dave.sudlik 1.52 PEGASUS_INET6_ADDRSTR_LEN);
221 hostIP = ipAddress;
222 freeaddrinfo(info);
223 return true;
224 }
225
226 return false;
227 #else
228 *af = AF_INET;
|
229 kumpf 1.36 struct hostent* hostEntry;
230 struct in_addr inaddr;
231 String ipAddress;
232 CString hostNameCString = hostName.getCString();
233 const char* hostNamePtr = hostNameCString;
234
235 char hostEntryBuffer[8192];
236 struct hostent hostEntryStruct;
|
237 dmitry.mikulin 1.59 hostEntry = getHostByName(hostNamePtr, &hostEntryStruct,
238 hostEntryBuffer, sizeof (hostEntryBuffer));
|
239 kumpf 1.36
240 if (hostEntry)
|
241 marek 1.24 {
|
242 kumpf 1.36 ::memcpy( &inaddr, hostEntry->h_addr,4);
|
243 marek 1.24 ipAddress = ::inet_ntoa( inaddr );
|
244 dmitry.mikulin 1.59 hostIP = ipAddress;
245 return true;
|
246 marek 1.24 }
|
247 dmitry.mikulin 1.59 return false;
|
248 dave.sudlik 1.52 #endif
|
249 marek 1.24 }
|
250 r.kieninger 1.21
|
251 venkat.puvvada 1.56
252 #ifdef PEGASUS_ENABLE_IPV6
253 Boolean System::isIPv6StackActive()
254 {
255 SocketHandle ip6Socket;
256 if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
257 == PEGASUS_INVALID_SOCKET)
258 {
259 if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
260 {
261 return false;
262 }
263 }
264 else
265 {
266 Socket::close(ip6Socket);
267 }
268
269 return true;
270 }
271 #endif
272 venkat.puvvada 1.56
|
273 r.kieninger 1.21 // ------------------------------------------------------------------------
274 // Convert a hostname into a a single host unique integer representation
275 // ------------------------------------------------------------------------
|
276 dave.sudlik 1.52 Boolean System::_acquireIP(const char* hostname, int *af, void *dst)
277 {
278 #ifdef PEGASUS_ENABLE_IPV6
279 String ipAddress;
280 if(getHostIP(hostname, af, ipAddress))
|
281 dmitry.mikulin 1.59 {
|
282 dave.sudlik 1.52 HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
283 return true;
284 }
285 return false;
286 #else
287 *af = AF_INET;
|
288 kumpf 1.44 Uint32 ip = 0xFFFFFFFF;
289 if (!hostname) return 0xFFFFFFFF;
|
290 r.kieninger 1.21
|
291 dave.sudlik 1.22 ////////////////////////////////////////////////////////////////////////////////
292 // This code used to check if the first character of "hostname" was alphabetic
|
293 kumpf 1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
294 // relaxed this requirement to alphabetic character *or* digit. So bug 1462
295 // changed the flow here to call inet_addr first to check for a valid IP
296 // address in dotted decimal notation. If it's not a valid IP address, then
297 // try to validate it as a hostname.
298 // RFC 1123 states: The host SHOULD check the string syntactically for a
299 // dotted-decimal number before looking it up in the Domain Name System.
|
300 dave.sudlik 1.22 // Hence the call to inet_addr() first.
301 ////////////////////////////////////////////////////////////////////////////////
302
|
303 kumpf 1.44 Uint32 tmp_addr = inet_addr((char *) hostname);
|
304 kumpf 1.36 struct hostent* hostEntry;
|
305 r.kieninger 1.21
|
306 dave.sudlik 1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
307 // A better solution would be to use inet_aton() or equivalent, as
308 // inet_addr() is now considered "obsolete".
309
310 if (tmp_addr == 0xFFFFFFFF) // if hostname is not an IP address
|
311 kumpf 1.36 {
312 char hostEntryBuffer[8192];
313 struct hostent hostEntryStruct;
|
314 dmitry.mikulin 1.59 hostEntry = getHostByName(hostname, &hostEntryStruct,
315 hostEntryBuffer, sizeof (hostEntryBuffer));
|
316 kumpf 1.36
317 if (!hostEntry)
|
318 kumpf 1.44 {
|
319 dave.sudlik 1.52 // error, couldn't resolve the ip
320 memcpy(dst, &ip, sizeof (Uint32));
321 return false;
|
322 kumpf 1.44 }
323 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
324
325 ip_part1 = hostEntry->h_addr[0];
326 ip_part2 = hostEntry->h_addr[1];
327 ip_part3 = hostEntry->h_addr[2];
328 ip_part4 = hostEntry->h_addr[3];
329 ip = ip_part1;
330 ip = (ip << 8) + ip_part2;
331 ip = (ip << 8) + ip_part3;
332 ip = (ip << 8) + ip_part4;
333 }
|
334 dave.sudlik 1.22 else // else hostname *is* a dotted-decimal IP address
|
335 kumpf 1.44 {
336 // resolve hostaddr to a real host entry
337 // casting to (const char *) as (char *) will work as (void *) too,
338 // those it fits all platforms
|
339 ms.aruran 1.45 char hostEntryBuffer[8192];
340 struct hostent hostEntryStruct;
|
341 dmitry.mikulin 1.59 hostEntry =
342 getHostByAddr((const char*) &tmp_addr, sizeof(tmp_addr), AF_INET,
343 &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
|
344 ms.aruran 1.45
|
345 kumpf 1.44 if (hostEntry == 0)
346 {
347 // error, couldn't resolve the ip
|
348 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
349 return false;
|
350 kumpf 1.44 }
351 else
352 {
353 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
|
354 r.kieninger 1.21
|
355 kumpf 1.44 ip_part1 = hostEntry->h_addr[0];
356 ip_part2 = hostEntry->h_addr[1];
357 ip_part3 = hostEntry->h_addr[2];
358 ip_part4 = hostEntry->h_addr[3];
359 ip = ip_part1;
360 ip = (ip << 8) + ip_part2;
361 ip = (ip << 8) + ip_part3;
362 ip = (ip << 8) + ip_part4;
363 }
364 }
|
365 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
|
366 carolann.graves 1.29
367 return true;
|
368 dave.sudlik 1.52 #endif
|
369 carolann.graves 1.29 }
370
|
371 kumpf 1.44 Boolean System::resolveHostNameAtDNS(
372 const char* hostname,
373 Uint32* resolvedNameIP)
|
374 marek 1.43 {
|
375 dmitry.mikulin 1.59 struct hostent* hostEntry;
376
|
377 marek 1.43 // ask the DNS for hostname resolution to IP address
378 // this can mean a time delay for as long as the DNS
|
379 kumpf 1.44 // takes to answer
380 char hostEntryBuffer[8192];
381 struct hostent hostEntryStruct;
|
382 dmitry.mikulin 1.59 hostEntry = getHostByName(hostname, &hostEntryStruct,
383 hostEntryBuffer, sizeof (hostEntryBuffer));
|
384 marek 1.43
385 if (hostEntry == 0)
386 {
387 // error, couldn't resolve the hostname to an ip address
388 return false;
|
389 kumpf 1.44 }
390 else
|
391 marek 1.43 {
392 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
393 ip_part1 = hostEntry->h_addr[0];
394 ip_part2 = hostEntry->h_addr[1];
395 ip_part3 = hostEntry->h_addr[2];
396 ip_part4 = hostEntry->h_addr[3];
397 *resolvedNameIP = ip_part1;
398 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
399 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
400 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
401 }
402 return true;
403 }
404
405 Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
406 {
|
407 kumpf 1.44 struct hostent *entry;
|
408 marek 1.43
|
409 dmitry.mikulin 1.59 entry = getHostByAddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
410 ouyang.jian 1.51
|
411 kumpf 1.44 if (entry == 0)
412 {
413 // error, couldn't resolve the ip
414 return false;
415 }
416 else
417 {
418 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
419 ip_part1 = entry->h_addr[0];
420 ip_part2 = entry->h_addr[1];
421 ip_part3 = entry->h_addr[2];
422 ip_part4 = entry->h_addr[3];
423 *resolvedIP = ip_part1;
424 *resolvedIP = (*resolvedIP << 8) + ip_part2;
425 *resolvedIP = (*resolvedIP << 8) + ip_part3;
426 *resolvedIP = (*resolvedIP << 8) + ip_part4;
427 }
428 return true;
|
429 marek 1.43 }
430
431
|
432 dave.sudlik 1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
433 {
434 #ifdef PEGASUS_ENABLE_IPV6
435 struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
436 #endif
437 Uint32 ip4 = PEGASUS_IPV4_LOOPBACK_INIT;
438 switch (af)
439 {
440 #ifdef PEGASUS_ENABLE_IPV6
441 case AF_INET6:
442 return !memcmp(&ip6, binIPAddress, sizeof (ip6));
443 #endif
444 case AF_INET:
445 Uint32 n = ntohl( *(Uint32*)binIPAddress);
446 return !memcmp(&ip4, &n, sizeof (ip4));
447 }
448
449 return false;
450 }
451
|
452 marek 1.43 Boolean System::isLocalHost(const String &hostName)
453 {
|
454 dave.sudlik 1.52 // Get all ip addresses on the node and compare them with the given hostname.
455 #ifdef PEGASUS_ENABLE_IPV6
456 CString csName = hostName.getCString();
|
457 dave.sudlik 1.53 struct addrinfo hints, *res1, *res2, *res1root, *res2root;
|
458 dave.sudlik 1.52 char localHostName[PEGASUS_MAXHOSTNAMELEN];
459 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
460 Boolean isLocal = false;
461
462 memset(&hints, 0, sizeof(hints));
463 hints.ai_family = AF_INET;
464 hints.ai_socktype = SOCK_STREAM;
465 hints.ai_protocol = IPPROTO_TCP;
|
466 dave.sudlik 1.53 res1root = res2root = 0;
|
467 dmitry.mikulin 1.59 getAddrInfo(csName, 0, &hints, &res1root);
468 getAddrInfo(localHostName, 0, &hints, &res2root);
|
469 dave.sudlik 1.52
|
470 dave.sudlik 1.53 res1 = res1root;
|
471 dave.sudlik 1.52 while (res1 && !isLocal)
472 {
473 if (isLoopBack(AF_INET,
|
474 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
|
475 dave.sudlik 1.52 {
476 isLocal = true;
477 break;
478 }
479
|
480 dave.sudlik 1.53 res2 = res2root;
481 while (res2)
|
482 dave.sudlik 1.52 {
|
483 kumpf 1.54 if (!memcmp(
484 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
485 sin_addr,
486 &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
487 sin_addr,
488 sizeof (struct in_addr)))
|
489 dave.sudlik 1.52 {
490 isLocal = true;
491 break;
492 }
|
493 dave.sudlik 1.53 res2 = res2->ai_next;
|
494 dave.sudlik 1.52 }
495 res1 = res1->ai_next;
496 }
|
497 kumpf 1.62 if (res1root)
498 {
499 freeaddrinfo(res1root);
500 }
501 if (res2root)
502 {
503 freeaddrinfo(res2root);
504 }
|
505 dave.sudlik 1.52 if (isLocal)
506 {
507 return true;
508 }
509
510 hints.ai_family = AF_INET6;
|
511 dave.sudlik 1.53 res1root = res2root = 0;
|
512 dmitry.mikulin 1.59 getAddrInfo(csName, 0, &hints, &res1root);
513 getAddrInfo(localHostName, 0, &hints, &res2root);
|
514 dave.sudlik 1.53
515 res1 = res1root;
|
516 dave.sudlik 1.52 while (res1 && !isLocal)
517 {
|
518 kumpf 1.54 if (isLoopBack(
519 AF_INET6,
520 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
521 sin6_addr))
|
522 dave.sudlik 1.52 {
523 isLocal = true;
524 break;
525 }
526
|
527 dave.sudlik 1.53 res2 = res2root;
528 while (res2)
|
529 dave.sudlik 1.52 {
|
530 kumpf 1.54 if (!memcmp(
531 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
532 sin6_addr,
533 &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
534 sin6_addr,
535 sizeof (struct in6_addr)))
|
536 dave.sudlik 1.52 {
537 isLocal = true;
538 break;
539 }
|
540 dave.sudlik 1.53 res2 = res2->ai_next;
|
541 dave.sudlik 1.52 }
542 res1 = res1->ai_next;
543 }
|
544 kumpf 1.62 if (res1root)
545 {
546 freeaddrinfo(res1root);
547 }
548 if (res2root)
549 {
550 freeaddrinfo(res2root);
551 }
|
552 dave.sudlik 1.52 return isLocal;
553 #else
554
|
555 marek 1.43 // differentiate between a dotted IP address given
556 // and a real hostname given
557 CString csName = hostName.getCString();
|
558 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
559 strcpy(cc_hostname, (const char*) csName);
|
560 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
561 Boolean hostNameIsIPNotation;
562
563 // Note: Platforms already supporting the inet_aton()
564 // should define their platform here,
565 // as this is the superior way to work
|
566 kumpf 1.54 #if defined(PEGASUS_OS_LINUX) || \
567 defined(PEGASUS_OS_AIX) || \
|
568 ouyang.jian 1.55 defined(PEGASUS_OS_HPUX) || \
|
569 carson.hovey 1.60 defined(PEGASUS_OS_PASE) || \
570 defined(PEGASUS_OS_VMS)
|
571 kumpf 1.44
|
572 marek 1.43 struct in_addr inaddr;
573 // if inet_aton failed(return=0),
574 // we do not have a valip IP address (x.x.x.x)
575 int atonSuccess = inet_aton(cc_hostname, &inaddr);
576 if (atonSuccess == 0) hostNameIsIPNotation = false;
577 else
578 {
579 hostNameIsIPNotation = true;
580 tmp_addr = inaddr.s_addr;
581 }
582 #else
583 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
584 // A better solution would be to use inet_aton() or equivalent, as
585 // inet_addr() is now considered "obsolete".
586 // Note: inet_aton() not yet supported on all Pegasus platforms
|
587 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
588 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
589 else hostNameIsIPNotation = true;
590 #endif
|
591 kumpf 1.44
|
592 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
593 kumpf 1.44 {
|
594 marek 1.43 // localhost ?
595 if (String::equalNoCase(hostName,String("localhost"))) return true;
|
596 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
597 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
598 marek 1.46 strcpy(localHostName, (const char*) cstringLocalHostName);
|
599 marek 1.43 // given hostname equals what system returns as local hostname ?
600 if (String::equalNoCase(hostName,localHostName)) return true;
601 Uint32 hostIP;
602 // bail out if hostname unresolveable
603 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
604 // lets see if the IP is defined on one of the network interfaces
605 // this can help us avoid another call to DNS
606 if (System::isIpOnNetworkInterface(hostIP)) return true;
607 // need to check if the local hosts name is possibly
608 // registered at the DNS with the IP address equal resolvedNameIP
609 Uint32 localHostIP;
|
610 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
611 return false;
|
612 marek 1.43 if (localHostIP == hostIP) return true;
|
613 kumpf 1.44 }
614 else
|
615 marek 1.43 { // hostname is an IP address
616 // 127.0.0.1 is always the loopback
617 // inet_addr returns network byte order
618 if (tmp_addr == htonl(0x7F000001)) return true;
619 // IP defined on a local AF_INET network interface
620 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
621 // out of luck so far, lets ask the DNS what our IP is
622 // and check against what we got
623 Uint32 localHostIP;
|
624 kumpf 1.44 if (!System::resolveHostNameAtDNS(
625 (const char*) System::getHostName().getCString(), &localHostIP))
626 return false;
|
627 marek 1.43 if (localHostIP == tmp_addr) return true;
628 // not yet, sometimes resolving the IP address we got against the DNS
629 // can solve the problem
|
630 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
631 // those it fits all platforms
|
632 marek 1.43 Uint32 hostIP;
633 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
634 if (hostIP == localHostIP) return true;
635 }
636 return false;
|
637 dave.sudlik 1.52 #endif
|
638 marek 1.43 }
639
|
640 dmitry.mikulin 1.59 struct hostent* System::getHostByName(
641 const char* name,
642 struct hostent* he,
643 char* buf,
644 size_t len)
645 {
646 int hostEntryErrno = 0;
647 struct hostent* hostEntry = 0;
648 unsigned int maxTries = 5;
649
650 do
651 {
652 #if defined(PEGASUS_OS_LINUX)
653 gethostbyname_r(name,
654 he,
655 buf,
656 len,
657 &hostEntry,
658 &hostEntryErrno);
659 #elif defined(PEGASUS_OS_SOLARIS)
660 hostEntry = gethostbyname_r((char *)name,
661 dmitry.mikulin 1.59 he,
662 buf,
663 len,
664 &hostEntryErrno);
665 #elif defined(PEGASUS_OS_ZOS)
666 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
667 if (String::equalNoCase("localhost", String(name)))
668 {
669 gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
670 hostName[sizeof(hostName) - 1] = 0;
671 hostEntry = gethostbyname(hostName);
672 }
673 else
674 {
675 hostEntry = gethostbyname((char *)name);
676 }
677 hostEntryErrno = h_errno;
678 #else
679 hostEntry = gethostbyname((char *)name);
680 hostEntryErrno = h_errno;
681 #endif
682 dmitry.mikulin 1.59 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
683 maxTries-- > 0);
684
685 return hostEntry;
686 }
687
688 struct hostent* System::getHostByAddr(
689 const char *addr,
690 int len,
691 int type,
692 struct hostent* he,
693 char* buf,
694 size_t buflen)
695 {
696 int hostEntryErrno = 0;
697 struct hostent* hostEntry = 0;
698 unsigned int maxTries = 5;
699
700 do
701 {
702 #if defined(PEGASUS_OS_LINUX)
703 dmitry.mikulin 1.59 gethostbyaddr_r(addr,
704 len,
705 type,
706 he,
707 buf,
708 buflen,
709 &hostEntry,
710 &hostEntryErrno);
711 #elif defined(PEGASUS_OS_SOLARIS)
712 char hostEntryBuffer[8192];
713 struct hostent hostEntryStruct;
714
715 hostEntry = gethostbyaddr_r(addr,
716 len,
717 type,
718 he,
719 buf,
720 buflen,
721 &hostEntryErrno);
722 #else
723 hostEntry = gethostbyaddr(addr,
724 dmitry.mikulin 1.59 len,
725 type);
726 hostEntryErrno = h_errno;
727 #endif
728 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
729 maxTries-- > 0);
730
731 return hostEntry;
732 }
733
|
734 dmitry.mikulin 1.61 #if defined(PEGASUS_OS_ZOS) || \
735 defined(PEGASUS_OS_VMS) || \
736 defined(PEGASUS_ENABLE_IPV6)
737
|
738 dmitry.mikulin 1.59 int System::getAddrInfo(
739 const char *hostname,
740 const char *servname,
741 const struct addrinfo *hints,
742 struct addrinfo **res)
743 {
744 int rc = 0;
745 unsigned int maxTries = 5;
746
747 while ((rc = getaddrinfo(hostname,
748 servname,
749 hints,
750 res)) == EAI_AGAIN &&
751 maxTries-- > 0)
752 ;
753 return rc;
754 }
755
756 int System::getNameInfo(
757 const struct sockaddr *sa,
758 size_t salen,
759 dmitry.mikulin 1.59 char *host,
760 size_t hostlen,
761 char *serv,
762 size_t servlen,
763 int flags)
764 {
765 int rc = 0;
766 unsigned int maxTries = 5;
767
768 while ((rc = getnameinfo(sa,
769 salen,
770 host,
771 hostlen,
772 serv,
773 servlen,
774 flags)) == EAI_AGAIN &&
775 maxTries-- > 0)
776 ;
777 return rc;
778 }
779
|
780 dmitry.mikulin 1.61 #endif
|
781 dmitry.mikulin 1.59
|
782 tony 1.17 // System ID constants for Logger::put and Logger::trace
783 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
784
|
785 mike 1.8 PEGASUS_NAMESPACE_END
|