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.47.4.1 #include <Pegasus/Common/FileSystem.h>
|
46 dave.sudlik 1.47.4.2 #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 david 1.16 #if defined(PEGASUS_OS_OS400)
|
58 mike 1.40 # include "EBCDIC_OS400.h"
|
59 david 1.16 #endif
60
|
61 mike 1.8 PEGASUS_USING_STD;
62
63 PEGASUS_NAMESPACE_BEGIN
64
|
65 kumpf 1.20 Boolean System::bindVerbose = false;
66
|
67 mike 1.8 Boolean System::copyFile(const char* fromPath, const char* toPath)
68 {
|
69 ramnath 1.9 ifstream is(fromPath PEGASUS_IOS_BINARY);
|
70 mateus.baur 1.47.4.1 fstream os(toPath, ios::out PEGASUS_OR_IOS_BINARY);
|
71 mike 1.8
72 char c;
73
74 while (is.get(c))
75 {
|
76 kumpf 1.44 if (!os.put(c))
77 return false;
|
78 mike 1.8 }
79
|
80 mateus.baur 1.47.4.1 FileSystem::syncWithDirectoryUpdates(os);
|
81 kumpf 1.42 return is.eof();
|
82 kumpf 1.13 }
83
|
84 kumpf 1.44 static const Uint8 _toLowerTable[256] =
|
85 mike 1.32 {
86 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
87 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
88 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
89 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
90 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
91 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
92 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
93 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
94 0x40,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,0x5B,0x5C,0x5D,0x5E,0x5F,
98 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
99 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
100 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
101 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
102 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
103 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
104 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
105 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
106 mike 1.32 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
107 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
108 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
109 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
110 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
111 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
112 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
113 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
114 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
115 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
116 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
117 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
118 };
119
|
120 kumpf 1.13 Sint32 System::strcasecmp(const char* s1, const char* s2)
121 {
|
122 mike 1.32 // Note: this is faster than glibc strcasecmp().
123
124 Uint8* p = (Uint8*)s1;
125 Uint8* q = (Uint8*)s2;
126 int r;
127
128 for (;;)
|
129 kumpf 1.13 {
|
130 kumpf 1.44 if ((r = _toLowerTable[p[0]] - _toLowerTable[q[0]]) || !p[0] ||
131 (r = _toLowerTable[p[1]] - _toLowerTable[q[1]]) || !p[1] ||
132 (r = _toLowerTable[p[2]] - _toLowerTable[q[2]]) || !p[2] ||
133 (r = _toLowerTable[p[3]] - _toLowerTable[q[3]]) || !p[3])
134 break;
|
135 kumpf 1.13
|
136 kumpf 1.44 p += 4;
137 q += 4;
|
138 kumpf 1.13 }
139
|
140 mike 1.32 return r;
|
141 mike 1.8 }
142
|
143 tony 1.15 // Return the just the file name from the path into basename
144 char *System::extract_file_name(const char *fullpath, char *basename)
145 {
|
146 kumpf 1.44 if (fullpath == NULL)
147 {
148 basename[0] = '\0';
149 return basename;
150 }
|
151 kumpf 1.31
|
152 kumpf 1.44 for (const char* p = fullpath + strlen(fullpath) - 1; p >= fullpath; p--)
153 {
154 if (*p == '\\' || *p == '/')
155 {
156 strcpy(basename, p+1);
157 return basename;
158 }
159 }
160
161 strcpy(basename, fullpath);
162 return basename;
|
163 tony 1.15 }
164
165 // Return the just the path to the file name into dirname
166 char *System::extract_file_path(const char *fullpath, char *dirname)
167 {
|
168 kumpf 1.44 char *p;
169 char buff[4096];
170 if (fullpath == NULL)
171 {
172 dirname[0] = '\0';
173 return dirname;
174 }
175 strncpy(buff, fullpath, sizeof(buff)-1);
176 buff[sizeof(buff)-1] = '\0';
177 for (p = buff + strlen(buff); p >= buff; p--)
|
178 tony 1.15 {
|
179 kumpf 1.44 if (*p == '\\' || *p == '/')
|
180 tony 1.15 {
181 strncpy(dirname, buff, p+1 - buff);
182 dirname[p+1 - buff] = '\0';
183 return dirname;
184 }
185 }
|
186 kumpf 1.44 strcpy(dirname, fullpath);
187 return dirname;
|
188 tony 1.15 }
189
|
190 dave.sudlik 1.47.4.2 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
|
191 marek 1.24 {
|
192 dave.sudlik 1.47.4.2 #ifdef PEGASUS_ENABLE_IPV6
193 struct addrinfo *info, hints;
194 memset (&hints, 0, sizeof(struct addrinfo));
195
196 // Check for valid IPV4 address, if found return ipv4 address
197 *af = AF_INET;
198 hints.ai_family = *af;
199 hints.ai_protocol = IPPROTO_TCP;
200 hints.ai_socktype = SOCK_STREAM;
201 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
202 {
203 char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
204 HostAddress::convertBinaryToText(info->ai_family,
205 &((struct sockaddr_in*)(info->ai_addr))->sin_addr, ipAddress,
206 PEGASUS_INET_ADDRSTR_LEN);
207 hostIP = ipAddress;
208 freeaddrinfo(info);
209 return true;
210 }
211
212 // Check for valid IPV6 Address.
213 dave.sudlik 1.47.4.2 *af = AF_INET6;
214 hints.ai_family = *af;
215 hints.ai_protocol = IPPROTO_TCP;
216 hints.ai_socktype = SOCK_STREAM;
217 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
218 {
219 char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
220 HostAddress::convertBinaryToText(info->ai_family,
221 &((struct sockaddr_in6*)(info->ai_addr))->sin6_addr, ipAddress,
222 PEGASUS_INET6_ADDRSTR_LEN);
223 hostIP = ipAddress;
224 freeaddrinfo(info);
225 return true;
226 }
227
228 return false;
229 #else
230 *af = AF_INET;
|
231 kumpf 1.36 struct hostent* hostEntry;
232 struct in_addr inaddr;
233 String ipAddress;
234 CString hostNameCString = hostName.getCString();
235 const char* hostNamePtr = hostNameCString;
236
237 #if defined(PEGASUS_OS_LINUX)
238 char hostEntryBuffer[8192];
239 struct hostent hostEntryStruct;
240 int hostEntryErrno;
241
242 gethostbyname_r(
243 hostNamePtr,
244 &hostEntryStruct,
245 hostEntryBuffer,
246 sizeof(hostEntryBuffer),
247 &hostEntry,
248 &hostEntryErrno);
249 #elif defined(PEGASUS_OS_SOLARIS)
250 char hostEntryBuffer[8192];
251 struct hostent hostEntryStruct;
252 kumpf 1.36 int hostEntryErrno;
253
254 hostEntry = gethostbyname_r(
255 (char *)hostNamePtr,
256 &hostEntryStruct,
257 hostEntryBuffer,
258 sizeof(hostEntryBuffer),
259 &hostEntryErrno);
260 #elif defined(PEGASUS_OS_OS400)
|
261 chuck 1.28 char ebcdicHost[PEGASUS_MAXHOSTNAMELEN];
|
262 kumpf 1.36 if (strlen(hostNamePtr) < PEGASUS_MAXHOSTNAMELEN)
263 strcpy(ebcdicHost, hostNamePtr);
|
264 chuck 1.28 else
265 return ipAddress;
266 AtoE(ebcdicHost);
|
267 kumpf 1.36 hostEntry = gethostbyname(ebcdicHost);
268 #else
269 hostEntry = gethostbyname(hostNamePtr);
|
270 humberto 1.27 #endif
|
271 kumpf 1.36
272 if (hostEntry)
|
273 marek 1.24 {
|
274 kumpf 1.36 ::memcpy( &inaddr, hostEntry->h_addr,4);
|
275 marek 1.34 #if defined(PEGASUS_OS_OS400)
|
276 david 1.33 char * gottenIPAdress = NULL;
277 gottenIPAdress = ::inet_ntoa( inaddr );
|
278 kumpf 1.44
|
279 david 1.33 if (gottenIPAdress != NULL)
280 {
|
281 kumpf 1.44 EtoA(gottenIPAdress);
|
282 david 1.33 ipAddress.assign(gottenIPAdress);
283 }
|
284 marek 1.24 #else
285 ipAddress = ::inet_ntoa( inaddr );
286 #endif
287 }
|
288 dave.sudlik 1.47.4.2 hostIP = ipAddress;
289 return true;
290 #endif
|
291 marek 1.24 }
|
292 r.kieninger 1.21
|
293 venkat.puvvada 1.47.4.4
294 #ifdef PEGASUS_ENABLE_IPV6
295 Boolean System::isIPv6StackActive()
296 {
297 SocketHandle ip6Socket;
298 if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
299 == PEGASUS_INVALID_SOCKET)
300 {
301 if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
302 {
303 return false;
304 }
305 }
306 else
307 {
308 Socket::close(ip6Socket);
309 }
310
311 return true;
312 }
313 #endif
314 venkat.puvvada 1.47.4.4
|
315 r.kieninger 1.21 // ------------------------------------------------------------------------
316 // Convert a hostname into a a single host unique integer representation
317 // ------------------------------------------------------------------------
|
318 dave.sudlik 1.47.4.2 Boolean System::_acquireIP(const char* hostname, int *af, void *dst)
319 {
320 #ifdef PEGASUS_ENABLE_IPV6
321 String ipAddress;
322 if(getHostIP(hostname, af, ipAddress))
|
323 r.kieninger 1.21 {
|
324 dave.sudlik 1.47.4.2 HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
325 return true;
326 }
327 return false;
328 #else
329 *af = AF_INET;
|
330 kumpf 1.44 Uint32 ip = 0xFFFFFFFF;
331 if (!hostname) return 0xFFFFFFFF;
|
332 r.kieninger 1.21
333 #ifdef PEGASUS_OS_OS400
|
334 kumpf 1.44 char ebcdicHost[PEGASUS_MAXHOSTNAMELEN];
335 if (strlen(hostname) < PEGASUS_MAXHOSTNAMELEN)
336 strcpy(ebcdicHost, hostname);
337 else
338 return 0xFFFFFFFF;
339 AtoE(ebcdicHost);
|
340 r.kieninger 1.21 #endif
341
|
342 dave.sudlik 1.22 ////////////////////////////////////////////////////////////////////////////////
343 // This code used to check if the first character of "hostname" was alphabetic
|
344 kumpf 1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
345 // relaxed this requirement to alphabetic character *or* digit. So bug 1462
346 // changed the flow here to call inet_addr first to check for a valid IP
347 // address in dotted decimal notation. If it's not a valid IP address, then
348 // try to validate it as a hostname.
349 // RFC 1123 states: The host SHOULD check the string syntactically for a
350 // dotted-decimal number before looking it up in the Domain Name System.
|
351 dave.sudlik 1.22 // Hence the call to inet_addr() first.
352 ////////////////////////////////////////////////////////////////////////////////
353
354 #ifdef PEGASUS_OS_OS400
|
355 kumpf 1.44 Uint32 tmp_addr = inet_addr(ebcdicHost);
|
356 dave.sudlik 1.22 #else
|
357 kumpf 1.44 Uint32 tmp_addr = inet_addr((char *) hostname);
|
358 dave.sudlik 1.22 #endif
359
|
360 kumpf 1.36 struct hostent* hostEntry;
|
361 r.kieninger 1.21
|
362 dave.sudlik 1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
363 // A better solution would be to use inet_aton() or equivalent, as
364 // inet_addr() is now considered "obsolete".
365
366 if (tmp_addr == 0xFFFFFFFF) // if hostname is not an IP address
|
367 kumpf 1.36 {
368 #if defined(PEGASUS_OS_LINUX)
369 char hostEntryBuffer[8192];
370 struct hostent hostEntryStruct;
371 int hostEntryErrno;
372
373 gethostbyname_r(
374 hostname,
375 &hostEntryStruct,
376 hostEntryBuffer,
377 sizeof(hostEntryBuffer),
378 &hostEntry,
379 &hostEntryErrno);
380 #elif defined(PEGASUS_OS_SOLARIS)
381 char hostEntryBuffer[8192];
382 struct hostent hostEntryStruct;
383 int hostEntryErrno;
384
385 hostEntry = gethostbyname_r(
386 (char *)hostname,
387 &hostEntryStruct,
388 kumpf 1.36 hostEntryBuffer,
389 sizeof(hostEntryBuffer),
390 &hostEntryErrno);
|
391 r.kieninger 1.21 #elif defined(PEGASUS_OS_OS400)
|
392 kumpf 1.36 hostEntry = gethostbyname(ebcdicHost);
|
393 r.kieninger 1.21 #elif defined(PEGASUS_OS_ZOS)
|
394 kumpf 1.36 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
395 if (String::equalNoCase("localhost",String(hostname)))
396 {
397 gethostname( hostName, PEGASUS_MAXHOSTNAMELEN );
398 hostName[sizeof(hostName)-1] = 0;
399 hostEntry = gethostbyname(hostName);
|
400 kumpf 1.44 }
401 else
|
402 kumpf 1.36 {
403 hostEntry = gethostbyname((char *)hostname);
404 }
|
405 r.kieninger 1.21 #else
|
406 kumpf 1.36 hostEntry = gethostbyname((char *)hostname);
|
407 r.kieninger 1.21 #endif
|
408 kumpf 1.36 if (!hostEntry)
|
409 kumpf 1.44 {
|
410 dave.sudlik 1.47.4.2 // error, couldn't resolve the ip
411 memcpy(dst, &ip, sizeof (Uint32));
412 return false;
|
413 kumpf 1.44 }
414 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
415
416 ip_part1 = hostEntry->h_addr[0];
417 ip_part2 = hostEntry->h_addr[1];
418 ip_part3 = hostEntry->h_addr[2];
419 ip_part4 = hostEntry->h_addr[3];
420 ip = ip_part1;
421 ip = (ip << 8) + ip_part2;
422 ip = (ip << 8) + ip_part3;
423 ip = (ip << 8) + ip_part4;
424 }
|
425 dave.sudlik 1.22 else // else hostname *is* a dotted-decimal IP address
|
426 kumpf 1.44 {
427 // resolve hostaddr to a real host entry
428 // casting to (const char *) as (char *) will work as (void *) too,
429 // those it fits all platforms
|
430 ms.aruran 1.45 #if defined(PEGASUS_OS_LINUX)
431 char hostEntryBuffer[8192];
432 struct hostent hostEntryStruct;
433 int hostEntryErrno;
434
435 gethostbyaddr_r(
436 (const char*) &tmp_addr,
437 sizeof(tmp_addr),
438 AF_INET,
439 &hostEntryStruct,
440 hostEntryBuffer,
441 sizeof(hostEntryBuffer),
442 &hostEntry,
443 &hostEntryErrno);
444 #elif defined(PEGASUS_OS_SOLARIS)
445 char hostEntryBuffer[8192];
446 struct hostent hostEntryStruct;
447 int hostEntryErrno;
448
449 hostEntry = gethostbyaddr_r(
450 (const char *) &tmp_addr,
451 ms.aruran 1.45 sizeof(tmp_addr),
452 AF_INET,
453 &hostEntryStruct,
454 hostEntryBuffer,
455 sizeof(hostEntryBuffer),
456 &hostEntryErrno);
457 #elif defined(PEGASUS_OS_OS400)
|
458 kumpf 1.44 hostEntry =
|
459 ms.aruran 1.45 gethostbyaddr((char *) &tmp_addr, sizeof(tmp_addr), AF_INET);
|
460 humberto 1.27 #else
|
461 kumpf 1.44 hostEntry =
|
462 ms.aruran 1.45 gethostbyaddr((const char *) &tmp_addr, sizeof(tmp_addr), AF_INET);
|
463 humberto 1.27 #endif
|
464 kumpf 1.44 if (hostEntry == 0)
465 {
466 // error, couldn't resolve the ip
|
467 dave.sudlik 1.47.4.2 memcpy(dst, &ip, sizeof (Uint32));
468 return false;
|
469 kumpf 1.44 }
470 else
471 {
472 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
|
473 r.kieninger 1.21
|
474 kumpf 1.44 ip_part1 = hostEntry->h_addr[0];
475 ip_part2 = hostEntry->h_addr[1];
476 ip_part3 = hostEntry->h_addr[2];
477 ip_part4 = hostEntry->h_addr[3];
478 ip = ip_part1;
479 ip = (ip << 8) + ip_part2;
480 ip = (ip << 8) + ip_part3;
481 ip = (ip << 8) + ip_part4;
482 }
483 }
|
484 dave.sudlik 1.47.4.2 memcpy(dst, &ip, sizeof (Uint32));
|
485 carolann.graves 1.29
486 return true;
|
487 dave.sudlik 1.47.4.2 #endif
|
488 carolann.graves 1.29 }
489
|
490 kumpf 1.44 Boolean System::resolveHostNameAtDNS(
491 const char* hostname,
492 Uint32* resolvedNameIP)
|
493 marek 1.43 {
494 // ask the DNS for hostname resolution to IP address
495 // this can mean a time delay for as long as the DNS
|
496 kumpf 1.44 // takes to answer
|
497 marek 1.43 struct hostent* hostEntry;
498
499 #if defined(PEGASUS_OS_LINUX)
|
500 kumpf 1.44 char hostEntryBuffer[8192];
501 struct hostent hostEntryStruct;
502 int hostEntryErrno;
|
503 marek 1.43
|
504 kumpf 1.44 gethostbyname_r(
505 hostname,
506 &hostEntryStruct,
507 hostEntryBuffer,
508 sizeof(hostEntryBuffer),
509 &hostEntry,
510 &hostEntryErrno);
|
511 marek 1.43 #elif defined(PEGASUS_OS_SOLARIS)
|
512 kumpf 1.44 char hostEntryBuffer[8192];
513 struct hostent hostEntryStruct;
514 int hostEntryErrno;
|
515 marek 1.43
|
516 kumpf 1.44 hostEntry = gethostbyname_r(
517 (char *)hostname,
518 &hostEntryStruct,
519 hostEntryBuffer,
520 sizeof(hostEntryBuffer),
521 &hostEntryErrno);
|
522 marek 1.43 #else
|
523 kumpf 1.44 hostEntry = gethostbyname((char *)hostname);
|
524 marek 1.43 #endif
525 if (hostEntry == 0)
526 {
527 // error, couldn't resolve the hostname to an ip address
528 return false;
|
529 kumpf 1.44 }
530 else
|
531 marek 1.43 {
532 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
533 ip_part1 = hostEntry->h_addr[0];
534 ip_part2 = hostEntry->h_addr[1];
535 ip_part3 = hostEntry->h_addr[2];
536 ip_part4 = hostEntry->h_addr[3];
537 *resolvedNameIP = ip_part1;
538 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
539 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
540 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
541 }
542 return true;
543 }
544
545 Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
546 {
|
547 kumpf 1.44 struct hostent *entry;
|
548 marek 1.43
549 #ifndef PEGASUS_OS_OS400
|
550 kumpf 1.44 entry = gethostbyaddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
551 marek 1.43 #else
|
552 kumpf 1.44 entry = gethostbyaddr((char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
553 marek 1.43 #endif
|
554 kumpf 1.44 if (entry == 0)
555 {
556 // error, couldn't resolve the ip
557 return false;
558 }
559 else
560 {
561 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
562 ip_part1 = entry->h_addr[0];
563 ip_part2 = entry->h_addr[1];
564 ip_part3 = entry->h_addr[2];
565 ip_part4 = entry->h_addr[3];
566 *resolvedIP = ip_part1;
567 *resolvedIP = (*resolvedIP << 8) + ip_part2;
568 *resolvedIP = (*resolvedIP << 8) + ip_part3;
569 *resolvedIP = (*resolvedIP << 8) + ip_part4;
570 }
571 return true;
|
572 marek 1.43 }
573
574
|
575 dave.sudlik 1.47.4.2 Boolean System::isLoopBack(int af, void *binIPAddress)
576 {
577 #ifdef PEGASUS_ENABLE_IPV6
578 struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
579 #endif
580 Uint32 ip4 = PEGASUS_IPV4_LOOPBACK_INIT;
581 switch (af)
582 {
583 #ifdef PEGASUS_ENABLE_IPV6
584 case AF_INET6:
585 return !memcmp(&ip6, binIPAddress, sizeof (ip6));
586 #endif
587 case AF_INET:
588 Uint32 n = ntohl( *(Uint32*)binIPAddress);
589 return !memcmp(&ip4, &n, sizeof (ip4));
590 }
591
592 return false;
593 }
594
|
595 marek 1.43 Boolean System::isLocalHost(const String &hostName)
596 {
|
597 dave.sudlik 1.47.4.2 // Get all ip addresses on the node and compare them with the given hostname.
598 #ifdef PEGASUS_ENABLE_IPV6
599 CString csName = hostName.getCString();
|
600 dave.sudlik 1.47.4.3 struct addrinfo hints, *res1, *res2, *res1root, *res2root;
|
601 dave.sudlik 1.47.4.2 char localHostName[PEGASUS_MAXHOSTNAMELEN];
602 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
603 Boolean isLocal = false;
604
605 memset(&hints, 0, sizeof(hints));
606 hints.ai_family = AF_INET;
607 hints.ai_socktype = SOCK_STREAM;
608 hints.ai_protocol = IPPROTO_TCP;
|
609 dave.sudlik 1.47.4.3 res1root = res2root = 0;
610 getaddrinfo(csName, 0, &hints, &res1root);
611 getaddrinfo(localHostName, 0, &hints, &res2root);
|
612 dave.sudlik 1.47.4.2
|
613 dave.sudlik 1.47.4.3 res1 = res1root;
|
614 dave.sudlik 1.47.4.2 while (res1 && !isLocal)
615 {
616 if (isLoopBack(AF_INET,
617 &((struct sockaddr_in*)res1->ai_addr)->sin_addr))
618 {
619 isLocal = true;
620 break;
621 }
622
|
623 dave.sudlik 1.47.4.3 res2 = res2root;
624 while (res2)
|
625 dave.sudlik 1.47.4.2 {
626 if (!memcmp(&((struct sockaddr_in*)res1->ai_addr)->sin_addr,
627 &((struct sockaddr_in*)res2->ai_addr)->sin_addr,
628 sizeof (struct in_addr)))
629 {
630 isLocal = true;
631 break;
632 }
|
633 dave.sudlik 1.47.4.3 res2 = res2->ai_next;
|
634 dave.sudlik 1.47.4.2 }
635 res1 = res1->ai_next;
636 }
|
637 dave.sudlik 1.47.4.3 freeaddrinfo(res1root);
638 freeaddrinfo(res2root);
|
639 dave.sudlik 1.47.4.2 if (isLocal)
640 {
641 return true;
642 }
643
644 hints.ai_family = AF_INET6;
|
645 dave.sudlik 1.47.4.3 res1root = res2root = 0;
646 getaddrinfo(csName, 0, &hints, &res1root);
647 getaddrinfo(localHostName, 0, &hints, &res2root);
648
649 res1 = res1root;
|
650 dave.sudlik 1.47.4.2 while (res1 && !isLocal)
651 {
652 if (isLoopBack(AF_INET6,
653 &((struct sockaddr_in6*)res1->ai_addr)->sin6_addr))
654 {
655 isLocal = true;
656 break;
657 }
658
|
659 dave.sudlik 1.47.4.3 res2 = res2root;
660 while (res2)
|
661 dave.sudlik 1.47.4.2 {
662 if (!memcmp(&((struct sockaddr_in6*)res1->ai_addr)->sin6_addr,
663 &((struct sockaddr_in6*)res2->ai_addr)->sin6_addr,
664 sizeof (struct in6_addr)))
665 {
666 isLocal = true;
667 break;
668 }
|
669 dave.sudlik 1.47.4.3 res2 = res2->ai_next;
|
670 dave.sudlik 1.47.4.2 }
671 res1 = res1->ai_next;
672 }
|
673 dave.sudlik 1.47.4.3 freeaddrinfo(res1root);
674 freeaddrinfo(res2root);
|
675 dave.sudlik 1.47.4.2
676 return isLocal;
677 #else
678
|
679 marek 1.43 // differentiate between a dotted IP address given
680 // and a real hostname given
681 CString csName = hostName.getCString();
|
682 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
683 strcpy(cc_hostname, (const char*) csName);
|
684 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
685 Boolean hostNameIsIPNotation;
686
687 #ifdef PEGASUS_OS_OS400
688 AtoE(cc_hostname);
689 #endif
690
691 // Note: Platforms already supporting the inet_aton()
692 // should define their platform here,
693 // as this is the superior way to work
694 #if defined(PEGASUS_OS_LINUX) || defined(PEGASUS_OS_AIX)
|
695 kumpf 1.44
|
696 marek 1.43 struct in_addr inaddr;
697 // if inet_aton failed(return=0),
698 // we do not have a valip IP address (x.x.x.x)
699 int atonSuccess = inet_aton(cc_hostname, &inaddr);
700 if (atonSuccess == 0) hostNameIsIPNotation = false;
701 else
702 {
703 hostNameIsIPNotation = true;
704 tmp_addr = inaddr.s_addr;
705 }
706 #else
707 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
708 // A better solution would be to use inet_aton() or equivalent, as
709 // inet_addr() is now considered "obsolete".
710 // Note: inet_aton() not yet supported on all Pegasus platforms
|
711 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
712 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
713 else hostNameIsIPNotation = true;
714 #endif
|
715 kumpf 1.44
|
716 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
717 kumpf 1.44 {
|
718 marek 1.43 // localhost ?
719 if (String::equalNoCase(hostName,String("localhost"))) return true;
|
720 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
721 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
722 marek 1.46 strcpy(localHostName, (const char*) cstringLocalHostName);
|
723 marek 1.43 // given hostname equals what system returns as local hostname ?
724 if (String::equalNoCase(hostName,localHostName)) return true;
725 Uint32 hostIP;
726 // bail out if hostname unresolveable
727 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
728 // lets see if the IP is defined on one of the network interfaces
729 // this can help us avoid another call to DNS
730 if (System::isIpOnNetworkInterface(hostIP)) return true;
731 // need to check if the local hosts name is possibly
732 // registered at the DNS with the IP address equal resolvedNameIP
733 Uint32 localHostIP;
|
734 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
735 return false;
|
736 marek 1.43 if (localHostIP == hostIP) return true;
|
737 kumpf 1.44 }
738 else
|
739 marek 1.43 { // hostname is an IP address
740 // 127.0.0.1 is always the loopback
741 // inet_addr returns network byte order
742 if (tmp_addr == htonl(0x7F000001)) return true;
743 // IP defined on a local AF_INET network interface
744 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
745 // out of luck so far, lets ask the DNS what our IP is
746 // and check against what we got
747 Uint32 localHostIP;
|
748 kumpf 1.44 if (!System::resolveHostNameAtDNS(
749 (const char*) System::getHostName().getCString(), &localHostIP))
750 return false;
|
751 marek 1.43 if (localHostIP == tmp_addr) return true;
752 // not yet, sometimes resolving the IP address we got against the DNS
753 // can solve the problem
|
754 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
755 // those it fits all platforms
|
756 marek 1.43 Uint32 hostIP;
757 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
758 if (hostIP == localHostIP) return true;
759 }
760 return false;
|
761 dave.sudlik 1.47.4.2 #endif
|
762 marek 1.43 }
763
|
764 tony 1.17 // System ID constants for Logger::put and Logger::trace
765 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
766
|
767 mike 1.8 PEGASUS_NAMESPACE_END
|
768 ms.aruran 1.45
|