summaryrefslogtreecommitdiff
path: root/lib/backupclient
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backupclient')
-rw-r--r--lib/backupclient/BackupClientCryptoKeys.cpp52
-rw-r--r--lib/backupclient/BackupClientCryptoKeys.h2
-rw-r--r--lib/backupclient/BackupClientFileAttributes.cpp64
-rw-r--r--lib/backupclient/BackupClientFileAttributes.h8
-rw-r--r--lib/backupclient/BackupClientRestore.cpp289
-rw-r--r--lib/backupclient/BackupClientRestore.h19
-rw-r--r--lib/backupclient/BackupDaemonConfigVerify.cpp97
-rw-r--r--lib/backupclient/BackupStoreFile.cpp27
-rw-r--r--lib/backupclient/BackupStoreFile.h17
-rw-r--r--lib/backupclient/BackupStoreFileDiff.cpp69
-rw-r--r--lib/backupclient/BackupStoreFileEncodeStream.cpp69
-rw-r--r--lib/backupclient/BackupStoreFileEncodeStream.h10
-rw-r--r--lib/backupclient/BackupStoreFilename.cpp32
-rw-r--r--lib/backupclient/BackupStoreFilename.h24
-rw-r--r--lib/backupclient/BackupStoreFilenameClear.cpp23
-rw-r--r--lib/backupclient/BackupStoreObjectDump.cpp21
-rw-r--r--lib/backupclient/RunStatusProvider.h29
17 files changed, 606 insertions, 246 deletions
diff --git a/lib/backupclient/BackupClientCryptoKeys.cpp b/lib/backupclient/BackupClientCryptoKeys.cpp
index 46b77f0a..7a8da7ba 100644
--- a/lib/backupclient/BackupClientCryptoKeys.cpp
+++ b/lib/backupclient/BackupClientCryptoKeys.cpp
@@ -28,40 +28,58 @@
// Created: 1/12/03
//
// --------------------------------------------------------------------------
-void BackupClientCryptoKeys_Setup(const char *KeyMaterialFilename)
+void BackupClientCryptoKeys_Setup(const std::string& rKeyMaterialFilename)
{
// Read in the key material
unsigned char KeyMaterial[BACKUPCRYPTOKEYS_FILE_SIZE];
// Open the file
- FileStream file(KeyMaterialFilename);
+ FileStream file(rKeyMaterialFilename);
+
// Read in data
if(!file.ReadFullBuffer(KeyMaterial, BACKUPCRYPTOKEYS_FILE_SIZE, 0))
{
THROW_EXCEPTION(BackupStoreException, CouldntLoadClientKeyMaterial)
}
- // Tell the filename how to encrypt
- BackupStoreFilenameClear::SetBlowfishKey(KeyMaterial + BACKUPCRYPTOKEYS_FILENAME_KEY_START, BACKUPCRYPTOKEYS_FILENAME_KEY_LENGTH,
- KeyMaterial + BACKUPCRYPTOKEYS_FILENAME_IV_START, BACKUPCRYPTOKEYS_FILENAME_IV_LENGTH);
- BackupStoreFilenameClear::SetEncodingMethod(BackupStoreFilename::Encoding_Blowfish);
+ // Setup keys and encoding method for filename encryption
+ BackupStoreFilenameClear::SetBlowfishKey(
+ KeyMaterial + BACKUPCRYPTOKEYS_FILENAME_KEY_START,
+ BACKUPCRYPTOKEYS_FILENAME_KEY_LENGTH,
+ KeyMaterial + BACKUPCRYPTOKEYS_FILENAME_IV_START,
+ BACKUPCRYPTOKEYS_FILENAME_IV_LENGTH);
+ BackupStoreFilenameClear::SetEncodingMethod(
+ BackupStoreFilename::Encoding_Blowfish);
+
+ // Setup key for attributes encryption
+ BackupClientFileAttributes::SetBlowfishKey(
+ KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_START,
+ BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_LENGTH);
+
+ // Setup secret for attribute hashing
+ BackupClientFileAttributes::SetAttributeHashSecret(
+ KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTE_HASH_SECRET_START,
+ BACKUPCRYPTOKEYS_ATTRIBUTE_HASH_SECRET_LENGTH);
- // Tell the attributes how to encrypt
- BackupClientFileAttributes::SetBlowfishKey(KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_START, BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_LENGTH);
- // and the secret for hashing
- BackupClientFileAttributes::SetAttributeHashSecret(KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTE_HASH_SECRET_START, BACKUPCRYPTOKEYS_ATTRIBUTE_HASH_SECRET_LENGTH);
+ // Setup keys for file data encryption
+ BackupStoreFile::SetBlowfishKeys(
+ KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_START,
+ BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_LENGTH,
+ KeyMaterial + BACKUPCRYPTOKEYS_FILE_BLOCK_ENTRY_KEY_START,
+ BACKUPCRYPTOKEYS_FILE_BLOCK_ENTRY_KEY_LENGTH);
- // Tell the files how to encrypt
- BackupStoreFile::SetBlowfishKeys(KeyMaterial + BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_START, BACKUPCRYPTOKEYS_ATTRIBUTES_KEY_LENGTH,
- KeyMaterial + BACKUPCRYPTOKEYS_FILE_BLOCK_ENTRY_KEY_START, BACKUPCRYPTOKEYS_FILE_BLOCK_ENTRY_KEY_LENGTH);
#ifndef HAVE_OLD_SSL
// Use AES where available
- BackupStoreFile::SetAESKey(KeyMaterial + BACKUPCRYPTOKEYS_FILE_AES_KEY_START, BACKUPCRYPTOKEYS_FILE_AES_KEY_LENGTH);
+ BackupStoreFile::SetAESKey(
+ KeyMaterial + BACKUPCRYPTOKEYS_FILE_AES_KEY_START,
+ BACKUPCRYPTOKEYS_FILE_AES_KEY_LENGTH);
#endif
// Wipe the key material from memory
- ::memset(KeyMaterial, 0, BACKUPCRYPTOKEYS_FILE_SIZE);
+ #ifdef _MSC_VER // not defined on MinGW
+ SecureZeroMemory(KeyMaterial, BACKUPCRYPTOKEYS_FILE_SIZE);
+ #else
+ ::memset(KeyMaterial, 0, BACKUPCRYPTOKEYS_FILE_SIZE);
+ #endif
}
-
-
diff --git a/lib/backupclient/BackupClientCryptoKeys.h b/lib/backupclient/BackupClientCryptoKeys.h
index 5e3a7df2..f40e2e03 100644
--- a/lib/backupclient/BackupClientCryptoKeys.h
+++ b/lib/backupclient/BackupClientCryptoKeys.h
@@ -49,7 +49,7 @@
#define BACKUPCRYPTOKEYS_FILE_AES_KEY_LENGTH 32
-void BackupClientCryptoKeys_Setup(const char *KeyMaterialFilename);
+void BackupClientCryptoKeys_Setup(const std::string& rKeyMaterialFilename);
#endif // BACKUPCLIENTCRYTOKEYS__H
diff --git a/lib/backupclient/BackupClientFileAttributes.cpp b/lib/backupclient/BackupClientFileAttributes.cpp
index 3ffeb189..bb17d41f 100644
--- a/lib/backupclient/BackupClientFileAttributes.cpp
+++ b/lib/backupclient/BackupClientFileAttributes.cpp
@@ -15,11 +15,14 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <string.h>
+#include <errno.h>
#include <limits.h>
+
#include <algorithm>
+#include <cstring>
#include <new>
#include <vector>
+
#ifdef HAVE_SYS_XATTR_H
#include <cerrno>
#include <sys/xattr.h>
@@ -299,9 +302,11 @@ void BackupClientFileAttributes::ReadAttributes(const char *Filename, bool ZeroM
StreamableMemBlock *pnewAttr = 0;
try
{
- struct stat st;
- if(::lstat(Filename, &st) != 0)
+ EMU_STRUCT_STAT st;
+ if(EMU_LSTAT(Filename, &st) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to stat file: '" <<
+ Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
@@ -390,7 +395,7 @@ void BackupClientFileAttributes::ReadAttributes(const char *Filename, bool ZeroM
// Created: 2003/10/07
//
// --------------------------------------------------------------------------
-void BackupClientFileAttributes::FillAttributes(StreamableMemBlock &outputBlock, const char *Filename, struct stat &st, bool ZeroModificationTimes)
+void BackupClientFileAttributes::FillAttributes(StreamableMemBlock &outputBlock, const char *Filename, EMU_STRUCT_STAT &st, bool ZeroModificationTimes)
{
outputBlock.ResizeBlock(sizeof(attr_StreamFormat));
attr_StreamFormat *pattr = (attr_StreamFormat*)outputBlock.GetBuffer();
@@ -439,6 +444,7 @@ void BackupClientFileAttributes::FillAttributesLink(StreamableMemBlock &outputBl
int linkedToSize = ::readlink(Filename, linkedTo, PATH_MAX);
if(linkedToSize == -1)
{
+ BOX_LOG_SYS_ERROR("Failed to readlink '" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError);
}
@@ -463,7 +469,7 @@ void BackupClientFileAttributes::FillAttributesLink(StreamableMemBlock &outputBl
void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBlock, const char *Filename)
{
#ifdef HAVE_SYS_XATTR_H
- int listBufferSize = 1000;
+ int listBufferSize = 10000;
char* list = new char[listBufferSize];
try
@@ -529,6 +535,9 @@ void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBloc
int valueSize = ::lgetxattr(Filename, attrKey.c_str(), 0, 0);
if(valueSize<0)
{
+ BOX_LOG_SYS_ERROR("Failed to get "
+ "extended attributes size "
+ "for '" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError);
}
@@ -544,6 +553,9 @@ void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBloc
valueSize = ::lgetxattr(Filename, attrKey.c_str(), buffer+xattrSize, xattrBufferSize-xattrSize);
if(valueSize<0)
{
+ BOX_LOG_SYS_ERROR("Failed to get "
+ "extended attributes for "
+ "'" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError);
}
xattrSize += valueSize;
@@ -559,9 +571,25 @@ void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBloc
outputBlock.ResizeBlock(xattrSize);
}
- else if(listSize<0 && errno!=EOPNOTSUPP && errno!=EACCES)
+ else if(listSize<0)
{
- THROW_EXCEPTION(CommonException, OSFileError);
+ if(errno == EOPNOTSUPP || errno == EACCES)
+ {
+ // fail silently
+ }
+ else if(errno == ERANGE)
+ {
+ BOX_ERROR("Failed to list extended "
+ "attributes of '" << Filename << "': "
+ "buffer too small, not backed up");
+ }
+ else
+ {
+ BOX_LOG_SYS_ERROR("Failed to list extended "
+ "attributes of '" << Filename << "', "
+ "not backed up");
+ THROW_EXCEPTION(CommonException, OSFileError);
+ }
}
}
catch(...)
@@ -638,6 +666,8 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename,
::unlink(Filename);
if(::symlink((char*)(pattr + 1), Filename) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to symlink '" << Filename <<
+ "' to '" << (char*)(pattr + 1) << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
#endif
@@ -655,12 +685,18 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename,
// Not a link, use normal chown
if(::chown(Filename, ntohl(pattr->UID), ntohl(pattr->GID)) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to change "
+ "owner of file "
+ "'" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
}
#else
- if(::lchown(Filename, ntohl(pattr->UID), ntohl(pattr->GID)) != 0) // use the version which sets things on symlinks
+ // use the version which sets things on symlinks
+ if(::lchown(Filename, ntohl(pattr->UID), ntohl(pattr->GID)) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to change owner of "
+ "symbolic link '" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
#endif
@@ -705,6 +741,8 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename,
// Try to apply
if(::utimes(Filename, times) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to change times of "
+ "file '" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
}
@@ -715,8 +753,12 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename,
}
// Apply everything else... (allowable mode flags only)
- if(::chmod(Filename, mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX)) != 0) // mode must be done last (think setuid)
+ // Mode must be done last (think setuid)
+ if(::chmod(Filename, mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID
+ | S_ISGID | S_ISVTX)) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to change permissions of file "
+ "'" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError)
}
}
@@ -831,6 +873,8 @@ void BackupClientFileAttributes::WriteExtendedAttr(const char *Filename, int xat
// FIXME: Warn on EOPNOTSUPP
if(::lsetxattr(Filename, key, buffer+xattrOffset, valueSize, 0)!=0 && errno!=EOPNOTSUPP)
{
+ BOX_LOG_SYS_ERROR("Failed to set extended attributes "
+ "on file '" << Filename << "'");
THROW_EXCEPTION(CommonException, OSFileError);
}
@@ -993,7 +1037,7 @@ void BackupClientFileAttributes::SetAttributeHashSecret(const void *pSecret, int
// Created: 25/4/04
//
// --------------------------------------------------------------------------
-uint64_t BackupClientFileAttributes::GenerateAttributeHash(struct stat &st, const std::string &filename, const std::string &leafname)
+uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_STRUCT_STAT &st, const std::string &filename, const std::string &leafname)
{
if(sAttributeHashSecretLength == 0)
{
diff --git a/lib/backupclient/BackupClientFileAttributes.h b/lib/backupclient/BackupClientFileAttributes.h
index fa56ff65..b32c14dd 100644
--- a/lib/backupclient/BackupClientFileAttributes.h
+++ b/lib/backupclient/BackupClientFileAttributes.h
@@ -15,7 +15,7 @@
#include "StreamableMemBlock.h"
#include "BoxTime.h"
-struct stat;
+EMU_STRUCT_STAT; // declaration
// --------------------------------------------------------------------------
//
@@ -53,11 +53,13 @@ public:
static void SetBlowfishKey(const void *pKey, int KeyLength);
static void SetAttributeHashSecret(const void *pSecret, int SecretLength);
- static uint64_t GenerateAttributeHash(struct stat &st, const std::string &filename, const std::string &leafname);
+ static uint64_t GenerateAttributeHash(EMU_STRUCT_STAT &st, const std::string &filename, const std::string &leafname);
static void FillExtendedAttr(StreamableMemBlock &outputBlock, const char *Filename);
private:
- static void FillAttributes(StreamableMemBlock &outputBlock, const char *Filename, struct stat &st, bool ZeroModificationTimes);
+ static void FillAttributes(StreamableMemBlock &outputBlock,
+ const char *Filename, EMU_STRUCT_STAT &st,
+ bool ZeroModificationTimes);
static void FillAttributesLink(StreamableMemBlock &outputBlock, const char *Filename, struct stat &st);
void WriteExtendedAttr(const char *Filename, int xattrOffset) const;
diff --git a/lib/backupclient/BackupClientRestore.cpp b/lib/backupclient/BackupClientRestore.cpp
index b5a54964..b1c5cd0f 100644
--- a/lib/backupclient/BackupClientRestore.cpp
+++ b/lib/backupclient/BackupClientRestore.cpp
@@ -193,6 +193,8 @@ typedef struct
{
bool PrintDots;
bool RestoreDeleted;
+ bool ContinueAfterErrors;
+ bool ContinuedAfterError;
std::string mRestoreResumeInfoFilename;
RestoreResumeInfo mResumeInfo;
} RestoreParams;
@@ -202,20 +204,26 @@ typedef struct
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupClientRestoreDir(BackupProtocolClient &, int64_t, const char *, bool)
+// Name: BackupClientRestoreDir(BackupProtocolClient &,
+// int64_t, const char *, bool)
// Purpose: Restore a directory
// Created: 23/11/03
//
// --------------------------------------------------------------------------
-static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t DirectoryID, std::string &rLocalDirectoryName,
+static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
+ int64_t DirectoryID, std::string &rLocalDirectoryName,
RestoreParams &Params, RestoreResumeInfo &rLevel)
{
- // If we're resuming... check that we haven't got a next level to look at
+ // If we're resuming... check that we haven't got a next level to
+ // look at
if(rLevel.mpNextLevel != 0)
{
// Recurse immediately
- std::string localDirname(rLocalDirectoryName + DIRECTORY_SEPARATOR_ASCHAR + rLevel.mNextLevelLocalName);
- BackupClientRestoreDir(rConnection, rLevel.mNextLevelID, localDirname, Params, *rLevel.mpNextLevel);
+ std::string localDirname(rLocalDirectoryName +
+ DIRECTORY_SEPARATOR_ASCHAR +
+ rLevel.mNextLevelLocalName);
+ BackupClientRestoreDir(rConnection, rLevel.mNextLevelID,
+ localDirname, Params, *rLevel.mpNextLevel);
// Add it to the list of done itmes
rLevel.mRestoredObjects.insert(rLevel.mNextLevelID);
@@ -259,22 +267,23 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
break;
case ObjectExists_File:
{
- // File exists with this name, which is fun. Get rid of it.
+ // File exists with this name, which is fun.
+ // Get rid of it.
BOX_WARNING("File present with name '" <<
- rLocalDirectoryName << "', removing " <<
+ rLocalDirectoryName << "', removing "
"out of the way of restored directory. "
"Use specific restore with ID to "
"restore this object.");
if(::unlink(rLocalDirectoryName.c_str()) != 0)
{
- BOX_ERROR("Failed to delete file " <<
- rLocalDirectoryName << ": " <<
- strerror(errno));
+ BOX_LOG_SYS_ERROR("Failed to delete "
+ "file '" <<
+ rLocalDirectoryName << "'");
return Restore_UnknownError;
}
BOX_TRACE("In restore, directory name "
- "collision with file " <<
- rLocalDirectoryName);
+ "collision with file '" <<
+ rLocalDirectoryName << "'");
}
break;
case ObjectExists_NoObject:
@@ -378,10 +387,17 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
exists == ObjectExists_File) &&
::mkdir(rLocalDirectoryName.c_str(), S_IRWXU) != 0)
{
- BOX_ERROR("Failed to create directory '" <<
- rLocalDirectoryName << "': " <<
- strerror(errno));
- return Restore_UnknownError;
+ BOX_LOG_SYS_ERROR("Failed to create directory '" <<
+ rLocalDirectoryName << "'");
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
// Save the restore info, in case it's needed later
@@ -394,23 +410,39 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
BOX_ERROR("Failed to save resume info file '" <<
Params.mRestoreResumeInfoFilename << "': " <<
e.what());
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
BOX_ERROR("Failed to save resume info file '" <<
Params.mRestoreResumeInfoFilename <<
"': unknown error");
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
// Fetch the directory listing from the server -- getting a
// list of files which is appropriate to the restore type
rConnection.QueryListDirectory(
- DirectoryID,
- Params.RestoreDeleted?(BackupProtocolClientListDirectory::Flags_Deleted):(BackupProtocolClientListDirectory::Flags_INCLUDE_EVERYTHING),
- BackupProtocolClientListDirectory::Flags_OldVersion | (Params.RestoreDeleted?(0):(BackupProtocolClientListDirectory::Flags_Deleted)),
- true /* want attributes */);
+ DirectoryID,
+ Params.RestoreDeleted?(BackupProtocolClientListDirectory::Flags_Deleted):(BackupProtocolClientListDirectory::Flags_INCLUDE_EVERYTHING),
+ BackupProtocolClientListDirectory::Flags_OldVersion | (Params.RestoreDeleted?(0):(BackupProtocolClientListDirectory::Flags_Deleted)),
+ true /* want attributes */);
// Retrieve the directory from the stream following
BackupStoreDirectory dir;
@@ -429,13 +461,29 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
{
BOX_ERROR("Failed to restore attributes for '" <<
rLocalDirectoryName << "': " << e.what());
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
BOX_ERROR("Failed to restore attributes for '" <<
rLocalDirectoryName << "': unknown error");
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
int64_t bytesWrittenSinceLastRestoreInfoSave = 0;
@@ -444,35 +492,51 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
{
BackupStoreDirectory::Iterator i(dir);
BackupStoreDirectory::Entry *en = 0;
- while((en = i.Next(BackupStoreDirectory::Entry::Flags_File)) != 0)
+ while((en = i.Next(BackupStoreDirectory::Entry::Flags_File))
+ != 0)
{
// Check ID hasn't already been done
- if(rLevel.mRestoredObjects.find(en->GetObjectID()) == rLevel.mRestoredObjects.end())
+ if(rLevel.mRestoredObjects.find(en->GetObjectID())
+ == rLevel.mRestoredObjects.end())
{
// Local name
BackupStoreFilenameClear nm(en->GetName());
- std::string localFilename(rLocalDirectoryName + DIRECTORY_SEPARATOR_ASCHAR + nm.GetClearFilename());
+ std::string localFilename(rLocalDirectoryName +
+ DIRECTORY_SEPARATOR_ASCHAR +
+ nm.GetClearFilename());
// Unlink anything which already exists:
// For resuming restores, we can't overwrite
// files already there.
- if(ObjectExists(localFilename) != ObjectExists_NoObject &&
+ if(ObjectExists(localFilename)
+ != ObjectExists_NoObject &&
::unlink(localFilename.c_str()) != 0)
{
- BOX_ERROR("Failed to delete file '" <<
- localFilename << "': " <<
- strerror(errno));
- return Restore_UnknownError;
+ BOX_LOG_SYS_ERROR("Failed to delete "
+ "file '" << localFilename <<
+ "'");
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
// Request it from the store
- rConnection.QueryGetFile(DirectoryID, en->GetObjectID());
+ rConnection.QueryGetFile(DirectoryID,
+ en->GetObjectID());
// Stream containing encoded file
- std::auto_ptr<IOStream> objectStream(rConnection.ReceiveStream());
+ std::auto_ptr<IOStream> objectStream(
+ rConnection.ReceiveStream());
- // Decode the file -- need to do different things depending on whether
- // the directory entry has additional attributes
+ // Decode the file -- need to do different
+ // things depending on whether the directory
+ // entry has additional attributes
try
{
if(en->HasAttributes())
@@ -493,14 +557,30 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
BOX_ERROR("Failed to restore file '" <<
localFilename << "': " <<
e.what());
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
BOX_ERROR("Failed to restore file '" <<
localFilename <<
"': unknown error");
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
// Progress display?
@@ -515,7 +595,7 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
// Save restore info?
int64_t fileSize;
- int exists;
+ bool exists = false;
try
{
@@ -531,7 +611,15 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
"whether file exists: '" <<
localFilename << "': " <<
e.what());
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
@@ -539,17 +627,27 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
"whether file exists: '" <<
localFilename << "': "
"unknown error");
- return Restore_UnknownError;
+
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
if(exists)
{
// File exists...
- bytesWrittenSinceLastRestoreInfoSave += fileSize;
+ bytesWrittenSinceLastRestoreInfoSave
+ += fileSize;
if(bytesWrittenSinceLastRestoreInfoSave > MAX_BYTES_WRITTEN_BETWEEN_RESTORE_INFO_SAVES)
{
- // Save the restore info, in case it's needed later
+ // Save the restore info, in
+ // case it's needed later
try
{
Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename);
@@ -590,14 +688,28 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
BOX_ERROR("Failed to save resume info file '" <<
Params.mRestoreResumeInfoFilename << "': " <<
e.what());
- return Restore_UnknownError;
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
BOX_ERROR("Failed to save resume info file '" <<
Params.mRestoreResumeInfoFilename <<
"': unknown error");
- return Restore_UnknownError;
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
bytesWrittenSinceLastRestoreInfoSave = 0;
@@ -608,17 +720,23 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
{
BackupStoreDirectory::Iterator i(dir);
BackupStoreDirectory::Entry *en = 0;
- while((en = i.Next(BackupStoreDirectory::Entry::Flags_Dir)) != 0)
+ while((en = i.Next(BackupStoreDirectory::Entry::Flags_Dir))
+ != 0)
{
// Check ID hasn't already been done
- if(rLevel.mRestoredObjects.find(en->GetObjectID()) == rLevel.mRestoredObjects.end())
+ if(rLevel.mRestoredObjects.find(en->GetObjectID())
+ == rLevel.mRestoredObjects.end())
{
// Local name
BackupStoreFilenameClear nm(en->GetName());
- std::string localDirname(rLocalDirectoryName + DIRECTORY_SEPARATOR_ASCHAR + nm.GetClearFilename());
+ std::string localDirname(rLocalDirectoryName
+ + DIRECTORY_SEPARATOR_ASCHAR
+ + nm.GetClearFilename());
// Add the level for the next entry
- RestoreResumeInfo &rnextLevel(rLevel.AddLevel(en->GetObjectID(), nm.GetClearFilename()));
+ RestoreResumeInfo &rnextLevel(
+ rLevel.AddLevel(en->GetObjectID(),
+ nm.GetClearFilename()));
// Recurse
int result = BackupClientRestoreDir(
@@ -648,13 +766,27 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
{
BOX_ERROR("Failed to restore attributes for '" <<
rLocalDirectoryName << "': " << e.what());
- return Restore_UnknownError;
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
catch(...)
{
BOX_ERROR("Failed to restore attributes for '" <<
rLocalDirectoryName << "': unknown error");
- return Restore_UnknownError;
+ if (Params.ContinueAfterErrors)
+ {
+ Params.ContinuedAfterError = true;
+ }
+ else
+ {
+ return Restore_UnknownError;
+ }
}
return Restore_Complete;
@@ -664,33 +796,45 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Dir
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupClientRestore(BackupProtocolClient &, int64_t, const char *, bool, bool)
-// Purpose: Restore a directory on the server to a local directory on the disc.
-//
-// The local directory must not already exist.
+// Name: BackupClientRestore(BackupProtocolClient &, int64_t,
+// const char *, bool, bool, bool, bool, bool)
+// Purpose: Restore a directory on the server to a local
+// directory on the disc. The local directory must not
+// already exist.
//
-// If a restore is aborted for any reason, then it may be resumed if
-// Resume == true. If Resume == false and resumption is possible, then
-// Restore_ResumePossible is returned.
+// If a restore is aborted for any reason, then it may
+// be resumed if Resume == true. If Resume == false
+// and resumption is possible, then
+// Restore_ResumePossible is returned.
//
-// Set RestoreDeleted to restore a deleted directory. This may not give the
-// directory structure when it was deleted, because files may have been deleted
-// within it before it was deleted.
+// Set RestoreDeleted to restore a deleted directory.
+// This may not give the directory structure when it
+// was deleted, because files may have been deleted
+// within it before it was deleted.
//
-// Returns Restore_TargetExists if the target directory exists, but
-// there is no restore possible. (Won't attempt to overwrite things.)
+// Returns Restore_TargetExists if the target
+// directory exists, but there is no restore possible.
+// (Won't attempt to overwrite things.)
//
-// Returns Restore_Complete on success. (Exceptions on error.)
+// Returns Restore_Complete on success. (Exceptions
+// on error, unless ContinueAfterError is true and
+// the error is recoverable, in which case it returns
+// Restore_CompleteWithErrors)
// Created: 23/11/03
//
// --------------------------------------------------------------------------
-int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID, const char *LocalDirectoryName,
- bool PrintDots, bool RestoreDeleted, bool UndeleteAfterRestoreDeleted, bool Resume)
+int BackupClientRestore(BackupProtocolClient &rConnection,
+ int64_t DirectoryID, const char *LocalDirectoryName,
+ bool PrintDots, bool RestoreDeleted,
+ bool UndeleteAfterRestoreDeleted, bool Resume,
+ bool ContinueAfterErrors)
{
// Parameter block
RestoreParams params;
params.PrintDots = PrintDots;
params.RestoreDeleted = RestoreDeleted;
+ params.ContinueAfterErrors = ContinueAfterErrors;
+ params.ContinuedAfterError = false;
params.mRestoreResumeInfoFilename = LocalDirectoryName;
params.mRestoreResumeInfoFilename += ".boxbackupresume";
@@ -699,12 +843,13 @@ int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID,
// Does any resumption information exist?
bool doingResume = false;
- if(FileExists(params.mRestoreResumeInfoFilename.c_str()) && targetExistance == ObjectExists_Dir)
+ if(FileExists(params.mRestoreResumeInfoFilename.c_str()) &&
+ targetExistance == ObjectExists_Dir)
{
if(!Resume)
{
- // Caller didn't specify that resume should be done, so refuse to do it
- // but say why.
+ // Caller didn't specify that resume should be done,
+ // so refuse to do it but say why.
return Restore_ResumePossible;
}
@@ -752,9 +897,7 @@ int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID,
// Delete the resume information file
::unlink(params.mRestoreResumeInfoFilename.c_str());
- return Restore_Complete;
+ return params.ContinuedAfterError ? Restore_CompleteWithErrors
+ : Restore_Complete;
}
-
-
-
diff --git a/lib/backupclient/BackupClientRestore.h b/lib/backupclient/BackupClientRestore.h
index f7724030..7e492238 100644
--- a/lib/backupclient/BackupClientRestore.h
+++ b/lib/backupclient/BackupClientRestore.h
@@ -15,14 +15,21 @@ class BackupProtocolClient;
enum
{
Restore_Complete = 0,
- Restore_ResumePossible = 1,
- Restore_TargetExists = 2,
- Restore_TargetPathNotFound = 3,
- Restore_UnknownError = 4,
+ Restore_ResumePossible,
+ Restore_TargetExists,
+ Restore_TargetPathNotFound,
+ Restore_UnknownError,
+ Restore_CompleteWithErrors,
};
-int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID, const char *LocalDirectoryName,
- bool PrintDots = false, bool RestoreDeleted = false, bool UndeleteAfterRestoreDeleted = false, bool Resume = false);
+int BackupClientRestore(BackupProtocolClient &rConnection,
+ int64_t DirectoryID,
+ const char *LocalDirectoryName,
+ bool PrintDots = false,
+ bool RestoreDeleted = false,
+ bool UndeleteAfterRestoreDeleted = false,
+ bool Resume = false,
+ bool ContinueAfterErrors = false);
#endif // BACKUPSCLIENTRESTORE__H
diff --git a/lib/backupclient/BackupDaemonConfigVerify.cpp b/lib/backupclient/BackupDaemonConfigVerify.cpp
index 61033b5b..e70ba865 100644
--- a/lib/backupclient/BackupDaemonConfigVerify.cpp
+++ b/lib/backupclient/BackupDaemonConfigVerify.cpp
@@ -17,15 +17,15 @@
static const ConfigurationVerifyKey backuplocationkeys[] =
{
- {"ExcludeFile", 0, ConfigTest_MultiValueAllowed, 0},
- {"ExcludeFilesRegex", 0, ConfigTest_MultiValueAllowed, 0},
- {"ExcludeDir", 0, ConfigTest_MultiValueAllowed, 0},
- {"ExcludeDirsRegex", 0, ConfigTest_MultiValueAllowed, 0},
- {"AlwaysIncludeFile", 0, ConfigTest_MultiValueAllowed, 0},
- {"AlwaysIncludeFilesRegex", 0, ConfigTest_MultiValueAllowed, 0},
- {"AlwaysIncludeDir", 0, ConfigTest_MultiValueAllowed, 0},
- {"AlwaysIncludeDirsRegex", 0, ConfigTest_MultiValueAllowed, 0},
- {"Path", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("ExcludeFile", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("ExcludeFilesRegex", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("ExcludeDir", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("ExcludeDirsRegex", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("AlwaysIncludeFile", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("AlwaysIncludeFilesRegex", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("AlwaysIncludeDir", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("AlwaysIncludeDirsRegex", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("Path", ConfigTest_Exists | ConfigTest_LastEntry)
};
static const ConfigurationVerify backuplocations[] =
@@ -64,39 +64,62 @@ static const ConfigurationVerify verifyserver[] =
static const ConfigurationVerifyKey verifyrootkeys[] =
{
- {"AccountNumber", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
-
- {"UpdateStoreInterval", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"MinimumFileAge", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"MaxUploadWait", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"MaxFileTimeInFuture", "172800", ConfigTest_IsInt, 0}, // file is uploaded if the file is this much in the future (2 days default)
-
- {"AutomaticBackup", "yes", ConfigTest_IsBool, 0},
+ ConfigurationVerifyKey("AccountNumber",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("UpdateStoreInterval",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("MinimumFileAge",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("MaxUploadWait",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("MaxFileTimeInFuture", ConfigTest_IsInt, 172800),
+ // file is uploaded if the file is this much in the future
+ // (2 days default)
+ ConfigurationVerifyKey("AutomaticBackup", ConfigTest_IsBool, true),
- {"SyncAllowScript", 0, 0, 0}, // optional script to run to see if the sync should be started now
- // return "now" if it's allowed, or a number of seconds if it's not
+ ConfigurationVerifyKey("SyncAllowScript", 0),
+ // script that returns "now" if backup is allowed now, or a number
+ // of seconds to wait before trying again if not
- {"MaximumDiffingTime", 0, ConfigTest_IsInt, 0},
- {"DeleteRedundantLocationsAfter", "172800", ConfigTest_IsInt, 0},
+ ConfigurationVerifyKey("MaximumDiffingTime", ConfigTest_IsInt),
+ ConfigurationVerifyKey("DeleteRedundantLocationsAfter",
+ ConfigTest_IsInt, 172800),
- {"FileTrackingSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"DiffingUploadSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"StoreHostname", 0, ConfigTest_Exists, 0},
- {"ExtendedLogging", "no", ConfigTest_IsBool, 0}, // extended log to syslog
- {"ExtendedLogFile", NULL, 0, 0}, // extended log to a file
- {"LogAllFileAccess", "no", ConfigTest_IsBool, 0},
+ ConfigurationVerifyKey("FileTrackingSizeThreshold",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("DiffingUploadSizeThreshold",
+ ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("StoreHostname", ConfigTest_Exists),
+ ConfigurationVerifyKey("StorePort", ConfigTest_IsInt,
+ BOX_PORT_BBSTORED),
+ ConfigurationVerifyKey("ExtendedLogging", ConfigTest_IsBool, false),
+ // extended log to syslog
+ ConfigurationVerifyKey("ExtendedLogFile", 0),
+ // extended log to a file
+ ConfigurationVerifyKey("LogAllFileAccess", ConfigTest_IsBool, false),
+ // enable logging reasons why each file is backed up or not
+ ConfigurationVerifyKey("LogFile", 0),
+ // enable logging to a file
+ ConfigurationVerifyKey("LogFileLevel", 0),
+ // set the level of verbosity of file logging
+ ConfigurationVerifyKey("CommandSocket", 0),
+ // not compulsory to have this
+ ConfigurationVerifyKey("KeepAliveTime", ConfigTest_IsInt),
+ ConfigurationVerifyKey("StoreObjectInfoFile", 0),
+ // optional
- {"CommandSocket", 0, 0, 0}, // not compulsory to have this
- {"KeepAliveTime", 0, ConfigTest_IsInt, 0}, // optional
- {"StoreObjectInfoFile", 0, 0, 0}, // optional
-
- {"NotifyScript", 0, 0, 0}, // optional script to run when backup needs attention, eg store full
+ ConfigurationVerifyKey("NotifyScript", 0),
+ // optional script to run when backup needs attention, eg store full
- {"CertificateFile", 0, ConfigTest_Exists, 0},
- {"PrivateKeyFile", 0, ConfigTest_Exists, 0},
- {"TrustedCAsFile", 0, ConfigTest_Exists, 0},
- {"KeysFile", 0, ConfigTest_Exists, 0},
- {"DataDirectory", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("NotifyAlways", ConfigTest_IsBool, false),
+ // option to disable the suppression of duplicate notifications
+
+ ConfigurationVerifyKey("CertificateFile", ConfigTest_Exists),
+ ConfigurationVerifyKey("PrivateKeyFile", ConfigTest_Exists),
+ ConfigurationVerifyKey("TrustedCAsFile", ConfigTest_Exists),
+ ConfigurationVerifyKey("KeysFile", ConfigTest_Exists),
+ ConfigurationVerifyKey("DataDirectory",
+ ConfigTest_Exists | ConfigTest_LastEntry),
};
const ConfigurationVerify BackupDaemonConfigVerify =
diff --git a/lib/backupclient/BackupStoreFile.cpp b/lib/backupclient/BackupStoreFile.cpp
index 7e93d59d..27e12bc8 100644
--- a/lib/backupclient/BackupStoreFile.cpp
+++ b/lib/backupclient/BackupStoreFile.cpp
@@ -65,22 +65,27 @@ BackupStoreFileStats BackupStoreFile::msStats = {0,0,0};
// Function
// Name: BackupStoreFile::EncodeFile(IOStream &, IOStream &)
// Purpose: Encode a file into something for storing on file server.
-// Requires a real filename so full info can be stored.
+// Requires a real filename so full info can be stored.
//
-// Returns a stream. Most of the work is done by the stream
-// when data is actually requested -- the file will be held
-// open until the stream is deleted or the file finished.
+// Returns a stream. Most of the work is done by the stream
+// when data is actually requested -- the file will be held
+// open until the stream is deleted or the file finished.
// Created: 2003/08/28
//
// --------------------------------------------------------------------------
-std::auto_ptr<IOStream> BackupStoreFile::EncodeFile(const char *Filename, int64_t ContainerID, const BackupStoreFilename &rStoreFilename, int64_t *pModificationTime)
+std::auto_ptr<IOStream> BackupStoreFile::EncodeFile(const char *Filename,
+ int64_t ContainerID, const BackupStoreFilename &rStoreFilename,
+ int64_t *pModificationTime, ReadLoggingStream::Logger* pLogger,
+ RunStatusProvider* pRunStatusProvider)
{
// Create the stream
std::auto_ptr<IOStream> stream(new BackupStoreFileEncodeStream);
// Do the initial setup
- ((BackupStoreFileEncodeStream*)stream.get())->Setup(Filename, 0 /* no recipe, just encode */,
- ContainerID, rStoreFilename, pModificationTime);
+ ((BackupStoreFileEncodeStream*)stream.get())->Setup(Filename,
+ 0 /* no recipe, just encode */,
+ ContainerID, rStoreFilename, pModificationTime, pLogger,
+ pRunStatusProvider);
// Return the stream for the caller
return stream;
@@ -267,8 +272,8 @@ bool BackupStoreFile::VerifyEncodedFileFormat(IOStream &rFile, int64_t *pDiffFro
void BackupStoreFile::DecodeFile(IOStream &rEncodedFile, const char *DecodedFilename, int Timeout, const BackupClientFileAttributes *pAlterativeAttr)
{
// Does file exist?
- struct stat st;
- if(::stat(DecodedFilename, &st) == 0)
+ EMU_STRUCT_STAT st;
+ if(EMU_STAT(DecodedFilename, &st) == 0)
{
THROW_EXCEPTION(BackupStoreException, OutputFileAlreadyExists)
}
@@ -1255,8 +1260,8 @@ bool BackupStoreFile::CompareFileContentsAgainstBlockIndex(const char *Filename,
// is it a symlink?
bool sourceIsSymlink = false;
{
- struct stat st;
- if(::lstat(Filename, &st) == -1)
+ EMU_STRUCT_STAT st;
+ if(EMU_LSTAT(Filename, &st) == -1)
{
THROW_EXCEPTION(CommonException, OSFileError)
}
diff --git a/lib/backupclient/BackupStoreFile.h b/lib/backupclient/BackupStoreFile.h
index 3ee5ddb0..f38cd821 100644
--- a/lib/backupclient/BackupStoreFile.h
+++ b/lib/backupclient/BackupStoreFile.h
@@ -10,11 +10,14 @@
#ifndef BACKUPSTOREFILE__H
#define BACKUPSTOREFILE__H
-#include "IOStream.h"
+#include <cstdlib>
+#include <memory>
+
#include "BackupClientFileAttributes.h"
#include "BackupStoreFilename.h"
-
-#include <memory>
+#include "IOStream.h"
+#include "ReadLoggingStream.h"
+#include "RunStatusProvider.h"
typedef struct
{
@@ -114,7 +117,11 @@ public:
// Main interface
- static std::auto_ptr<IOStream> EncodeFile(const char *Filename, int64_t ContainerID, const BackupStoreFilename &rStoreFilename, int64_t *pModificationTime = 0);
+ static std::auto_ptr<IOStream> EncodeFile(const char *Filename,
+ int64_t ContainerID, const BackupStoreFilename &rStoreFilename,
+ int64_t *pModificationTime = 0,
+ ReadLoggingStream::Logger* pLogger = NULL,
+ RunStatusProvider* pRunStatusProvider = NULL);
static std::auto_ptr<IOStream> EncodeFileDiff
(
const char *Filename, int64_t ContainerID,
@@ -207,7 +214,7 @@ public:
static BackupStoreFileStats msStats;
// For debug
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
static bool TraceDetailsOfDiffProcess;
#endif
diff --git a/lib/backupclient/BackupStoreFileDiff.cpp b/lib/backupclient/BackupStoreFileDiff.cpp
index f7842a0b..e9da1ee7 100644
--- a/lib/backupclient/BackupStoreFileDiff.cpp
+++ b/lib/backupclient/BackupStoreFileDiff.cpp
@@ -9,6 +9,8 @@
#include "Box.h"
+#include <string.h>
+
#include <new>
#include <map>
@@ -38,7 +40,7 @@ using namespace BackupStoreFileCreation;
// By default, don't trace out details of the diff as we go along -- would fill up logs significantly.
// But it's useful for the test.
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
bool BackupStoreFile::TraceDetailsOfDiffProcess = false;
#endif
@@ -128,8 +130,8 @@ std::auto_ptr<IOStream> BackupStoreFile::EncodeFileDiff
{
// Is it a symlink?
{
- struct stat st;
- if(::lstat(Filename, &st) != 0)
+ EMU_STRUCT_STAT st;
+ if(EMU_LSTAT(Filename, &st) != 0)
{
THROW_EXCEPTION(CommonException, OSFileError)
}
@@ -149,7 +151,7 @@ std::auto_ptr<IOStream> BackupStoreFile::EncodeFileDiff
int64_t blocksInIndex = 0;
bool canDiffFromThis = false;
LoadIndex(rDiffFromBlockIndex, DiffFromObjectID, &pindex, blocksInIndex, Timeout, canDiffFromThis);
- //TRACE1("Diff: Blocks in index: %lld\n", blocksInIndex);
+ // BOX_TRACE("Diff: Blocks in index: " << blocksInIndex);
if(!canDiffFromThis)
{
@@ -434,12 +436,14 @@ static void FindMostUsedSizes(BlocksAvailableEntry *pIndex, int64_t NumBlocks, i
}
// trace the size table in debug builds
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
if(BackupStoreFile::TraceDetailsOfDiffProcess)
{
for(int t = 0; t < BACKUP_FILE_DIFF_MAX_BLOCK_SIZES; ++t)
{
- TRACE3("Diff block size %d: %d (count = %lld)\n", t, Sizes[t], sizeCounts[t]);
+ BOX_TRACE("Diff block size " << t << ": " <<
+ Sizes[t] << " (count = " <<
+ sizeCounts[t] << ")");
}
}
#endif
@@ -459,11 +463,12 @@ static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t>
BlocksAvailableEntry *pIndex, int64_t NumBlocks,
int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES], DiffTimer *pDiffTimer)
{
- Timer maximumDiffingTime(0);
+ Timer maximumDiffingTime(0, "MaximumDiffingTime");
if(pDiffTimer && pDiffTimer->IsManaged())
{
- maximumDiffingTime = Timer(pDiffTimer->GetMaximumDiffingTime());
+ maximumDiffingTime = Timer(pDiffTimer->GetMaximumDiffingTime(),
+ "MaximumDiffingTime");
}
std::map<int64_t, int32_t> goodnessOfFit;
@@ -626,7 +631,7 @@ static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t>
// Block matched, roll the checksum forward to the next block without doing
// any more comparisons, because these are pointless (as any more matches will be ignored when
- // the receipe is generated) and just take up valuable processor time. Edge cases are
+ // the recipe is generated) and just take up valuable processor time. Edge cases are
// especially nasty, using huge amounts of time and memory.
int skip = Sizes[s];
if(offset < bytesInEndings && skip > 0)
@@ -723,7 +728,7 @@ static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t>
throw;
}
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
if(BackupStoreFile::TraceDetailsOfDiffProcess)
{
// Trace out the found blocks in debug mode
@@ -774,7 +779,7 @@ static void SetupHashTable(BlocksAvailableEntry *pIndex, int64_t NumBlocks, int3
// Already present in table?
if(pHashTable[hash] != 0)
{
- //TRACE1("Another hash entry for %d found\n", hash);
+ //BOX_TRACE("Another hash entry for " << hash << " found");
// Yes -- need to set the pointer in this entry to the current entry to build the linked list
pIndex[b].mpNextInHashList = pHashTable[hash];
}
@@ -805,7 +810,7 @@ static bool SecondStageMatch(BlocksAvailableEntry *pFirstInHashList, RollingChec
ASSERT(pFirstInHashList != 0);
ASSERT(pIndex != 0);
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
uint16_t DEBUG_Hash = fastSum.GetComponentForHashing();
#endif
uint32_t Checksum = fastSum.GetChecksum();
@@ -840,17 +845,19 @@ static bool SecondStageMatch(BlocksAvailableEntry *pFirstInHashList, RollingChec
// Then go through the entries in the hash list, comparing with the strong digest calculated
scan = pFirstInHashList;
- //TRACE0("second stage match\n");
+ //BOX_TRACE("second stage match");
while(scan != 0)
{
- //TRACE3("scan size %d, block size %d, hash %d\n", scan->mSize, BlockSize, Hash);
+ //BOX_TRACE("scan size " << scan->mSize <<
+ // ", block size " << BlockSize <<
+ // ", hash " << Hash);
ASSERT(scan->mSize == BlockSize);
ASSERT(RollingChecksum::ExtractHashingComponent(scan->mWeakChecksum) == DEBUG_Hash);
// Compare?
if(strong.DigestMatches(scan->mStrongChecksum))
{
- //TRACE0("Match!\n");
+ //BOX_TRACE("Match!\n");
// Found! Add to list of found blocks...
int64_t fileOffset = (FileBlockNumber * BlockSize) + Offset;
int64_t blockIndex = (scan - pIndex); // pointer arthmitic is frowned upon. But most efficient way of doing it here -- alternative is to use more memory
@@ -909,10 +916,11 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
instruction.mSpaceBefore = SizeOfInputFile;
rRecipe.push_back(instruction);
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
if(BackupStoreFile::TraceDetailsOfDiffProcess)
{
- TRACE1("Diff: Default recipe generated, %lld bytes of file\n", SizeOfInputFile);
+ BOX_TRACE("Diff: Default recipe generated, " <<
+ SizeOfInputFile << " bytes of file");
}
#endif
@@ -928,7 +936,7 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
ASSERT(i != rFoundBlocks.end()); // check logic
// Counting for debug tracing
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
int64_t debug_NewBytesFound = 0;
int64_t debug_OldBlocksUsed = 0;
#endif
@@ -955,7 +963,7 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
instruction.mSpaceBefore = i->first - loc;
// Move location forward to match
loc += instruction.mSpaceBefore;
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
debug_NewBytesFound += instruction.mSpaceBefore;
#endif
}
@@ -981,7 +989,7 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
instruction.mBlocks += 1;
}
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
debug_OldBlocksUsed++;
#endif
@@ -997,18 +1005,22 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
{
RESET_INSTRUCTION
instruction.mSpaceBefore = SizeOfInputFile - loc;
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
debug_NewBytesFound += instruction.mSpaceBefore;
#endif
rRecipe.push_back(instruction);
}
// dump out the recipe
-#ifndef NDEBUG
- TRACE2("Diff: %lld new bytes found, %lld old blocks used\n", debug_NewBytesFound, debug_OldBlocksUsed);
+#ifndef BOX_RELEASE_BUILD
+ BOX_TRACE("Diff: " <<
+ debug_NewBytesFound << " new bytes found, " <<
+ debug_OldBlocksUsed << " old blocks used");
if(BackupStoreFile::TraceDetailsOfDiffProcess)
{
- TRACE1("Diff: Recipe generated (size %d)\n======== ========= ========\nSpace b4 FirstBlk NumBlks\n", rRecipe.size());
+ BOX_TRACE("Diff: Recipe generated (size " << rRecipe.size());
+ BOX_TRACE("======== ========= ========");
+ BOX_TRACE("Space b4 FirstBlk NumBlks");
{
for(unsigned int e = 0; e < rRecipe.size(); ++e)
{
@@ -1018,10 +1030,15 @@ static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksA
#else
sprintf(b, "%8lld", (int64_t)(rRecipe[e].mpStartBlock - pIndex));
#endif
- TRACE3("%8lld %s %8lld\n", rRecipe[e].mSpaceBefore, (rRecipe[e].mpStartBlock == 0)?" -":b, (int64_t)rRecipe[e].mBlocks);
+ BOX_TRACE(std::setw(8) <<
+ rRecipe[e].mSpaceBefore <<
+ " " <<
+ ((rRecipe[e].mpStartBlock == 0)?" -":b) <<
+ " " << std::setw(8) <<
+ rRecipe[e].mBlocks);
}
}
- TRACE0("======== ========= ========\n");
+ BOX_TRACE("======== ========= ========");
}
#endif
}
diff --git a/lib/backupclient/BackupStoreFileEncodeStream.cpp b/lib/backupclient/BackupStoreFileEncodeStream.cpp
index 423c11a3..b2d44697 100644
--- a/lib/backupclient/BackupStoreFileEncodeStream.cpp
+++ b/lib/backupclient/BackupStoreFileEncodeStream.cpp
@@ -9,18 +9,20 @@
#include "Box.h"
-#include "BackupStoreFileEncodeStream.h"
+#include <string.h>
+
+#include "BackupClientFileAttributes.h"
+#include "BackupStoreConstants.h"
+#include "BackupStoreException.h"
#include "BackupStoreFile.h"
-#include "BackupStoreFileWire.h"
#include "BackupStoreFileCryptVar.h"
+#include "BackupStoreFileEncodeStream.h"
+#include "BackupStoreFileWire.h"
#include "BackupStoreObjectMagic.h"
-#include "BackupStoreException.h"
-#include "BackupStoreConstants.h"
#include "BoxTime.h"
-#include "BackupClientFileAttributes.h"
#include "FileStream.h"
-#include "RollingChecksum.h"
#include "Random.h"
+#include "RollingChecksum.h"
#include "MemLeakFindOn.h"
@@ -39,6 +41,7 @@ BackupStoreFileEncodeStream::BackupStoreFileEncodeStream()
: mpRecipe(0),
mpFile(0),
mpLogging(0),
+ mpRunStatusProvider(NULL),
mStatus(Status_Header),
mSendData(true),
mTotalBlocks(0),
@@ -105,8 +108,11 @@ BackupStoreFileEncodeStream::~BackupStoreFileEncodeStream()
// Created: 8/12/03
//
// --------------------------------------------------------------------------
-void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEncodeStream::Recipe *pRecipe,
- int64_t ContainerID, const BackupStoreFilename &rStoreFilename, int64_t *pModificationTime)
+void BackupStoreFileEncodeStream::Setup(const char *Filename,
+ BackupStoreFileEncodeStream::Recipe *pRecipe,
+ int64_t ContainerID, const BackupStoreFilename &rStoreFilename,
+ int64_t *pModificationTime, ReadLoggingStream::Logger* pLogger,
+ RunStatusProvider* pRunStatusProvider)
{
// Pointer to a blank recipe which we might create
BackupStoreFileEncodeStream::Recipe *pblankRecipe = 0;
@@ -126,9 +132,9 @@ void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEnc
pblankRecipe = new BackupStoreFileEncodeStream::Recipe(0, 0);
BackupStoreFileEncodeStream::RecipeInstruction instruction;
- instruction.mSpaceBefore = fileSize; // whole file
- instruction.mBlocks = 0; // no blocks
- instruction.mpStartBlock = 0; // no block
+ instruction.mSpaceBefore = fileSize; // whole file
+ instruction.mBlocks = 0; // no blocks
+ instruction.mpStartBlock = 0; // no block
pblankRecipe->push_back(instruction);
pRecipe = pblankRecipe;
@@ -208,8 +214,18 @@ void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEnc
// Open the file
mpFile = new FileStream(Filename);
- // Create logging stream
- mpLogging = new ReadLoggingStream(*mpFile);
+ if (pLogger)
+ {
+ // Create logging stream
+ mpLogging = new ReadLoggingStream(*mpFile,
+ *pLogger);
+ }
+ else
+ {
+ // re-use FileStream instead
+ mpLogging = mpFile;
+ mpFile = NULL;
+ }
// Work out the largest possible block required for the encoded data
mAllocatedBufferSize = BackupStoreFile::MaxBlockSizeForChunkSize(maxBlockClearSize);
@@ -220,7 +236,7 @@ void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEnc
{
throw std::bad_alloc();
}
-#ifndef NDEBUG
+#ifndef BOX_RELEASE_BUILD
// In debug builds, make sure that the reallocation code is exercised.
mEncodedBuffer.Allocate(mAllocatedBufferSize / 4);
#else
@@ -257,6 +273,8 @@ void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEnc
}
throw;
}
+
+ mpRunStatusProvider = pRunStatusProvider;
}
@@ -314,6 +332,11 @@ int BackupStoreFileEncodeStream::Read(void *pBuffer, int NBytes, int Timeout)
{
return 0;
}
+
+ if(mpRunStatusProvider && mpRunStatusProvider->StopRun())
+ {
+ THROW_EXCEPTION(BackupStoreException, SignalReceived);
+ }
int bytesToRead = NBytes;
uint8_t *buffer = (uint8_t*)pBuffer;
@@ -529,22 +552,25 @@ void BackupStoreFileEncodeStream::EncodeCurrentBlock()
ASSERT(blockRawSize < mAllocatedBufferSize);
// Check file open
- if(mpFile == 0 || mpLogging == 0)
+ if(mpLogging == 0)
{
// File should be open, but isn't. So logical error.
THROW_EXCEPTION(BackupStoreException, Internal)
}
// Read the data in
- if(!mpLogging->ReadFullBuffer(mpRawBuffer, blockRawSize, 0 /* not interested in size if failure */))
+ if(!mpLogging->ReadFullBuffer(mpRawBuffer, blockRawSize,
+ 0 /* not interested in size if failure */))
{
- // TODO: Do something more intelligent, and abort this upload because the file
- // has changed
- THROW_EXCEPTION(BackupStoreException, Temp_FileEncodeStreamDidntReadBuffer)
+ // TODO: Do something more intelligent, and abort
+ // this upload because the file has changed.
+ THROW_EXCEPTION(BackupStoreException,
+ Temp_FileEncodeStreamDidntReadBuffer)
}
// Encode it
- mCurrentBlockEncodedSize = BackupStoreFile::EncodeChunk(mpRawBuffer, blockRawSize, mEncodedBuffer);
+ mCurrentBlockEncodedSize = BackupStoreFile::EncodeChunk(mpRawBuffer,
+ blockRawSize, mEncodedBuffer);
//TRACE2("Encode: Encoded size of block %d is %d\n", (int32_t)mCurrentBlock, (int32_t)mCurrentBlockEncodedSize);
@@ -555,7 +581,8 @@ void BackupStoreFileEncodeStream::EncodeCurrentBlock()
strongChecksum.Finish();
// Add entry to the index
- StoreBlockIndexEntry(mCurrentBlockEncodedSize, blockRawSize, weakChecksum.GetChecksum(), strongChecksum.DigestAsData());
+ StoreBlockIndexEntry(mCurrentBlockEncodedSize, blockRawSize,
+ weakChecksum.GetChecksum(), strongChecksum.DigestAsData());
// Set vars to reading this block
mPositionInCurrentBlock = 0;
diff --git a/lib/backupclient/BackupStoreFileEncodeStream.h b/lib/backupclient/BackupStoreFileEncodeStream.h
index fb5d0851..c5fa780a 100644
--- a/lib/backupclient/BackupStoreFileEncodeStream.h
+++ b/lib/backupclient/BackupStoreFileEncodeStream.h
@@ -18,6 +18,7 @@
#include "MD5Digest.h"
#include "BackupStoreFile.h"
#include "ReadLoggingStream.h"
+#include "RunStatusProvider.h"
namespace BackupStoreFileCreation
{
@@ -74,7 +75,11 @@ public:
int64_t mOtherFileID;
};
- void Setup(const char *Filename, Recipe *pRecipe, int64_t ContainerID, const BackupStoreFilename &rStoreFilename, int64_t *pModificationTime);
+ void Setup(const char *Filename, Recipe *pRecipe, int64_t ContainerID,
+ const BackupStoreFilename &rStoreFilename,
+ int64_t *pModificationTime,
+ ReadLoggingStream::Logger* pLogger = NULL,
+ RunStatusProvider* pRunStatusProvider = NULL);
virtual int Read(void *pBuffer, int NBytes, int Timeout);
virtual void Write(const void *pBuffer, int NBytes);
@@ -101,7 +106,8 @@ private:
Recipe *mpRecipe;
IOStream *mpFile; // source file
CollectInBufferStream mData; // buffer for header and index entries
- ReadLoggingStream *mpLogging;
+ IOStream *mpLogging;
+ RunStatusProvider* mpRunStatusProvider;
int mStatus;
bool mSendData; // true if there's file data to send (ie not a symlink)
int64_t mTotalBlocks; // Total number of blocks in the file
diff --git a/lib/backupclient/BackupStoreFilename.cpp b/lib/backupclient/BackupStoreFilename.cpp
index fbfe3313..72cd1acd 100644
--- a/lib/backupclient/BackupStoreFilename.cpp
+++ b/lib/backupclient/BackupStoreFilename.cpp
@@ -37,7 +37,7 @@ BackupStoreFilename::BackupStoreFilename()
//
// --------------------------------------------------------------------------
BackupStoreFilename::BackupStoreFilename(const BackupStoreFilename &rToCopy)
- : BackupStoreFilename_base(rToCopy)
+ : mEncryptedName(rToCopy.mEncryptedName)
{
}
@@ -65,7 +65,7 @@ bool BackupStoreFilename::CheckValid(bool ExceptionIfInvalid) const
{
bool ok = true;
- if(size() < 2)
+ if(mEncryptedName.size() < 2)
{
// Isn't long enough to have a header
ok = false;
@@ -73,14 +73,14 @@ bool BackupStoreFilename::CheckValid(bool ExceptionIfInvalid) const
else
{
// Check size is consistent
- unsigned int dsize = BACKUPSTOREFILENAME_GET_SIZE(*this);
- if(dsize != size())
+ unsigned int dsize = BACKUPSTOREFILENAME_GET_SIZE(this->mEncryptedName);
+ if(dsize != mEncryptedName.size())
{
ok = false;
}
// And encoding is an accepted value
- unsigned int encoding = BACKUPSTOREFILENAME_GET_ENCODING(*this);
+ unsigned int encoding = BACKUPSTOREFILENAME_GET_ENCODING(this->mEncryptedName);
if(encoding < Encoding_Min || encoding > Encoding_Max)
{
ok = false;
@@ -119,8 +119,8 @@ void BackupStoreFilename::ReadFromProtocol(Protocol &rProtocol)
rProtocol.Read(data, dsize - 2);
// assign to this string, storing the header and the extra data
- assign(hdr, 2);
- append(data.c_str(), data.size());
+ mEncryptedName.assign(hdr, 2);
+ mEncryptedName.append(data.c_str(), data.size());
// Check it
CheckValid();
@@ -141,7 +141,7 @@ void BackupStoreFilename::WriteToProtocol(Protocol &rProtocol) const
{
CheckValid();
- rProtocol.Write(c_str(), size());
+ rProtocol.Write(mEncryptedName.c_str(), mEncryptedName.size());
}
// --------------------------------------------------------------------------
@@ -177,7 +177,7 @@ void BackupStoreFilename::ReadFromStream(IOStream &rStream, int Timeout)
buf[0] = hdr[0]; buf[1] = hdr[1];
// assign to this string, storing the header and the extra data
- assign(buf, dsize);
+ mEncryptedName.assign(buf, dsize);
}
else
{
@@ -194,7 +194,7 @@ void BackupStoreFilename::ReadFromStream(IOStream &rStream, int Timeout)
data[0] = hdr[0]; data[1] = hdr[1];
// assign to this string, storing the header and the extra data
- assign(data, dsize);
+ mEncryptedName.assign(data, dsize);
}
// Check it
@@ -216,7 +216,7 @@ void BackupStoreFilename::WriteToStream(IOStream &rStream) const
{
CheckValid();
- rStream.Write(c_str(), size());
+ rStream.Write(mEncryptedName.c_str(), mEncryptedName.size());
}
// --------------------------------------------------------------------------
@@ -242,7 +242,8 @@ void BackupStoreFilename::EncodedFilenameChanged()
// --------------------------------------------------------------------------
bool BackupStoreFilename::IsEncrypted() const
{
- return BACKUPSTOREFILENAME_GET_ENCODING(*this) != Encoding_Clear;
+ return BACKUPSTOREFILENAME_GET_ENCODING(this->mEncryptedName) !=
+ Encoding_Clear;
}
@@ -250,8 +251,9 @@ bool BackupStoreFilename::IsEncrypted() const
//
// Function
// Name: BackupStoreFilename::SetAsClearFilename(const char *)
-// Purpose: Sets this object to be a valid filename, but with a filename in the clear.
-// Used on the server to create filenames when there's no way of encrypting it.
+// Purpose: Sets this object to be a valid filename, but with a
+// filename in the clear. Used on the server to create
+// filenames when there's no way of encrypting it.
// Created: 22/4/04
//
// --------------------------------------------------------------------------
@@ -268,7 +270,7 @@ void BackupStoreFilename::SetAsClearFilename(const char *Clear)
ASSERT(encoded.size() == toEncode.size() + 2);
// Store the encoded string
- assign(encoded);
+ mEncryptedName.assign(encoded);
// Stuff which must be done
EncodedFilenameChanged();
diff --git a/lib/backupclient/BackupStoreFilename.h b/lib/backupclient/BackupStoreFilename.h
index a7b6c437..80db9516 100644
--- a/lib/backupclient/BackupStoreFilename.h
+++ b/lib/backupclient/BackupStoreFilename.h
@@ -40,8 +40,11 @@ class IOStream;
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
-class BackupStoreFilename : public BackupStoreFilename_base
+class BackupStoreFilename /* : public BackupStoreFilename_base */
{
+private:
+ std::string mEncryptedName;
+
public:
BackupStoreFilename();
BackupStoreFilename(const BackupStoreFilename &rToCopy);
@@ -71,8 +74,27 @@ public:
Encoding_Max = 2
};
+ const std::string& GetEncodedFilename() const
+ {
+ return mEncryptedName;
+ }
+
+ bool operator==(const BackupStoreFilename& rOther) const
+ {
+ return mEncryptedName == rOther.mEncryptedName;
+ }
+
+ bool operator!=(const BackupStoreFilename& rOther) const
+ {
+ return mEncryptedName != rOther.mEncryptedName;
+ }
+
protected:
virtual void EncodedFilenameChanged();
+ void SetEncodedFilename(const std::string &rEncoded)
+ {
+ mEncryptedName = rEncoded;
+ }
};
// On the wire utilities for class and derived class
diff --git a/lib/backupclient/BackupStoreFilenameClear.cpp b/lib/backupclient/BackupStoreFilenameClear.cpp
index 9114fdd1..e529d8d3 100644
--- a/lib/backupclient/BackupStoreFilenameClear.cpp
+++ b/lib/backupclient/BackupStoreFilenameClear.cpp
@@ -160,15 +160,17 @@ void BackupStoreFilenameClear::MakeClearAvailable() const
CheckValid();
// Decode the header
- int size = BACKUPSTOREFILENAME_GET_SIZE(*this);
- int encoding = BACKUPSTOREFILENAME_GET_ENCODING(*this);
+ int size = BACKUPSTOREFILENAME_GET_SIZE(GetEncodedFilename());
+ int encoding = BACKUPSTOREFILENAME_GET_ENCODING(GetEncodedFilename());
// Decode based on encoding given in the header
switch(encoding)
{
case Encoding_Clear:
- TRACE0("**** BackupStoreFilename encoded with Clear encoding ****\n");
- mClearFilename.assign(c_str() + 2, size - 2);
+ BOX_TRACE("**** BackupStoreFilename encoded with "
+ "Clear encoding ****");
+ mClearFilename.assign(GetEncodedFilename().c_str() + 2,
+ size - 2);
break;
case Encoding_Blowfish:
@@ -193,7 +195,8 @@ static void EnsureEncDecBufferSize(int BufSize)
if(spEncDecBuffer == 0)
{
#ifndef WIN32
- TRACE1("Allocating filename encoding/decoding buffer with size %d\n", BufSize);
+ BOX_TRACE("Allocating filename encoding/decoding buffer "
+ "with size " << BufSize);
#endif
spEncDecBuffer = new MemoryBlockGuard<uint8_t *>(BufSize);
MEMLEAKFINDER_NOT_A_LEAK(spEncDecBuffer);
@@ -242,7 +245,7 @@ void BackupStoreFilenameClear::EncryptClear(const std::string &rToEncode, Cipher
BACKUPSTOREFILENAME_MAKE_HDR(buffer, encSize, StoreAsEncoding);
// Store the encoded string
- assign((char*)buffer, encSize);
+ SetEncodedFilename(std::string((char*)buffer, encSize));
}
@@ -256,8 +259,10 @@ void BackupStoreFilenameClear::EncryptClear(const std::string &rToEncode, Cipher
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::DecryptEncoded(CipherContext &rCipherContext) const
{
+ const std::string& rEncoded = GetEncodedFilename();
+
// Work out max size
- int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(size()) + 4;
+ int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(rEncoded.size()) + 4;
// Make sure encode/decode buffer has enough space
EnsureEncDecBufferSize(maxOutSize);
@@ -266,8 +271,8 @@ void BackupStoreFilenameClear::DecryptEncoded(CipherContext &rCipherContext) con
uint8_t *buffer = *spEncDecBuffer;
// Decrypt
- const char *str = c_str() + 2;
- int sizeOut = rCipherContext.TransformBlock(buffer, sEncDecBufferSize, str, size() - 2);
+ const char *str = rEncoded.c_str() + 2;
+ int sizeOut = rCipherContext.TransformBlock(buffer, sEncDecBufferSize, str, rEncoded.size() - 2);
// Assign to this
mClearFilename.assign((char*)buffer, sizeOut);
diff --git a/lib/backupclient/BackupStoreObjectDump.cpp b/lib/backupclient/BackupStoreObjectDump.cpp
index d3d9cc17..654317c1 100644
--- a/lib/backupclient/BackupStoreObjectDump.cpp
+++ b/lib/backupclient/BackupStoreObjectDump.cpp
@@ -47,7 +47,7 @@ static void OutputLine(FILE *file, bool ToTrace, const char *format, ...)
}
if(ToTrace)
{
- TRACE1("%s", text);
+ BOX_TRACE(text);
}
}
@@ -70,7 +70,7 @@ void BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace)
mAttributesModTime, mAttributes.GetSize());
// So repeated filenames can be illustrated, even though they can't be decoded
- std::map<BackupStoreFilename, int> nameNum;
+ std::map<std::string, int> nameNum;
int nameNumI = 0;
// Dump items
@@ -78,7 +78,7 @@ void BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace)
for(std::vector<Entry*>::const_iterator i(mEntries.begin()); i != mEntries.end(); ++i)
{
// Choose file name index number for this file
- std::map<BackupStoreFilename, int>::iterator nn(nameNum.find((*i)->GetName()));
+ std::map<std::string, int>::iterator nn(nameNum.find((*i)->GetName().GetEncodedFilename()));
int ni = nameNumI;
if(nn != nameNum.end())
{
@@ -86,7 +86,7 @@ void BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace)
}
else
{
- nameNum[(*i)->GetName()] = nameNumI;
+ nameNum[(*i)->GetName().GetEncodedFilename()] = nameNumI;
++nameNumI;
}
@@ -124,7 +124,7 @@ void BackupStoreDirectory::Dump(void *clibFileHandle, bool ToTrace)
(*i)->GetSizeInBlocks(),
(*i)->GetAttributesHash(),
(*i)->GetAttributes().GetSize(),
- (*i)->GetName().size(),
+ (*i)->GetName().GetEncodedFilename().size(),
ni,
((f & BackupStoreDirectory::Entry::Flags_File)?" file":""),
((f & BackupStoreDirectory::Entry::Flags_Dir)?" dir":""),
@@ -173,7 +173,8 @@ void BackupStoreFile::DumpFile(void *clibFileHandle, bool ToTrace, IOStream &rFi
// Read the next two objects
BackupStoreFilename fn;
fn.ReadFromStream(rFile, IOStream::TimeOutInfinite);
- OutputLine(file, ToTrace, "Filename size: %d\n", fn.size());
+ OutputLine(file, ToTrace, "Filename size: %d\n",
+ fn.GetEncodedFilename().size());
BackupClientFileAttributes attr;
attr.ReadFromStream(rFile, IOStream::TimeOutInfinite);
@@ -211,14 +212,16 @@ void BackupStoreFile::DumpFile(void *clibFileHandle, bool ToTrace, IOStream &rFi
if(s > 0)
{
nnew++;
- TRACE2("%8lld this s=%8lld\n", b, s);
+ BOX_TRACE(std::setw(8) << b << " this s=" <<
+ std::setw(8) << s);
}
else
{
nold++;
- TRACE2("%8lld other i=%8lld\n", b, 0 - s);
+ BOX_TRACE(std::setw(8) << b << " other i=" <<
+ std::setw(8) << 0 - s);
}
}
- TRACE0("======== ===== ==========\n");
+ BOX_TRACE("======== ===== ==========");
}
diff --git a/lib/backupclient/RunStatusProvider.h b/lib/backupclient/RunStatusProvider.h
new file mode 100644
index 00000000..89f361ca
--- /dev/null
+++ b/lib/backupclient/RunStatusProvider.h
@@ -0,0 +1,29 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: RunStatusProvider.h
+// Purpose: Declares the RunStatusProvider interface.
+// Created: 2008/08/14
+//
+// --------------------------------------------------------------------------
+
+#ifndef RUNSTATUSPROVIDER__H
+#define RUNSTATUSPROVIDER__H
+
+// --------------------------------------------------------------------------
+//
+// Class
+// Name: RunStatusProvider
+// Purpose: Provides a StopRun() method which returns true if
+// the current backup should be halted.
+// Created: 2005/11/15
+//
+// --------------------------------------------------------------------------
+class RunStatusProvider
+{
+ public:
+ virtual ~RunStatusProvider() { }
+ virtual bool StopRun() = 0;
+};
+
+#endif // RUNSTATUSPROVIDER__H