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