Esempio n. 1
0
bool checkDaemonExistence(const char* daemonName) 
{
    SingleLogger* logger = SingleLogger::InitLogger(); 
    std::string serviceName(daemonName);
    bool isRunning = false;
    std::string pidFileName("/var/run/" + serviceName + ".pid");
    std::ifstream pidFile(pidFileName.c_str(), std::ifstream::binary);
    if(pidFile.is_open())
    {
        long pid = 0;
        std::string pidLine;
        if (pidFile.is_open()) 
        {
            getline(pidFile, pidLine);
            pid = std::stoi(pidLine);
            kill(pid, 0);
            isRunning = !(errno == ESRCH);
        }
    }

    if (!isRunning) 
    {
        std::ofstream pidFile(pidFileName.c_str(), std::ofstream::binary);
        if (pidFile.is_open()) {
            pidFile << getpid();
            pidFile.close();
        }
        else
            logger->logMessage(SingleLogger::WARNING, "pid file is not created");
    } 
    else
        logger->logMessage(SingleLogger::ERROR, "daemon already running");

    return isRunning;
}
Esempio n. 2
0
bool
PidFile::createPidFile( void )
{
  
  remove( fileName );

  std::ofstream pidFile( fileName );

  if( ! pidFile.good() )
    {
      osErrno = errno;
    }
  else
    {
      pidFile << getpid() << std::endl;
    }

  if( ! pidFile.good() )
    osErrno = errno;
  
  pidFile.close();

  return( good() );
  
}
Esempio n. 3
0
/*!
 * @brief Gets crash-reporter-daemon pid and saves it to file.
 *
 * @param app Reference to application.
 * @return True, if first startup; otherwise false.
 */
bool getPid(QCoreApplication &app)
{
    QFile pidFile(CREPORTER_PID_FILE);
    qint64 pid = 0;
    bool firstStartup = true;

	// Get new PID.
	pid = app.applicationPid();
    qDebug() << __PRETTY_FUNCTION__  <<  CReporter::DaemonBinaryName
            << "[" << pid << "] starting...";

    if (pidFile.exists()) {
        firstStartup = false;
		qDebug() << __PRETTY_FUNCTION__ << "Removing stale PID file.";
		pidFile.remove();
	}
	
    if (pidFile.open(QIODevice::WriteOnly)) {
        QTextStream out(&pidFile);
		out << pid;
		pidFile.close();
	}

    qDebug() <<  __PRETTY_FUNCTION__ << "Startup delayed =" << firstStartup;
    return firstStartup;
}
Esempio n. 4
0
int Dynamic::getPid() const
{
    QFile pidFile(Utils::cacheDir(constDir, false)+constLockFile);

    if (pidFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
        QTextStream str(&pidFile);
        int pid=0;
        str >> pid;
        return pid;
    }
Esempio n. 5
0
  /** 
   * Stop a previously started Xrootd server 
   * 
   * @return true if stopped, false otherwise 
   */
  static Bool_t StopXrootd()
  {
    std::ifstream pidFile("xrd.pid");
    if (!pidFile) return false;

    TString s; s.ReadFile(pidFile);
    pidFile.close();
    gSystem->Unlink("xrd.pid");
    
    if (s.IsNull()) return false;

    Info("StopXrootd", "Stopping XRootd server (pid: %s)", s.Data());
    return gSystem->Exec(Form("kill -9 %s", s.Data())) == 0;
  }
Esempio n. 6
0
/**
 * Write a file containing the process id to current directory.
 * File name is written as "prefix.suffix.pid"
 * @parma prefix arbitrary string prefix (can be NULL) for filename
 * @param suffix arbitrary string suffix (can be NULL)
 * @param pid the current process id
 * @parma ppid the curren process parent id - NOT USED junk for now
 * @return 0 on success
 */
int WritePidFile(const char* prefix, const char* suffix, pid_t pid, pid_t ppid) {
  std::string pidFileName = std::string(prefix)
      + "."
      +  suffix
      + std::string(".pid");
  std::ofstream pidFile(pidFileName);
  if (pidFile.is_open()) {
    pidFile << pid;
    pidFile.flush();
    pidFile.close();
    return (0);
  } else {
    return (-1);
  }
}
Esempio n. 7
0
bool isRun(qint64 pid)
{
	QString pidPath(QDir::homePath());
	pidPath=pidPath+"/.config/qxkb.pid";
	qDebug()<<"Pid file locate :"<<pidPath;
	QFile pidFile(pidPath);
	QDir proc(QString("/proc"));
	if (pidFile.exists()) {
		qDebug()<<"File exist check pid";
		if (!pidFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
			qDebug()<<"Faled open file";
			return false;
		}
		QStringList proccessList=proc.entryList(QDir::Dirs);
		qDebug()<<"Proc list "<<proccessList;
		QTextStream in(&pidFile);
		while (!in.atEnd()) {
			QString pidString = in.readLine();
			qDebug()<<"Get exist pid"<<pidString;
			int index = proccessList.indexOf(pidString.trimmed());
			qDebug()<<"Index pid in list"<<index;
			if (index<0) {
				pidFile.close();
				pidFile.remove();
			} else {
				QString pidExist=proccessList.at(index);
				qDebug()<<"Compare processname: "<<pidExist;
				if (getName(pidExist)=="qxkb") {
					pidFile.close();
					return true;
				}
			}

		}
		pidFile.close();
		pidFile.remove();
	}
	if (!pidFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		qDebug()<<"Faled to create pid";
		return false;
	}
	qDebug()<<"Create pid";
	QTextStream out(&pidFile);
	out << QString::number(pid);
	pidFile.close();
	return false;
}
Esempio n. 8
0
long Dialog::verifyPidFile()
{
  QMessageBox messageBox;
  char *charPid = new char[pidLength];
  char *endPtr;
  long pidNumber;
  int charPidLen;
  QString configPathQStr(configPathStr.c_str());
  QString pidFileQStr(pidFileStr.c_str());
  QFile pidFile(configPathQStr + pidFileQStr);
  
  if (!pidFile.exists())
  {
    messageBox.information(this, "File not found",
                           "Could not find the PID file");
    return -1;
  }

  if (!pidFile.open(QFile::ReadOnly))
  {
    messageBox.information(this, "Could not open",
                           "Could not open the pid file");
    return -1;
  }

  if (0 >= pidFile.readLine(charPid, sizeof(charPid)))
  {
    messageBox.information(this, "Invalid read",
                           "Could not read");
    return -1;
  }

  /* readLine sempre coloca \n no final, se nao encontrar */
  charPidLen = strlen(charPid);
  pidNumber = strtol(charPid, &endPtr, numberBase);
  if (charPidLen != endPtr - charPid)
  {
    messageBox.information(this, "Invalid PID",
                           "Invalid PID number");
    return -1;
  }

  pidFile.close();
  return  pidNumber;
}
void writePidToFile()
{
   UtlString pidFileName = SipXecsService::Path(SipXecsService::RunDirType, SUPERVISOR_PID_FILE);
   char pidString[1024];
   sprintf(pidString, "%ld\n", (long)getpid());
   OsFile pidFile(pidFileName);
   if ( OS_SUCCESS == pidFile.open(OsFile::CREATE) )
   {
      size_t bytesWritten;
      if ( OS_SUCCESS != pidFile.write(pidString, strlen(pidString), bytesWritten) )
      {
         osPrintf("sipXsupervisor: could not write pidFile %s\n", pidFileName.data());
      }
      pidFile.close();
   }
   else
   {
      osPrintf("sipXsupervisor: could not open pidFile %s\n", pidFileName.data());
   }
}
Esempio n. 10
0
int
daemonShutdown(const String& daemonName, const ServiceEnvironmentIFCRef& env)
{
#ifndef WIN32
#if defined(OW_NETWARE)
	(void)daemonName;
	{
		NonRecursiveMutexLock l(g_shutdownGuard);
		g_shutDown = true;
		g_shutdownCond.notifyAll();
		pthread_yield();
	}
	if(!FromEventHandler)
	{
		UnRegisterEventNotification(DownEvent);
	}
#else
	String pidFile(env->getConfigItem(ConfigOpts::PIDFILE_opt, OW_DEFAULT_PIDFILE));
	PidFile::removePid(pidFile.c_str());
#endif
#endif
	shutdownSig();
	return 0;
}
Esempio n. 11
0
int startDaemon()
{
    pid_t pid;

    pid = fork();

	///NOTE: version in trunk checks for CHILD, not 0...
    if( pid  < 0 )
	exit( EXIT_FAILURE );

    if( pid > 0 )
	exit( EXIT_SUCCESS );

    ///NOTE: version in trunk checks for ERROR not 0...
    if( setsid() < 0 )
        exit( EXIT_FAILURE  );

	/// change to root in file system
    if( ( chdir( "/" ) ) < 0 ) 
        exit( EXIT_FAILURE  );

    umask( 0 );

    for( int i = sysconf( _SC_OPEN_MAX ); i > 0; i-- )
        close( i );

    /// check if the directory for pid file exist
    ifstream fin;
    string path = "/tmp/wonder";
    fin.open( path.c_str() , ios_base::in );

    if( !fin.is_open() )
    {
        /// create /tmp/wonder directory if it does not exist yet
        /// the sticky: anyone is able to create files, but
        /// not able to delete anyone elses files but their own
        int error = mkdir( path.c_str(), mode_t(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX));
        if( error != 0 )
            return 1;   
    }

    /// open file stream to write the pid in
    string name;
    ostringstream spid;

    /// get pid of parent process
    spid << getpid();

    if( twonderConf->user == NULL )
        pathPidfile = path + "/twonder." + spid.str() + ".pid";
    else
        pathPidfile = path + "/twonder." + ( string ) twonderConf->user + ".pid";

    ofstream pidFile( pathPidfile.c_str() );
    pidFile << spid.str();
    pidFile.close();

    /// write stdin to /dev/null
    freopen("/dev/null", "r", stdin );

    /// write stdout and stderr to the log file     
    freopen( "/var/log/wonder.log", "w", stdout );
    freopen( "/var/log/wonder.log", "w", stderr );

    return 0;
}
Esempio n. 12
0
/**
 * Main entry point for the application.
 */
int main (int argc, char* argv[])
{
    // Initialise the debug flags
    crt_init();

    // Set the stream references for rMessage(), redirect std::cout, etc.
    applog::initialiseLogStreams();

    // Initialise the context (application path / settings path, is OS-specific)
    module::ModuleRegistry::Instance().initialiseContext(argc, argv);

    // Acquire the appplication context ref (shortcut)
    const ApplicationContext& ctx = module::getRegistry().getApplicationContext();

    // The settings path is set, start logging now
    applog::LogFile::create("darkradiant.log");

#ifndef POSIX
    // Initialise the language based on the settings in the user settings folder
    // This needs to happen before gtk_init() to set up the environment for GTK
    language::LanguageManager().init(ctx);
#endif

    // Initialise gtkmm (don't set locale on Windows)
#ifndef POSIX
    Gtk::Main gtkmm_main(argc, argv, false);
#else
    Gtk::Main gtkmm_main(argc, argv, true);

#ifndef LOCALEDIR
#error LOCALEDIR not defined
#endif

    // Other POSIX gettext initialisation
    setlocale(LC_ALL, "");
    textdomain(GETTEXT_PACKAGE);
    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);

#endif

	// Initialise Glib threading if necessary
	if (!Glib::thread_supported()) 
	{
		Glib::thread_init();
	}

    Glib::add_exception_handler(&std::terminate);

#ifdef HAVE_GTKSOURCEVIEW
    // Initialise gtksourceviewmm
    gtksourceview::init();
#endif

    // Initialise GTKGLExtmm
    Gtk::GL::init(argc, argv);

    // reset some locale settings back to standard c
    // this is e.g. needed for parsing float values from textfiles
    setlocale(LC_NUMERIC, "C");
    setlocale(LC_TIME, "C");

    // Now that GTK is ready, activate the Popup Error Handler
    module::ModuleRegistry::Instance().initErrorHandler();

    {
        // Create the radiant.pid file in the settings folder
        // (emits a warning if the file already exists (due to a previous startup failure))
        applog::PIDFile pidFile(PID_FILENAME);

        ui::Splash::Instance().show_all();

        // Initialise the Reference in the GlobalModuleRegistry() accessor.
        module::RegistryReference::Instance().setRegistry(module::getRegistry());

        ui::Splash::Instance().setProgressAndText(_("Searching for Modules"), 0.0f);

        // Invoke the ModuleLoad routine to load the DLLs from modules/ and plugins/
#if defined(POSIX) && defined(PKGLIBDIR)
        // Load modules from compiled-in path (e.g. /usr/lib/darkradiant)
        module::Loader::loadModules(PKGLIBDIR);
#else
        // Load modules from application-relative path
        module::Loader::loadModules(ctx.getApplicationPath());
#endif

        module::getRegistry().initialiseModules();

        radiant::getGlobalRadiant()->postModuleInitialisation();

        // Delete the splash screen here
        ui::Splash::Instance().destroy();

        // Scope ends here, PIDFile is deleted by its destructor
    }

    // greebo: Check if we should run an automated test
    if (!profile::CheckAutomatedTestRun())
	{
        // Start the GTK main loop. This will run until a quit command is given by
        // the user
        Gtk::Main::run();
    }

    GlobalMap().freeMap();

    GlobalMainFrame().destroy();

    // Issue a shutdown() call to all the modules
    module::GlobalModuleRegistry().shutdownModules();

    // Close the logfile
    applog::LogFile::close();
    applog::shutdownStreams();

    return EXIT_SUCCESS;
}
Esempio n. 13
0
int CIMListenerProcess::cimserver_run(
    int argc,
    char** argv,
    Boolean shutdownOption,
    Boolean debugOutputOption)
{
    String logsDirectory;
    String homeDir = configManager->getListenerHome();

    //
    // Get an instance of the Config Manager.
    //
    //configManager = DynamicListenerConfig::getInstance();

    //
    // Check to see if we should Pegasus as a daemon
    //
    Boolean daemonOption;
#if defined(PEGASUS_OS_TYPE_WINDOWS)
    daemonOption = false;
#else
    daemonOption = true;
    for (int i=1; i < argc; i++)
    {
        if (strcmp(argv[i], OPTION_NO_DAEMON) == 0)
        {
            daemonOption = false;
            break;
        }
    }
#endif

    //
    // Get options (from command line and from configuration file); this
    // removes corresponding options and their arguments from the command
    // line.
    //
    try
    {
        String configFilePath = homeDir + "/" + DEFAULT_CONFIG_FILE;
        FileSystem::translateSlashes(configFilePath);
        configManager->initOptions(configFilePath);
    }
    catch (Exception& e)
    {
        MessageLoaderParms parms("DynListener.cimlistener.LISTENER_NOT_STARTED",
                "CIM Listener not started: $0", e.getMessage());

        Logger::put_l(Logger::ERROR_LOG, System::CIMLISTENER, Logger::SEVERE,
            parms);

        PEGASUS_STD(cerr) << argv[0] << ": " << MessageLoader::getMessage(parms)
            << PEGASUS_STD(endl);

        return(1);
    }

// l10n
    // Set the home directory, msg sub-dir, into the MessageLoader.
    // This will be the default directory where the resource bundles
    // are found.
    String msgHome = homeDir + "/msg";
    FileSystem::translateSlashes(msgHome);
    MessageLoader::setPegasusMsgHome(msgHome);

    //
    // Check to see if we need to shutdown CIMOM
    //
    if (shutdownOption)
    {
        //gracefully exit
        //Uncomment the following line when signals are implemented on all
        //platforms.
        //The workaround is to use a file.
#ifdef PEGASUS_HAS_SIGNALS
        PidFile pidFile(LISTENER_START_FILE);
        PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();

        if (pid == 0)
        {
           pidFile.remove();
           return (-1);
        }

        int rc = kill(pid, PEGASUS_SIGTERM);
        // check for success or failure of the kill operation
        if (rc == -1)
        {

            if (errno == EPERM)
            {
                MessageLoaderParms parms(
                  "DynListener.cimlistener.KILL_PERM_DENIED",
                  "Permission denied: Not permitted to"
                  "shutdown cimlistener process.");
                cout << MessageLoader::getMessage(parms) << endl;
            } else
            {
                MessageLoaderParms parms(
                    "DynListener.cimlistener.KILL_FAILED",
                    "Failed to shutdown cimlistener process. Error: \"$1\"",
                    strerror(errno));
                cout << MessageLoader::getMessage(parms) << endl;
            }
            return(rc);
        }

        //cimserver_kill(1);
#else
#if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) \
        || defined(PEGASUS_OS_ZOS) \
        || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE) \
        || defined(PEGASUS_OS_SOLARIS) \
        || defined(PEGASUS_OS_VMS)

        // Check to see if the CIM Listener is running.
        // No need to stop if not running.
        if (_serverRunStatus.isServerRunning())
        {
            PidFile pidFile(LISTENER_STOP_FILE);
            pidFile.setPid(System::getPID());
        }
        else
        {
            printf("CIM Listener may not be running.\n");
            return(0);
        }
#endif

#endif //PEGASUS_HAS_SIGNALS

        //l10n
        //cout << "CIM Server stopped." << endl;
        MessageLoaderParms parms("DynListener.cimlistener.LISTENER_STOPPED",
                                 "CIM Listener stopped.");
        cout << MessageLoader::getMessage(parms) << endl;
        return(0);
    }

    //get config options.
    //note that the paths will be converted to homedPaths in the lookup calls.
    Uint32 listenerPort;
    Boolean httpsConnection;
    String sslKeyFilePath;
    String sslCertificateFilePath;
    String sslCipherSuite;
    String consumerDir;
    String consumerConfigDir;
    Boolean enableConsumerUnload;
    Uint32 consumerIdleTimeout;
    Uint32 shutdownTimeout;
    String traceFile;
    Uint32 traceLevel;
    String traceComponents;

    try
    {
    configManager->lookupIntegerValue("listenerPort", listenerPort);
    httpsConnection = configManager->isTrue("enableHttpsListenerConnection");
    configManager->lookupValue("sslKeyFilePath", sslKeyFilePath);
    configManager->lookupValue("sslCertificateFilePath",
                               sslCertificateFilePath);
    if(!configManager->lookupValue("sslCipherSuite",sslCipherSuite))
    {
        throw InvalidPropertyValue("sslCipherSuite",sslCipherSuite);
    } 
    configManager->lookupValue("consumerDir", consumerDir);
    configManager->lookupValue("consumerConfigDir", consumerConfigDir);
    enableConsumerUnload = configManager->isTrue("enableConsumerUnload");
    configManager->lookupIntegerValue("consumerIdleTimeout",
                                       consumerIdleTimeout);
    configManager->lookupIntegerValue("consumerIdleTimeout",
                                      consumerIdleTimeout);
    configManager->lookupIntegerValue("shutdownTimeout", shutdownTimeout);
    configManager->lookupValue("traceFilePath", traceFile);
    configManager->lookupIntegerValue("traceLevel", traceLevel);
    configManager->lookupValue("traceComponents", traceComponents);

    }
    catch (Exception& ex)
    {
        cout << ex.getMessage() << endl;
        exit(0);
    }

    //Check listener port validity
    //ATTN: Do we need this?
    /*CString portString = listenerPort.getCString();
    char* end = 0;
    Uint32 port = strtol(portString, &end, 10);
    if(!(end != 0 && *end == '\0'))
    {
        PEGASUS_STD(cerr) << "Bad HTTP/HTTPS Port Value" << PEGASUS_STD(endl);
        exit(1);
    }*/

    //Configure trace options
    if (traceLevel > 0)
    {
        Uint32 traceLevelArg = 0;

        switch (traceLevel)
        {
        case 1: traceLevelArg = Tracer::LEVEL1; break;
        case 2: traceLevelArg = Tracer::LEVEL2; break;
        case 3: traceLevelArg = Tracer::LEVEL3; break;
        case 4: traceLevelArg = Tracer::LEVEL4; break;
        default: break;
        }

        Tracer::setTraceFile((const char*)traceFile.getCString());
        Tracer::setTraceComponents(traceComponents);
        Tracer::setTraceLevel(traceLevelArg);
    }

#if defined(PEGASUS_DEBUG)
    {
        // Put out startup up message.
        cout << _cimListenerProcess->getProductName() << " "
             << _cimListenerProcess->getVersion() << endl;
        MessageLoaderParms parms("DynListener.cimlistener.STARTUP_MESSAGE",
            "CIM Listener built $0 $1\nCIM Listener starting...",
            __DATE__,
            __TIME__);
    }
#endif

//l10n
// reset message loading to NON-process locale
MessageLoader::_useProcessLocale = false;
//l10n

    // Get the parent's PID before forking
    _serverRunStatus.setParentPid(System::getPID());

    // do we need to run as a daemon ?
    if (daemonOption)
    {
        if(-1 == _cimListenerProcess->cimserver_fork())
    {
        return(-1);
    }
    }

// l10n
    // Now we are after the fork...
    // Create a dummy Thread object that can be used to store the
    // AcceptLanguageList object for CIM requests that are serviced
    // by this thread (initial thread of server).  Need to do this
    // because this thread is not in a ThreadPool, but is used
    // to service CIM requests.
    // The run function for the dummy Thread should never be called,
    Thread *dummyInitialThread = new Thread(dummyThreadFunc, NULL, false);
    Thread::setCurrent(dummyInitialThread);
    try
    {
         Thread::setLanguages(LanguageParser::getDefaultAcceptLanguages());
    }
    catch(InvalidAcceptLanguageHeader& e)
    {
          Logger::put_l(Logger::ERROR_LOG, System::CIMLISTENER, Logger::SEVERE,
              MessageLoaderParms(
                  "src.Server.cimserver.FAILED_TO_SET_PROCESS_LOCALE",
                  "Could not convert the system process"
                  "locale into a valid AcceptLanguage format."));
          Logger::put(Logger::ERROR_LOG, System::CIMLISTENER, Logger::SEVERE,
                             e.getMessage());
    }

#if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) \
|| defined(PEGASUS_OS_ZOS) || defined(PEGASUS_OS_AIX) \
|| defined(PEGASUS_OS_PASE) \
|| defined(PEGASUS_OS_SOLARIS) || defined (PEGASUS_OS_VMS)
    umask(S_IWGRP|S_IWOTH);

    //
    // check if CIMServer is already running
    // if CIMServer is already running, print message and
    // notify parent process (if there is a parent process) to terminate
    //
    if (_serverRunStatus.isServerRunning())
    {
        MessageLoaderParms parms(
            "DynListener.cimlistener.UNABLE_TO_START_LISTENER_ALREADY_RUNNING",
            "Unable to start CIM Listener.\nCIM Listener is already running.");
        PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) <<
            PEGASUS_STD(endl);

        //
        // notify parent process (if there is a parent process) to terminate
        //
        if (daemonOption)
        {
            _cimListenerProcess->notify_parent(1);
        }

        return 1;
    }

#endif

    // try loop to bind the address, and run the server
    try
    {
#ifdef PEGASUS_HAS_SSL
        //create DynListener
        if (httpsConnection)
        {
            _cimListener = new DynamicListener(
                listenerPort,
                consumerDir,
                consumerConfigDir,
                true,
                sslKeyFilePath,
                sslCertificateFilePath,
                enableConsumerUnload,
                consumerIdleTimeout,
                shutdownTimeout,
                sslCipherSuite);
        }
        else
#endif
        {
            _cimListener = new DynamicListener(
                listenerPort,
                consumerDir,
                consumerConfigDir,
                enableConsumerUnload,
                consumerIdleTimeout,
                shutdownTimeout);
        }
        _cimListener->start();

        Logger::put_l(Logger::STANDARD_LOG,
            System::CIMLISTENER, Logger::INFORMATION,
            MessageLoaderParms(
                "DynListener.cimlistener.LISTENING_ON_PORT",
                "The CIM listener is listening on port $0.",
                listenerPort));


#if defined(PEGASUS_DEBUG)
        //Log startup options
        printf("Starting CIMListener with the following options\n");
        printf("\tlistenerPort %u\n", listenerPort);
        printf("\thttpsConnection %d\n", httpsConnection);
        printf("\tsslKeyFilePath %s\n",
                (const char*)sslKeyFilePath.getCString());
        printf("\tsslCertificateFilePath %s\n",
                (const char*)sslCertificateFilePath.getCString());
        printf("\tsslCipherSuite %s\n",
            (const char*)sslCipherSuite.getCString());
        printf("\tconsumerDir %s\n", (const char*)consumerDir.getCString());
        printf("\tconsumerConfigDir %s\n",
                (const char*)consumerConfigDir.getCString());
        printf("\tenableConsumerUnload %d\n", enableConsumerUnload);
        printf("\tconsumerIdleTimeout %u\n", consumerIdleTimeout);
        printf("\tshutdownTimeout %u\n", shutdownTimeout);
        printf("\ttraceFilePath %s\n", (const char*)traceFile.getCString());
        printf("\ttraceLevel %u\n", traceLevel);
        printf("\ttraceComponents %s\n",
                (const char*)traceComponents.getCString());
        printf("\tMessage home is %s\n", (const char*)msgHome.getCString());
#endif

    // notify parent process (if there is a parent process) to terminate
        // so user knows that there is cimserver ready to serve CIM requests.
    if (daemonOption)
        _cimListenerProcess->notify_parent(0);

#if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || \
    defined(PEGASUS_OS_ZOS) || defined(PEGASUS_OS_AIX) || \
    defined(PEGASUS_OS_PASE) || \
    defined(PEGASUS_OS_SOLARIS) || defined(PEGASUS_OS_VMS)
        //
        // create a file to indicate that the cimserver has started and
        // save the process id of the cimserver process in the file
        //
        _serverRunStatus.setServerRunning();
#endif

//#if defined(PEGASUS_DEBUG)
    cout << "Started. " << endl;
//#endif

        // Put server started message to the logger
        Logger::put_l(Logger::STANDARD_LOG, System::CIMLISTENER,
            Logger::INFORMATION,
            MessageLoaderParms(
                "src.Server.cimserver.STARTED_VERSION",
                "Started $0 version $1.",
                _cimListenerProcess->getProductName(),
                _cimListenerProcess->getVersion()));

#if defined(PEGASUS_OS_TYPE_UNIX)
        if (daemonOption && !debugOutputOption)
        {
            // Direct standard input, output, and error to /dev/null,
            // since we are running as a daemon.
            close(0);
            open("/dev/null", O_RDONLY);
            close(1);
            open("/dev/null", O_RDWR);
            close(2);
            open("/dev/null", O_RDWR);
        }
#endif

#if !defined(PEGASUS_OS_TYPE_WINDOWS)

// if signals are defined, do not use old file creation mechanism
#ifndef PEGASUS_HAS_SIGNALS
#if defined(PEGASUS_DEBUG)
        printf("Blocking until shutdown signal\n");
#endif
        while (true)
        {
            if (FileSystem::exists(LISTENER_STOP_FILE))
            {
                break;
            }

            Threads::sleep(500);
        }

#if defined(PEGASUS_DEBUG)
        printf("Received signal to shutdown\n");
#endif
        FileSystem::removeFile(LISTENER_STOP_FILE);
        _cimListener->stop();
#else // defined(PEGASUS_HAS_SIGNALS)

        //Temporary workaround is to use a file, as specified above.
        //wait until signalled to terminate
        int sig = _cimListenerProcess->cimserver_wait();
#if defined(PEGASUS_DEBUG)
        printf("Returned from sigwait %d\n", sig);
#endif
        if ((sig == PEGASUS_SIGTERM) || (sig == PEGASUS_SIGHUP))
        {
#if defined(PEGASUS_DEBUG)
            printf("Graceful shutdown\n");
#endif
            _cimListener->stop();
        }
#endif
#else
        //ATTN: Implement cimserver_wait for windows
        //so we don't have to loop here
        //The listener is stopped in the cimserver_stop method
        //by the service control manager
        while (true)
        {
            if (!_cimListener->isAlive())
            {
                break;
            }

            Sleep(500);
        }
#endif

#if defined(PEGASUS_DEBUG)
    PEGASUS_STD(cout) << "Stopped\n";
#endif

        //
        // normal termination
        //

        // Put server shutdown message to the logger
        Logger::put_l(Logger::STANDARD_LOG, System::CIMLISTENER,
            Logger::INFORMATION,
            MessageLoaderParms(
                "src.Server.cimserver.STOPPED",
                "$0 stopped.", _cimListenerProcess->getProductName()));
    }
    catch (Exception& e)
    {
        Logger::put_l(
            Logger::STANDARD_LOG, System::CIMLISTENER, Logger::WARNING,
            MessageLoaderParms(
                "src.Server.cimserver.ERROR",
                "Error: $0", e.getMessage()));

        MessageLoaderParms parms("DynListener.cimlistener.ERROR",
            "CIM Listener error: $0");
        PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) <<
            PEGASUS_STD(endl);

        //
        // notify parent process (if there is a parent process) to terminate
        //
        if (daemonOption)
                _cimListenerProcess->notify_parent(1);

        delete _cimListener;
        _cimListener = 0;

        return 1;
    }

    delete _cimListener;
    _cimListener = 0;

#if defined(PEGASUS_DEBUG)
    printf("Exiting child process\n");
#endif

    return 0;
}
Esempio n. 14
0
/**
 * daemonize() - detach process from user and disappear into the background
 * Throws DaemonException on error.
 */
void
daemonize(bool dbgFlg, const String& daemonName, const ServiceEnvironmentIFCRef& env)
{
#ifndef WIN32
#ifdef OW_NETWARE
	{
		NonRecursiveMutexLock l(g_shutdownGuard);
		g_shutDown = false;
	}
#endif
	initDaemonizePipe();

	// If we're running as root and owcimomd.drop_root_privileges != "false", then try to switch users/groups to owcimomd/owcimomd
	if (geteuid() == 0 && !env->getConfigItem(ConfigOpts::DROP_ROOT_PRIVILEGES_opt, OW_DEFAULT_DROP_ROOT_PRIVILEGES).equalsIgnoreCase("false"))
	{
		const char OWCIMOMD_USER[] = "owcimomd";
		// dont need to worry about thread safety here, the threads won't start until later.
		struct passwd* owcimomdInfo = ::getpwnam(OWCIMOMD_USER);
		if (!owcimomdInfo)
		{
			OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): getpwnam(\"owcimomd\")");
		}
		if (::setgid(owcimomdInfo->pw_gid) != 0)
		{
			OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): setgid");
		}
		if (::initgroups(owcimomdInfo->pw_name, owcimomdInfo->pw_gid) != 0)
		{
			OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): initgroups");
		}
		if (::setuid(owcimomdInfo->pw_uid) != 0)
		{
			OW_THROW_ERRNO_MSG(DaemonException, "Platform::daemonize(): setuid");
		}
	}


	int pid = -1;
#if !defined(OW_NETWARE)
	String pidFile(env->getConfigItem(ConfigOpts::PIDFILE_opt, OW_DEFAULT_PIDFILE));
	pid = PidFile::checkPid(pidFile.c_str());
	// Is there already another instance of the cimom running?
	if (pid != -1)
	{
		OW_THROW(DaemonException,
			Format("Another instance of %1 is already running [%2]",
				daemonName, pid).c_str());
	}
#endif
	if (!dbgFlg)
	{
#if !defined(OW_NETWARE) && !defined(WIN32)
		pid = fork();
		switch (pid)
		{
			case 0:
				break;
			case -1:
				OW_THROW_ERRNO_MSG(DaemonException,
					"FAILED TO DETACH FROM THE TERMINAL - First fork");
			default:
				int status = DAEMONIZE_FAIL;
				if (daemonize_upipe->readInt(&status) < 1
						|| status != DAEMONIZE_SUCCESS)
				{
					cerr << "Error starting CIMOM.  Check the log files." << endl;
					_exit(1);
				}
				_exit(0); // exit the original process
		}
		if (setsid() < 0)					  // shoudn't fail on linux
		{
			OW_THROW(DaemonException,
				"FAILED TO DETACH FROM THE TERMINAL - setsid failed");
		}
		pid = fork();
		switch (pid)
		{
			case 0:
				break;
			case -1:
				{
					// Save the error number, since the sendDaemonizeStatus function can cause it to change.
					int saved_errno = errno;
					sendDaemonizeStatus(DAEMONIZE_FAIL);
					// Restore the real error number.
					errno = saved_errno;
					OW_THROW_ERRNO_MSG(DaemonException,
						"FAILED TO DETACH FROM THE TERMINAL - Second fork");
					exit(1);
				}
			default:
				_exit(0);
		}
#endif
		chdir("/");
		close(0);
		close(1);
		close(2);
		open("/dev/null", O_RDONLY);
		open("/dev/null", O_WRONLY);
		dup(1);
	}
	else
	{
		pid = getpid();
	}
	umask(0077); // ensure all files we create are only accessible by us.
#if !defined(OW_NETWARE)
	if (PidFile::writePid(pidFile.c_str()) == -1)
	{
		// Save the error number, since the sendDaemonizeStatus function can cause it to change.
		int saved_errno = errno;
		sendDaemonizeStatus(DAEMONIZE_FAIL);
		// Restore the real error number.
		errno = saved_errno;
		OW_THROW_ERRNO_MSG(DaemonException,
			Format("Failed to write the pid file (%1)", pidFile).c_str());
	}
#endif
	OW_LOG_INFO(env->getLogger(COMPONENT_NAME), Format("Platform::daemonize() pid = %1", ::getpid()));
#endif
	initSig();
#ifndef WIN32
	setupSigHandler(dbgFlg);
#endif

#ifdef OW_HAVE_PTHREAD_ATFORK
	// this registers shutdownSig to be run in the child whenever a fork() happens. 
	// This will prevent a child process from writing to the signal pipe and shutting down the parent.
	::pthread_atfork(NULL, NULL, &shutdownSig);
#endif
}
Esempio n. 15
0
int _SMERP_posixMain( int argc, char* argv[] )
{
// i18n global stuff
	if ( setlocale( LC_ALL, "" ) == NULL )	{
		std::cerr << "Unable to set locale. Falling back to default." << std::endl;
	}
	else	{
		if ( bindtextdomain( "SMERP", "../po" ) == NULL )	{
			std::cerr << "Not enough memory to bind textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		if ( textdomain( "SMERP" ) == NULL )	{
			std::cerr << "Not enough memory to set textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
	}
// end of i18n global stuff

	try	{
		_SMERP::Version		appVersion( MAJOR_VERSION, MINOR_VERSION, REVISION_NUMBER );
		_SMERP::CmdLineConfig	cmdLineCfg;
		const char		*configFile;

// it's just a DUMMY for now
		_SMERP::HandlerConfiguration	handlerConfig;

		if ( !cmdLineCfg.parse( argc, argv ))	{	// there was an error parsing the command line
			std::cerr << cmdLineCfg.errMsg() << std::endl << std::endl;
			cmdLineCfg.usage( std::cerr );
			std::cerr << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
// command line has been parsed successfully
// if cmdLineCfg.errMsg() is not empty than we have a warning
		if ( !cmdLineCfg.errMsg().empty() )	// there was a warning parsing the command line
			std::cerr << "BOO:" << cmdLineCfg.errMsg() << std::endl << std::endl;

// if we have to print the version or the help do it and exit
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_VERSION )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_HELP )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			cmdLineCfg.usage( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

// decide what configuration file to use
		if ( !cmdLineCfg.cfgFile.empty() )	// if it has been specified than that's The One ! (and only)
			configFile = cmdLineCfg.cfgFile.c_str();
		else
			configFile = _SMERP::CfgFileConfig::chooseFile( DEFAULT_MAIN_CONFIG,
								       DEFAULT_USER_CONFIG,
								       DEFAULT_LOCAL_CONFIG );
		if ( configFile == NULL )	{	// there is no configuration file
			std::cerr << gettext ( "MOMOMO: no configuration file found !" ) << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}

		_SMERP::CfgFileConfig	cfgFileCfg;
		if ( !cfgFileCfg.parse( configFile ))	{	// there was an error parsing the configuration file
			std::cerr << cfgFileCfg.errMsg() << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		else if ( !cfgFileCfg.errMsg().empty())
			std::cerr << cfgFileCfg.errMsg() << std::endl;
// configuration file has been parsed successfully
// build the application configuration
		_SMERP::ApplicationConfiguration config( cmdLineCfg, cfgFileCfg);

// now here we know where to log to on stderr
		_SMERP::LogBackend::instance().setConsoleLevel( config.stderrLogLevel );

// Check the configuration
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::CHECK_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			if ( config.check() )	{
				if ( config.errMsg().empty() )	{
					std::cout << "Configuration OK" << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
				else	{
					std::cout << "WARNING: " << config.errMsg() << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
			}
			else	{
				std::cout << "ERROR: " << config.errMsg() << std::endl << std::endl;
				return _SMERP::ErrorCodes::OK;
			}
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			config.print( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::TEST_CONFIG )	{
			std::cout << "Not implemented yet" << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		// Daemon stuff
		if( !config.foreground ) {
			// Aba: maybe also in the foreground?
			// try to lock the pidfile, bail out if not possible
			if( boost::filesystem::exists( config.pidFile ) ) {
				boost::interprocess::file_lock lock( config.pidFile.c_str( ) );
				if( lock.try_lock( ) ) {
					std::cerr << "Pidfile is locked, another daemon running?" << std::endl;
					return _SMERP::ErrorCodes::FAILURE;
				}
			}

			// daemonize, lose process group, terminal output, etc.
			if( daemon( 0, 0 ) ) {
				std::cerr << "Daemonizing server failed" << std::endl;
				return _SMERP::ErrorCodes::FAILURE;
			}

			// now here we lost constrol over the console, we should
			// create a temporary logger which at least tells what's
			// going on in the syslog
			_SMERP::LogBackend::instance().setSyslogLevel( config.syslogLogLevel );
			_SMERP::LogBackend::instance().setSyslogFacility( config.syslogFacility );
			_SMERP::LogBackend::instance().setSyslogIdent( config.syslogIdent );

			// if we are root we can drop privileges now
			struct group *groupent;
			struct passwd *passwdent;

			groupent = getgrnam( config.group.c_str( ) );
			passwdent = getpwnam( config.user.c_str( ) );
			if( groupent == NULL || passwdent == NULL ) {
				LOG_CRITICAL << "Illegal group '" << config.group << "' or user '" << config.user << "'";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setgid( groupent->gr_gid ) < 0 ) {
				LOG_CRITICAL << "setgid for group '" << config.group << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setuid( passwdent->pw_uid ) < 0 ) {
				LOG_CRITICAL << "setgid for user '" << config.user << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			// create a pid file and lock id
			std::ofstream pidFile( config.pidFile.c_str( ), std::ios_base::trunc );
			if( !pidFile.good( ) ) {
				LOG_CRITICAL << "Unable to create PID file '" << config.pidFile << "'!";
				return _SMERP::ErrorCodes::FAILURE;
			}
			pidFile << getpid( ) << std::endl;
			pidFile.close( );

			// Create the final logger based on the configuration
			// file logger only here to get the right permissions
			_SMERP::LogBackend::instance().setLogfileLevel( config.logFileLogLevel );
			_SMERP::LogBackend::instance().setLogfileName( config.logFile );
		}

		// Block all signals for background thread.
		sigset_t new_mask;
		sigfillset( &new_mask );
		sigset_t old_mask;
		pthread_sigmask( SIG_BLOCK, &new_mask, &old_mask );

		LOG_NOTICE << "Starting server";

		// Run server in background thread(s).
		_SMERP::ServerHandler	handler( handlerConfig );
		_SMERP::Network::server s( config.address, config.SSLaddress, handler,
					   config.threads, config.maxConnections );
		boost::thread t( boost::bind( &_SMERP::Network::server::run, &s ));

		// Restore previous signals.
		pthread_sigmask( SIG_SETMASK, &old_mask, 0 );

		// Wait for signal indicating time to shut down.
		sigset_t wait_mask;
		sigemptyset( &wait_mask );
		sigaddset( &wait_mask, SIGINT );
		sigaddset( &wait_mask, SIGQUIT );
		sigaddset( &wait_mask, SIGTERM );
		pthread_sigmask( SIG_BLOCK, &wait_mask, 0 );
		int sig = 0;
		sigwait( &wait_mask, &sig );

		// Stop the server.
		LOG_INFO << "Stopping server";
		s.stop();
		t.join();
		LOG_NOTICE << "Server stopped";

		// Daemon stuff
		if( !config.foreground ) {
			(void)remove( config.pidFile.c_str( ) );
		}
	}
	catch (std::exception& e)	{
		// Aba: how to delete the pid file here?
		LOG_ERROR << "posixMain: exception: " << e.what() << "\n";
		return _SMERP::ErrorCodes::FAILURE;
	}

	return _SMERP::ErrorCodes::OK;
}
Esempio n. 16
0
int main( int argc, char** argv )
{
	int err = 0;
	std::string argOutputDir; 
	std::string symbolFile;
	std::string configFile;
	std::string password;
	bool printDebug; 
    bool isLogging;
    int zero = 0;  

    (void) signal(SIGINT, sighandler);
    (void) signal(SIGTERM, sighandler);
    (void) signal(SIGHUP, sighandler);

	g_zmq_context = zmq_init(1);
	assert(g_zmq_context);
	pub_socket = zmq_socket(g_zmq_context, ZMQ_PUB);
    zmq_setsockopt(pub_socket, ZMQ_LINGER, &zero, sizeof(zero));
	assert(pub_socket);


    GOOGLE_PROTOBUF_VERIFY_VERSION;


	try {
		po::options_description desc("Allowed options");
		desc.add_options()
			("help", "produce help message")
			("c", po::value<std::string>(), "<config file>")
			("s", po::value<std::string>(), "<symbol file>")
			("o", po::value<std::string>(), "<output path>")
			("nolog", po::value<int>()->implicit_value(0), "disable logging (FIX and tick)")
			("d", "debug info")
		;
		
		po::variables_map vm;        
		po::store(po::parse_command_line(argc, argv, desc), vm);
		po::notify(vm);    

		if (vm.count("nolog")) {
            std::cout << "Logging disabled" << std::endl;
            //isLogging = (vm["nolog"].as<int>() == 1 ? false : true);
            isLogging = false;
		}
        else { 
            std::cout << "Logging enabled" << std::endl;
            isLogging = true;
        }
		if (vm.count("help")) {
			std::cout << desc << "\n";
			return 1;
		}
		if (vm.count("o")) {
			std::cout << "Output path: " << vm["o"].as<std::string>() << "\n";
            argOutputDir = vm["o"].as<std::string>();
		} else {
			// set default
			std::cout << "Output path file was not set \n";
		}
		if (vm.count("s")) {
			std::cout << "Symbol file: " << vm["s"].as<std::string>() << "\n";
			symbolFile = vm["s"].as<std::string>();
		} else {
			// use default name for symbols file name 
			symbolFile = "symbols.cfg"; 
			std::cout << "Using default symbols file: symbols.cfg\n"; 
		}
		if (vm.count("c")) {
			std::cout << "Config file: " << vm["c"].as<std::string>() << ".\n";
			configFile = vm["c"].as<std::string>();
		} else {
			std::cout << "Config file was not set.\n";
			err++;
		}
		printDebug = vm.count("d") > 0; 
			
		/* moved passwords to cfg files 
		if (vm.count("p")) {
			std::cout << "Pass: "******"p"].as<std::string>() << ".\n";
			password = vm["p"].as<std::string>();
		} else {
			std::cout << "Password was not set.\n";
			err++;
		}
		*/ 
	}
	catch(std::exception& e) {
		std::cerr << "EXCEPTION:" << e.what();
		return 1;
	}
	if (err > 0) {
		std::cout << "Aborting due to missing parameters.\n";
		return 1;
	}
	
	/* 
 	* @see http://www.boost.org/doc/libs/1_41_0/doc/html/program_options.html
 	*/
	
	std::vector<std::string> symbols = readSymbols(symbolFile);
	try
	{
		FIX::SessionSettings settings(configFile);
                std::set<FIX::SessionID> sessions = settings.getSessions ();
		assert(sessions.size() == 1); 
		FIX::SessionID sessionId = *(sessions.begin()); 
		const FIX::Dictionary& dict = settings.get(sessionId);
		ApplicationConfig config;  

        // MIC code for adding to output filename 
		config.mic_string = dict.has("MIC") ? dict.getString("MIC") : ""; 
        std::cout << "My MIC is: " << config.mic_string << std::endl;


        capk::get_config_params(g_zmq_context, "tcp://127.0.0.1:11111", &all_venue_config);
        capkproto::venue_configuration my_config = capk::get_venue_config(&all_venue_config, config.mic_string.c_str());
        std::cout << "Received config:\n" << my_config.DebugString() << std::endl;

        // venue id as for protobuf usage to identify venue
        if (my_config.venue_id() == "") {
            std::cerr << "venue_id not set!" << std::endl;
            exit(-1);
        }
        else {
            // boost version of atoi
            if (qi::parse(my_config.venue_id().begin(), my_config.venue_id().end(),  qi::int_, config.venue_id) == false) {
                std::cout << "Can't parse venue_id"  << std::endl;
                exit(-1); 
            }
            if (config.venue_id == 0) {
                std::cerr << "venue_id can not be 0" << std::endl;
                exit(-1);
            }
            std::cout << "Set venue_id to: " << config.venue_id << std::endl;
        }

        // Username and password settings
		config.username = dict.has("Username") ? dict.getString("Username") : ""; 
		config.password = dict.has("Password") ? dict.getString("Password") : ""; 
		config.sendPasswordInRawDataField = dict.has("SendPasswordInRawData") && 
		    dict.getBool("SendPasswordInRawData");

        // Should use aggregated book?  
        config.aggregatedBook = dict.has("AggregatedBook") && dict.getBool("AggregatedBook");
        std::cout << "Aggregated book: " << config.aggregatedBook << std::endl;

        // Should we reset sequence numbers? 
		bool bReset = dict.has("ResetSeqNo") && dict.getBool("ResetSeqNo");  
		std::cout << "Resetting sequence numbers: " << bReset << std::endl; 

        // How to send market data requests - bulk or multiple messages
		config.sendIndividualMarketDataRequests = 
            dict.has("SendIndividualMarketDataRequests") && dict.getBool("SendIndividualMarketDataRequests");
		std::cout << "Send individual market data requests: " 
            << config.sendIndividualMarketDataRequests << std::endl;

        // Fix Version string
		config.version = dict.has("FIXVersion") ? (FIXVersion)atoi(dict.getString("FIXVersion").c_str()) : FIX_42;
		std::cout << "Using FIX version: " << config.version << std::endl;

        // Market depth 
		std::string depth = dict.has("MarketDepth") ? dict.getString("MarketDepth") : ""; 
        config.marketDepth = atoi(depth.c_str());
		std::cout << "Setting market depth: " << config.marketDepth << std::endl;

        // Update Type 
		long updateType = dict.has("MDUpdateType") ? dict.getLong("MDUpdateType") : -1; 
		std::cout << "Setting update type: " << updateType << std::endl;

        // Debug settings
		config.printDebug = printDebug; 

		Application application(bReset, config);
        papplication = &application;
		application.addSymbols(symbols);
    
        // if user specified an output dir, then put files into date-sorted
        // subdirectories, otherwise put into the default dirs specified in 
        // config file 
        std::string orderBooksOutputDir = ".";
        std::string logOutputDir = dict.has("FileLogPath") ? dict.getString("FileLogPath") : "."; 
        std::string storeOutputDir = dict.has("FileStorePath") ? dict.getString("FileStorePath") : ".";

        if (argOutputDir.length() > 0) { 
            orderBooksOutputDir = argOutputDir; 
            fs::path argPath = fs::path(argOutputDir); 
            if (!fs::exists(argPath)) { fs::create_directories(argPath); }
            
            /* put both order books and message logs in subdirs, 
               but put the store at the root dir 
            */ 
            fs::path logOutputPath = argPath / fs::path("log");  
			if (!fs::exists(logOutputPath)) { fs::create_directory(logOutputPath); } 
			logOutputDir = logOutputPath.string(); 

            fs::path storeOutputPath = argPath / fs::path("store"); 
			if (!fs::exists(storeOutputPath)) { fs::create_directory(storeOutputPath); }
			storeOutputDir = storeOutputPath.string(); 
        }

        pid_t pid = getpid();
        pid_t ppid = getppid();
        
        printf("pid: %d, ppid: %d\n", pid, ppid);
        std::string pidFileName = std::string(argv[0]) + "." +  config.mic_string + std::string(".pid");
        std::ofstream pidFile(pidFileName);
        if (pidFile.is_open()) {
            pidFile << pid;
            pidFile.flush();
        }
        else {
            std::cerr << "Can't write pid file - exiting";
            exit(-1);
        }

        // Get the bind address for zmq sockets
        bool isPublishing = dict.has("should_publish_prices") && dict.getBool("should_publish_prices");
        if (isPublishing) {
            std::cout << "Collector is publishing prices to: " << my_config.market_data_broadcast_addr() << std::endl;
        }
        else {
            std::cout << "Collector is NOT publishing prices" << std::endl;
        }

        // ZMQ initialization
        if (isPublishing) {
            zmq_bind(pub_socket, my_config.market_data_broadcast_addr().c_str());
            application.setZMQContext(g_zmq_context);
            application.setZMQSocket(pub_socket);
        }
        application.setPublishing(isPublishing);
        application.setLogging(isLogging);

		// Set MDUpdateType
		application.setUpdateType(updateType);
        
        // orderbook output setup
		application.setDataPath(orderBooksOutputDir);
        // fix logging params

        if (isLogging) {
            std::cout << "Logging with FileStoreFactory" << std::endl;
		    FIX::FileStoreFactory fileStoreFactory(storeOutputDir);         
		    FIX::FileLogFactory logFactory(logOutputDir);
		    pinitiator = new FIX::SocketInitiator(application, fileStoreFactory, settings, logFactory);
        }
        else {
            std::cout << "Logging with NullStoreFactory" << std::endl;
            FIX::NullStoreFactory nullStoreFactory;
		    pinitiator = new FIX::SocketInitiator(application, nullStoreFactory, settings);
        }
        //pinitiator = &initiator;
		std::cout << "Starting initiator" << std::endl; 
		pinitiator->start();

		char x;
		while(std::cin >> x) {
			if (x == 'q') {
				break;
			}
		}
		std::cout << "Stopping initiator..." << std::endl;
		pinitiator->stop();
		return 0;
	}
	catch ( FIX::Exception & e )
	{
		std::cout << e.what();
		return 1;
	}
    
}