main.cc

Go to the documentation of this file.
00001 //                            Package   : omniEvents
00002 //  main.cc                   Created   : 2004/08/01
00003 //                            Author    : Alex Tingle.
00004 //
00005 //    Copyright (C) 1998 Paul Nader, 2004-2005 Alex Tingle.
00006 //
00007 //    This file is part of the omniEvents application.
00008 //
00009 //    omniEvents is free software; you can redistribute it and/or
00010 //    modify it under the terms of the GNU Lesser General Public
00011 //    License as published by the Free Software Foundation; either
00012 //    version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //    omniEvents is distributed in the hope that it will be useful,
00015 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //    Lesser General Public License for more details.
00018 //
00019 //    You should have received a copy of the GNU Lesser General Public
00020 //    License along with this library; if not, write to the Free Software
00021 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // Description:
00024 //    Event Services Channel Factory implementation. The factory registers
00025 //    itself with the naming service. Clients wishing to create event
00026 //    channels can either use the factory by resolving its name with the
00027 //    naming service or create in-process channels.
00028 //
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #  include "config.h"
00032 #endif
00033 
00034 #ifdef HAVE_GETOPT
00035 #  include <unistd.h>
00036 extern char* optarg;
00037 extern int optind;
00038 #else
00039 #  include "getopt.h"
00040 #endif
00041 
00042 #include "main.h"
00043 #include "omniEvents.h"
00044 #include "naming.h"
00045 #include "omniEventsLog.h"
00046 #include "EventChannelFactory.h"
00047 #include "Orb.h"
00048 #include "daemon.h"
00049 #include "version.h"
00050 
00051 #if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGSET)
00052 #  include <signal.h>
00053 #  define SIGSET(sig,func) ::sigset(sig,func)
00054 #elif defined(HAVE_SIGNAL_H)
00055 #  include <signal.h>
00056 #  define SIGSET(sig,func) ::signal(sig,func)
00057 #endif
00058 
00059 #ifdef HAVE_OMNIORB4
00060 #  include <omniORB4/internal/orbOptions.h>
00061 #endif
00062 
00063 #include <cstdlib>
00064 #include <stdio.h> // for sprintf
00065 
00066 int main(int argc, char** argv)
00067 {
00068   OmniEvents::Daemon daemon(argc,argv);
00069 
00070 #ifdef HAVE_OMNIORB4
00071   try
00072   {
00073     // Duplicate argv & argc.
00074     int    originalArgc =argc;
00075     char** originalArgv =new char*[originalArgc];
00076     for(int i=0; i<originalArgc; ++i)
00077         originalArgv[i]=strdup(argv[i]);
00078 
00079     // Remove ORB arguments from argc & argv.
00080     try {
00081       omni::orbOptions::singleton().extractInitOptions(argc,argv);
00082     }
00083     catch(...) {
00084       argc=originalArgc;
00085       argv=originalArgv;
00086     }
00087 #endif
00088 
00089   using namespace OmniEvents;
00090 
00091   //
00092   // Process Options
00093   const char* endPointNoListen =NULL;
00094   int         port             =0;
00095   const char* logDir           =NULL;
00096   const char* factoryName      ="EventChannelFactory";
00097   bool        verbose          =false;
00098 
00099   int c;
00100   while ((c = getopt(argc,argv,"O:a:p:l:P:N:dft:vVh")) != EOF)
00101   {
00102      switch (c)
00103      {
00104         case 'O': break; // Helps protect us from -ORB arguments.
00105         
00106      // Initialisation options (only useful on first run)
00107         case 'a': endPointNoListen=optarg;
00108                   break;
00109 
00110         case 'p': port=atoi(optarg);
00111                   if (port <= 0)
00112                   {
00113                      cerr<<"\nError: port must be a positive integer"<<endl;
00114                      usage(argc,argv);
00115                   }
00116                   break;
00117 
00118      // Other options
00119         case 'l': logDir=optarg;
00120                   break;
00121 
00122         case 'P': daemon.pidfile(optarg);
00123                   break;
00124 
00125         case 'N': factoryName=optarg;
00126                   break;
00127 
00128         case 'd': cerr<<"Option '-d' is deprecated. Use '-f' instead."<<endl;
00129                   daemon.foreground(true);
00130                   break;
00131 
00132         case 'f': daemon.foreground(true);
00133                   break;
00134 
00135      // Informational options
00136         case 't': daemon.tracefile(optarg);
00137                   break;
00138 
00139         case 'v': verbose=true;
00140                   break;
00141         
00142         case 'V': cout<<OmniEvents::version()<<endl;
00143                   ::exit(0);
00144 
00145         case 'h':
00146         default : usage(argc,argv);
00147                   break;
00148      }
00149   }
00150 
00151   //
00152   // Create database instance.
00153   omniEventsLog logfile(logDir);
00154   PersistNode* initialState =NULL;
00155   if(logfile.fileExists(logfile.activeFilename()))
00156   {
00157     // Read library file.
00158     initialState=logfile.parse();
00159     // Check for incompatibilities between options and the file.
00160     if(port && port!=initialState->child("ecf")->attrLong("port"))
00161     {
00162       cerr<<
00163         "Error: Option '-p "<<port<<"' conflicts with value '"<<
00164         initialState->child("ecf")->attrLong("port")<<"'\n stored in"
00165         " database file '"<<logfile.activeFilename()<<"'.\n"
00166         " Either delete the file to clear the database, or do not use the"
00167         " '-p' option."<<endl;
00168       exit(1);
00169     }
00170     if(endPointNoListen && string(endPointNoListen)!=
00171          initialState->child("ecf")->attrString("endPointNoListen"))
00172     {
00173       cerr<<
00174         "Error: Option '-a "<<endPointNoListen<<"' conflicts with value '"<<
00175         initialState->child("ecf")->attrString("endPointNoListen")<<"'\n"
00176         " stored in database file '"<<logfile.activeFilename()<<"'.\n"
00177         " Either delete the file to clear the database, or do not use the"
00178         " '-a' option."<<endl;
00179       exit(1);
00180     }
00181   }
00182   else if(logfile.fileExists(logfile.backupFilename()))
00183   {
00184     // Quit with an error.
00185     cerr <<
00186       "Error: backup file '" << logfile.backupFilename() << "' exists.\n"
00187       " Rename it to '" << logfile.activeFilename() << "'\n"
00188       " to recover the server's state, or delete it to create a new\n"
00189       " database file." << endl;
00190     exit(1);
00191   }
00192   else
00193   {
00194     // Create initial state without a library file.
00195     initialState=logfile.bootstrap(port?port:11169,endPointNoListen);
00196   }
00197   port=initialState->child("ecf")->attrLong("port",port);
00198   string endPoint2=initialState->child("ecf")->attrString("endPointNoListen");
00199 
00200   //
00201   // Daemonise
00202   daemon.daemonize();
00203 
00204   //
00205   // Initialise orb & POAs.
00206 #ifdef HAVE_OMNIORB4
00207   char endPoint[64];
00208   sprintf(endPoint,"giop:::%d",port);
00209   if(endPoint2.empty())
00210   {
00211     const char* opts[][2] ={ {"endPoint",endPoint}, {0,0} };
00212     Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
00213   }
00214   else
00215   {
00216     const char* opts[][2] ={
00217       {"endPoint",endPoint},
00218       {"endPointNoListen",endPoint2.c_str()},
00219       {0,0} };
00220     Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
00221   }
00222 #else
00223   insertArgs(argc, argv, 1, 2);
00224   argv[1] = strdup("-ORBpoa_iiop_port");
00225   argv[2] = new char[32 + 1];
00226   sprintf(argv[2], "%d", port);
00227   Orb::inst()._orb=CORBA::ORB_init(argc,argv);
00228 #endif
00229   Orb::inst().resolveInitialReferences();
00230   {
00231     PortableServer::POAManager_var pman;
00232     pman=Orb::inst()._RootPOA->the_POAManager();
00233     pman->activate();
00234     pman=Orb::inst()._omniINSPOA->the_POAManager();
00235     pman->activate();
00236   }
00237 
00238   //
00239   // If omniEvents is restarting then the omniEventsLog object
00240   // will take care of creating the factory and any subordinate
00241   // event channels, proxies, etc under it.
00242   logfile.incarnateFactory(initialState);
00243   delete initialState; // Tidy up.
00244   initialState=NULL;
00245 
00246   {
00247     //
00248     // Register factory with the Naming Service.
00249     omniEvents::EventChannelFactory_var factory( logfile.factory()->_this() );
00250     bindName2Object(
00251       Orb::inst()._NameService.in(), 
00252       str2name(factoryName),
00253       factory.in()
00254     );
00255 
00256     //
00257     // Print the factory IOR.
00258     if(verbose)
00259     {
00260       DB(1,"Starting omniEvents on port "<<port)
00261       if(!endPoint2.empty())
00262           DB(1,"Alternate endPoint "<<endPoint2.c_str())
00263       CORBA::String_var iorstr =
00264         Orb::inst()._orb->object_to_string(factory.in());
00265       DB(1,iorstr.in())
00266     }
00267   } // factory reference is released.
00268 
00269 #ifdef HAVE_SIGNAL_H
00270   SIGSET(SIGINT , ::OmniEvents_Orb_shutdown);
00271   SIGSET(SIGTERM, ::OmniEvents_Orb_shutdown);
00272 #  ifdef SIGUSR1
00273   SIGSET(SIGUSR1, ::OmniEvents_Orb_bumpTraceLevel);
00274 #  endif
00275 #  ifdef SIGPIPE
00276   SIGSET(SIGPIPE, SIG_IGN); // Ignore broken pipes
00277 #  endif
00278 #endif
00279 
00280   daemon.runningOk();
00281 
00282   //
00283   // Start the background tasks.
00284   logfile.runWorker(); // Logfile's worker thread.
00285   Orb::inst().run();   // Use the main thread to collect orphaned responses.
00286 
00287   DB(1,"Shutdown requested.")
00288   Orb::inst()._orb->shutdown(1); // Synchronous shutdown
00289   Orb::inst()._orb->destroy(); // clean up
00290 
00291   return 0; // Delete any pidfile & exit.
00292 
00293 #ifdef HAVE_OMNIORB4
00294   }
00295   catch (CORBA::SystemException& ex) {
00296     DB(0,"System exception: "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")")
00297   }
00298   catch (CORBA::Exception& ex) {
00299     DB(0,"CORBA exception: "<<ex._name())
00300   }
00301   return 1;
00302 #endif
00303 } // end main()
00304 
00305 
00306 //
00307 // Signal handlers.
00308 //
00309 
00310 extern "C"
00311 {
00312   void OmniEvents_Orb_shutdown(int signum)
00313   {
00314     OmniEvents::Orb::inst().shutdown(signum);
00315   }
00316 
00317   void OmniEvents_Orb_bumpTraceLevel(int signum)
00318   {
00319     omniORB::traceLevel=(omniORB::traceLevel+5)%45;
00320     DB(0,"TRACE LEVEL BUMPED TO "<<omniORB::traceLevel<<" BY SIGNAL "<<signum)
00321   }
00322 }

Generated on Tue Jan 29 04:19:53 2008 for OmniEvents by  doxygen 1.5.4