diff options
author | Ben Summers <ben@fluffy.co.uk> | 2005-10-14 08:50:54 +0000 |
---|---|---|
committer | Ben Summers <ben@fluffy.co.uk> | 2005-10-14 08:50:54 +0000 |
commit | 99f8ce096bc5569adbfea1911dbcda24c28d8d8b (patch) | |
tree | 049c302161fea1f2f6223e1e8f3c40d9e8aadc8b /bin/bbackupquery/bbackupquery.cpp |
Box Backup 0.09 with a few tweeks
Diffstat (limited to 'bin/bbackupquery/bbackupquery.cpp')
-rwxr-xr-x | bin/bbackupquery/bbackupquery.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/bin/bbackupquery/bbackupquery.cpp b/bin/bbackupquery/bbackupquery.cpp new file mode 100755 index 00000000..aea0faa8 --- /dev/null +++ b/bin/bbackupquery/bbackupquery.cpp @@ -0,0 +1,243 @@ +// -------------------------------------------------------------------------- +// +// File +// Name: bbackupquery.cpp +// Purpose: Backup query utility +// Created: 2003/10/10 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#ifndef PLATFORM_READLINE_NOT_SUPPORTED + #ifdef PLATFORM_LINUX + #include "../../local/_linux_readline.h" + #else + #include <readline/readline.h> + #include <readline/history.h> + #endif +#endif + +#include "MainHelper.h" +#include "BoxPortsAndFiles.h" +#include "BackupDaemonConfigVerify.h" +#include "SocketStreamTLS.h" +#include "Socket.h" +#include "TLSContext.h" +#include "SSLLib.h" +#include "BackupStoreConstants.h" +#include "BackupStoreException.h" +#include "autogen_BackupProtocolClient.h" +#include "BackupQueries.h" +#include "FdGetLine.h" +#include "BackupClientCryptoKeys.h" +#include "BannerText.h" + +#include "MemLeakFindOn.h" + +void PrintUsageAndExit() +{ + printf("Usage: bbackupquery [-q] [-c config_file] [-l log_file] [commands]\nAs many commands as you require.\n" \ + "If commands are multiple words, remember to enclose the command in quotes.\n" \ + "Remember to use quit command if you don't want to drop into interactive mode.\n"); + exit(1); +} + +int main(int argc, const char *argv[]) +{ + MAINHELPER_SETUP_MEMORY_LEAK_EXIT_REPORT("bbackupquery.memleaks", "bbackupquery") + + // Really don't want trace statements happening, even in debug mode + #ifndef NDEBUG + BoxDebugTraceOn = false; + #endif + + int returnCode = 0; + + MAINHELPER_START + + FILE *logFile = 0; + + // Filename for configuraiton file? + const char *configFilename = BOX_FILE_BBACKUPD_DEFAULT_CONFIG; + + // Flags + bool quiet = false; + bool readWrite = false; + + // See if there's another entry on the command line + int c; + while((c = getopt(argc, (char * const *)argv, "qwc:l:")) != -1) + { + switch(c) + { + case 'q': + // Quiet mode + quiet = true; + break; + + case 'w': + // Read/write mode + readWrite = true; + break; + + case 'c': + // store argument + configFilename = optarg; + break; + + case 'l': + // open log file + logFile = ::fopen(optarg, "w"); + if(logFile == 0) + { + printf("Can't open log file '%s'\n", optarg); + } + break; + + case '?': + default: + PrintUsageAndExit(); + } + } + // Adjust arguments + argc -= optind; + argv += optind; + + // Print banner? + if(!quiet) + { + const char *banner = BANNER_TEXT("Backup Query Tool"); + printf(banner); + } + + // Read in the configuration file + if(!quiet) printf("Using configuration file %s\n", configFilename); + std::string errs; + std::auto_ptr<Configuration> config(Configuration::LoadAndVerify(configFilename, &BackupDaemonConfigVerify, errs)); + if(config.get() == 0 || !errs.empty()) + { + printf("Invalid configuration file:\n%s", errs.c_str()); + return 1; + } + // Easier coding + const Configuration &conf(*config); + + // Setup and connect + // 1. TLS context + SSLLib::Initialise(); + // Read in the certificates creating a TLS context + TLSContext tlsContext; + std::string certFile(conf.GetKeyValue("CertificateFile")); + std::string keyFile(conf.GetKeyValue("PrivateKeyFile")); + std::string caFile(conf.GetKeyValue("TrustedCAsFile")); + tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str()); + + // Initialise keys + BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str()); + + // 2. Connect to server + if(!quiet) printf("Connecting to store...\n"); + SocketStreamTLS socket; + socket.Open(tlsContext, Socket::TypeINET, conf.GetKeyValue("StoreHostname").c_str(), BOX_PORT_BBSTORED); + + // 3. Make a protocol, and handshake + if(!quiet) printf("Handshake with store...\n"); + BackupProtocolClient connection(socket); + connection.Handshake(); + + // logging? + if(logFile != 0) + { + connection.SetLogToFile(logFile); + } + + // 4. Log in to server + if(!quiet) printf("Login to store...\n"); + // Check the version of the server + { + std::auto_ptr<BackupProtocolClientVersion> serverVersion(connection.QueryVersion(BACKUP_STORE_SERVER_VERSION)); + if(serverVersion->GetVersion() != BACKUP_STORE_SERVER_VERSION) + { + THROW_EXCEPTION(BackupStoreException, WrongServerVersion) + } + } + // Login -- if this fails, the Protocol will exception + connection.QueryLogin(conf.GetKeyValueInt("AccountNumber"), + (readWrite)?0:(BackupProtocolClientLogin::Flags_ReadOnly)); + + // 5. Tell user. + if(!quiet) printf("Login complete.\n\nType \"help\" for a list of commands.\n\n"); + + // Set up a context for our work + BackupQueries context(connection, conf); + + // Start running commands... first from the command line + { + int c = 0; + while(c < argc && !context.Stop()) + { + context.DoCommand(argv[c++]); + } + } + + // Get commands from input +#ifndef PLATFORM_READLINE_NOT_SUPPORTED + using_history(); + char *last_cmd = 0; + while(!context.Stop()) + { + char *command = readline("query > "); + if(command == NULL) + { + // Ctrl-D pressed -- terminate now + break; + } + context.DoCommand(command); + if(last_cmd != 0 && ::strcmp(last_cmd, command) == 0) + { + free(command); + } + else + { + add_history(command); + last_cmd = command; + } + } +#else + // Version for platforms which don't have readline by default + FdGetLine getLine(fileno(stdin)); + while(!context.Stop()) + { + printf("query > "); + fflush(stdout); + std::string command(getLine.GetLine()); + context.DoCommand(command.c_str()); + } +#endif + + // Done... stop nicely + if(!quiet) printf("Logging off...\n"); + connection.QueryFinished(); + if(!quiet) printf("Session finished.\n"); + + // Return code + returnCode = context.GetReturnCode(); + + // Close log file? + if(logFile) + { + ::fclose(logFile); + } + + // Let everything be cleaned up on exit. + + MAINHELPER_END + + exit(returnCode); + return returnCode; +} + |