summaryrefslogtreecommitdiff
path: root/bin/bbstoreaccounts/bbstoreaccounts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bin/bbstoreaccounts/bbstoreaccounts.cpp')
-rw-r--r--bin/bbstoreaccounts/bbstoreaccounts.cpp500
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
}
-