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