text: // Copyright (c) 2009-2010 Satoshi Nakamoto
  // Copyright (c) 2009-2013 The Bitcoin developers
  // Distributed under the MIT/X11 software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
  #include "rpcserver.h"
  #include "rpcclient.h"
  #include "init.h"
  #include "main.h"
  #include "noui.h"
  #include "ui_interface.h"
  #include "util.h"
  
  #include <boost/algorithm/string/predicate.hpp>
  #include <boost/filesystem.hpp>
  
  static bool fDaemon;
  
  void DetectShutdownThread(boost::thread_group* threadGroup)
  {
      bool fShutdown = ShutdownRequested();
      // Tell the main threads to shutdown.
      while (!fShutdown)
      {
          MilliSleep(200);
          fShutdown = ShutdownRequested();
      }
      if (threadGroup)
      {
          threadGroup->interrupt_all();
          threadGroup->join_all();
      }
  }
  
  bool AppInit(int argc, char* argv[])
  {
      boost::thread_group threadGroup;
      boost::thread* detectShutdownThread = NULL;
  
      bool fRet = false;
      try
      {
          // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
          ParseParameters(argc, argv);
          if (!boost::filesystem::is_directory(GetDataDir(false)))
          {
              fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
              return false;
          }
          try
          {
              ReadConfigFile(mapArgs, mapMultiArgs);
          } catch(std::exception &e) {
              fprintf(stderr,"Error reading configuration file: %s\n", e.what());
              return false;
          }
  
          if (mapArgs.count("-?") || mapArgs.count("--help"))
          {
              // First part of help message is specific to bitcoind / RPC client
              std::string strUsage = _("runecoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n\n" +
                  _("Usage:") + "\n" +
                    "  runecoind [options]                     " + _("Start runecoin Core Daemon") + "\n" +
                  _("Usage (deprecated, use runecoin-cli):") + "\n" +
                    "  runecoind [options] <command> [params]  " + _("Send command to runecoin Core") + "\n" +
                    "  runecoind [options] help                " + _("List commands") + "\n" +
                    "  runecoind [options] help <command>      " + _("Get help for a command") + "\n";
  
              strUsage += "\n" + HelpMessage(HMM_BITCOIND);
              strUsage += "\n" + HelpMessageCli(false);
  
              fprintf(stdout, "%s", strUsage.c_str());
              return false;
          }
  
          // Command-line RPC
          bool fCommandLine = false;
          for (int i = 1; i < argc; i++)
              if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "runecoin:"))
                  fCommandLine = true;
  
          if (fCommandLine)
          {
              int ret = CommandLineRPC(argc, argv);
              exit(ret);
          }
  #ifndef WIN32
          fDaemon = GetBoolArg("-daemon", false);
          if (fDaemon)
          {
              fprintf(stdout, "runecoin server starting\n");
  
              // Daemonize
              pid_t pid = fork();
              if (pid < 0)
              {
                  fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
                  return false;
              }
              if (pid > 0) // Parent process, pid is child process id
              {
                  CreatePidFile(GetPidFile(), pid);
                  return true;
              }
              // Child process falls through to rest of initialization
  
              pid_t sid = setsid();
              if (sid < 0)
                  fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
          }
  #endif
          SoftSetBoolArg("-server", true);
  
          detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
          fRet = AppInit2(threadGroup);
      }
      catch (std::exception& e) {
          PrintExceptionContinue(&e, "AppInit()");
      } catch (...) {
          PrintExceptionContinue(NULL, "AppInit()");
      }
  
      if (!fRet)
      {
          if (detectShutdownThread)
              detectShutdownThread->interrupt();
  
          threadGroup.interrupt_all();
      }
  
      if (detectShutdownThread)
      {
          detectShutdownThread->join();
          delete detectShutdownThread;
          detectShutdownThread = NULL;
      }
      Shutdown();
  
      return fRet;
  }
  
  int main(int argc, char* argv[])
  {
      SetupEnvironment();
  
      bool fRet = false;
  
      // Connect bitcoind signal handlers
      noui_connect();
  
      fRet = AppInit(argc, argv);
  
      if (fRet && fDaemon)
          return 0;
  
      return (fRet ? 0 : 1);
  }
  