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 //%/////////////////////////////////////////////////////////////////////////////
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 //
44 // To INSTALL the Pegasus service,
45 //
46 // cimserver -install
47 //
48 mike 1.32 // 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 //
65 //////////////////////////////////////////////////////////////////////
66
67
68 #include <iostream>
69 mike 1.32 #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 # include "cimserver_unix.cpp"
86 #else
87 # error "Unsupported platform"
88 #endif
89
90 mike 1.32 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
107 pegasusHome = tmp;
108 FileSystem::translateSlashes(pegasusHome);
109 }
110
111 mike 1.32 /** 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 "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 mike 1.32 {"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 mike 1.33 "Detach Pegasus from the console and run it in the background "},
|
139 mike 1.32 {"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 "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 mike 1.32 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 om.checkRequiredOptions();
|
170 mike 1.33
|
171 mike 1.32 }
172
173 /* PrintHelp - This is temporary until we expand the options manager to allow
174 options help to be defined with the OptionRow entries and presented from
175 those entries.
176 */
177 void PrintHelp(const char* arg0)
178 {
179 cout << '\n';
180 cout << PEGASUS_NAME << PEGASUS_VERSION << endl;
181 cout << '\n';
182 cout << "Usage: " << arg0 << endl;
183 cout << endl;
184 }
185
|
186 mike 1.33 /////////////////////////////////////////////////////////////////////////
|
187 mike 1.32 // MAIN
188 //////////////////////////////////////////////////////////////////////////
189 int main(int argc, char** argv)
190 {
191 // on Windows NT if there are no command-line options, run as a service
192
193 if (argc == 1 )
194 cim_server_service(argc, argv) ;
195
196 // Get environment variables
197
198 String pegasusHome;
199
200 for (int i=0; i < argc; i++) {
201 if (!strcmp(argv[i],"-D")) {
202 i++;
203 if (i < argc) pegasusHome = argv[i];
204 break;
205 }
206 }
207 if (pegasusHome.size() == 0)
208 mike 1.32 GetEnvironmentVariables(argv[0], pegasusHome);
209
210 // Get options (from command line and from configuration file); this
211 // removes corresponding options and their arguments fromt he command
212 // line.
213
214 OptionManager om;
215
216 try
217 {
218 GetOptions(om, argc, argv, pegasusHome);
219 // om.print();
220 }
221 catch (Exception& e)
222 {
223 cerr << argv[0] << ": " << e.getMessage() << endl;
224 exit(1);
225 }
226
227 // At this point, all options should have been extracted; print an
228 // error if there are any remaining:
229 mike 1.32
230 if (argc != 1)
231 {
232 cerr << argv[0] << ": unrecognized options: ";
233
234 for (int i = 1; i < argc; i++)
235 cerr << argv[i] << ' ';
236 cout << endl;
237 exit(1);
238 }
239
240 // Check to see if we should (can) install as a NT service
241
242 String installOption;
243 if(om.lookupValue("install", installOption) && installOption == "true")
244 {
245 if( 0 != cimserver_install_nt_service( pegasusHome ))
246 cout << "\nPegasus installed as NT Service";
247 exit(0);
248 }
249
250 mike 1.32 // Check to see if we should (can) remove Pegasus as an NT service
251
252 String removeOption;
253 if(om.lookupValue("remove", removeOption) && removeOption == "true")
254 {
255 if( 0 != cimserver_remove_nt_service() )
256 cout << "\nPegasus removed as NT Service";
257 exit(0);
258
259 }
260
261 // Check to see if user asked for the version (-v otpion):
262
263 String versionOption;
264
265 if (om.lookupValue("version", versionOption) && versionOption == "true")
266 {
267 cerr << PEGASUS_VERSION << endl;
268 exit(0);
269 }
270
271 mike 1.32 // Check to see if user asked for help (-h otpion):
272 String helpOption;
273
274 if (om.lookupValue("help", helpOption) && helpOption == "true")
275 {
276 PrintHelp(argv[0]);
277 om.printHelp();
278 exit(0);
279 }
280
281 // Check the trace options and set global variable
282 Boolean pegasusIOTrace = false;
283 if (om.valueEquals("trace", "true"))
284 {
285 Handler::setMessageTrace(true);
286 pegasusIOTrace = true;
287 }
288
289 Boolean pegasusIOLog = false;
290 if (om.valueEquals("logtrace", "true"))
291 {
292 mike 1.32 Handler::setMessageLogTrace(true);
293 pegasusIOLog = true;
294 }
295
296 // Grab the port otpion:
297
298 String portOption;
299 om.lookupValue("port", portOption);
300
301 // Get the log file directory definition.
302 // We put String into Cstring because
303 // Directory functions only handle Cstring.
304 // ATTN-KS: create String based directory functions.
305 String logsDirectory;
306 om.lookupValue("logdir", logsDirectory);
307
308 // Set up the Logger. This does not open the logs
309 // Might be more logical to clean before set.
310 // ATTN: Need tool to completely disable logging.
311 Logger::setHomeDirectory(logsDirectory);
312
313 mike 1.32 if (om.valueEquals("cleanlogs", "true"))
314 {
315 Logger::clean(logsDirectory);;
316 }
317
318 // Option to Display the options table. Primarily
319 // a diagnostic tool.
320 if (om.valueEquals("options", "true"))
321 om.print();
322
323 // Leave this in until people get familiar with the logs.
324 cout << "Logs Directory = " << logsDirectory << endl;
325
326 Boolean useSLP = (om.valueEquals("slp", "true")) ? true: false;
327
328 char* address = portOption.allocateCString();
329
330 // Put out startup up message.
331 cout << PEGASUS_NAME << PEGASUS_VERSION <<
332 " on port " << address << endl;
333 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
334 mike 1.32 cout <<"Started..."
335 << (pegasusIOTrace ? " Tracing to Display ": " ")
336 << (pegasusIOLog ? " Tracing to Log ": " ")
337 << (useSLP ? " SLP reg. " : " No SLP ")
338 << endl;
339
340 // Put server start message to the logger
341 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
342 "Start $0 $1 port $2 $3 $4",
343 PEGASUS_NAME,
344 PEGASUS_VERSION,
345 address,
346 (pegasusIOTrace ? " Tracing": " "),
347 (useSLP ? " SLP on " : " SLP off "));
348
349 // do we need to run as a daemon ?
350 String daemonOption;
351 if(om.lookupValue("daemon", daemonOption) && daemonOption == "true")
352 {
353 if(-1 == cimserver_fork())
354 exit(-1);
355 mike 1.32 }
356
357
358 // try loop to bind the address, and run the server
359 try
360 {
361 slp_client *discovery = new slp_client() ;;
362 String serviceURL;
363 serviceURL.assign("service:cim.pegasus://");
364 String host_name = slp_get_host_name();
365 serviceURL += host_name;
366 serviceURL += ":";
367 serviceURL += address;
368 char *url = serviceURL.allocateCString();
369 // free(host_name);
370
371 Selector selector;
372 CIMServer server(&selector, pegasusHome);
373
374 // bind throws an exception of the bind fails
|
375 mike 1.33 cout << "Binding to " << address << endl;
|
376 mike 1.32 server.bind(address);
377 delete [] address;
378
379 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 mike 1.32 server.runForever();
398 }
399
|
400 mike 1.34 // This statement is unrechable!
401 //
402 // Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
403 // "Normal Termination");
|
404 mike 1.32 }
405 catch(Exception& e)
406 {
407 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
408 "Abnormal Termination $0", e.getMessage());
409
410 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
411 }
412
413 return 0;
414 }
|