diff options
Diffstat (limited to 'bin/bbstoreaccounts/bbstoreaccounts.cpp')
-rw-r--r-- | bin/bbstoreaccounts/bbstoreaccounts.cpp | 500 |
1 files changed, 318 insertions, 182 deletions
diff --git a/bin/bbstoreaccounts/bbstoreaccounts.cpp b/bin/bbstoreaccounts/bbstoreaccounts.cpp index a9d2b0af..6a5c2e33 100644 --- a/bin/bbstoreaccounts/bbstoreaccounts.cpp +++ b/bin/bbstoreaccounts/bbstoreaccounts.cpp @@ -11,7 +11,10 @@ #include <limits.h> #include <stdio.h> -#include <unistd.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif #include <sys/types.h> @@ -21,17 +24,18 @@ #include <ostream> #include <vector> -#include "BoxPortsAndFiles.h" -#include "BackupStoreConfigVerify.h" -#include "RaidFileController.h" #include "BackupStoreAccounts.h" #include "BackupStoreAccountDatabase.h" -#include "MainHelper.h" +#include "BackupStoreCheck.h" +#include "BackupStoreConfigVerify.h" #include "BackupStoreInfo.h" -#include "StoreStructure.h" +#include "BoxPortsAndFiles.h" +#include "HousekeepStoreAccount.h" +#include "MainHelper.h" #include "NamedLock.h" +#include "RaidFileController.h" +#include "StoreStructure.h" #include "UnixUser.h" -#include "BackupStoreCheck.h" #include "Utils.h" #include "MemLeakFindOn.h" @@ -59,31 +63,31 @@ void CheckSoftHardLimits(int64_t SoftLimit, int64_t HardLimit) } } -int BlockSizeOfDiscSet(int DiscSet) +int BlockSizeOfDiscSet(int discSetNum) { // Get controller, check disc set number RaidFileController &controller(RaidFileController::GetController()); - if(DiscSet < 0 || DiscSet >= controller.GetNumDiscSets()) + if(discSetNum < 0 || discSetNum >= controller.GetNumDiscSets()) { - BOX_FATAL("Disc set " << DiscSet << " does not exist."); + BOX_FATAL("Disc set " << discSetNum << " does not exist."); exit(1); } // Return block size - return controller.GetDiscSet(DiscSet).GetBlockSize(); + return controller.GetDiscSet(discSetNum).GetBlockSize(); } -std::string BlockSizeToString(int64_t Blocks, int64_t MaxBlocks, int DiscSet) +std::string BlockSizeToString(int64_t Blocks, int64_t MaxBlocks, int discSetNum) { - return FormatUsageBar(Blocks, Blocks * BlockSizeOfDiscSet(DiscSet), - MaxBlocks * BlockSizeOfDiscSet(DiscSet), + return FormatUsageBar(Blocks, Blocks * BlockSizeOfDiscSet(discSetNum), + MaxBlocks * BlockSizeOfDiscSet(discSetNum), sMachineReadableOutput); } -int64_t SizeStringToBlocks(const char *string, int DiscSet) +int64_t SizeStringToBlocks(const char *string, int discSetNum) { // Find block size - int blockSize = BlockSizeOfDiscSet(DiscSet); + int blockSize = BlockSizeOfDiscSet(discSetNum); // Get number char *endptr = (char*)string; @@ -124,144 +128,174 @@ int64_t SizeStringToBlocks(const char *string, int DiscSet) } } -bool GetWriteLockOnAccount(NamedLock &rLock, const std::string rRootDir, int DiscSetNum) -{ - std::string writeLockFilename; - StoreStructure::MakeWriteLockFilename(rRootDir, DiscSetNum, writeLockFilename); +bool OpenAccount(Configuration &rConfig, int32_t ID, std::string &rRootDirOut, + int &rDiscSetOut, std::auto_ptr<UnixUser> apUser, NamedLock* pLock); - bool gotLock = false; - int triesLeft = 8; - do - { - gotLock = rLock.TryAndGetLock(writeLockFilename.c_str(), 0600 /* restrictive file permissions */); - - if(!gotLock) - { - --triesLeft; - ::sleep(1); - } - } while(!gotLock && triesLeft > 0); +int SetLimit(Configuration &rConfig, int32_t ID, const char *SoftLimitStr, + const char *HardLimitStr) +{ + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + NamedLock writeLock; - if(!gotLock) + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock)) { - // Couldn't lock the account -- just stop now - BOX_ERROR("Failed to lock the account, did not change limits. " - "Try again later."); + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " to change limits."); + return 1; } + + // Load the info + std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, rootDir, + discSetNum, false /* Read/Write */)); - return gotLock; + // Change the limits + int64_t softlimit = SizeStringToBlocks(SoftLimitStr, discSetNum); + int64_t hardlimit = SizeStringToBlocks(HardLimitStr, discSetNum); + CheckSoftHardLimits(softlimit, hardlimit); + info->ChangeLimits(softlimit, hardlimit); + + // Save + info->Save(); + + BOX_NOTICE("Limits on account " << BOX_FORMAT_ACCOUNT(ID) << + " changed to " << softlimit << " soft, " << + hardlimit << " hard."); + + return 0; } -int SetLimit(Configuration &rConfig, const std::string &rUsername, int32_t ID, const char *SoftLimitStr, const char *HardLimitStr) +int SetAccountName(Configuration &rConfig, int32_t ID, + const std::string& rNewAccountName) { - // Become the user specified in the config file? - std::auto_ptr<UnixUser> user; - if(!rUsername.empty()) - { - // Username specified, change... - user.reset(new UnixUser(rUsername.c_str())); - user->ChangeProcessUser(true /* temporary */); - // Change will be undone at the end of this function - } - - // Load in the account database - std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str())); - - // Already exists? - if(!db->EntryExists(ID)) - { - BOX_ERROR("Account " << BOX_FORMAT_ACCOUNT(ID) << - " does not exist."); - return 1; - } - - // Load it in - BackupStoreAccounts acc(*db); std::string rootDir; - int discSet; - acc.GetAccountRoot(ID, rootDir, discSet); - - // Attempt to lock + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return NamedLock writeLock; - if(!GetWriteLockOnAccount(writeLock, rootDir, discSet)) + + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock)) { - // Failed to get lock + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " to change name."); return 1; } // Load the info - std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, rootDir, discSet, false /* Read/Write */)); + std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, + rootDir, discSetNum, false /* Read/Write */)); - // Change the limits - int64_t softlimit = SizeStringToBlocks(SoftLimitStr, discSet); - int64_t hardlimit = SizeStringToBlocks(HardLimitStr, discSet); - CheckSoftHardLimits(softlimit, hardlimit); - info->ChangeLimits(softlimit, hardlimit); + info->SetAccountName(rNewAccountName); // Save info->Save(); - BOX_NOTICE("Limits on account " << BOX_FORMAT_ACCOUNT(ID) << - " changed to " << softlimit << " soft, " << - hardlimit << " hard."); + BOX_NOTICE("Account " << BOX_FORMAT_ACCOUNT(ID) << + " name changed to " << rNewAccountName); return 0; } int AccountInfo(Configuration &rConfig, int32_t ID) { - // Load in the account database - std::auto_ptr<BackupStoreAccountDatabase> db( - BackupStoreAccountDatabase::Read( - rConfig.GetKeyValue("AccountDatabase").c_str())); - - // Exists? - if(!db->EntryExists(ID)) + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, + NULL /* no write lock needed for this read-only operation */)) { - BOX_ERROR("Account " << BOX_FORMAT_ACCOUNT(ID) << - " does not exist."); + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " to display info."); return 1; } // Load it in - BackupStoreAccounts acc(*db); - std::string rootDir; - int discSet; - acc.GetAccountRoot(ID, rootDir, discSet); std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, - rootDir, discSet, true /* ReadOnly */)); + rootDir, discSetNum, true /* ReadOnly */)); // Then print out lots of info std::cout << FormatUsageLineStart("Account ID", sMachineReadableOutput) << BOX_FORMAT_ACCOUNT(ID) << std::endl; + std::cout << FormatUsageLineStart("Account Name", sMachineReadableOutput) << + info->GetAccountName() << std::endl; std::cout << FormatUsageLineStart("Last object ID", sMachineReadableOutput) << BOX_FORMAT_OBJECTID(info->GetLastObjectIDUsed()) << std::endl; std::cout << FormatUsageLineStart("Used", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksUsed(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; + std::cout << FormatUsageLineStart("Current files", + sMachineReadableOutput) << + BlockSizeToString(info->GetBlocksInCurrentFiles(), + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Old files", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksInOldFiles(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Deleted files", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksInDeletedFiles(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Directories", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksInDirectories(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Soft limit", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksSoftLimit(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Hard limit", sMachineReadableOutput) << BlockSizeToString(info->GetBlocksHardLimit(), - info->GetBlocksHardLimit(), discSet) << std::endl; + info->GetBlocksHardLimit(), discSetNum) << std::endl; std::cout << FormatUsageLineStart("Client store marker", sMachineReadableOutput) << info->GetLastObjectIDUsed() << std::endl; + std::cout << FormatUsageLineStart("Live Files", sMachineReadableOutput) << + info->GetNumFiles() << std::endl; + std::cout << FormatUsageLineStart("Old Files", sMachineReadableOutput) << + info->GetNumOldFiles() << std::endl; + std::cout << FormatUsageLineStart("Deleted Files", sMachineReadableOutput) << + info->GetNumDeletedFiles() << std::endl; + std::cout << FormatUsageLineStart("Directories", sMachineReadableOutput) << + info->GetNumDirectories() << std::endl; + std::cout << FormatUsageLineStart("Enabled", sMachineReadableOutput) << + (info->IsAccountEnabled() ? "yes" : "no") << std::endl; return 0; } -int DeleteAccount(Configuration &rConfig, const std::string &rUsername, int32_t ID, bool AskForConfirmation) +int SetAccountEnabled(Configuration &rConfig, int32_t ID, bool enabled) { + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + NamedLock writeLock; + + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock)) + { + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " to change enabled flag."); + return 1; + } + + // Load it in + std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, + rootDir, discSetNum, false /* ReadOnly */)); + info->SetAccountEnabled(enabled); + info->Save(); + return 0; +} + +int DeleteAccount(Configuration &rConfig, int32_t ID, bool AskForConfirmation) +{ + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + NamedLock writeLock; + + // Obtain a write lock, as the daemon user + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock)) + { + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " for deletion."); + return 1; + } + // Check user really wants to do this if(AskForConfirmation) { @@ -275,45 +309,10 @@ int DeleteAccount(Configuration &rConfig, const std::string &rUsername, int32_t } } - // Load in the account database + // Back to original user, but write lock is maintained + user.reset(); + std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str())); - - // Exists? - if(!db->EntryExists(ID)) - { - BOX_ERROR("Account " << BOX_FORMAT_ACCOUNT(ID) << - " does not exist."); - return 1; - } - - // Get info from the database - BackupStoreAccounts acc(*db); - std::string rootDir; - int discSetNum; - acc.GetAccountRoot(ID, rootDir, discSetNum); - - // Obtain a write lock, as the daemon user - NamedLock writeLock; - { - // Bbecome the user specified in the config file - std::auto_ptr<UnixUser> user; - if(!rUsername.empty()) - { - // Username specified, change... - user.reset(new UnixUser(rUsername.c_str())); - user->ChangeProcessUser(true /* temporary */); - // Change will be undone at the end of this function - } - - // Get a write lock - if(!GetWriteLockOnAccount(writeLock, rootDir, discSetNum)) - { - // Failed to get lock - return 1; - } - - // Back to original user, but write is maintained - } // Delete from account database db->DeleteEntry(ID); @@ -324,15 +323,24 @@ int DeleteAccount(Configuration &rConfig, const std::string &rUsername, int32_t // Remove the store files... // First, become the user specified in the config file - std::auto_ptr<UnixUser> user; - if(!rUsername.empty()) + std::string username; + { + const Configuration &rserverConfig(rConfig.GetSubConfiguration("Server")); + if(rserverConfig.KeyExists("User")) + { + username = rserverConfig.GetKeyValue("User"); + } + } + + // Become the right user + if(!username.empty()) { // Username specified, change... - user.reset(new UnixUser(rUsername.c_str())); + user.reset(new UnixUser(username)); user->ChangeProcessUser(true /* temporary */); - // Change will be undone at the end of this function + // Change will be undone when user goes out of scope } - + // Secondly, work out which directories need wiping std::vector<std::string> toDelete; RaidFileController &rcontroller(RaidFileController::GetController()); @@ -345,6 +353,11 @@ int DeleteAccount(Configuration &rConfig, const std::string &rUsername, int32_t } } +#ifdef WIN32 + // Cannot remove files while holding a lock on them + writeLock.ReleaseLock(); +#endif + int retcode = 0; // Thirdly, delete the directories... @@ -367,7 +380,8 @@ int DeleteAccount(Configuration &rConfig, const std::string &rUsername, int32_t return retcode; } -int CheckAccount(Configuration &rConfig, const std::string &rUsername, int32_t ID, bool FixErrors, bool Quiet) +bool OpenAccount(Configuration &rConfig, int32_t ID, std::string &rRootDirOut, + int &rDiscSetOut, std::auto_ptr<UnixUser> apUser, NamedLock* pLock) { // Load in the account database std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str())); @@ -377,23 +391,53 @@ int CheckAccount(Configuration &rConfig, const std::string &rUsername, int32_t I { BOX_ERROR("Account " << BOX_FORMAT_ACCOUNT(ID) << " does not exist."); - return 1; + return false; } // Get info from the database BackupStoreAccounts acc(*db); - std::string rootDir; - int discSetNum; - acc.GetAccountRoot(ID, rootDir, discSetNum); - + acc.GetAccountRoot(ID, rRootDirOut, rDiscSetOut); + + // Get the user under which the daemon runs + std::string username; + { + const Configuration &rserverConfig(rConfig.GetSubConfiguration("Server")); + if(rserverConfig.KeyExists("User")) + { + username = rserverConfig.GetKeyValue("User"); + } + } + // Become the right user - std::auto_ptr<UnixUser> user; - if(!rUsername.empty()) + if(!username.empty()) { // Username specified, change... - user.reset(new UnixUser(rUsername.c_str())); - user->ChangeProcessUser(true /* temporary */); - // Change will be undone at the end of this function + apUser.reset(new UnixUser(username)); + apUser->ChangeProcessUser(true /* temporary */); + // Change will be undone when apUser goes out of scope + // in the caller. + } + + if(pLock) + { + acc.LockAccount(ID, *pLock); + } + + return true; +} + +int CheckAccount(Configuration &rConfig, int32_t ID, bool FixErrors, bool Quiet) +{ + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + NamedLock writeLock; + + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock)) + { + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " for checking."); + return 1; } // Check it @@ -403,7 +447,8 @@ int CheckAccount(Configuration &rConfig, const std::string &rUsername, int32_t I return check.ErrorsFound()?1:0; } -int CreateAccount(Configuration &rConfig, const std::string &rUsername, int32_t ID, int32_t DiscNumber, int32_t SoftLimit, int32_t HardLimit) +int CreateAccount(Configuration &rConfig, int32_t ID, int32_t DiscNumber, + int32_t SoftLimit, int32_t HardLimit) { // Load in the account database std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str())); @@ -415,16 +460,58 @@ int CreateAccount(Configuration &rConfig, const std::string &rUsername, int32_t " already exists."); return 1; } + + // Get the user under which the daemon runs + std::string username; + { + const Configuration &rserverConfig(rConfig.GetSubConfiguration("Server")); + if(rserverConfig.KeyExists("User")) + { + username = rserverConfig.GetKeyValue("User"); + } + } // Create it. BackupStoreAccounts acc(*db); - acc.Create(ID, DiscNumber, SoftLimit, HardLimit, rUsername); + acc.Create(ID, DiscNumber, SoftLimit, HardLimit, username); BOX_NOTICE("Account " << BOX_FORMAT_ACCOUNT(ID) << " created."); return 0; } +int HousekeepAccountNow(Configuration &rConfig, int32_t ID) +{ + std::string rootDir; + int discSetNum; + std::auto_ptr<UnixUser> user; // used to reset uid when we return + + if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, + NULL /* housekeeping locks the account itself */)) + { + BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID) + << " for housekeeping."); + return 1; + } + + HousekeepStoreAccount housekeeping(ID, rootDir, discSetNum, NULL); + bool success = housekeeping.DoHousekeeping(); + + if(!success) + { + BOX_ERROR("Failed to lock account " << BOX_FORMAT_ACCOUNT(ID) + << " for housekeeping: perhaps a client is " + "still connected?"); + return 1; + } + else + { + BOX_TRACE("Finished housekeeping on account " << + BOX_FORMAT_ACCOUNT(ID)); + return 0; + } +} + void PrintUsageAndExit() { printf( @@ -440,6 +527,8 @@ void PrintUsageAndExit() " 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" @@ -451,6 +540,14 @@ void PrintUsageAndExit() " 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); } @@ -465,17 +562,12 @@ int main(int argc, const char *argv[]) Logging::SetProgramName("bbstoreaccounts"); // Filename for configuration file? - std::string configFilename; - - #ifdef WIN32 - configFilename = BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE; - #else - configFilename = BOX_FILE_BBSTORED_DEFAULT_CONFIG; - #endif + std::string configFilename = BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE; + int logLevel = Log::EVERYTHING; // See if there's another entry on the command line int c; - while((c = getopt(argc, (char * const *)argv, "c:m")) != -1) + while((c = getopt(argc, (char * const *)argv, "c:W:m")) != -1) { switch(c) { @@ -484,6 +576,15 @@ 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 sMachineReadableOutput = true; @@ -494,6 +595,10 @@ int main(int argc, const char *argv[]) PrintUsageAndExit(); } } + + Logging::FilterConsole((Log::Level) logLevel); + Logging::FilterSyslog (Log::NOTHING); + // Adjust arguments argc -= optind; argv += optind; @@ -510,16 +615,6 @@ int main(int argc, const char *argv[]) ":" << errs); } - // Get the user under which the daemon runs - std::string username; - { - const Configuration &rserverConfig(config->GetSubConfiguration("Server")); - if(rserverConfig.KeyExists("User")) - { - username = rserverConfig.GetKeyValue("User"); - } - } - // Initialise the raid file controller RaidFileController &rcontroller(RaidFileController::GetController()); rcontroller.Initialise(config->GetKeyValue("RaidFileConf").c_str()); @@ -537,8 +632,10 @@ int main(int argc, const char *argv[]) PrintUsageAndExit(); } + std::string command = argv[0]; + // Now do the command. - if(::strcmp(argv[0], "create") == 0) + if(command == "create") { // which disc? int32_t discnum; @@ -558,14 +655,39 @@ int main(int argc, const char *argv[]) CheckSoftHardLimits(softlimit, hardlimit); // Create the account... - return CreateAccount(*config, username, id, discnum, softlimit, hardlimit); + return CreateAccount(*config, id, discnum, softlimit, hardlimit); } - else if(::strcmp(argv[0], "info") == 0) + else if(command == "info") { // Print information on this account return AccountInfo(*config, id); } - else if(::strcmp(argv[0], "setlimit") == 0) + else if(command == "enabled") + { + // Change the AccountEnabled flag on this account + if(argc != 3) + { + PrintUsageAndExit(); + } + + bool enabled = true; + std::string enabled_string = argv[2]; + if(enabled_string == "yes") + { + enabled = true; + } + else if(enabled_string == "no") + { + enabled = false; + } + else + { + PrintUsageAndExit(); + } + + return SetAccountEnabled(*config, id, enabled); + } + else if(command == "setlimit") { // Change the limits on this account if(argc < 4) @@ -574,9 +696,20 @@ int main(int argc, const char *argv[]) return 1; } - return SetLimit(*config, username, id, argv[2], argv[3]); + return SetLimit(*config, id, argv[2], argv[3]); + } + else if(command == "name") + { + // Change the limits on this account + if(argc != 3) + { + BOX_ERROR("name command requires a new name."); + return 1; + } + + return SetAccountName(*config, id, argv[2]); } - else if(::strcmp(argv[0], "delete") == 0) + else if(command == "delete") { // Delete an account bool askForConfirmation = true; @@ -584,9 +717,9 @@ int main(int argc, const char *argv[]) { askForConfirmation = false; } - return DeleteAccount(*config, username, id, askForConfirmation); + return DeleteAccount(*config, id, askForConfirmation); } - else if(::strcmp(argv[0], "check") == 0) + else if(command == "check") { bool fixErrors = false; bool quiet = false; @@ -610,11 +743,15 @@ int main(int argc, const char *argv[]) } // Check the account - return CheckAccount(*config, username, id, fixErrors, quiet); + return CheckAccount(*config, id, fixErrors, quiet); + } + else if(command == "housekeep") + { + return HousekeepAccountNow(*config, id); } else { - BOX_ERROR("Unknown command '" << argv[0] << "'."); + BOX_ERROR("Unknown command '" << command << "'."); return 1; } @@ -623,4 +760,3 @@ int main(int argc, const char *argv[]) MAINHELPER_END } - |