diff options
Diffstat (limited to 'src/main_gui.cpp')
| -rw-r--r-- | src/main_gui.cpp | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 6164ad7..a2577ca 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -40,6 +40,60 @@ static string argval2(int argc, char* argv[], const char* keySlash, const char* | |||
| 40 | return argval(argc, argv, keyDash); | 40 | return argval(argc, argv, keyDash); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static bool ReadPassphraseArgument(const string& strArg, string& strPassphraseRet, string& strErrorRet) | ||
| 44 | { | ||
| 45 | strPassphraseRet.clear(); | ||
| 46 | strErrorRet.clear(); | ||
| 47 | if (strArg.empty()) | ||
| 48 | { | ||
| 49 | AttachTerminal(); | ||
| 50 | fprintf(stderr, "Enter wallet passphrase: "); | ||
| 51 | fflush(stderr); | ||
| 52 | char buf[4096]; | ||
| 53 | if (!fgets(buf, sizeof(buf), stdin)) | ||
| 54 | { | ||
| 55 | strErrorRet = "could not read passphrase from stdin"; | ||
| 56 | return false; | ||
| 57 | } | ||
| 58 | strPassphraseRet = buf; | ||
| 59 | } | ||
| 60 | else if (strArg[0] == '@') | ||
| 61 | { | ||
| 62 | string strPath = strArg.substr(1); | ||
| 63 | FILE* pf = fopen(strPath.c_str(), "rb"); | ||
| 64 | if (!pf) | ||
| 65 | { | ||
| 66 | strErrorRet = strprintf("could not read passphrase file %s", strPath.c_str()); | ||
| 67 | return false; | ||
| 68 | } | ||
| 69 | char buf[4096]; | ||
| 70 | if (!fgets(buf, sizeof(buf), pf)) | ||
| 71 | { | ||
| 72 | fclose(pf); | ||
| 73 | strErrorRet = strprintf("passphrase file %s is empty", strPath.c_str()); | ||
| 74 | return false; | ||
| 75 | } | ||
| 76 | fclose(pf); | ||
| 77 | strPassphraseRet = buf; | ||
| 78 | } | ||
| 79 | else | ||
| 80 | { | ||
| 81 | strErrorRet = "passphrase literals on the command line are unsafe; use the option without a value to read stdin, or use @FILE"; | ||
| 82 | return false; | ||
| 83 | } | ||
| 84 | |||
| 85 | while (!strPassphraseRet.empty() && | ||
| 86 | (strPassphraseRet[strPassphraseRet.size() - 1] == '\n' || | ||
| 87 | strPassphraseRet[strPassphraseRet.size() - 1] == '\r')) | ||
| 88 | strPassphraseRet.resize(strPassphraseRet.size() - 1); | ||
| 89 | if (strPassphraseRet.empty()) | ||
| 90 | { | ||
| 91 | strErrorRet = "empty passphrase"; | ||
| 92 | return false; | ||
| 93 | } | ||
| 94 | return true; | ||
| 95 | } | ||
| 96 | |||
| 43 | // The real printf, not the one util.h remaps to OutputDebugStringF. Help that | 97 | // The real printf, not the one util.h remaps to OutputDebugStringF. Help that |
| 44 | // goes to debug.log is help nobody asked for: `-help` printed a full page into | 98 | // goes to debug.log is help nobody asked for: `-help` printed a full page into |
| 45 | // the data directory and returned 0 with an empty terminal, which reads as a | 99 | // the data directory and returned 0 with an empty terminal, which reads as a |
| @@ -56,7 +110,7 @@ static void PrintUsage() | |||
| 56 | printf(" /debug\n"); | 110 | printf(" /debug\n"); |
| 57 | printf(" /gen\n"); | 111 | printf(" /gen\n"); |
| 58 | printf(" /nogui or /daemon\n"); | 112 | printf(" /nogui or /daemon\n"); |
| 59 | printf(" /selftest=wallet-keypool or /selftest=wallet-hd\n"); | 113 | printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, or wallet-encrypt\n"); |
| 60 | printf("\n"); | 114 | printf("\n"); |
| 61 | printf("Mining mode:\n"); | 115 | printf("Mining mode:\n"); |
| 62 | printf(" /operator\n"); | 116 | printf(" /operator\n"); |
| @@ -85,6 +139,10 @@ static void PrintUsage() | |||
| 85 | printf(" /dumpwallet=FILE (export private keys as text -- readable by\n"); | 139 | printf(" /dumpwallet=FILE (export private keys as text -- readable by\n"); |
| 86 | printf(" anyone, so guard it like cash)\n"); | 140 | printf(" anyone, so guard it like cash)\n"); |
| 87 | printf(" /importwallet=FILE (load keys from such a file back in)\n"); | 141 | printf(" /importwallet=FILE (load keys from such a file back in)\n"); |
| 142 | printf(" /encryptwallet[=@FILE] (rewrite wallet.dat with encrypted private keys\n"); | ||
| 143 | printf(" and encrypted HD seed, then exit)\n"); | ||
| 144 | printf(" /walletpassphrase[=@FILE] (unlock an encrypted wallet for one-shot\n"); | ||
| 145 | printf(" commands; without @FILE reads stdin)\n"); | ||
| 88 | printf(" /newaddress (print the next receiving address, then exit)\n"); | 146 | printf(" /newaddress (print the next receiving address, then exit)\n"); |
| 89 | printf(" /sendto=ADDRESS,AMOUNT (spend from this wallet, then exit -- the\n"); | 147 | printf(" /sendto=ADDRESS,AMOUNT (spend from this wallet, then exit -- the\n"); |
| 90 | printf(" only way to send without the window)\n"); | 148 | printf(" only way to send without the window)\n"); |
| @@ -299,6 +357,39 @@ int main(int argc, char* argv[]) | |||
| 299 | } | 357 | } |
| 300 | printf("Height=%d\n", nBestHeight); | 358 | printf("Height=%d\n", nBestHeight); |
| 301 | 359 | ||
| 360 | bool fEncryptWallet = arg(argc, argv, "/encryptwallet") || arg(argc, argv, "-encryptwallet"); | ||
| 361 | string strEncryptWallet = argval2(argc, argv, "/encryptwallet", "-encryptwallet"); | ||
| 362 | if (fEncryptWallet) | ||
| 363 | { | ||
| 364 | string strPassphrase; | ||
| 365 | string strPassphraseError; | ||
| 366 | if (!ReadPassphraseArgument(strEncryptWallet, strPassphrase, strPassphraseError)) | ||
| 367 | { | ||
| 368 | fprintf(stderr, "Cannot read encryption passphrase: %s\n", strPassphraseError.c_str()); | ||
| 369 | DBFlush(true); | ||
| 370 | return 1; | ||
| 371 | } | ||
| 372 | int nRet = CmdEncryptWallet(strPassphrase); | ||
| 373 | if (nRet != 0) | ||
| 374 | DBFlush(true); | ||
| 375 | return nRet; | ||
| 376 | } | ||
| 377 | |||
| 378 | bool fWalletPassphrase = arg(argc, argv, "/walletpassphrase") || arg(argc, argv, "-walletpassphrase"); | ||
| 379 | string strWalletPassphrase = argval2(argc, argv, "/walletpassphrase", "-walletpassphrase"); | ||
| 380 | if (fWalletPassphrase) | ||
| 381 | { | ||
| 382 | string strPassphrase; | ||
| 383 | string strUnlockError; | ||
| 384 | if (!ReadPassphraseArgument(strWalletPassphrase, strPassphrase, strUnlockError) || | ||
| 385 | !UnlockWallet(strPassphrase, strUnlockError)) | ||
| 386 | { | ||
| 387 | fprintf(stderr, "Cannot unlock wallet: %s\n", strUnlockError.c_str()); | ||
| 388 | DBFlush(true); | ||
| 389 | return 1; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 302 | // Before the node opens sockets or touches anything: the wallet is loaded, | 393 | // Before the node opens sockets or touches anything: the wallet is loaded, |
| 303 | // which is all a backup needs, and finishing here means the copy is taken | 394 | // which is all a backup needs, and finishing here means the copy is taken |
| 304 | // from a quiet directory rather than from under a running node. | 395 | // from a quiet directory rather than from under a running node. |
| @@ -442,6 +533,14 @@ int main(int argc, char* argv[]) | |||
| 442 | return 0; | 533 | return 0; |
| 443 | } | 534 | } |
| 444 | 535 | ||
| 536 | if (fGenerateBitcoins && IsWalletLocked()) | ||
| 537 | { | ||
| 538 | fprintf(stderr, "Cannot mine while the encrypted wallet is locked. " | ||
| 539 | "Start with /walletpassphrase or /walletpassphrase=@FILE, or disable mining.\n"); | ||
| 540 | DBFlush(true); | ||
| 541 | return 1; | ||
| 542 | } | ||
| 543 | |||
| 445 | ReacceptWalletTransactions(); | 544 | ReacceptWalletTransactions(); |
| 446 | 545 | ||
| 447 | if (!StartNode(strErrors)) { fprintf(stderr,"StartNode: %s\n",strErrors.c_str()); return 1; } | 546 | if (!StartNode(strErrors)) { fprintf(stderr,"StartNode: %s\n",strErrors.c_str()); return 1; } |