summaryrefslogtreecommitdiff
path: root/lib/backupstore/BackupCommands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backupstore/BackupCommands.cpp')
-rw-r--r--lib/backupstore/BackupCommands.cpp419
1 files changed, 243 insertions, 176 deletions
diff --git a/lib/backupstore/BackupCommands.cpp b/lib/backupstore/BackupCommands.cpp
index 318ce55a..22ef0215 100644
--- a/lib/backupstore/BackupCommands.cpp
+++ b/lib/backupstore/BackupCommands.cpp
@@ -52,11 +52,66 @@
return PROTOCOL_ERROR(Err_SessionReadOnly); \
}
+
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupProtocolVersion::DoCommand(Protocol &, BackupStoreContext &)
-// Purpose: Return the current version, or an error if the requested version isn't allowed
+// Name: BackupProtocolMessage::HandleException(BoxException& e)
+// Purpose: Return an error message appropriate to the passed-in
+// exception, or rethrow it.
+// Created: 2014/09/14
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<BackupProtocolMessage> BackupProtocolReplyable::HandleException(BoxException& e) const
+{
+ if(e.GetType() == RaidFileException::ExceptionType &&
+ e.GetSubType() == RaidFileException::RaidFileDoesntExist)
+ {
+ return PROTOCOL_ERROR(Err_DoesNotExist);
+ }
+ else if (e.GetType() == BackupStoreException::ExceptionType)
+ {
+ if(e.GetSubType() == BackupStoreException::AddedFileDoesNotVerify)
+ {
+ return PROTOCOL_ERROR(Err_FileDoesNotVerify);
+ }
+ else if(e.GetSubType() == BackupStoreException::AddedFileExceedsStorageLimit)
+ {
+ return PROTOCOL_ERROR(Err_StorageLimitExceeded);
+ }
+ else if(e.GetSubType() == BackupStoreException::MultiplyReferencedObject)
+ {
+ return PROTOCOL_ERROR(Err_MultiplyReferencedObject);
+ }
+ else if(e.GetSubType() == BackupStoreException::CouldNotFindEntryInDirectory)
+ {
+ return PROTOCOL_ERROR(Err_DoesNotExistInDirectory);
+ }
+ else if(e.GetSubType() == BackupStoreException::NameAlreadyExistsInDirectory)
+ {
+ return PROTOCOL_ERROR(Err_TargetNameExists);
+ }
+ else if(e.GetSubType() == BackupStoreException::ObjectDoesNotExist)
+ {
+ return PROTOCOL_ERROR(Err_DoesNotExist);
+ }
+ else if(e.GetSubType() == BackupStoreException::PatchChainInfoBadInDirectory)
+ {
+ return PROTOCOL_ERROR(Err_PatchConsistencyError);
+ }
+ }
+
+ throw;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupProtocolVersion::DoCommand(Protocol &,
+// BackupStoreContext &)
+// Purpose: Return the current version, or an error if the
+// requested version isn't allowed
// Created: 2003/08/20
//
// --------------------------------------------------------------------------
@@ -93,7 +148,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtoc
// and that the client actually has an account on this machine
if(mClientID != rContext.GetClientID())
{
- BOX_WARNING("Failed login from client ID " <<
+ BOX_WARNING("Failed login from client ID " <<
BOX_FORMAT_ACCOUNT(mClientID) << ": "
"wrong certificate for this account");
return PROTOCOL_ERROR(Err_BadLogin);
@@ -101,7 +156,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtoc
if(!rContext.GetClientHasAccount())
{
- BOX_WARNING("Failed login from client ID " <<
+ BOX_WARNING("Failed login from client ID " <<
BOX_FORMAT_ACCOUNT(mClientID) << ": "
"no such account on this server");
return PROTOCOL_ERROR(Err_BadLogin);
@@ -117,17 +172,17 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtoc
BOX_FORMAT_ACCOUNT(mClientID));
return PROTOCOL_ERROR(Err_CannotLockStoreForWriting);
}
-
+
// Debug: check we got the lock
ASSERT(!rContext.SessionIsReadOnly());
}
-
+
// Load the store info
rContext.LoadStoreInfo();
if(!rContext.GetBackupStoreInfo().IsAccountEnabled())
{
- BOX_WARNING("Refused login from disabled client ID " <<
+ BOX_WARNING("Refused login from disabled client ID " <<
BOX_FORMAT_ACCOUNT(mClientID));
return PROTOCOL_ERROR(Err_DisabledAccount);
}
@@ -137,9 +192,9 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtoc
// Mark the next phase
rContext.SetPhase(BackupStoreContext::Phase_Commands);
-
+
// Log login
- BOX_NOTICE("Login from Client ID " <<
+ BOX_NOTICE("Login from Client ID " <<
BOX_FORMAT_ACCOUNT(mClientID) << " "
"(name=" << rContext.GetAccountName() << "): " <<
(((mFlags & Flags_ReadOnly) != Flags_ReadOnly)
@@ -164,14 +219,15 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolLogin::DoCommand(BackupProtoc
// --------------------------------------------------------------------------
std::auto_ptr<BackupProtocolMessage> BackupProtocolFinished::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
{
- BOX_NOTICE("Session finished for Client ID " <<
+ // can be called in any phase
+
+ BOX_NOTICE("Session finished for Client ID " <<
BOX_FORMAT_ACCOUNT(rContext.GetClientID()) << " "
"(name=" << rContext.GetAccountName() << ")");
// Let the context know about it
rContext.ReceivedFinishCommand();
- // can be called in any phase
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolFinished);
}
@@ -191,26 +247,15 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolListDirectory::DoCommand(Back
// Store the listing to a stream
std::auto_ptr<CollectInBufferStream> stream(new CollectInBufferStream);
- try
- {
- // Ask the context for a directory
- const BackupStoreDirectory &rdir(
- rContext.GetDirectory(mObjectID));
- rdir.WriteToStream(*stream, mFlagsMustBeSet,
- mFlagsNotToBeSet, mSendAttributes,
- false /* never send dependency info to the client */);
- }
- catch (RaidFileException &e)
- {
- if (e.GetSubType() == RaidFileException::RaidFileDoesntExist)
- {
- return PROTOCOL_ERROR(Err_DoesNotExist);
- }
- throw;
- }
+ // Ask the context for a directory
+ const BackupStoreDirectory &rdir(
+ rContext.GetDirectory(mObjectID));
+ rdir.WriteToStream(*stream, mFlagsMustBeSet,
+ mFlagsNotToBeSet, mSendAttributes,
+ false /* never send dependency info to the client */);
stream->SetForReading();
-
+
// Get the protocol to send the stream
rProtocol.SendStreamAfterCommand(static_cast< std::auto_ptr<IOStream> > (stream));
@@ -226,7 +271,9 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolListDirectory::DoCommand(Back
// Created: 2003/09/02
//
// --------------------------------------------------------------------------
-std::auto_ptr<BackupProtocolMessage> BackupProtocolStoreFile::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
+std::auto_ptr<BackupProtocolMessage> BackupProtocolStoreFile::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext,
+ IOStream& rDataStream) const
{
CHECK_PHASE(Phase_Commands)
CHECK_WRITEABLE_SESSION
@@ -237,7 +284,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolStoreFile::DoCommand(BackupPr
{
return hookResult;
}
-
+
// Check that the diff from file actually exists, if it's specified
if(mDiffFromFileID != 0)
{
@@ -247,35 +294,13 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolStoreFile::DoCommand(BackupPr
return PROTOCOL_ERROR(Err_DiffFromFileDoesNotExist);
}
}
-
- // A stream follows, which contains the file
- std::auto_ptr<IOStream> filestream(rProtocol.ReceiveStream());
-
+
// Ask the context to store it
- int64_t id = 0;
- try
- {
- id = rContext.AddFile(*filestream, mDirectoryObjectID,
- mModificationTime, mAttributesHash, mDiffFromFileID,
- mFilename,
- true /* mark files with same name as old versions */);
- }
- catch(BackupStoreException &e)
- {
- if(e.GetSubType() == BackupStoreException::AddedFileDoesNotVerify)
- {
- return PROTOCOL_ERROR(Err_FileDoesNotVerify);
- }
- else if(e.GetSubType() == BackupStoreException::AddedFileExceedsStorageLimit)
- {
- return PROTOCOL_ERROR(Err_StorageLimitExceeded);
- }
- else
- {
- throw;
- }
- }
-
+ int64_t id = rContext.AddFile(rDataStream, mDirectoryObjectID,
+ mModificationTime, mAttributesHash, mDiffFromFileID,
+ mFilename,
+ true /* mark files with same name as old versions */);
+
// Tell the caller what the file ID was
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(id));
}
@@ -298,7 +323,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObject::DoCommand(BackupPr
// Check the object exists
if(!rContext.ObjectExists(mObjectID))
{
- return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(NoObject));
+ return PROTOCOL_ERROR(Err_DoesNotExist);
}
// Open the object
@@ -315,7 +340,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObject::DoCommand(BackupPr
//
// Function
// Name: BackupProtocolGetFile::DoCommand(Protocol &, BackupStoreContext &)
-// Purpose: Command to get an file object from the server -- may have to do a bit of
+// Purpose: Command to get an file object from the server -- may have to do a bit of
// work to get the object.
// Created: 2003/09/03
//
@@ -357,13 +382,13 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetFile::DoCommand(BackupProt
en = rdir.FindEntryByID(id);
if(en == 0)
{
- BOX_ERROR("Object " <<
+ BOX_ERROR("Object " <<
BOX_FORMAT_OBJECTID(mObjectID) <<
- " in dir " <<
+ " in dir " <<
BOX_FORMAT_OBJECTID(mInDirectory) <<
" for account " <<
BOX_FORMAT_ACCOUNT(rContext.GetClientID()) <<
- " references object " <<
+ " references object " <<
BOX_FORMAT_OBJECTID(id) <<
" which does not exist in dir");
return PROTOCOL_ERROR(Err_PatchConsistencyError);
@@ -371,89 +396,73 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetFile::DoCommand(BackupProt
id = en->GetDependsNewer();
}
while(en != 0 && id != 0);
-
+
// OK! The last entry in the chain is the full file, the others are patches back from it.
// Open the last one, which is the current from file
std::auto_ptr<IOStream> from(rContext.OpenObject(patchChain[patchChain.size() - 1]));
-
+
// Then, for each patch in the chain, do a combine
for(int p = ((int)patchChain.size()) - 2; p >= 0; --p)
{
// ID of patch
int64_t patchID = patchChain[p];
-
+
// Open it a couple of times
std::auto_ptr<IOStream> diff(rContext.OpenObject(patchID));
std::auto_ptr<IOStream> diff2(rContext.OpenObject(patchID));
-
+
// Choose a temporary filename for the result of the combination
std::ostringstream fs;
- fs << rContext.GetStoreRoot() << ".recombinetemp." << p;
- std::string tempFn =
+ fs << rContext.GetAccountRoot() << ".recombinetemp." << p;
+ std::string tempFn =
RaidFileController::DiscSetPathToFileSystemPath(
rContext.GetStoreDiscSet(), fs.str(),
p + 16);
-
+
// Open the temporary file
- std::auto_ptr<IOStream> combined;
- try
- {
- {
- // Write nastily to allow this to work with gcc 2.x
- std::auto_ptr<IOStream> t(
- new InvisibleTempFileStream(
- tempFn.c_str(),
- O_RDWR | O_CREAT |
- O_EXCL | O_BINARY |
- O_TRUNC));
- combined = t;
- }
- }
- catch(...)
- {
- // Make sure it goes
- ::unlink(tempFn.c_str());
- throw;
- }
-
+ std::auto_ptr<IOStream> combined(
+ new InvisibleTempFileStream(
+ tempFn, O_RDWR | O_CREAT | O_EXCL |
+ O_BINARY | O_TRUNC));
+
// Do the combining
BackupStoreFile::CombineFile(*diff, *diff2, *from, *combined);
-
+
// Move to the beginning of the combined file
combined->Seek(0, IOStream::SeekType_Absolute);
-
+
// Then shuffle round for the next go
if (from.get()) from->Close();
from = combined;
}
-
+
// Now, from contains a nice file to send to the client. Reorder it
{
// Write nastily to allow this to work with gcc 2.x
std::auto_ptr<IOStream> t(BackupStoreFile::ReorderFileToStreamOrder(from.get(), true /* take ownership */));
stream = t;
}
-
+
// Release from file to avoid double deletion
from.release();
}
else
{
// Simple case: file already exists on disc ready to go
-
+
// Open the object
std::auto_ptr<IOStream> object(rContext.OpenObject(mObjectID));
BufferedStream buf(*object);
-
+
// Verify it
if(!BackupStoreFile::VerifyEncodedFileFormat(buf))
{
return PROTOCOL_ERROR(Err_FileDoesNotVerify);
}
-
+
// Reset stream -- seek to beginning
object->Seek(0, IOStream::SeekType_Absolute);
-
+
// Reorder the stream/file into stream order
{
// Write nastily to allow this to work with gcc 2.x
@@ -461,15 +470,15 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetFile::DoCommand(BackupProt
stream = t;
}
- // Object will be deleted when the stream is deleted,
- // so can release the object auto_ptr here to avoid
+ // Object will be deleted when the stream is deleted,
+ // so can release the object auto_ptr here to avoid
// premature deletion
object.release();
}
// Stream the reordered stream to the peer
rProtocol.SendStreamAfterCommand(stream);
-
+
// Tell the caller what the file was
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID));
}
@@ -483,18 +492,38 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetFile::DoCommand(BackupProt
// Created: 2003/09/04
//
// --------------------------------------------------------------------------
-std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
+std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext,
+ IOStream& rDataStream) const
+{
+ return BackupProtocolCreateDirectory2(mContainingDirectoryID,
+ mAttributesModTime, 0 /* ModificationTime */,
+ mDirectoryName).DoCommand(rProtocol, rContext, rDataStream);
+}
+
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupProtocolCreateDirectory2::DoCommand(Protocol &, BackupStoreContext &)
+// Purpose: Create directory command, with a specific
+// modification time.
+// Created: 2014/02/11
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory2::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext,
+ IOStream& rDataStream) const
{
CHECK_PHASE(Phase_Commands)
CHECK_WRITEABLE_SESSION
-
- // Get the stream containing the attributes
- std::auto_ptr<IOStream> attrstream(rProtocol.ReceiveStream());
- // Collect the attributes -- do this now so no matter what the outcome,
+
+ // Collect the attributes -- do this now so no matter what the outcome,
// the data has been absorbed.
StreamableMemBlock attr;
- attr.Set(*attrstream, rProtocol.GetTimeout());
-
+ attr.Set(rDataStream, rProtocol.GetTimeout());
+
// Check to see if the hard limit has been exceeded
if(rContext.HardLimitExceeded())
{
@@ -503,8 +532,10 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory::DoCommand(Ba
}
bool alreadyExists = false;
- int64_t id = rContext.AddDirectory(mContainingDirectoryID, mDirectoryName, attr, mAttributesModTime, alreadyExists);
-
+ int64_t id = rContext.AddDirectory(mContainingDirectoryID,
+ mDirectoryName, attr, mAttributesModTime, mModificationTime,
+ alreadyExists);
+
if(alreadyExists)
{
return PROTOCOL_ERROR(Err_DirectoryAlreadyExists);
@@ -524,17 +555,17 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolCreateDirectory::DoCommand(Ba
// Created: 2003/09/06
//
// --------------------------------------------------------------------------
-std::auto_ptr<BackupProtocolMessage> BackupProtocolChangeDirAttributes::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
+std::auto_ptr<BackupProtocolMessage> BackupProtocolChangeDirAttributes::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext,
+ IOStream& rDataStream) const
{
CHECK_PHASE(Phase_Commands)
CHECK_WRITEABLE_SESSION
- // Get the stream containing the attributes
- std::auto_ptr<IOStream> attrstream(rProtocol.ReceiveStream());
- // Collect the attributes -- do this now so no matter what the outcome,
+ // Collect the attributes -- do this now so no matter what the outcome,
// the data has been absorbed.
StreamableMemBlock attr;
- attr.Set(*attrstream, rProtocol.GetTimeout());
+ attr.Set(rDataStream, rProtocol.GetTimeout());
// Get the context to do it's magic
rContext.ChangeDirAttributes(mObjectID, attr, mAttributesModTime);
@@ -552,17 +583,18 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolChangeDirAttributes::DoComman
// Created: 2003/09/06
//
// --------------------------------------------------------------------------
-std::auto_ptr<BackupProtocolMessage> BackupProtocolSetReplacementFileAttributes::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
+std::auto_ptr<BackupProtocolMessage>
+BackupProtocolSetReplacementFileAttributes::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext,
+ IOStream& rDataStream) const
{
CHECK_PHASE(Phase_Commands)
CHECK_WRITEABLE_SESSION
- // Get the stream containing the attributes
- std::auto_ptr<IOStream> attrstream(rProtocol.ReceiveStream());
- // Collect the attributes -- do this now so no matter what the outcome,
+ // Collect the attributes -- do this now so no matter what the outcome,
// the data has been absorbed.
StreamableMemBlock attr;
- attr.Set(*attrstream, rProtocol.GetTimeout());
+ attr.Set(rDataStream, rProtocol.GetTimeout());
// Get the context to do it's magic
int64_t objectID = 0;
@@ -577,7 +609,6 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolSetReplacementFileAttributes:
}
-
// --------------------------------------------------------------------------
//
// Function
@@ -644,19 +675,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolDeleteDirectory::DoCommand(Ba
}
// Context handles this
- try
- {
- rContext.DeleteDirectory(mObjectID);
- }
- catch (BackupStoreException &e)
- {
- if(e.GetSubType() == BackupStoreException::MultiplyReferencedObject)
- {
- return PROTOCOL_ERROR(Err_MultiplyReferencedObject);
- }
-
- throw;
- }
+ rContext.DeleteDirectory(mObjectID);
// return the object ID
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID));
@@ -722,29 +741,11 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolMoveObject::DoCommand(BackupP
{
CHECK_PHASE(Phase_Commands)
CHECK_WRITEABLE_SESSION
-
+
// Let context do this, but modify error reporting on exceptions...
- try
- {
- rContext.MoveObject(mObjectID, mMoveFromDirectory, mMoveToDirectory,
- mNewFilename, (mFlags & Flags_MoveAllWithSameName) == Flags_MoveAllWithSameName,
- (mFlags & Flags_AllowMoveOverDeletedObject) == Flags_AllowMoveOverDeletedObject);
- }
- catch(BackupStoreException &e)
- {
- if(e.GetSubType() == BackupStoreException::CouldNotFindEntryInDirectory)
- {
- return PROTOCOL_ERROR(Err_DoesNotExist);
- }
- else if(e.GetSubType() == BackupStoreException::NameAlreadyExistsInDirectory)
- {
- return PROTOCOL_ERROR(Err_TargetNameExists);
- }
- else
- {
- throw;
- }
- }
+ rContext.MoveObject(mObjectID, mMoveFromDirectory, mMoveToDirectory,
+ mNewFilename, (mFlags & Flags_MoveAllWithSameName) == Flags_MoveAllWithSameName,
+ (mFlags & Flags_AllowMoveOverDeletedObject) == Flags_AllowMoveOverDeletedObject);
// Return the object ID
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolSuccess(mObjectID));
@@ -762,21 +763,21 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolMoveObject::DoCommand(BackupP
std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
{
CHECK_PHASE(Phase_Commands)
-
+
// Create a stream for the list of filenames
std::auto_ptr<CollectInBufferStream> stream(new CollectInBufferStream);
// Object and directory IDs
int64_t objectID = mObjectID;
int64_t dirID = mContainingDirectoryID;
-
+
// Data to return in the reply
int32_t numNameElements = 0;
int16_t objectFlags = 0;
int64_t modTime = 0;
uint64_t attrModHash = 0;
bool haveModTimes = false;
-
+
do
{
// Check the directory really exists
@@ -786,7 +787,28 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(Back
}
// Load up the directory
- const BackupStoreDirectory &rdir(rContext.GetDirectory(dirID));
+ const BackupStoreDirectory *pDir;
+
+ try
+ {
+ pDir = &rContext.GetDirectory(dirID);
+ }
+ catch(BackupStoreException &e)
+ {
+ if(e.GetSubType() == BackupStoreException::ObjectDoesNotExist)
+ {
+ // If this can't be found, then there is a problem...
+ // tell the caller it can't be found.
+ return std::auto_ptr<BackupProtocolMessage>(
+ new BackupProtocolObjectName(
+ BackupProtocolObjectName::NumNameElements_ObjectDoesntExist,
+ 0, 0, 0));
+ }
+
+ throw;
+ }
+
+ const BackupStoreDirectory& rdir(*pDir);
// Find the element in this directory and store it's name
if(objectID != ObjectID_DirectoryOnly)
@@ -799,13 +821,13 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(Back
// Abort!
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolObjectName(BackupProtocolObjectName::NumNameElements_ObjectDoesntExist, 0, 0, 0));
}
-
+
// Store flags?
if(objectFlags == 0)
{
objectFlags = en->GetFlags();
}
-
+
// Store modification times?
if(!haveModTimes)
{
@@ -813,14 +835,14 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(Back
attrModHash = en->GetAttributesHash();
haveModTimes = true;
}
-
+
// Store the name in the stream
en->GetName().WriteToStream(*stream);
-
+
// Count of name elements
++numNameElements;
}
-
+
// Setup for next time round
objectID = dirID;
dirID = rdir.GetContainerID();
@@ -831,7 +853,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetObjectName::DoCommand(Back
if(numNameElements > 0)
{
// Get the stream ready to go
- stream->SetForReading();
+ stream->SetForReading();
// Tell the protocol to send the stream
rProtocol.SendStreamAfterCommand(static_cast< std::auto_ptr<IOStream> >(stream));
}
@@ -856,10 +878,10 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByID::DoCommand(
// Open the file
std::auto_ptr<IOStream> stream(rContext.OpenObject(mObjectID));
-
+
// Move the file pointer to the block index
BackupStoreFile::MoveStreamPositionToBlockIndex(*stream);
-
+
// Return the stream to the client
rProtocol.SendStreamAfterCommand(stream);
@@ -882,7 +904,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByName::DoComman
// Get the directory
const BackupStoreDirectory &dir(rContext.GetDirectory(mInDirectory));
-
+
// Find the latest object ID within it which has the same name
int64_t objectID = 0;
BackupStoreDirectory::Iterator i(dir);
@@ -898,7 +920,7 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByName::DoComman
}
}
}
-
+
// Found anything?
if(objectID == 0)
{
@@ -908,10 +930,10 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetBlockIndexByName::DoComman
// Open the file
std::auto_ptr<IOStream> stream(rContext.OpenObject(objectID));
-
+
// Move the file pointer to the block index
BackupStoreFile::MoveStreamPositionToBlockIndex(*stream);
-
+
// Return the stream to the client
rProtocol.SendStreamAfterCommand(stream);
@@ -934,11 +956,11 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetAccountUsage::DoCommand(Ba
// Get store info from context
const BackupStoreInfo &rinfo(rContext.GetBackupStoreInfo());
-
+
// Find block size
RaidFileController &rcontroller(RaidFileController::GetController());
RaidFileDiscSet &rdiscSet(rcontroller.GetDiscSet(rinfo.GetDiscSetNumber()));
-
+
// Return info
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolAccountUsage(
rinfo.GetBlocksUsed(),
@@ -968,3 +990,48 @@ std::auto_ptr<BackupProtocolMessage> BackupProtocolGetIsAlive::DoCommand(BackupP
//
return std::auto_ptr<BackupProtocolMessage>(new BackupProtocolIsAlive());
}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupProtocolGetAccountUsage2::DoCommand(BackupProtocolReplyable &, BackupStoreContext &)
+// Purpose: Return the amount of disc space used
+// Created: 26/12/13
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<BackupProtocolMessage> BackupProtocolGetAccountUsage2::DoCommand(
+ BackupProtocolReplyable &rProtocol, BackupStoreContext &rContext) const
+{
+ CHECK_PHASE(Phase_Commands)
+
+ // Get store info from context
+ const BackupStoreInfo &info(rContext.GetBackupStoreInfo());
+
+ // Find block size
+ RaidFileController &rcontroller(RaidFileController::GetController());
+ RaidFileDiscSet &rdiscSet(rcontroller.GetDiscSet(info.GetDiscSetNumber()));
+
+ // Return info
+ BackupProtocolAccountUsage2* usage = new BackupProtocolAccountUsage2();
+ std::auto_ptr<BackupProtocolMessage> reply(usage);
+ #define COPY(name) usage->Set ## name (info.Get ## name ())
+ COPY(AccountName);
+ usage->SetAccountEnabled(info.IsAccountEnabled());
+ COPY(ClientStoreMarker);
+ usage->SetBlockSize(rdiscSet.GetBlockSize());
+ COPY(LastObjectIDUsed);
+ COPY(BlocksUsed);
+ COPY(BlocksInCurrentFiles);
+ COPY(BlocksInOldFiles);
+ COPY(BlocksInDeletedFiles);
+ COPY(BlocksInDirectories);
+ COPY(BlocksSoftLimit);
+ COPY(BlocksHardLimit);
+ COPY(NumCurrentFiles);
+ COPY(NumOldFiles);
+ COPY(NumDeletedFiles);
+ COPY(NumDirectories);
+ #undef COPY
+
+ return reply;
+}