Skip to content

Commit

Permalink
bbstoreaccounts: add support for standard command-line logging options
Browse files Browse the repository at this point in the history
Tidy up usage text, and fix erroneous memory leak reported after calling
PrintUsageAndExit().

(cherry picked from commit 1a209b5)
  • Loading branch information
qris committed Jul 23, 2017
1 parent cd1cd87 commit e8fa6aa
Showing 1 changed file with 92 additions and 75 deletions.
167 changes: 92 additions & 75 deletions bin/bbstoreaccounts/bbstoreaccounts.cpp
Expand Up @@ -18,12 +18,15 @@

#include <sys/types.h>

#include <iostream>

#include "box_getopt.h"
#include "BackupStoreAccounts.h"
#include "BackupStoreAccountDatabase.h"
#include "BackupStoreCheck.h"
#include "BackupStoreConfigVerify.h"
#include "BackupStoreInfo.h"
#include "BannerText.h"
#include "BoxPortsAndFiles.h"
#include "HousekeepStoreAccount.h"
#include "MainHelper.h"
Expand All @@ -36,44 +39,54 @@

#include <cstring>

void PrintUsageAndExit()
int PrintUsage()
{
printf(
"Usage: bbstoreaccounts [-c config_file] action account_id [args]\n"
"Account ID is integer specified in hex\n"
"\n"
"Commands (and arguments):\n"
" create <account> <discnum> <softlimit> <hardlimit>\n"
" Creates the specified account number (in hex with no 0x) on the\n"
" specified raidfile disc set number (see raidfile.conf for valid\n"
" set numbers) with the specified soft and hard limits (in blocks\n"
" if suffixed with B, MB with M, GB with G)\n"
" info [-m] <account>\n"
" Prints information about the specified account including number\n"
" of blocks used. The -m option enable machine-readable output.\n"
" enabled <accounts> <yes|no>\n"
" Sets the account as enabled or disabled for new logins.\n"
" setlimit <accounts> <softlimit> <hardlimit>\n"
" Changes the limits of the account as specified. Numbers are\n"
" interpreted as for the 'create' command (suffixed with B, M or G)\n"
" delete <account> [yes]\n"
" Deletes the specified account. Prompts for confirmation unless\n"
" the optional 'yes' parameter is provided.\n"
" check <account> [fix] [quiet]\n"
" Checks the specified account for errors. If the 'fix' option is\n"
" provided, any errors discovered that can be fixed automatically\n"
" will be fixed. If the 'quiet' option is provided, less output is\n"
" produced.\n"
" name <account> <new name>\n"
" Changes the \"name\" of the account to the specified string.\n"
" The name is purely cosmetic and intended to make it easier to\n"
" identify your accounts.\n"
" housekeep <account>\n"
" Runs housekeeping immediately on the account. If it cannot be locked,\n"
" bbstoreaccounts returns an error status code (1), otherwise success\n"
" (0) even if any errors were fixed by housekeeping.\n"
);
exit(2);
std::string configFilename = BOX_GET_DEFAULT_BBSTORED_CONFIG_FILE;

std::cout <<
BANNER_TEXT("account management utility (bbstoreaccounts)") << "\n"
"\n"
"Usage: bbstoreaccounts [-3] [-c config_file] <action> <account_id> [args]\n"
"Account ID is integer specified in hex, with no 0x prefix.\n"
"\n"
"Options:\n"
" -3 Amazon S3 mode. Not all commands are supported yet. Use account\n"
" name for <account_id>, and bbackupd.conf for <config_file>.\n"
" -c Use an alternate configuration file instead of\n"
" " << configFilename << ".\n"
<< Logging::OptionParser::GetUsageString() <<
"\n"
"Commands (and arguments):\n"
" create <account> <discnum> <softlimit> <hardlimit>\n"
" Creates a RaidFile account with the specified account number, on the\n"
" specified RaidFile disc set number (see raidfile.conf for valid set\n"
" numbers) with the specified soft and hard limits (in blocks if\n"
" suffixed with B, MB with M, GB with G).\n"
" info [-m] <account>\n"
" Prints information about the specified account including number\n"
" of blocks used. The -m option enables machine-readable output.\n"
" enabled <accounts> <yes|no>\n"
" Sets the account as enabled or disabled for new logins.\n"
" setlimit <accounts> <softlimit> <hardlimit>\n"
" Changes the limits of the account as specified. Numbers are\n"
" interpreted as for the 'create' command (suffixed with B, M or G).\n"
" delete <account> [yes]\n"
" Deletes the specified account. Prompts for confirmation unless\n"
" the optional 'yes' parameter is provided.\n"
" check <account> [fix] [quiet]\n"
" Checks the specified account for errors. If the 'fix' option is\n"
" provided, any errors discovered that can be fixed automatically\n"
" will be fixed. If the 'quiet' option is provided, less output is\n"
" produced.\n"
" name <account> <new name>\n"
" Changes the \"name\" of the account to the specified string.\n"
" The name is purely cosmetic and intended to make it easier to\n"
" identify your accounts.\n"
" housekeep <account>\n"
" Runs housekeeping immediately on the account. If it cannot be locked,\n"
" bbstoreaccounts returns an error status code (1), otherwise success\n"
" (0) even if any errors were fixed by housekeeping.\n";
return 2;
}

int main(int argc, const char *argv[])
Expand All @@ -87,12 +100,13 @@ int main(int argc, const char *argv[])

// Filename for configuration file?
std::string configFilename = BOX_GET_DEFAULT_BBSTORED_CONFIG_FILE;
int logLevel = Log::EVERYTHING;
Logging::OptionParser log_level;
bool machineReadableOutput = false;

// See if there's another entry on the command line
int c;
while((c = getopt(argc, (char * const *)argv, "c:W:m")) != -1)
std::string options = Logging::OptionParser::GetOptionString() + "3c:m";
while((c = getopt(argc, (char * const *)argv, options.c_str())) != -1)
{
switch(c)
{
Expand All @@ -101,33 +115,39 @@ int main(int argc, const char *argv[])
configFilename = optarg;
break;

case 'W':
logLevel = Logging::GetNamedLevel(optarg);
if(logLevel == Log::INVALID)
{
BOX_FATAL("Invalid logging level: " << optarg);
return 2;
}
break;

case 'm':
// enable machine readable output
machineReadableOutput = true;
break;

case '?':
return PrintUsage();
break;

default:
PrintUsageAndExit();
if(log_level.ProcessOption(c) != 0)
{
return PrintUsage();
}
}
}

Logging::FilterConsole((Log::Level) logLevel);
Logging::FilterConsole(log_level.GetCurrentLevel());
Logging::FilterSyslog (Log::NOTHING);

// Adjust arguments
argc -= optind;
argv += optind;

// We should have at least one argument at this point.
if(argc < 1)
{
return PrintUsage();
}
std::string command = argv[0];
argv++;
argc--;

// Read in the configuration file
std::string errs;
std::auto_ptr<Configuration> config(
Expand All @@ -144,20 +164,17 @@ int main(int argc, const char *argv[])
RaidFileController &rcontroller(RaidFileController::GetController());
rcontroller.Initialise(config->GetKeyValue("RaidFileConf").c_str());

// Then... check we have two arguments
if(argc < 2)
{
PrintUsageAndExit();
}

// Get the id
// Get the Account ID (in hex without the leading 0x).
int32_t id;
if(::sscanf(argv[1], "%x", &id) != 1)
if(argc == 0 || ::sscanf(argv[0], "%x", &id) != 1)
{
PrintUsageAndExit();
BOX_FATAL("All commands require an account ID, in hex without 0x");
return PrintUsage();
}

std::string command = argv[0];
argv++;
argc--;


BackupStoreAccountsControl control(*config, machineReadableOutput);

// Now do the command.
Expand All @@ -167,8 +184,8 @@ int main(int argc, const char *argv[])
int32_t discnum;
int32_t softlimit;
int32_t hardlimit;
if(argc < 5
|| ::sscanf(argv[2], "%d", &discnum) != 1)
if(argc < 3
|| ::sscanf(argv[0], "%d", &discnum) != 1)
{
BOX_ERROR("create requires raid file disc number, "
"soft and hard limits.");
Expand All @@ -177,8 +194,8 @@ int main(int argc, const char *argv[])

// Decode limits
int blocksize = control.BlockSizeOfDiscSet(discnum);
softlimit = control.SizeStringToBlocks(argv[3], blocksize);
hardlimit = control.SizeStringToBlocks(argv[4], blocksize);
softlimit = control.SizeStringToBlocks(argv[1], blocksize);
hardlimit = control.SizeStringToBlocks(argv[2], blocksize);
control.CheckSoftHardLimits(softlimit, hardlimit);

// Create the account...
Expand All @@ -192,13 +209,13 @@ int main(int argc, const char *argv[])
else if(command == "enabled")
{
// Change the AccountEnabled flag on this account
if(argc != 3)
if(argc != 1)
{
PrintUsageAndExit();
return PrintUsage();
}

bool enabled = true;
std::string enabled_string = argv[2];
std::string enabled_string = argv[0];
if(enabled_string == "yes")
{
enabled = true;
Expand All @@ -209,38 +226,38 @@ int main(int argc, const char *argv[])
}
else
{
PrintUsageAndExit();
return PrintUsage();
}

return control.SetAccountEnabled(id, enabled);
}
else if(command == "setlimit")
{
// Change the limits on this account
if(argc < 4)
if(argc < 2)
{
BOX_ERROR("setlimit requires soft and hard limits.");
return 1;
}

return control.SetLimit(id, argv[2], argv[3]);
return control.SetLimit(id, argv[0], argv[1]);
}
else if(command == "name")
{
// Change the limits on this account
if(argc != 3)
if(argc != 1)
{
BOX_ERROR("name command requires a new name.");
return 1;
}

return control.SetAccountName(id, argv[2]);
return control.SetAccountName(id, argv[0]);
}
else if(command == "delete")
{
// Delete an account
bool askForConfirmation = true;
if(argc >= 3 && (::strcmp(argv[2], "yes") == 0))
if(argc >= 1 && (::strcmp(argv[0], "yes") == 0))
{
askForConfirmation = false;
}
Expand All @@ -252,7 +269,7 @@ int main(int argc, const char *argv[])
bool quiet = false;

// Look at other options
for(int o = 2; o < argc; ++o)
for(int o = 0; o < argc; ++o)
{
if(::strcmp(argv[o], "fix") == 0)
{
Expand Down

0 comments on commit e8fa6aa

Please sign in to comment.