summaryrefslogtreecommitdiff
path: root/lib/backupclient
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2010-11-09 17:28:58 +0100
committerReinhard Tartler <siretart@tauware.de>2010-11-09 17:28:58 +0100
commit8a937bd354001a190dbe66538aacb353e7c99341 (patch)
tree9db021722d1743482e76f93d00fb97bed32a3ea7 /lib/backupclient
parentb591c86a418e8d5a0d1c1afd319d9acdad6fd4e3 (diff)
Import upstream version 0.11~rc8~r2714
Diffstat (limited to 'lib/backupclient')
-rw-r--r--lib/backupclient/BackupClientFileAttributes.cpp176
-rw-r--r--lib/backupclient/BackupClientFileAttributes.h4
-rw-r--r--lib/backupclient/BackupStoreException.txt1
-rw-r--r--lib/backupclient/Makefile.extra4
4 files changed, 151 insertions, 34 deletions
diff --git a/lib/backupclient/BackupClientFileAttributes.cpp b/lib/backupclient/BackupClientFileAttributes.cpp
index d896a363..af156a1d 100644
--- a/lib/backupclient/BackupClientFileAttributes.cpp
+++ b/lib/backupclient/BackupClientFileAttributes.cpp
@@ -78,6 +78,9 @@ typedef struct
typedef struct
{
int32_t uid, gid, mode;
+ #ifdef WIN32
+ int64_t fileCreationTime;
+ #endif
} attributeHashData;
// Use default packing
@@ -221,12 +224,15 @@ bool BackupClientFileAttributes::operator==(const BackupClientFileAttributes &rA
//
// Function
// Name: BackupClientFileAttributes::Compare(const BackupClientFileAttributes &, bool)
-// Purpose: Compare, optionally ignoring the attribute modification time and/or modification time, and some data which is
-// irrelevant in practise (eg file generation number)
+// Purpose: Compare, optionally ignoring the attribute
+// modification time and/or modification time, and some
+// data which is irrelevant in practise (eg file
+// generation number)
// Created: 10/12/03
//
// --------------------------------------------------------------------------
-bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr, bool IgnoreAttrModTime, bool IgnoreModTime) const
+bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr,
+ bool IgnoreAttrModTime, bool IgnoreModTime) const
{
EnsureClearAvailable();
rAttr.EnsureClearAvailable();
@@ -234,6 +240,10 @@ bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr
// Check sizes are the same, as a first check
if(mpClearAttributes->GetSize() != rAttr.mpClearAttributes->GetSize())
{
+ BOX_TRACE("Attribute Compare: Attributes objects are "
+ "different sizes, cannot compare them: local " <<
+ mpClearAttributes->GetSize() << " bytes, remote " <<
+ rAttr.mpClearAttributes->GetSize() << " bytes");
return false;
}
@@ -241,32 +251,51 @@ bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr
// Bytes are checked in network order, but this doesn't matter as we're only checking for equality.
attr_StreamFormat *a1 = (attr_StreamFormat*)mpClearAttributes->GetBuffer();
attr_StreamFormat *a2 = (attr_StreamFormat*)rAttr.mpClearAttributes->GetBuffer();
-
- if(a1->AttributeType != a2->AttributeType
- || a1->UID != a2->UID
- || a1->GID != a2->GID
- || a1->UserDefinedFlags != a2->UserDefinedFlags
- || a1->Mode != a2->Mode)
- {
- return false;
+
+ #define COMPARE(attribute, message) \
+ if (a1->attribute != a2->attribute) \
+ { \
+ BOX_TRACE("Attribute Compare: " << message << " differ: " \
+ "local " << ntoh(a1->attribute) << ", " \
+ "remote " << ntoh(a2->attribute)); \
+ return false; \
}
-
+ COMPARE(AttributeType, "Attribute types");
+ COMPARE(UID, "UIDs");
+ COMPARE(GID, "GIDs");
+ COMPARE(UserDefinedFlags, "User-defined flags");
+ COMPARE(Mode, "Modes");
+
if(!IgnoreModTime)
{
- int t1 = a1->ModificationTime / 1000000;
- int t2 = a2->ModificationTime / 1000000;
- if(t1 != t2)
+ uint64_t t1 = box_ntoh64(a1->ModificationTime);
+ uint64_t t2 = box_ntoh64(a2->ModificationTime);
+ time_t s1 = BoxTimeToSeconds(t1);
+ time_t s2 = BoxTimeToSeconds(t2);
+ if(s1 != s2)
{
+ BOX_TRACE("Attribute Compare: File modification "
+ "times differ: local " <<
+ FormatTime(t1, true) << " (" << s1 << "), "
+ "remote " <<
+ FormatTime(t2, true) << " (" << s2 << ")");
return false;
}
}
-
+
if(!IgnoreAttrModTime)
{
- int t1 = a1->AttrModificationTime / 1000000;
- int t2 = a2->AttrModificationTime / 1000000;
- if(t1 != t2)
+ uint64_t t1 = box_ntoh64(a1->AttrModificationTime);
+ uint64_t t2 = box_ntoh64(a2->AttrModificationTime);
+ time_t s1 = BoxTimeToSeconds(t1);
+ time_t s2 = BoxTimeToSeconds(t2);
+ if(s1 != s2)
{
+ BOX_TRACE("Attribute Compare: Attribute modification "
+ "times differ: local " <<
+ FormatTime(t1, true) << " (" << s1 << "), "
+ "remote " <<
+ FormatTime(t2, true) << " (" << s2 << ")");
return false;
}
}
@@ -276,8 +305,16 @@ bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr
if(size > sizeof(attr_StreamFormat))
{
// Symlink strings don't match. This also compares xattrs
- if(::memcmp(a1 + 1, a2 + 1, size - sizeof(attr_StreamFormat)) != 0)
+ int datalen = size - sizeof(attr_StreamFormat);
+
+ if(::memcmp(a1 + 1, a2 + 1, datalen) != 0)
{
+ std::string s1((char *)(a1 + 1), datalen);
+ std::string s2((char *)(a2 + 1), datalen);
+ BOX_TRACE("Attribute Compare: Symbolic link target "
+ "or extended attributes differ: "
+ "local " << PrintEscapedBinaryData(s1) << ", "
+ "remote " << PrintEscapedBinaryData(s2));
return false;
}
}
@@ -292,14 +329,21 @@ bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupClientFileAttributes::ReadAttributes(const char *)
-// Purpose: Read the attributes of the file, and store them ready for streaming.
-// Optionally retrieve the modification time and attribute modification time.
+// Name: BackupClientFileAttributes::ReadAttributes(
+// const char *Filename, bool ZeroModificationTimes,
+// box_time_t *pModTime, box_time_t *pAttrModTime,
+// int64_t *pFileSize, InodeRefType *pInodeNumber,
+// bool *pHasMultipleLinks)
+// Purpose: Read the attributes of the file, and store them
+// ready for streaming. Optionally retrieve the
+// modification time and attribute modification time.
// Created: 2003/10/07
//
// --------------------------------------------------------------------------
-void BackupClientFileAttributes::ReadAttributes(const char *Filename, bool ZeroModificationTimes, box_time_t *pModTime,
- box_time_t *pAttrModTime, int64_t *pFileSize, InodeRefType *pInodeNumber, bool *pHasMultipleLinks)
+void BackupClientFileAttributes::ReadAttributes(const char *Filename,
+ bool ZeroModificationTimes, box_time_t *pModTime,
+ box_time_t *pAttrModTime, int64_t *pFileSize,
+ InodeRefType *pInodeNumber, bool *pHasMultipleLinks)
{
StreamableMemBlock *pnewAttr = 0;
try
@@ -603,6 +647,62 @@ void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBloc
#endif
}
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupClientFileAttributes::GetModificationTimes()
+// Purpose: Returns the modification time embedded in the
+// attributes.
+// Created: 2010/02/24
+//
+// --------------------------------------------------------------------------
+void BackupClientFileAttributes::GetModificationTimes(
+ box_time_t *pModificationTime,
+ box_time_t *pAttrModificationTime) const
+{
+ // Got something loaded
+ if(GetSize() <= 0)
+ {
+ THROW_EXCEPTION(BackupStoreException, AttributesNotLoaded);
+ }
+
+ // Make sure there are clear attributes to use
+ EnsureClearAvailable();
+ ASSERT(mpClearAttributes != 0);
+
+ // Check if the decrypted attributes are small enough, and the type of attributes stored
+ if(mpClearAttributes->GetSize() < (int)sizeof(int32_t))
+ {
+ THROW_EXCEPTION(BackupStoreException, AttributesNotUnderstood);
+ }
+ int32_t *type = (int32_t*)mpClearAttributes->GetBuffer();
+ ASSERT(type != 0);
+ if(ntohl(*type) != ATTRIBUTETYPE_GENERIC_UNIX)
+ {
+ // Don't know what to do with these
+ THROW_EXCEPTION(BackupStoreException, AttributesNotUnderstood);
+ }
+
+ // Check there is enough space for an attributes block
+ if(mpClearAttributes->GetSize() < (int)sizeof(attr_StreamFormat))
+ {
+ // Too small
+ THROW_EXCEPTION(BackupStoreException, AttributesNotLoaded);
+ }
+
+ // Get pointer to structure
+ attr_StreamFormat *pattr = (attr_StreamFormat*)mpClearAttributes->GetBuffer();
+
+ if(pModificationTime)
+ {
+ *pModificationTime = box_ntoh64(pattr->ModificationTime);
+ }
+
+ if(pAttrModificationTime)
+ {
+ *pAttrModificationTime = box_ntoh64(pattr->AttrModificationTime);
+ }
+}
// --------------------------------------------------------------------------
//
@@ -1032,14 +1132,18 @@ void BackupClientFileAttributes::SetAttributeHashSecret(const void *pSecret, int
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupClientFileAttributes::GenerateAttributeHash(struct stat &, const std::string &, const std::string &)
-// Purpose: Generate a 64 bit hash from the attributes, used to detect changes.
-// Include filename in the hash, so that it changes from one file to another,
-// so don't reveal identical attributes.
+// Name: BackupClientFileAttributes::GenerateAttributeHash(
+// struct stat &, const std::string &,
+// const std::string &)
+// Purpose: Generate a 64 bit hash from the attributes, used to
+// detect changes. Include filename in the hash, so
+// that it changes from one file to another, so don't
+// reveal identical attributes.
// Created: 25/4/04
//
// --------------------------------------------------------------------------
-uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_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)
{
@@ -1054,6 +1158,16 @@ uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_STRUCT_STAT &st,
hashData.gid = htonl(st.st_gid);
hashData.mode = htonl(st.st_mode);
+ #ifdef WIN32
+ // On Windows, the "file attribute modification time" is the
+ // file creation time, and we want to back this up, restore
+ // it and compare it.
+ //
+ // On other platforms, it's not very important and can't
+ // reliably be set to anything other than the current time.
+ hashData.fileCreationTime = box_hton64(st.st_ctime);
+ #endif
+
StreamableMemBlock xattr;
FillExtendedAttr(xattr, filename.c_str());
@@ -1062,7 +1176,7 @@ uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_STRUCT_STAT &st,
digest.Add(&hashData, sizeof(hashData));
digest.Add(xattr.GetBuffer(), xattr.GetSize());
digest.Add(leafname.c_str(), leafname.size());
- digest.Add(sAttributeHashSecret, sAttributeHashSecretLength);
+ digest.Add(sAttributeHashSecret, sAttributeHashSecretLength);
digest.Finish();
// Return the first 64 bits of the hash
diff --git a/lib/backupclient/BackupClientFileAttributes.h b/lib/backupclient/BackupClientFileAttributes.h
index b32c14dd..f9a0d883 100644
--- a/lib/backupclient/BackupClientFileAttributes.h
+++ b/lib/backupclient/BackupClientFileAttributes.h
@@ -47,7 +47,9 @@ public:
InodeRefType *pInodeNumber = 0, bool *pHasMultipleLinks = 0);
void WriteAttributes(const char *Filename,
bool MakeUserWritable = false) const;
-
+ void GetModificationTimes(box_time_t *pModificationTime,
+ box_time_t *pAttrModificationTime) const;
+
bool IsSymLink() const;
static void SetBlowfishKey(const void *pKey, int KeyLength);
diff --git a/lib/backupclient/BackupStoreException.txt b/lib/backupclient/BackupStoreException.txt
index 50c615b2..528a8c94 100644
--- a/lib/backupclient/BackupStoreException.txt
+++ b/lib/backupclient/BackupStoreException.txt
@@ -68,3 +68,4 @@ SignalReceived 64 A signal was received by the process, restart or terminate
IncompatibleFromAndDiffFiles 65 Attempt to use a diff and a from file together, when they're not related
DiffFromIDNotFoundInDirectory 66 When uploading via a diff, the diff from file must be in the same directory
PatchChainInfoBadInDirectory 67 A directory contains inconsistent information. Run bbstoreaccounts check to fix it.
+UnknownObjectRefCountRequested 68 A reference count was requested for an object whose reference count is not known.
diff --git a/lib/backupclient/Makefile.extra b/lib/backupclient/Makefile.extra
index 925c880e..df3319df 100644
--- a/lib/backupclient/Makefile.extra
+++ b/lib/backupclient/Makefile.extra
@@ -5,12 +5,12 @@ GEN_CMD_SRV = $(MAKEPROTOCOL) Client ../../bin/bbstored/backupprotocol.txt
# AUTOGEN SEEDING
autogen_BackupProtocolClient.cpp autogen_BackupProtocolClient.h: $(MAKEPROTOCOL) ../../bin/bbstored/backupprotocol.txt
- $(PERL) $(GEN_CMD_SRV)
+ $(_PERL) $(GEN_CMD_SRV)
MAKEEXCEPTION = ../../lib/common/makeexception.pl
# AUTOGEN SEEDING
autogen_BackupStoreException.h autogen_BackupStoreException.cpp: $(MAKEEXCEPTION) BackupStoreException.txt
- $(PERL) $(MAKEEXCEPTION) BackupStoreException.txt
+ $(_PERL) $(MAKEEXCEPTION) BackupStoreException.txt