summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/bbackupd/BackupClientDirectoryRecord.cpp347
-rw-r--r--bin/bbackupd/BackupClientDirectoryRecord.h42
-rw-r--r--bin/bbackupd/BackupDaemon.cpp218
-rw-r--r--bin/bbackupd/BackupDaemon.h26
-rw-r--r--lib/win32/emu.cpp48
-rw-r--r--lib/win32/emu.h38
6 files changed, 396 insertions, 323 deletions
diff --git a/bin/bbackupd/BackupClientDirectoryRecord.cpp b/bin/bbackupd/BackupClientDirectoryRecord.cpp
index 3f95be47..ef17a23b 100644
--- a/bin/bbackupd/BackupClientDirectoryRecord.cpp
+++ b/bin/bbackupd/BackupClientDirectoryRecord.cpp
@@ -18,6 +18,7 @@
#include <string.h>
#include "autogen_BackupProtocol.h"
+#include "autogen_ClientException.h"
#include "Archive.h"
#include "BackupClientContext.h"
#include "BackupClientDirectoryRecord.h"
@@ -101,6 +102,23 @@ void BackupClientDirectoryRecord::DeleteSubDirectories()
mSubDirectories.clear();
}
+std::string BackupClientDirectoryRecord::ConvertVssPathToRealPath(
+ const std::string &rVssPath,
+ const Location& rBackupLocation)
+{
+#ifdef ENABLE_VSS
+ if (rBackupLocation.mIsSnapshotCreated &&
+ rVssPath.substr(0, rBackupLocation.mSnapshotPath.length()) ==
+ rBackupLocation.mSnapshotPath)
+ {
+ return rBackupLocation.mPath +
+ rVssPath.substr(rBackupLocation.mSnapshotPath.length());
+ }
+#endif
+
+ return rVssPath;
+}
+
// --------------------------------------------------------------------------
//
// Function
@@ -118,6 +136,7 @@ void BackupClientDirectoryRecord::SyncDirectory(
int64_t ContainingDirectoryID,
const std::string &rLocalPath,
const std::string &rRemotePath,
+ const Location& rBackupLocation,
bool ThisDirHasJustBeenCreated)
{
BackupClientContext& rContext(rParams.mrContext);
@@ -163,7 +182,8 @@ void BackupClientDirectoryRecord::SyncDirectory(
// just ignore this error. In a future scan, this
// deletion will be noticed, deleted from server,
// and this object deleted.
- rNotifier.NotifyDirStatFailed(this, rLocalPath,
+ rNotifier.NotifyDirStatFailed(this,
+ ConvertVssPathToRealPath(rLocalPath, rBackupLocation),
strerror(errno));
return;
}
@@ -212,12 +232,12 @@ void BackupClientDirectoryRecord::SyncDirectory(
{
// Report the error (logs and
// eventual email to administrator)
- rNotifier.NotifyFileStatFailed(this, rLocalPath,
+ rNotifier.NotifyFileStatFailed(this,
+ ConvertVssPathToRealPath(rLocalPath, rBackupLocation),
strerror(errno));
// FIXME move to NotifyFileStatFailed()
- SetErrorWhenReadingFilesystemObject(rParams,
- rLocalPath.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, rLocalPath);
// This shouldn't happen, so we'd better not continue
THROW_EXCEPTION(CommonException, OSFileError)
@@ -229,7 +249,8 @@ void BackupClientDirectoryRecord::SyncDirectory(
DIR *dirHandle = 0;
try
{
- rNotifier.NotifyScanDirectory(this, rLocalPath);
+ rNotifier.NotifyScanDirectory(this,
+ ConvertVssPathToRealPath(rLocalPath, rBackupLocation));
dirHandle = ::opendir(rLocalPath.c_str());
if(dirHandle == 0)
@@ -239,18 +260,19 @@ void BackupClientDirectoryRecord::SyncDirectory(
if (errno == EACCES)
{
rNotifier.NotifyDirListFailed(this,
- rLocalPath, "Access denied");
+ ConvertVssPathToRealPath(rLocalPath, rBackupLocation),
+ "Access denied");
}
else
{
rNotifier.NotifyDirListFailed(this,
- rLocalPath, strerror(errno));
+ ConvertVssPathToRealPath(rLocalPath, rBackupLocation),
+ strerror(errno));
}
// Report the error (logs and eventual email
// to administrator)
- SetErrorWhenReadingFilesystemObject(rParams,
- rLocalPath.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, rLocalPath);
// Ignore this directory for now.
return;
}
@@ -297,9 +319,19 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Our emulated readdir() abuses en->d_type,
// which would normally contain DT_REG,
// DT_DIR, etc, but we only use it here and
- // prefer S_IFREG, S_IFDIR...
- int type = en->d_type;
- #else
+ // prefer to have the full file attributes.
+ int type;
+ if (en->d_type & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ type = S_IFDIR;
+ }
+ else
+ {
+ type = S_IFREG;
+ }
+
+ #else // !WIN32
+
if(EMU_LSTAT(filename.c_str(), &file_st) != 0)
{
if(!(rParams.mrContext.ExcludeDir(
@@ -314,8 +346,7 @@ void BackupClientDirectoryRecord::SyncDirectory(
// FIXME move to
// NotifyFileStatFailed()
- SetErrorWhenReadingFilesystemObject(
- rParams, filename.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, filename);
}
// Ignore this entry for now.
@@ -347,8 +378,7 @@ void BackupClientDirectoryRecord::SyncDirectory(
" (suppressing further warnings)");
mSuppressMultipleLinksWarning = true;
}
- SetErrorWhenReadingFilesystemObject(
- rParams, filename.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, filename);
}
BOX_TRACE("Stat entry '" << filename << "' "
@@ -380,9 +410,8 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Exclude it?
if(rParams.mrContext.ExcludeFile(filename))
{
- rNotifier.NotifyFileExcluded(
- this,
- filename);
+ rNotifier.NotifyFileExcluded(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
// Next item!
continue;
@@ -398,14 +427,26 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Exclude it?
if(rParams.mrContext.ExcludeDir(filename))
{
- rNotifier.NotifyDirExcluded(
- this,
- filename);
+ rNotifier.NotifyDirExcluded(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
// Next item!
continue;
}
+ #ifdef WIN32
+ // exclude reparse points, as Application Data points to the
+ // parent directory under Vista and later, and causes an
+ // infinite loop:
+ // http://social.msdn.microsoft.com/forums/en-US/windowscompatibility/thread/05d14368-25dd-41c8-bdba-5590bf762a68/
+ if (en->d_type & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ rNotifier.NotifyMountPointSkipped(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
+ continue;
+ }
+ #endif
+
// Store on list
dirs.push_back(std::string(en->d_name));
}
@@ -422,16 +463,15 @@ void BackupClientDirectoryRecord::SyncDirectory(
}
else if(rParams.mrContext.ExcludeFile(filename))
{
- rNotifier.NotifyFileExcluded(
- this,
- filename);
+ rNotifier.NotifyFileExcluded(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
}
else
{
- rNotifier.NotifyUnsupportedFileType(
- this, filename);
- SetErrorWhenReadingFilesystemObject(
- rParams, filename.c_str());
+ rNotifier.NotifyUnsupportedFileType(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
+ SetErrorWhenReadingFilesystemObject(rParams,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
}
continue;
@@ -446,13 +486,12 @@ void BackupClientDirectoryRecord::SyncDirectory(
if(emu_stat(filename.c_str(), &file_st) != 0)
{
rNotifier.NotifyFileStatFailed(this,
- filename,
+ ConvertVssPathToRealPath(filename, rBackupLocation),
strerror(errno));
// Report the error (logs and
// eventual email to administrator)
- SetErrorWhenReadingFilesystemObject(
- rParams, filename.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, filename);
// Ignore this entry for now.
continue;
@@ -461,7 +500,7 @@ void BackupClientDirectoryRecord::SyncDirectory(
if(file_st.st_dev != link_st.st_dev)
{
rNotifier.NotifyMountPointSkipped(this,
- filename);
+ ConvertVssPathToRealPath(filename, rBackupLocation));
continue;
}
#endif
@@ -481,8 +520,8 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Log that this has happened
if(!rParams.mHaveLoggedWarningAboutFutureFileTimes)
{
- rNotifier.NotifyFileModifiedInFuture(
- this, filename);
+ rNotifier.NotifyFileModifiedInFuture(this,
+ ConvertVssPathToRealPath(filename, rBackupLocation));
rParams.mHaveLoggedWarningAboutFutureFileTimes = true;
}
}
@@ -556,7 +595,7 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Do the directory reading
bool updateCompleteSuccess = UpdateItems(rParams, rLocalPath,
- rRemotePath, pdirOnStore, entriesLeftOver, files, dirs);
+ rRemotePath, rBackupLocation, pdirOnStore, entriesLeftOver, files, dirs);
// LAST THING! (think exception safety)
// Store the new checksum -- don't fetch things unnecessarily in the future
@@ -699,6 +738,7 @@ bool BackupClientDirectoryRecord::UpdateItems(
BackupClientDirectoryRecord::SyncParams &rParams,
const std::string &rLocalPath,
const std::string &rRemotePath,
+ const Location& rBackupLocation,
BackupStoreDirectory *pDirOnStore,
std::vector<BackupStoreDirectory::Entry *> &rEntriesLeftOver,
std::vector<std::string> &rFiles,
@@ -754,8 +794,7 @@ bool BackupClientDirectoryRecord::UpdateItems(
// Report the error (logs and
// eventual email to administrator)
- SetErrorWhenReadingFilesystemObject(rParams,
- filename.c_str());
+ SetErrorWhenReadingFilesystemObject(rParams, filename);
// Ignore this entry for now.
continue;
@@ -1060,9 +1099,8 @@ bool BackupClientDirectoryRecord::UpdateItems(
// code false, to show error in directory
allUpdatedSuccessfully = false;
// Log it.
- SetErrorWhenReadingFilesystemObject(rParams, filename.c_str());
- rNotifier.NotifyFileUploadException(
- this, filename, e);
+ SetErrorWhenReadingFilesystemObject(rParams, filename);
+ rNotifier.NotifyFileUploadException(this, filename, e);
}
// Update structures if the file was uploaded
@@ -1081,7 +1119,7 @@ bool BackupClientDirectoryRecord::UpdateItems(
else
{
rNotifier.NotifyFileSkippedServerFull(this,
- filename);
+ ConvertVssPathToRealPath(filename, rBackupLocation));
}
}
else if(en != 0 && en->GetAttributesHash() != attributesHash)
@@ -1420,8 +1458,8 @@ bool BackupClientDirectoryRecord::UpdateItems(
if(psubDirRecord)
{
// Sync this sub directory too
- psubDirRecord->SyncDirectory(rParams, mObjectID,
- dirname, rRemotePath + "/" + *d,
+ psubDirRecord->SyncDirectory(rParams, mObjectID, dirname,
+ rRemotePath + "/" + *d, rBackupLocation,
haveJustCreatedDirOnServer);
}
@@ -1731,7 +1769,9 @@ int64_t BackupClientDirectoryRecord::UploadFile(
// Created: 29/3/04
//
// --------------------------------------------------------------------------
-void BackupClientDirectoryRecord::SetErrorWhenReadingFilesystemObject(BackupClientDirectoryRecord::SyncParams &rParams, const char *Filename)
+void BackupClientDirectoryRecord::SetErrorWhenReadingFilesystemObject(
+ BackupClientDirectoryRecord::SyncParams &rParams,
+ const std::string& rFilename)
{
// Zero hash, so it gets synced properly next time round.
::memset(mStateChecksum, 0, sizeof(mStateChecksum));
@@ -1965,3 +2005,220 @@ void BackupClientDirectoryRecord::Serialize(Archive & rArchive) const
pSubItem->Serialize(rArchive);
}
}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: Location::Location()
+// Purpose: Constructor
+// Created: 11/11/03
+//
+// --------------------------------------------------------------------------
+Location::Location()
+ : mIDMapIndex(0),
+ mpExcludeFiles(0),
+ mpExcludeDirs(0)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: Location::~Location()
+// Purpose: Destructor
+// Created: 11/11/03
+//
+// --------------------------------------------------------------------------
+Location::~Location()
+{
+ // Clean up exclude locations
+ if(mpExcludeDirs != 0)
+ {
+ delete mpExcludeDirs;
+ mpExcludeDirs = 0;
+ }
+ if(mpExcludeFiles != 0)
+ {
+ delete mpExcludeFiles;
+ mpExcludeFiles = 0;
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: Location::Serialize(Archive & rArchive)
+// Purpose: Serializes this object instance into a stream of bytes,
+// using an Archive abstraction.
+//
+// Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void Location::Serialize(Archive & rArchive) const
+{
+ //
+ //
+ //
+ rArchive.Write(mName);
+ rArchive.Write(mPath);
+ rArchive.Write(mIDMapIndex);
+
+ //
+ //
+ //
+ if(mpDirectoryRecord.get() == NULL)
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
+ rArchive.Write(aMagicMarker);
+ }
+ else
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
+ rArchive.Write(aMagicMarker);
+
+ mpDirectoryRecord->Serialize(rArchive);
+ }
+
+ //
+ //
+ //
+ if(!mpExcludeFiles)
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
+ rArchive.Write(aMagicMarker);
+ }
+ else
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
+ rArchive.Write(aMagicMarker);
+
+ mpExcludeFiles->Serialize(rArchive);
+ }
+
+ //
+ //
+ //
+ if(!mpExcludeDirs)
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
+ rArchive.Write(aMagicMarker);
+ }
+ else
+ {
+ int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
+ rArchive.Write(aMagicMarker);
+
+ mpExcludeDirs->Serialize(rArchive);
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: Location::Deserialize(Archive & rArchive)
+// Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction.
+//
+// Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void Location::Deserialize(Archive &rArchive)
+{
+ //
+ //
+ //
+ mpDirectoryRecord.reset(NULL);
+ if(mpExcludeFiles)
+ {
+ delete mpExcludeFiles;
+ mpExcludeFiles = NULL;
+ }
+ if(mpExcludeDirs)
+ {
+ delete mpExcludeDirs;
+ mpExcludeDirs = NULL;
+ }
+
+ //
+ //
+ //
+ rArchive.Read(mName);
+ rArchive.Read(mPath);
+ rArchive.Read(mIDMapIndex);
+
+ //
+ //
+ //
+ int64_t aMagicMarker = 0;
+ rArchive.Read(aMagicMarker);
+
+ if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
+ {
+ // NOOP
+ }
+ else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
+ {
+ BackupClientDirectoryRecord *pSubRecord = new BackupClientDirectoryRecord(0, "");
+ if(!pSubRecord)
+ {
+ throw std::bad_alloc();
+ }
+
+ mpDirectoryRecord.reset(pSubRecord);
+ mpDirectoryRecord->Deserialize(rArchive);
+ }
+ else
+ {
+ // there is something going on here
+ THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
+ }
+
+ //
+ //
+ //
+ rArchive.Read(aMagicMarker);
+
+ if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
+ {
+ // NOOP
+ }
+ else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
+ {
+ mpExcludeFiles = new ExcludeList;
+ if(!mpExcludeFiles)
+ {
+ throw std::bad_alloc();
+ }
+
+ mpExcludeFiles->Deserialize(rArchive);
+ }
+ else
+ {
+ // there is something going on here
+ THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
+ }
+
+ //
+ //
+ //
+ rArchive.Read(aMagicMarker);
+
+ if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
+ {
+ // NOOP
+ }
+ else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
+ {
+ mpExcludeDirs = new ExcludeList;
+ if(!mpExcludeDirs)
+ {
+ throw std::bad_alloc();
+ }
+
+ mpExcludeDirs->Deserialize(rArchive);
+ }
+ else
+ {
+ // there is something going on here
+ THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
+ }
+}
diff --git a/bin/bbackupd/BackupClientDirectoryRecord.h b/bin/bbackupd/BackupClientDirectoryRecord.h
index d9291520..81c10680 100644
--- a/bin/bbackupd/BackupClientDirectoryRecord.h
+++ b/bin/bbackupd/BackupClientDirectoryRecord.h
@@ -21,9 +21,18 @@
#include "ReadLoggingStream.h"
#include "RunStatusProvider.h"
+#ifdef ENABLE_VSS
+# include <comdef.h>
+# include <Vss.h>
+# include <VsWriter.h>
+# include <VsBackup.h>
+#endif
+
class Archive;
class BackupClientContext;
class BackupDaemon;
+class ExcludeList;
+class Location;
// --------------------------------------------------------------------------
//
@@ -125,8 +134,12 @@ public:
int64_t ContainingDirectoryID,
const std::string &rLocalPath,
const std::string &rRemotePath,
+ const Location& rBackupLocation,
bool ThisDirHasJustBeenCreated = false);
+ std::string ConvertVssPathToRealPath(const std::string &rVssPath,
+ const Location& rBackupLocation);
+
private:
void DeleteSubDirectories();
BackupStoreDirectory *FetchDirectoryListing(SyncParams &rParams);
@@ -135,6 +148,7 @@ private:
const std::string &rLocalPath);
bool UpdateItems(SyncParams &rParams, const std::string &rLocalPath,
const std::string &rRemotePath,
+ const Location& rBackupLocation,
BackupStoreDirectory *pDirOnStore,
std::vector<BackupStoreDirectory::Entry *> &rEntriesLeftOver,
std::vector<std::string> &rFiles,
@@ -145,7 +159,7 @@ private:
int64_t FileSize, box_time_t ModificationTime,
box_time_t AttributesHash, bool NoPreviousVersionOnServer);
void SetErrorWhenReadingFilesystemObject(SyncParams &rParams,
- const char *Filename);
+ const std::string& rFilename);
void RemoveDirectoryInPlaceOfFile(SyncParams &rParams,
BackupStoreDirectory* pDirOnStore,
BackupStoreDirectory::Entry* pEntry,
@@ -168,6 +182,32 @@ private:
// waste a lot of memory because of STL allocation policies.
};
+class Location
+{
+public:
+ Location();
+ ~Location();
+
+ void Deserialize(Archive & rArchive);
+ void Serialize(Archive & rArchive) const;
+private:
+ Location(const Location &); // copy not allowed
+ Location &operator=(const Location &);
+public:
+ std::string mName;
+ std::string mPath;
+ std::auto_ptr<BackupClientDirectoryRecord> mpDirectoryRecord;
+ int mIDMapIndex;
+ ExcludeList *mpExcludeFiles;
+ ExcludeList *mpExcludeDirs;
+
+#ifdef ENABLE_VSS
+ bool mIsSnapshotCreated;
+ VSS_ID mSnapshotVolumeId;
+ std::string mSnapshotPath;
+#endif
+};
+
#endif // BACKUPCLIENTDIRECTORYRECORD__H
diff --git a/bin/bbackupd/BackupDaemon.cpp b/bin/bbackupd/BackupDaemon.cpp
index 507ac377..0c2f6b97 100644
--- a/bin/bbackupd/BackupDaemon.cpp
+++ b/bin/bbackupd/BackupDaemon.cpp
@@ -1014,7 +1014,7 @@ void BackupDaemon::RunSyncNow()
(*i)->mpDirectoryRecord->SyncDirectory(params,
BackupProtocolListDirectory::RootDirectory,
- locationPath, std::string("/") + (*i)->mName);
+ locationPath, std::string("/") + (*i)->mName, **i);
// Unset exclude lists (just in case)
clientContext.SetExcludeLists(0, 0);
@@ -2947,222 +2947,6 @@ typedef struct
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupDaemon::Location::Location()
-// Purpose: Constructor
-// Created: 11/11/03
-//
-// --------------------------------------------------------------------------
-BackupDaemon::Location::Location()
- : mIDMapIndex(0),
- mpExcludeFiles(0),
- mpExcludeDirs(0)
-{
-}
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: BackupDaemon::Location::~Location()
-// Purpose: Destructor
-// Created: 11/11/03
-//
-// --------------------------------------------------------------------------
-BackupDaemon::Location::~Location()
-{
- // Clean up exclude locations
- if(mpExcludeDirs != 0)
- {
- delete mpExcludeDirs;
- mpExcludeDirs = 0;
- }
- if(mpExcludeFiles != 0)
- {
- delete mpExcludeFiles;
- mpExcludeFiles = 0;
- }
-}
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: BackupDaemon::Location::Deserialize(Archive & rArchive)
-// Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction.
-//
-// Created: 2005/04/11
-//
-// --------------------------------------------------------------------------
-void BackupDaemon::Location::Deserialize(Archive &rArchive)
-{
- //
- //
- //
- mpDirectoryRecord.reset(NULL);
- if(mpExcludeFiles)
- {
- delete mpExcludeFiles;
- mpExcludeFiles = NULL;
- }
- if(mpExcludeDirs)
- {
- delete mpExcludeDirs;
- mpExcludeDirs = NULL;
- }
-
- //
- //
- //
- rArchive.Read(mName);
- rArchive.Read(mPath);
- rArchive.Read(mIDMapIndex);
-
- //
- //
- //
- int64_t aMagicMarker = 0;
- rArchive.Read(aMagicMarker);
-
- if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
- {
- // NOOP
- }
- else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
- {
- BackupClientDirectoryRecord *pSubRecord = new BackupClientDirectoryRecord(0, "");
- if(!pSubRecord)
- {
- throw std::bad_alloc();
- }
-
- mpDirectoryRecord.reset(pSubRecord);
- mpDirectoryRecord->Deserialize(rArchive);
- }
- else
- {
- // there is something going on here
- THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
- }
-
- //
- //
- //
- rArchive.Read(aMagicMarker);
-
- if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
- {
- // NOOP
- }
- else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
- {
- mpExcludeFiles = new ExcludeList;
- if(!mpExcludeFiles)
- {
- throw std::bad_alloc();
- }
-
- mpExcludeFiles->Deserialize(rArchive);
- }
- else
- {
- // there is something going on here
- THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
- }
-
- //
- //
- //
- rArchive.Read(aMagicMarker);
-
- if(aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
- {
- // NOOP
- }
- else if(aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
- {
- mpExcludeDirs = new ExcludeList;
- if(!mpExcludeDirs)
- {
- throw std::bad_alloc();
- }
-
- mpExcludeDirs->Deserialize(rArchive);
- }
- else
- {
- // there is something going on here
- THROW_EXCEPTION(ClientException, CorruptStoreObjectInfoFile);
- }
-}
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: BackupDaemon::Location::Serialize(Archive & rArchive)
-// Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction.
-//
-// Created: 2005/04/11
-//
-// --------------------------------------------------------------------------
-void BackupDaemon::Location::Serialize(Archive & rArchive) const
-{
- //
- //
- //
- rArchive.Write(mName);
- rArchive.Write(mPath);
- rArchive.Write(mIDMapIndex);
-
- //
- //
- //
- if(mpDirectoryRecord.get() == NULL)
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
- rArchive.Write(aMagicMarker);
- }
- else
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
- rArchive.Write(aMagicMarker);
-
- mpDirectoryRecord->Serialize(rArchive);
- }
-
- //
- //
- //
- if(!mpExcludeFiles)
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
- rArchive.Write(aMagicMarker);
- }
- else
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
- rArchive.Write(aMagicMarker);
-
- mpExcludeFiles->Serialize(rArchive);
- }
-
- //
- //
- //
- if(!mpExcludeDirs)
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_NOOP;
- rArchive.Write(aMagicMarker);
- }
- else
- {
- int64_t aMagicMarker = ARCHIVE_MAGIC_VALUE_RECURSE; // be explicit about whether recursion follows
- rArchive.Write(aMagicMarker);
-
- mpExcludeDirs->Serialize(rArchive);
- }
-}
-
-// --------------------------------------------------------------------------
-//
-// Function
// Name: BackupDaemon::CommandSocketInfo::CommandSocketInfo()
// Purpose: Constructor
// Created: 18/2/04
diff --git a/bin/bbackupd/BackupDaemon.h b/bin/bbackupd/BackupDaemon.h
index 4a9097b9..c584a2bd 100644
--- a/bin/bbackupd/BackupDaemon.h
+++ b/bin/bbackupd/BackupDaemon.h
@@ -157,32 +157,6 @@ private:
int UseScriptToSeeIfSyncAllowed();
public:
- class Location
- {
- public:
- Location();
- ~Location();
-
- void Deserialize(Archive & rArchive);
- void Serialize(Archive & rArchive) const;
- private:
- Location(const Location &); // copy not allowed
- Location &operator=(const Location &);
- public:
- std::string mName;
- std::string mPath;
- std::auto_ptr<BackupClientDirectoryRecord> mpDirectoryRecord;
- int mIDMapIndex;
- ExcludeList *mpExcludeFiles;
- ExcludeList *mpExcludeDirs;
-
-#ifdef ENABLE_VSS
- bool mIsSnapshotCreated;
- VSS_ID mSnapshotVolumeId;
- std::string mSnapshotPath;
-#endif
- };
-
typedef const std::vector<Location *> Locations;
Locations GetLocations() { return mLocations; }
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp
index 2c1fb0df..ef237671 100644
--- a/lib/win32/emu.cpp
+++ b/lib/win32/emu.cpp
@@ -1,8 +1,5 @@
// Box Backup Win32 native port by Nick Knight
-// Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW
-#define WINVER 0x0500
-
#include "emu.h"
#ifdef WIN32
@@ -1080,9 +1077,10 @@ DIR *opendir(const char *name)
return NULL;
}
- pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info));
+ pDir->fd = FindFirstFileW(pDir->name, &pDir->info);
+ DWORD tmp = GetLastError();
- if (pDir->fd == -1)
+ if (pDir->fd == INVALID_HANDLE_VALUE)
{
delete [] pDir->name;
delete pDir;
@@ -1111,26 +1109,37 @@ struct dirent *readdir(DIR *dp)
{
struct dirent *den = NULL;
- if (dp && dp->fd != -1)
+ if (dp && dp->fd != INVALID_HANDLE_VALUE)
{
- if (!dp->result.d_name ||
- _wfindnext(dp->fd, &dp->info) != -1)
+ // first time around, when dp->result.d_name == NULL, use
+ // the values returned by FindFirstFile. After that, call
+ // FindNextFileW to return new ones.
+ if (!dp->result.d_name ||
+ FindNextFileW(dp->fd, &dp->info) != 0)
{
den = &dp->result;
- std::wstring input(dp->info.name);
+ std::wstring input(dp->info.cFileName);
memset(tempbuff, 0, sizeof(tempbuff));
- WideCharToMultiByte(CP_UTF8, 0, dp->info.name,
+ WideCharToMultiByte(CP_UTF8, 0, dp->info.cFileName,
-1, &tempbuff[0], sizeof (tempbuff),
NULL, NULL);
//den->d_name = (char *)dp->info.name;
den->d_name = &tempbuff[0];
- if (dp->info.attrib & FILE_ATTRIBUTE_DIRECTORY)
+ den->d_type = dp->info.dwFileAttributes;
+ }
+ else // FindNextFileW failed
+ {
+ // Why did it fail? No more files?
+ winerrno = GetLastError();
+ den = NULL;
+
+ if (winerrno == ERROR_NO_MORE_FILES)
{
- den->d_type = S_IFDIR;
+ errno = 0; // no more files
}
else
{
- den->d_type = S_IFREG;
+ errno = ENOSYS;
}
}
}
@@ -1138,6 +1147,7 @@ struct dirent *readdir(DIR *dp)
{
errno = EBADF;
}
+
return den;
}
catch (...)
@@ -1159,24 +1169,26 @@ int closedir(DIR *dp)
{
try
{
- int finres = -1;
+ BOOL finres = false;
+
if (dp)
{
- if(dp->fd != -1)
+ if(dp->fd != INVALID_HANDLE_VALUE)
{
- finres = _findclose(dp->fd);
+ finres = FindClose(dp->fd);
}
delete [] dp->name;
delete dp;
}
- if (finres == -1) // errors go to EBADF
+ if (finres == FALSE) // errors go to EBADF
{
+ winerrno = GetLastError();
errno = EBADF;
}
- return finres;
+ return (finres == TRUE) ? 0 : -1;
}
catch (...)
{
diff --git a/lib/win32/emu.h b/lib/win32/emu.h
index 1ebd45c2..151fa2cb 100644
--- a/lib/win32/emu.h
+++ b/lib/win32/emu.h
@@ -50,22 +50,30 @@
#define __MSVCRT_VERSION__ 0x0601
#endif
+// We need WINVER at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW,
+// and 0x0501 for FindFirstFile(W) for opendir/readdir.
+//
// WIN32_WINNT versions 0x0600 (Vista) and higher enable WSAPoll() in
// winsock2.h, whose struct pollfd conflicts with ours below, so for
-// now we just set it lower than that, to Windows 2000.
+// now we just set it lower than that, to Windows XP (0x0501).
+
#ifdef WINVER
- #if WINVER != 0x0500
- #error Must include emu.h before setting WINVER
- #endif
+# if WINVER != 0x0501
+// provoke a redefinition warning to track down the offender
+# define WINVER 0x0501
+# error Must include emu.h before setting WINVER
+# endif
#endif
-#define WINVER 0x0500
+#define WINVER 0x0501
#ifdef _WIN32_WINNT
- #if _WIN32_WINNT != 0x0500
- #error Must include emu.h before setting _WIN32_WINNT
- #endif
+# if _WIN32_WINNT != 0x0501
+// provoke a redefinition warning to track down the offender
+# define _WIN32_WINNT 0x0501
+# error Must include emu.h before setting _WIN32_WINNT
+# endif
#endif
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
// Windows headers
@@ -237,17 +245,15 @@ inline int strcasecmp(const char *s1, const char *s2)
struct dirent
{
char *d_name;
- unsigned long d_type;
+ DWORD d_type; // file attributes
};
struct DIR
{
- intptr_t fd; // filedescriptor
- // struct _finddata_t info;
- struct _wfinddata_t info;
- // struct _finddata_t info;
- struct dirent result; // d_name (first time null)
- wchar_t *name; // null-terminated byte string
+ HANDLE fd; // the HANDLE returned by FindFirstFile
+ WIN32_FIND_DATAW info;
+ struct dirent result; // d_name (first time null)
+ wchar_t* name; // null-terminated byte string
};
DIR *opendir(const char *name);