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 kumpf 1.34.2.2 if (pegasusHome.size() == 0)
|
210 mike 1.32 for (int i=0; i < argc; i++) {
211 if (!strcmp(argv[i],"-D")) {
212 i++;
213 if (i < argc) pegasusHome = argv[i];
214 break;
215 }
216 }
217 if (pegasusHome.size() == 0)
218 GetEnvironmentVariables(argv[0], pegasusHome);
219
220 // Get options (from command line and from configuration file); this
|
221 kumpf 1.34.2.1 // removes corresponding options and their arguments from the command
|
222 mike 1.32 // line.
223
|
224 kumpf 1.34.2.1 //
225 // Get an instance of the Config Manager.
226 //
227 ConfigManager* configManager;
228
229 configManager = ConfigManager::getInstance();
|
230 mike 1.32
|
231 kumpf 1.34.2.1 //
232 // Get options (from command line and from configuration file); this
233 // removes corresponding options and their arguments fromt he command
234 // line.
235 //
|
236 mike 1.32 try
237 {
|
238 kumpf 1.34.2.1 GetOptions(configManager, argc, argv, pegasusHome);
|
239 mike 1.32 }
240 catch (Exception& e)
241 {
|
242 kumpf 1.34.2.1 cerr << argv[0] << ": " << e.getMessage() << endl;
243 exit(1);
|
244 mike 1.32 }
245
246 // At this point, all options should have been extracted; print an
247 // error if there are any remaining:
248
249 if (argc != 1)
250 {
251 cerr << argv[0] << ": unrecognized options: ";
252
253 for (int i = 1; i < argc; i++)
254 cerr << argv[i] << ' ';
255 cout << endl;
256 exit(1);
257 }
258
|
259 kumpf 1.34.2.1 try
260 {
261 //
262 // Check to see if user asked for the version (-v option):
263 //
264
265 if (configManager->isVersionFlagSet())
266 {
267 cout << PEGASUS_VERSION << endl;
268 exit(0);
269 }
|
270 mike 1.32
|
271 kumpf 1.34.2.1 //
272 // Check to see if user asked for help (-h option):
273 //
274
275 if (configManager->isHelpFlagSet())
276 {
277 PrintHelp(argv[0]);
278 exit(0);
279 }
|
280 mike 1.32
|
281 kumpf 1.34.2.1 //
282 // Check to see if we should (can) install as a NT service
283 //
284
|
285 kumpf 1.34.2.2 if (configManager->isInstallFlagSet())
|
286 kumpf 1.34.2.1 {
287 if( 0 != cimserver_install_nt_service( pegasusHome ))
288 {
289 cout << "\nPegasus installed as NT Service";
290 exit(0);
291 }
292 }
|
293 mike 1.32
|
294 kumpf 1.34.2.1 //
295 // Check to see if we should (can) remove Pegasus as an NT service
296 //
297
|
298 kumpf 1.34.2.2 if (configManager->isRemoveFlagSet())
|
299 kumpf 1.34.2.1 {
300 if( 0 != cimserver_remove_nt_service() )
301 {
302 cout << "\nPegasus removed as NT Service";
303 exit(0);
304 }
305 }
|
306 mike 1.32
|
307 kumpf 1.34.2.1 //
308 // Check to see if we should Pegasus as a daemon
309 //
310
|
311 kumpf 1.34.2.2 if (configManager->isDaemonFlagSet())
|
312 kumpf 1.34.2.1 {
313 daemonOption = true;
314 }
|
315 mike 1.32
|
316 kumpf 1.34.2.1 //
317 // Grab the port option:
318 //
319
320 portOption = configManager->getCurrentValue("port");
321
322 //
323 // Check the trace options and set global variable
324 //
325
326 if (configManager->isTraceFlagSet())
327 {
328 Handler::setMessageTrace(true);
329 pegasusIOTrace = true;
330 cout << "Trace Set" << endl;
331 }
332 //
333 // Check the log trace options and set global variable
334 //
335
336 if (configManager->isLogTraceFlagSet())
337 kumpf 1.34.2.1 {
338 Handler::setMessageLogTrace(true);
339 pegasusIOLog = true;
340 }
|
341 mike 1.32
|
342 kumpf 1.34.2.1 // Get the log file directory definition.
343 // We put String into Cstring because
344 // Directory functions only handle Cstring.
345 // ATTN-KS: create String based directory functions.
346
347 logsDirectory = configManager->getCurrentValue("logdir");
348
349 // Set up the Logger. This does not open the logs
350 // Might be more logical to clean before set.
351 // ATTN: Need tool to completely disable logging.
352 Logger::setHomeDirectory(logsDirectory);
353
|
354 kumpf 1.34.2.2 if (configManager->isCleanLogsFlagSet())
|
355 kumpf 1.34.2.1 {
356 Logger::clean(logsDirectory);;
357 }
|
358 mike 1.32
|
359 kumpf 1.34.2.1 // Leave this in until people get familiar with the logs.
360 cout << "Logs Directory = " << logsDirectory << endl;
|
361 mike 1.32
|
362 kumpf 1.34.2.2 if (configManager->isSlpFlagSet())
|
363 kumpf 1.34.2.1 {
364 useSLP = true;
365 }
|
366 mike 1.32 }
|
367 kumpf 1.34.2.1 catch (UnrecognizedConfigProperty e)
|
368 mike 1.32 {
|
369 kumpf 1.34.2.1 cout << "Error: " << e.getMessage() << endl;
|
370 mike 1.32 }
371
372 char* address = portOption.allocateCString();
373
374 // Put out startup up message.
375 cout << PEGASUS_NAME << PEGASUS_VERSION <<
376 " on port " << address << endl;
377 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
378 cout <<"Started..."
379 << (pegasusIOTrace ? " Tracing to Display ": " ")
380 << (pegasusIOLog ? " Tracing to Log ": " ")
381 << (useSLP ? " SLP reg. " : " No SLP ")
382 << endl;
383
384 // Put server start message to the logger
385 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
386 "Start $0 $1 port $2 $3 $4",
387 PEGASUS_NAME,
388 PEGASUS_VERSION,
389 address,
390 (pegasusIOTrace ? " Tracing": " "),
391 mike 1.32 (useSLP ? " SLP on " : " SLP off "));
392
|
393 kumpf 1.34.2.1 // do we need to run as a daemon ?
394 if (daemonOption)
395 {
396 if(-1 == cimserver_fork())
397 exit(-1);
398 }
|
399 mike 1.32
400 // try loop to bind the address, and run the server
401 try
402 {
403 slp_client *discovery = new slp_client() ;;
404 String serviceURL;
405 serviceURL.assign("service:cim.pegasus://");
406 String host_name = slp_get_host_name();
407 serviceURL += host_name;
408 serviceURL += ":";
409 serviceURL += address;
410 char *url = serviceURL.allocateCString();
411 // free(host_name);
412
413 Selector selector;
414 CIMServer server(&selector, pegasusHome);
415
416 // bind throws an exception of the bind fails
|
417 mike 1.33 cout << "Binding to " << address << endl;
|
418 mike 1.32 server.bind(address);
419 delete [] address;
420
421 time_t last = 0;
422 while( 1 )
423 {
424 if(useSLP )
425 {
426 if( (time(NULL) - last ) > 60 )
427 {
428 if( discovery != NULL && url != NULL )
429 discovery->srv_reg_all(url,
430 "(namespace=root/cimv20)",
431 "service:cim.pegasus",
432 "DEFAULT",
433 70) ;
434 time(&last);
435 }
436
437 discovery->service_listener();
438 }
439 mike 1.32 server.runForever();
440 }
441
|
442 mike 1.34 // This statement is unrechable!
443 //
444 // Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
445 // "Normal Termination");
|
446 mike 1.32 }
447 catch(Exception& e)
448 {
449 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
450 "Abnormal Termination $0", e.getMessage());
451
452 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
453 }
454
455 return 0;
456 }
|