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.57 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.57 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.57 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.57 hostIP = ipAddress;
245 return true;
|
246 marek 1.24 }
|
247 dmitry.mikulin 1.57 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.57 {
|
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.57 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.57 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.57 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.57 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.57 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.57 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 dave.sudlik 1.53 freeaddrinfo(res1root);
498 freeaddrinfo(res2root);
|
499 dave.sudlik 1.52 if (isLocal)
500 {
501 return true;
502 }
503
504 hints.ai_family = AF_INET6;
|
505 dave.sudlik 1.53 res1root = res2root = 0;
|
506 dmitry.mikulin 1.57 getAddrInfo(csName, 0, &hints, &res1root);
507 getAddrInfo(localHostName, 0, &hints, &res2root);
|
508 dave.sudlik 1.53
509 res1 = res1root;
|
510 dave.sudlik 1.52 while (res1 && !isLocal)
511 {
|
512 kumpf 1.54 if (isLoopBack(
513 AF_INET6,
514 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
515 sin6_addr))
|
516 dave.sudlik 1.52 {
517 isLocal = true;
518 break;
519 }
520
|
521 dave.sudlik 1.53 res2 = res2root;
522 while (res2)
|
523 dave.sudlik 1.52 {
|
524 kumpf 1.54 if (!memcmp(
525 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
526 sin6_addr,
527 &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
528 sin6_addr,
529 sizeof (struct in6_addr)))
|
530 dave.sudlik 1.52 {
531 isLocal = true;
532 break;
533 }
|
534 dave.sudlik 1.53 res2 = res2->ai_next;
|
535 dave.sudlik 1.52 }
536 res1 = res1->ai_next;
537 }
|
538 dave.sudlik 1.53 freeaddrinfo(res1root);
539 freeaddrinfo(res2root);
|
540 dave.sudlik 1.52
541 return isLocal;
542 #else
543
|
544 marek 1.43 // differentiate between a dotted IP address given
545 // and a real hostname given
546 CString csName = hostName.getCString();
|
547 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
548 strcpy(cc_hostname, (const char*) csName);
|
549 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
550 Boolean hostNameIsIPNotation;
551
552 // Note: Platforms already supporting the inet_aton()
553 // should define their platform here,
554 // as this is the superior way to work
|
555 kumpf 1.54 #if defined(PEGASUS_OS_LINUX) || \
556 defined(PEGASUS_OS_AIX) || \
|
557 ouyang.jian 1.55 defined(PEGASUS_OS_HPUX) || \
558 defined(PEGASUS_OS_PASE)
|
559 kumpf 1.44
|
560 marek 1.43 struct in_addr inaddr;
561 // if inet_aton failed(return=0),
562 // we do not have a valip IP address (x.x.x.x)
563 int atonSuccess = inet_aton(cc_hostname, &inaddr);
564 if (atonSuccess == 0) hostNameIsIPNotation = false;
565 else
566 {
567 hostNameIsIPNotation = true;
568 tmp_addr = inaddr.s_addr;
569 }
570 #else
571 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
572 // A better solution would be to use inet_aton() or equivalent, as
573 // inet_addr() is now considered "obsolete".
574 // Note: inet_aton() not yet supported on all Pegasus platforms
|
575 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
576 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
577 else hostNameIsIPNotation = true;
578 #endif
|
579 kumpf 1.44
|
580 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
581 kumpf 1.44 {
|
582 marek 1.43 // localhost ?
583 if (String::equalNoCase(hostName,String("localhost"))) return true;
|
584 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
585 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
586 marek 1.46 strcpy(localHostName, (const char*) cstringLocalHostName);
|
587 marek 1.43 // given hostname equals what system returns as local hostname ?
588 if (String::equalNoCase(hostName,localHostName)) return true;
589 Uint32 hostIP;
590 // bail out if hostname unresolveable
591 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
592 // lets see if the IP is defined on one of the network interfaces
593 // this can help us avoid another call to DNS
594 if (System::isIpOnNetworkInterface(hostIP)) return true;
595 // need to check if the local hosts name is possibly
596 // registered at the DNS with the IP address equal resolvedNameIP
597 Uint32 localHostIP;
|
598 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
599 return false;
|
600 marek 1.43 if (localHostIP == hostIP) return true;
|
601 kumpf 1.44 }
602 else
|
603 marek 1.43 { // hostname is an IP address
604 // 127.0.0.1 is always the loopback
605 // inet_addr returns network byte order
606 if (tmp_addr == htonl(0x7F000001)) return true;
607 // IP defined on a local AF_INET network interface
608 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
609 // out of luck so far, lets ask the DNS what our IP is
610 // and check against what we got
611 Uint32 localHostIP;
|
612 kumpf 1.44 if (!System::resolveHostNameAtDNS(
613 (const char*) System::getHostName().getCString(), &localHostIP))
614 return false;
|
615 marek 1.43 if (localHostIP == tmp_addr) return true;
616 // not yet, sometimes resolving the IP address we got against the DNS
617 // can solve the problem
|
618 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
619 // those it fits all platforms
|
620 marek 1.43 Uint32 hostIP;
621 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
622 if (hostIP == localHostIP) return true;
623 }
624 return false;
|
625 dave.sudlik 1.52 #endif
|
626 marek 1.43 }
627
|
628 dmitry.mikulin 1.57 struct hostent* System::getHostByName(
629 const char* name,
630 struct hostent* he,
631 char* buf,
632 size_t len)
633 {
634 int hostEntryErrno = 0;
635 struct hostent* hostEntry = 0;
636 unsigned int maxTries = 5;
637
638 do
639 {
640 #if defined(PEGASUS_OS_LINUX)
641 gethostbyname_r(name,
642 he,
643 buf,
644 len,
645 &hostEntry,
646 &hostEntryErrno);
647 #elif defined(PEGASUS_OS_SOLARIS)
648 hostEntry = gethostbyname_r((char *)name,
649 dmitry.mikulin 1.57 he,
650 buf,
651 len,
652 &hostEntryErrno);
653 #elif defined(PEGASUS_OS_ZOS)
654 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
655 if (String::equalNoCase("localhost", String(name)))
656 {
657 gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
658 hostName[sizeof(hostName) - 1] = 0;
659 hostEntry = gethostbyname(hostName);
660 }
661 else
662 {
663 hostEntry = gethostbyname((char *)name);
664 }
665 hostEntryErrno = h_errno;
666 #else
667 hostEntry = gethostbyname((char *)name);
668 hostEntryErrno = h_errno;
669 #endif
670 dmitry.mikulin 1.57 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
671 maxTries-- > 0);
672
673 return hostEntry;
674 }
675
676 struct hostent* System::getHostByAddr(
677 const char *addr,
678 int len,
679 int type,
680 struct hostent* he,
681 char* buf,
682 size_t buflen)
683 {
684 int hostEntryErrno = 0;
685 struct hostent* hostEntry = 0;
686 unsigned int maxTries = 5;
687
688 do
689 {
690 #if defined(PEGASUS_OS_LINUX)
691 dmitry.mikulin 1.57 gethostbyaddr_r(addr,
692 len,
693 type,
694 he,
695 buf,
696 buflen,
697 &hostEntry,
698 &hostEntryErrno);
699 #elif defined(PEGASUS_OS_SOLARIS)
700 char hostEntryBuffer[8192];
701 struct hostent hostEntryStruct;
702
703 hostEntry = gethostbyaddr_r(addr,
704 len,
705 type,
706 he,
707 buf,
708 buflen,
709 &hostEntryErrno);
710 #else
711 hostEntry = gethostbyaddr(addr,
712 dmitry.mikulin 1.57 len,
713 type);
714 hostEntryErrno = h_errno;
715 #endif
716 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
717 maxTries-- > 0);
718
719 return hostEntry;
720 }
721
722 int System::getAddrInfo(
723 const char *hostname,
724 const char *servname,
725 const struct addrinfo *hints,
726 struct addrinfo **res)
727 {
728 int rc = 0;
729 unsigned int maxTries = 5;
730
731 while ((rc = getaddrinfo(hostname,
732 servname,
733 dmitry.mikulin 1.57 hints,
734 res)) == EAI_AGAIN &&
735 maxTries-- > 0)
736 ;
737 return rc;
738 }
739
740 int System::getNameInfo(
741 const struct sockaddr *sa,
742 size_t salen,
743 char *host,
744 size_t hostlen,
745 char *serv,
746 size_t servlen,
747 int flags)
748 {
749 int rc = 0;
750 unsigned int maxTries = 5;
751
752 while ((rc = getnameinfo(sa,
753 salen,
754 dmitry.mikulin 1.57 host,
755 hostlen,
756 serv,
757 servlen,
758 flags)) == EAI_AGAIN &&
759 maxTries-- > 0)
760 ;
761 return rc;
762 }
763
764
|
765 tony 1.17 // System ID constants for Logger::put and Logger::trace
766 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
767
|
768 mike 1.8 PEGASUS_NAMESPACE_END
|