summaryrefslogtreecommitdiff
path: root/bin/bbstored
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2008-09-13 15:29:26 +0000
committerChris Wilson <chris+github@qwirx.com>2008-09-13 15:29:26 +0000
commitbed534690981df575f5e6000c28c6b7b6c0d84f4 (patch)
treefe11494d36104453e9fb7b77d8747384530438a1 /bin/bbstored
parentf3d1fd71bd8bb41b2ee95e72ae2d8fcb6a535d48 (diff)
Add command to undelete a file, to complete the set of commands
implemented by the bbstored server.
Diffstat (limited to 'bin/bbstored')
-rw-r--r--bin/bbstored/BackupCommands.cpp24
-rw-r--r--bin/bbstored/BackupStoreContext.cpp82
-rw-r--r--bin/bbstored/BackupStoreContext.h1
-rw-r--r--bin/bbstored/backupprotocol.txt6
4 files changed, 112 insertions, 1 deletions
diff --git a/bin/bbstored/BackupCommands.cpp b/bin/bbstored/BackupCommands.cpp
index b5ae365c..38cda234 100644
--- a/bin/bbstored/BackupCommands.cpp
+++ b/bin/bbstored/BackupCommands.cpp
@@ -610,6 +610,30 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerDeleteFile::DoCommand(BackupPr
// --------------------------------------------------------------------------
//
// Function
+// Name: BackupProtocolServerUndeleteFile::DoCommand(
+// BackupProtocolServer &, BackupStoreContext &)
+// Purpose: Undelete a file
+// Created: 2008-09-12
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<ProtocolObject> BackupProtocolServerUndeleteFile::DoCommand(
+ BackupProtocolServer &rProtocol, BackupStoreContext &rContext)
+{
+ CHECK_PHASE(Phase_Commands)
+ CHECK_WRITEABLE_SESSION
+
+ // Context handles this
+ bool result = rContext.UndeleteFile(mObjectID, mInDirectory);
+
+ // return the object ID or zero for not found
+ return std::auto_ptr<ProtocolObject>(
+ new BackupProtocolServerSuccess(result ? mObjectID : 0));
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
// Name: BackupProtocolServerDeleteDirectory::DoCommand(BackupProtocolServer &, BackupStoreContext &)
// Purpose: Delete a directory
// Created: 2003/10/21
diff --git a/bin/bbstored/BackupStoreContext.cpp b/bin/bbstored/BackupStoreContext.cpp
index 8334658a..f8108beb 100644
--- a/bin/bbstored/BackupStoreContext.cpp
+++ b/bin/bbstored/BackupStoreContext.cpp
@@ -695,6 +695,7 @@ bool BackupStoreContext::DeleteFile(const BackupStoreFilename &rFilename, int64_
{
THROW_EXCEPTION(BackupStoreException, StoreInfoNotLoaded)
}
+
if(mReadOnly)
{
THROW_EXCEPTION(BackupStoreException, ContextIsReadOnly)
@@ -759,12 +760,91 @@ bool BackupStoreContext::DeleteFile(const BackupStoreFilename &rFilename, int64_
RemoveDirectoryFromCache(InDirectory);
throw;
}
-
return fileExisted;
}
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupStoreContext::DeleteFile(const BackupStoreFilename &, int64_t, int64_t &)
+// Purpose: Deletes a file, returning true if the file existed. Object ID returned too, set to zero if not found.
+// Created: 2003/10/21
+//
+// --------------------------------------------------------------------------
+bool BackupStoreContext::UndeleteFile(int64_t ObjectID, int64_t InDirectory)
+{
+ // Essential checks!
+ if(mpStoreInfo.get() == 0)
+ {
+ THROW_EXCEPTION(BackupStoreException, StoreInfoNotLoaded)
+ }
+
+ if(mReadOnly)
+ {
+ THROW_EXCEPTION(BackupStoreException, ContextIsReadOnly)
+ }
+
+ // Find the directory the file is in (will exception if it fails)
+ BackupStoreDirectory &dir(GetDirectoryInternal(InDirectory));
+
+ // Setup flags
+ bool fileExisted = false;
+ bool madeChanges = false;
+
+ // Count of deleted blocks
+ int64_t blocksDel = 0;
+
+ try
+ {
+ // Iterate through directory, only looking at files which have been deleted
+ BackupStoreDirectory::Iterator i(dir);
+ BackupStoreDirectory::Entry *e = 0;
+ while((e = i.Next(BackupStoreDirectory::Entry::Flags_File |
+ BackupStoreDirectory::Entry::Flags_Deleted, 0)) != 0)
+ {
+ // Compare name
+ if(e->GetObjectID() == ObjectID)
+ {
+ // Check that it's definitely already deleted
+ ASSERT((e->GetFlags() & BackupStoreDirectory::Entry::Flags_Deleted) != 0);
+ // Clear deleted flag
+ e->RemoveFlags(BackupStoreDirectory::Entry::Flags_Deleted);
+ // Mark as made a change
+ madeChanges = true;
+ blocksDel -= e->GetSizeInBlocks();
+
+ // Is this the last version?
+ if((e->GetFlags() & BackupStoreDirectory::Entry::Flags_OldVersion) == 0)
+ {
+ // Yes. It's been found.
+ fileExisted = true;
+ }
+ }
+ }
+
+ // Save changes?
+ if(madeChanges)
+ {
+ // Save the directory back
+ SaveDirectory(dir, InDirectory);
+
+ // Modify the store info, and write
+ mpStoreInfo->ChangeBlocksInDeletedFiles(blocksDel);
+
+ // Maybe postponed save of store info
+ SaveStoreInfo();
+ }
+ }
+ catch(...)
+ {
+ RemoveDirectoryFromCache(InDirectory);
+ throw;
+ }
+
+ return fileExisted;
+}
// --------------------------------------------------------------------------
diff --git a/bin/bbstored/BackupStoreContext.h b/bin/bbstored/BackupStoreContext.h
index da0a7668..4cfdb601 100644
--- a/bin/bbstored/BackupStoreContext.h
+++ b/bin/bbstored/BackupStoreContext.h
@@ -112,6 +112,7 @@ public:
void ChangeDirAttributes(int64_t Directory, const StreamableMemBlock &Attributes, int64_t AttributesModTime);
bool ChangeFileAttributes(const BackupStoreFilename &rFilename, int64_t InDirectory, const StreamableMemBlock &Attributes, int64_t AttributesHash, int64_t &rObjectIDOut);
bool DeleteFile(const BackupStoreFilename &rFilename, int64_t InDirectory, int64_t &rObjectIDOut);
+ bool UndeleteFile(int64_t ObjectID, int64_t InDirectory);
void DeleteDirectory(int64_t ObjectID, bool Undelete = false);
void MoveObject(int64_t ObjectID, int64_t MoveFromDirectory, int64_t MoveToDirectory, const BackupStoreFilename &rNewFilename, bool MoveAllWithSameName, bool AllowMoveOverDeletedObject);
diff --git a/bin/bbstored/backupprotocol.txt b/bin/bbstored/backupprotocol.txt
index d5406ae2..3eca514a 100644
--- a/bin/bbstored/backupprotocol.txt
+++ b/bin/bbstored/backupprotocol.txt
@@ -204,6 +204,12 @@ GetBlockIndexByName 35 Command(Success)
# stream of the block index follows the reply if found ID != 0
+UndeleteFile 36 Command(Success)
+ int64 InDirectory
+ int64 ObjectID
+ # will return 0 if the object couldn't be found in the specified directory
+
+
# -------------------------------------------------------------------------------------
# Information commands
# -------------------------------------------------------------------------------------