1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
|
// Package : omniEvents
// main.cc Created : 2004/08/01
// Author : Alex Tingle.
//
// Copyright (C) 1998 Paul Nader, 2004-2005 Alex Tingle.
//
// This file is part of the omniEvents application.
//
// omniEvents is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// omniEvents is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Description:
// Event Services Channel Factory implementation. The factory registers
// itself with the naming service. Clients wishing to create event
// channels can either use the factory by resolving its name with the
// naming service or create in-process channels.
//
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_GETOPT
# include <unistd.h>
extern char* optarg;
extern int optind;
#else
# include "getopt.h"
#endif
#include "main.h"
#include "omniEvents.h"
#include "naming.h"
#include "omniEventsLog.h"
#include "EventChannelFactory.h"
#include "Orb.h"
#include "daemon.h"
#include "version.h"
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGSET)
# include <signal.h>
# define SIGSET(sig,func) ::sigset(sig,func)
#elif defined(HAVE_SIGNAL_H)
# include <signal.h>
# define SIGSET(sig,func) ::signal(sig,func)
#endif
#ifdef HAVE_OMNIORB4
# include <omniORB4/internal/orbOptions.h>
#endif
#include <cstdlib>
#include <stdio.h> // for sprintf
int main(int argc, char** argv)
{
OmniEvents::Daemon daemon(argc,argv);
#ifdef HAVE_OMNIORB4
try
{
// Duplicate argv & argc.
int originalArgc =argc;
char** originalArgv =new char*[originalArgc];
for(int i=0; i<originalArgc; ++i)
originalArgv[i]=strdup(argv[i]);
// Remove ORB arguments from argc & argv.
try {
omni::orbOptions::singleton().extractInitOptions(argc,argv);
}
catch(...) {
argc=originalArgc;
argv=originalArgv;
}
#endif
using namespace OmniEvents;
//
// Process Options
const char* endPointNoListen =NULL;
int port =0;
const char* logDir =NULL;
const char* factoryName ="EventChannelFactory";
bool verbose =false;
int c;
while ((c = getopt(argc,argv,"O:a:p:l:P:N:dft:vVh")) != EOF)
{
switch (c)
{
case 'O': break; // Helps protect us from -ORB arguments.
// Initialisation options (only useful on first run)
case 'a': endPointNoListen=optarg;
break;
case 'p': port=atoi(optarg);
if (port <= 0)
{
cerr<<"\nError: port must be a positive integer"<<endl;
usage(argc,argv);
}
break;
// Other options
case 'l': logDir=optarg;
break;
case 'P': daemon.pidfile(optarg);
break;
case 'N': factoryName=optarg;
break;
case 'd': cerr<<"Option '-d' is deprecated. Use '-f' instead."<<endl;
daemon.foreground(true);
break;
case 'f': daemon.foreground(true);
break;
// Informational options
case 't': daemon.tracefile(optarg);
break;
case 'v': verbose=true;
break;
case 'V': cout<<OmniEvents::version()<<endl;
::exit(0);
case 'h':
default : usage(argc,argv);
break;
}
}
//
// Create database instance.
omniEventsLog logfile(logDir);
PersistNode* initialState =NULL;
if(logfile.fileExists(logfile.activeFilename()))
{
// Read library file.
initialState=logfile.parse();
// Check for incompatibilities between options and the file.
if(port && port!=initialState->child("ecf")->attrLong("port"))
{
cerr<<
"Error: Option '-p "<<port<<"' conflicts with value '"<<
initialState->child("ecf")->attrLong("port")<<"'\n stored in"
" database file '"<<logfile.activeFilename()<<"'.\n"
" Either delete the file to clear the database, or do not use the"
" '-p' option."<<endl;
exit(1);
}
if(endPointNoListen && string(endPointNoListen)!=
initialState->child("ecf")->attrString("endPointNoListen"))
{
cerr<<
"Error: Option '-a "<<endPointNoListen<<"' conflicts with value '"<<
initialState->child("ecf")->attrString("endPointNoListen")<<"'\n"
" stored in database file '"<<logfile.activeFilename()<<"'.\n"
" Either delete the file to clear the database, or do not use the"
" '-a' option."<<endl;
exit(1);
}
}
else if(logfile.fileExists(logfile.backupFilename()))
{
// Quit with an error.
cerr <<
"Error: backup file '" << logfile.backupFilename() << "' exists.\n"
" Rename it to '" << logfile.activeFilename() << "'\n"
" to recover the server's state, or delete it to create a new\n"
" database file." << endl;
exit(1);
}
else
{
// Create initial state without a library file.
initialState=logfile.bootstrap(port?port:11169,endPointNoListen);
}
port=initialState->child("ecf")->attrLong("port",port);
string endPoint2=initialState->child("ecf")->attrString("endPointNoListen");
//
// Daemonise
daemon.daemonize();
//
// Initialise orb & POAs.
#ifdef HAVE_OMNIORB4
char endPoint[64];
sprintf(endPoint,"giop:::%d",port);
if(endPoint2.empty())
{
const char* opts[][2] ={ {"endPoint",endPoint}, {0,0} };
Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
}
else
{
const char* opts[][2] ={
{"endPoint",endPoint},
{"endPointNoListen",endPoint2.c_str()},
{0,0} };
Orb::inst()._orb=CORBA::ORB_init(originalArgc,originalArgv,"omniORB4",opts);
}
#else
insertArgs(argc, argv, 1, 2);
argv[1] = strdup("-ORBpoa_iiop_port");
argv[2] = new char[32 + 1];
sprintf(argv[2], "%d", port);
Orb::inst()._orb=CORBA::ORB_init(argc,argv);
#endif
Orb::inst().resolveInitialReferences();
{
PortableServer::POAManager_var pman;
pman=Orb::inst()._RootPOA->the_POAManager();
pman->activate();
pman=Orb::inst()._omniINSPOA->the_POAManager();
pman->activate();
}
//
// If omniEvents is restarting then the omniEventsLog object
// will take care of creating the factory and any subordinate
// event channels, proxies, etc under it.
logfile.incarnateFactory(initialState);
delete initialState; // Tidy up.
initialState=NULL;
{
//
// Register factory with the Naming Service.
omniEvents::EventChannelFactory_var factory( logfile.factory()->_this() );
bindName2Object(
Orb::inst()._NameService.in(),
str2name(factoryName),
factory.in()
);
//
// Print the factory IOR.
if(verbose)
{
DB(1,"Starting omniEvents on port "<<port)
if(!endPoint2.empty())
DB(1,"Alternate endPoint "<<endPoint2.c_str())
CORBA::String_var iorstr =
Orb::inst()._orb->object_to_string(factory.in());
DB(1,iorstr.in())
}
} // factory reference is released.
#ifdef HAVE_SIGNAL_H
SIGSET(SIGINT , ::OmniEvents_Orb_shutdown);
SIGSET(SIGTERM, ::OmniEvents_Orb_shutdown);
# ifdef SIGUSR1
SIGSET(SIGUSR1, ::OmniEvents_Orb_bumpTraceLevel);
# endif
# ifdef SIGPIPE
SIGSET(SIGPIPE, SIG_IGN); // Ignore broken pipes
# endif
#endif
daemon.runningOk();
//
// Start the background tasks.
logfile.runWorker(); // Logfile's worker thread.
Orb::inst().run(); // Use the main thread to collect orphaned responses.
DB(1,"Shutdown requested.")
Orb::inst()._orb->shutdown(1); // Synchronous shutdown
Orb::inst()._orb->destroy(); // clean up
return 0; // Delete any pidfile & exit.
#ifdef HAVE_OMNIORB4
}
catch (CORBA::SystemException& ex) {
DB(0,"System exception: "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")")
}
catch (CORBA::Exception& ex) {
DB(0,"CORBA exception: "<<ex._name())
}
return 1;
#endif
} // end main()
//
// Signal handlers.
//
extern "C"
{
void OmniEvents_Orb_shutdown(int signum)
{
OmniEvents::Orb::inst().shutdown(signum);
}
void OmniEvents_Orb_bumpTraceLevel(int signum)
{
omniORB::traceLevel=(omniORB::traceLevel+5)%45;
DB(0,"TRACE LEVEL BUMPED TO "<<omniORB::traceLevel<<" BY SIGNAL "<<signum)
}
}
|