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 kumpf 1.34.2.1 // Modified By: Nag Boranna (nagaraja_boranna@hp.com)
30 //
|
31 mike 1.32 //%/////////////////////////////////////////////////////////////////////////////
32
33
34 //////////////////////////////////////////////////////////////////////
35 //
36 // Notes on deamon operation (Unix) and service operation (Win 32):
37 //
38 // To run pegasus as a daemon on Unix platforms, use the -d option:
39 //
40 // cimserver -d
41 //
42 // The -d option has no effect on windows operation.
43 //
44 // To run pegasus as an NT service, there are FOUR different possibilities:
45 //
46 // To INSTALL the Pegasus service,
47 //
48 // cimserver -install
49 //
50 // To REMOVE the Pegasus service,
51 //
52 mike 1.32 // cimserver -remove
53 //
54 // To START the Pegasus service,
55 //
56 // net start cimserver
57 //
58 // To STOP the Pegasus service,
59 //
60 // net stop cimserver
61 //
62 // Alternatively, you can use the windows service manager. Pegasus shows up
63 // in the service database as "Pegasus CIM Object Manager"
64 //
65 // Mike Day, mdday@us.ibm.com
66 //
67 //////////////////////////////////////////////////////////////////////
68
69
70 #include <iostream>
|
71 sage 1.34.2.9 #include <cassert>
|
72 mike 1.32 #include <cstdlib>
73 #include <Pegasus/Common/FileSystem.h>
|
74 mike 1.34.2.5 #include <Pegasus/Common/Monitor.h>
|
75 mike 1.32 #include <Pegasus/Server/CIMServer.h>
76 #include <Pegasus/Common/PegasusVersion.h>
77 #include <Pegasus/Protocol/Handler.h>
78 #include <Pegasus/Common/Logger.h>
79 #include <Pegasus/Common/System.h>
|
80 kumpf 1.34.2.1 #include <Pegasus/Common/Tracer.h>
81 #include <Pegasus/Config/ConfigManager.h>
|
82 sage 1.34.2.9 #ifndef PEGASUS_OS_ZOS
|
83 mike 1.32 #include <slp/slp.h>
|
84 sage 1.34.2.9 #endif
|
85 mike 1.32
86
87 #if defined(PEGASUS_OS_TYPE_WINDOWS)
88 # include "cimserver_windows.cpp"
89 #elif defined(PEGASUS_OS_TYPE_UNIX)
90 # include "cimserver_unix.cpp"
91 #else
92 # error "Unsupported platform"
93 #endif
94
95 PEGASUS_USING_PEGASUS;
96 PEGASUS_USING_STD;
97
|
98 kumpf 1.34.2.4 //
99 // The command name.
100 //
|
101 kumpf 1.34.2.1 static const char COMMAND_NAME [] = "cimserver";
102
|
103 kumpf 1.34.2.4 //
104 // The constant defining usage string.
105 //
106 static const char USAGE [] = "Usage: ";
107
|
108 kumpf 1.34.2.1 /**
|
109 kumpf 1.34.2.4 Constants representing the command line options.
|
110 kumpf 1.34.2.1 */
|
111 kumpf 1.34.2.4 static const char OPTION_VERSION = 'v';
112
113 static const char OPTION_HELP = 'h';
114
115 static const char OPTION_HOME = 'D';
116
|
117 kumpf 1.34.2.1
118
|
119 mike 1.32 void GetEnvironmentVariables(
120 const char* arg0,
121 String& pegasusHome)
122 {
123 // Get environment variables:
124
125 const char* tmp = getenv("PEGASUS_HOME");
126
127 if (!tmp)
128 {
129 cerr << arg0 << ": PEGASUS_HOME environment variable undefined" << endl;
130 exit(1);
131 }
132
133 pegasusHome = tmp;
134 FileSystem::translateSlashes(pegasusHome);
135 }
136
|
137 sage 1.34.2.6 void SetEnvironmentVariables(
138 const char* arg0)
139 {
140 cout << "PEGASUS_HOME is now " << arg0 << endl;
|
141 mike 1.34.2.7
142 String str = "PEGASUS_HOME=";
143 str += arg0;
144 char* tmp = str.allocateCString();
145 putenv(tmp);
146
|
147 mike 1.34.2.8 // Note: don't delete tmp! putenv() uses it.
|
148 sage 1.34.2.6 }
149
|
150 mike 1.32 /** GetOptions function - This function defines the Options Table
|
151 kumpf 1.34.2.1 and sets up the options from that table using the config manager.
|
152 mike 1.32 */
153 void GetOptions(
|
154 kumpf 1.34.2.1 ConfigManager* cm,
|
155 mike 1.32 int& argc,
156 char** argv,
157 const String& pegasusHome)
158 {
|
159 kumpf 1.34.2.1 String currentFile = pegasusHome + "/" + CURRENT_CONFIG_FILE;
160 String plannedFile = pegasusHome + "/" + PLANNED_CONFIG_FILE;
161
162 try
|
163 mike 1.32 {
|
164 kumpf 1.34.2.1 cm->mergeConfigFiles(currentFile, plannedFile);
|
165 mike 1.32
|
166 kumpf 1.34.2.1 cm->mergeCommandLine(argc, argv);
167 }
168 catch (NoSuchFile nsf)
169 {
170 throw nsf;
171 }
172 catch (FileNotReadable fnr)
173 {
174 throw fnr;
175 }
176 catch (CannotRenameFile ftrf)
177 {
178 throw ftrf;
179 }
180 catch (ConfigFileSyntaxError cfse)
181 {
182 throw cfse;
183 }
|
184 kumpf 1.34.2.4 catch(UnrecognizedConfigProperty ucp)
185 {
186 throw ucp;
187 }
188 catch(InvalidPropertyValue ipv)
189 {
190 throw ipv;
191 }
|
192 mike 1.32 }
193
194 /* PrintHelp - This is temporary until we expand the options manager to allow
195 options help to be defined with the OptionRow entries and presented from
196 those entries.
197 */
198 void PrintHelp(const char* arg0)
199 {
|
200 kumpf 1.34.2.1 /**
201 Build the usage string for the config command.
202 */
203 String usage = String (USAGE);
204 usage.append (COMMAND_NAME);
205 usage.append (" [ [ options ] | [ configProperty=value, ... ] ]\n");
206 usage.append (" options\n");
|
207 kumpf 1.34.2.4 usage.append (" -v - displays pegasus version number\n");
208 usage.append (" -h - prints this help message\n");
|
209 sage 1.34.2.6 usage.append (" -D [home] - sets pegasus home directory\n");
|
210 kumpf 1.34.2.4 usage.append (" -t - turns tracing on\n");
211 usage.append (" -t - turns on trace of client IO to console\n");
212 usage.append (" -l - turns on trace of client IO to trace file\n");
213 usage.append (" -d - runs pegasus as a daemon\n");
214 usage.append (" -cleanlogs - clears the log files at startup\n");
215 usage.append (" -install - installs pegasus as a Windows NT Service\n");
216 usage.append (" -remove - removes pegasus as a Windows NT Service\n");
217 usage.append (" -slp - registers pegasus as a service with SLP\n\n");
218
219 usage.append (" configProperty=value\n");
220 usage.append (" port=nnnn - sets port number to listen on\n");
221 usage.append (" home=/pegasus/bin - sets pegasus home directory\n");
222 usage.append (" logdir=/pegasus/logs - directory for log files\n");
|
223 kumpf 1.34.2.1
224 cout << endl;
|
225 mike 1.32 cout << PEGASUS_NAME << PEGASUS_VERSION << endl;
226 cout << endl;
|
227 kumpf 1.34.2.1 cout << usage << endl;
|
228 mike 1.32 }
229
|
230 mike 1.33 /////////////////////////////////////////////////////////////////////////
|
231 mike 1.32 // MAIN
232 //////////////////////////////////////////////////////////////////////////
233 int main(int argc, char** argv)
234 {
|
235 kumpf 1.34.2.1 String pegasusHome = String::EMPTY;
236 Boolean pegasusIOTrace = false;
237 Boolean pegasusIOLog = false;
238 String portOption = String::EMPTY;
239 String logsDirectory = String::EMPTY;
240 Boolean useSLP = false;
241 Boolean daemonOption = false;
242
|
243 mike 1.32 // on Windows NT if there are no command-line options, run as a service
244
245 if (argc == 1 )
246 cim_server_service(argc, argv) ;
247
|
248 kumpf 1.34.2.4 // Get help, version and home options
|
249 mike 1.32
|
250 kumpf 1.34.2.4 for (int i = 0; i < argc; )
251 {
252 const char* arg = argv[i];
253
254 // Check for -option
255 if (*arg == '-')
256 {
257 // Get the option
258 const char* option = arg + 1;
259
260 //
261 // Check to see if user asked for the version (-v option):
262 //
263 if (*option == OPTION_VERSION)
264 {
265 cout << PEGASUS_VERSION << endl;
266 exit(0);
267 }
268 //
269 // Check to see if user asked for help (-h option):
270 //
271 kumpf 1.34.2.4 else if (*option == OPTION_HELP)
272 {
273 PrintHelp(argv[0]);
274 exit(0);
275 }
276 else if (*option == OPTION_HOME)
277 {
278 if (i + 1 < argc)
279 {
|
280 sage 1.34.2.6 pegasusHome.assign(argv[i + 1]);
281 SetEnvironmentVariables(argv[i + 1]);
|
282 kumpf 1.34.2.4 }
283 else
284 {
285 cout << "Missing argument for option -" << option << endl;
286 exit(0);
287 }
288
289 memmove(&argv[i], &argv[i + 2], (argc-i-1) * sizeof(char*));
290 argc -= 2;
291 }
|
292 mike 1.32 }
|
293 kumpf 1.34.2.4 i++;
|
294 mike 1.32 }
|
295 kumpf 1.34.2.4
|
296 mike 1.32 if (pegasusHome.size() == 0)
297 GetEnvironmentVariables(argv[0], pegasusHome);
298
|
299 kumpf 1.34.2.1 //
300 // Get an instance of the Config Manager.
301 //
|
302 mike 1.34.2.3 ConfigManager* configManager = ConfigManager::getInstance();
|
303 mike 1.32
|
304 kumpf 1.34.2.1 //
305 // Get options (from command line and from configuration file); this
|
306 kumpf 1.34.2.4 // removes corresponding options and their arguments from the command
|
307 kumpf 1.34.2.1 // line.
308 //
|
309 mike 1.32 try
310 {
|
311 kumpf 1.34.2.1 GetOptions(configManager, argc, argv, pegasusHome);
|
312 mike 1.32 }
313 catch (Exception& e)
314 {
|
315 kumpf 1.34.2.1 cerr << argv[0] << ": " << e.getMessage() << endl;
316 exit(1);
|
317 mike 1.32 }
318
319
|
320 kumpf 1.34.2.1 try
321 {
322 //
323 // Check to see if we should (can) install as a NT service
324 //
325
|
326 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("install"), "true"))
|
327 kumpf 1.34.2.1 {
328 if( 0 != cimserver_install_nt_service( pegasusHome ))
329 {
330 cout << "\nPegasus installed as NT Service";
331 exit(0);
332 }
333 }
|
334 mike 1.32
|
335 kumpf 1.34.2.1 //
336 // Check to see if we should (can) remove Pegasus as an NT service
337 //
338
|
339 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("remove"), "true"))
|
340 kumpf 1.34.2.1 {
341 if( 0 != cimserver_remove_nt_service() )
342 {
343 cout << "\nPegasus removed as NT Service";
344 exit(0);
345 }
346 }
|
347 mike 1.32
|
348 kumpf 1.34.2.1 //
349 // Check to see if we should Pegasus as a daemon
350 //
351
|
352 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("daemon"), "true"))
|
353 kumpf 1.34.2.1 {
354 daemonOption = true;
355 }
|
356 mike 1.32
|
357 kumpf 1.34.2.1 //
358 // Grab the port option:
359 //
360
361 portOption = configManager->getCurrentValue("port");
362
363 //
364 // Check the trace options and set global variable
365 //
366
|
367 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("trace"), "true"))
|
368 kumpf 1.34.2.1 {
369 Handler::setMessageTrace(true);
370 pegasusIOTrace = true;
371 cout << "Trace Set" << endl;
372 }
373 //
374 // Check the log trace options and set global variable
375 //
376
|
377 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("logtrace"), "true"))
|
378 kumpf 1.34.2.1 {
379 Handler::setMessageLogTrace(true);
380 pegasusIOLog = true;
381 }
|
382 mike 1.32
|
383 kumpf 1.34.2.1 // Get the log file directory definition.
384 // We put String into Cstring because
385 // Directory functions only handle Cstring.
386 // ATTN-KS: create String based directory functions.
387
388 logsDirectory = configManager->getCurrentValue("logdir");
389
390 // Set up the Logger. This does not open the logs
391 // Might be more logical to clean before set.
392 // ATTN: Need tool to completely disable logging.
|
393 kumpf 1.34.2.4
|
394 kumpf 1.34.2.1 Logger::setHomeDirectory(logsDirectory);
395
|
396 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("cleanlogs"), "true"))
|
397 kumpf 1.34.2.1 {
398 Logger::clean(logsDirectory);;
399 }
|
400 mike 1.32
|
401 kumpf 1.34.2.1 // Leave this in until people get familiar with the logs.
402 cout << "Logs Directory = " << logsDirectory << endl;
|
403 mike 1.32
|
404 kumpf 1.34.2.4 if (String::equal(configManager->getCurrentValue("slp"), "true"))
|
405 kumpf 1.34.2.1 {
406 useSLP = true;
407 }
|
408 mike 1.32 }
|
409 kumpf 1.34.2.1 catch (UnrecognizedConfigProperty e)
|
410 mike 1.32 {
|
411 kumpf 1.34.2.1 cout << "Error: " << e.getMessage() << endl;
|
412 mike 1.32 }
413
414 char* address = portOption.allocateCString();
415
416 // Put out startup up message.
417 cout << PEGASUS_NAME << PEGASUS_VERSION <<
418 " on port " << address << endl;
419 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
420 cout <<"Started..."
421 << (pegasusIOTrace ? " Tracing to Display ": " ")
422 << (pegasusIOLog ? " Tracing to Log ": " ")
423 << (useSLP ? " SLP reg. " : " No SLP ")
424 << endl;
425
426 // Put server start message to the logger
427 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
428 "Start $0 $1 port $2 $3 $4",
429 PEGASUS_NAME,
430 PEGASUS_VERSION,
431 address,
432 (pegasusIOTrace ? " Tracing": " "),
433 mike 1.32 (useSLP ? " SLP on " : " SLP off "));
434
|
435 kumpf 1.34.2.1 // do we need to run as a daemon ?
436 if (daemonOption)
437 {
438 if(-1 == cimserver_fork())
439 exit(-1);
440 }
|
441 mike 1.32
442 // try loop to bind the address, and run the server
443 try
444 {
|
445 sage 1.34.2.9 #ifndef PEGASUS_OS_ZOS
|
446 mike 1.32 slp_client *discovery = new slp_client() ;;
447 String serviceURL;
448 serviceURL.assign("service:cim.pegasus://");
449 String host_name = slp_get_host_name();
450 serviceURL += host_name;
451 serviceURL += ":";
452 serviceURL += address;
453 char *url = serviceURL.allocateCString();
454 // free(host_name);
|
455 sage 1.34.2.9 #endif
|
456 mike 1.32
|
457 mike 1.34.2.5 Monitor monitor;
458 CIMServer server(&monitor, pegasusHome);
|
459 mike 1.32
460 // bind throws an exception of the bind fails
|
461 mike 1.33 cout << "Binding to " << address << endl;
|
462 mike 1.34.2.5
463 char* end = 0;
464 long portNumber = strtol(address, &end, 10);
465 assert(end != 0 && *end == '\0');
466 server.bind(portNumber);
467
|
468 mike 1.32 delete [] address;
469
470 time_t last = 0;
471 while( 1 )
472 {
|
473 sage 1.34.2.9 #ifndef PEGASUS_OS_ZOS
|
474 mike 1.32 if(useSLP )
475 {
476 if( (time(NULL) - last ) > 60 )
477 {
478 if( discovery != NULL && url != NULL )
479 discovery->srv_reg_all(url,
|
480 kumpf 1.34.2.4 "(namespace=root/cimv2)",
|
481 mike 1.32 "service:cim.pegasus",
482 "DEFAULT",
483 70) ;
484 time(&last);
485 }
486
487 discovery->service_listener();
488 }
|
489 sage 1.34.2.9 #endif
|
490 mike 1.32 server.runForever();
491 }
492
|
493 mike 1.34 // This statement is unrechable!
494 //
495 // Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
496 // "Normal Termination");
|
497 mike 1.32 }
498 catch(Exception& e)
499 {
500 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
501 "Abnormal Termination $0", e.getMessage());
502
503 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
504 }
505
506 return 0;
507 }
|