[Box Backup-dev] COMMIT r365 - in box/chris/win32/vc2005-compile-fixes: . bin/bbackupd bin/bbackupquery bin/bbstored distribution distribution/boxbackup distribution/boxbackup/contrib/rpm infrastructure infrastructure/m4 lib/backupclient lib/common lib/crypto lib/server lib/win32 test/backupdiff test/backupstore test/backupstorepatch test/bbackupd test/raidfile

boxbackup-dev at fluffy.co.uk boxbackup-dev at fluffy.co.uk
Fri Feb 3 20:22:03 GMT 2006


Author: chris
Date: 2006-02-03 20:21:10 +0000 (Fri, 03 Feb 2006)
New Revision: 365

Added:
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_bswap64.m4
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_compare_version.m4
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_path_bdb.m4
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_split_version.m4
   box/chris/win32/vc2005-compile-fixes/lib/common/Archive.h
Removed:
   box/chris/win32/vc2005-compile-fixes/VERSION.txt
   box/chris/win32/vc2005-compile-fixes/infrastructure/tests/
   box/chris/win32/vc2005-compile-fixes/test/raidfile/Darwin-SYS.h
   box/chris/win32/vc2005-compile-fixes/test/raidfile/Makefile.extra.Darwin
   box/chris/win32/vc2005-compile-fixes/test/raidfile/make-darwin-intercepts.pl
Modified:
   box/chris/win32/vc2005-compile-fixes/BUGS.txt
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.h
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.h
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientInodeToIDMap.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.h
   box/chris/win32/vc2005-compile-fixes/bin/bbackupd/bbackupd-config
   box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/bbackupquery.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbstored/BackupCommands.cpp
   box/chris/win32/vc2005-compile-fixes/bin/bbstored/backupprotocol.txt
   box/chris/win32/vc2005-compile-fixes/configure.ac
   box/chris/win32/vc2005-compile-fixes/distribution/COMMON-MANIFEST.txt
   box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt
   box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/LICENSE.txt
   box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/THANKS.txt
   box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/VERSION.txt
   box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/contrib/rpm/boxbackup.spec
   box/chris/win32/vc2005-compile-fixes/infrastructure/BoxPlatform.pm.in
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_check_mount_point.m4
   box/chris/win32/vc2005-compile-fixes/infrastructure/m4/vl_lib_readline.m4
   box/chris/win32/vc2005-compile-fixes/infrastructure/makebuildenv.pl
   box/chris/win32/vc2005-compile-fixes/infrastructure/makedistribution.pl
   box/chris/win32/vc2005-compile-fixes/infrastructure/makeparcels.pl
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupClientFileAttributes.cpp
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupDaemonConfigVerify.cpp
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreDirectory.cpp
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.cpp
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.h
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFileDiff.cpp
   box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFilenameClear.cpp
   box/chris/win32/vc2005-compile-fixes/lib/common/
   box/chris/win32/vc2005-compile-fixes/lib/common/Box.h
   box/chris/win32/vc2005-compile-fixes/lib/common/BoxPlatform.h
   box/chris/win32/vc2005-compile-fixes/lib/common/CommonException.txt
   box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.cpp
   box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.h
   box/chris/win32/vc2005-compile-fixes/lib/crypto/Random.cpp
   box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.cpp
   box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.h
   box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp
   box/chris/win32/vc2005-compile-fixes/parcels.txt
   box/chris/win32/vc2005-compile-fixes/test/backupdiff/testbackupdiff.cpp
   box/chris/win32/vc2005-compile-fixes/test/backupstore/testbackupstore.cpp
   box/chris/win32/vc2005-compile-fixes/test/backupstorepatch/testbackupstorepatch.cpp
   box/chris/win32/vc2005-compile-fixes/test/bbackupd/testbbackupd.cpp
   box/chris/win32/vc2005-compile-fixes/test/raidfile/intercept.cpp
Log:
* Many files
- Merged changes from trunk since this branch was forked


Modified: box/chris/win32/vc2005-compile-fixes/BUGS.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/BUGS.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/BUGS.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -8,3 +8,8 @@
 * if bbackupd gets an error then a signal, it may not wait it's full 100 seconds before retrying. And then won't stop the cycle...
 * bbackupquery restore, if not root, then won't do file ownership properly, but won't alert the user to this fact
 * empty (real) directories in the store aren't deleted when they're empty (and will never be used again) -- uses up disc space unnecessarily
+* need unit tests for SSL keepalives and state saving (serialisation)
+* make Archive derive from Protocol
+* more automated tests for win32
+* change off_t to box_off_t in preparation for win32 large file support
+* support large files on win32 by using native *i64 functions instead of posix

Deleted: box/chris/win32/vc2005-compile-fixes/VERSION.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/VERSION.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/VERSION.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,2 +0,0 @@
-0.09_autoconf_win32
-boxbackup

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -9,9 +9,15 @@
 
 #include "Box.h"
 
-#ifndef WIN32
-#include <syslog.h>
+#ifdef HAVE_SYSLOG_H
+	#include <syslog.h>
 #endif
+#ifdef HAVE_SIGNAL_H
+	#include <signal.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+	#include <sys/time.h>
+#endif
 
 #include "BoxPortsAndFiles.h"
 #include "BoxTime.h"
@@ -22,6 +28,7 @@
 #include "BackupStoreException.h"
 #include "BackupDaemon.h"
 #include "autogen_BackupProtocolClient.h"
+#include "BackupStoreFile.h"
 
 #include "MemLeakFindOn.h"
 
@@ -48,7 +55,11 @@
 	  mpNewIDMap(0),
 	  mStorageLimitExceeded(false),
 	  mpExcludeFiles(0),
-	  mpExcludeDirs(0)
+	  mpExcludeDirs(0),
+	  mbIsManaged(false),
+	  mTimeMgmtEpoch(0),
+	  mMaximumDiffTime(600),
+	  mKeepAliveTime(0)
 {
 }
 
@@ -453,3 +464,166 @@
 }
 
 
+// maximum time to spend diffing
+static int sMaximumDiffTime = 600;
+// maximum time of SSL inactivity (keep-alive interval)
+static int sKeepAliveTime = 0;
+
+void BackupClientContext::SetMaximumDiffingTime(int iSeconds)
+{
+	sMaximumDiffTime = iSeconds < 0 ? 0 : iSeconds;
+	TRACE1("Set maximum diffing time to %d seconds\n", sMaximumDiffTime);
+}
+
+void BackupClientContext::SetKeepAliveTime(int iSeconds)
+{
+	sKeepAliveTime = iSeconds < 0 ? 0 : iSeconds;
+	TRACE1("Set keep-alive time to %d seconds\n", sKeepAliveTime);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    static TimerSigHandler(int)
+//		Purpose: Signal handler
+//		Created: 19/3/04
+//
+// --------------------------------------------------------------------------
+static void TimerSigHandler(int iUnused)
+{
+	BackupStoreFile::DiffTimerExpired();	
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientContext::ManageDiffProcess()
+//		Purpose: Initiates a file diff control timer
+//		Created: 04/19/2005
+//
+// --------------------------------------------------------------------------
+void BackupClientContext::ManageDiffProcess()
+{
+	if (mbIsManaged || !mpConnection)
+		return;
+
+	ASSERT(mTimeMgmtEpoch == 0);
+
+#ifdef PLATFORM_CYGWIN
+	::signal(SIGALRM, TimerSigHandler);
+#else
+	::signal(SIGVTALRM, TimerSigHandler);
+#endif // PLATFORM_CYGWIN
+
+	struct itimerval timeout;
+	memset(&timeout, 0, sizeof(timeout));
+
+	//
+	//
+	//
+	if (sMaximumDiffTime <= 0 && sKeepAliveTime <= 0)
+	{
+		TRACE0("Diff control not requested - letting things run wild\n");
+		return;
+	}
+	else if (sMaximumDiffTime > 0 && sKeepAliveTime > 0)
+	{
+		timeout.it_value.tv_sec = sKeepAliveTime < sMaximumDiffTime ? sKeepAliveTime : sMaximumDiffTime;
+		timeout.it_interval.tv_sec = sKeepAliveTime < sMaximumDiffTime ? sKeepAliveTime : sMaximumDiffTime;
+	}
+	else
+	{
+		timeout.it_value.tv_sec = sKeepAliveTime > 0 ? sKeepAliveTime : sMaximumDiffTime;
+		timeout.it_interval.tv_sec = sKeepAliveTime > 0 ? sKeepAliveTime : sMaximumDiffTime;
+	}
+
+	// avoid race
+	mTimeMgmtEpoch = time(NULL);
+
+#ifdef PLATFORM_CYGWIN
+	if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0)
+#else
+	if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0)
+#endif // PLATFORM_CYGWIN
+	{
+		mTimeMgmtEpoch = 0;
+
+		TRACE0("WARNING: couldn't set file diff control timeout\n");
+		THROW_EXCEPTION(BackupStoreException, Internal)
+	}
+
+	mbIsManaged = true;
+	TRACE0("Initiated timer for file diff control\n");
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientContext::UnManageDiffProcess()
+//		Purpose: suspends file diff control timer
+//		Created: 04/19/2005
+//
+// --------------------------------------------------------------------------
+void BackupClientContext::UnManageDiffProcess()
+{
+	if (!mbIsManaged /* don't test for active connection, just do it */)
+		return;
+
+	struct itimerval timeout;
+	memset(&timeout, 0, sizeof(timeout));
+
+#ifdef PLATFORM_CYGWIN
+	if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0)
+#else
+	if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0)
+#endif // PLATFORM_CYGWIN
+	{
+		TRACE0("WARNING: couldn't clear file diff control timeout\n");
+		THROW_EXCEPTION(BackupStoreException, Internal)
+	}
+
+	mbIsManaged = false;
+	mTimeMgmtEpoch = 0;
+
+	TRACE0("Suspended timer for file diff control\n");
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientContext::DoKeepAlive()
+//		Purpose: Does something inconsequential over the SSL link to keep it up
+//		Created: 04/19/2005
+//
+// --------------------------------------------------------------------------
+void BackupClientContext::DoKeepAlive()
+{
+	if (!mpConnection)
+		return;
+
+	mpConnection->QueryGetIsAlive();
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientContext::GetTimeMgmtEpoch()
+//		Purpose: Returns the unix time when the diff was started, or zero
+//				 if the diff process is unmanaged.
+//		Created: 04/19/2005
+//
+// --------------------------------------------------------------------------
+time_t BackupClientContext::GetTimeMgmtEpoch() 
+{
+	return mTimeMgmtEpoch;
+}
+
+int BackupClientContext::GetMaximumDiffingTime() 
+{
+	return mMaximumDiffTime;
+}
+
+int BackupClientContext::GetKeepaliveTime() 
+{
+	return mKeepAliveTime;
+}

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientContext.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -12,6 +12,7 @@
 
 #include "BoxTime.h"
 #include "BackupClientDeleteList.h"
+#include "BackupStoreFile.h"
 #include "ExcludeList.h"
 
 class TLSContext;
@@ -31,12 +32,12 @@
 //		Created: 2003/10/08
 //
 // --------------------------------------------------------------------------
-class BackupClientContext
+class BackupClientContext : public DiffTimer
 {
 public:
 	BackupClientContext(BackupDaemon &rDaemon, TLSContext &rTLSContext, const std::string &rHostname,
 		int32_t AccountNumber, bool ExtendedLogging);
-	~BackupClientContext();
+	virtual ~BackupClientContext();
 private:
 	BackupClientContext(const BackupClientContext &);
 public:
@@ -134,6 +135,60 @@
 		bool &rIsCurrentVersionOut, box_time_t *pModTimeOnServer = 0, box_time_t *pAttributesHashOnServer = 0,
 		BackupStoreFilenameClear *pLeafname = 0); // not const as may connect to server
 
+	// --------------------------------------------------------------------------
+	//
+	// Function
+	//		Name:    BackupClientContext::SetMaximumDiffingTime()
+	//		Purpose: Sets the maximum time that will be spent diffing a file
+	//		Created: 04/19/2005
+	//
+	// --------------------------------------------------------------------------
+	static void SetMaximumDiffingTime(int iSeconds);
+
+	// --------------------------------------------------------------------------
+	//
+	// Function
+	//		Name:    BackupClientContext::SetKeepAliveTime()
+	//		Purpose: Sets the time interval for repetitive keep-alive operation
+	//		Created: 04/19/2005
+	//
+	// --------------------------------------------------------------------------
+	static void SetKeepAliveTime(int iSeconds);
+
+	// --------------------------------------------------------------------------
+	//
+	// Function
+	//		Name:    BackupClientContext::ManageDiffProcess()
+	//		Purpose: Initiates an SSL connection/session keep-alive process
+	//		Created: 04/19/2005
+	//
+	// --------------------------------------------------------------------------
+	void ManageDiffProcess();
+
+	// --------------------------------------------------------------------------
+	//
+	// Function
+	//		Name:    BackupClientContext::UnManageDiffProcess()
+	//		Purpose: Suspends an SSL connection/session keep-alive process
+	//		Created: 04/19/2005
+	//
+	// --------------------------------------------------------------------------
+	void UnManageDiffProcess();
+
+	// --------------------------------------------------------------------------
+	//
+	// Function
+	//		Name:    BackupClientContext::DoKeepAlive()
+	//		Purpose: Does something inconsequential over the SSL link to 
+	//				 keep it up, implements DiffTimer interface
+	//		Created: 04/19/2005
+	//
+	// --------------------------------------------------------------------------
+	virtual void   DoKeepAlive();
+	virtual time_t GetTimeMgmtEpoch();
+	virtual int    GetMaximumDiffingTime();
+	virtual int    GetKeepaliveTime();
+	
 private:
 	BackupDaemon &mrDaemon;
 	TLSContext &mrTLSContext;
@@ -149,8 +204,16 @@
 	bool mStorageLimitExceeded;
 	ExcludeList *mpExcludeFiles;
 	ExcludeList *mpExcludeDirs;
+
+	bool mbIsManaged;
+	// unix time when diff was started
+	time_t mTimeMgmtEpoch;
+	// maximum time to spend diffing, in seconds
+	int mMaximumDiffTime;
+	// maximum time of SSL inactivity (keep-alive interval), in seconds
+	int mKeepAliveTime;
+
 };
 
 
 #endif // BACKUPCLIENTCONTEXT__H
-

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -28,6 +28,7 @@
 #include "FileModificationTime.h"
 #include "BackupDaemon.h"
 #include "BackupStoreException.h"
+#include "Archive.h"
 
 #include "MemLeakFindOn.h"
 
@@ -1096,14 +1097,28 @@
 				// Found an old version -- get the index
 				std::auto_ptr<IOStream> blockIndexStream(connection.ReceiveStream());
 			
+				//
 				// Diff the file
+				//
+
+				rParams.mrContext.ManageDiffProcess();
+
 				bool isCompletelyDifferent = false;
-				std::auto_ptr<IOStream> patchStream(BackupStoreFile::EncodeFileDiff(rFilename.c_str(),
+				std::auto_ptr<IOStream> patchStream(
+					BackupStoreFile::EncodeFileDiff(
+						rFilename.c_str(),
 						mObjectID,	/* containing directory */
 						rStoreFilename, diffFromID, *blockIndexStream,
-						connection.GetTimeout(), 0 /* not interested in the modification time */, &isCompletelyDifferent));
+						connection.GetTimeout(), 
+						&rParams.mrContext, // DiffTimer implementation
+						0 /* not interested in the modification time */, 
+						&isCompletelyDifferent));
 	
+				rParams.mrContext.UnManageDiffProcess();
+
+				//
 				// Upload the patch to the store
+				//
 				std::auto_ptr<BackupProtocolClientSuccess> stored(connection.QueryStoreFile(mObjectID, ModificationTime,
 						AttributesHash, isCompletelyDifferent?(0):(diffFromID), rStoreFilename, *patchStream));
 				
@@ -1133,6 +1148,8 @@
 	}
 	catch(BoxException &e)
 	{
+		rParams.mrContext.UnManageDiffProcess();
+
 		if(e.GetType() == ConnectionException::ExceptionType && e.GetSubType() == ConnectionException::Protocol_UnexpectedReply)
 		{
 			// Check and see what error the protocol has -- as it might be an error...
@@ -1214,5 +1231,177 @@
 {
 }
 
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientDirectoryRecord::Deserialize(Archive & rArchive)
+//		Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void BackupClientDirectoryRecord::Deserialize(Archive & rArchive)
+{
+	// Make deletion recursive
+	DeleteSubDirectories();
 
+	// Delete maps
+	if(mpPendingEntries != 0)
+	{
+		delete mpPendingEntries;
+		mpPendingEntries = 0;
+	}
 
+	//
+	//
+	//
+	rArchive.Read(mObjectID);
+	rArchive.Read(mSubDirName);
+	rArchive.Read(mInitialSyncDone);
+	rArchive.Read(mSyncDone);
+
+	//
+	//
+	//
+	int64_t iCount = 0;
+	rArchive.Read(iCount);
+
+	if (iCount != sizeof(mStateChecksum)/sizeof(mStateChecksum[0]))
+	{
+		// we have some kind of internal system representation change: throw for now
+		THROW_EXCEPTION(CommonException, Internal)
+	}
+
+	for (int v = 0; v < iCount; v++)
+	{
+		// Load each checksum entry
+		rArchive.Read(mStateChecksum[v]);
+	}
+
+	//
+	//
+	//
+	iCount = 0;
+	rArchive.Read(iCount);
+
+	if (iCount > 0)
+	{
+		// load each pending entry
+		mpPendingEntries = new std::map<std::string, box_time_t>;
+		if (!mpPendingEntries)
+		{
+			throw std::bad_alloc();
+		}
+
+		for (int v = 0; v < iCount; v++)
+		{
+			std::string strItem;
+			box_time_t btItem;
+
+			rArchive.Read(strItem);
+			rArchive.Read(btItem);
+			(*mpPendingEntries)[strItem] = btItem;
+		}
+	}
+
+	//
+	//
+	//
+	iCount = 0;
+	rArchive.Read(iCount);
+
+	if (iCount > 0)
+	{
+		for (int v = 0; v < iCount; v++)
+		{
+			std::string strItem;
+			rArchive.Read(strItem);
+
+			BackupClientDirectoryRecord* pSubDirRecord = 
+				new BackupClientDirectoryRecord(0, ""); 
+			// will be deserialized anyway, give it id 0 for now
+
+			if (!pSubDirRecord)
+			{
+				throw std::bad_alloc();
+			}
+
+			/***** RECURSE *****/
+			pSubDirRecord->Deserialize(rArchive);
+			mSubDirectories[strItem] = pSubDirRecord;
+		}
+	}
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupClientDirectoryRecord::Serialize(Archive & rArchive)
+//		Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void BackupClientDirectoryRecord::Serialize(Archive & rArchive) const
+{
+	//
+	//
+	//
+	rArchive.Write(mObjectID);
+	rArchive.Write(mSubDirName);
+	rArchive.Write(mInitialSyncDone);
+	rArchive.Write(mSyncDone);
+
+	//
+	//
+	//
+	int64_t iCount = 0;
+
+	// when reading back the archive, we will 
+	// need to know how many items there are.
+	iCount = sizeof(mStateChecksum) / sizeof(mStateChecksum[0]);
+	rArchive.Write(iCount); 
+
+	for (int v = 0; v < iCount; v++)
+	{
+		rArchive.Write(mStateChecksum[v]);
+	}
+
+	//
+	//
+	//
+	if (!mpPendingEntries)
+	{
+		iCount = 0;
+		rArchive.Write(iCount);
+	}
+	else
+	{
+		iCount = mpPendingEntries->size();
+		rArchive.Write(iCount);
+
+		for (std::map<std::string, box_time_t>::const_iterator
+			i =  mpPendingEntries->begin(); 
+			i != mpPendingEntries->end(); i++)
+		{
+			rArchive.Write(i->first);
+			rArchive.Write(i->second);
+		}
+	}
+	//
+	//
+	//
+	iCount = mSubDirectories.size();
+	rArchive.Write(iCount);
+
+	for (std::map<std::string, BackupClientDirectoryRecord*>::const_iterator
+		i =  mSubDirectories.begin(); 
+		i != mSubDirectories.end(); i++)
+	{
+		const BackupClientDirectoryRecord* pSubItem = i->second;
+		ASSERT(pSubItem);
+
+		rArchive.Write(i->first);
+		pSubItem->Serialize(rArchive);
+	}
+}

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientDirectoryRecord.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -18,6 +18,7 @@
 #include "BackupStoreDirectory.h"
 #include "MD5Digest.h"
 
+class Archive;
 class BackupClientContext;
 class BackupDaemon;
 
@@ -34,6 +35,9 @@
 public:
 	BackupClientDirectoryRecord(int64_t ObjectID, const std::string &rSubDirName);
 	~BackupClientDirectoryRecord();
+
+	void Deserialize(Archive & rArchive);
+	void Serialize(Archive & rArchive) const;
 private:
 	BackupClientDirectoryRecord(const BackupClientDirectoryRecord &);
 public:

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientInodeToIDMap.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientInodeToIDMap.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupClientInodeToIDMap.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -14,7 +14,7 @@
 	#include <sys/types.h>
 	#include <fcntl.h>
 	#include <limits.h>
-	#include DB_HEADER
+	#include <db.h>
 	#include <sys/stat.h>
 #endif
 
@@ -65,7 +65,7 @@
 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION
 	if(dbp != 0)
 	{
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 		dbp->close(0);
 #else
 		dbp->close(dbp);
@@ -94,7 +94,7 @@
 	ASSERT(!mEmpty);
 	
 	// Open the database file
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 	dbp = new Db(0,0);
 	dbp->set_pagesize(1024);		/* Page size: 1K. */
 	dbp->set_cachesize(0, 32 * 1024, 0);
@@ -146,7 +146,7 @@
 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION
 	if(dbp != 0)
 	{
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 		if(dbp->close(0) != 0)
 #else
 		if(dbp->close(dbp) != 0)
@@ -188,7 +188,7 @@
 	rec.mObjectID = ObjectID;
 	rec.mInDirectory = InDirectory;
 
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 	Dbt key(&InodeRef, sizeof(InodeRef));
 	Dbt data(&rec, sizeof(rec));
 
@@ -250,7 +250,7 @@
 		THROW_EXCEPTION(BackupStoreException, InodeMapNotOpen);
 	}
 
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 	Dbt key(&InodeRef, sizeof(InodeRef));
 	Dbt data(0, 0);
 	switch(dbp->get(NULL, &key, &data, 0))
@@ -280,7 +280,7 @@
 	}
 
 	// Check for sensible return
-#ifdef BERKELY_V4
+#if BDB_VERSION_MAJOR >= 3
 	if(key.get_data() == 0 || data.get_size() != sizeof(IDBRecord))
 	{
 		// Assert in debug version

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -10,15 +10,21 @@
 #include "Box.h"
 
 #include <stdio.h>
+#include <string.h>
 
 #ifdef HAVE_UNISTD_H
 	#include <unistd.h>
 #endif
-
-#ifndef WIN32
+#ifdef HAVE_SIGNAL_H
 	#include <signal.h>
+#endif
+#ifdef HAVE_SYSLOG_H
 	#include <syslog.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
 	#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
 	#include <sys/wait.h>
 #endif
 #ifdef HAVE_SYS_MOUNT_H
@@ -67,6 +73,7 @@
 #include "LocalProcessStream.h"
 #include "IOStreamGetLine.h"
 #include "Conversion.h"
+#include "Archive.h"
 
 #include "MemLeakFindOn.h"
 
@@ -450,11 +457,15 @@
 	// Set up the keys for various things
 	BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str());
 
-	// Set maximum diffing time?
+	// max diffing time, keep-alive time
 	if(conf.KeyExists("MaximumDiffingTime"))
 	{
-		BackupStoreFile::SetMaximumDiffingTime(conf.GetKeyValueInt("MaximumDiffingTime"));
+		BackupClientContext::SetMaximumDiffingTime(conf.GetKeyValueInt("MaximumDiffingTime"));
 	}
+	if(conf.KeyExists("KeepAliveTime"))
+	{
+		BackupClientContext::SetKeepAliveTime(conf.GetKeyValueInt("KeepAliveTime"));
+	}
 
 	// Setup various timings
 	
@@ -478,10 +489,18 @@
 	// When the last sync started (only updated if the store was not full when the sync ended)
 	box_time_t lastSyncTime = 0;
 
+ 	// --------------------------------------------------------------------------------------------
+ 
+	// And what's the current client store marker?
+	int64_t clientStoreMarker = 
+		BackupClientContext::ClientStoreMarker_NotKnown;
+	// haven't contacted the store yet
+
+ 	DeserializeStoreObjectInfo(clientStoreMarker, lastSyncTime, 
+		nextSyncTime);
+ 
 	// --------------------------------------------------------------------------------------------
 	
-	// And what's the current client store marker?
-	int64_t clientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown;		// haven't contacted the store yet
 
 	// Set state
 	SetState(State_Idle);
@@ -685,6 +704,13 @@
 
 				// Log
 				::syslog(LOG_INFO, "Finished scan of local files");
+
+				// --------------------------------------------------------------------------------------------
+
+				// We had a successful backup, save the store info
+				SerializeStoreObjectInfo(clientStoreMarker, lastSyncTime, nextSyncTime);
+
+				// --------------------------------------------------------------------------------------------
 			}
 			catch(BoxException &e)
 			{
@@ -900,7 +926,7 @@
 			{
 #ifdef PLATFORM_CANNOT_FIND_PEER_UID_OF_UNIX_SOCKET
 				bool uidOK = true;
-				::syslog(LOG_ERR, "On this platform, no security check can be made on the credientials of peers connecting to the command socket. (bbackupctl)");
+				::syslog(LOG_WARNING, "On this platform, no security check can be made on the credientials of peers connecting to the command socket. (bbackupctl)");
 #else
 				// Security check -- does the process connecting to this socket have
 				// the same UID as this process?
@@ -1845,7 +1871,19 @@
 	mUnusedRootDirEntries.clear();
 }
 
+// --------------------------------------------------------------------------
 
+typedef struct
+{
+	int32_t mMagicValue;	// also the version number
+	int32_t mNumEntries;
+	int64_t mObjectID;		// this object ID
+	int64_t mContainerID;	// ID of container
+	uint64_t mAttributesModTime;
+	int32_t mOptionsPresent;	// bit mask of optional sections / features present
+
+} loc_StreamFormat;
+
 // --------------------------------------------------------------------------
 //
 // Function
@@ -1884,10 +1922,181 @@
 	}
 }
 
+// --------------------------------------------------------------------------
+//
+// 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(CommonException, Internal)
+	}
+
+	//
+	//
+	//
+	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(CommonException, Internal)
+	}
+
+	//
+	//
+	//
+	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(CommonException, Internal)
+	}
+}
+
 // --------------------------------------------------------------------------
 //
 // 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
@@ -1926,3 +2135,249 @@
 		mpGetLine = 0;
 	}
 }
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime)
+//		Purpose: Serializes remote directory and file information into a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+
+static const int STOREOBJECTINFO_MAGIC_ID_VALUE = 0x7777525F;
+static const std::string STOREOBJECTINFO_MAGIC_ID_STRING = "BBACKUPD-STATE";
+static const int STOREOBJECTINFO_VERSION = 1;
+
+void BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const
+{
+	if(!GetConfiguration().KeyExists("StoreObjectInfoFile"))
+	{
+		return;
+	}
+
+	std::string StoreObjectInfoFile = 
+		GetConfiguration().GetKeyValue("StoreObjectInfoFile");
+
+	if (StoreObjectInfoFile.size() <= 0)
+	{
+		return;
+	}
+
+	try
+	{
+		FileStream aFile(StoreObjectInfoFile.c_str(), 
+			O_WRONLY | O_CREAT | O_TRUNC);
+		Archive anArchive(aFile, 0);
+
+		anArchive.Write(STOREOBJECTINFO_MAGIC_ID_VALUE);
+		anArchive.Write(STOREOBJECTINFO_MAGIC_ID_STRING); 
+		anArchive.Write(STOREOBJECTINFO_VERSION);
+		anArchive.Write(GetLoadedConfigModifiedTime());
+		anArchive.Write(aClientStoreMarker);
+		anArchive.Write(theLastSyncTime);
+		anArchive.Write(theNextSyncTime);
+
+		//
+		//
+		//
+		int64_t iCount = mLocations.size();
+		anArchive.Write(iCount);
+
+		for (int v = 0; v < iCount; v++)
+		{
+			ASSERT(mLocations[v]);
+			mLocations[v]->Serialize(anArchive);
+		}
+
+		//
+		//
+		//
+		iCount = mIDMapMounts.size();
+		anArchive.Write(iCount);
+
+		for (int v = 0; v < iCount; v++)
+			anArchive.Write(mIDMapMounts[v]);
+
+		//
+		//
+		//
+		aFile.Close();
+		::syslog(LOG_INFO, "Saved store object info file '%s'", 
+			StoreObjectInfoFile.c_str());
+	}
+	catch (...)
+	{
+		::syslog(LOG_WARNING, "Requested store object info file '%s' "
+			"not accessible or could not be created", 
+			StoreObjectInfoFile.c_str());
+	}
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime)
+//		Purpose: Deserializes remote directory and file information from a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime)
+{
+	//
+	//
+	//
+	DeleteAllLocations();
+
+	//
+	//
+	//
+	if(!GetConfiguration().KeyExists("StoreObjectInfoFile"))
+	{
+		return;
+	}
+
+	std::string StoreObjectInfoFile = 
+		GetConfiguration().GetKeyValue("StoreObjectInfoFile");
+
+	if (StoreObjectInfoFile.size() <= 0)
+	{
+		return;
+	}
+
+	try
+	{
+		FileStream aFile(StoreObjectInfoFile.c_str(), O_RDONLY);
+		Archive anArchive(aFile, 0);
+
+		//
+		// see if the content looks like a valid serialised archive
+		//
+		int iMagicValue = 0;
+		anArchive.Read(iMagicValue);
+
+		if (iMagicValue != STOREOBJECTINFO_MAGIC_ID_VALUE)
+		{
+			::syslog(LOG_WARNING, "Store object info file '%s' "
+				"is not a valid or compatible serialised "
+				"archive. Will re-cache from store.", 
+				StoreObjectInfoFile.c_str());
+			return;
+		}
+
+		//
+		// get a bit optimistic and read in a string identifier
+		//
+		std::string strMagicValue;
+		anArchive.Read(strMagicValue);
+
+		if (strMagicValue != STOREOBJECTINFO_MAGIC_ID_STRING)
+		{
+			::syslog(LOG_WARNING, "Store object info file '%s' "
+				"is not a valid or compatible serialised "
+				"archive. Will re-cache from store.", 
+				StoreObjectInfoFile.c_str());
+			return;
+		}
+
+		//
+		// check if we are loading some future format
+		// version by mistake
+		//
+		int iVersion = 0;
+		anArchive.Read(iVersion);
+
+		if (iVersion != STOREOBJECTINFO_VERSION)
+		{
+			::syslog(LOG_WARNING, "Store object info file '%s' "
+				"version [%d] unsupported. "
+				"Will re-cache from store.", 
+				StoreObjectInfoFile.c_str(), 
+				iVersion);
+			return;
+		}
+
+		//
+		// check if this state file is even valid 
+		// for the loaded bbackupd.conf file
+		//
+		box_time_t lastKnownConfigModTime;
+		anArchive.Read(lastKnownConfigModTime);
+
+		if (lastKnownConfigModTime != GetLoadedConfigModifiedTime())
+		{
+			::syslog(LOG_WARNING, "Store object info file '%s' "
+				"out of date. Will re-cache from store", 
+				StoreObjectInfoFile.c_str());
+			return;
+		}
+
+		//
+		// this is it, go at it
+		//
+		anArchive.Read(aClientStoreMarker);
+		anArchive.Read(theLastSyncTime);
+		anArchive.Read(theNextSyncTime);
+
+		//
+		//
+		//
+		int64_t iCount = 0;
+		anArchive.Read(iCount);
+
+		for (int v = 0; v < iCount; v++)
+		{
+			Location* pLocation = new Location;
+			if (!pLocation)
+				throw std::bad_alloc();
+
+			pLocation->Deserialize(anArchive);
+			mLocations.push_back(pLocation);
+		}
+
+		//
+		//
+		//
+		iCount = 0;
+		anArchive.Read(iCount);
+
+		for (int v = 0; v < iCount; v++)
+		{
+			std::string strItem;
+			anArchive.Read(strItem);
+
+			mIDMapMounts.push_back(strItem);
+		}
+
+		//
+		//
+		//
+		aFile.Close();
+		::syslog(LOG_INFO, "Loaded store object info file '%s', "
+			"version [%d]", StoreObjectInfoFile.c_str(), 
+			iVersion);
+
+		if (::unlink(StoreObjectInfoFile.c_str()) != 0)
+		{
+			::syslog(LOG_ERR, "Failed to delete the old "
+				"store object info file '%s': %s",
+				StoreObjectInfoFile.c_str(), strerror(errno));
+		}
+	}
+	catch (...)
+	{
+		DeleteAllLocations();
+
+		aClientStoreMarker = 
+			BackupClientContext::ClientStoreMarker_NotKnown;
+		theLastSyncTime = 0;
+		theNextSyncTime = 0;
+
+		::syslog(LOG_WARNING, "Requested store object info file '%s' "
+			"does not exist, not accessible, or inconsistent. "
+			"Will re-cache from store.", 
+			StoreObjectInfoFile.c_str());
+	}
+}

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/BackupDaemon.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -14,12 +14,14 @@
 #include <string>
 #include <memory>
 
+#include "BoxTime.h"
 #include "Daemon.h"
-#include "BoxTime.h"
 #include "Socket.h"
 #include "SocketListen.h"
 #include "SocketStream.h"
-#include "WinNamedPipeStream.h"
+#ifdef WIN32
+	#include "WinNamedPipeStream.h"
+#endif
 
 class BackupClientDirectoryRecord;
 class BackupClientContext;
@@ -27,6 +29,7 @@
 class BackupClientInodeToIDMap;
 class ExcludeList;
 class IOStreamGetLine;
+class Archive;
 
 // --------------------------------------------------------------------------
 //
@@ -41,6 +44,10 @@
 public:
 	BackupDaemon();
 	~BackupDaemon();
+
+	// methods below do partial (specialized) serialization of client state only
+	void SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const;
+	void DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime);
 private:
 	BackupDaemon(const BackupDaemon &);
 public:
@@ -117,6 +124,9 @@
 	public:
 		Location();
 		~Location();
+
+		void Deserialize(Archive & rArchive);
+		void Serialize(Archive & rArchive) const;
 	private:
 		Location(const Location &);	// copy not allowed
 		Location &operator=(const Location &);

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupd/bbackupd-config
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupd/bbackupd-config	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupd/bbackupd-config	2006-02-03 20:21:10 UTC (rev 365)
@@ -382,7 +382,15 @@
 
 CommandSocket = /var/run/bbackupd.sock
 
+# Uncomment the StoreObjectInfoFile to enable the experimental archiving
+# of the daemon's state (including client store marker and configuration)
+# between backup runs. This saves time and increases efficiency when
+# bbackupd is frequently stopped and started, since it removes the need
+# to rescan all directories on the remote server. However, it is new and
+# not yet heavily tested, so use with caution.
 
+# StoreObjectInfoFile = $working_dir/bbackupd.state
+
 Server
 {
 	PidFile = /var/run/bbackupd.pid

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/BackupQueries.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -785,7 +785,9 @@
 	// Check args
 	if(args.size() < 1 || (opts['i'] && args.size() != 2) || args.size() > 2)
 	{
-		printf("Incorrect usage.\ngetobject <object-id> <local-filename>\n or get -i <object-id> <local-filename>\n");
+		printf("Incorrect usage.\n"
+			"get <remote-filename> [<local-filename>] or\n"
+			"get -i <object-id> <local-filename>\n");
 		return;
 	}
 

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/bbackupquery.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/bbackupquery.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbackupquery/bbackupquery.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -17,6 +17,8 @@
 #ifdef HAVE_LIBREADLINE
 	#ifdef HAVE_READLINE_READLINE_H
 		#include <readline/readline.h>
+	#elif defined(HAVE_EDITLINE_READLINE_H)
+		#include <editline/readline.h>
 	#elif defined(HAVE_READLINE_H)
 		#include <readline.h>
 	#endif

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbstored/BackupCommands.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbstored/BackupCommands.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbstored/BackupCommands.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -859,3 +859,20 @@
 	));
 }
 
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &, BackupContext &)
+//		Purpose: Return the amount of disc space used
+//		Created: 19/4/04
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<ProtocolObject> BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &rProtocol, BackupContext &rContext)
+{
+	CHECK_PHASE(Phase_Commands)
+
+	//
+	// NOOP
+	//
+	return std::auto_ptr<ProtocolObject>(new BackupProtocolServerIsAlive());
+}

Modified: box/chris/win32/vc2005-compile-fixes/bin/bbstored/backupprotocol.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/bin/bbstored/backupprotocol.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/bin/bbstored/backupprotocol.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -219,3 +219,10 @@
 	int64	BlocksSoftLimit
 	int64	BlocksHardLimit
 	int32	BlockSize
+
+GetIsAlive	42	Command(IsAlive)
+	# no data members
+
+IsAlive	43	Reply
+	# no data members
+

Modified: box/chris/win32/vc2005-compile-fixes/configure.ac
===================================================================
--- box/chris/win32/vc2005-compile-fixes/configure.ac	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/configure.ac	2006-02-03 20:21:10 UTC (rev 365)
@@ -4,11 +4,10 @@
 AC_PREREQ(2.59)
 AC_INIT([Box Backup], 0.09, [box at fluffy.co.uk])
 AC_CONFIG_SRCDIR([lib/common/Box.h])
-AC_CONFIG_HEADERS([lib/common/config.h])
+AC_CONFIG_HEADERS([lib/common/BoxConfig.h])
 
 touch install-sh
 AC_CANONICAL_SYSTEM
-# echo "Build target OS: '$target_os'"
 test -s install-sh || rm install-sh
 
 ### Checks for programs.
@@ -30,19 +29,31 @@
 
 
 ### Checks for libraries.
+
 if test "$target_os" != "mingw32" -a "$target_os" != "winnt"; then
-AC_SEARCH_LIBS([nanosleep], [rt], [ac_have_nanosleep=yes], 
-	[AC_MSG_ERROR([[Cannot find a short sleep function (nanosleep)]])])
+  AC_SEARCH_LIBS([nanosleep], [rt], [ac_have_nanosleep=yes],
+                 [AC_MSG_ERROR([[cannot find a short sleep function (nanosleep)]])])
 fi
+AC_CHECK_LIB([z], [zlibVersion],, [AC_MSG_ERROR([[cannot find zlib]])])
+VL_LIB_READLINE([have_libreadline=yes], [have_libreadline=no])
 
-AC_CHECK_LIB([z], [zlibVersion],, [AC_MSG_ERROR([[Cannot find zlib]])])
-AX_CHECK_BDB_V1
-VL_LIB_READLINE
-have_libreadline=no
-test "x$vl_cv_lib_readline" != "xno" && have_libreadline=yes
+## Check for Berkely DB. Restrict to certain versions
+AX_PATH_BDB(, [
+  LIBS="$BDB_LIBS $LIBS"
+  LDFLAGS="$BDB_LDFLAGS $LDFLAGS"
+  CPPFLAGS="$CPPFLAGS $BDB_CPPFLAGS"
 
+  AX_COMPARE_VERSION([$BDB_VERSION],[ge],[4.1],,
+    [AX_COMPARE_VERSION([$BDB_VERSION],[lt],[2],,
+      [AC_MSG_ERROR([[only Berkely DB versions 1.x or at least 4.1 are currently supported]])]
+      )]
+  )
+  AX_SPLIT_VERSION([BDB_VERSION], [$BDB_VERSION])
+])
 
 ## Check for Open SSL, use old versions only if explicitly requested
+AC_SEARCH_LIBS([gethostbyname], [nsl socket resolv])
+AC_SEARCH_LIBS([shutdown], [nsl socket resolv])
 AX_CHECK_SSL(, [AC_MSG_ERROR([[OpenSSL is not installed but is required]])])
 AC_ARG_ENABLE(
   [old-ssl],
@@ -65,7 +76,11 @@
 AC_HEADER_DIRENT
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([execinfo.h netinet/in.h regex.h sys/types.h sys/xattr.h pwd.h process.h sys/socket.h dirent.h])
+AC_CHECK_HEADERS([dirent.h execinfo.h process.h pwd.h regex.h signal.h]
+AC_CHECK_HEADERS([syslog.h time.h])
+AC_CHECK_HEADERS([netinet/in.h])
+AC_CHECK_HEADERS([sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h])
+AC_CHECK_HEADERS([sys/xattr.h])
 
 
 ### Checks for typedefs, structures, and compiler characteristics.
@@ -95,12 +110,17 @@
 AC_SYS_LARGEFILE
 AX_CHECK_LLONG_MINMAX
 AX_CHECK_DEFINE_PRAGMA
-
+if test "x$ac_cv_c_bigendian" != "xyes"; then
+  AX_BSWAP64
+fi
 if test "$target_os" != "mingw32"; then
-AX_RANDOM_DEVICE
+  AX_RANDOM_DEVICE
 fi
-
-AX_CHECK_MOUNT_POINT([],[])
+AX_CHECK_MOUNT_POINT(,[
+  if test "$target_os" != "mingw32" -a "$target_os" != "winnt"; then
+    AC_MSG_ERROR([[cannot work out how to discover mount points on your platform]])
+  fi
+  ])
 AX_CHECK_MALLOC_WORKAROUND
 
 
@@ -113,27 +133,32 @@
 AC_CHECK_FUNCS([getpeereid kqueue lchown setproctitle getpid])
 AX_FUNC_SYSCALL
 AX_CHECK_SYSCALL_LSEEK
+AC_CHECK_FUNCS([listxattr llistxattr getxattr lgetxattr setxattr lsetxattr])
+AC_CHECK_DECLS([XATTR_NOFOLLOW],,, [[#include <sys/xattr.h>]])
 
 
 ### Miscellaneous complicated feature checks
 
 ## Check for large file support active. AC_SYS_LARGEFILE has already worked
-## out how to enable it if necessary, we need to know if we've got it so we
-## can disable the raidfile intercepts
+## out how to enable it if necessary, we just use this to report to the user
 AC_CACHE_CHECK([if we have large file support enabled], [have_large_file_support],
   [AC_RUN_IFELSE([AC_LANG_PROGRAM([[$ac_includes_default]], [[
       return sizeof(off_t)==4;
     ]])],
     [have_large_file_support=yes], [have_large_file_support=no]
   )])
-if test "x$have_large_file_support" = "xyes"; then
-  AC_DEFINE([HAVE_LARGE_FILE_SUPPORT], 1, [Define to 1 large file support is in use])
-fi
 
 ## Find out how to do file locking
 AC_CHECK_FUNCS([flock])
 AC_CHECK_DECLS([O_EXLOCK],,, [[#include <fcntl.h>]])
 AC_CHECK_DECLS([F_SETLK],,, [[#include <fcntl.h>]])
+if test "x$ac_cv_func_flock" != "xyes" && \
+   test "x$ac_cv_have_decl_O_EXLOCK" != "xyes" && \
+   test "x$ac_cv_have_decl_F_SETLK" != "xyes" && \
+   test "$target_os" != "mingw32" -a "$target_os" != "winnt"
+then
+  AC_MSG_ERROR([[cannot work out how to do file locking on your platform]])
+fi
 
 ## Get tmpdir
 temp_directory_name="/tmp"
@@ -148,7 +173,7 @@
   [static-bin],
   [AC_HELP_STRING([--enable-static-bin], [Link binaries with static libraries])])
 if test "x$enable_static_bin" = "xyes"; then
-  AC_CHECK_LIB([ssl],[SSL_read],[],[],[crypto])
+  AC_CHECK_LIB([ssl],[SSL_read],,, [crypto])
   LIBS="-Wl,-Bstatic $LIBS -Wl,-Bdynamic"
 fi
 
@@ -169,7 +194,7 @@
 to the documentation for more information on each feature.
 
 Large files:         $have_large_file_support
-Berkeley DB:         $ac_have_bdb
+Berkeley DB:         $ax_path_bdb_ok
 Readline:            $have_libreadline
 Extended attributes: $ac_cv_header_sys_xattr_h
 EOC
@@ -191,12 +216,7 @@
   *readline*)
     echo
     AC_MSG_WARN([[do not distribute binaries compiled against GNU readline,
-as this would violate the GNU readline licence, which is GPL. You may use
+as this could violate the GNU readline licence, which is GPL. You may use
 libedit or libeditline instead.]])
     ;;
 esac
-
-if test "x$ac_have_bdb" != "xyes"; then
-  echo
-  AC_MSG_WARN([[db is not installed -- will run in reduced efficiency mode without it]])
-fi

Modified: box/chris/win32/vc2005-compile-fixes/distribution/COMMON-MANIFEST.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/COMMON-MANIFEST.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/COMMON-MANIFEST.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,3 +1,4 @@
+RUN ./bootstrap
 lib/common
 lib/crypto
 lib/server
@@ -2,2 +3,3 @@
 lib/compress
+lib/win32
 test/common
@@ -8,6 +10,7 @@
 test/basicserver/testfiles
 test/crypto
 test/compress
+test/win32
 docs/common notes
 docs/common/lib_common notes/lib_common
 docs/common/lib_crypto notes/lib_crypto
@@ -15,10 +18,16 @@
 MKDIR infrastructure
 infrastructure/buildenv-testmain-template.cpp
 infrastructure/makebuildenv.pl
-infrastructure/BoxPlatform.pm
+infrastructure/BoxPlatform.pm.in
 infrastructure/makeparcels.pl
-MKDIR infrastructure/tests
-infrastructure/tests/common_tests.pl
+configure.ac
+NO-LICENSE config.sub
+config.sub
+NO-LICENSE config.guess
+config.guess
+bootstrap
 parcels.txt
+runtest.pl
+NO-LICENSE-IN-DIR infrastructure/m4
+infrastructure/m4
 configure
-runtest.pl

Modified: box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -6,6 +6,7 @@
 bin/bbstored
 bin/bbstoreaccounts
 bin/bbackupd
+bin/bbackupd/win32
 bin/bbackupquery
 bin/bbackupctl
 bin/bbackupobjdump

Modified: box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/LICENSE.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/LICENSE.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/LICENSE.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,6 +1,6 @@
  
-Copyright (c) 2003, 2005
-     Ben Summers.  All rights reserved.
+Copyright (c) 2003 - 2006
+     Ben Summers and contributors.  All rights reserved.
  
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -11,7 +11,7 @@
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. All use of this software and associated advertising materials must 
-   display the following acknowledgement:
+   display the following acknowledgment:
        This product includes software developed by Ben Summers.
 4. The names of the Authors may not be used to endorse or promote
    products derived from this software without specific prior written

Modified: box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/THANKS.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/THANKS.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/THANKS.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,6 +1,34 @@
 
+The following developers contributed code to version 0.10:
+
+Nick Knight
+  - ported Box Backup to Windows (properly, not using Cygwin)
+ 
+Gary Niemcewicz
+  - added client/server (SSL) keepalives to keep the connection to the
+    server alive during a long diff, and saving the daemon's state across restarts
+
+Martin Ebourne
+  - ported to Solaris; wrote extended attribute support (xattr);
+    converted to use autoconf for automatic compiler configuration.
+
+Chris Wilson
+  - updated Nick's and Gary's work to fit in with the new trunk,
+    fixed some issues pointed out by Ben and Martin, made it compile
+    on Windows with the free MinGW compiler.
+
+Jonathan Morton
+  - vastly improved the performance and efficiency of the file-diffing code, and
+    obtained a free G5 PowerMac from IBM as his reward.
+
+
+----
+
 Many individuals have helped with the development of Box Backup by testing, reporting experiences, and making suggestions. In particular, thanks are due to
 
+Charles Lecklider
+  - Helped with the finer details of Win32 programming
+
 Pascal Lalonde
   - Comprehensive and accurate bug reports, and constructive feedback
 
@@ -17,6 +45,7 @@
 
 Per Thomsen
   - Cygwin Windows service install scripts and build notes
+  - Answering queries on the boxbackup mailing list
 
 Tim Fletcher
 David Harris
@@ -35,3 +64,6 @@
 John Pybus
   - Ideas and feature requests
   - Useful little patches to code
+
+Stefan Norlin
+  - Help with testing and fixes on lots of different Solaris platforms

Modified: box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/VERSION.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/VERSION.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/VERSION.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,2 +1,2 @@
-0.08
+0.09_plus2
 boxbackup

Modified: box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/contrib/rpm/boxbackup.spec
===================================================================
--- box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/contrib/rpm/boxbackup.spec	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/distribution/boxbackup/contrib/rpm/boxbackup.spec	2006-02-03 20:21:10 UTC (rev 365)
@@ -3,7 +3,7 @@
 
 # Detect distribution. So far we only special-case SUSE. If you need to make
 # any distro specific changes to get the package building on your system
-# please email them to martin at zepler.org
+# please email them to boxbackup-dev at fluffy.co.uk
 #%define is_fc   %(test -e %{_sysconfdir}/fedora-release && echo 1 || echo 0)
 #%define is_mdk  %(test -e %{_sysconfdir}/mandrake-release && echo 1 || echo 0)
 #%define is_rh   %(test -e %{_sysconfdir}/redhat-release && echo 1 || echo 0)
@@ -25,7 +25,7 @@
 Release: 1
 License: BSD
 Group: Applications/Archiving
-Packager: Martin Ebourne <martin at zepler.org>
+Packager: Martin Ebourne <boxbackup-dev at fluffy.co.uk>
 URL: http://www.fluffy.co.uk/boxbackup/
 Source0: %{ident}.tgz
 Requires: openssl >= 0.9.7a
@@ -72,7 +72,8 @@
 %setup -q
 
 %build
-./configure
+test -e configure || ./bootstrap
+%configure
 
 make
 
@@ -194,6 +195,9 @@
 %{_sbindir}/raidfile-config
 
 %changelog
+* Wed Dec 28 2005 Martin Ebourne <martin at zepler.org>
+- Box now uses autoconf so use configure macro
+
 * Fri Oct  1 2004 Martin Ebourne <martin at zepler.org> - 0.08-3
 - Moved most of the exes to /usr/sbin
 - SUSE updates from Chris Smith

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/BoxPlatform.pm.in
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/BoxPlatform.pm.in	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/BoxPlatform.pm.in	2006-02-03 20:21:10 UTC (rev 365)
@@ -21,6 +21,7 @@
 
 	# blank extra flags by default
 	$platform_compile_line_extra = '@CPPFLAGS@ @CXXFLAGS@ @CXXFLAGS_STRICT@';
+	$platform_compile_line_extra =~ s/ -O2//;
 	$platform_link_line_extra = '@LDFLAGS@';
 	$platform_lib_files = '@LIBS@';
 	$target_os = '@target_os@';
@@ -51,7 +52,7 @@
 		# test for fink installation
 		if(-d '/sw/include' && -d '/sw/lib')
 		{
-			print "Fink installation detected, will use headers and libraries\n";
+			print "Fink installation detected, will use headers and libraries\n\n\n";
 			$platform_compile_line_extra = '-I/sw/include ';
 			$platform_link_line_extra = '-L/sw/lib ';
 		}

Copied: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_bswap64.m4 (from rev 364, box/trunk/infrastructure/m4/ax_bswap64.m4)

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_check_mount_point.m4
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_check_mount_point.m4	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_check_mount_point.m4	2006-02-03 20:21:10 UTC (rev 365)
@@ -19,10 +19,18 @@
 
 AC_DEFUN([AX_CHECK_MOUNT_POINT], [
   AC_CHECK_FUNCS([getmntent statfs])
-  AC_CHECK_HEADERS([mntent.h sys/mnttab.h sys/mount.h],,, [[#include <stdio.h>]])
+  AC_CHECK_HEADERS([sys/param.h])
+  AC_CHECK_HEADERS([mntent.h sys/mnttab.h sys/mount.h],,, [[
+    #include <stdio.h>
+    #ifdef HAVE_SYS_PARAM_H
+      #include <sys/param.h>
+    #endif
+    ]])
   # BSD
   AC_CHECK_MEMBERS([struct statfs.f_mntonname],,, [[
-    #include <sys/param.h>
+    #ifdef HAVE_SYS_PARAM_H
+      #include <sys/param.h>
+    #endif
     #include <sys/mount.h>
     ]])
   # Linux

Copied: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_compare_version.m4 (from rev 364, box/trunk/infrastructure/m4/ax_compare_version.m4)

Copied: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_path_bdb.m4 (from rev 364, box/trunk/infrastructure/m4/ax_path_bdb.m4)

Copied: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/ax_split_version.m4 (from rev 364, box/trunk/infrastructure/m4/ax_split_version.m4)

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/m4/vl_lib_readline.m4
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/m4/vl_lib_readline.m4	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/m4/vl_lib_readline.m4	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,4 +1,4 @@
-dnl @synopsis VL_LIB_READLINE
+dnl @synopsis VL_LIB_READLINE([ACTION-IF-TRUE], [ACTION-IF-FALSE])
 dnl
 dnl Searches for a readline compatible library. If found, defines
 dnl `HAVE_LIBREADLINE'. If the found library has the `add_history'
@@ -46,6 +46,8 @@
 dnl Modifications to add --enable-gnu-readline to work around licensing
 dnl problems between the traditional BSD licence and the GPL.
 dnl Martin Ebourne, 2005/7/11
+dnl Rewrite to match headers with libraries and be more selective.
+dnl Martin Ebourne, 2006/1/4
 dnl
 dnl @category InstalledPackages
 dnl @author Ville Laurikari <vl at iki.fi>
@@ -56,16 +58,34 @@
   AC_ARG_ENABLE(
     [gnu-readline],
     AC_HELP_STRING([--enable-gnu-readline],
-                   [Allow use of GNU readline (may violate GNU licence)])
+                   [Use GNU readline if present (may violate GNU licence)])
   )
-  vl_gnu_readline_lib=""
+  vl_cv_lib_readline_compat_found=no
   if test "x$enable_gnu_readline" = "xyes"; then
-    vl_gnu_readline_lib=readline
+    VL_LIB_READLINE_CHECK([readline],
+                          [readline],
+                          [readline/readline.h readline.h],
+                          [readline/history.h history.h])
   fi
-  AC_CACHE_CHECK([for a readline compatible library],
-                 vl_cv_lib_readline, [
+  if test "x$vl_cv_lib_readline_compat_found" = "xno"; then
+    VL_LIB_READLINE_CHECK([editline],
+                          [edit editline],
+	  		  [editline/readline.h],
+			  [editline/readline.h])
+  fi
+  if test "x$vl_cv_lib_readline_compat_found" = "xyes"; then
+    m4_ifvaln([$1],[$1],[:])dnl
+    m4_ifvaln([$2],[else $2])dnl
+  fi
+])
+
+dnl VL_LIB_READLINE_CHECK(name, libraries, headers, history headers)
+AC_DEFUN([VL_LIB_READLINE_CHECK], [
+  AC_CACHE_CHECK([for $1 library],
+                 [vl_cv_lib_$1], [
     ORIG_LIBS="$LIBS"
-    for readline_lib in edit editline $vl_gnu_readline_lib; do
+    vl_cv_lib_$1=""
+    for readline_lib in $2; do
       for termcap_lib in "" termcap curses ncurses; do
         if test -z "$termcap_lib"; then
           TRY_LIB="-l$readline_lib"
@@ -73,34 +93,43 @@
           TRY_LIB="-l$readline_lib -l$termcap_lib"
         fi
         LIBS="$ORIG_LIBS $TRY_LIB"
-        AC_TRY_LINK_FUNC(readline, vl_cv_lib_readline="$TRY_LIB")
-        if test -n "$vl_cv_lib_readline"; then
+        AC_TRY_LINK_FUNC([readline], [vl_cv_lib_$1="$TRY_LIB"])
+        if test -n "$vl_cv_lib_$1"; then
           break
         fi
       done
-      if test -n "$vl_cv_lib_readline"; then
+      if test -n "$vl_cv_lib_$1"; then
         break
       fi
     done
-    if test -z "$vl_cv_lib_readline"; then
-      vl_cv_lib_readline="no"
+    if test -z "$vl_cv_lib_$1"; then
+      vl_cv_lib_$1=no
       LIBS="$ORIG_LIBS"
     fi
   ])
 
-  if test "x$vl_cv_lib_readline" != "xno"; then
-    AC_DEFINE(HAVE_LIBREADLINE, 1,
+  vl_cv_lib_readline_compat_found=no
+  if test "x$vl_cv_lib_$1" != "xno"; then
+    AC_CHECK_HEADERS([$3], [vl_cv_lib_readline_compat_found=yes])
+  fi
+
+  if test "x$vl_cv_lib_readline_compat_found" = "xyes"; then
+    AC_DEFINE([HAVE_LIBREADLINE], 1,
               [Define if you have a readline compatible library])
-    AC_CHECK_HEADERS(readline.h readline/readline.h)
-    AC_CACHE_CHECK([whether readline supports history],
-                   vl_cv_lib_readline_history, [
-      vl_cv_lib_readline_history="no"
-      AC_TRY_LINK_FUNC(add_history, vl_cv_lib_readline_history="yes")
+
+    AC_CACHE_CHECK([whether $1 supports history],
+                   [vl_cv_lib_$1_history], [
+      vl_cv_lib_$1_history=no
+      AC_TRY_LINK_FUNC([add_history], [vl_cv_lib_$1_history=yes])
     ])
-    if test "x$vl_cv_lib_readline_history" = "xyes"; then
-      AC_DEFINE(HAVE_READLINE_HISTORY, 1,
-                [Define if your readline library has \`add_history'])
-      AC_CHECK_HEADERS(history.h readline/history.h)
+    if test "x$vl_cv_lib_$1_history" = "xyes"; then
+      vl_cv_lib_$1_history=no
+      AC_CHECK_HEADERS(
+        [$4],
+	[AC_DEFINE([HAVE_READLINE_HISTORY], [1],
+                   [Define if your readline library has add_history])])
     fi
+  else
+    LIBS="$ORIG_LIBS"
   fi
 ])dnl

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/makebuildenv.pl
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/makebuildenv.pl	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/makebuildenv.pl	2006-02-03 20:21:10 UTC (rev 365)
@@ -38,6 +38,13 @@
 # flags about the environment
 my %env_flags;
 
+my $windows_include_path = "-I../../lib/win32 ";
+if ($target_os ne "mingw32" && $target_os ne "winnt")
+{
+	$windows_include_path = "";
+	$env_flags{'IGNORE_lib/win32'} = 1;
+}
+
 # print "Flag: $_\n" for(keys %env_flags);
 
 # seed autogen code
@@ -343,8 +350,8 @@
 {
 	opendir DIR,$mod;
 	for my $h (grep /\.h\Z/i, readdir DIR)
-	{	
-		next if /\A\._/;	# Temp Mac OS Resource hack
+	{
+		next if $h =~ /\A\./;		# Ignore Mac resource forks, autosaves, etc
 
 		open FL,"$mod/$h" or die "can't open $mod/$h";
 		my $f;
@@ -447,7 +454,7 @@
 	
 
 	# make include path
-	my $include_paths = "-I../../lib/win32 " .
+	my $include_paths = $windows_include_path .
 		join(' ',map {'-I../../'.$_} @all_deps_for_module);
 
 	# is target a library?

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/makedistribution.pl
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/makedistribution.pl	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/makedistribution.pl	2006-02-03 20:21:10 UTC (rev 365)
@@ -78,6 +78,19 @@
 		{
 			replace_version_in($dst);
 		}
+		elsif($src eq 'NO-LICENSE')
+		{
+			$no_license{$dst} = 1;
+		}
+		elsif($src eq 'RUN')
+		{
+			print "Running $dst...\n";
+			if(system($dst) != 0)
+			{
+				print "Error running $dst. Aborting.\n";
+				exit(1);
+			}
+		}
 		elsif(-d $src)
 		{
 			$modules_included{$_} = 1;
@@ -205,8 +218,8 @@
 		}
 	}
 	
-	# make sure perl scripts are marked as executable, and other things aren't
-	if($ext eq 'pl' || $ext eq '')
+	# copy executable bit from src
+	if(-x $fn)
 	{
 		system 'chmod','a+x',"$base_name/$dst_fn"
 	}

Modified: box/chris/win32/vc2005-compile-fixes/infrastructure/makeparcels.pl
===================================================================
--- box/chris/win32/vc2005-compile-fixes/infrastructure/makeparcels.pl	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/infrastructure/makeparcels.pl	2006-02-03 20:21:10 UTC (rev 365)
@@ -104,7 +104,7 @@
 	print MAKE $target,":\n";
 	
 	my $dir = parcel_dir($parcel);
-	print MAKE "\tmkdir $dir\n";
+	print MAKE "\ttest -d $dir || mkdir $dir\n";
 	
 	open SCRIPT,">parcels/scripts/install-$parcel" or die "Can't open installer script for $parcel for writing";
 	print SCRIPT "#!/bin/sh\n\n";
@@ -169,7 +169,7 @@
 
 sub parcel_root
 {
-	$product_name.'-'.$product_version.'-'.$_[0].'-'.$build_os.$os_suffix
+	$product_name.'-'.$product_version.'-'.$_[0].'-'.$target_os.$os_suffix
 }
 
 sub parcel_dir

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupClientFileAttributes.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupClientFileAttributes.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupClientFileAttributes.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -520,18 +520,24 @@
 				int valueSizeOffset = xattrSize;
 				xattrSize += sizeof(u_int32_t);
 
-				// This gets the attribute value (may be text or binary), no termination
-				int valueSize = ::lgetxattr(Filename, attrKey.c_str(), buffer+xattrSize, xattrBufferSize-xattrSize);
+				// Find size of attribute (must call with buffer and length 0 on some platforms,
+				// as -1 is returned if the data doesn't fit.)
+				int valueSize = ::lgetxattr(Filename, attrKey.c_str(), 0, 0);
+				if(valueSize<0)
+				{
+					THROW_EXCEPTION(CommonException, OSFileError);
+				}
 
+				// Resize block, if needed
 				if(xattrSize+valueSize>xattrBufferSize)
 				{
 					xattrBufferSize = (xattrBufferSize+valueSize)*2;
 					outputBlock.ResizeBlock(xattrBufferSize);
 					buffer = static_cast<unsigned char*>(outputBlock.GetBuffer());
-
-					valueSize = ::lgetxattr(Filename, attrKey.c_str(), buffer+xattrSize, xattrBufferSize-xattrSize);
 				}
 
+				// This gets the attribute value (may be text or binary), no termination
+				valueSize = ::lgetxattr(Filename, attrKey.c_str(), buffer+xattrSize, xattrBufferSize-xattrSize);
 				if(valueSize<0)
 				{
 					THROW_EXCEPTION(CommonException, OSFileError);

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupDaemonConfigVerify.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupDaemonConfigVerify.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupDaemonConfigVerify.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -84,6 +84,8 @@
 	{"ExtendedLogging",	"no", ConfigTest_IsBool, 0},			// make value "yes" to enable in config file
 
 	{"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
 	
@@ -102,4 +104,3 @@
 	ConfigTest_Exists | ConfigTest_LastEntry,
 	0
 };
-

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreDirectory.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreDirectory.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreDirectory.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -36,7 +36,7 @@
 	// Then a StreamableMemBlock for attributes
 } dir_StreamFormat;
 
-enum
+typedef enum
 {
 	Option_DependencyInfoPresent = 1
 } dir_StreamFormatOptions;

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -1504,3 +1504,27 @@
 }
 
 
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    DiffTimer::DiffTimer();
+//		Purpose: Constructor
+//		Created: 2005/02/01
+//
+// --------------------------------------------------------------------------
+DiffTimer::DiffTimer()
+{
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    DiffTimer::DiffTimer();
+//		Purpose: Destructor
+//		Created: 2005/02/01
+//
+// --------------------------------------------------------------------------
+DiffTimer::~DiffTimer()
+{	
+}

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFile.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -38,6 +38,27 @@
 // --------------------------------------------------------------------------
 //
 // Class
+//		Name:    DiffTimer
+//		Purpose: Interface for classes that can keep track of diffing time,
+//				 and send SSL keepalive messages
+//		Created: 2006/01/19
+//
+// --------------------------------------------------------------------------
+class DiffTimer
+{
+public:
+	DiffTimer();
+	virtual ~DiffTimer();
+public:
+	virtual void   DoKeepAlive() = 0;
+	virtual time_t GetTimeMgmtEpoch() = 0;
+	virtual int    GetMaximumDiffingTime() = 0;
+	virtual int    GetKeepaliveTime() = 0;
+};
+
+// --------------------------------------------------------------------------
+//
+// Class
 //		Name:    BackupStoreFile
 //		Purpose: Class to hold together utils for maniplating files.
 //		Created: 2003/08/28
@@ -95,9 +116,16 @@
 
 	// 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> EncodeFileDiff(const char *Filename, int64_t ContainerID,
-		const BackupStoreFilename &rStoreFilename, int64_t DiffFromObjectID, IOStream &rDiffFromBlockIndex,
-		int Timeout, int64_t *pModificationTime = 0, bool *pIsCompletelyDifferent = 0);
+	static std::auto_ptr<IOStream> EncodeFileDiff
+	(
+		const char *Filename, int64_t ContainerID,
+		const BackupStoreFilename &rStoreFilename, 
+		int64_t DiffFromObjectID, IOStream &rDiffFromBlockIndex,
+		int Timeout, 
+		DiffTimer *pDiffTimer,
+		int64_t *pModificationTime = 0, 
+		bool *pIsCompletelyDifferent = 0
+	);
 	static bool VerifyEncodedFileFormat(IOStream &rFile, int64_t *pDiffFromObjectIDOut = 0, int64_t *pContainerIDOut = 0);
 	static void CombineFile(IOStream &rDiff, IOStream &rDiff2, IOStream &rFrom, IOStream &rOut);
 	static void CombineDiffs(IOStream &rDiff1, IOStream &rDiff2, IOStream &rDiff2b, IOStream &rOut);
@@ -144,8 +172,7 @@
 		free(a);
 	}
 
-	// Limits
-	static void SetMaximumDiffingTime(int Seconds);
+	static void DiffTimerExpired();
 
 	// Building blocks
 	class EncodingBuffer
@@ -192,4 +219,3 @@
 #include "MemLeakFindOff.h"
 
 #endif // BACKUPSTOREFILE__H
-

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFileDiff.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFileDiff.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFileDiff.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -11,11 +11,11 @@
 
 #include <new>
 #include <map>
-#include <signal.h>
-#ifdef WIN32
-#include <time.h>
-#else
-#include <sys/time.h>
+
+#ifdef HAVE_TIME_H
+	#include <time.h>
+#elif HAVE_SYS_TIME_H
+	#include <sys/time.h>
 #endif
 
 #include "BackupStoreFile.h"
@@ -43,33 +43,37 @@
 
 static void LoadIndex(IOStream &rBlockIndex, int64_t ThisID, BlocksAvailableEntry **ppIndex, int64_t &rNumBlocksOut, int Timeout, bool &rCanDiffFromThis);
 static void FindMostUsedSizes(BlocksAvailableEntry *pIndex, int64_t NumBlocks, int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES]);
-static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t> &rFoundBlocks, BlocksAvailableEntry *pIndex, int64_t NumBlocks, int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES]);
+static void SearchForMatchingBlocks(IOStream &rFile, 
+	std::map<int64_t, int64_t> &rFoundBlocks, BlocksAvailableEntry *pIndex, 
+	int64_t NumBlocks, int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES],
+	DiffTimer *pDiffTimer);
 static void SetupHashTable(BlocksAvailableEntry *pIndex, int64_t NumBlocks, int32_t BlockSize, BlocksAvailableEntry **pHashTable);
 static bool SecondStageMatch(BlocksAvailableEntry *pFirstInHashList, RollingChecksum &fastSum, uint8_t *pBeginnings, uint8_t *pEndings, int Offset, int32_t BlockSize, int64_t FileBlockNumber,
 BlocksAvailableEntry *pIndex, std::map<int64_t, int64_t> &rFoundBlocks);
 static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksAvailableEntry *pIndex, int64_t NumBlocks, std::map<int64_t, int64_t> &rFoundBlocks, int64_t SizeOfInputFile);
 
-// Avoid running on too long with diffs
-static int sMaximumDiffTime = 600;		// maximum time to spend diffing
-static bool sDiffTimedOut = false;
-static bool sSetTimerSignelHandler = false;
-static void TimerSignalHandler(int signal);
-static void StartDiffTimer();
+// sDiffTimerExpired flags when the diff timer has expired. When true, the 
+// diff routine should check the wall clock as soon as possible, to determine 
+// whether it's time for a keepalive to be sent, or whether the diff has been 
+// running for too long and should be terminated.
+static bool sDiffTimerExpired = false;
 
 
 // --------------------------------------------------------------------------
 //
 // Function
-//		Name:    BackupStoreFile::SetMaximumDiffingTime(int)
-//		Purpose: Sets the maximum time to spend diffing, in seconds. Time is
-//				 process virutal time.
-//		Created: 19/3/04
+//		Name:    BackupStoreFile::DiffTimerExpired()
+//		Purpose: Notifies BackupStoreFile object that the diff operation
+//				 timer has expired, which may mean that a keepalive should
+//				 be sent, or the diff should be terminated. Called from an
+//				 external timer, so it should not do more than set a flag.
 //
+//		Created: 19/1/06
+//
 // --------------------------------------------------------------------------
-void BackupStoreFile::SetMaximumDiffingTime(int Seconds)
+void BackupStoreFile::DiffTimerExpired()
 {
-	sMaximumDiffTime = Seconds;
-	TRACE1("Set maximum diffing time to %d seconds\n", Seconds);
+	sDiffTimerExpired = true;
 }
 
 
@@ -139,9 +143,12 @@
 //		Created: 12/1/04
 //
 // --------------------------------------------------------------------------
-std::auto_ptr<IOStream> BackupStoreFile::EncodeFileDiff(const char *Filename, int64_t ContainerID,
-	const BackupStoreFilename &rStoreFilename, int64_t DiffFromObjectID, IOStream &rDiffFromBlockIndex,
-	int Timeout, int64_t *pModificationTime, bool *pIsCompletelyDifferent)
+std::auto_ptr<IOStream> BackupStoreFile::EncodeFileDiff
+(
+	const char *Filename, int64_t ContainerID,
+	const BackupStoreFilename &rStoreFilename, int64_t DiffFromObjectID, 
+	IOStream &rDiffFromBlockIndex, int Timeout, DiffTimer *pDiffTimer, 
+	int64_t *pModificationTime, bool *pIsCompletelyDifferent)
 {
 	// Is it a symlink?
 	{
@@ -180,9 +187,6 @@
 	
 	// Pointer to recipe we're going to create
 	BackupStoreFileEncodeStream::Recipe *precipe = 0;
-
-	// Start the timeout timer, so that the operation doesn't continue for ever
-	StartDiffTimer();
 	
 	try
 	{
@@ -204,7 +208,8 @@
 				// Get size of file
 				sizeOfInputFile = file.BytesLeftToRead();
 				// Find all those lovely matching blocks
-				SearchForMatchingBlocks(file, foundBlocks, pindex, blocksInIndex, sizesToScan);
+				SearchForMatchingBlocks(file, foundBlocks, pindex, 
+					blocksInIndex, sizesToScan, pDiffTimer);
 				
 				// Is it completely different?
 				completelyDifferent = (foundBlocks.size() == 0);
@@ -475,8 +480,20 @@
 //
 // --------------------------------------------------------------------------
 static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t> &rFoundBlocks,
-	BlocksAvailableEntry *pIndex, int64_t NumBlocks, int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES])
+	BlocksAvailableEntry *pIndex, int64_t NumBlocks, 
+	int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES], DiffTimer *pDiffTimer)
 {
+	time_t TimeMgmtEpoch   = 0;
+	int MaximumDiffingTime = 0;
+	int KeepAliveTime      = 0;
+
+	if (pDiffTimer)
+	{
+		TimeMgmtEpoch      = pDiffTimer->GetTimeMgmtEpoch();
+		MaximumDiffingTime = pDiffTimer->GetMaximumDiffingTime();
+		KeepAliveTime      = pDiffTimer->GetKeepaliveTime();
+	}
+	
 	std::map<int64_t, int32_t> goodnessOfFit;
 
 	// Allocate the hash lookup table
@@ -643,9 +660,40 @@
 							// End this loop, so the final byte isn't used again
 							break;
 						}
+
+						bool DiffTimedOut = false;
 						
-						if(static_cast<int64_t>(rFoundBlocks.size()) > (NumBlocks * BACKUP_FILE_DIFF_MAX_BLOCK_FIND_MULTIPLE) || sDiffTimedOut)
+						if(sDiffTimerExpired)
 						{
+							ASSERT(TimeMgmtEpoch > 0);
+							ASSERT(pDiffTimer != NULL);
+							
+							time_t tTotalRunIntvl = time(NULL) - TimeMgmtEpoch;
+							
+							if(MaximumDiffingTime > 0 && 
+								tTotalRunIntvl >= MaximumDiffingTime)
+							{
+								TRACE0("MaximumDiffingTime reached - "
+									"suspending file diff\n");
+								DiffTimedOut = true;
+							}
+							else if(KeepAliveTime > 0)
+							{
+								TRACE0("KeepAliveTime reached - "
+									"initiating keep-alive\n");
+								pDiffTimer->DoKeepAlive();
+							}
+
+							sDiffTimerExpired = false;
+						}
+
+						int64_t NumBlocksFound = static_cast<int64_t>(
+							rFoundBlocks.size());
+						int64_t MaxBlocksFound = NumBlocks * 
+							BACKUP_FILE_DIFF_MAX_BLOCK_FIND_MULTIPLE;
+						
+						if(NumBlocksFound > MaxBlocksFound || DiffTimedOut)
+						{
 							abortSearch = true;
 							break;
 						}
@@ -787,7 +835,9 @@
 	ASSERT(pFirstInHashList != 0);
 	ASSERT(pIndex != 0);
 
-	uint16_t Hash = fastSum.GetComponentForHashing();
+#ifndef NDEBUG
+	uint16_t DEBUG_Hash = fastSum.GetComponentForHashing();
+#endif
 	uint32_t Checksum = fastSum.GetChecksum();
 
 	// Before we go to the expense of the MD5, make sure it's a darn good match on the checksum we already know.
@@ -825,7 +875,7 @@
 	{
 		//TRACE3("scan size %d, block size %d, hash %d\n", scan->mSize, BlockSize, Hash);
 		ASSERT(scan->mSize == BlockSize);
-		ASSERT(RollingChecksum::ExtractHashingComponent(scan->mWeakChecksum) == Hash);
+		ASSERT(RollingChecksum::ExtractHashingComponent(scan->mWeakChecksum) == DEBUG_Hash);
 	
 		// Compare?
 		if(strong.DigestMatches(scan->mStrongChecksum))
@@ -1005,60 +1055,3 @@
 	}
 #endif
 }
-
-
-// --------------------------------------------------------------------------
-//
-// Function
-//		Name:    static TimerSignalHandler(int)
-//		Purpose: Signal handler
-//		Created: 19/3/04
-//
-// --------------------------------------------------------------------------
-void TimerSignalHandler(int signal)
-{
-	sDiffTimedOut = true;
-}
-
-
-// --------------------------------------------------------------------------
-//
-// Function
-//		Name:    static StartDiffTimer()
-//		Purpose: Starts the diff timeout timer
-//		Created: 19/3/04
-//
-// --------------------------------------------------------------------------
-void StartDiffTimer()
-{
-#ifdef WIN32
-	// no support for SIGVTALRM
-	SetTimerHandler(TimerSignalHandler);
-#else
-	// Set timer signal handler
-	if(!sSetTimerSignelHandler)
-	{
-		::signal(SIGVTALRM, TimerSignalHandler);
-		sSetTimerSignelHandler = true;
-	}
-#endif
-
-	struct itimerval timeout;
-	// Don't want this to repeat
-	timeout.it_interval.tv_sec = 0;
-	timeout.it_interval.tv_usec = 0;
-	// Single timeout after the specified number of seconds
-	timeout.it_value.tv_sec = sMaximumDiffTime;
-	timeout.it_value.tv_usec = 0;
-	// Set timer
-	if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0)
-	{
-		TRACE0("WARNING: couldn't set diff timeout\n");
-	}
-	
-	// Unset flag (last thing)
-	sDiffTimedOut = false;
-}
-
-
-

Modified: box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFilenameClear.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFilenameClear.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/backupclient/BackupStoreFilenameClear.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -184,28 +184,34 @@
 // Buffer for encoding and decoding -- do this all in one single buffer to
 // avoid lots of string allocation, which stuffs up memory usage.
 // These static memory vars are, of course, not thread safe, but we don't use threads.
-#ifndef NDEBUG
-static int sEncDecBufferSize = 2;	// small size for debug builds
-#else
-static int sEncDecBufferSize = 256;
-#endif
-static MemoryBlockGuard<uint8_t *> spEncDecBuffer(sEncDecBufferSize);
+static int sEncDecBufferSize = 0;
+static MemoryBlockGuard<uint8_t *> *spEncDecBuffer = 0;
 
-// fudge to stop leak reporting
-#ifdef BOX_MEMORY_LEAK_TESTING
-namespace
+static void EnsureEncDecBufferSize(int BufSize)
 {
-	class leak_off
+	if(spEncDecBuffer == 0)
 	{
-	public:
-		leak_off()
+#ifndef WIN32
+		TRACE1("Allocating filename encoding/decoding buffer with size %d\n", BufSize);
+#endif
+		spEncDecBuffer = new MemoryBlockGuard<uint8_t *>(BufSize);
+		MEMLEAKFINDER_NOT_A_LEAK(spEncDecBuffer);
+		MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
+		sEncDecBufferSize = BufSize;
+	}
+	else
+	{
+		if(sEncDecBufferSize < BufSize)
 		{
-			MEMLEAKFINDER_NOT_A_LEAK(spEncDecBuffer);
+#ifndef WIN32
+			TRACE2("Reallocating filename encoding/decoding buffer from %d to %d\n", sEncDecBufferSize, BufSize);
+#endif
+			spEncDecBuffer->Resize(BufSize);
+			sEncDecBufferSize = BufSize;
+			MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
 		}
-	};
-	leak_off dont_report_as_leak;
+	}
 }
-#endif
 
 // --------------------------------------------------------------------------
 //
@@ -221,18 +227,10 @@
 	int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(rToEncode.size()) + 4;
 	
 	// Make sure encode/decode buffer has enough space
-	if(sEncDecBufferSize < maxOutSize)
-	{
-#ifndef WIN32
-		TRACE2("Reallocating filename encoding/decoding buffer from %d to %d\n", sEncDecBufferSize, maxOutSize);
-#endif
-		spEncDecBuffer.Resize(maxOutSize);
-		sEncDecBufferSize = maxOutSize;
-	}
+	EnsureEncDecBufferSize(maxOutSize);
 	
 	// Pointer to buffer
-	uint8_t *buffer = spEncDecBuffer;
-	MEMLEAKFINDER_NOT_A_LEAK(buffer);
+	uint8_t *buffer = *spEncDecBuffer;
 	
 	// Encode -- do entire block in one go
 	int encSize = rCipherContext.TransformBlock(buffer + 2, sEncDecBufferSize - 2, rToEncode.c_str(), rToEncode.size());
@@ -261,18 +259,10 @@
 	int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(size()) + 4;
 	
 	// Make sure encode/decode buffer has enough space
-	if(sEncDecBufferSize < maxOutSize)
-	{
-#ifndef WIN32
-		TRACE2("Reallocating filename encoding/decoding buffer from %d to %d\n", sEncDecBufferSize, maxOutSize);
-#endif
-		spEncDecBuffer.Resize(maxOutSize);
-		sEncDecBufferSize = maxOutSize;
-	}
+	EnsureEncDecBufferSize(maxOutSize);
 	
 	// Pointer to buffer
-	uint8_t *buffer = spEncDecBuffer;
-	MEMLEAKFINDER_NOT_A_LEAK(buffer);
+	uint8_t *buffer = *spEncDecBuffer;
 	
 	// Decrypt
 	const char *str = c_str() + 2;


Property changes on: box/chris/win32/vc2005-compile-fixes/lib/common
___________________________________________________________________
Name: svn:ignore
   - autogen_CommonException.cpp
autogen_CommonException.h
autogen_ConversionException.cpp
autogen_ConversionException.h
config.h
config.h.in
Makefile

   + autogen_CommonException.cpp
autogen_CommonException.h
autogen_ConversionException.cpp
autogen_ConversionException.h
BoxConfig.h
BoxConfig.h.in
Makefile



Copied: box/chris/win32/vc2005-compile-fixes/lib/common/Archive.h (from rev 364, box/trunk/lib/common/Archive.h)

Modified: box/chris/win32/vc2005-compile-fixes/lib/common/Box.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/common/Box.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/common/Box.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -114,6 +114,10 @@
 
 // extra macros for converting to network byte order
 
+#ifdef HAVE_NETINET_IN_H
+	#include <netinet/in.h>
+#endif
+
 // Always define a swap64 function, as it's useful.
 inline uint64_t box_swap64(uint64_t x)
 {
@@ -130,14 +134,20 @@
 #ifdef WORDS_BIGENDIAN
 	#define box_hton64(x) (x)
 	#define box_ntoh64(x) (x)
+#elif defined(HAVE_BSWAP64)
+	#ifdef HAVE_SYS_ENDIAN_H
+		#include <sys/endian.h>
+	#endif
+	#ifdef HAVE_ASM_BYTEORDER_H
+		#include <asm/byteorder.h>
+	#endif
+
+	#define box_hton64(x) BSWAP64(x)
+	#define box_ntoh64(x) BSWAP64(x)
 #else
 	#define box_hton64(x) box_swap64(x)
 	#define box_ntoh64(x) box_swap64(x)
 #endif
 
-#ifdef HAVE_NETINET_IN_H
-	#include <netinet/in.h>
-#endif
-
 #endif // BOX__H
 

Modified: box/chris/win32/vc2005-compile-fixes/lib/common/BoxPlatform.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/common/BoxPlatform.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/common/BoxPlatform.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -21,7 +21,7 @@
 
 #define PLATFORM_DEV_NULL			"/dev/null"
 
-#include "config.h"
+#include "BoxConfig.h"
 
 #ifdef WIN32
 	// need msvcrt version 6.1 or higher for _gmtime64()
@@ -40,6 +40,12 @@
 	#endif
 #endif
 
+// Slight hack; disable interception on Darwin within raidfile test
+#ifdef __APPLE__
+	// TODO: Replace with autoconf test
+	#define PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
+#endif
+
 // Find out if credentials on UNIX sockets can be obtained
 #ifndef HAVE_GETPEEREID
 	#if !HAVE_DECL_SO_PEERCRED
@@ -47,11 +53,6 @@
 	#endif
 #endif
 
-// Cannot do the intercepts in test/raidfile if large file support is enabled
-#ifdef HAVE_LARGE_FILE_SUPPORT
-	#define PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
-#endif
-
 #ifdef HAVE_DEFINE_PRAGMA
 	// set packing to one bytes (can't use push/pop on gcc)
 	#define BEGIN_STRUCTURE_PACKING_FOR_WIRE	#pragma pack(1)
@@ -62,6 +63,19 @@
 	#define STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS
 #endif
 
+// Handle differing xattr APIs
+#ifdef HAVE_SYS_XATTR_H
+	#if !defined(HAVE_LLISTXATTR) && defined(HAVE_LISTXATTR) && HAVE_DECL_XATTR_NOFOLLOW
+		#define llistxattr(a,b,c) listxattr(a,b,c,XATTR_NOFOLLOW)
+	#endif
+	#if !defined(HAVE_LGETXATTR) && defined(HAVE_GETXATTR) && HAVE_DECL_XATTR_NOFOLLOW
+		#define lgetxattr(a,b,c,d) getxattr(a,b,c,d,0,XATTR_NOFOLLOW)
+	#endif
+	#if !defined(HAVE_LSETXATTR) && defined(HAVE_SETXATTR) && HAVE_DECL_XATTR_NOFOLLOW
+		#define lsetxattr(a,b,c,d,e) setxattr(a,b,c,d,0,(e)|XATTR_NOFOLLOW)
+	#endif
+#endif
+
 #if defined WIN32 && !defined __MINGW32__
 	typedef __int8  int8_t;
 	typedef __int16 int16_t;

Modified: box/chris/win32/vc2005-compile-fixes/lib/common/CommonException.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/common/CommonException.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/common/CommonException.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -43,3 +43,4 @@
 KQueueNotSupportedOnThisPlatform		36
 IOStreamGetLineNotEnoughDataToIgnore	37	Bad value passed to IOStreamGetLine::IgnoreBufferedData()
 TempDirPathTooLong				38	Your temporary directory path is too long. Check the TMP and TEMP environment variables.
+ArchiveBlockIncompleteRead		39	The Store Object Info File is too short or corrupted, and will be rewritten automatically when the next backup completes.

Modified: box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -17,6 +17,7 @@
 #include "ExcludeList.h"
 #include "Utils.h"
 #include "Configuration.h"
+#include "Archive.h"
 
 #include "MemLeakFindOn.h"
 
@@ -130,6 +131,8 @@
 				
 				// Store in list of regular expressions
 				mRegex.push_back(pregex);
+				// Store in list of regular expression string for Serialize
+				mRegexStr.push_back(i->c_str());
 			}
 			catch(...)
 			{
@@ -213,7 +216,183 @@
 	mpAlwaysInclude = pAlwaysInclude;
 }
 
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    ExcludeList::Deserialize(Archive & rArchive)
+//		Purpose: Deserializes this object instance from a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void ExcludeList::Deserialize(Archive & rArchive)
+{
+	//
+	//
+	//
+	mDefinite.clear();
 
-	
+#ifndef PLATFORM_REGEX_NOT_SUPPORTED
+	// free regex memory
+	while(mRegex.size() > 0)
+	{
+		regex_t *pregex = mRegex.back();
+		mRegex.pop_back();
+		// Free regex storage, and the structure itself
+		::regfree(pregex);
+		delete pregex;
+	}
 
+	mRegexStr.clear();
+#endif
 
+	// Clean up exceptions list
+	if(mpAlwaysInclude != 0)
+	{
+		delete mpAlwaysInclude;
+		mpAlwaysInclude = 0;
+	}
+
+	//
+	//
+	//
+	int64_t iCount = 0;
+	rArchive.Read(iCount);
+
+	if (iCount > 0)
+	{
+		for (int v = 0; v < iCount; v++)
+		{
+			// load each one
+			std::string strItem;
+			rArchive.Read(strItem);
+			mDefinite.insert(strItem);
+		}
+	}
+
+	//
+	//
+	//
+#ifndef PLATFORM_REGEX_NOT_SUPPORTED
+	rArchive.Read(iCount);
+
+	if (iCount > 0)
+	{
+		for (int v = 0; v < iCount; v++)
+		{
+			std::string strItem;
+			rArchive.Read(strItem);
+
+			// Allocate memory
+			regex_t* pregex = new regex_t;
+			
+			try
+			{
+				// Compile
+				if(::regcomp(pregex, strItem.c_str(), 
+					REG_EXTENDED | REG_NOSUB) != 0)
+				{
+					THROW_EXCEPTION(CommonException, 
+						BadRegularExpression)
+				}
+				
+				// Store in list of regular expressions
+				mRegex.push_back(pregex);
+
+				// Store in list of regular expression strings
+				// for Serialize
+				mRegexStr.push_back(strItem);
+			}
+			catch(...)
+			{
+				delete pregex;
+				throw;
+			}
+		}
+	}
+#endif // PLATFORM_REGEX_NOT_SUPPORTED
+
+	//
+	//
+	//
+	int64_t aMagicMarker = 0;
+	rArchive.Read(aMagicMarker);
+
+	if (aMagicMarker == ARCHIVE_MAGIC_VALUE_NOOP)
+	{
+		// NOOP
+	}
+	else if (aMagicMarker == ARCHIVE_MAGIC_VALUE_RECURSE)
+	{
+		mpAlwaysInclude = new ExcludeList;
+		if (!mpAlwaysInclude)
+		{
+			throw std::bad_alloc();
+		}
+
+		mpAlwaysInclude->Deserialize(rArchive);
+	}
+	else
+	{
+		// there is something going on here
+		THROW_EXCEPTION(CommonException, Internal)
+	}
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    ExcludeList::Serialize(Archive & rArchive)
+//		Purpose: Serializes this object instance into a stream of bytes, using an Archive abstraction.
+//
+//		Created: 2005/04/11
+//
+// --------------------------------------------------------------------------
+void ExcludeList::Serialize(Archive & rArchive) const
+{
+	//
+	//
+	//
+	int64_t iCount = mDefinite.size();
+	rArchive.Write(iCount);
+
+	for (std::set<std::string>::const_iterator i = mDefinite.begin(); 
+		i != mDefinite.end(); i++)
+	{
+		rArchive.Write(*i);
+	}
+
+	//
+	//
+	//
+#ifndef PLATFORM_REGEX_NOT_SUPPORTED
+	// don't even try to save compiled regular expressions,
+	// use string copies instead.
+	ASSERT(mRegex.size() == mRegexStr.size()); 	
+
+	iCount = mRegexStr.size();
+	rArchive.Write(iCount);
+
+	for (std::vector<std::string>::const_iterator i = mRegexStr.begin(); 
+		i != mRegexStr.end(); i++)
+	{
+		rArchive.Write(*i);
+	}
+#endif // PLATFORM_REGEX_NOT_SUPPORTED
+
+	//
+	//
+	//
+	if (!mpAlwaysInclude)
+	{
+		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);
+
+		mpAlwaysInclude->Serialize(rArchive);
+	}
+}

Modified: box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/common/ExcludeList.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -19,6 +19,8 @@
 	typedef int regex_t;
 #endif
 
+class Archive;
+
 // --------------------------------------------------------------------------
 //
 // Class
@@ -33,6 +35,9 @@
 	ExcludeList();
 	~ExcludeList();
 
+	void Deserialize(Archive & rArchive);
+	void Serialize(Archive & rArchive) const;
+
 	void AddDefiniteEntries(const std::string &rEntries);
 	void AddRegexEntries(const std::string &rEntries);
 
@@ -55,6 +60,7 @@
 	std::set<std::string> mDefinite;
 #ifdef HAVE_REGEX_H
 	std::vector<regex_t *> mRegex;
+	std::vector<std::string> mRegexStr;	// save original regular expression string-based source for Serialize
 #endif
 
 	// For exceptions to the excludes

Modified: box/chris/win32/vc2005-compile-fixes/lib/crypto/Random.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/crypto/Random.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/crypto/Random.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -69,7 +69,7 @@
 std::string Random::GenerateHex(int Length)
 {
 	uint8_t r[256];
-	if(Length > sizeof(r))
+	if(Length > (int)sizeof(r))
 	{
 		THROW_EXCEPTION(CipherException, LengthRequestedTooLongForRandomHex)
 	}

Modified: box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -13,13 +13,14 @@
 	#include <unistd.h>
 #endif
 
+#include <errno.h>
 #include <stdio.h>
 #include <signal.h>
 #include <string.h>
 #include <stdarg.h>
 
-#ifndef WIN32
-#include <syslog.h>
+#ifdef HAVE_SYSLOG_H
+	#include <syslog.h>
 #endif
 
 #include "Daemon.h"
@@ -27,6 +28,7 @@
 #include "ServerException.h"
 #include "Guards.h"
 #include "UnixUser.h"
+#include "FileModificationTime.h"
 
 #include "MemLeakFindOn.h"
 
@@ -95,22 +97,21 @@
 	}
 
 	std::string pidFileName;
-	const char *configfile = 0;
 
 	try
 	{
 		// Find filename of config file
-		configfile = DefaultConfigFile;
+		mConfigFileName = DefaultConfigFile;
 		if(argc >= 2)
 		{
 			// First argument is config file, or it's -c and the next arg is the config file
 			if(::strcmp(argv[1], "-c") == 0 && argc >= 3)
 			{
-				configfile = argv[2];
+				mConfigFileName = argv[2];
 			}
 			else
 			{
-				configfile = argv[1];
+				mConfigFileName = argv[1];
 			}
 		}
 		
@@ -126,19 +127,25 @@
 
 		// Load the configuration file.
 		std::string errors;
-		std::auto_ptr<Configuration> pconfig = Configuration::LoadAndVerify(configfile, GetConfigVerify(), errors);
+		std::auto_ptr<Configuration> pconfig = 
+			Configuration::LoadAndVerify(
+				mConfigFileName.c_str(), 
+				GetConfigVerify(), errors);
 
 		// Got errors?
 		if(pconfig.get() == 0 || !errors.empty())
 		{
 			// Tell user about errors
-			fprintf(stderr, "%s: Errors in config file %s:\n%s", DaemonName(), configfile, errors.c_str());
+			fprintf(stderr, "%s: Errors in config file %s:\n%s", 
+				DaemonName(), mConfigFileName.c_str(), 
+				errors.c_str());
 			// And give up
 			return 1;
 		}
 		
 		// Store configuration
 		mpConfiguration = pconfig.release();
+		mLoadedConfigModifiedTime = GetConfigFileModifiedTime();
 		
 		// Server configuration
 		const Configuration &serverConfig(mpConfiguration->GetSubConfiguration("Server"));
@@ -231,7 +238,8 @@
 		// open the log
 		::openlog(DaemonName(), LOG_PID, LOG_LOCAL6);
 		// Log the start message
-		::syslog(LOG_INFO, "Starting daemon (config: %s) (version " BOX_VERSION ")", configfile);
+		::syslog(LOG_INFO, "Starting daemon (config: %s) (version " 
+			BOX_VERSION ")", mConfigFileName.c_str());
 
 #ifndef WIN32
 		// Write PID to file
@@ -309,15 +317,23 @@
 			if(mReloadConfigWanted && !mTerminateWanted)
 			{
 				// Need to reload that config file...
-				::syslog(LOG_INFO, "Reloading configuration (config: %s)", configfile);
+				::syslog(LOG_INFO, "Reloading configuration "
+					"(config: %s)", 
+					mConfigFileName.c_str());
 				std::string errors;
-				std::auto_ptr<Configuration> pconfig = Configuration::LoadAndVerify(configfile, GetConfigVerify(), errors);
+				std::auto_ptr<Configuration> pconfig = 
+					Configuration::LoadAndVerify(
+						mConfigFileName.c_str(),
+						GetConfigVerify(), errors);
 
 				// Got errors?
 				if(pconfig.get() == 0 || !errors.empty())
 				{
 					// Tell user about errors
-					::syslog(LOG_ERR, "Errors in config file %s:\n%s", configfile, errors.c_str());
+					::syslog(LOG_ERR, "Errors in config "
+						"file %s:\n%s", 
+						mConfigFileName.c_str(),
+						errors.c_str());
 					// And give up
 					return 1;
 				}
@@ -328,6 +344,8 @@
 
 				// Store configuration
 				mpConfiguration = pconfig.release();
+				mLoadedConfigModifiedTime =
+					GetConfigFileModifiedTime();
 				
 				// Stop being marked for loading config again
 				mReloadConfigWanted = false;
@@ -550,3 +568,49 @@
 	
 #endif // HAVE_SETPROCTITLE
 }
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    Daemon::GetConfigFileModifiedTime()
+//		Purpose: Returns the timestamp when the configuration file
+//			 was last modified
+//
+//		Created: 2006/01/29
+//
+// --------------------------------------------------------------------------
+
+box_time_t Daemon::GetConfigFileModifiedTime() const
+{
+	struct stat st;
+
+	if(::stat(GetConfigFileName().c_str(), &st) != 0)
+	{
+		if (errno == ENOENT)
+		{
+			return 0;
+		}
+		THROW_EXCEPTION(CommonException, OSFileError)
+	}
+	
+	return FileModificationTime(st);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    Daemon::GetLoadedConfigModifiedTime()
+//		Purpose: Returns the timestamp when the configuration file
+//			 had been last modified, at the time when it was 
+//			 loaded
+//
+//		Created: 2006/01/29
+//
+// --------------------------------------------------------------------------
+
+box_time_t Daemon::GetLoadedConfigModifiedTime() const
+{
+	return mLoadedConfigModifiedTime;
+}
+

Modified: box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/server/Daemon.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -16,6 +16,10 @@
 #ifndef DAEMON__H
 #define DAEMON__H
 
+#include <string>
+
+#include "BoxTime.h"
+
 class Configuration;
 class ConfigurationVerify;
 
@@ -40,7 +44,8 @@
 	
 	virtual void Run();
 	const Configuration &GetConfiguration() const;
-	
+	const std::string &GetConfigFileName() const {return mConfigFileName;}
+
 	virtual const char *DaemonName() const;
 	virtual const char *DaemonBanner() const;
 	virtual const ConfigurationVerify *GetConfigVerify() const;
@@ -57,12 +62,18 @@
 	virtual void EnterChild();
 	
 	static void SetProcessTitle(const char *format, ...);
+
+protected:
+	box_time_t GetLoadedConfigModifiedTime() const;
 	
 private:
 	static void SignalHandler(int sigraised);
+	box_time_t GetConfigFileModifiedTime() const;
 	
 private:
+	std::string mConfigFileName;
 	Configuration *mpConfiguration;
+	box_time_t mLoadedConfigModifiedTime;
 	bool mReloadConfigWanted;
 	bool mTerminateWanted;
 	static Daemon *spDaemon;

Modified: box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/lib/win32/emu.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -527,8 +527,6 @@
 
 		if (err == ERROR_FILE_NOT_FOUND)
 		{
-			::syslog(LOG_WARNING, 
-				"Failed to open '%s': file not found", pName);
 			errno = ENOENT;
 		}
 		else

Modified: box/chris/win32/vc2005-compile-fixes/parcels.txt
===================================================================
--- box/chris/win32/vc2005-compile-fixes/parcels.txt	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/parcels.txt	2006-02-03 20:21:10 UTC (rev 365)
@@ -8,9 +8,14 @@
 	bin bbackupquery
 	bin bbackupctl
 	script bin/bbackupd/bbackupd-config
+
+ONLY:mingw32
 	script bin/bbackupd/win32/installer.iss 
 	script bin/bbackupd/win32/ReadMe.txt 
 	script bin/bbackupd/win32/bbackupd.conf
+	script /bin/mgwz.dll
+	script /bin/mingwm10.dll
+END-ONLY
 
 OMIT:mingw32
 OMIT:CYGWIN

Modified: box/chris/win32/vc2005-compile-fixes/test/backupdiff/testbackupdiff.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/backupdiff/testbackupdiff.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/backupdiff/testbackupdiff.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -83,7 +83,7 @@
 	fclose(f);
 	free(b);
 
-	TEST_THAT(TestGetFileSize(filename) == size);
+	TEST_THAT((size_t)TestGetFileSize(filename) == size);
 }
 
 
@@ -169,9 +169,17 @@
 	{
 		BackupStoreFilenameClear f1name("filename");
 		FileStream out(to_diff, O_WRONLY | O_CREAT | O_EXCL);
-		std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFileDiff(to_orig, 1 /* dir ID */, f1name,
-			1000 + from /* object ID of the file diffing from */, blockindex, IOStream::TimeOutInfinite,
-			0, &completelyDifferent));
+		std::auto_ptr<IOStream> encoded(
+			BackupStoreFile::EncodeFileDiff(
+				to_orig, 
+				1 /* dir ID */, 
+				f1name,
+				1000 + from /* object ID of the file diffing from */, 
+				blockindex, 
+				IOStream::TimeOutInfinite,
+				NULL, // DiffTimer interface
+				0, 
+				&completelyDifferent));
 		encoded->CopyStreamTo(out);
 	}
 	TEST_THAT(completelyDifferent == expect_completely_different);
@@ -443,9 +451,17 @@
 			
 			BackupStoreFilenameClear f1name("filename");
 			FileStream out("testfiles/f2.symlink.diff", O_WRONLY | O_CREAT | O_EXCL);
-			std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFileDiff("testfiles/f2.symlink", 1 /* dir ID */, f1name,
-				1001 /* object ID of the file diffing from */, blockindex, IOStream::TimeOutInfinite,
-				0, &completelyDifferent));
+			std::auto_ptr<IOStream> encoded(
+				BackupStoreFile::EncodeFileDiff(
+					"testfiles/f2.symlink", 
+					1 /* dir ID */, 
+					f1name,
+					1001 /* object ID of the file diffing from */, 
+					blockindex, 
+					IOStream::TimeOutInfinite,
+					NULL, // DiffTimer interface
+					0, 
+					&completelyDifferent));
 			encoded->CopyStreamTo(out);
 		}
 		TEST_THAT(completelyDifferent == true);

Modified: box/chris/win32/vc2005-compile-fixes/test/backupstore/testbackupstore.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/backupstore/testbackupstore.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/backupstore/testbackupstore.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -1072,9 +1072,16 @@
 			// Do the patching
 			bool isCompletelyDifferent = false;
 			int64_t modtime;
-			std::auto_ptr<IOStream> patchstream(BackupStoreFile::EncodeFileDiff(TEST_FILE_FOR_PATCHING ".mod", BackupProtocolClientListDirectory::RootDirectory,
-					uploads[UPLOAD_PATCH_EN].name, uploads[UPLOAD_PATCH_EN].allocated_objid, *blockIndexStream,
-					IOStream::TimeOutInfinite, &modtime, &isCompletelyDifferent));
+			std::auto_ptr<IOStream> patchstream(
+				BackupStoreFile::EncodeFileDiff(
+					TEST_FILE_FOR_PATCHING ".mod", 
+					BackupProtocolClientListDirectory::RootDirectory,
+					uploads[UPLOAD_PATCH_EN].name, 
+					uploads[UPLOAD_PATCH_EN].allocated_objid, 
+					*blockIndexStream,
+					IOStream::TimeOutInfinite, 
+					NULL, // pointer to DiffTimer impl
+					&modtime, &isCompletelyDifferent));
 			TEST_THAT(isCompletelyDifferent == false);
 			// Sent this to a file, so we can check the size, rather than uploading it directly
 			{

Modified: box/chris/win32/vc2005-compile-fixes/test/backupstorepatch/testbackupstorepatch.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/backupstorepatch/testbackupstorepatch.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/backupstorepatch/testbackupstorepatch.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -376,10 +376,17 @@
 					char filename[64];
 					::sprintf(filename, "testfiles/%d.test", f);
 					bool isCompletelyDifferent = false;
-					std::auto_ptr<IOStream> patchStream(BackupStoreFile::EncodeFileDiff(filename,
+					std::auto_ptr<IOStream> patchStream(
+						BackupStoreFile::EncodeFileDiff(
+							filename,
 							BackupProtocolClientListDirectory::RootDirectory,	/* containing directory */
-							storeFilename, diffFromID, *blockIndexStream,
-							protocol.GetTimeout(), 0 /* not interested in the modification time */, &isCompletelyDifferent));
+							storeFilename, 
+							diffFromID, 
+							*blockIndexStream,
+							protocol.GetTimeout(), 
+							NULL, // DiffTimer impl
+							0 /* not interested in the modification time */, 
+							&isCompletelyDifferent));
 		
 					// Upload the patch to the store
 					std::auto_ptr<BackupProtocolClientSuccess> stored(protocol.QueryStoreFile(

Modified: box/chris/win32/vc2005-compile-fixes/test/bbackupd/testbbackupd.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/bbackupd/testbbackupd.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/bbackupd/testbbackupd.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -16,6 +16,11 @@
 #include <string.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#ifdef HAVE_SYS_XATTR_H
+#include <cerrno>
+#include <sys/xattr.h>
+#endif
+#include <map>
 
 #include "Test.h"
 #include "BackupClientFileAttributes.h"
@@ -39,6 +44,11 @@
 
 #include "MemLeakFindOn.h"
 
+// ENOATTR may be defined in a separate header file which we may not have
+#ifndef ENOATTR
+#define ENOATTR ENODATA
+#endif
+
 // two cycles and a bit
 #define TIME_TO_WAIT_FOR_BACKUP_OPERATION	12
 
@@ -57,12 +67,188 @@
 
 int bbstored_pid = 0;
 
+#ifdef HAVE_SYS_XATTR_H
+bool readxattr_into_map(const char *filename, std::map<std::string,std::string> &rOutput)
+{
+	rOutput.clear();
+	
+	ssize_t xattrNamesBufferSize = llistxattr(filename, NULL, 0);
+	if(xattrNamesBufferSize < 0)
+	{
+		return false;
+	}
+	else if(xattrNamesBufferSize > 0)
+	{
+		// There is some data there to look at
+		char *xattrNamesBuffer = (char*)malloc(xattrNamesBufferSize + 4);
+		if(xattrNamesBuffer == NULL) return false;
+		char *xattrDataBuffer = 0;
+		int xattrDataBufferSize = 0;
+		// note: will leak these buffers if a read error occurs. (test code, so doesn't matter)
+		
+		ssize_t ns = llistxattr(filename, xattrNamesBuffer, xattrNamesBufferSize);
+		if(ns < 0)
+		{
+			return false;
+		}
+		else if(ns > 0)
+		{
+			// Read all the attribute values
+			const char *xattrName = xattrNamesBuffer;
+			while(xattrName < (xattrNamesBuffer + ns))
+			{
+				// Store size of name
+				int xattrNameSize = strlen(xattrName);
+				
+				bool ok = true;
+					
+				ssize_t dataSize = lgetxattr(filename, xattrName, NULL, 0);
+				if(dataSize < 0)
+				{
+					if(errno == ENOATTR)
+					{
+						// Deleted from under us
+						ok = false;
+					}
+					else
+					{
+						return false;
+					}
+				}
+				else if(dataSize == 0)
+				{
+					// something must have removed all the data from under us
+					ok = false;
+				}
+				else
+				{
+					// Make sure there's enough space in the buffer to get the attribute
+					if(xattrDataBuffer == 0)
+					{
+						xattrDataBuffer = (char*)malloc(dataSize + 4);
+						xattrDataBufferSize = dataSize + 4;
+					}
+					else if(xattrDataBufferSize < (dataSize + 4))
+					{
+						char *resized = (char*)realloc(xattrDataBuffer, dataSize + 4);
+						if(resized == NULL) return false;
+						xattrDataBuffer = resized;
+						xattrDataBufferSize = dataSize + 4;
+					}
+				}
+
+				// Read the data!
+				dataSize = 0;
+				if(ok)
+				{
+					dataSize = lgetxattr(filename, xattrName, xattrDataBuffer,
+						xattrDataBufferSize - 1 /*for terminator*/);
+					if(dataSize < 0)
+					{
+						if(errno == ENOATTR)
+						{
+							// Deleted from under us
+							ok = false;
+						}
+						else
+						{
+							return false;
+						}
+					}
+					else if(dataSize == 0)
+					{
+						// something must have deleted this from under us
+						ok = false;
+					}
+					else
+					{
+						// Terminate the data
+						xattrDataBuffer[dataSize] = '\0';
+					}
+					// Got the data in the buffer
+				}
+				
+				// Store in map
+				if(ok)
+				{
+					rOutput[std::string(xattrName)] = std::string(xattrDataBuffer, dataSize);
+				}
+
+				// Next attribute
+				xattrName += xattrNameSize + 1;
+			}
+		}
+		
+		if(xattrNamesBuffer != 0) ::free(xattrNamesBuffer);
+		if(xattrDataBuffer != 0) ::free(xattrDataBuffer);
+	}
+
+	return true;
+}
+
+static FILE *xattrTestDataHandle = 0;
+bool write_xattr_test(const char *filename, const char *attrName, unsigned int length, bool *pNotSupported = 0)
+{
+	if(xattrTestDataHandle == 0)
+	{
+		xattrTestDataHandle = ::fopen("testfiles/test3.tgz", "rb");	// largest test file
+	}
+	if(xattrTestDataHandle == 0)
+	{
+		return false;
+	}
+	else
+	{
+		char data[1024];
+		if(length > sizeof(data)) length = sizeof(data);
+		
+		if(::fread(data, length, 1, xattrTestDataHandle) != 1)
+		{
+			return false;
+		}
+		
+		if(::lsetxattr(filename, attrName, data, length, 0) != 0)
+		{
+			if(pNotSupported != 0)
+			{
+				*pNotSupported = (errno == ENOTSUP);
+			}
+			return false;
+		}
+	}
+
+	return true;
+}
+void finish_with_write_xattr_test()
+{
+	if(xattrTestDataHandle != 0)
+	{
+		::fclose(xattrTestDataHandle);
+	}
+}
+#endif // HAVE_SYS_XATTR_H
+
 bool attrmatch(const char *f1, const char *f2)
 {
 	struct stat s1, s2;
 	TEST_THAT(::lstat(f1, &s1) == 0);
 	TEST_THAT(::lstat(f2, &s2) == 0);
 
+#ifdef HAVE_SYS_XATTR_H
+	{
+		std::map<std::string,std::string> xattr1, xattr2;
+		if(!readxattr_into_map(f1, xattr1)
+			|| !readxattr_into_map(f2, xattr2))
+		{
+			return false;
+		}
+		if(!(xattr1 == xattr2))
+		{
+			return false;
+		}
+	}
+#endif // HAVE_SYS_XATTR_H
+
 	// if link, just make sure other file is a link too, and that the link to names match
 	if((s1.st_mode & S_IFMT) == S_IFLNK)
 	{
@@ -143,6 +329,49 @@
 	TEST_THAT(t1_r == t1b);
 	TEST_THAT(t1b_r == t1);
 
+#ifdef HAVE_SYS_XATTR_H
+	// Write some attributes to the file, checking for ENOTSUP
+	bool xattrNotSupported = false;
+	if(!write_xattr_test("testfiles/test1", "user.attr_1", 1000, &xattrNotSupported) && xattrNotSupported)
+	{
+		::printf("***********\nYour platform supports xattr, but your filesystem does not.\nSkipping tests.\n***********\n");
+	}
+	else
+	{
+		BackupClientFileAttributes x1, x2, x3, x4;
+
+		// Write more attributes
+		TEST_THAT(write_xattr_test("testfiles/test1", "user.attr_2", 947));
+		TEST_THAT(write_xattr_test("testfiles/test1", "user.sadfohij39998.3hj", 123));
+	
+		// Read file attributes
+		x1.ReadAttributes("testfiles/test1");
+		
+		// Write file attributes
+		FILE *f = fopen("testfiles/test1_nx", "w");
+		fclose(f);
+		x1.WriteAttributes("testfiles/test1_nx");
+		
+		// Compare to see if xattr copied
+		TEST_THAT(attrmatch("testfiles/test1", "testfiles/test1_nx"));
+		
+		// Add more attributes to a file
+		x2.ReadAttributes("testfiles/test1");
+		TEST_THAT(write_xattr_test("testfiles/test1", "user.328989sj..sdf", 23));
+		
+		// Read them again, and check that the Compare() function detects that they're different
+		x3.ReadAttributes("testfiles/test1");
+		TEST_THAT(x1.Compare(x2, true, true));
+		TEST_THAT(!x1.Compare(x3, true, true));
+		
+		// Change the value of one of them, leaving the size the same.
+		TEST_THAT(write_xattr_test("testfiles/test1", "user.328989sj..sdf", 23));
+		x4.ReadAttributes("testfiles/test1");
+		TEST_THAT(!x1.Compare(x4, true, true));
+	}
+	finish_with_write_xattr_test();
+#endif // HAVE_SYS_XATTR_H
+
 	return 0;
 }
 
@@ -287,7 +516,7 @@
 	// unpack the files for the initial test
 	TEST_THAT(::system("rm -rf testfiles/TestDir1") == 0);
 	TEST_THAT(::system("mkdir testfiles/TestDir1") == 0);
-	TEST_THAT(::system("tar xzf testfiles/spacetest1.tgz -C testfiles/TestDir1/") == 0);
+	TEST_THAT(::system("gzip -d < testfiles/spacetest1.tgz | tar xf - -C testfiles/TestDir1/") == 0);
 
 	int pid = LaunchServer("../../bin/bbackupd/bbackupd testfiles/bbackupd.conf", "testfiles/bbackupd.pid");
 	TEST_THAT(pid != -1 && pid != 0);
@@ -306,7 +535,7 @@
 		TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks");
 
 		// Unpack some more files
-		TEST_THAT(::system("tar xzf testfiles/spacetest2.tgz -C testfiles/TestDir1/") == 0);
+		TEST_THAT(::system("gzip -d < testfiles/spacetest2.tgz | tar xf - -C testfiles/TestDir1/") == 0);
 		// Delete a file and a directory
 		TEST_THAT(::unlink("testfiles/TestDir1/spacetest/d1/f3") == 0);
 		TEST_THAT(::system("rm -rf testfiles/TestDir1/spacetest/d3/d4") == 0);
@@ -327,7 +556,7 @@
 		TEST_THAT(!TestFileExists("testfiles/notifyran.store-full.2"));
 		
 		// unpack the initial files again
-		TEST_THAT(::system("tar xzf testfiles/test_base.tgz -C testfiles/") == 0);
+		TEST_THAT(::system("gzip -d < testfiles/test_base.tgz | tar xf - -C testfiles/") == 0);
 
 		// wait for it to do it's stuff
 		wait_for_backup_operation();
@@ -427,7 +656,7 @@
 		// Add some more files
 		// Because the 'm' option is not used, these files will look very old to the daemon.
 		// Lucky it'll upload them then!
-		TEST_THAT(::system("tar xzf testfiles/test2.tgz -C testfiles/") == 0);
+		TEST_THAT(::system("gzip -d < testfiles/test2.tgz | tar xf - -C testfiles/") == 0);
 		::chmod("testfiles/TestDir1/sub23/dhsfdss/blf.h", 0415);
 		
 		// Wait and test
@@ -464,7 +693,7 @@
 
 		// Add some files and directories which are marked as excluded
 		printf("Add files and dirs for exclusion test\n");
-		TEST_THAT(::system("tar xzf testfiles/testexclude.tgz -C testfiles/") == 0);
+		TEST_THAT(::system("gzip -d < testfiles/testexclude.tgz | tar xf - -C testfiles/") == 0);
 		// Wait and test
 		wait_for_backup_operation();
 		compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3c.log \"compare -ac\" quit");
@@ -601,7 +830,7 @@
 	
 		// Add some more files and modify others
 		// Use the m flag this time so they have a recent modification time
-		TEST_THAT(::system("tar xzmf testfiles/test3.tgz -C testfiles/") == 0);
+		TEST_THAT(::system("gzip -d < testfiles/test3.tgz | tar xmf - -C testfiles/") == 0);
 		
 		// Wait and test
 		wait_for_backup_operation();
@@ -806,7 +1035,7 @@
 	BackupClientCryptoKeys_Setup("testfiles/bbackupd.keys");
 
 	// Initial files
-	TEST_THAT(::system("tar xzf testfiles/test_base.tgz -C testfiles/") == 0);
+	TEST_THAT(::system("gzip -d < testfiles/test_base.tgz | tar xf - -C testfiles/") == 0);
 
 	// Do the tests
 

Deleted: box/chris/win32/vc2005-compile-fixes/test/raidfile/Darwin-SYS.h
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/raidfile/Darwin-SYS.h	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/raidfile/Darwin-SYS.h	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,167 +0,0 @@
-
-/* Taken from the Darwin Libc source
-*/
-
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved.
- *
- *	File:	SYS.h
- *
- *	Definition of the user side of the UNIX system call interface
- *	for M98K.
- *
- *	Errors are flagged by the location of the trap return (ie., which
- *	instruction is executed upon rfi):
- *
- *		SC PC + 4:	Error (typically branch to cerror())
- *		SC PC + 8:	Success
- *
- * HISTORY
- * 18-Nov-92	Ben Fathi (benf at next.com)
- *	Ported to m98k.
- *
- *  9-Jan-92	Peter King (king at next.com)
- *	Created.
- */
-
-#define KERNEL_PRIVATE	1
-/*
- * Header files.
- */
-#import	<architecture/ppc/asm_help.h>
-#import	<architecture/ppc/pseudo_inst.h>
-#import	<mach/ppc/exception.h>
-#import	<sys/syscall.h>
-
-/* From rhapsody kernel mach/ppc/syscall_sw.h */
-#define	kernel_trap_args_0
-#define	kernel_trap_args_1
-#define	kernel_trap_args_2
-#define	kernel_trap_args_3
-#define	kernel_trap_args_4
-#define	kernel_trap_args_5
-#define	kernel_trap_args_6
-#define	kernel_trap_args_7
-
-/*
- * simple_kernel_trap -- Mach system calls with 8 or less args
- * Args are passed in a0 - a7, system call number in r0.
- * Do a "sc" instruction to enter kernel.
- */	
-#define simple_kernel_trap(trap_name, trap_number)	\
-	.globl	_##trap_name				@\
-_##trap_name:						@\
-	li	r0,trap_number				 @\
-	sc						 @\
-	blr						 @\
-	END(trap_name)
-
-#define kernel_trap_0(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_1(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_2(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_3(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_4(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_5(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_6(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_7(trap_name,trap_number)		 \
-	simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_8(trap_name,trap_number)		 \
-        simple_kernel_trap(trap_name,trap_number)
-
-#define kernel_trap_9(trap_name,trap_number)		 \
-        simple_kernel_trap(trap_name,trap_number)
-
-/* End of rhapsody kernel mach/ppc/syscall_sw.h */
-
-/*
- * Macros.
- */
-
-#define	SYSCALL(name, nargs)			\
-	.globl	cerror				@\
-LEAF(_##name)					@\
-	kernel_trap_args_##nargs		@\
-	li	r0,SYS_##name			@\
-	sc					@\
-	b	1f   				@\
-	b	2f				@\
-1:	BRANCH_EXTERN(cerror)			@\
-.text						\
-2:	nop
-
-#define	SYSCALL_NONAME(name, nargs)		\
-	.globl	cerror				@\
-	kernel_trap_args_##nargs		@\
-	li	r0,SYS_##name			@\
-	sc					@\
-	b	1f   				@\
-	b	2f				@\
-1:	BRANCH_EXTERN(cerror)			@\
-.text						\
-2:	nop
-
-#define	PSEUDO(pseudo, name, nargs)		\
-LEAF(_##pseudo)					@\
-	SYSCALL_NONAME(name, nargs)
-
-
-#undef END
-#import	<mach/ppc/syscall_sw.h>
-
-#if !defined(SYS_getdirentriesattr)
-#define SYS_getdirentriesattr 222
-#endif
-
-#if !defined(SYS_semsys)
-#define SYS_semsys	251
-#define SYS_msgsys	252
-#define SYS_shmsys	253
-#define SYS_semctl	254
-#define SYS_semget	255
-#define SYS_semop	256
-#define SYS_semconfig	257
-#define SYS_msgctl	258
-#define SYS_msgget	259
-#define SYS_msgsnd	260
-#define SYS_msgrcv	261
-#define SYS_shmat	262
-#define SYS_shmctl	263
-#define SYS_shmdt	264
-#define SYS_shmget	265
-#endif
- 

Deleted: box/chris/win32/vc2005-compile-fixes/test/raidfile/Makefile.extra.Darwin
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/raidfile/Makefile.extra.Darwin	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/raidfile/Makefile.extra.Darwin	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,6 +0,0 @@
-
-# link-extra: intercept-lseek.o intercept-close.o intercept-open.o intercept-read.o intercept-readv.o intercept-write.o
-
-$(OUTDIR)/intercept-lseek.o:	make-darwin-intercepts.pl $(OUTDIR)
-	./make-darwin-intercepts.pl $(OUTDIR)
-

Modified: box/chris/win32/vc2005-compile-fixes/test/raidfile/intercept.cpp
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/raidfile/intercept.cpp	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/raidfile/intercept.cpp	2006-02-03 20:21:10 UTC (rev 365)
@@ -162,6 +162,15 @@
 }
 
 extern "C" int
+open64(const char *path, int flags, mode_t mode)
+{
+	// With _FILE_OFFSET_BITS set to 64 this should really use (flags |
+	// O_LARGEFILE) here, but not actually necessary for the tests and not
+	// worth the trouble finding O_LARGEFILE
+	return open(path, flags, mode);
+}
+
+extern "C" int
 close(int d)
 {
 	CHECK_FOR_FAKE_ERROR_COND(d, SIZE_ALWAYS_ERROR, SYS_close, -1);
@@ -245,6 +254,10 @@
 #else
 	#ifdef HAVE_LSEEK_DUMMY_PARAM
 		off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence);
+	#elif defined(_FILE_OFFSET_BITS)
+		// Don't bother trying to call SYS__llseek on 32 bit since it is
+		// fiddly and not needed for the tests
+		off_t r = syscall(SYS_lseek, fildes, (uint32_t)offset, whence);
 	#else
 		off_t r = syscall(SYS_lseek, fildes, offset, whence);
 	#endif

Deleted: box/chris/win32/vc2005-compile-fixes/test/raidfile/make-darwin-intercepts.pl
===================================================================
--- box/chris/win32/vc2005-compile-fixes/test/raidfile/make-darwin-intercepts.pl	2006-02-03 19:58:38 UTC (rev 364)
+++ box/chris/win32/vc2005-compile-fixes/test/raidfile/make-darwin-intercepts.pl	2006-02-03 20:21:10 UTC (rev 365)
@@ -1,46 +0,0 @@
-#!/usr/bin/perl
-use strict;
-
-my $out = $ARGV[0];
-die "No out directory specified" unless $out ne '';
-
-my @calls = split /[\r\n]+/,<<__E;
-lseek SYSCALL_TEST(lseek, 3)
-open SYSCALL_TEST(open, 3)
-close SYSCALL_TEST(close, 1)
-write SYSCALL_TEST(write, 3)
-read SYSCALL_TEST(read, 3)
-readv SYSCALL_TEST(readv, 3)
-__E
-
-for(@calls)
-{
-	my ($name,$line) = split / /,$_,2;
-	
-	open FL,">$out/intercept-$name.s" or die "Can't open out file";
-	print FL <<'__S';
-#include "../../../test/raidfile/Darwin-SYS.h"
-
-#define	SYSCALL_TEST(name, nargs)			\
-	.globl	cerror				@\
-LEAF(_TEST_##name)					@\
-	kernel_trap_args_##nargs		@\
-	li	r0,SYS_##name			@\
-	sc					@\
-	b	1f   				@\
-	b	2f				@\
-1:	BRANCH_EXTERN(cerror)			@\
-.text						\
-2:	nop
-
-__S
-	print FL $line,"\n\tblr\n\n";
-
-	close FL;
-	
-	if(system("gcc -c $out/intercept-$name.s -o $out/intercept-$name.o") != 0)
-	{
-		die "Assembly failed\n";
-	}
-}
-




More information about the Boxbackup-dev mailing list