Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

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 <stdio.h> // for sprintf
00064 
00065 int main(int argc, char** argv)
00066 {
00067   OmniEvents::Daemon daemon(argc,argv);
00068 
00069 #ifdef HAVE_OMNIORB4
00070   try
00071   {
00072     // Duplicate argv & argc.
00073     int    originalArgc =argc;
00074     char** originalArgv =new char*[originalArgc];
00075     for(int i=0; i<originalArgc; ++i)
00076         originalArgv[i]=strdup(argv[i]);
00077 
00078     // Remove ORB arguments from argc & argv.
00079     try {
00080       omni::orbOptions::singleton().extractInitOptions(argc,argv);
00081     }
00082     catch(...) {
00083       argc=originalArgc;
00084       argv=originalArgv;
00085     }
00086 #endif
00087 
00088   using namespace OmniEvents;
00089 
00090   //
00091   // Process Options
00092   const char* endPointNoListen =NULL;
00093   int         port             =0;
00094   const char* logDir           =NULL;
00095   const char* factoryName      ="EventChannelFactory";
00096   bool        verbose          =false;
00097 
00098   int c;
00099   while ((c = getopt(argc,argv,"O:a:p:l:P:N:dft:vVh")) != EOF)
00100   {
00101      switch (c)
00102      {
00103         case 'O': break; // Helps protect us from -ORB arguments.
00104         
00105      // Initialisation options (only useful on first run)
00106         case 'a': endPointNoListen=optarg;
00107                   break;
00108 
00109         case 'p': port=atoi(optarg);
00110                   if (port <= 0)
00111                   {
00112                      cerr<<"\nError: port must be a positive integer"<<endl;
00113                      usage(argc,argv);
00114                   }
00115                   break;
00116 
00117      // Other options
00118         case 'l': logDir=optarg;
00119                   break;
00120 
00121         case 'P': daemon.pidfile(optarg);
00122                   break;
00123 
00124         case 'N': factoryName=optarg;
00125                   break;
00126 
00127         case 'd': cerr<<"Option '-d' is deprecated. Use '-f' instead."<<endl;
00128                   daemon.foreground(true);
00129                   break;
00130 
00131         case 'f': daemon.foreground(true);
00132                   break;
00133 
00134      // Informational options
00135         case 't': daemon.tracefile(optarg);
00136                   break;
00137 
00138         case 'v': verbose=true;
00139                   break;
00140         
00141         case 'V': cout<<OmniEvents::version()<<endl;
00142                   ::exit(0);
00143 
00144         case 'h':
00145         default : usage(argc,argv);
00146                   break;
00147      }
00148   }
00149 
00150   //
00151   // Create database instance.
00152   omniEventsLog logfile(logDir);
00153   PersistNode* initialState =NULL;
00154   if(logfile.fileExists(logfile.activeFilename()))
00155   {
00156     // Read library file.
00157     initialState=logfile.parse();
00158     // Check for incompatibilities between options and the file.
00159     if(port && port!=initialState->child("ecf")->attrLong("port"))
00160     {
00161       cerr<<
00162         "Error: Option '-p "<<port<<"' conflicts with value '"<<
00163         initialState->child("ecf")->attrLong("port")<<"'\n stored in"
00164         " database file '"<<logfile.activeFilename()<<"'.\n"
00165         " Either delete the file to clear the database, or do not use the"
00166         " '-p' option."<<endl;
00167       exit(1);
00168     }
00169     if(endPointNoListen && string(endPointNoListen)!=
00170          initialState->child("ecf")->attrString("endPointNoListen"))
00171     {
00172       cerr<<
00173         "Error: Option '-a "<<endPointNoListen<<"' conflicts with value '"<<
00174         initialState->child("ecf")->attrString("endPointNoListen")<<"'\n"
00175         " stored in database file '"<<logfile.activeFilename()<<"'.\n"
00176         " Either delete the file to clear the database, or do not use the"
00177         " '-a' option."<<endl;
00178       exit(1);
00179     }
00180   }
00181   else if(logfile.fileExists(logfile.backupFilename()))
00182   {
00183     // Quit with an error.
00184     cerr <<
00185       "Error: backup file '" << logfile.backupFilename() << "' exists.\n"
00186       " Rename it to '" << logfile.activeFilename() << "'\n"
00187       " to recover the server's state, or delete it to create a new\n"
00188       " database file." << endl;
00189     exit(1);
00190   }
00191   else
00192   {
00193     // Create initial state without a library file.
00194     initialState=logfile.bootstrap(port?port:11169,endPointNoListen);
00195   }
00196   port=initialState->child("ecf")->attrLong("port",port);
00197   string endPoint2=initialState->child("ecf")->attrString("endPointNoListen");
00198 
00199   //
00200   // Daemonise
00201   daemon.daemonize();
00202 
00203   //
00204   // Initialise orb & POAs.
00205 #ifdef HAVE_OMNIORB4
00206   char endPoint[64];
00207   sprintf(endPoint,"giop:::%d",port);
00208   if(endPoint2.empty())
00209   {
00210     const char* opts[][2] ={ {"endPoint",endPoint}, {0,0} };
00211     Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
00212   }
00213   else
00214   {
00215     const char* opts[][2] ={
00216       {"endPoint",endPoint},
00217       {"endPointNoListen",endPoint2.c_str()},
00218       {0,0} };
00219     Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
00220   }
00221 #else
00222   insertArgs(argc, argv, 1, 2);
00223   argv[1] = strdup("-ORBpoa_iiop_port");
00224   argv[2] = new char[32 + 1];
00225   sprintf(argv[2], "%d", port);
00226   Orb::inst()._orb=CORBA::ORB_init(argc,argv);
00227 #endif
00228   Orb::inst().resolveInitialReferences();
00229   {
00230     PortableServer::POAManager_var pman;
00231     pman=Orb::inst()._RootPOA->the_POAManager();
00232     pman->activate();
00233     pman=Orb::inst()._omniINSPOA->the_POAManager();
00234     pman->activate();
00235   }
00236 
00237   //
00238   // If omniEvents is restarting then the omniEventsLog object
00239   // will take care of creating the factory and any subordinate
00240   // event channels, proxies, etc under it.
00241   logfile.incarnateFactory(initialState);
00242   delete initialState; // Tidy up.
00243   initialState=NULL;
00244 
00245   {
00246     //
00247     // Register factory with the Naming Service.
00248     omniEvents::EventChannelFactory_var factory( logfile.factory()->_this() );
00249     bindName2Object(
00250       Orb::inst()._NameService.in(), 
00251       str2name(factoryName),
00252       factory.in()
00253     );
00254 
00255     //
00256     // Print the factory IOR.
00257     if(verbose)
00258     {
00259       DB(1,"Starting omniEvents on port "<<port)
00260       if(!endPoint2.empty())
00261           DB(1,"Alternate endPoint "<<endPoint2.c_str())
00262       CORBA::String_var iorstr =
00263         Orb::inst()._orb->object_to_string(factory.in());
00264       DB(1,iorstr.in())
00265     }
00266   } // factory reference is released.
00267 
00268 #ifdef HAVE_SIGNAL_H
00269   SIGSET(SIGINT , ::OmniEvents_Orb_shutdown);
00270   SIGSET(SIGTERM, ::OmniEvents_Orb_shutdown);
00271 #  ifdef SIGUSR1
00272   SIGSET(SIGUSR1, ::OmniEvents_Orb_bumpTraceLevel);
00273 #  endif
00274 #  ifdef SIGPIPE
00275   SIGSET(SIGPIPE, SIG_IGN); // Ignore broken pipes
00276 #  endif
00277 #endif
00278 
00279   daemon.runningOk();
00280 
00281   //
00282   // Start the background tasks.
00283   logfile.runWorker(); // Logfile's worker thread.
00284   Orb::inst().run();   // Use the main thread to collect orphaned responses.
00285 
00286   DB(1,"Shutdown requested.")
00287   Orb::inst()._orb->shutdown(1); // Synchronous shutdown
00288   Orb::inst()._orb->destroy(); // clean up
00289 
00290   return 0; // Delete any pidfile & exit.
00291 
00292 #ifdef HAVE_OMNIORB4
00293   }
00294   catch (CORBA::SystemException& ex) {
00295     DB(0,"System exception: "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")")
00296   }
00297   catch (CORBA::Exception& ex) {
00298     DB(0,"CORBA exception: "<<ex._name())
00299   }
00300   return 1;
00301 #endif
00302 } // end main()
00303 
00304 
00305 //
00306 // Signal handlers.
00307 //
00308 
00309 extern "C"
00310 {
00311   void OmniEvents_Orb_shutdown(int signum)
00312   {
00313     OmniEvents::Orb::inst().shutdown(signum);
00314   }
00315 
00316   void OmniEvents_Orb_bumpTraceLevel(int signum)
00317   {
00318     omniORB::traceLevel=(omniORB::traceLevel+5)%45;
00319     DB(0,"TRACE LEVEL BUMPED TO "<<omniORB::traceLevel<<" BY SIGNAL "<<signum)
00320   }
00321 }

Generated on Fri Aug 26 20:56:14 2005 for OmniEvents by  doxygen 1.4.3-20050530