1 mike 1.31 //%/////////////////////////////////////////////////////////////////////////////
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.31 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
25 // Modified By: Mike Day (mdday@us.ibm.com)
26 // =======
27 // Modified By: Karl Schopmeyer (k.schopmeyer@opengroup.org)
28 //
29 //%/////////////////////////////////////////////////////////////////////////////
30
31
32 //////////////////////////////////////////////////////////////////////
33 //
34 // Notes on deamon operation (Unix) and service operation (Win 32):
35 //
36 // To run pegasus as a daemon on Unix platforms, use the -d option:
37 //
38 // cimserver -d
39 //
40 // The -d option has no effect on windows operation.
41 //
42 // To run pegasus as an NT service, there are FOUR different possibilities:
43 mike 1.31 //
44 // To INSTALL the Pegasus service,
45 //
46 // cimserver -install
47 //
48 // To REMOVE the Pegasus service,
49 //
50 // cimserver -remove
51 //
52 // To START the Pegasus service,
53 //
54 // net start cimserver
55 //
56 // To STOP the Pegasus service,
57 //
58 // net stop cimserver
59 //
60 // Alternatively, you can use the windows service manager. Pegasus shows up
61 // in the service database as "Pegasus CIM Object Manager"
62 //
63 // Mike Day, mdday@us.ibm.com
64 mike 1.31 //
65 //////////////////////////////////////////////////////////////////////
66
67
68 #include <iostream>
69 #include <cstdlib>
70 #include <Pegasus/Common/FileSystem.h>
71 #include <Pegasus/Common/Selector.h>
72 #include <Pegasus/Common/OptionManager.h>
73 #include <Pegasus/Server/CIMServer.h>
74 #include <Pegasus/Common/PegasusVersion.h>
75 #include <Pegasus/Protocol/Handler.h>
76 #include <Pegasus/Common/Logger.h>
77 #include <Pegasus/Common/System.h>
78 #include <slp/slp.h>
79
80
81
82 #if defined(PEGASUS_OS_TYPE_WINDOWS)
83 # include "cimserver_windows.cpp"
84 #elif defined(PEGASUS_OS_TYPE_UNIX)
85 mike 1.31 # include "cimserver_unix.cpp"
86 #else
87 # error "Unsupported platform"
88 #endif
89
90 PEGASUS_USING_PEGASUS;
91 PEGASUS_USING_STD;
92
93 void GetEnvironmentVariables(
94 const char* arg0,
95 String& pegasusHome)
96 {
97 // Get environment variables:
98
99 const char* tmp = getenv("PEGASUS_HOME");
100
101 if (!tmp)
102 {
103 cerr << arg0 << ": PEGASUS_HOME environment variable undefined" << endl;
104 exit(1);
105 }
106 mike 1.31
107 pegasusHome = tmp;
108 FileSystem::translateSlashes(pegasusHome);
109 }
110
111 /** GetOptions function - This function defines the Options Table
112 and sets up the options from that table using the option manager.
113 */
114 void GetOptions(
115 OptionManager& om,
116 int& argc,
117 char** argv,
118 const String& pegasusHome)
119 {
120 static struct OptionRow optionsTable[] =
121 {
122 {"home", "/etc/pegasus", false, Option::STRING, 0, 0, "D",
123 "Sets the pegasus home directory"},
124 {"port", "5988", false, Option::WHOLE_NUMBER, 0, 0, "port",
125 "specifies port number to listen on" },
126 {"trace", "false", false, Option::BOOLEAN, 0, 0, "t",
127 mike 1.31 "turns on trace of Client IO to console "},
128 {"logtrace", "false", false, Option::BOOLEAN, 0, 0, "l",
129 "Turns on trace of Client IO to trace log "},
130 {"options", "false", false, Option::BOOLEAN, 0, 0, "options",
131 " Displays the settings of the Options "},
132 {"severity", "ALL", false, Option::STRING, 0, 0, "s",
133
134 "Sets the severity level that will be logged "},
135 {"logs", "ALL", false, Option::STRING, 0, 0, "X",
136 "Not Used "},
137 {"daemon", "false", false, Option::BOOLEAN, 0, 0, "d",
138 "Detach Pegasus from the console and run it in the background "},
139 {"logdir", "./logs", false, Option::STRING, 0, 0, "logdir",
140 "Directory for log files"},
141 {"cleanlogs", "false", false, Option::BOOLEAN, 0, 0, "clean",
142 "Clears the log files at startup"},
143 {"version", "false", false, Option::BOOLEAN, 0, 0, "v",
144 "Displays Pegasus Version "},
145 {"help", "false", false, Option::BOOLEAN, 0, 0, "h",
146 "Prints help message with command line options "},
147 {"install", "false", false, Option::BOOLEAN, 0, 0, "install",
148 mike 1.31 "Installs Pegasus as a Windows NT Service "},
149 {"remove", "false", false, Option::BOOLEAN, 0, 0, "remove",
150 "Removes Pegasus as a Windows NT Service "},
151 {"debug", "false", false, Option::BOOLEAN, 0, 0, "d",
152 "Not Used "},
153 {"slp", "false", false, Option::BOOLEAN, 0, 0, "slp",
154 "Register Pegasus as a Service with SLP"}
155 };
156 const Uint32 NUM_OPTIONS = sizeof(optionsTable) / sizeof(optionsTable[0]);
157
158 om.registerOptions(optionsTable, NUM_OPTIONS);
159
160 String configFile = pegasusHome + "/testclient.conf";
161
162 cout << "Config file from " << configFile << endl;
163
164 if (FileSystem::exists(configFile))
165 om.mergeFile(configFile);
166 if(argc && argv != NULL)
167 om.mergeCommandLine(argc, argv);
168
169 mike 1.31 om.checkRequiredOptions();
170 }
171
172 /* PrintHelp - This is temporary until we expand the options manager to allow
173 options help to be defined with the OptionRow entries and presented from
174 those entries.
175 */
176 void PrintHelp(const char* arg0)
177 {
178 cout << '\n';
179 cout << PEGASUS_NAME << PEGASUS_VERSION << endl;
180 cout << '\n';
181 cout << "Usage: " << arg0 << endl;
182 cout << endl;
183 }
184
185 //////////////////////////////////////////////////////////////////////////
186 // MAIN
187 //////////////////////////////////////////////////////////////////////////
188 int main(int argc, char** argv)
189 {
190 mike 1.31 // on Windows NT if there are no command-line options, run as a service
191
192 if (argc == 1 )
193 cim_server_service(argc, argv) ;
194
195 // Get environment variables
196
197 String pegasusHome;
198
199 for (int i=0; i < argc; i++) {
200 if (!strcmp(argv[i],"-D")) {
201 i++;
202 if (i < argc) pegasusHome = argv[i];
203 break;
204 }
205 }
206 if (pegasusHome.size() == 0)
207 GetEnvironmentVariables(argv[0], pegasusHome);
208
209 // Get options (from command line and from configuration file); this
210 // removes corresponding options and their arguments fromt he command
211 mike 1.31 // line.
212
213 OptionManager om;
214
215 try
216 {
217 GetOptions(om, argc, argv, pegasusHome);
218 // om.print();
219 }
220 catch (Exception& e)
221 {
222 cerr << argv[0] << ": " << e.getMessage() << endl;
223 exit(1);
224 }
225
226 // At this point, all options should have been extracted; print an
227 // error if there are any remaining:
228
229 if (argc != 1)
230 {
231 cerr << argv[0] << ": unrecognized options: ";
232 mike 1.31
233 for (int i = 1; i < argc; i++)
234 cerr << argv[i] << ' ';
235 cout << endl;
236 exit(1);
237 }
238
239 // Check to see if we should (can) install as a NT service
240
241 String installOption;
242 if(om.lookupValue("install", installOption) && installOption == "true")
243 {
244 if( 0 != cimserver_install_nt_service( pegasusHome ))
245 cout << "\nPegasus installed as NT Service";
246 exit(0);
247 }
248
249 // Check to see if we should (can) remove Pegasus as an NT service
250
251 String removeOption;
252 if(om.lookupValue("remove", removeOption) && removeOption == "true")
253 mike 1.31 {
254 if( 0 != cimserver_remove_nt_service() )
255 cout << "\nPegasus removed as NT Service";
256 exit(0);
257
258 }
259
260 // Check to see if user asked for the version (-v otpion):
261
262 String versionOption;
263
264 if (om.lookupValue("version", versionOption) && versionOption == "true")
265 {
266 cerr << PEGASUS_VERSION << endl;
267 exit(0);
268 }
269
270 // Check to see if user asked for help (-h otpion):
271 String helpOption;
272
273 if (om.lookupValue("help", helpOption) && helpOption == "true")
274 mike 1.31 {
275 PrintHelp(argv[0]);
276 om.printHelp();
277 exit(0);
278 }
279
280 // Check the trace options and set global variable
281 Boolean pegasusIOTrace = false;
282 if (om.valueEquals("trace", "true"))
283 {
284 Handler::setMessageTrace(true);
285 pegasusIOTrace = true;
286 }
287
288 Boolean pegasusIOLog = false;
289 if (om.valueEquals("logtrace", "true"))
290 {
291 Handler::setMessageLogTrace(true);
292 pegasusIOLog = true;
293 }
294
295 mike 1.31 // Grab the port otpion:
296
297 String portOption;
298 om.lookupValue("port", portOption);
299
300 // Get the log file directory definition.
301 // We put String into Cstring because
302 // Directory functions only handle Cstring.
303 // ATTN-KS: create String based directory functions.
304 String logsDirectory;
305 om.lookupValue("logdir", logsDirectory);
306
307 // Set up the Logger. This does not open the logs
308 // Might be more logical to clean before set.
309 // ATTN: Need tool to completely disable logging.
310 Logger::setHomeDirectory(logsDirectory);
311
312 if (om.valueEquals("cleanlogs", "true"))
313 {
314 Logger::clean(logsDirectory);;
315 }
316 mike 1.31
317 // Option to Display the options table. Primarily
318 // a diagnostic tool.
319 if (om.valueEquals("options", "true"))
320 om.print();
321
322 // Leave this in until people get familiar with the logs.
323 cout << "Logs Directory = " << logsDirectory << endl;
324
325 Boolean useSLP = (om.valueEquals("slp", "true")) ? true: false;
326
327 char* address = portOption.allocateCString();
328
329 // Put out startup up message.
330 cout << PEGASUS_NAME << PEGASUS_VERSION <<
331 " on port " << address << endl;
332 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
333 cout <<"Started..."
334 << (pegasusIOTrace ? " Tracing to Display ": " ")
335 << (pegasusIOLog ? " Tracing to Log ": " ")
336 << (useSLP ? " SLP reg. " : " No SLP ")
337 mike 1.31 << endl;
338
339 // Put server start message to the logger
340 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
341 "Start $0 $1 port $2 $3 $4",
342 PEGASUS_NAME,
343 PEGASUS_VERSION,
344 address,
345 (pegasusIOTrace ? " Tracing": " "),
346 (useSLP ? " SLP on " : " SLP off "));
347
348 // do we need to run as a daemon ?
349 String daemonOption;
350 if(om.lookupValue("daemon", daemonOption) && daemonOption == "true")
351 {
352 if(-1 == cimserver_fork())
353 exit(-1);
354 }
355
356
357 // try loop to bind the address, and run the server
358 mike 1.31 try
359 {
360 slp_client *discovery = new slp_client() ;;
361 String serviceURL;
362 serviceURL.assign("service:cim.pegasus://");
363 String host_name = slp_get_host_name();
364 serviceURL += host_name;
365 serviceURL += ":";
366 serviceURL += address;
367 char *url = serviceURL.allocateCString();
368 // free(host_name);
369
370 Selector selector;
371 CIMServer server(&selector, pegasusHome);
372
373 // bind throws an exception of the bind fails
374 server.bind(address);
375 delete [] address;
376
377
378
379 mike 1.31 time_t last = 0;
380 while( 1 )
381 {
382 if(useSLP )
383 {
384 if( (time(NULL) - last ) > 60 )
385 {
386 if( discovery != NULL && url != NULL )
387 discovery->srv_reg_all(url,
388 "(namespace=root/cimv20)",
389 "service:cim.pegasus",
390 "DEFAULT",
391 70) ;
392 time(&last);
393 }
394
395 discovery->service_listener();
396 }
397 server.runForever();
398 }
399
400 mike 1.31 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
401 "Normal Termination");
402 }
403 catch(Exception& e)
404 {
405 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
406 "Abnormal Termination $0", e.getMessage());
407
408 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
409 }
410
411 return 0;
412 }
|