1 martin 1.62 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.63 //
|
3 martin 1.62 // 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.63 //
|
10 martin 1.62 // 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.63 //
|
17 martin 1.62 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.63 //
|
20 martin 1.62 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.63 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.62 // 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.63 //
|
28 martin 1.62 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 r.kieninger 1.55 #if defined(PEGASUS_OS_ZOS)
|
33 mike 1.2 # define _OPEN_SYS_EXT
34 # include <sys/ps.h>
|
35 r.kieninger 1.8 # include <sys/__messag.h>
|
36 mike 1.2 #endif
37
38 #include <unistd.h>
39 #include <dirent.h>
40 #include <pwd.h>
41 #include <grp.h>
42 #include <errno.h>
43
44 #if defined(PEGASUS_OS_SOLARIS)
45 # include <string.h>
|
46 marek 1.49 # include <sys/sockio.h>
|
47 mike 1.2 #endif
48
49 #include "Network.h"
50
51 #if defined(PEGASUS_USE_SYSLOGS)
52 # include <syslog.h>
53 #endif
54
55 #include <sys/stat.h>
56 #include <sys/types.h>
57 #include <cstdio>
58 #include <time.h>
59 #include <sys/time.h>
60 #include "System.h"
|
61 ouyang.jian 1.39
62 #ifdef PEGASUS_OS_PASE
63 #include <ILEWrapper/ILEUtilities.h>
64 #endif
65
|
66 mike 1.2 #include <Pegasus/Common/Tracer.h>
67 #include <Pegasus/Common/InternalException.h>
68 #include <Pegasus/Common/Mutex.h>
69
|
70 marek 1.10 #include <net/if.h>
71
|
72 mike 1.2 #include "Once.h"
73
74 PEGASUS_NAMESPACE_BEGIN
75
76 //==============================================================================
77 //
78 // System
79 //
80 //==============================================================================
81
82 // System ID constants for Logger::put and Logger::trace
|
83 ouyang.jian 1.23 #if defined(PEGASUS_OS_ZOS)
|
84 s.kodali 1.70 # ifdef PEGASUS_FLAVOR
85 const String System::CIMSERVER = "CFZCIM" PEGASUS_FLAVOR;
86 # else
|
87 marek 1.12 const String System::CIMSERVER = "CFZCIM"; // Server system ID
|
88 s.kodali 1.70 # endif
89 #else
90 # ifdef PEGASUS_FLAVOR
91 const String System::CIMSERVER = "cimserver" PEGASUS_FLAVOR;//Server system ID
|
92 mike 1.2 #else
93 const String System::CIMSERVER = "cimserver"; // Server system ID
94 #endif
|
95 s.kodali 1.70 #endif
|
96 mike 1.2
97 void System::getCurrentTime(Uint32& seconds, Uint32& milliseconds)
98 {
99 timeval tv;
100 gettimeofday(&tv, 0);
101 seconds = Uint32(tv.tv_sec);
102 milliseconds = Uint32(tv.tv_usec) / 1000;
103 }
104
105 void System::getCurrentTimeUsec(Uint32& seconds, Uint32& microseconds)
106 {
107 timeval tv;
108 gettimeofday(&tv, 0);
109 seconds = Uint32(tv.tv_sec);
110 microseconds = Uint32(tv.tv_usec);
111 }
112
|
113 venkat.puvvada 1.72 Uint64 System::getCurrentTimeUsec()
114 {
115 timeval tv;
116 gettimeofday(&tv, 0);
117 Uint64 microseconds = tv.tv_sec;
118 microseconds *= 1000000;
119 microseconds += Uint64(tv.tv_usec);
120 return microseconds;
121 }
122
|
123 mike 1.2 String System::getCurrentASCIITime()
124 {
125 char str[50];
126 time_t rawTime;
127 struct tm tmBuffer;
128
129 time(&rawTime);
130 strftime(str, 40,"%m/%d/%Y-%T", localtime_r(&rawTime, &tmBuffer));
131 return String(str);
132 }
133
134 static inline void _sleep_wrapper(Uint32 seconds)
135 {
136 sleep(seconds);
137 }
138
139 void System::sleep(Uint32 seconds)
140 {
141 _sleep_wrapper(seconds);
142 }
143
144 mike 1.2 Boolean System::exists(const char* path)
145 {
146 return access(path, F_OK) == 0;
147 }
148
149 Boolean System::getCurrentDirectory(char* path, Uint32 size)
150 {
151 return getcwd(path, size) != NULL;
152 }
153
154 Boolean System::isDirectory(const char* path)
155 {
156 struct stat st;
157 if (stat(path, &st) != 0)
158 return false;
|
159 kumpf 1.65
|
160 mike 1.2 return S_ISDIR(st.st_mode);
161 }
162
163 Boolean System::changeDirectory(const char* path)
164 {
165 return chdir(path) == 0;
166 }
167
168 Boolean System::makeDirectory(const char* path)
169 {
170 return mkdir(path, 0777) == 0;
171 }
172
173 Boolean System::getFileSize(const char* path, Uint32& size)
174 {
175 struct stat st;
176 if (stat(path, &st) != 0)
177 return false;
178 size = st.st_size;
|
179 kumpf 1.65
|
180 mike 1.2 return true;
181 }
182 Boolean System::removeDirectory(const char* path)
183 {
184 return rmdir(path) == 0;
185 }
186
187 Boolean System::removeFile(const char* path)
188 {
189 return unlink(path) == 0;
190 }
191
192 Boolean System::renameFile(const char* oldPath, const char* newPath)
193 {
|
194 kumpf 1.54 Boolean success = (rename(oldPath, newPath) == 0);
|
195 mike 1.2
|
196 kumpf 1.54 if (!success)
197 {
198 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
199 "rename(\"%s\", \"%s\") failed: %s",
200 oldPath,
201 newPath,
202 (const char*) PEGASUS_SYSTEM_ERRORMSG.getCString()));
203 }
|
204 mike 1.2
|
205 kumpf 1.54 return success;
|
206 mike 1.2 }
207
208 String System::getSystemCreationClassName ()
209 {
210 //
211 // The value returned should match the value of the CreationClassName key
212 // property used in the instrumentation of the CIM_ComputerSystem class
213 // as determined by the provider for the CIM_ComputerSystem class
214 //
215 return "CIM_ComputerSystem";
216 }
217
218 Uint32 System::lookupPort(
219 const char * serviceName,
220 Uint32 defaultPort)
221 {
222 Uint32 localPort;
223
224 struct servent *serv;
225
226 //
227 mike 1.2 // Get wbem-local port from /etc/services
228 //
229
230 #if defined(PEGASUS_OS_SOLARIS)
231 # define SERV_BUFF_SIZE 1024
232 struct servent serv_result;
233 char buf[SERV_BUFF_SIZE];
234
235 if ( (serv = getservbyname_r(serviceName, TCP, &serv_result,
236 buf, SERV_BUFF_SIZE)) != NULL )
|
237 venkat.puvvada 1.57 #elif defined(PEGASUS_OS_LINUX)
238 # define SERV_BUFF_SIZE 1024
239 struct servent serv_result;
240 char buf[SERV_BUFF_SIZE];
241 int ret = getservbyname_r(
|
242 kumpf 1.65 serviceName,
243 TCP,
|
244 venkat.puvvada 1.57 &serv_result,
245 buf,
246 SERV_BUFF_SIZE,
247 &serv);
248 if (ret == 0 && serv != NULL)
249 #else
|
250 mike 1.2 if ( (serv = getservbyname(serviceName, TCP)) != NULL )
|
251 venkat.puvvada 1.57 #endif
|
252 mike 1.2 {
253 localPort = htons((uint16_t)serv->s_port);
254 }
255 else
256 {
257 localPort = defaultPort;
258 }
259
260 return localPort;
261 }
262
263 String System::getEffectiveUserName()
264 {
|
265 kumpf 1.44 #if defined(PEGASUS_OS_ZOS)
266 char effective_username[9];
267 __getuserid(effective_username, 9);
268 __etoa_l(effective_username,9);
269 return String(effective_username);
270 #else
|
271 kumpf 1.20 String userName;
|
272 mike 1.2 struct passwd* pwd = NULL;
273 const unsigned int PWD_BUFF_SIZE = 1024;
|
274 kumpf 1.44 struct passwd local_pwd;
275 char buf[PWD_BUFF_SIZE];
|
276 mike 1.2
|
277 kumpf 1.13 if (getpwuid_r(geteuid(), &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
|
278 mike 1.2 {
|
279 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
280 kumpf 1.44 "getpwuid_r failure: %s", strerror(errno)));
|
281 mike 1.2 }
|
282 kumpf 1.44 else if (pwd == NULL)
|
283 mike 1.2 {
|
284 marek 1.51 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
285 kumpf 1.44 "getpwuid_r failure; user may have been removed");
|
286 mike 1.2 }
287 else
288 {
289 //
290 // get the user name
291 //
292 userName.assign(pwd->pw_name);
293 }
294
|
295 ouyang.jian 1.61 # if defined(PEGASUS_OS_PASE)
296 userName.toUpper();
297 # endif
298
|
299 kumpf 1.13 return userName;
|
300 kumpf 1.44 #endif
|
301 mike 1.2 }
302
303 Boolean System::isSystemUser(const char* userName)
304 {
305 const unsigned int PWD_BUFF_SIZE = 1024;
306 struct passwd pwd;
307 struct passwd *result;
308 char pwdBuffer[PWD_BUFF_SIZE];
309
310 if (getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
311 {
|
312 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
313 kumpf 1.44 "getpwnam_r failure: %s", strerror(errno)));
|
314 mike 1.2 }
315
|
316 kumpf 1.44 return (result != NULL);
|
317 mike 1.2 }
318
|
319 kumpf 1.44 static String _privilegedUserName;
320 static Once _privilegedUserNameOnce = PEGASUS_ONCE_INITIALIZER;
|
321 mike 1.2
322 static void _initPrivilegedUserName()
323 {
324 struct passwd* pwd = NULL;
325 const unsigned int PWD_BUFF_SIZE = 1024;
326 struct passwd local_pwd;
327 char buf[PWD_BUFF_SIZE];
|
328 carson.hovey 1.35 PEGASUS_UID_T uid;
|
329 mike 1.2
|
330 carson.hovey 1.35 #if defined(PEGASUS_OS_VMS)
331 // 65540 = 10004 hex = [1,4] the UIC for [SYSTEM] on OpenVMS
332 uid = 0x10004;
333 #else
334 uid = 0;
335 #endif
|
336 kumpf 1.44
|
337 carson.hovey 1.35 if (getpwuid_r(uid, &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
|
338 mike 1.2 {
|
339 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
340 kumpf 1.44 "getpwuid_r failure: %s", strerror(errno)));
|
341 mike 1.2 }
|
342 kumpf 1.44 else if (pwd == NULL)
|
343 mike 1.2 {
|
344 kumpf 1.44 PEG_TRACE_CSTRING(
|
345 marek 1.51 TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
346 kumpf 1.44 "getpwuid_r: Could not find entry.");
347 PEGASUS_ASSERT(0);
|
348 mike 1.2 }
349 else
350 {
|
351 kumpf 1.44 _privilegedUserName.assign(pwd->pw_name);
|
352 ouyang.jian 1.61 #if defined(PEGASUS_OS_PASE)
353 _privilegedUserName.toUpper();
354 #endif
|
355 mike 1.2 }
356 }
357
358 String System::getPrivilegedUserName()
359 {
|
360 kumpf 1.44 once(&_privilegedUserNameOnce, _initPrivilegedUserName);
361 return _privilegedUserName;
|
362 mike 1.2 }
363
364 Boolean System::lookupUserId(
365 const char* userName,
366 PEGASUS_UID_T& uid,
367 PEGASUS_GID_T& gid)
368 {
|
369 ouyang.jian 1.46 #if defined(PEGASUS_OS_PASE)
370 if (!umeLookupUserProfile(userName))
371 {
|
372 marek 1.51 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
373 ouyang.jian 1.46 "umeLookupUserProfile failed.");
374 return false;
375 }
376 return true;
377 #else
|
378 mike 1.2 const unsigned int PWD_BUFF_SIZE = 1024;
379 struct passwd pwd;
380 struct passwd *result;
381 char pwdBuffer[PWD_BUFF_SIZE];
382
383 int rc = getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result);
384
385 if (rc != 0)
386 {
|
387 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
388 "getpwnam_r failure: %s", strerror(errno)));
|
389 mike 1.2 return false;
390 }
391
392 if (result == 0)
393 {
|
394 marek 1.51 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
395 mike 1.2 "getpwnam_r failed.");
396 return false;
397 }
398
399 uid = pwd.pw_uid;
400 gid = pwd.pw_gid;
401
402 return true;
|
403 ouyang.jian 1.46 #endif
|
404 mike 1.2 }
405
|
406 kumpf 1.22 Boolean System::changeUserContext_SingleThreaded(
407 const char* userName,
|
408 mike 1.2 const PEGASUS_UID_T& uid,
409 const PEGASUS_GID_T& gid)
410 {
|
411 ouyang.jian 1.46 #if defined(PEGASUS_OS_PASE)
412 char required_ph[12];
413
414 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL4,
415 "Changing user context to: username = %s", userName));
416
417 if (!umeGetUserProfile(userName, required_ph))
418 return false;
419
420 if (!umeSwapUserProfile(required_ph))
421 return false;
422
423 umeReleaseUserProfile(required_ph);
424 return true;
425 #else
|
426 marek 1.19 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL4,
|
427 kumpf 1.22 "Changing user context to: username = %s, uid = %d, gid = %d",
428 userName, (int)uid, (int)gid));
|
429 mike 1.2
430 if (setgid(gid) != 0)
431 {
|
432 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
433 "setgid failed: %s",strerror(errno)));
|
434 mike 1.2 return false;
435 }
436
|
437 ouyang.jian 1.46 # if !defined(PEGASUS_OS_VMS)
|
438 kumpf 1.22 // NOTE: initgroups() uses non-reentrant functions and should only be
439 // called from a single-threaded process.
440 if (initgroups(userName, gid) != 0)
441 {
|
442 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
443 "initgroups failed: %s", strerror(errno)));
|
444 kumpf 1.22 return false;
445 }
|
446 ouyang.jian 1.46 # endif
|
447 kumpf 1.22
|
448 mike 1.2 if (setuid(uid) != 0)
449 {
|
450 marek 1.51 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
451 "setuid failed: %s", strerror(errno)));
|
452 mike 1.2 return false;
453 }
454
455 return true;
|
456 ouyang.jian 1.46 #endif
|
457 mike 1.2 }
458
459 Uint32 System::getPID()
460 {
461 return getpid();
462 }
463
464 Boolean System::truncateFile(
465 const char* path,
466 size_t newSize)
467 {
468 return (truncate(path, newSize) == 0);
469 }
470
471 Boolean System::is_absolute_path(const char *path)
472 {
473 if (path == NULL)
474 return false;
475
476 if (path[0] == '/')
477 return true;
478 mike 1.2
479 return false;
480 }
481
482 Boolean System::changeFilePermissions(const char* path, mode_t mode)
483 {
|
484 kumpf 1.50 return chmod(path, mode) == 0;
|
485 mike 1.2 }
486
487 Boolean System::verifyFileOwnership(const char* path)
488 {
489 struct stat st;
|
490 kumpf 1.65
|
491 mike 1.2 if (lstat(path, &st) != 0)
492 return false;
493
494 return ((st.st_uid == geteuid()) && // Verify the file owner
495 S_ISREG(st.st_mode) && // Verify it is a regular file
496 (st.st_nlink == 1)); // Verify it is not a hard link
497 }
498
499 void System::syslog(const String& ident, Uint32 severity, const char* message)
500 {
|
501 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
502 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX))
|
503 mike 1.2
504 // Since the openlog(), syslog(), and closelog() function calls must be
505 // coordinated (see below), we need a thread control.
506
507 static Mutex logMutex;
508
509 AutoMutex loglock(logMutex);
510
511 // Get a const char* representation of the identifier string. Note: The
512 // character string passed to the openlog() function must persist until
513 // closelog() is called. The syslog() method uses this pointer directly
514 // rather than a copy of the string it refers to.
515
516 CString identCString = ident.getCString();
517 openlog(identCString, LOG_PID, LOG_DAEMON);
518
519 // Map from the Logger log level to the system log level.
520
521 Uint32 syslogLevel;
522 if (severity & Logger::FATAL)
523 {
524 mike 1.2 syslogLevel = LOG_CRIT;
525 }
526 else if (severity & Logger::SEVERE)
527 {
528 syslogLevel = LOG_ERR;
529 }
530 else if (severity & Logger::WARNING)
531 {
532 syslogLevel = LOG_WARNING;
533 }
534 else if (severity & Logger::INFORMATION)
535 {
536 syslogLevel = LOG_INFO;
537 }
538 else // if (severity & Logger::TRACE)
539 {
540 syslogLevel = LOG_DEBUG;
541 }
542
543 // Write the message to the system log.
544
545 mike 1.2 ::syslog(syslogLevel, "%s", message);
546
547 closelog();
548
|
549 thilo.boehm 1.11 #elif defined(PEGASUS_OS_ZOS) && defined(PEGASUS_USE_SYSLOGS)
|
550 marek 1.14 #define ZOS_MSGID_LENGTH 11
|
551 r.kieninger 1.8
|
552 marek 1.14 char* zosMessageString;
553 Uint32 messageLength = strlen(message);
554 Uint32 syslogLevel = LOG_DEBUG;
555 const char* zos_msgid;
|
556 r.kieninger 1.9
|
557 marek 1.14 // determine syslog level and create zos_msgid string
|
558 r.kieninger 1.9 if ((severity & Logger::SEVERE) || (severity & Logger::FATAL) )
559 {
560 syslogLevel = LOG_ERR;
561 zos_msgid = "CFZ00004E: ";
562 }
563 else if (severity & Logger::WARNING)
564 {
565 syslogLevel = LOG_WARNING;
566 zos_msgid = "CFZ00002W: ";
567 }
568 else if (severity & Logger::INFORMATION)
569 {
570 syslogLevel = LOG_INFO;
571 zos_msgid = "CFZ00001I: ";
572 }
573 else
574 {
575 syslogLevel = LOG_DEBUG;
576 zos_msgid = "CFZ00001I: ";
577 }
|
578 r.kieninger 1.8
|
579 marek 1.14 // we cut at 4000 characters
580 // leaving room for 11 additional message characters
|
581 martin 1.63 //
|
582 marek 1.14 if (messageLength > 4000)
583 messageLength = 4000;
584
585 // reserve memory for the message string, also prepend
586 // z/OS message id CFZ* if necessary
|
587 r.kieninger 1.47 if ((strncmp(message, "CFZ", 3) != 0) &&
588 (strncmp(message, "CEZ", 3) != 0) )
|
589 r.kieninger 1.8 {
|
590 marek 1.14 // reserve message + 11 char message prepend + 1 byte for \0 char
591 zosMessageString = (char*) malloc(messageLength+ZOS_MSGID_LENGTH+1);
592 memcpy(zosMessageString, zos_msgid, ZOS_MSGID_LENGTH);
593 memcpy(zosMessageString+ZOS_MSGID_LENGTH, message, messageLength);
594 messageLength+=ZOS_MSGID_LENGTH;
595 } else
|
596 marek 1.12 {
|
597 marek 1.14 zosMessageString = (char*) malloc(messageLength+1);
598 memcpy(zosMessageString, message, messageLength);
|
599 marek 1.12 }
|
600 marek 1.14 // terminate with a null character
601 zosMessageString[messageLength]='\0';
|
602 marek 1.12
|
603 marek 1.14 // write first to syslog, __console changes the content of
604 // message string
605 ::syslog(syslogLevel, "%s", zosMessageString);
|
606 kumpf 1.65
|
607 marek 1.12 CString identCString = ident.getCString();
|
608 r.kieninger 1.8 // Issue important messages to the z/OS console
|
609 marek 1.14 // audit messages will go to a different syslog like place
|
610 kumpf 1.13 if (!(severity & Logger::TRACE) &&
|
611 marek 1.12 !(strcmp("cimserver audit",identCString) == 0))
|
612 r.kieninger 1.8 {
613 struct __cons_msg cons;
614 int concmd=0;
|
615 kumpf 1.65
|
616 r.kieninger 1.8 memset(&cons,0,sizeof(cons));
|
617 marek 1.14 cons.__format.__f1.__msg_length = messageLength;
618 cons.__format.__f1.__msg = zosMessageString;
619 __console(&cons, NULL, &concmd);
|
620 r.kieninger 1.8 }
|
621 marek 1.14 free(zosMessageString);
|
622 r.kieninger 1.8
|
623 mike 1.2 #else /* default */
624
625 // Not implemented!
626
627 #endif /* default */
628 }
629
|
630 marek 1.12 void System::openlog(const char *ident, int logopt, int facility)
631 {
632
|
633 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
634 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || \
635 defined(PEGASUS_OS_ZOS))
|
636 marek 1.12 ::openlog(ident, logopt, facility);
637 #else /* default */
638
639 // Not implemented!
640
641 #endif /* default */
642
643 }
644
645 void System::closelog()
646 {
647
|
648 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
649 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || \
650 defined(PEGASUS_OS_ZOS))
|
651 marek 1.12 ::closelog();
652 #else /* default */
653
654 // Not implemented!
655
656 #endif /* default */
657
658 }
659
660
|
661 marek 1.10 // check if a given IP address is defined on the local network interfaces
662 Boolean System::isIpOnNetworkInterface(Uint32 inIP)
663 {
664 // Function compares all IP addresses defined on
665 // local network interface with a given IP address
|
666 kumpf 1.27 #define PEGASUS_MAX_NETWORK_INTERFACES 32
|
667 marek 1.10 struct ifconf conf;
668
|
669 kumpf 1.13 conf.ifc_buf =
670 (char *)calloc(PEGASUS_MAX_NETWORK_INTERFACES, sizeof(struct ifreq));
671 conf.ifc_len = PEGASUS_MAX_NETWORK_INTERFACES * sizeof(struct ifreq);
672
|
673 marek 1.59 int sd=socket(AF_INET, SOCK_DGRAM, 0);
674 int rc = ioctl(sd, SIOCGIFCONF, &conf);
675 close(sd);
676 if (-1 < rc)
|
677 kumpf 1.13 {
678 struct ifreq* r = conf.ifc_req;
|
679 kumpf 1.15 sockaddr_in* addr;
680 addr = reinterpret_cast<struct sockaddr_in*>(&r->ifr_addr);
|
681 kumpf 1.13 while (addr->sin_addr.s_addr != 0)
682 {
683 Uint32 ip = addr->sin_addr.s_addr;
684 if (ip == inIP)
685 {
686 free(conf.ifc_buf);
687 return true;
688 }
689 // next interface
690 r++;
|
691 kumpf 1.15 addr = reinterpret_cast<struct sockaddr_in*>(&r->ifr_addr);
|
692 kumpf 1.13 }
|
693 marek 1.10 }
694 free(conf.ifc_buf);
695 return false;
696 }
697
|
698 marek 1.79 #if defined(PEGASUS_OS_ZOS)
|
699 thilo.boehm 1.41 String System::getErrorMSG_NLS(int errorCode,int errorCode2)
700 {
701
702 char buf[10];
703
704 sprintf(buf,"%08X",errorCode2);
705
706 MessageLoaderParms parms(
707 "Common.System.ERROR_MESSAGE.PEGASUS_OS_ZOS",
708 "$0 (error code $1, reason code 0x$2)",
709 strerror(errorCode),errorCode,buf);
710
|
711 marek 1.79 return MessageLoader::getMessage(parms);
|
712 thilo.boehm 1.41 }
713
714 String System::getErrorMSG(int errorCode,int errorCode2)
715 {
716
717 String buffer;
718
719 char strErrorCode[32];
720 sprintf(strErrorCode, "%d", errorCode);
721
722 buffer.append(strerror(errorCode));
723 buffer.append(" (error code ");
724 buffer.append(strErrorCode);
725
726 char strErrorCode2[10];
727 sprintf(strErrorCode2,"%08X",errorCode2);
728 buffer.append(", reason code 0x");
729 buffer.append(strErrorCode2);
|
730 marek 1.79 buffer.append(")");
731
732 return buffer;
733 }
734 #else
735
736 String System::getErrorMSG_NLS(int errorCode,int)
737 {
738 MessageLoaderParms parms(
739 "Common.System.ERROR_MESSAGE.STANDARD",
740 "$0 (error code $1)",strerror(errorCode),errorCode);
741 return MessageLoader::getMessage(parms);
742 }
743 String System::getErrorMSG(int errorCode,int)
744 {
745
746 String buffer;
747
748 char strErrorCode[32];
749 sprintf(strErrorCode, "%d", errorCode);
|
750 thilo.boehm 1.41
|
751 marek 1.79 buffer.append(strerror(errorCode));
752 buffer.append(" (error code ");
753 buffer.append(strErrorCode);
|
754 thilo.boehm 1.41 buffer.append(")");
755
756 return buffer;
757 }
|
758 marek 1.79 #endif
759
760
|
761 thilo.boehm 1.41
762
|
763 kumpf 1.6
764 ///////////////////////////////////////////////////////////////////////////////
765 // AutoFileLock class
766 ///////////////////////////////////////////////////////////////////////////////
767
768 AutoFileLock::AutoFileLock(const char* fileName)
769 {
770 #ifdef PEGASUS_OS_TYPE_UNIX
771 _fl.l_type = F_WRLCK;
772 _fl.l_whence = SEEK_SET;
773 _fl.l_start = 0;
774 _fl.l_len = 0;
775 _fl.l_pid = getpid();
776
777 do
778 {
779 _fd = open(fileName, O_WRONLY);
780 } while ((_fd == -1) && (errno == EINTR));
781
782 if (_fd != -1)
783 {
784 kumpf 1.6 int rc;
785
786 do
787 {
788 rc = fcntl(_fd, F_SETLKW, &_fl);
789 } while ((rc == -1) && (errno == EINTR));
790
791 if (rc == -1)
792 {
|
793 marek 1.51 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
794 kumpf 1.6 "AutoFileLock: Failed to lock file '%s', error code %d.",
|
795 marek 1.19 fileName, errno));
|
796 kumpf 1.6 _fd = -1;
797 }
798 }
799 else
800 {
|
801 marek 1.51 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
802 kumpf 1.6 "AutoFileLock: Failed to open lock file '%s', error code %d.",
|
803 marek 1.19 fileName, errno));
|
804 kumpf 1.6 }
805 #endif
806 }
807
808 AutoFileLock::~AutoFileLock()
809 {
810 #ifdef PEGASUS_OS_TYPE_UNIX
811 if (_fd != -1)
812 {
813 _fl.l_type = F_UNLCK;
814 int rc = fcntl(_fd, F_SETLK, &_fl);
815 if (rc == -1)
816 {
|
817 marek 1.51 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
818 kumpf 1.6 "AutoFileLock: Failed to unlock file, error code %d.",
|
819 marek 1.19 errno));
|
820 kumpf 1.6 }
821 close(_fd);
822 }
823 #endif
824 }
825
|
826 ouyang.jian 1.53 #if defined(PEGASUS_OS_PASE)
827 class PaseSystemInitializer
828 {
829 public:
830 PaseSystemInitializer()
831 {
832 putenv("XPG_SUS_ENV=ON");
833 };
834 };
835
836 static PaseSystemInitializer initializer;
837 #endif
|
838 kumpf 1.6
|
839 mike 1.2 //==============================================================================
840 //
|
841 ouyang.jian 1.53 // PEGASUS_OS_AIX
|
842 mike 1.2 //
843 //==============================================================================
844
845 // System Initializater for AIX
|
846 ouyang.jian 1.53 #if defined(PEGASUS_OS_AIX)
|
847 mike 1.2 # include <cstdlib>
848
849 class SystemInitializer
850 {
851
852 public:
853 /**
854 *
855 * Default constructor.
856 *
857 */
858 SystemInitializer();
859 };
860
861 SystemInitializer::SystemInitializer()
862 {
863 putenv("XPG_SUS_ENV=ON");
864 }
865
866 static SystemInitializer initializer;
867
|
868 s.kodali 1.52 #include <sys/ioctl.h>
869 #include <net/if.h>
870 #define AIX_MAX(x,y) ((x) > (y) ? (x) : (y))
871 #define AIX_SIZE(p) AIX_MAX((p).sa_len, sizeof(p))
872
|
873 mike 1.2 #endif /* PEGASUS_OS_AIX */
874
|
875 venkat.puvvada 1.37 Array<String> System::getInterfaceAddrs()
876 {
877 Array<String> ips;
878
879
|
880 venkat.puvvada 1.42 #if defined(PEGASUS_HAS_GETIFADDRS)
|
881 venkat.puvvada 1.37 struct ifaddrs *array, *addrs;
882 char buff[PEGASUS_INET6_ADDRSTR_LEN];
883
884 if (0 > getifaddrs(&array))
885 {
886 return ips;
887 }
|
888 venkat.puvvada 1.56 Boolean ipFound;
|
889 venkat.puvvada 1.37 for( addrs = array; addrs != NULL; addrs = addrs->ifa_next)
890 {
|
891 venkat.puvvada 1.56 ipFound = false;
|
892 venkat.puvvada 1.73
893 if (addrs->ifa_addr == NULL || (addrs->ifa_flags & IFF_LOOPBACK) ||
894 (addrs->ifa_flags & IFF_UP) == 0)
|
895 kamal.locahana 1.71 {
896 continue;
897 }
|
898 venkat.puvvada 1.73
|
899 venkat.puvvada 1.37 switch(addrs->ifa_addr->sa_family)
900 {
901 case AF_INET :
|
902 dev.meetei 1.75 if( !System::getNameInfo(addrs->ifa_addr,
|
903 dev.meetei 1.74 sizeof(struct sockaddr_in),
|
904 dev.meetei 1.75 buff, sizeof(buff), NULL, 0, NI_NUMERICHOST))
|
905 dev.meetei 1.74 {
906 ipFound = true;
907 }
|
908 venkat.puvvada 1.37 break;
|
909 dev.meetei 1.75
|
910 dev.meetei 1.74 #ifdef PEGASUS_ENABLE_IPV6
|
911 venkat.puvvada 1.37 case AF_INET6 :
|
912 dev.meetei 1.75 if( !System::getNameInfo(addrs->ifa_addr,
|
913 dev.meetei 1.74 sizeof(struct sockaddr_in6),
|
914 dev.meetei 1.75 buff, sizeof(buff), NULL, 0, NI_NUMERICHOST))
|
915 dev.meetei 1.74 {
916 ipFound = true;
917 }
|
918 venkat.puvvada 1.37 break;
|
919 dev.meetei 1.74 #endif
|
920 venkat.puvvada 1.37 }
|
921 dev.meetei 1.74
|
922 venkat.puvvada 1.56 if (ipFound)
923 {
|
924 dev.meetei 1.74 ips.append(buff);
|
925 venkat.puvvada 1.56 }
|
926 venkat.puvvada 1.37 }
927 if(array)
928 {
929 freeifaddrs(array);
930 }
931 #elif defined(PEGASUS_OS_AIX)
|
932 s.kodali 1.52 struct ifconf ifc;
|
933 marek 1.60 SocketHandle sd=socket(AF_INET6, SOCK_DGRAM, 0);
934 // Use an AutoPtr to ensure the socket handle is closed on exception
935 AutoPtr<SocketHandle, CloseSocketHandle> sockPtr(&sd);
|
936 s.kodali 1.52 int bsz=sizeof(struct ifreq);
937 int prevsz=bsz;
938 ifc.ifc_req=0;
939 ifc.ifc_len=bsz;
940 do
941 {
|
942 dl.meetei 1.81 ifc.ifc_req=(struct ifreq *)peg_inln_realloc(ifc.ifc_req, bsz);
|
943 s.kodali 1.52 if (!ifc.ifc_req)
944 {
945 return ips;
946 }
947 ifc.ifc_len=bsz;
948 if (ioctl(sd, SIOCGIFCONF, (caddr_t)&ifc) == -1)
949 {
950 free(ifc.ifc_req);
951 return ips;
952 }
953 if (prevsz==ifc.ifc_len)
954 {
955 break;
956 }
957 else
958 {
959 bsz*=2;
960 prevsz=(0==ifc.ifc_len ? bsz : ifc.ifc_len);
961 }
962 } while (1);
963
|
964 dl.meetei 1.81 ifc.ifc_req=(struct ifreq *)peg_inln_realloc(ifc.ifc_req, prevsz);
|
965 s.kodali 1.52
966 struct sockaddr *sa;
|
967 dev.meetei 1.76 char *cp, *cplim, buff[PEGASUS_INET6_ADDRSTR_LEN];
|
968 s.kodali 1.52 struct ifreq *ifr=ifc.ifc_req;
969 cp=(char *)ifc.ifc_req;
970 cplim=cp+ifc.ifc_len;
|
971 dev.meetei 1.76 for (; cp < cplim; cp += (sizeof(ifr->ifr_name) + AIX_SIZE(ifr->ifr_addr)))
|
972 s.kodali 1.52 {
|
973 dev.meetei 1.76 ifr = (struct ifreq *)cp;
974 sa = (struct sockaddr *)&(ifr->ifr_addr);
|
975 s.kodali 1.52 switch(sa->sa_family)
976 {
977 case AF_INET:
978 if (System::isLoopBack(
979 AF_INET, &(((struct sockaddr_in *)sa)->sin_addr)))
980 {
981 break;
982 }
|
983 dev.meetei 1.77 if( !System::getNameInfo((const struct sockaddr *)sa,
|
984 dev.meetei 1.76 sizeof(struct sockaddr_in),
985 buff, sizeof(buff), NULL, 0, NI_NUMERICHOST))
986 {
987 ips.append(buff);
988 }
|
989 s.kodali 1.52 break;
|
990 dev.meetei 1.74 #ifdef PEGASUS_ENABLE_IPV6
|
991 s.kodali 1.52 case AF_INET6:
992 if (System::isLoopBack(
993 AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr)))
994 {
995 break;
996 }
|
997 dev.meetei 1.77 if( !System::getNameInfo((const struct sockaddr *)sa,
|
998 dev.meetei 1.76 sizeof(struct sockaddr_in6),
999 buff, sizeof(buff), NULL, 0, NI_NUMERICHOST))
1000 {
1001 ips.append(buff);
1002 }
|
1003 s.kodali 1.52 break;
|
1004 dev.meetei 1.74 #endif
|
1005 s.kodali 1.52 }
1006 }
1007 free(ifc.ifc_req);
1008
|
1009 venkat.puvvada 1.37 #elif defined(PEGASUS_OS_ZOS)
|
1010 kumpf 1.65
|
1011 dev.meetei 1.74 #ifdef PEGASUS_ENABLE_IPV6
|
1012 thilo.boehm 1.64 SocketHandle sdV6=socket(AF_INET6, SOCK_DGRAM, 0);
1013 // Use an AutoPtr to ensure the socket handle is closed on exception
1014 AutoPtr<SocketHandle, CloseSocketHandle> sockV6Ptr(&sdV6);
1015
1016 if (sdV6 != PEGASUS_INVALID_SOCKET)
1017 {
1018 __net_ifconf6header_t ifConfHeader;
1019 __net_ifconf6entry_t *pifConfEntries;
1020 char buff[PEGASUS_INET6_ADDRSTR_LEN];
|
1021 kumpf 1.65
|
1022 thilo.boehm 1.64 // clera the ifconf header
1023 memset(&ifConfHeader,0,sizeof(__net_ifconf6header_t));
1024 // fill the ifconf header with the current values
1025 if (-1 != ioctl(sdV6, SIOCGIFCONF6, &ifConfHeader))
1026 {
1027 // allocate the buffer for the interface entries
1028 ifConfHeader.__nif6h_buffer=
1029 (char *)calloc(ifConfHeader.__nif6h_entries,
1030 ifConfHeader.__nif6h_entrylen);
1031
1032 // Prevent memory leak on exception
1033 AutoPtr<char,FreeCharPtr>
1034 ifConfInfV6Ptr( ifConfHeader.__nif6h_buffer );
1035
1036 // set the sitze of the buffer for the interface entries.
1037 ifConfHeader.__nif6h_buflen= ifConfHeader.__nif6h_entries *
1038 ifConfHeader.__nif6h_entrylen;
1039
1040 // get the interface entries.
1041 if (-1 != ioctl(sdV6, SIOCGIFCONF6, &ifConfHeader))
1042 {
1043 thilo.boehm 1.64 pifConfEntries=
1044 (__net_ifconf6entry_t *)ifConfHeader.__nif6h_buffer;
1045
1046 // loop throug the interface entries.
1047 for (int i = 0 ; i < ifConfHeader.__nif6h_entries; i++)
1048 {
1049 // do not save loop back addresses.
|
1050 thilo.boehm 1.78 if (System::isLoopBack(
|
1051 kumpf 1.65 AF_INET6,
|
1052 thilo.boehm 1.64 &(pifConfEntries[i].__nif6e_addr.sin6_addr)))
|
1053 thilo.boehm 1.78 {
1054 continue;
1055 }
1056
1057 HostAddress::convertBinaryToText(
1058 AF_INET6,
1059 &(pifConfEntries[i].__nif6e_addr.sin6_addr),
1060 buff,
1061 sizeof(buff));
1062 String ip6addr(buff);
1063
1064 if(String::equalNoCase(ip6addr.subString(0,4), "fe80"))
|
1065 thilo.boehm 1.64 {
|
1066 thilo.boehm 1.78 __etoa_l(
1067 pifConfEntries[i].__nif6e_name,
1068 sizeof(pifConfEntries->__nif6e_name));
1069 String zoneidx(
1070 pifConfEntries[i].__nif6e_name,
1071 sizeof(pifConfEntries->__nif6e_name));
1072 zoneidx.remove(zoneidx.find(' '));
1073 ip6addr.append("%");
1074 ip6addr.append(zoneidx);
1075 }
1076
1077 ips.append(ip6addr); // append IPV6 addresses
|
1078 thilo.boehm 1.64 } // loop through deliverd interfaces
1079 } // query IPV6 interface
1080 } // fill ifconf header structure
|
1081 kumpf 1.65 } // create IPV6 socket
|
1082 dev.meetei 1.74 #endif
|
1083 thilo.boehm 1.64
1084 // create an IPV4 socket to get the interface configurations via ioclt()
1085 SocketHandle sdv4=socket(AF_INET, SOCK_DGRAM, 0);
1086 // Use an AutoPtr to ensure the socket handle is closed on exception
1087 AutoPtr<SocketHandle, CloseSocketHandle> sockV4Ptr(&sdv4);
1088
1089 if (sdv4 != PEGASUS_INVALID_SOCKET)
1090 {
1091 struct ifconf ifc;
1092 char buff[PEGASUS_INET_ADDRSTR_LEN];
1093 // On z/OS the interface the maximal number of interface
1094 // structures is 100. To avoid memory fragmentation,
1095 // the value of 128 is used.
1096 ifc.ifc_buf=(char *)calloc(128, sizeof(struct ifreq));
1097 ifc.ifc_len=128 * sizeof(struct ifreq);
1098
1099 // Prevent memory leak on exception
1100 AutoPtr<char,FreeCharPtr> ifConfInfV4Ptr( ifc.ifc_buf );
1101
1102 // query for the IPV4 addresses.
1103 if (-1 < ioctl(sdv4, SIOCGIFCONF, &ifc) )
1104 thilo.boehm 1.64 {
1105 // calcutate the numer of V4 interfaces
1106 int noInterFace = ifc.ifc_len/sizeof(struct ifreq);
1107
1108 sockaddr_in* addr;
1109
1110 for (int i = 0; i < noInterFace; i++)
1111 {
1112 addr = (sockaddr_in *)&ifc.ifc_req[i].ifr_addr;
1113 if (!System::isLoopBack( AF_INET, &(addr->sin_addr.s_addr)))
1114 {
|
1115 thilo.boehm 1.78 HostAddress::convertBinaryToText(
1116 AF_INET,
1117 &(addr->sin_addr.s_addr),
1118 buff,
1119 PEGASUS_INET_ADDRSTR_LEN);
1120 ips.append(buff);
|
1121 thilo.boehm 1.64 }
1122 }
1123 }
1124 }
|
1125 ouyang.jian 1.66 #elif defined(PEGASUS_OS_PASE)
1126 addrinfo hints;
1127 addrinfo *info = NULL;
1128
1129 memset(&hints, 0, sizeof(hints));
1130 hints.ai_family = AF_UNSPEC;
1131 hints.ai_socktype = SOCK_STREAM;
1132 hints.ai_flags = AI_V4MAPPED | AI_ALL;
1133 hints.ai_protocol = IPPROTO_TCP;
1134
|
1135 dev.meetei 1.75 int ret = 0;
1136 ret = System::getAddrInfo(System::getHostName().getCString(),
|
1137 ouyang.jian 1.66 NULL, &hints, &info);
1138 if (ret != 0)
1139 {
1140 if (info != NULL)
1141 {
1142 freeaddrinfo(info);
1143 info = NULL;
1144 }
1145 return ips;
1146 }
1147 PEGASUS_ASSERT(info != NULL);
1148
1149 addrinfo *ai;
1150 for (ai = info; ai != NULL; ai = ai->ai_next)
1151 {
1152 if (ai->ai_family == AF_INET6)
1153 {
|
1154 dev.meetei 1.74 #ifdef PEGASUS_ENABLE_IPV6
|
1155 dev.meetei 1.76 char ipAddr[PEGASUS_INET6_ADDRSTR_LEN];
|
1156 ouyang.jian 1.66 struct sockaddr_in6 sockaddr6;
1157 struct sockaddr_in6 *in6 = (sockaddr_in6 *) (ai->ai_addr);
1158
|
1159 dev.meetei 1.76 memset(&sockaddr6, 0, sizeof(sockaddr_in6));
|
1160 ouyang.jian 1.66 sockaddr6.sin6_family = AF_INET6;
1161 sockaddr6.sin6_flowinfo = 0;
1162 sockaddr6.sin6_scope_id = 0;
1163 memcpy(&sockaddr6.sin6_addr,
1164 &(in6->sin6_addr),
1165 sizeof(struct in6_addr));
|
1166 dev.meetei 1.77 if( !System::getNameInfo((const struct sockaddr *)&sockaddr6 ,
|
1167 dev.meetei 1.76 sizeof(struct sockaddr_in6),
1168 ipAddr, sizeof(ipAddr), NULL, 0, NI_NUMERICHOST))
|
1169 ouyang.jian 1.66 {
|
1170 dev.meetei 1.76 ips.append(ipAddr);
|
1171 ouyang.jian 1.66 }
|
1172 dev.meetei 1.74 #endif
|
1173 ouyang.jian 1.66 }
1174 else if (ai->ai_family == AF_INET)
1175 {
|
1176 dev.meetei 1.76 char ipAddr[PEGASUS_INET_ADDRSTR_LEN];
|
1177 ouyang.jian 1.66 struct sockaddr_in sockaddr4;
1178 struct sockaddr_in *in4 = (sockaddr_in *) (ai->ai_addr);
1179
1180 memset(&sockaddr4, 0, sizeof(sockaddr4));
1181 sockaddr4.sin_family = AF_INET;
1182
1183 memcpy(&sockaddr4.sin_addr,
1184 &(in4->sin_addr),
1185 sizeof(struct in_addr));
|
1186 dev.meetei 1.77 if( !System::getNameInfo((const struct sockaddr *)&sockaddr4,
|
1187 dev.meetei 1.76 sizeof(struct sockaddr_in),
1188 ipAddr, sizeof(ipAddr), NULL, 0, NI_NUMERICHOST))
|
1189 ouyang.jian 1.66 {
|
1190 dev.meetei 1.76 ips.append(ipAddr);
|
1191 ouyang.jian 1.66 }
1192 }
1193 }
1194 freeaddrinfo(info);
1195
|
1196 venkat.puvvada 1.37 #elif defined(PEGASUS_OS_HPUX)
1197 //ATTN: implement for HPUX
1198 #elif defined(PEGASUS_OS_VMS)
1199 //ATTN: implement for VMS
1200 #else
1201 //ATTN: implement for rest of UNIX flavors.
1202 #endif
1203
1204 return ips;
1205 }
1206
|
1207 thilo.boehm 1.41
|
1208 mike 1.2 PEGASUS_NAMESPACE_END
|