1 mike 1.32 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
14 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 //==============================================================================
22 mike 1.32 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
25 // Modified By: Mike Day (mdday@us.ibm.com)
|
26 mike 1.33 //
|
27 mike 1.32 // Modified By: Karl Schopmeyer (k.schopmeyer@opengroup.org)
28 //
|
29 mike 1.35 // Modified By: Nag Boranna (nagaraja_boranna@hp.com)
30 //
31 // Modified By: Jenny Yu (jenny_yu@hp.com)
32 //
|
33 mike 1.32 //%/////////////////////////////////////////////////////////////////////////////
34
35
36 //////////////////////////////////////////////////////////////////////
37 //
38 // Notes on deamon operation (Unix) and service operation (Win 32):
39 //
40 // To run pegasus as a daemon on Unix platforms, use the -d option:
41 //
42 // cimserver -d
43 //
44 // The -d option has no effect on windows operation.
45 //
|
46 mike 1.35 // To shutdown pegasus, use the -s option:
47 //
48 // cimserver -s [-f] [-T timeout_value]
49 //
|
50 mike 1.32 // To run pegasus as an NT service, there are FOUR different possibilities:
51 //
52 // To INSTALL the Pegasus service,
53 //
54 // cimserver -install
55 //
56 // To REMOVE the Pegasus service,
57 //
58 // cimserver -remove
59 //
60 // To START the Pegasus service,
61 //
62 // net start cimserver
63 //
64 // To STOP the Pegasus service,
65 //
66 // net stop cimserver
67 //
68 // Alternatively, you can use the windows service manager. Pegasus shows up
69 // in the service database as "Pegasus CIM Object Manager"
70 //
71 mike 1.32 // Mike Day, mdday@us.ibm.com
72 //
73 //////////////////////////////////////////////////////////////////////
74
75
|
76 mike 1.35 #include <Pegasus/Common/Config.h>
|
77 mike 1.32 #include <iostream>
|
78 mike 1.35 #include <cassert>
|
79 mike 1.32 #include <cstdlib>
80 #include <Pegasus/Common/FileSystem.h>
|
81 mike 1.35 #include <Pegasus/Common/Monitor.h>
|
82 mike 1.32 #include <Pegasus/Server/CIMServer.h>
83 #include <Pegasus/Common/PegasusVersion.h>
84 #include <Pegasus/Protocol/Handler.h>
85 #include <Pegasus/Common/Logger.h>
86 #include <Pegasus/Common/System.h>
|
87 mike 1.35 #include <Pegasus/Common/Tracer.h>
88 #include <Pegasus/Config/ConfigManager.h>
89 #include <Pegasus/Client/CIMClient.h>
90 #include <Pegasus/Common/HTTPConnector.h>
91 #include <Pegasus/Server/ShutdownService.h>
92 #ifndef PEGASUS_OS_ZOS
|
93 mike 1.32 #include <slp/slp.h>
|
94 mike 1.35 #endif
|
95 mike 1.32
96
97 #if defined(PEGASUS_OS_TYPE_WINDOWS)
98 # include "cimserver_windows.cpp"
99 #elif defined(PEGASUS_OS_TYPE_UNIX)
100 # include "cimserver_unix.cpp"
101 #else
102 # error "Unsupported platform"
103 #endif
104
105 PEGASUS_USING_PEGASUS;
106 PEGASUS_USING_STD;
107
|
108 mike 1.35 //
109 // The command name.
110 //
111 static const char COMMAND_NAME [] = "cimserver";
112
113 //
114 // The constant defining usage string.
115 //
116 static const char USAGE [] = "Usage: ";
117
118 /**
119 Constants representing the command line options.
120 */
121 static const char OPTION_VERSION = 'v';
122
123 static const char OPTION_HELP = 'h';
124
125 static const char OPTION_HOME = 'D';
126
127 static const char OPTION_SHUTDOWN = 's';
128
129 mike 1.35 static const char OPTION_FORCE = 'f';
130
131 static const char OPTION_TIMEOUT = 'T';
132
133 static const String NAMESPACE = "root/cimv2";
134 static const String CLASSNAME_SHUTDOWNSERVICE = "PG_ShutdownService";
135 static const String PROPERTY_TIMEOUT = "timeout";
136
137 ConfigManager* configManager;
138
|
139 mike 1.32 void GetEnvironmentVariables(
140 const char* arg0,
141 String& pegasusHome)
142 {
143 // Get environment variables:
144
145 const char* tmp = getenv("PEGASUS_HOME");
146
147 if (!tmp)
148 {
149 cerr << arg0 << ": PEGASUS_HOME environment variable undefined" << endl;
150 exit(1);
151 }
152
153 pegasusHome = tmp;
154 FileSystem::translateSlashes(pegasusHome);
155 }
156
|
157 mike 1.35 void SetEnvironmentVariables(
158 const char* arg0)
159 {
160 cout << "PEGASUS_HOME is now " << arg0 << endl;
161
162 String str = "PEGASUS_HOME=";
163 str += arg0;
164 char* tmp = str.allocateCString();
165 putenv(tmp);
166
167 // Note: don't delete tmp! putenv() uses it.
168 }
169
|
170 mike 1.32 /** GetOptions function - This function defines the Options Table
|
171 mike 1.35 and sets up the options from that table using the config manager.
|
172 mike 1.32 */
173 void GetOptions(
|
174 mike 1.35 ConfigManager* cm,
|
175 mike 1.32 int& argc,
176 char** argv,
177 const String& pegasusHome)
178 {
|
179 mike 1.35 String currentFile = pegasusHome + "/" + CURRENT_CONFIG_FILE;
180 String plannedFile = pegasusHome + "/" + PLANNED_CONFIG_FILE;
181
182 try
|
183 mike 1.32 {
|
184 mike 1.35 cm->mergeConfigFiles(currentFile, plannedFile);
|
185 mike 1.33
|
186 mike 1.35 cm->mergeCommandLine(argc, argv);
187 }
188 catch (NoSuchFile nsf)
189 {
190 throw nsf;
191 }
192 catch (FileNotReadable fnr)
193 {
194 throw fnr;
195 }
196 catch (CannotRenameFile ftrf)
197 {
198 throw ftrf;
199 }
200 catch (ConfigFileSyntaxError cfse)
201 {
202 throw cfse;
203 }
204 catch(UnrecognizedConfigProperty ucp)
205 {
206 throw ucp;
207 mike 1.35 }
208 catch(InvalidPropertyValue ipv)
209 {
210 throw ipv;
211 }
|
212 mike 1.32 }
213
214 /* PrintHelp - This is temporary until we expand the options manager to allow
215 options help to be defined with the OptionRow entries and presented from
216 those entries.
217 */
218 void PrintHelp(const char* arg0)
219 {
|
220 mike 1.35 /**
221 Build the usage string for the config command.
222 */
223 String usage = String (USAGE);
224 usage.append (COMMAND_NAME);
225 usage.append (" [ [ options ] | [ configProperty=value, ... ] ]\n");
226 usage.append (" options\n");
227 usage.append (" -v - displays pegasus version number\n");
228 usage.append (" -h - prints this help message\n");
229 usage.append (" -D [home] - sets pegasus home directory\n");
230 usage.append (" -t - turns tracing on\n");
231 usage.append (" -t - turns on trace of client IO to console\n");
232 usage.append (" -l - turns on trace of client IO to trace file\n");
233 usage.append (" -d - runs pegasus as a daemon\n");
234 usage.append (" -s [-f] [-T timeout] \n");
235 usage.append (" - shuts down pegasus\n");
236 usage.append (" -cleanlogs - clears the log files at startup\n");
237 usage.append (" -install - installs pegasus as a Windows NT Service\n");
238 usage.append (" -remove - removes pegasus as a Windows NT Service\n");
239 usage.append (" -slp - registers pegasus as a service with SLP\n\n");
240 usage.append (" -SSL - uses SSL\n\n");
241 mike 1.35
242 usage.append (" configProperty=value\n");
243 usage.append (" port=nnnn - sets port number to listen on\n");
244 usage.append (" home=/pegasus/bin - sets pegasus home directory\n");
245 usage.append (" logdir=/pegasus/logs - directory for log files\n");
246
247 cout << endl;
|
248 mike 1.32 cout << PEGASUS_NAME << PEGASUS_VERSION << endl;
249 cout << endl;
|
250 mike 1.35 cout << usage << endl;
251 }
252
253 void shutdownCIMOM(Boolean forceOption, String timeoutStr)
254 {
255 //
256 // Create CIMClient object
257 //
258 Monitor* monitor = new Monitor;
259 HTTPConnector* httpConnector = new HTTPConnector(monitor);
260 CIMClient client(monitor, httpConnector);
261
262 //
263 // Get the port number
264 //
265 String portNumberStr = configManager->getCurrentValue("port");
266
267 String hostStr = System::getHostName();
268 hostStr.append(":");
269 hostStr.append(portNumberStr);
270
271 mike 1.35 //
272 // open connection to CIMOM
273 //
274 try
275 {
276 client.connect(hostStr.allocateCString());
277 }
278 catch(Exception& e)
279 {
280 PEGASUS_STD(cerr) << "Failed to connect to server: " << e.getMessage() << PEGASUS_STD(endl);
281 exit(1);
282 }
283
284 try
285 {
286 //
287 // construct CIMReference
288 //
289 String referenceStr = "//";
290 referenceStr.append(hostStr);
291 referenceStr.append("/root/cimv2:PG_ShutdownService");
292 mike 1.35 CIMReference reference(referenceStr);
293
294 //
295 // issue the invokeMethod request on the shutdown method
296 //
297 Array<CIMParamValue> inParams;
298 Array<CIMParamValue> outParams;
299
300 if (forceOption)
301 {
302 inParams.append(CIMParamValue(
303 CIMParameter("force", CIMType::STRING),
304 CIMValue("TRUE")));
305 }
306 else
307 {
308 inParams.append(CIMParamValue(
309 CIMParameter("force", CIMType::STRING),
310 CIMValue("FALSE")));
311 }
312
313 mike 1.35 inParams.append(CIMParamValue(
314 CIMParameter("timeout", CIMType::STRING),
315 CIMValue(timeoutStr)));
316
317 CIMValue retValue = client.invokeMethod(
318 NAMESPACE,
319 reference,
320 "shutdown",
321 inParams,
322 outParams);
323 }
324 catch(Exception& e)
325 {
326 PEGASUS_STD(cerr) << "Failed to shutdown server: " << e.getMessage() << PEGASUS_STD(endl);
327 exit(1);
328 }
329
330 return;
|
331 mike 1.32 }
332
|
333 mike 1.35
|
334 mike 1.33 /////////////////////////////////////////////////////////////////////////
|
335 mike 1.32 // MAIN
336 //////////////////////////////////////////////////////////////////////////
337 int main(int argc, char** argv)
338 {
|
339 mike 1.35 String pegasusHome = String::EMPTY;
340 Boolean pegasusIOTrace = false;
341 Boolean pegasusIOLog = false;
342 String portOption = String::EMPTY;
343 String logsDirectory = String::EMPTY;
344 Boolean useSLP = false;
345 Boolean useSSL = false;
346 Boolean daemonOption = false;
347 Boolean shutdownOption = false;
348 Boolean forceOption = false;
349 Boolean timeoutOption = false;
350 String timeoutStr = String::EMPTY;
351 long timeoutValue = 0;
352
|
353 mike 1.32 // on Windows NT if there are no command-line options, run as a service
354
355 if (argc == 1 )
|
356 mike 1.35 {
357 cim_server_service(argc, argv);
358 }
359 else
360 {
361 // Get help, version and home options
362
363 for (int i = 1; i < argc; )
364 {
365 const char* arg = argv[i];
366
367 // Check for -option
368 if (*arg == '-')
369 {
370 // Get the option
371 const char* option = arg + 1;
372
373 //
374 // Check to see if user asked for the version (-v option):
375 //
376 if (*option == OPTION_VERSION)
377 mike 1.35 {
378 cout << PEGASUS_VERSION << endl;
379 exit(0);
380 }
381 //
382 // Check to see if user asked for help (-h option):
383 //
384 else if (*option == OPTION_HELP)
385 {
386 PrintHelp(argv[0]);
387 exit(0);
388 }
389 else if (*option == OPTION_HOME)
390 {
391 if (i + 1 < argc)
392 {
393 pegasusHome.assign(argv[i + 1]);
394 SetEnvironmentVariables(argv[i + 1]);
395 }
396 else
397 {
398 mike 1.35 cout << "Missing argument for option -" << option << endl;
399 exit(0);
400 }
401
402 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
403 argc -= 2;
404 }
405 //
406 // Check to see if user asked for shutdown (-s option):
407 //
408 else if (*option == OPTION_SHUTDOWN)
409 {
410 //
411 // Check to see if shutdown has already been specified:
412 //
413 if (shutdownOption)
414 {
415 cout << "Duplicate shutdown option specified." << endl;
416 exit(0);
417 }
418 shutdownOption = true;
419 mike 1.35
420 // remove the option from the command line
421 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
422 argc--;
423 }
424 else if (*option == OPTION_FORCE)
425 {
426 //
427 // Check to see if shutdown has been specified:
428 //
429 if (!shutdownOption)
430 {
431 cout << "Invalid option -" << option << endl;
432 exit(0);
433 }
434
435 //
436 // Check to see if force has already been specified:
437 //
438 if (forceOption)
439 {
440 mike 1.35 cout << "Duplicate force option specified." << endl;
441 exit(0);
442 }
443
444 forceOption = true;
445
446 // remove the option from the command line
447 memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
448 argc--;
449 }
450 else if (*option == OPTION_TIMEOUT)
451 {
452 //
453 // Check to see if shutdown has been specified:
454 //
455 if (!shutdownOption)
456 {
457 cout << "Invalid option -" << option << endl;
458 exit(0);
459 }
460
461 mike 1.35 if (timeoutOption)
462 {
463 cout << "Duplicate timeout option specified." << endl;
464 exit(0);
465 }
466
467 timeoutOption = true;
468
469 if (i + 1 < argc)
470 {
471 // get timeout value
472 timeoutStr.assign(argv[i + 1]);
473
474 // validate timeout value string
475 char* tmp = timeoutStr.allocateCString();
476 char* end = 0;
477 timeoutValue = strtol(tmp, &end, 10);
478
479 if (!end || *end != '\0')
480 {
481 cout << "invalid timeout value specified: ";
482 mike 1.35 cout << timeoutStr << endl;
483 delete [] tmp;
484 exit(0);
485 }
486 }
487 else
488 {
489 cout << "Missing argument for option -";
490 cout << option << endl;
491 exit(0);
492 }
493
494 // remove the option from the command line
495 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
496 argc -= 2;
497 }
498 else
499 i++;
500 }
501 else
502 i++;
|
503 mike 1.32 }
504 }
|
505 mike 1.35
|
506 mike 1.32 if (pegasusHome.size() == 0)
507 GetEnvironmentVariables(argv[0], pegasusHome);
508
|
509 mike 1.35 //
510 // Get an instance of the Config Manager.
511 //
512 configManager = ConfigManager::getInstance();
513
514 //
|
515 mike 1.32 // Get options (from command line and from configuration file); this
|
516 mike 1.35 // removes corresponding options and their arguments from the command
|
517 mike 1.32 // line.
|
518 mike 1.35 //
|
519 mike 1.32 try
520 {
|
521 mike 1.35 GetOptions(configManager, argc, argv, pegasusHome);
|
522 mike 1.32 }
523 catch (Exception& e)
524 {
|
525 mike 1.35 cerr << argv[0] << ": " << e.getMessage() << endl;
526 exit(1);
|
527 mike 1.32 }
528
529
|
530 mike 1.35 try
|
531 mike 1.32 {
|
532 mike 1.35 //
533 // Check to see if we should (can) install as a NT service
534 //
535
536 if (String::equal(configManager->getCurrentValue("install"), "true"))
537 {
538 if( 0 != cimserver_install_nt_service( pegasusHome ))
539 {
540 cout << "\nPegasus installed as NT Service";
541 exit(0);
542 }
543 }
|
544 mike 1.32
|
545 mike 1.35 //
546 // Check to see if we should (can) remove Pegasus as an NT service
547 //
548
549 if (String::equal(configManager->getCurrentValue("remove"), "true"))
550 {
551 if( 0 != cimserver_remove_nt_service() )
552 {
553 cout << "\nPegasus removed as NT Service";
554 exit(0);
555 }
556 }
|
557 mike 1.32
|
558 mike 1.35 //
559 // Check to see if we should Pegasus as a daemon
560 //
561
562 if (String::equal(configManager->getCurrentValue("daemon"), "true"))
563 {
564 daemonOption = true;
565 }
|
566 mike 1.32
|
567 mike 1.35 //
568 // Check to see if we need to shutdown CIMOM
569 //
570 if (shutdownOption)
571 {
572 //
573 // if timeout was specified, validate the timeout value
574 //
575 if (timeoutOption)
576 {
577 Boolean valid = configManager->validatePropertyValue(
578 PROPERTY_TIMEOUT,
579 timeoutStr);
580 if (!valid)
581 {
582 cout << "Invalid timeout value specified: " << timeoutValue;
583 cout << endl;
584 exit(1);
585 }
586 }
587
588 mike 1.35 shutdownCIMOM(forceOption, timeoutStr);
589 cout << "Pegasus CIM Server terminated." << endl;
590 exit(0);
591 }
|
592 mike 1.32
|
593 mike 1.35 //
594 // Grab the port option:
595 //
596
597 portOption = configManager->getCurrentValue("port");
598
599 //
600 // Check the trace options and set global variable
601 //
602
603 if (String::equal(configManager->getCurrentValue("trace"), "true"))
604 {
605 Handler::setMessageTrace(true);
606 pegasusIOTrace = true;
607 cout << "Trace Set" << endl;
608 }
609 //
610 // Check the log trace options and set global variable
611 //
612
613 if (String::equal(configManager->getCurrentValue("logtrace"), "true"))
614 mike 1.35 {
615 Handler::setMessageLogTrace(true);
616 pegasusIOLog = true;
617 }
|
618 mike 1.32
|
619 mike 1.35 // Get the log file directory definition.
620 // We put String into Cstring because
621 // Directory functions only handle Cstring.
622 // ATTN-KS: create String based directory functions.
623
624 logsDirectory = configManager->getCurrentValue("logdir");
625
626 // Set up the Logger. This does not open the logs
627 // Might be more logical to clean before set.
628 // ATTN: Need tool to completely disable logging.
629
630 Logger::setHomeDirectory(logsDirectory);
631
632 if (String::equal(configManager->getCurrentValue("cleanlogs"), "true"))
633 {
634 Logger::clean(logsDirectory);;
635 }
|
636 mike 1.32
|
637 mike 1.35 // Leave this in until people get familiar with the logs.
638 cout << "Logs Directory = " << logsDirectory << endl;
|
639 mike 1.32
|
640 mike 1.35 if (String::equal(configManager->getCurrentValue("slp"), "true"))
641 {
642 useSLP = true;
643 }
|
644 mike 1.32
|
645 mike 1.35 if (String::equal(configManager->getCurrentValue("SSL"), "true"))
646 {
647 useSSL = true;
648 }
|
649 mike 1.32 }
|
650 mike 1.35 catch (UnrecognizedConfigProperty e)
|
651 mike 1.32 {
|
652 mike 1.35 cout << "Error: " << e.getMessage() << endl;
|
653 mike 1.32 }
654
655 char* address = portOption.allocateCString();
656
657 // Put out startup up message.
658 cout << PEGASUS_NAME << PEGASUS_VERSION <<
659 " on port " << address << endl;
660 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
661 cout <<"Started..."
662 << (pegasusIOTrace ? " Tracing to Display ": " ")
663 << (pegasusIOLog ? " Tracing to Log ": " ")
664 << (useSLP ? " SLP reg. " : " No SLP ")
|
665 mike 1.35 << (useSSL ? " Use SSL " : " No SSL ")
|
666 mike 1.32 << endl;
667
668 // Put server start message to the logger
669 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
|
670 mike 1.35 "Start $0 $1 port $2 $3 $4 $5",
|
671 mike 1.32 PEGASUS_NAME,
672 PEGASUS_VERSION,
673 address,
674 (pegasusIOTrace ? " Tracing": " "),
|
675 mike 1.35 (useSLP ? " SLP on " : " SLP off "),
676 (useSSL ? " Use SSL " : " No SSL "));
|
677 mike 1.32
|
678 mike 1.35 // do we need to run as a daemon ?
679 if (daemonOption)
680 {
681 if(-1 == cimserver_fork())
682 exit(-1);
683 }
|
684 mike 1.32
685 // try loop to bind the address, and run the server
686 try
687 {
|
688 mike 1.35 #ifndef PEGASUS_OS_ZOS
|
689 mike 1.32 slp_client *discovery = new slp_client() ;;
690 String serviceURL;
691 serviceURL.assign("service:cim.pegasus://");
692 String host_name = slp_get_host_name();
693 serviceURL += host_name;
694 serviceURL += ":";
695 serviceURL += address;
696 char *url = serviceURL.allocateCString();
697 // free(host_name);
|
698 mike 1.35 #endif
|
699 mike 1.32
|
700 mike 1.35 Monitor monitor;
701 CIMServer server(&monitor, pegasusHome, useSSL);
702
|
703 mike 1.32 // bind throws an exception of the bind fails
|
704 mike 1.33 cout << "Binding to " << address << endl;
|
705 mike 1.35
706 char* end = 0;
707 long portNumber = strtol(address, &end, 10);
708 assert(end != 0 && *end == '\0');
709 server.bind(portNumber);
710
|
711 mike 1.32 delete [] address;
712
713 time_t last = 0;
|
714 mike 1.35
715 //
716 // Loop to call CIMServer's runForever() method until CIMServer
717 // has been shutdown
718 //
719 while( !server.terminated() )
|
720 mike 1.32 {
|
721 mike 1.35 #ifndef PEGASUS_OS_ZOS
|
722 mike 1.32 if(useSLP )
723 {
724 if( (time(NULL) - last ) > 60 )
725 {
726 if( discovery != NULL && url != NULL )
727 discovery->srv_reg_all(url,
|
728 mike 1.35 "(namespace=root/cimv2)",
|
729 mike 1.32 "service:cim.pegasus",
730 "DEFAULT",
731 70) ;
732 time(&last);
733 }
734
735 discovery->service_listener();
736 }
|
737 mike 1.35 #endif
|
738 mike 1.32 server.runForever();
739 }
740
|
741 mike 1.34 // This statement is unrechable!
742 //
743 // Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
744 // "Normal Termination");
|
745 mike 1.32 }
746 catch(Exception& e)
747 {
748 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
749 "Abnormal Termination $0", e.getMessage());
750
751 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
752 }
753
754 return 0;
755 }
|