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

Generated on Mon Jan 9 03:52:13 2006 for OmniEvents by  doxygen 1.4.6