Better wording for transaction fee notification messages
[novacoin.git] / init.cpp
index ba57866..8f72181 100644 (file)
--- a/init.cpp
+++ b/init.cpp
@@ -7,6 +7,14 @@
 
 
 
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Shutdown
+//
+
 void ExitTimeout(void* parg)
 {
 #ifdef __WXMSW__
@@ -33,6 +41,7 @@ void Shutdown(void* parg)
         DBFlush(false);
         StopNode();
         DBFlush(true);
+        boost::filesystem::remove(GetPidFile());
         CreateThread(ExitTimeout, NULL);
         Sleep(50);
         printf("Bitcoin exiting\n\n");
@@ -48,156 +57,11 @@ void Shutdown(void* parg)
     }
 }
 
-
-
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Startup folder
-//
-
-#ifdef __WXMSW__
-string StartupShortcutPath()
-{
-    return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
-}
-
-bool GetStartOnSystemStartup()
+void HandleSIGTERM(int)
 {
-    return filesystem::exists(StartupShortcutPath().c_str());
+    fRequestShutdown = true;
 }
 
-void SetStartOnSystemStartup(bool fAutoStart)
-{
-    // If the shortcut exists already, remove it for updating
-    remove(StartupShortcutPath().c_str());
-
-    if (fAutoStart)
-    {
-        CoInitialize(NULL);
-
-        // Get a pointer to the IShellLink interface.
-        IShellLink* psl = NULL;
-        HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
-                                CLSCTX_INPROC_SERVER, IID_IShellLink,
-                                reinterpret_cast<void**>(&psl));
-
-        if (SUCCEEDED(hres))
-        {
-            // Get the current executable path
-            TCHAR pszExePath[MAX_PATH];
-            GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
-
-            // Set the path to the shortcut target
-            psl->SetPath(pszExePath);
-            PathRemoveFileSpec(pszExePath);
-            psl->SetWorkingDirectory(pszExePath);
-            psl->SetShowCmd(SW_SHOWMINNOACTIVE);
-
-            // Query IShellLink for the IPersistFile interface for
-            // saving the shortcut in persistent storage.
-            IPersistFile* ppf = NULL;
-            hres = psl->QueryInterface(IID_IPersistFile,
-                                       reinterpret_cast<void**>(&ppf));
-            if (SUCCEEDED(hres))
-            {
-                WCHAR pwsz[MAX_PATH];
-                // Ensure that the string is ANSI.
-                MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
-                // Save the link by calling IPersistFile::Save.
-                hres = ppf->Save(pwsz, TRUE);
-                ppf->Release();
-            }
-            psl->Release();
-        }
-        CoUninitialize();
-    }
-}
-
-#elif defined(__WXGTK__)
-
-//
-// Follow the Desktop Application Autostart Spec:
-//  http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
-//
-
-boost::filesystem::path GetAutostartDir()
-{
-    namespace fs = boost::filesystem;
-
-    char* pszConfigHome = getenv("XDG_CONFIG_HOME");
-    if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart");
-    char* pszHome = getenv("HOME");
-    if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart");
-    return fs::path();
-}
-
-boost::filesystem::path GetAutostartFilePath()
-{
-    return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop");
-}
-
-bool GetStartOnSystemStartup()
-{
-    boost::filesystem::ifstream optionFile(GetAutostartFilePath());
-    if (!optionFile.good())
-        return false;
-    // Scan through file for "Hidden=true":
-    string line;
-    while (!optionFile.eof())
-    {
-        getline(optionFile, line);
-        if (line.find("Hidden") != string::npos &&
-            line.find("true") != string::npos)
-            return false;
-    }
-    optionFile.close();
-
-    return true;
-}
-
-void SetStartOnSystemStartup(bool fAutoStart)
-{
-    if (!fAutoStart)
-    {
-        unlink(GetAutostartFilePath().native_file_string().c_str());
-    }
-    else
-    {
-        boost::filesystem::create_directories(GetAutostartDir());
-
-        boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
-        if (!optionFile.good())
-        {
-            wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin");
-            return;
-        }
-        // Write a bitcoin.desktop file to the autostart directory:
-        char pszExePath[MAX_PATH+1];
-        memset(pszExePath, 0, sizeof(pszExePath));
-        readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1);
-        optionFile << "[Desktop Entry]\n";
-        optionFile << "Type=Application\n";
-        optionFile << "Name=Bitcoin\n";
-        optionFile << "Exec=" << pszExePath << "\n";
-        optionFile << "Terminal=false\n";
-        optionFile << "Hidden=false\n";
-        optionFile.close();
-    }
-}
-#else
-
-// TODO: OSX startup stuff; see:
-// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
-
-bool GetStartOnSystemStartup() { return false; }
-void SetStartOnSystemStartup(bool fAutoStart) { }
-
-#endif
-
-
 
 
 
@@ -205,122 +69,40 @@ void SetStartOnSystemStartup(bool fAutoStart) { }
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// CMyApp
+// Start
 //
 
-// Define a new application
-class CMyApp : public wxApp
+#ifndef GUI
+int main(int argc, char* argv[])
 {
-public:
-    wxLocale m_locale;
-
-    CMyApp(){};
-    ~CMyApp(){};
-    bool OnInit();
-    bool OnInit2();
-    int OnExit();
-
-    // Hook Initialize so we can start without GUI
-    virtual bool Initialize(int& argc, wxChar** argv);
-
-    // 2nd-level exception handling: we get all the exceptions occurring in any
-    // event handler here
-    virtual bool OnExceptionInMainLoop();
-
-    // 3rd, and final, level exception handling: whenever an unhandled
-    // exception is caught, this function is called
-    virtual void OnUnhandledException();
-
-    // and now for something different: this function is called in case of a
-    // crash (e.g. dereferencing null pointer, division by 0, ...)
-    virtual void OnFatalException();
-};
-
-IMPLEMENT_APP(CMyApp)
-
-bool CMyApp::Initialize(int& argc, wxChar** argv)
-{
-    if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
-        wxString(argv[1]) != "start")
-    {
-        fCommandLine = true;
-    }
-    else if (!fGUI)
-    {
-        fDaemon = true;
-    }
-    else
-    {
-        // wxApp::Initialize will remove environment-specific parameters,
-        // so it's too early to call ParseParameters yet
-        for (int i = 1; i < argc; i++)
-        {
-            wxString str = argv[i];
-            #ifdef __WXMSW__
-            if (str.size() >= 1 && str[0] == '/')
-                str[0] = '-';
-            char pszLower[MAX_PATH];
-            strlcpy(pszLower, str.c_str(), sizeof(pszLower));
-            strlwr(pszLower);
-            str = pszLower;
-            #endif
-            // haven't decided which argument to use for this yet
-            if (str == "-daemon" || str == "-d" || str == "start")
-                fDaemon = true;
-        }
-    }
-
-#ifdef __WXGTK__
-    if (fDaemon || fCommandLine)
-    {
-        // Call the original Initialize while suppressing error messages
-        // and ignoring failure.  If unable to initialize GTK, it fails
-        // near the end so hopefully the last few things don't matter.
-        {
-            wxLogNull logNo;
-            wxApp::Initialize(argc, argv);
-        }
-
-        if (fDaemon)
-        {
-            // Daemonize
-            pid_t pid = fork();
-            if (pid < 0)
-            {
-                fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
-                return false;
-            }
-            if (pid > 0)
-                pthread_exit((void*)0);
-        }
+    bool fRet = false;
+    fRet = AppInit(argc, argv);
 
-        return true;
-    }
-#endif
+    if (fRet && fDaemon)
+        return 0;
 
-    return wxApp::Initialize(argc, argv);
+    return 1;
 }
+#endif
 
-bool CMyApp::OnInit()
+bool AppInit(int argc, char* argv[])
 {
     bool fRet = false;
     try
     {
-        fRet = OnInit2();
+        fRet = AppInit2(argc, argv);
     }
     catch (std::exception& e) {
-        PrintException(&e, "OnInit()");
+        PrintException(&e, "AppInit()");
     } catch (...) {
-        PrintException(NULL, "OnInit()");
+        PrintException(NULL, "AppInit()");
     }
     if (!fRet)
         Shutdown(NULL);
     return fRet;
 }
 
-extern int g_isPainting;
-
-bool CMyApp::OnInit2()
+bool AppInit2(int argc, char* argv[])
 {
 #ifdef _MSC_VER
     // Turn off microsoft heap dump noise
@@ -331,106 +113,169 @@ bool CMyApp::OnInit2()
     // Disable confusing "helpful" text message on abort, ctrl-c
     _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
 #endif
-#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI
-    // Disable malfunctioning wxWidgets debug assertion
-    g_isPainting = 10000;
-#endif
-#if wxUSE_GUI
-    wxImage::AddHandler(new wxPNGHandler);
-#endif
-#if defined(__WXMSW__ ) || defined(__WXMAC__)
-    SetAppName("Bitcoin");
-#else
-    SetAppName("bitcoin");
-#endif
 #ifndef __WXMSW__
     umask(077);
 #endif
-#ifdef __WXMSW__
-#if wxUSE_UNICODE
-    // Hack to set wxConvLibc codepage to UTF-8 on Windows,
-    // may break if wxMBConv_win32 implementation in strconv.cpp changes.
-    class wxMBConv_win32 : public wxMBConv
-    {
-    public:
-        long m_CodePage;
-        size_t m_minMBCharWidth;
-    };
-    if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
-        ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
-#endif
+#ifndef __WXMSW__
+    // Clean shutdown on SIGTERM
+    struct sigaction sa;
+    sa.sa_handler = HandleSIGTERM;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sigaction(SIGTERM, &sa, NULL);
+    sigaction(SIGINT, &sa, NULL);
+    sigaction(SIGHUP, &sa, NULL);
 #endif
 
-    // Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
-    m_locale.Init(wxLANGUAGE_DEFAULT, 0);
-    m_locale.AddCatalogLookupPathPrefix("locale");
-    if (!fWindows)
-    {
-        m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
-        m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
-    }
-    m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
-    m_locale.AddCatalog("bitcoin");
-
     //
     // Parameters
     //
-    if (fCommandLine)
+    ParseParameters(argc, argv);
+
+    if (mapArgs.count("-datadir"))
     {
-        int ret = CommandLineRPC(argc, argv);
-        exit(ret);
+        filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
+        strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
     }
 
-    ParseParameters(argc, argv);
+    ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
+
     if (mapArgs.count("-?") || mapArgs.count("--help"))
     {
-        wxString strUsage = string() +
+        string beta = VERSION_IS_BETA ? _(" beta") : "";
+        string strUsage = string() +
+          _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
           _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
-            "  bitcoin [options]       \t" + "\n" +
-            "  bitcoin [command]       \t" + _("Send command to bitcoin running with -server or -daemon\n") +
-            "  bitcoin [command] -?    \t" + _("Get help for a command\n") +
-            "  bitcoin help            \t" + _("List commands\n") +
+            "  bitcoin [options]                   \t  " + "\n" +
+            "  bitcoin [options] <command> [params]\t  " + _("Send command to -server or bitcoind\n") +
+            "  bitcoin [options] help              \t\t  " + _("List commands\n") +
+            "  bitcoin [options] help <command>    \t\t  " + _("Get help for a command\n") +
           _("Options:\n") +
-            "  -gen            \t  " + _("Generate coins\n") +
-            "  -gen=0          \t  " + _("Don't generate coins\n") +
-            "  -min            \t  " + _("Start minimized\n") +
-            "  -datadir=<dir>  \t  " + _("Specify data directory\n") +
-            "  -proxy=<ip:port>\t  " + _("Connect through socks4 proxy\n") +
-            "  -addnode=<ip>   \t  " + _("Add a node to connect to\n") +
-            "  -connect=<ip>   \t  " + _("Connect only to the specified node\n") +
-            "  -server         \t  " + _("Accept command line and JSON-RPC commands\n") +
-            "  -daemon         \t  " + _("Run in the background as a daemon and accept commands\n") +
-            "  -?              \t  " + _("This help message\n");
-
-#if defined(__WXMSW__) && wxUSE_GUI
+            "  -conf=<file>     \t\t  " + _("Specify configuration file (default: bitcoin.conf)\n") +
+            "  -pid=<file>      \t\t  " + _("Specify pid file (default: bitcoind.pid)\n") +
+            "  -gen             \t\t  " + _("Generate coins\n") +
+            "  -gen=0           \t\t  " + _("Don't generate coins\n") +
+            "  -min             \t\t  " + _("Start minimized\n") +
+            "  -datadir=<dir>   \t\t  " + _("Specify data directory\n") +
+            "  -proxy=<ip:port> \t  "   + _("Connect through socks4 proxy\n") +
+            "  -addnode=<ip>    \t  "   + _("Add a node to connect to\n") +
+            "  -connect=<ip>    \t\t  " + _("Connect only to the specified node\n") +
+            "  -nolisten        \t  "   + _("Don't accept connections from outside\n") +
+#ifdef USE_UPNP
+#if USE_UPNP
+            "  -noupnp          \t  "   + _("Don't attempt to use UPnP to map the listening port\n") +
+#else
+            "  -upnp            \t  "   + _("Attempt to use UPnP to map the listening port\n") +
+#endif
+#endif
+            "  -paytxfee=<amt>  \t  "   + _("Fee per KB to add to transactions you send\n") +
+#ifdef GUI
+            "  -server          \t\t  " + _("Accept command line and JSON-RPC commands\n") +
+#endif
+#ifndef __WXMSW__
+            "  -daemon          \t\t  " + _("Run in the background as a daemon and accept commands\n") +
+#endif
+            "  -testnet         \t\t  " + _("Use the test network\n") +
+            "  -rpcuser=<user>  \t  "   + _("Username for JSON-RPC connections\n") +
+            "  -rpcpassword=<pw>\t  "   + _("Password for JSON-RPC connections\n") +
+            "  -rpcport=<port>  \t\t  " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
+            "  -rpcallowip=<ip> \t\t  " + _("Allow JSON-RPC connections from specified IP address\n") +
+            "  -rpcconnect=<ip> \t  "   + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
+            "  -keypool=<n>     \t  "   + _("Set key pool size to <n> (default: 100)\n") +
+            "  -rescan          \t  "   + _("Rescan the block chain for missing wallet transactions\n");
+
+#ifdef USE_SSL
+        strUsage += string() +
+            _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
+            "  -rpcssl                                \t  " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
+            "  -rpcsslcertificatechainfile=<file.cert>\t  " + _("Server certificate file (default: server.cert)\n") +
+            "  -rpcsslprivatekeyfile=<file.pem>       \t  " + _("Server private key (default: server.pem)\n") +
+            "  -rpcsslciphers=<ciphers>               \t  " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
+#endif
+
+        strUsage += string() +
+            "  -?               \t\t  " + _("This help message\n");
+
+#if defined(__WXMSW__) && defined(GUI)
         // Tabs make the columns line up in the message box
         wxMessageBox(strUsage, "Bitcoin", wxOK);
 #else
         // Remove tabs
-        strUsage.Replace("\t", "");
-        fprintf(stderr, "%s", ((string)strUsage).c_str());
+        strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
+        fprintf(stderr, "%s", strUsage.c_str());
 #endif
         return false;
     }
 
-    if (mapArgs.count("-datadir"))
-        strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
+    fDebug = GetBoolArg("-debug");
+
+#ifndef __WXMSW__
+    fDaemon = GetBoolArg("-daemon");
+#else
+    fDaemon = false;
+#endif
+
+    if (fDaemon)
+        fServer = true;
+    else
+        fServer = GetBoolArg("-server");
+
+    /* force fServer when running without GUI */
+#ifndef GUI
+    fServer = true;
+#endif
+
+    fPrintToConsole = GetBoolArg("-printtoconsole");
+    fPrintToDebugger = GetBoolArg("-printtodebugger");
 
-    if (mapArgs.count("-debug"))
-        fDebug = true;
+    fTestNet = GetBoolArg("-testnet");
+    fNoListen = GetBoolArg("-nolisten");
+    fLogTimestamps = GetBoolArg("-logtimestamps");
 
-    if (mapArgs.count("-printtodebugger"))
-        fPrintToDebugger = true;
+    for (int i = 1; i < argc; i++)
+        if (!IsSwitchChar(argv[i][0]))
+            fCommandLine = true;
+
+    if (fCommandLine)
+    {
+        int ret = CommandLineRPC(argc, argv);
+        exit(ret);
+    }
+
+#ifndef __WXMSW__
+    if (fDaemon)
+    {
+        // Daemonize
+        pid_t pid = fork();
+        if (pid < 0)
+        {
+            fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
+            return false;
+        }
+        if (pid > 0)
+        {
+            CreatePidFile(GetPidFile(), pid);
+            return true;
+        }
+
+        pid_t sid = setsid();
+        if (sid < 0)
+            fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
+    }
+#endif
 
     if (!fDebug && !pszSetDataDir[0])
         ShrinkDebugFile();
     printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
-    printf("Bitcoin version %d.%d.%d%s beta, OS version %s\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
-    printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
-    printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
+    printf("Bitcoin version %s\n", FormatFullVersion().c_str());
+#ifdef GUI
+    printf("OS version %s\n", ((string)wxGetOsDescription()).c_str());
+    printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str());
+    printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str());
+#endif
     printf("Default data directory %s\n", GetDefaultDataDir().c_str());
 
-    if (mapArgs.count("-loadblockindextest"))
+    if (GetBoolArg("-loadblockindextest"))
     {
         CTxDB txdb("r");
         txdb.LoadBlockIndex();
@@ -442,9 +287,8 @@ bool CMyApp::OnInit2()
     // Limit to single instance per user
     // Required to protect the database files if we're going to keep deleting log.*
     //
-#ifdef __WXMSW__
-    // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
-    //  maybe should go by whether successfully bind port 8333 instead
+#if defined(__WXMSW__) && defined(GUI)
+    // wxSingleInstanceChecker doesn't work on Linux
     wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
     for (int i = 0; i < strMutexName.size(); i++)
         if (!isalnum(strMutexName[i]))
@@ -456,7 +300,6 @@ bool CMyApp::OnInit2()
         unsigned int nStart = GetTime();
         loop
         {
-            // TODO: find out how to do this in Linux, or replace with wxWidgets commands
             // Show the previous instance and exit
             HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
             if (hwndPrev)
@@ -480,13 +323,26 @@ bool CMyApp::OnInit2()
     }
 #endif
 
+    // Make sure only a single bitcoin process is using the data directory.
+    string strLockFile = GetDataDir() + "/.lock";
+    FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
+    fclose(file);
+    static boost::interprocess::file_lock lock(strLockFile.c_str());
+    if (!lock.try_lock())
+    {
+        wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s.  Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
+        return false;
+    }
+
     // Bind to the port early so we can tell if another instance is already running.
-    // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
     string strErrors;
-    if (!BindListenPort(strErrors))
+    if (!fNoListen)
     {
-        wxMessageBox(strErrors, "Bitcoin");
-        return false;
+        if (!BindListenPort(strErrors))
+        {
+            wxMessageBox(strErrors, "Bitcoin");
+            return false;
+        }
     }
 
     //
@@ -516,6 +372,24 @@ bool CMyApp::OnInit2()
         strErrors += _("Error loading wallet.dat      \n");
     printf(" wallet      %15"PRI64d"ms\n", GetTimeMillis() - nStart);
 
+    CBlockIndex *pindexRescan = pindexBest;
+    if (GetBoolArg("-rescan"))
+        pindexRescan = pindexGenesisBlock;
+    else
+    {
+        CWalletDB walletdb;
+        CBlockLocator locator;
+        if (walletdb.ReadBestBlock(locator))
+            pindexRescan = locator.GetBlockIndex();
+    }
+    if (pindexBest != pindexRescan)
+    {
+        printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
+        nStart = GetTimeMillis();
+        ScanForWalletTransactions(pindexRescan);
+        printf(" rescan      %15"PRI64d"ms\n", GetTimeMillis() - nStart);
+    }
+
     printf("Done loading\n");
 
         //// debug print
@@ -528,7 +402,7 @@ bool CMyApp::OnInit2()
 
     if (!strErrors.empty())
     {
-        wxMessageBox(strErrors, "Bitcoin");
+        wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
         return false;
     }
 
@@ -538,7 +412,7 @@ bool CMyApp::OnInit2()
     //
     // Parameters
     //
-    if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
+    if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
     {
         PrintBlockTree();
         return false;
@@ -567,13 +441,7 @@ bool CMyApp::OnInit2()
         return false;
     }
 
-    if (mapArgs.count("-gen"))
-    {
-        if (mapArgs["-gen"].empty())
-            fGenerateBitcoins = true;
-        else
-            fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
-    }
+    fGenerateBitcoins = GetBoolArg("-gen");
 
     if (mapArgs.count("-proxy"))
     {
@@ -597,11 +465,38 @@ bool CMyApp::OnInit2()
         }
     }
 
+    if (mapArgs.count("-dnsseed"))
+        DNSAddressSeed();
+
+    if (mapArgs.count("-paytxfee"))
+    {
+        if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
+        {
+            wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
+            return false;
+        }
+        if (nTransactionFee > 0.25 * COIN)
+            wxMessageBox(_("Warning: -paytxfee is set very high.  This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
+    }
+
+    if (fHaveUPnP)
+    {
+#if USE_UPNP
+    if (GetBoolArg("-noupnp"))
+        fUseUPnP = false;
+#else
+    if (GetBoolArg("-upnp"))
+        fUseUPnP = true;
+#endif
+    }
+
     //
     // Create the main window and start the node
     //
+#ifdef GUI
     if (!fDaemon)
         CreateMainWindow();
+#endif
 
     if (!CheckDiskSpace())
         return false;
@@ -611,68 +506,18 @@ bool CMyApp::OnInit2()
     if (!CreateThread(StartNode, NULL))
         wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
 
-    if (mapArgs.count("-server") || fDaemon)
+    if (fServer)
         CreateThread(ThreadRPCServer, NULL);
 
+#if defined(__WXMSW__) && defined(GUI)
     if (fFirstRun)
         SetStartOnSystemStartup(true);
+#endif
 
-    return true;
-}
-
-int CMyApp::OnExit()
-{
-    Shutdown(NULL);
-    return wxApp::OnExit();
-}
+#ifndef GUI
+    while (1)
+        Sleep(5000);
+#endif
 
-bool CMyApp::OnExceptionInMainLoop()
-{
-    try
-    {
-        throw;
-    }
-    catch (std::exception& e)
-    {
-        PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
-        wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
-        Sleep(1000);
-        throw;
-    }
-    catch (...)
-    {
-        PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
-        wxLogWarning("Unknown exception");
-        Sleep(1000);
-        throw;
-    }
     return true;
 }
-
-void CMyApp::OnUnhandledException()
-{
-    // this shows how we may let some exception propagate uncaught
-    try
-    {
-        throw;
-    }
-    catch (std::exception& e)
-    {
-        PrintException(&e, "CMyApp::OnUnhandledException()");
-        wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
-        Sleep(1000);
-        throw;
-    }
-    catch (...)
-    {
-        PrintException(NULL, "CMyApp::OnUnhandledException()");
-        wxLogWarning("Unknown exception");
-        Sleep(1000);
-        throw;
-    }
-}
-
-void CMyApp::OnFatalException()
-{
-    wxMessageBox(_("Program has crashed and will terminate.  "), "Bitcoin", wxOK | wxICON_ERROR);
-}