(file) Return to cimserver.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Server

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2