1 mike 1.25 //%/////////////////////////////////////////////////////////////////////////////
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.25 //
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.25 //
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.25 //
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
79
80
81 #if defined(PEGASUS_OS_TYPE_WINDOWS)
82 # include "cimserver_windows.cpp"
83 #elif defined(PEGASUS_OS_TYPE_UNIX)
84 # include "cimserver_unix.cpp"
85 mike 1.25 #else
86 # error "Unsupported platform"
87 #endif
88
89 PEGASUS_USING_PEGASUS;
90 PEGASUS_USING_STD;
91
92 void GetEnvironmentVariables(
93 const char* arg0,
94 String& pegasusHome)
95 {
96 // Get environment variables:
97
98 const char* tmp = getenv("PEGASUS_HOME");
99
100 if (!tmp)
101 {
102 cerr << arg0 << ": PEGASUS_HOME environment variable undefined" << endl;
103 exit(1);
104 }
105
106 mike 1.25 pegasusHome = tmp;
107 FileSystem::translateSlashes(pegasusHome);
108 }
109
110 /** GetOptions function - This function defines the Options Table
111 and sets up the options from that table using the option manager.
112 */
113 void GetOptions(
114 OptionManager& om,
115 int& argc,
116 char** argv,
117 const String& pegasusHome)
118 {
119 static struct OptionRow optionsTable[] =
120 {
121 {"port", "5988", false, Option::WHOLE_NUMBER, 0, 0, "port",
122 "specifies port number to listen on" },
123 {"trace", "false", false, Option::BOOLEAN, 0, 0, "t",
124 "turns on trace of Client IO to console "},
125 {"logtrace", "false", false, Option::BOOLEAN, 0, 0, "l",
126 "Turns on trace of Client IO to trace log "},
127 mike 1.25 {"options", "false", false, Option::BOOLEAN, 0, 0, "options",
128 " Displays the settings of the Options "},
129 {"severity", "ALL", false, Option::STRING, 0, 0, "s",
130
131 "Sets the severity level that will be logged "},
132 {"logs", "ALL", false, Option::STRING, 0, 0, "X",
133 "Not Used "},
134 {"daemon", "false", false, Option::BOOLEAN, 0, 0, "d",
135 "Detach Pegasus from the console and run it in the background "},
136 {"logdir", "./logs", false, Option::STRING, 0, 0, "logdir",
137 "Directory for log files"},
138 {"cleanlogs", "false", false, Option::BOOLEAN, 0, 0, "clean",
139 "Clears the log files at startup"},
140 {"version", "false", false, Option::BOOLEAN, 0, 0, "v",
141 "Displays Pegasus Version "},
142 {"help", "false", false, Option::BOOLEAN, 0, 0, "h",
143 "Prints help message with command line options "},
144 {"install", "false", false, Option::BOOLEAN, 0, 0, "install",
145 "Installs Pegasus as a Windows NT Service "},
146 {"remove", "false", false, Option::BOOLEAN, 0, 0, "remove",
147 "Removes Pegasus as a Windows NT Service "},
148 mike 1.25 {"debug", "false", false, Option::BOOLEAN, 0, 0, "d",
149 "Not Used "},
150 {"slp", "true", false, Option::BOOLEAN, 0, 0, "slp",
151 "Register Pegasus as a Service with SLP"}
152 };
153 const Uint32 NUM_OPTIONS = sizeof(optionsTable) / sizeof(optionsTable[0]);
154
155 om.registerOptions(optionsTable, NUM_OPTIONS);
156
157 String configFile = pegasusHome + "/testclient.conf";
158
159 cout << "Config file from " << configFile << endl;
160
161 if (FileSystem::exists(configFile))
162 om.mergeFile(configFile);
163 if(argc && argv != NULL)
164 om.mergeCommandLine(argc, argv);
165
166 om.checkRequiredOptions();
167 }
168
169 mike 1.25 /* PrintHelp - This is temporary until we expand the options manager to allow
170 options help to be defined with the OptionRow entries and presented from
171 those entries.
172 */
173 void PrintHelp(const char* arg0)
174 {
175 cout << '\n';
176 cout << PEGASUS_NAME << PEGASUS_VERSION << endl;
177 cout << '\n';
178 cout << "Usage: " << arg0 << endl;
179 cout << endl;
180 }
181
182 //////////////////////////////////////////////////////////////////////////
183 // MAIN
184 //////////////////////////////////////////////////////////////////////////
185 int main(int argc, char** argv)
186 {
187 // on Windows NT if there are no command-line options, run as a service
188
189 if (argc == 1 )
190 mike 1.25 cim_server_service(argc, argv) ;
191
192 // Get environment variables:
193
194 String pegasusHome;
195
196 GetEnvironmentVariables(argv[0], pegasusHome);
197
198 // Get options (from command line and from configuration file); this
199 // removes corresponding options and their arguments fromt he command
200 // line.
201
202 OptionManager om;
203
204 try
205 {
206 GetOptions(om, argc, argv, pegasusHome);
207 // om.print();
208 }
209 catch (Exception& e)
210 {
211 mike 1.25 cerr << argv[0] << ": " << e.getMessage() << endl;
212 exit(1);
213 }
214
215 // At this point, all options should have been extracted; print an
216 // error if there are any remaining:
217
218 if (argc != 1)
219 {
220 cerr << argv[0] << ": unrecognized options: ";
221
222 for (int i = 1; i < argc; i++)
223 cerr << argv[i] << ' ';
224 cout << endl;
225 exit(1);
226 }
227
228 // Check to see if we should (can) install as a NT service
229
230 String installOption;
231 if(om.lookupValue("install", installOption) && installOption == "true")
232 mike 1.25 {
233 if( 0 != cimserver_install_nt_service( pegasusHome ))
234 cout << "\nPegasus installed as NT Service";
235 exit(0);
236 }
237
238 // Check to see if we should (can) remove Pegasus as an NT service
239
240 String removeOption;
241 if(om.lookupValue("remove", removeOption) && removeOption == "true")
242 {
243 if( 0 != cimserver_remove_nt_service() )
244 cout << "\nPegasus removed as NT Service";
245 exit(0);
246
247 }
248
249 // Check to see if user asked for the version (-v otpion):
250
251 String versionOption;
252
253 mike 1.25 if (om.lookupValue("version", versionOption) && versionOption == "true")
254 {
255 cerr << PEGASUS_VERSION << endl;
256 exit(0);
257 }
258
259 // Check to see if user asked for help (-h otpion):
260 String helpOption;
261
262 if (om.lookupValue("help", helpOption) && helpOption == "true")
263 {
264 PrintHelp(argv[0]);
265 om.printHelp();
266 exit(0);
267 }
268
269 // Check the trace options and set global variable
270 Boolean pegasusIOTrace = false;
271 if (om.valueEquals("trace", "true"))
272 {
273 Handler::setMessageTrace(true);
274 mike 1.25 pegasusIOTrace = true;
275 }
276
277 Boolean pegasusIOLog = false;
278 if (om.valueEquals("logtrace", "true"))
279 {
280 Handler::setMessageLogTrace(true);
281 pegasusIOLog = true;
282 }
283
284 // Grab the port otpion:
285
286 String portOption;
287 om.lookupValue("port", portOption);
288
289 // Get the log file directory definition.
290 // We put String into Cstring because
291 // Directory functions only handle Cstring.
292 // ATTN-KS: create String based directory functions.
293 String logsDirectory;
294 om.lookupValue("logdir", logsDirectory);
295 mike 1.25
296 // Set up the Logger. This does not open the logs
297 // Might be more logical to clean before set.
298 // ATTN: Need tool to completely disable logging.
299 Logger::setHomeDirectory(logsDirectory);
300
301 if (om.valueEquals("cleanlogs", "true"))
302 {
303 Logger::clean(logsDirectory);;
304 }
305
306 // Leave this in until people get familiar with the logs.
307 cout << "Logs Directory = " << logsDirectory << endl;
308
309
310 char* address = portOption.allocateCString();
311
312 // Put out startup up message.
313 cout << PEGASUS_NAME << PEGASUS_VERSION <<
314 " on port " << address << endl;
315 cout << "Built " << __DATE__ << " " << __TIME__ << endl;
316 mike 1.25 cout <<"Started..."
317 << (pegasusIOTrace ? " Tracing to Display ": " ")
318 << (pegasusIOLog ? " Tracing to Log ": " ")
319 << endl;
320
321 // Option to Display the options table. Primarily
322 // a diagnostic tool.
323 if (om.valueEquals("options", "true"))
324 om.print();
325
326 // Put server start message to the logger
327 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
328 "Start $0 $1 port $2 $3 ",
329 PEGASUS_NAME,
330 PEGASUS_VERSION,
331 address,
332 (pegasusIOTrace ? " Tracing": " "));
333
334 Boolean useSLP = false;;
335
336 if(om.valueEquals("slp", "true"))
337 mike 1.25 useSLP = true;
338
339 // do we need to run as a daemon ?
340 String daemonOption;
341 if(om.lookupValue("daemon", daemonOption) && daemonOption == "true")
342 {
343 if(-1 == cimserver_fork())
344 exit(-1);
345 }
346
347
348 // try loop to bind the address, and run the server
349 try
350 {
351 Selector selector;
352 CIMServer server(&selector, pegasusHome);
353 server.setSLP(useSLP);
354
355 // bind throws an exception of the bind fails
356 server.bind(address);
357 delete [] address;
358 mike 1.25 server.runForever();
359
360 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
361 "Normal Termination");
362
363 }
364 catch(Exception& e)
365 {
366 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
367 "Abnormal Termination $0", e.getMessage());
368
369 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
370 }
371
372 return 0;
373 }
|