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