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