From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:21:48 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:21:48 +0100
Subject: [Box Backup-commit] COMMIT r1862 - box/trunk/bin/bbackupd
Message-ID: <E1If1v2-0001la-EU@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:21:48 +0100 (Tue, 09 Oct 2007)
New Revision: 1862

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
Log:
Fix crash when notifyscript is called for BackupStart or BackupFinish.


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-09-23 20:17:01 UTC (rev 1861)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-08 23:21:48 UTC (rev 1862)
@@ -2278,16 +2278,18 @@
 		return;
 	}
 
-	// Is there a notifation script?
+	// Is there a notification script?
 	const Configuration &conf(GetConfiguration());
-	if(!conf.KeyExists("NotifyScript") &&
-		Event != NotifyEvent_BackupStart &&
-		Event != NotifyEvent_BackupFinish)
+	if(!conf.KeyExists("NotifyScript"))
 	{
 		// Log, and then return
-		BOX_ERROR("Not notifying administrator about event "
-			<< sEventNames[Event] << " -- set NotifyScript "
-			"to do this in future");
+		if(Event != NotifyEvent_BackupStart &&
+			Event != NotifyEvent_BackupFinish)
+		{
+			BOX_ERROR("Not notifying administrator about event "
+				<< sEventNames[Event] << " -- set NotifyScript "
+				"to do this in future");
+		}
 		return;
 	}
 


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:23:59 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:23:59 +0100
Subject: [Box Backup-commit] COMMIT r1863 - in box/trunk: bin/bbackupd lib/backupclient
Message-ID: <E1If1x9-000F0l-BT@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:23:59 +0100 (Tue, 09 Oct 2007)
New Revision: 1863

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
   box/trunk/bin/bbackupd/BackupDaemon.h
   box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp
   box/trunk/lib/backupclient/BackupStoreConstants.h
Log:
Allow configuration of the time to delete redundant store locations.


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-08 23:21:48 UTC (rev 1862)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-08 23:23:59 UTC (rev 1863)
@@ -876,6 +876,9 @@
 					SecondsToBoxTime(
 						conf.GetKeyValueInt(
 							"MaxFileTimeInFuture"));
+				mDeleteRedundantLocationsAfter =
+					conf.GetKeyValueInt(
+						"DeleteRedundantLocationsAfter");
 
 				clientContext.SetMaximumDiffingTime(maximumDiffingTime);
 				clientContext.SetKeepAliveTime(keepAliveTime);
@@ -1659,7 +1662,7 @@
 	for(std::list<std::pair<std::string, Configuration> >::const_iterator i = rLocationsConf.mSubConfigurations.begin();
 		i != rLocationsConf.mSubConfigurations.end(); ++i)
 	{
-		BOX_TRACE("new location");
+		BOX_TRACE("new location: " << i->first);
 		// Create a record for it
 		Location *ploc = new Location;
 		try
@@ -1821,12 +1824,12 @@
 		}
 		catch (std::exception &e)
 		{
-			delete ploc;
-			ploc = 0;
 			BOX_ERROR("Failed to configure location '"
 				<< ploc->mName << "' path '"
 				<< ploc->mPath << "': " << e.what() <<
 				": please check for previous errors");
+			delete ploc;
+			ploc = 0;
 			throw;
 		}
 		catch(...)
@@ -1857,8 +1860,7 @@
 			mDeleteUnusedRootDirEntriesAfter == 0)
 		{
 			mDeleteUnusedRootDirEntriesAfter = now + 
-				SecondsToBoxTime(
-				BACKUP_DELETE_UNUSED_ROOT_ENTRIES_AFTER);
+				SecondsToBoxTime(mDeleteRedundantLocationsAfter);
 		}
 
 		int secs = BoxTimeToSeconds(mDeleteUnusedRootDirEntriesAfter

Modified: box/trunk/bin/bbackupd/BackupDaemon.h
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-08 23:21:48 UTC (rev 1862)
+++ box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-08 23:23:59 UTC (rev 1863)
@@ -158,6 +158,8 @@
 	std::vector<BackupClientInodeToIDMap *> mCurrentIDMaps;
 	std::vector<BackupClientInodeToIDMap *> mNewIDMaps;
 	
+	int mDeleteRedundantLocationsAfter;
+
 	// For the command socket
 	class CommandSocketInfo
 	{

Modified: box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp
===================================================================
--- box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp	2007-10-08 23:21:48 UTC (rev 1862)
+++ box/trunk/lib/backupclient/BackupDaemonConfigVerify.cpp	2007-10-08 23:23:59 UTC (rev 1863)
@@ -77,6 +77,7 @@
 				// return "now" if it's allowed, or a number of seconds if it's not
 
 	{"MaximumDiffingTime", 0, ConfigTest_IsInt, 0},
+	{"DeleteRedundantLocationsAfter", "172800", ConfigTest_IsInt, 0},
 
 	{"FileTrackingSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
 	{"DiffingUploadSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},

Modified: box/trunk/lib/backupclient/BackupStoreConstants.h
===================================================================
--- box/trunk/lib/backupclient/BackupStoreConstants.h	2007-10-08 23:21:48 UTC (rev 1862)
+++ box/trunk/lib/backupclient/BackupStoreConstants.h	2007-10-08 23:23:59 UTC (rev 1863)
@@ -40,14 +40,5 @@
 // This is a multiple of the number of blocks in the diff from file.
 #define BACKUP_FILE_DIFF_MAX_BLOCK_FIND_MULTIPLE	4096
 
-// How many seconds to wait before deleting unused root directory entries?
-#ifndef NDEBUG
-	// Debug: 30 seconds (easier to test)
-	#define BACKUP_DELETE_UNUSED_ROOT_ENTRIES_AFTER		30
-#else
-	// Release: 2 days (plenty of time for sysadmins to notice, or change their mind)
-	#define BACKUP_DELETE_UNUSED_ROOT_ENTRIES_AFTER		172800
-#endif
-
 #endif // BACKUPSTORECONSTANTS__H
 


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:24:26 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:24:26 +0100
Subject: [Box Backup-commit] COMMIT r1864 - box/trunk/lib/common
Message-ID: <E1If1xa-000BBy-5N@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:24:26 +0100 (Tue, 09 Oct 2007)
New Revision: 1864

Modified:
   box/trunk/lib/common/Logging.h
Log:
Revert from hex to decimal default format after logging an account number.


Modified: box/trunk/lib/common/Logging.h
===================================================================
--- box/trunk/lib/common/Logging.h	2007-10-08 23:23:59 UTC (rev 1863)
+++ box/trunk/lib/common/Logging.h	2007-10-08 23:24:26 UTC (rev 1864)
@@ -49,7 +49,8 @@
 	std::internal << \
 	std::setw(10) << \
 	std::setfill('0') << \
-	(accno)
+	(accno) \\
+	std::dec
 
 #define BOX_FORMAT_OBJECTID(objectid) \
 	std::hex << \


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:24:43 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:24:43 +0100
Subject: [Box Backup-commit] COMMIT r1865 - box/trunk/lib/common
Message-ID: <E1If1xr-000ITY-FF@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:24:43 +0100 (Tue, 09 Oct 2007)
New Revision: 1865

Modified:
   box/trunk/lib/common/Configuration.cpp
Log:
Log the name of missing configuration keys before throwing exception.


Modified: box/trunk/lib/common/Configuration.cpp
===================================================================
--- box/trunk/lib/common/Configuration.cpp	2007-10-08 23:24:26 UTC (rev 1864)
+++ box/trunk/lib/common/Configuration.cpp	2007-10-08 23:24:43 UTC (rev 1865)
@@ -319,6 +319,7 @@
 	
 	if(i == mKeys.end())
 	{
+		BOX_ERROR("Missing configuration key: " << pKeyName);
 		THROW_EXCEPTION(CommonException, ConfigNoKey)
 	}
 	else


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:25:36 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:25:36 +0100
Subject: [Box Backup-commit] COMMIT r1866 - box/trunk
Message-ID: <E1If1yi-0009T7-Ao@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:25:36 +0100 (Tue, 09 Oct 2007)
New Revision: 1866

Modified:
   box/trunk/configure.ac
Log:
Die if infrastructure/makebuildenv.pl or infrastructure/makeparcels.pl fails
during configure.


Modified: box/trunk/configure.ac
===================================================================
--- box/trunk/configure.ac	2007-10-08 23:24:43 UTC (rev 1865)
+++ box/trunk/configure.ac	2007-10-08 23:25:36 UTC (rev 1866)
@@ -281,8 +281,11 @@
 
 # Configure the Box build system
 echo
-$PERL ./infrastructure/makebuildenv.pl &&
-  $PERL ./infrastructure/makeparcels.pl
+if ! $PERL ./infrastructure/makebuildenv.pl \
+|| ! $PERL ./infrastructure/makeparcels.pl; then
+	echo "Making infrastructure failed!"
+	exit 1
+fi
 
 # Write summary of important info
 cat <<EOC


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:26:26 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:26:26 +0100
Subject: [Box Backup-commit] COMMIT r1867 - in box/trunk/test/bbackupd: . testfiles
Message-ID: <E1If1zW-000O87-HN@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:26:26 +0100 (Tue, 09 Oct 2007)
New Revision: 1867

Added:
   box/trunk/test/bbackupd/testfiles/bbackupd-temploc.conf
Modified:
   box/trunk/test/bbackupd/testbbackupd.cpp
   box/trunk/test/bbackupd/testfiles/bbackupd.conf.in
Log:
Test that redundant locations are really deleted after the time expires.


Modified: box/trunk/test/bbackupd/testbbackupd.cpp
===================================================================
--- box/trunk/test/bbackupd/testbbackupd.cpp	2007-10-08 23:25:36 UTC (rev 1866)
+++ box/trunk/test/bbackupd/testbbackupd.cpp	2007-10-08 23:26:26 UTC (rev 1867)
@@ -605,6 +605,42 @@
 	TEST_THAT(id != BackupProtocolClientListDirectory::RootDirectory);
 	return id;
 }
+
+SocketStreamTLS sSocket;
+
+std::auto_ptr<BackupProtocolClient> Connect(TLSContext& rContext, int flags)
+{
+	sSocket.Open(rContext, Socket::TypeINET, 
+		"localhost", BOX_PORT_BBSTORED);
+	std::auto_ptr<BackupProtocolClient> connection;
+	connection.reset(new BackupProtocolClient(sSocket));
+	connection->Handshake();
+	std::auto_ptr<BackupProtocolClientVersion> 
+		serverVersion(connection->QueryVersion(
+			BACKUP_STORE_SERVER_VERSION));
+	if(serverVersion->GetVersion() != 
+		BACKUP_STORE_SERVER_VERSION)
+	{
+		THROW_EXCEPTION(BackupStoreException, 
+			WrongServerVersion);
+	}
+	connection->QueryLogin(0x01234567, flags);
+	return connection;
+}
+
+std::auto_ptr<BackupStoreDirectory> ReadDirectory
+(
+	BackupProtocolClient& rClient,
+	int64_t id
+)
+{
+	std::auto_ptr<BackupProtocolClientSuccess> dirreply(
+		rClient.QueryListDirectory(id, false, 0, false));
+	std::auto_ptr<IOStream> dirstream(rClient.ReceiveStream());
+	std::auto_ptr<BackupStoreDirectory> apDir(new BackupStoreDirectory());
+	apDir->ReadFromStream(*dirstream, rClient.GetTimeout());
+	return apDir;
+}
 	
 int start_internal_daemon()
 {
@@ -1050,7 +1086,10 @@
 	}
 #endif // PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
 
-	std::string cmd = BBACKUPD + bbackupd_args + " testfiles/bbackupd.conf";
+	printf("\n==== Testing that redundant locations are deleted on time\n");
+
+	std::string cmd = BBACKUPD + bbackupd_args + 
+		" testfiles/bbackupd-temploc.conf";
 	bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid");
 
 	TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0);
@@ -1062,6 +1101,74 @@
 	if (!ServerIsAlive(bbackupd_pid)) return 1;
 	if (!ServerIsAlive(bbstored_pid)) return 1;
 
+	{
+		std::auto_ptr<BackupProtocolClient> client = Connect(
+			context,
+			BackupProtocolClientLogin::Flags_ReadOnly);
+		
+		std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory(
+			*client,
+			BackupProtocolClientListDirectory::RootDirectory);
+
+		// int64_t testDirId = SearchDir(*dir, "Test2");
+		// TEST_THAT(testDirId == 0);
+
+		sync_and_wait();
+
+		dir = ReadDirectory(*client,
+			BackupProtocolClientListDirectory::RootDirectory);
+		int64_t testDirId = SearchDir(*dir, "Test2");
+		TEST_THAT(testDirId != 0);
+
+		// Kill the daemon
+		terminate_bbackupd(bbackupd_pid);
+
+		cmd = BBACKUPD + bbackupd_args + " testfiles/bbackupd.conf";
+		bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid");
+
+		TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0);
+
+		::safe_sleep(1);
+
+		TEST_THAT(ServerIsAlive(bbackupd_pid));
+		TEST_THAT(ServerIsAlive(bbstored_pid));
+		if (!ServerIsAlive(bbackupd_pid)) return 1;
+		if (!ServerIsAlive(bbstored_pid)) return 1;
+
+		// Test2 should be deleted after 10 seconds (4 runs)
+		wait_for_sync_end();
+		wait_for_sync_end();
+		wait_for_sync_end();
+
+		dir = ReadDirectory(*client,
+			BackupProtocolClientListDirectory::RootDirectory);
+		testDirId = SearchDir(*dir, "Test2");
+		TEST_THAT(testDirId != 0);
+
+		wait_for_sync_end();
+		
+		dir = ReadDirectory(*client,
+			BackupProtocolClientListDirectory::RootDirectory);
+		testDirId = SearchDir(*dir, "Test2");
+		TEST_THAT(testDirId != 0);
+
+		BackupStoreDirectory::Iterator i(*dir);
+		BackupStoreFilenameClear dirname("Test2");
+		BackupStoreDirectory::Entry *en = i.FindMatchingClearName(dirname);
+		TEST_THAT(en != 0);
+		int16_t en_flags = en->GetFlags();
+		TEST_THAT(en_flags && BackupStoreDirectory::Entry::Flags_Deleted);
+
+		// Log out.
+		client->QueryFinished();
+		sSocket.Close();
+	}
+
+	TEST_THAT(ServerIsAlive(bbackupd_pid));
+	TEST_THAT(ServerIsAlive(bbstored_pid));
+	if (!ServerIsAlive(bbackupd_pid)) return 1;
+	if (!ServerIsAlive(bbstored_pid)) return 1;
+
 	if(bbackupd_pid > 0)
 	{
 		printf("\n==== Testing that backup pauses when store is full\n");
@@ -1311,40 +1418,25 @@
 
 		// Check that we can find it in directory listing
 		{
-			SocketStreamTLS conn;
-			conn.Open(context, Socket::TypeINET, "localhost", 
-				BOX_PORT_BBSTORED);
-			BackupProtocolClient protocol(conn);
-			protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
-			protocol.QueryLogin(0x01234567, 0);
+			std::auto_ptr<BackupProtocolClient> client =
+				Connect(context, 0);
 
-			int64_t rootDirId = BackupProtocolClientListDirectory
-				::RootDirectory;
-			std::auto_ptr<BackupProtocolClientSuccess> dirreply(
-				protocol.QueryListDirectory(
-					rootDirId, false, 0, false));
-			std::auto_ptr<IOStream> dirstream(
-				protocol.ReceiveStream());
-			BackupStoreDirectory dir;
-			dir.ReadFromStream(*dirstream, protocol.GetTimeout());
+			std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory(
+				*client, 
+				BackupProtocolClientListDirectory::RootDirectory);
 
-			int64_t baseDirId = SearchDir(dir, "Test1");
+			int64_t baseDirId = SearchDir(*dir, "Test1");
 			TEST_THAT(baseDirId != 0);
-			dirreply = protocol.QueryListDirectory(baseDirId,
-				false, 0, false);
-			dirstream = protocol.ReceiveStream();
-			dir.ReadFromStream(*dirstream, protocol.GetTimeout());
+			dir = ReadDirectory(*client, baseDirId);
 
 			int64_t testDirId = SearchDir(dir, dirname.c_str());
 			TEST_THAT(testDirId != 0);
-			dirreply = protocol.QueryListDirectory(testDirId,
-				false, 0, false);
-			dirstream = protocol.ReceiveStream();
-			dir.ReadFromStream(*dirstream, protocol.GetTimeout());
+			dir = ReadDirectory(*client, testDirId);
 		
 			TEST_THAT(SearchDir(dir, filename.c_str()) != 0);
 			// Log out
-			protocol.QueryFinished();
+			client->QueryFinished();
+			sSocket.Close();
 		}
 
 
@@ -2092,75 +2184,37 @@
 			"actually work\n");
 
 		{
-			std::string errs;
-			std::auto_ptr<Configuration> config(
-				Configuration::LoadAndVerify(
-					"testfiles/bbackupd.conf",
-					&BackupDaemonConfigVerify, errs));
-			Configuration& conf(*config);
-			SSLLib::Initialise();
-			TLSContext tlsContext;
-			std::string certFile(conf.GetKeyValue("CertificateFile"));
-			std::string keyFile (conf.GetKeyValue("PrivateKeyFile"));
-			std::string caFile  (conf.GetKeyValue("TrustedCAsFile"));
-			tlsContext.Initialise(false, certFile.c_str(), 
-				keyFile.c_str(), caFile.c_str());
-			BackupClientCryptoKeys_Setup(
-				conf.GetKeyValue("KeysFile").c_str());
-			SocketStreamTLS socket;
-			socket.Open(tlsContext, Socket::TypeINET, 
-				conf.GetKeyValue("StoreHostname").c_str(), 
-				BOX_PORT_BBSTORED);
-			BackupProtocolClient connection(socket);
-			connection.Handshake();
-			std::auto_ptr<BackupProtocolClientVersion> 
-				serverVersion(connection.QueryVersion(
-					BACKUP_STORE_SERVER_VERSION));
-			if(serverVersion->GetVersion() != 
-				BACKUP_STORE_SERVER_VERSION)
-			{
-				THROW_EXCEPTION(BackupStoreException, 
-					WrongServerVersion);
-			}
-			connection.QueryLogin(
-				conf.GetKeyValueInt("AccountNumber"),
+			std::auto_ptr<BackupProtocolClient> client = Connect(
+				context,
 				BackupProtocolClientLogin::Flags_ReadOnly);
 			
-			int64_t rootDirId = BackupProtocolClientListDirectory
-				::RootDirectory;
-			std::auto_ptr<BackupProtocolClientSuccess> dirreply(
-				connection.QueryListDirectory(
-					rootDirId, false, 0, false));
-			std::auto_ptr<IOStream> dirstream(
-				connection.ReceiveStream());
-			BackupStoreDirectory dir;
-			dir.ReadFromStream(*dirstream, connection.GetTimeout());
+			std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory(
+				*client,
+				BackupProtocolClientListDirectory::RootDirectory);
 
-			int64_t testDirId = SearchDir(dir, "Test1");
+			int64_t testDirId = SearchDir(*dir, "Test1");
 			TEST_THAT(testDirId != 0);
-			dirreply = connection.QueryListDirectory(testDirId, 					false, 0, false);
-			dirstream = connection.ReceiveStream();
-			dir.ReadFromStream(*dirstream, connection.GetTimeout());
-			
-			TEST_THAT(!SearchDir(dir, "excluded_1"));
-			TEST_THAT(!SearchDir(dir, "excluded_2"));
-			TEST_THAT(!SearchDir(dir, "exclude_dir"));
-			TEST_THAT(!SearchDir(dir, "exclude_dir_2"));
+			dir = ReadDirectory(*client, testDirId);
+				
+			TEST_THAT(!SearchDir(*dir, "excluded_1"));
+			TEST_THAT(!SearchDir(*dir, "excluded_2"));
+			TEST_THAT(!SearchDir(*dir, "exclude_dir"));
+			TEST_THAT(!SearchDir(*dir, "exclude_dir_2"));
 			// xx_not_this_dir_22 should not be excluded by
 			// ExcludeDirsRegex, because it's a file
-			TEST_THAT(SearchDir (dir, "xx_not_this_dir_22"));
-			TEST_THAT(!SearchDir(dir, "zEXCLUDEu"));
-			TEST_THAT(SearchDir (dir, "dont.excludethis"));
-			TEST_THAT(SearchDir (dir, "xx_not_this_dir_ALWAYSINCLUDE"));
+			TEST_THAT(SearchDir (*dir, "xx_not_this_dir_22"));
+			TEST_THAT(!SearchDir(*dir, "zEXCLUDEu"));
+			TEST_THAT(SearchDir (*dir, "dont.excludethis"));
+			TEST_THAT(SearchDir (*dir, "xx_not_this_dir_ALWAYSINCLUDE"));
 
-			int64_t sub23id = SearchDir(dir, "sub23");
+			int64_t sub23id = SearchDir(*dir, "sub23");
 			TEST_THAT(sub23id != 0);
-			dirreply = connection.QueryListDirectory(sub23id, 					false, 0, false);
-			dirstream = connection.ReceiveStream();
-			dir.ReadFromStream(*dirstream, connection.GetTimeout());
-			TEST_THAT(!SearchDir(dir, "xx_not_this_dir_22"));
-			TEST_THAT(!SearchDir(dir, "somefile.excludethis"));
-			connection.QueryFinished();
+			dir = ReadDirectory(*client, sub23id);
+
+			TEST_THAT(!SearchDir(*dir, "xx_not_this_dir_22"));
+			TEST_THAT(!SearchDir(*dir, "somefile.excludethis"));
+			client->QueryFinished();
+			sSocket.Close();
 		}
 
 		TEST_THAT(ServerIsAlive(bbackupd_pid));
@@ -2303,22 +2357,17 @@
 		int64_t restoredirid = 0;
 		{
 			// connect and log in
-			SocketStreamTLS conn;
-			conn.Open(context, Socket::TypeINET, "localhost", 
-				BOX_PORT_BBSTORED);
-			BackupProtocolClient protocol(conn);
-			protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
-			std::auto_ptr<BackupProtocolClientLoginConfirmed> 
-				loginConf(protocol.QueryLogin(0x01234567, 
-				BackupProtocolClientLogin::Flags_ReadOnly));
+			std::auto_ptr<BackupProtocolClient> client = Connect(
+				context,
+				BackupProtocolClientLogin::Flags_ReadOnly);
 
 			// Find the ID of the Test1 directory
-			restoredirid = GetDirID(protocol, "Test1", 
+			restoredirid = GetDirID(*client, "Test1", 
 				BackupProtocolClientListDirectory::RootDirectory);
 			TEST_THAT(restoredirid != 0);
 
 			// Test the restoration
-			TEST_THAT(BackupClientRestore(protocol, restoredirid, 
+			TEST_THAT(BackupClientRestore(*client, restoredirid, 
 				"testfiles/restore-Test1", 
 				true /* print progress dots */) 
 				== Restore_Complete);
@@ -2327,32 +2376,33 @@
 			// to the server, so we'll compare later.
 
 			// Make sure you can't restore a restored directory
-			TEST_THAT(BackupClientRestore(protocol, restoredirid, 
+			TEST_THAT(BackupClientRestore(*client, restoredirid, 
 				"testfiles/restore-Test1", 
 				true /* print progress dots */) 
 				== Restore_TargetExists);
 			
 			// Make sure you can't restore to a nonexistant path
 			printf("Try to restore to a path that doesn't exist\n");
-			TEST_THAT(BackupClientRestore(protocol, restoredirid, 
+			TEST_THAT(BackupClientRestore(*client, restoredirid, 
 				"testfiles/no-such-path/subdir", 
 				true /* print progress dots */) 
 				== Restore_TargetPathNotFound);
 			
 			// Find ID of the deleted directory
-			deldirid = GetDirID(protocol, "x1", restoredirid);
+			deldirid = GetDirID(*client, "x1", restoredirid);
 			TEST_THAT(deldirid != 0);
 
 			// Just check it doesn't bomb out -- will check this 
 			// properly later (when bbackupd is stopped)
-			TEST_THAT(BackupClientRestore(protocol, deldirid, 
+			TEST_THAT(BackupClientRestore(*client, deldirid, 
 				"testfiles/restore-Test1-x1", 
 				true /* print progress dots */, 
 				true /* deleted files */) 
 				== Restore_Complete);
 
 			// Log out
-			protocol.QueryFinished();
+			client->QueryFinished();
+			sSocket.Close();
 		}
 
 		// Compare the restored files
@@ -2659,24 +2709,19 @@
 
 			printf("\n==== Resume restore\n");
 
-			SocketStreamTLS conn;
-			conn.Open(context, Socket::TypeINET, "localhost", 
-				BOX_PORT_BBSTORED);
-			BackupProtocolClient protocol(conn);
-			protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
-			std::auto_ptr<BackupProtocolClientLoginConfirmed> 
-				loginConf(protocol.QueryLogin(0x01234567, 
-				0 /* read-write */));
+			std::auto_ptr<BackupProtocolClient> client = Connect(
+				context,
+				BackupProtocolClientLogin::Flags_ReadOnly);
 
 			// Check that the restore fn returns resume possible,
 			// rather than doing anything
-			TEST_THAT(BackupClientRestore(protocol, restoredirid, 
+			TEST_THAT(BackupClientRestore(*client, restoredirid, 
 				"testfiles/restore-interrupt", 
 				true /* print progress dots */) 
 				== Restore_ResumePossible);
 
 			// Then resume it
-			TEST_THAT(BackupClientRestore(protocol, restoredirid, 
+			TEST_THAT(BackupClientRestore(*client, restoredirid, 
 				"testfiles/restore-interrupt", 
 				true /* print progress dots */, 
 				false /* deleted files */, 
@@ -2684,7 +2729,8 @@
 				true /* resume */) 
 				== Restore_Complete);
 
-			protocol.QueryFinished();
+			client->QueryFinished();
+			sSocket.Close();
 
 			// Then check it has restored the correct stuff
 			compareReturnValue = ::system(BBACKUPQUERY " -q "
@@ -2705,24 +2751,19 @@
 		printf("\n==== Check restore deleted files\n");
 
 		{
-			SocketStreamTLS conn;
-			conn.Open(context, Socket::TypeINET, "localhost", 
-				BOX_PORT_BBSTORED);
-			BackupProtocolClient protocol(conn);
-			protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
-			std::auto_ptr<BackupProtocolClientLoginConfirmed> 
-				loginConf(protocol.QueryLogin(0x01234567, 
-				0 /* read-write */));
+			std::auto_ptr<BackupProtocolClient> client = Connect(
+				context, 0 /* read-write */);
 
 			// Do restore and undelete
-			TEST_THAT(BackupClientRestore(protocol, deldirid, 
+			TEST_THAT(BackupClientRestore(*client, deldirid, 
 				"testfiles/restore-Test1-x1-2", 
 				true /* print progress dots */, 
 				true /* deleted files */, 
 				true /* undelete on server */) 
 				== Restore_Complete);
 
-			protocol.QueryFinished();
+			client->QueryFinished();
+			sSocket.Close();
 
 			// Do a compare with the now undeleted files
 			compareReturnValue = ::system(BBACKUPQUERY " -q "

Copied: box/trunk/test/bbackupd/testfiles/bbackupd-temploc.conf (from rev 1809, box/chris/merge/test/bbackupd/testfiles/bbackupd.conf.in)
===================================================================
--- box/trunk/test/bbackupd/testfiles/bbackupd-temploc.conf	                        (rev 0)
+++ box/trunk/test/bbackupd/testfiles/bbackupd-temploc.conf	2007-10-08 23:26:26 UTC (rev 1867)
@@ -0,0 +1,54 @@
+
+CertificateFile = testfiles/clientCerts.pem
+PrivateKeyFile = testfiles/clientPrivKey.pem
+TrustedCAsFile = testfiles/clientTrustedCAs.pem
+
+KeysFile = testfiles/bbackupd.keys
+
+DataDirectory = testfiles/bbackupd-data
+
+StoreHostname = localhost
+AccountNumber = 0x01234567
+
+UpdateStoreInterval = 3
+MinimumFileAge = 4
+MaxUploadWait = 24
+
+FileTrackingSizeThreshold = 1024
+DiffingUploadSizeThreshold = 1024
+
+MaximumDiffingTime = 3
+KeepAliveTime = 1
+
+ExtendedLogging = no
+ExtendedLogFile = testfiles/bbackupd.log
+
+CommandSocket = testfiles/bbackupd.sock
+
+Server
+{
+	PidFile = testfiles/bbackupd.pid
+}
+
+BackupLocations
+{
+	Test1
+	{
+		Path = testfiles/TestDir1
+
+		ExcludeFile = testfiles/TestDir1/excluded_1
+		ExcludeFile = testfiles/TestDir1/excluded_2
+		ExcludeFilesRegex = \.excludethis$
+		ExcludeFilesRegex = EXCLUDE
+		AlwaysIncludeFile = testfiles/TestDir1/dont.excludethis
+		ExcludeDir = testfiles/TestDir1/exclude_dir
+		ExcludeDir = testfiles/TestDir1/exclude_dir_2
+		ExcludeDirsRegex = not_this_dir
+		AlwaysIncludeDirsRegex = ALWAYSINCLUDE
+	}
+	Test2
+	{
+		Path = testfiles/TestDir1
+	}
+}
+

Modified: box/trunk/test/bbackupd/testfiles/bbackupd.conf.in
===================================================================
--- box/trunk/test/bbackupd/testfiles/bbackupd.conf.in	2007-10-08 23:25:36 UTC (rev 1866)
+++ box/trunk/test/bbackupd/testfiles/bbackupd.conf.in	2007-10-08 23:26:26 UTC (rev 1867)
@@ -13,6 +13,7 @@
 UpdateStoreInterval = 3
 MinimumFileAge = 4
 MaxUploadWait = 24
+DeleteRedundantLocationsAfter = 10
 
 FileTrackingSizeThreshold = 1024
 DiffingUploadSizeThreshold = 1024


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:27:40 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:27:40 +0100
Subject: [Box Backup-commit] COMMIT r1868 - in box/trunk/lib: backupstore compress server
Message-ID: <E1If20i-000ODU-7d@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:27:40 +0100 (Tue, 09 Oct 2007)
New Revision: 1868

Modified:
   box/trunk/lib/backupstore/BackupStoreInfo.h
   box/trunk/lib/compress/Compress.h
   box/trunk/lib/server/ProtocolUncertainStream.h
Log:
Fix wrong comments, thanks to Nestor Arocha Rodriguez.


Modified: box/trunk/lib/backupstore/BackupStoreInfo.h
===================================================================
--- box/trunk/lib/backupstore/BackupStoreInfo.h	2007-10-08 23:26:26 UTC (rev 1867)
+++ box/trunk/lib/backupstore/BackupStoreInfo.h	2007-10-08 23:27:40 UTC (rev 1868)
@@ -18,7 +18,7 @@
 
 // --------------------------------------------------------------------------
 //
-// File
+// Class
 //		Name:    BackupStoreInfo
 //		Purpose: Main backup store information storage
 //		Created: 2003/08/28

Modified: box/trunk/lib/compress/Compress.h
===================================================================
--- box/trunk/lib/compress/Compress.h	2007-10-08 23:26:26 UTC (rev 1867)
+++ box/trunk/lib/compress/Compress.h	2007-10-08 23:27:40 UTC (rev 1868)
@@ -1,7 +1,7 @@
 // --------------------------------------------------------------------------
 //
 // File
-//		Name:    CompressContext.h
+//		Name:    Compress.h
 //		Purpose: Interface to zlib compression
 //		Created: 5/12/03
 //
@@ -17,7 +17,7 @@
 // --------------------------------------------------------------------------
 //
 // Class
-//		Name:    CompressContext
+//		Name:    Compress
 //		Purpose: Interface to zlib compression, only very slight wrapper.
 //				 (Use CompressStream for a more friendly interface.)
 //		Created: 5/12/03

Modified: box/trunk/lib/server/ProtocolUncertainStream.h
===================================================================
--- box/trunk/lib/server/ProtocolUncertainStream.h	2007-10-08 23:26:26 UTC (rev 1867)
+++ box/trunk/lib/server/ProtocolUncertainStream.h	2007-10-08 23:27:40 UTC (rev 1868)
@@ -1,7 +1,7 @@
 // --------------------------------------------------------------------------
 //
 // File
-//		Name:    PartialReadStream.h
+//		Name:    ProtocolUncertainStream.h
 //		Purpose: Read part of another stream
 //		Created: 2003/12/05
 //
@@ -15,7 +15,7 @@
 // --------------------------------------------------------------------------
 //
 // Class
-//		Name:    PartialReadStream
+//		Name:    ProtocolUncertainStream
 //		Purpose: Read part of another stream
 //		Created: 2003/12/05
 //


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:33:24 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:33:24 +0100
Subject: [Box Backup-commit] COMMIT r1869 - box/trunk/lib/common
Message-ID: <E1If26G-000Hnt-9x@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:33:24 +0100 (Tue, 09 Oct 2007)
New Revision: 1869

Modified:
   box/trunk/lib/common/Logging.h
Log:
Revert to decimal properly, and also after logging an Object ID.


Modified: box/trunk/lib/common/Logging.h
===================================================================
--- box/trunk/lib/common/Logging.h	2007-10-08 23:27:40 UTC (rev 1868)
+++ box/trunk/lib/common/Logging.h	2007-10-08 23:33:24 UTC (rev 1869)
@@ -49,13 +49,14 @@
 	std::internal << \
 	std::setw(10) << \
 	std::setfill('0') << \
-	(accno) \\
+	(accno) << \\
 	std::dec
 
 #define BOX_FORMAT_OBJECTID(objectid) \
 	std::hex << \
 	std::showbase << \
-	(objectid)
+	(objectid) << \\
+	std::dec
 
 #undef ERROR
 


From boxbackup-dev@fluffy.co.uk  Tue Oct  9 00:52:52 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 09 Oct 2007 00:52:52 +0100
Subject: [Box Backup-commit] COMMIT r1870 - box/trunk/lib/common
Message-ID: <E1If2P6-000Bfz-2q@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-09 00:52:51 +0100 (Tue, 09 Oct 2007)
New Revision: 1870

Modified:
   box/trunk/lib/common/Logging.h
Log:
Fix double backslashes


Modified: box/trunk/lib/common/Logging.h
===================================================================
--- box/trunk/lib/common/Logging.h	2007-10-08 23:33:24 UTC (rev 1869)
+++ box/trunk/lib/common/Logging.h	2007-10-08 23:52:51 UTC (rev 1870)
@@ -49,13 +49,13 @@
 	std::internal << \
 	std::setw(10) << \
 	std::setfill('0') << \
-	(accno) << \\
+	(accno) << \
 	std::dec
 
 #define BOX_FORMAT_OBJECTID(objectid) \
 	std::hex << \
 	std::showbase << \
-	(objectid) << \\
+	(objectid) << \
 	std::dec
 
 #undef ERROR


From boxbackup-dev@fluffy.co.uk  Tue Oct 16 09:34:26 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 16 Oct 2007 09:34:26 +0100
Subject: [Box Backup-commit] COMMIT r1871 - box/trunk/documentation/boxbackup
Message-ID: <E1Ihhsg-000PCq-H7@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-16 09:34:26 +0100 (Tue, 16 Oct 2007)
New Revision: 1871

Modified:
   box/trunk/documentation/boxbackup/adminguide.xml
Log:
Document the need for -v options when using LogAllFileAccess.


Modified: box/trunk/documentation/boxbackup/adminguide.xml
===================================================================
--- box/trunk/documentation/boxbackup/adminguide.xml	2007-10-08 23:52:51 UTC (rev 1870)
+++ box/trunk/documentation/boxbackup/adminguide.xml	2007-10-16 08:34:26 UTC (rev 1871)
@@ -1160,6 +1160,13 @@
                 file, or crashing while trying to upload it. The logs will be
                 sent to the system log or Windows Event Viewer.</para>
 
+		<para>This generates a <emphasis>lot</emphasis>
+		of output, so it should only be used when instructed, or when
+		you suspect that bbackupd is skipping some files and want to
+		know why. Because it is verbose, the messages are hidden by
+		default even if the option is enabled. To see them, you must
+		run bbackupd with at least one -v option.</para>
+
                 <para>This is a boolean value, which may be set to
                 <quote>Yes</quote> or <quote>No</quote>. The default is of
                 course <quote>No</quote>.</para>
@@ -1971,4 +1978,4 @@
       testing, and should not be relied on in a production environment.</para>
     </section>
   </appendix>
-</book>
\ No newline at end of file
+</book>


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:44:49 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:44:49 +0100
Subject: [Box Backup-commit] COMMIT r1872 - box/trunk/bin/bbackupd
Message-ID: <E1Ii8GX-000IHN-9h@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:44:49 +0100 (Wed, 17 Oct 2007)
New Revision: 1872

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
Log:
Don't abort if one of the location paths doesn't exist, just print a 
warning
and continue.

Use an auto_ptr to avoid memory leaks when setting up a location fails.

(merges [1828])


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-16 08:34:26 UTC (rev 1871)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:44:49 UTC (rev 1872)
@@ -1664,22 +1664,24 @@
 	{
 		BOX_TRACE("new location: " << i->first);
 		// Create a record for it
-		Location *ploc = new Location;
+		std::auto_ptr<Location> apLoc(new Location);
+
 		try
 		{
 			// Setup names in the location record
-			ploc->mName = i->first;
-			ploc->mPath = i->second.GetKeyValue("Path");
+			apLoc->mName = i->first;
+			apLoc->mPath = i->second.GetKeyValue("Path");
 			
 			// Read the exclude lists from the Configuration
-			ploc->mpExcludeFiles = BackupClientMakeExcludeList_Files(i->second);
-			ploc->mpExcludeDirs = BackupClientMakeExcludeList_Dirs(i->second);
+			apLoc->mpExcludeFiles = BackupClientMakeExcludeList_Files(i->second);
+			apLoc->mpExcludeDirs = BackupClientMakeExcludeList_Dirs(i->second);
+
 			// Does this exist on the server?
 			// Remove from dir object early, so that if we fail
 			// to stat the local directory, we still don't 
 			// consider to remote one for deletion.
 			BackupStoreDirectory::Iterator iter(dir);
-			BackupStoreFilenameClear dirname(ploc->mName);	// generate the filename
+			BackupStoreFilenameClear dirname(apLoc->mName);	// generate the filename
 			BackupStoreDirectory::Entry *en = iter.FindMatchingClearName(dirname);
 			int64_t oid = 0;
 			if(en != 0)
@@ -1699,17 +1701,18 @@
 				// BSD style statfs -- includes mount point, which is nice.
 #ifdef HAVE_STRUCT_STATVFS_F_MNTONNAME
 				struct statvfs s;
-				if(::statvfs(ploc->mPath.c_str(), &s) != 0)
+				if(::statvfs(apLoc->mPath.c_str(), &s) != 0)
 #else // HAVE_STRUCT_STATVFS_F_MNTONNAME
 				struct statfs s;
-				if(::statfs(ploc->mPath.c_str(), &s) != 0)
+				if(::statfs(apLoc->mPath.c_str(), &s) != 0)
 #endif // HAVE_STRUCT_STATVFS_F_MNTONNAME
 				{
-					BOX_WARNING("Failed to stat location: "
-						<< ploc->mPath 
-						<< ": " << strerror(errno));
-					THROW_EXCEPTION(CommonException,
-						OSFileError)
+					BOX_WARNING("Failed to stat location "
+						"path '" << apLoc->mPath <<
+						"' (" << strerror(errno) <<
+						"), skipping location '" <<
+						apLoc->mName << "'");
+					continue;
 				}
 
 				// Where the filesystem is mounted
@@ -1718,10 +1721,10 @@
 #else // !HAVE_STRUCT_STATFS_F_MNTONNAME && !WIN32
 
 				// Warn in logs if the directory isn't absolute
-				if(ploc->mPath[0] != '/')
+				if(apLoc->mPath[0] != '/')
 				{
 					BOX_WARNING("Location path '"
-						<< ploc->mPath 
+						<< apLoc->mPath 
 						<< "' is not absolute");
 				}
 				// Go through the mount points found, and find a suitable one
@@ -1736,7 +1739,7 @@
 						// If it matches, the file belongs in that mount point
 						// (sorting order ensures this)
 						BOX_TRACE("checking against mount point " << *i);
-						if(::strncmp(i->c_str(), ploc->mPath.c_str(), i->size()) == 0)
+						if(::strncmp(i->c_str(), apLoc->mPath.c_str(), i->size()) == 0)
 						{
 							// Match
 							mountName = *i;
@@ -1744,7 +1747,7 @@
 						}
 					}
 					BOX_TRACE("mount point chosen for "
-						<< ploc->mPath << " is "
+						<< apLoc->mPath << " is "
 						<< mountName);
 				}
 
@@ -1755,12 +1758,12 @@
 				if(f != mounts.end())
 				{
 					// Yes -- store the index
-					ploc->mIDMapIndex = f->second;
+					apLoc->mIDMapIndex = f->second;
 				}
 				else
 				{
 					// No -- new index
-					ploc->mIDMapIndex = numIDMaps;
+					apLoc->mIDMapIndex = numIDMaps;
 					mounts[mountName] = numIDMaps;
 					
 					// Store the mount name
@@ -1780,7 +1783,7 @@
 				BackupClientFileAttributes attr;
 				try
 				{
-					attr.ReadAttributes(ploc->mPath.c_str(), 
+					attr.ReadAttributes(apLoc->mPath.c_str(), 
 						true /* directories have zero mod times */,
 						0 /* not interested in mod time */, 
 						&attrModTime /* get the attribute modification time */);
@@ -1788,8 +1791,9 @@
 				catch (BoxException &e)
 				{
 					BOX_ERROR("Failed to get attributes "
-						"for path '" << ploc->mPath
-						<< "', skipping.");
+						"for path '" << apLoc->mPath
+						<< "', skipping location '" <<
+						apLoc->mName << "'");
 					continue;
 				}
 				
@@ -1797,7 +1801,8 @@
 				try
 				{
 					MemBlockStream attrStream(attr);
-					std::auto_ptr<BackupProtocolClientSuccess> dirCreate(connection.QueryCreateDirectory(
+					std::auto_ptr<BackupProtocolClientSuccess>
+						dirCreate(connection.QueryCreateDirectory(
 						BackupProtocolClientListDirectory::RootDirectory,
 						attrModTime, dirname, attrStream));
 						
@@ -1807,8 +1812,9 @@
 				catch (BoxException &e)
 				{
 					BOX_ERROR("Failed to create remote "
-						"directory '/" << ploc->mName <<
-						"', skipping location.");
+						"directory '/" << apLoc->mName <<
+						"', skipping location '" <<
+						apLoc->mName << "'");
 					continue;
 				}
 
@@ -1817,31 +1823,25 @@
 			// Create and store the directory object for the root of this location
 			ASSERT(oid != 0);
 			BackupClientDirectoryRecord *precord = new BackupClientDirectoryRecord(oid, i->first);
-			ploc->mpDirectoryRecord.reset(precord);
+			apLoc->mpDirectoryRecord.reset(precord);
 			
 			// Push it back on the vector of locations
-			mLocations.push_back(ploc);
+			mLocations.push_back(apLoc.release());
 		}
 		catch (std::exception &e)
 		{
 			BOX_ERROR("Failed to configure location '"
-				<< ploc->mName << "' path '"
-				<< ploc->mPath << "': " << e.what() <<
+				<< apLoc->mName << "' path '"
+				<< apLoc->mPath << "': " << e.what() <<
 				": please check for previous errors");
-			delete ploc;
-			ploc = 0;
 			throw;
 		}
 		catch(...)
 		{
 			BOX_ERROR("Failed to configure location '"
-				<< ploc->mName << "' path '"
-				<< ploc->mPath << "': please check for "
+				<< apLoc->mName << "' path '"
+				<< apLoc->mPath << "': please check for "
 				"previous errors");
-
-			delete ploc;
-			ploc = NULL;
-
 			throw;
 		}
 	}


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:45:14 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:45:14 +0100
Subject: [Box Backup-commit] COMMIT r1873 - box/trunk/bin/bbackupd/win32
Message-ID: <E1Ii8Gw-000DSC-BO@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:45:14 +0100 (Wed, 17 Oct 2007)
New Revision: 1873

Modified:
   box/trunk/bin/bbackupd/win32/bbackupd.conf
Log:
Update to match improved comments generated by bbackupd-config in recent
versions.

Increase maximum diffing time to 120 seconds (from 20).

Enable KeepAliveTime by default and set to 120 seconds.

Link to James O'Gorman's NotifySysAdmin.vbs VBScript which works on
Windows, replacing the default shell script.

(merges [1829])


Modified: box/trunk/bin/bbackupd/win32/bbackupd.conf
===================================================================
--- box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-17 12:44:49 UTC (rev 1872)
+++ box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-17 12:45:14 UTC (rev 1873)
@@ -12,35 +12,64 @@
 # If you do not install it in the default location - also do not forget to 
 # change the pid file location (below)
 
-
-# This script is run whenever bbackupd encounters a problem which requires
-# the system administrator to assist:
+# This script is run whenever bbackupd changes state or encounters a
+# problem which requires the system administrator to assist:
+#
 # 1) The store is full, and no more data can be uploaded.
 # 2) Some files or directories were not readable.
-# The default script emails the system administrator.
+# 3) A backup run starts or finishes.
+#
+# The default script emails the system administrator, except for backups
+# starting and stopping, where it does nothing.
+#
+# NOTE: If your client does not run a local SMTP server then you MUST
+# edit this script and uncomment the lines near the end, which specify
+# the remote SMTP server to use for sending mail.
 
-# NotifyScript = NotifySysadmin.sh
+NotifyScript = cscript "C:\Program Files\Box Backup\NotifySysAdmin.vbs"
 
 
-# A scan of the local discs will be made once an hour (approximately).
-# To avoid cycles of load on the server, this time is randomly adjusted by a small
+# The number of seconds between backup runs under normal conditions. To avoid 
+# cycles of load on the server, this time is randomly adjusted by a small 
 # percentage as the daemon runs.
 
 UpdateStoreInterval = 3600
 
 
-# A file must have been modified at least 6 hours ago before it will be uploaded.
+# The minimum age of a file, in seconds, that will be uploaded. Avoids 
+# repeated uploads of a file which is constantly being modified.
 
 MinimumFileAge = 21600
 
 
-# If a file is modified repeated, it won't be uploaded immediately in case it's modified again.
-# However, it should be uploaded eventually. This is how long we should wait after first noticing
-# a change. (1 day)
+# If a file is modified repeated, it won't be uploaded immediately in case 
+# it's modified again, due to the MinimumFileAge specified above. However, it 
+# should be uploaded eventually even if it is being modified repeatedly. This 
+# is how long we should wait, in seconds, after first noticing a change. 
+# (86400 seconds = 1 day)
 
 MaxUploadWait = 86400
 
+# If the connection is idle for some time (e.g. over 10 minutes or 600
+# seconds, not sure exactly how long) then the server will give up and
+# disconnect the client, resulting in Connection Protocol_Timeout errors
+# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
+# Also, some firewalls and NAT gateways will kill idle connections after
+# similar lengths of time. 
+#
+# This can happen for example when most files are backed up already and
+# don't need to be sent to the store again, while scanning a large
+# directory, or while calculating diffs of a large file. To avoid this,
+# KeepAliveTime specifies that special keep-alive messages should be sent
+# when the connection is otherwise idle for a certain length of time,
+# specified here in seconds.
+#
+# The default is that these messages are never sent, equivalent to setting
+# this option to zero, but we recommend that all users enable this.
 
+KeepAliveTime = 120
+
+
 # Files above this size (in bytes) are tracked, and if they are renamed they will simply be
 # renamed on the server, rather than being uploaded again. (64k - 1)
 
@@ -53,30 +82,38 @@
 DiffingUploadSizeThreshold = 8192
 
 
-# The limit on how much time is spent diffing files. Most files shouldn't take very long,
-# but if you have really big files you can use this to limit the time spent diffing them.
+# The limit on how much time is spent diffing files, in seconds. Most files 
+# shouldn't take very long, but if you have really big files you can use this 
+# to limit the time spent diffing them.
+#
 # * Reduce if you are having problems with processor usage.
-# * Increase if you have large files, and think the upload of changes is too large and want
-#   to spend more time searching for unchanged blocks.
+#
+# * Increase if you have large files, and think the upload of changes is too 
+#   large and you want bbackupd to spend more time searching for unchanged
+#   blocks.
 
-MaximumDiffingTime = 20
+MaximumDiffingTime = 120
 
-# KeepAliveTime requires Gary's SSL KeepAlive patches
-# KeepAliveTime = 250
 
 # Uncomment this line to see exactly what the daemon is going when it's connected to the server.
 
 # ExtendedLogging = yes
 
 
-# Use this to temporarily stop bbackupd from syncronising or connecting to the store.
-# This specifies a program or script script which is run just before each sync, and ideally
-# the full path to the interpreter. It will be run as the same user bbackupd is running as,
-# usually root.
-# The script prints either "now" or a number to STDOUT (and a terminating newline, no quotes).
-# If the result was "now", then the sync will happen. If it's a number, then the script will
-# be asked again in that number of seconds.
-# For example, you could use this on a laptop to only backup when on a specific network.
+# This specifies a program or script script which is run just before each 
+# sync, and ideally the full path to the interpreter. It will be run as the 
+# same user bbackupd is running as, usually root.
+#
+# The script must output (print) either "now" or a number to STDOUT (and a 
+# terminating newline, no quotes).
+#
+# If the result was "now", then the sync will happen. If it's a number, then 
+# no backup will happen for that number of seconds (bbackupd will pause) and 
+# then the script will be run again.
+#
+# Use this to temporarily stop bbackupd from syncronising or connecting to the 
+# store. For example, you could use this on a laptop to only backup when on a 
+# specific network, or when it has a working Internet connection.
 
 # SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
 
@@ -85,16 +122,21 @@
 
 CommandSocket = pipe
 
+# 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 = C:\Program Files\Box Backup\bbackupd\bbackupd.state
+
 Server
 {
 	PidFile = C:\Program Files\Box Backup\bbackupd\bbackupd.pid
 }
 
-# StoreObjectInfoFile requires Gary's client marker serialisation patch
-# StoreObjectInfoFile = C:\Program Files\Box Backup\bbackupd\bbackupd.dat
 
-# 
 # BackupLocations specifies which locations on disc should be backed up. Each
 # directory is in the format
 # 
@@ -123,15 +165,31 @@
 # files, except one MP3 file in particular.
 # 
 # In general, Exclude excludes a file or directory, unless the directory is
-# explicitly mentioned in a AlwaysInclude directive.
+# explicitly mentioned in a AlwaysInclude directive. However, Box Backup
+# does NOT scan inside excluded directories and will never back up an
+# AlwaysIncluded file or directory inside an excluded directory or any
+# subdirectory thereof.
+#
+# To back up a directory inside an excluded directory, use a configuration
+# like this, to ensure that each directory in the path to the important
+# files is included, but none of their contents will be backed up except
+# the directories futher down that path to the important one.
+#
+# ExcludeDirsRegex = /home/user/bigfiles/.*
+# ExcludeFilesRegex = /home/user/bigfiles/.*
+# AlwaysIncludeDir = /home/user/bigfiles/path
+# AlwaysIncludeDir = /home/user/bigfiles/path/to
+# AlwaysIncludeDir = /home/user/bigfiles/path/important
+# AlwaysIncludeDir = /home/user/bigfiles/path/important/files
+# AlwaysIncludeDirsRegex = /home/user/bigfiles/path/important/files/.*
+# AlwaysIncludeFilesRegex = /home/user/bigfiles/path/important/files/.*
 # 
-# If a directive ends in Regex, then it is a regular expression rather than a
+# If a directive ends in Regex, then it is a regular expression rather than a 
 # explicit full pathname. See
 # 
 # 	man 7 re_format
 # 
 # for the regex syntax on your platform.
-# 
 
 BackupLocations
 {


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:46:32 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:46:32 +0100
Subject: [Box Backup-commit] COMMIT r1874 - box/trunk/bin/bbackupd/win32
Message-ID: <E1Ii8IC-0008Sw-4p@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:46:32 +0100 (Wed, 17 Oct 2007)
New Revision: 1874

Added:
   box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs
Log:
Add script to notify sysadmin by email on backup failure on Win32, 
thanks to James O'Gorman. (merges [1830])



Copied: box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs (from rev 1830, box/chris/general/bin/bbackupd/win32/NotifySysAdmin.vbs)
===================================================================
--- box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs	                        (rev 0)
+++ box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs	2007-10-17 12:46:32 UTC (rev 1874)
@@ -0,0 +1,83 @@
+Dim hostname
+Dim account
+Dim from
+Dim sendto
+Dim subjtmpl
+Dim subject
+Dim body
+Dim smtpserver
+
+Set WshNet = CreateObject("WScript.Network")
+hostname = WshNet.ComputerName
+
+account = "0a1"
+from = "boxbackup@" & hostname
+sendto = "admin@example.com"
+subjtmpl = "BACKUP PROBLEM on host " & hostname
+smtpserver = "smtp.example.com"
+
+Set args = WScript.Arguments
+
+If args(0) = "store-full" Then
+	subject = subjtmpl & " (store full)"
+	body =	"The store account for "&hostname&" is full." & vbCrLf & vbCrLf & _
+			"=============================" & vbCrLf & _
+			"FILES ARE NOT BEING BACKED UP" & vbCrLf & _
+			"=============================" & vbCrLf & vbCrLf & _
+			"Please adjust the limits on account "&account&" on server "&hostname&"." _
+			& vbCrLf
+	SendMail from,sendto,subject,body
+ElseIf args(0) = "read-error" Then
+	subject = subjtmpl & " (read errors)"
+	body =	"Errors occured reading some files or directories for backup on "&hostname&"." _
+			& vbCrLf & vbCrLf & _
+			"===================================" & vbCrLf & _
+			"THESE FILES ARE NOT BEING BACKED UP" & vbCrLf & _
+			"===================================" & vbCrLf & vbCrLf & _
+			"Check the logs on "&hostname&" for the files and directories which caused" & _
+			"these errors, and take appropraite action." & vbCrLf & vbCrLf & _
+			"Other files are being backed up." & vbCrLf
+	SendMail from,sendto,subject,body
+ElseIf args(0) = "backup-start" Or args(0) = "backup-finish" Then
+	' do nothing for these messages by default
+Else
+	subject = subjtmpl & " (unknown)"
+	body =	"The backup daemon on "&hostname&" reported an unknown error." _
+			& vbCrLf & vbCrLf & _
+			"==========================" & vbCrLf & _
+			"FILES MAY NOT BE BACKED UP" & vbCrLf & _
+			"==========================" & vbCrLf & vbCrLf & _
+			"Please check the logs on "&hostname&"." & vbCrLf
+	SendMail from,sendto,subject,body
+End If
+
+Function CheckSMTPSvc()
+	Set objWMISvc = GetObject("winmgmts:" _
+		& "{impersonationLevel=impersonate}!\\.\root\cimv2")
+	Set colSMTPSvc = objWMISvc.ExecQuery("Select * From Win32_Service " _
+		& "Where Name='SMTPSVC'")
+	If colSMTPSvc.Count > 0 Then
+		CheckSMTPSvc = True
+	Else
+		CheckSMTPSvc = False
+	End If
+End Function
+
+Sub SendMail(from,sendto,subject,body)
+	Set objEmail = CreateObject("CDO.Message")
+	Dim cdoschema
+	cdoschema = "http://schemas.microsoft.com/cdo/configuration/"
+	With objEmail
+		.From = from
+		.To = sendto
+		.Subject = subject
+		.TextBody = body
+		If CheckSMTPSvc = False Then
+			.Configuration.Fields.Item(cdoschema & "sendusing") = 2
+			.Configuration.Fields.Item(cdoschema & "smtpserver") = smtpserver
+			.Configuration.Fields.Item(cdoschema & "smtpserverport") = 25
+			.Configuration.Fields.Update
+		End If
+	End With
+	objEmail.Send
+End Sub


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:47:01 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:47:01 +0100
Subject: [Box Backup-commit] COMMIT r1875 - box/trunk/bin/bbackupd
Message-ID: <E1Ii8If-000NIC-2b@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:47:00 +0100 (Wed, 17 Oct 2007)
New Revision: 1875

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
Log:
Don't initialise the command socket thread (on Win32) until the
configuration is known.

Create the command socket (on Win32) with the specified pipe name
in the configuration file.

Commonise some code between Windows and Unix daemon startup.

(merges [1831])


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:46:32 UTC (rev 1874)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:47:00 UTC (rev 1875)
@@ -126,42 +126,33 @@
 		mNotificationsSent[l] = false;
 	}
 
-#ifdef WIN32
-	// Create the event object to signal from main thread to worker
-	// when new messages are queued to be sent to the command socket.
-	mhMessageToSendEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-	if(mhMessageToSendEvent == INVALID_HANDLE_VALUE)
-	{
-		BOX_ERROR("Failed to create event object: error " <<
-			GetLastError());
-		exit(1);
-	}
+	#ifdef WIN32
+		// Create the event object to signal from main thread to
+		// worker when new messages are queued to be sent to the
+		// command socket.
 
-	// Create the event object to signal from worker to main thread
-	// when a command has been received on the command socket.
-	mhCommandReceivedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-	if(mhCommandReceivedEvent == INVALID_HANDLE_VALUE)
-	{
-		BOX_ERROR("Failed to create event object: error " <<
-			GetLastError());
-		exit(1);
-	}
+		mhMessageToSendEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+		if(mhMessageToSendEvent == INVALID_HANDLE_VALUE)
+		{
+			BOX_ERROR("Failed to create event object: error " <<
+				GetLastError());
+			exit(1);
+		}
 
-	// Create the critical section to protect the message queue
-	InitializeCriticalSection(&mMessageQueueLock);
+		// Create the event object to signal from worker to main thread
+		// when a command has been received on the command socket.
 
-	// Create a thread to handle the named pipe
-	HANDLE hThread;
-	unsigned int dwThreadId;
+		mhCommandReceivedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+		if(mhCommandReceivedEvent == INVALID_HANDLE_VALUE)
+		{
+			BOX_ERROR("Failed to create event object: error " <<
+				GetLastError());
+			exit(1);
+		}
 
-	hThread = (HANDLE) _beginthreadex( 
-        	NULL,                        // default security attributes 
-        	0,                           // use default stack size  
-        	HelperThread,                // thread function 
-        	this,                        // argument to thread function 
-        	0,                           // use default creation flags 
-        	&dwThreadId);                // returns the thread identifier 
-#endif
+		// Create the critical section to protect the message queue
+		InitializeCriticalSection(&mMessageQueueLock);
+	#endif
 }
 
 // --------------------------------------------------------------------------
@@ -287,6 +278,7 @@
 #ifdef WIN32
 void BackupDaemon::RunHelperThread(void)
 {
+	const Configuration &conf(GetConfiguration());
 	mpCommandSocketInfo = new CommandSocketInfo;
 	WinNamedPipeStream& rSocket(mpCommandSocketInfo->mListeningSocket);
 
@@ -296,7 +288,8 @@
 	{
 		try
 		{
-			rSocket.Accept(BOX_NAMED_PIPE_NAME);
+			std::string socket = conf.GetKeyValue("CommandSocket");
+			rSocket.Accept(socket);
 		}
 		catch (BoxException &e)
 		{
@@ -331,7 +324,6 @@
 
 			// Send a header line summarising the configuration 
 			// and current state
-			const Configuration &conf(GetConfiguration());
 			char summary[256];
 			size_t summarySize = sprintf(summary, 
 				"bbackupd: %d %d %d %d\nstate %d\n",
@@ -512,31 +504,37 @@
 	// initialise global timer mechanism
 	Timers::Init();
 	
-#ifdef WIN32
-	try
-	{
-		Run2();
-	}
-	catch(...)
-	{
-		Timers::Cleanup();
-		throw;
-	}
-#else // ! WIN32
-	// Ignore SIGPIPE (so that if a command connection is broken, the daemon doesn't terminate)
-	::signal(SIGPIPE, SIG_IGN);
+	#ifdef WIN32
+		// Create a thread to handle the named pipe
+		HANDLE hThread;
+		unsigned int dwThreadId;
 
-	// Create a command socket?
-	const Configuration &conf(GetConfiguration());
-	if(conf.KeyExists("CommandSocket"))
-	{
-		// Yes, create a local UNIX socket
-		mpCommandSocketInfo = new CommandSocketInfo;
-		const char *socketName = conf.GetKeyValue("CommandSocket").c_str();
-		::unlink(socketName);
-		mpCommandSocketInfo->mListeningSocket.Listen(Socket::TypeUNIX, socketName);
-	}
+		hThread = (HANDLE) _beginthreadex( 
+			NULL,         // default security attributes 
+			0,            // use default stack size  
+			HelperThread, // thread function 
+			this,         // argument to thread function 
+			0,            // use default creation flags 
+			&dwThreadId); // returns the thread identifier 
+	#else
+		// Ignore SIGPIPE so that if a command connection is broken,
+		// the daemon doesn't terminate.
+		::signal(SIGPIPE, SIG_IGN);
 
+		// Create a command socket?
+		const Configuration &conf(GetConfiguration());
+		if(conf.KeyExists("CommandSocket"))
+		{
+			// Yes, create a local UNIX socket
+			mpCommandSocketInfo = new CommandSocketInfo;
+			const char *socketName =
+				conf.GetKeyValue("CommandSocket").c_str();
+			::unlink(socketName);
+			mpCommandSocketInfo->mListeningSocket.Listen(
+				Socket::TypeUNIX, socketName);
+		}
+	#endif // !WIN32
+
 	// Handle things nicely on exceptions
 	try
 	{
@@ -544,6 +542,11 @@
 	}
 	catch(...)
 	{
+		#ifdef WIN32
+			// Don't delete the socket, as the helper thread
+			// is probably still using it. Let Windows clean
+			// up after us.
+		#else
 		if(mpCommandSocketInfo != 0)
 		{
 			try 
@@ -563,19 +566,21 @@
 			}
 			mpCommandSocketInfo = 0;
 		}
+		#endif // WIN32
 
 		Timers::Cleanup();
 		
 		throw;
 	}
 
-	// Clean up
-	if(mpCommandSocketInfo != 0)
-	{
-		delete mpCommandSocketInfo;
-		mpCommandSocketInfo = 0;
-	}
-#endif
+	#ifndef WIN32
+		// Clean up
+		if(mpCommandSocketInfo != 0)
+		{
+			delete mpCommandSocketInfo;
+			mpCommandSocketInfo = 0;
+		}
+	#endif
 	
 	Timers::Cleanup();
 }


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:47:37 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:47:37 +0100
Subject: [Box Backup-commit] COMMIT r1876 - box/trunk/bin/bbackupctl
Message-ID: <E1Ii8JF-0001yr-PK@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:47:37 +0100 (Wed, 17 Oct 2007)
New Revision: 1876

Modified:
   box/trunk/bin/bbackupctl/bbackupctl.cpp
Log:
Pass the command socket name from the configuration to 
WinNamedPipeStream, to allow multiple command sockets per system.

Remove unnecessary newlines from log messages.

(merges [1832])


Modified: box/trunk/bin/bbackupctl/bbackupctl.cpp
===================================================================
--- box/trunk/bin/bbackupctl/bbackupctl.cpp	2007-10-17 12:47:00 UTC (rev 1875)
+++ box/trunk/bin/bbackupctl/bbackupctl.cpp	2007-10-17 12:47:37 UTC (rev 1876)
@@ -145,7 +145,8 @@
 	try
 	{
 #ifdef WIN32
-		connection.Connect(BOX_NAMED_PIPE_NAME);
+		std::string socket = conf.GetKeyValue("CommandSocket");
+		connection.Connect(socket);
 #else
 		connection.Open(Socket::TypeUNIX, conf.GetKeyValue("CommandSocket").c_str());
 #endif
@@ -200,7 +201,7 @@
 			"  UpdateStoreInterval = " << updateStoreInterval << 
 			" seconds\n"
 			"  MinimumFileAge = " << minimumFileAge << " seconds\n"
-			"  MaxUploadWait = " << maxUploadWait << " seconds\n");
+			"  MaxUploadWait = " << maxUploadWait << " seconds");
 	}
 
 	std::string stateLine;
@@ -312,7 +313,7 @@
 				{
 					if (syncIsRunning)
 					{
-						if (!quiet) BOX_INFO("Sync finished.\n");
+						if (!quiet) BOX_INFO("Sync finished.");
 						// Send a quit command to finish nicely
 						connection.Write("quit\n", 5);
 					
@@ -335,7 +336,7 @@
 				{
 					if(!quiet)
 					{
-						BOX_INFO("Succeeded.\n");
+						BOX_INFO("Succeeded.");
 					}
 					finished = true;
 				}


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:48:05 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:48:05 +0100
Subject: [Box Backup-commit] COMMIT r1877 - box/trunk/lib/server
Message-ID: <E1Ii8Jh-000CfF-F1@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:48:05 +0100 (Wed, 17 Oct 2007)
New Revision: 1877

Modified:
   box/trunk/lib/server/WinNamedPipeStream.cpp
   box/trunk/lib/server/WinNamedPipeStream.h
Log:
Prepend the system-required prefix to the named pipe name from the
configuration file. (merges [1833])


Modified: box/trunk/lib/server/WinNamedPipeStream.cpp
===================================================================
--- box/trunk/lib/server/WinNamedPipeStream.cpp	2007-10-17 12:47:37 UTC (rev 1876)
+++ box/trunk/lib/server/WinNamedPipeStream.cpp	2007-10-17 12:48:05 UTC (rev 1877)
@@ -26,6 +26,8 @@
 
 #include "MemLeakFindOn.h"
 
+std::string WinNamedPipeStream::sPipeNamePrefix = "\\\\.\\pipe\\";
+
 // --------------------------------------------------------------------------
 //
 // Function
@@ -72,21 +74,23 @@
 // --------------------------------------------------------------------------
 //
 // Function
-//		Name:    WinNamedPipeStream::Accept(const char* Name)
+//		Name:    WinNamedPipeStream::Accept(const std::string& rName)
 //		Purpose: Creates a new named pipe with the given name,
 //			and wait for a connection on it
 //		Created: 2005/12/07
 //
 // --------------------------------------------------------------------------
-void WinNamedPipeStream::Accept(const wchar_t* pName)
+void WinNamedPipeStream::Accept(const std::string& rName)
 {
 	if (mSocketHandle != INVALID_HANDLE_VALUE || mIsConnected) 
 	{
 		THROW_EXCEPTION(ServerException, SocketAlreadyOpen)
 	}
 
-	mSocketHandle = CreateNamedPipeW( 
-		pName,                     // pipe name 
+	std::string socket = sPipeNamePrefix + rName;
+
+	mSocketHandle = CreateNamedPipeA( 
+		socket.c_str(),            // pipe name 
 		PIPE_ACCESS_DUPLEX |       // read/write access 
 		FILE_FLAG_OVERLAPPED,      // enabled overlapped I/O
 		PIPE_TYPE_BYTE |           // message type pipe 
@@ -100,7 +104,7 @@
 
 	if (mSocketHandle == INVALID_HANDLE_VALUE)
 	{
-		BOX_ERROR("Failed to CreateNamedPipeW(" << pName << "): " <<
+		BOX_ERROR("Failed to CreateNamedPipeA(" << socket << "): " <<
 			GetErrorMessage(GetLastError()));
 		THROW_EXCEPTION(ServerException, SocketOpenError)
 	}
@@ -109,7 +113,7 @@
 
 	if (!connected)
 	{
-		BOX_ERROR("Failed to ConnectNamedPipe(" << pName << "): " <<
+		BOX_ERROR("Failed to ConnectNamedPipe(" << socket << "): " <<
 			GetErrorMessage(GetLastError()));
 		Close();
 		THROW_EXCEPTION(ServerException, SocketOpenError)
@@ -156,20 +160,22 @@
 // --------------------------------------------------------------------------
 //
 // Function
-//		Name:    WinNamedPipeStream::Connect(const char* Name)
+//		Name:    WinNamedPipeStream::Connect(const std::string& rName)
 //		Purpose: Opens a connection to a listening named pipe
 //		Created: 2005/12/07
 //
 // --------------------------------------------------------------------------
-void WinNamedPipeStream::Connect(const wchar_t* pName)
+void WinNamedPipeStream::Connect(const std::string& rName)
 {
 	if (mSocketHandle != INVALID_HANDLE_VALUE || mIsConnected) 
 	{
 		THROW_EXCEPTION(ServerException, SocketAlreadyOpen)
 	}
+
+	std::string socket = sPipeNamePrefix + rName;
 	
-	mSocketHandle = CreateFileW( 
-		pName,          // pipe name 
+	mSocketHandle = CreateFileA( 
+		socket.c_str(), // pipe name 
 		GENERIC_READ |  // read and write access 
 		GENERIC_WRITE, 
 		0,              // no sharing 

Modified: box/trunk/lib/server/WinNamedPipeStream.h
===================================================================
--- box/trunk/lib/server/WinNamedPipeStream.h	2007-10-17 12:47:37 UTC (rev 1876)
+++ box/trunk/lib/server/WinNamedPipeStream.h	2007-10-17 12:48:05 UTC (rev 1877)
@@ -27,10 +27,10 @@
 	~WinNamedPipeStream();
 
 	// server side - create the named pipe and listen for connections
-	void Accept(const wchar_t* Name);
+	void Accept(const std::string& rName);
 
 	// client side - connect to a waiting server
-	void Connect(const wchar_t* Name);
+	void Connect(const std::string& rName);
 
 	// both sides
 	virtual int Read(void *pBuffer, int NBytes, 
@@ -61,6 +61,8 @@
 	bool mWriteClosed;
 	bool mIsServer;
 	bool mIsConnected;
+
+	static std::string sPipeNamePrefix;
 };
 
 #endif // WINNAMEDPIPESTREAM__H


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:48:27 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:48:27 +0100
Subject: [Box Backup-commit] COMMIT r1878 - box/trunk/lib/server
Message-ID: <E1Ii8K3-000JUY-IZ@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:48:27 +0100 (Wed, 17 Oct 2007)
New Revision: 1878

Modified:
   box/trunk/lib/server/Daemon.cpp
Log:
Don't disable logging on Win32 console. (merges [1834])


Modified: box/trunk/lib/server/Daemon.cpp
===================================================================
--- box/trunk/lib/server/Daemon.cpp	2007-10-17 12:48:05 UTC (rev 1877)
+++ box/trunk/lib/server/Daemon.cpp	2007-10-17 12:48:27 UTC (rev 1878)
@@ -439,12 +439,12 @@
 			{
 				::close(devnull);
 			}
-#endif // ! WIN32
 
 			// And definitely don't try and send anything to those file descriptors
 			// -- this has in the past sent text to something which isn't expecting it.
 			TRACE_TO_STDOUT(false);
 			Logging::ToConsole(false);
+#endif // ! WIN32
 		}		
 	}
 	catch(BoxException &e)


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:48:54 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:48:54 +0100
Subject: [Box Backup-commit] COMMIT r1879 - box/trunk/lib/common
Message-ID: <E1Ii8KU-000Oqc-A9@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:48:54 +0100 (Wed, 17 Oct 2007)
New Revision: 1879

Modified:
   box/trunk/lib/common/BoxPortsAndFiles.h
Log:
Remove default pipe name to prevent applications from using it. (merges 
[1835])


Modified: box/trunk/lib/common/BoxPortsAndFiles.h
===================================================================
--- box/trunk/lib/common/BoxPortsAndFiles.h	2007-10-17 12:48:27 UTC (rev 1878)
+++ box/trunk/lib/common/BoxPortsAndFiles.h	2007-10-17 12:48:54 UTC (rev 1879)
@@ -36,8 +36,5 @@
 #define BOX_FILE_BBSTORED_DEFAULT_CONFIG 	"/etc/box/bbstored.conf"
 #endif
 
-// Default name of the named pipe
-#define BOX_NAMED_PIPE_NAME L"\\\\.\\pipe\\boxbackup"
-
 #endif // BOXPORTSANDFILES__H
 


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:49:18 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:49:18 +0100
Subject: [Box Backup-commit] COMMIT r1880 - box/trunk/lib/server
Message-ID: <E1Ii8Ks-000Khc-Rb@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:49:18 +0100 (Wed, 17 Oct 2007)
New Revision: 1880

Modified:
   box/trunk/lib/server/ServerControl.h
Log:
Added function to set the named pipe name, for use by any test which 
calls HUPServer() or SendCommands(). (merges [1836])


Modified: box/trunk/lib/server/ServerControl.h
===================================================================
--- box/trunk/lib/server/ServerControl.h	2007-10-17 12:48:54 UTC (rev 1879)
+++ box/trunk/lib/server/ServerControl.h	2007-10-17 12:49:18 UTC (rev 1880)
@@ -9,17 +9,24 @@
 #include "IOStreamGetLine.h"
 #include "BoxPortsAndFiles.h"
 
+static std::string sPipeName;
+
+static void SetNamedPipeName(const std::string& rPipeName)
+{
+	sPipeName = rPipeName;
+}
+
 static bool SendCommands(const std::string& rCmd)
 {
 	WinNamedPipeStream connection;
 
 	try
 	{
-		connection.Connect(BOX_NAMED_PIPE_NAME);
+		connection.Connect(sPipeName);
 	}
 	catch(...)
 	{
-		printf("Failed to connect to daemon control socket.\n");
+		BOX_ERROR("Failed to connect to daemon control socket");
 		return false;
 	}
 
@@ -30,14 +37,14 @@
 	std::string configSummary;
 	if(!getLine.GetLine(configSummary))
 	{
-		printf("Failed to receive configuration summary from daemon\n");
+		BOX_ERROR("Failed to receive configuration summary from daemon");
 		return false;
 	}
 
 	// Was the connection rejected by the server?
 	if(getLine.IsEOF())
 	{
-		printf("Server rejected the connection.\n");
+		BOX_ERROR("Server rejected the connection");
 		return false;
 	}
 
@@ -47,7 +54,7 @@
 			&autoBackup, &updateStoreInterval, 
 			&minimumFileAge, &maxUploadWait) != 4)
 	{
-		printf("Config summary didn't decode\n");
+		BOX_ERROR("Config summary didn't decode");
 		return false;
 	}
 
@@ -81,13 +88,13 @@
 		}
 		else if (line == "error")
 		{
-			printf("ERROR (%s)\n", rCmd.c_str());
+			BOX_ERROR(rCmd);
 			break;
 		}
 		else
 		{
-			printf("WARNING: Unexpected response to command '%s': "
-				"%s", rCmd.c_str(), line.c_str());
+			BOX_WARNING("Unexpected response to command '" <<
+				rCmd << "': " << line)
 		}
 	}
 	
@@ -104,15 +111,15 @@
 	HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, false, pid);
 	if (hProcess == NULL)
 	{
-		printf("Failed to open process %d: error %d\n",
-			pid, (int)GetLastError());
+		BOX_ERROR("Failed to open process " << pid << ": " <<
+			GetErrorMessage(GetLastError()));
 		return false;
 	}
 
 	if (!TerminateProcess(hProcess, 1))
 	{
-		printf("Failed to terminate process %d: error %d\n",
-			pid, (int)GetLastError());
+		BOX_ERROR("Failed to terminate process " << pid << ": " <<
+			GetErrorMessage(GetLastError()));
 		CloseHandle(hProcess);
 		return false;
 	}


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:49:48 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:49:48 +0100
Subject: [Box Backup-commit] COMMIT r1881 - box/trunk/bin/bbackupd/win32
Message-ID: <E1Ii8LM-000ORy-HS@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:49:48 +0100 (Wed, 17 Oct 2007)
New Revision: 1881

Modified:
   box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs
Log:
Windows notify script logs an error in the System Event Log if sending 
email fails. (merges [1837])


Modified: box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs
===================================================================
--- box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs	2007-10-17 12:49:18 UTC (rev 1880)
+++ box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs	2007-10-17 12:49:48 UTC (rev 1881)
@@ -65,8 +65,10 @@
 
 Sub SendMail(from,sendto,subject,body)
 	Set objEmail = CreateObject("CDO.Message")
+	Set WshShell = CreateObject("WScript.Shell")
 	Dim cdoschema
 	cdoschema = "http://schemas.microsoft.com/cdo/configuration/"
+	
 	With objEmail
 		.From = from
 		.To = sendto
@@ -79,5 +81,15 @@
 			.Configuration.Fields.Update
 		End If
 	End With
-	objEmail.Send
+	On Error Resume Next
+	rc = objEmail.Send
+	If rc Then
+		WshShell.Exec "eventcreate /L Application /ID 201 /T WARNING " _
+			& "/SO ""Box Backup"" /D """ & args(0) _
+			& " notification sent to " & sendto & "."""
+	Else
+		WshShell.Exec "eventcreate /L Application /ID 202 /T ERROR " _
+			& "/SO ""Box Backup"" /D ""Failed to send " & args(0) _
+			& " notification to " & sendto & "."""
+	End If
 End Sub


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:50:10 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:50:10 +0100
Subject: [Box Backup-commit] COMMIT r1882 - box/trunk
Message-ID: <E1Ii8Li-000JSp-Hl@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:50:10 +0100 (Wed, 17 Oct 2007)
New Revision: 1882

Modified:
   box/trunk/parcels.txt
Log:
Add James O'Gorman's NotifySysAdmin.vbs script to client parcel on 
Win32. (merges [1838])


Modified: box/trunk/parcels.txt
===================================================================
--- box/trunk/parcels.txt	2007-10-17 12:49:48 UTC (rev 1881)
+++ box/trunk/parcels.txt	2007-10-17 12:50:10 UTC (rev 1882)
@@ -13,6 +13,7 @@
 ONLY:mingw32,mingw32msvc
 	script bin/bbackupd/win32/installer.iss 
 	script bin/bbackupd/win32/bbackupd.conf
+	script bin/bbackupd/win32/NotifySysAdmin.vbs
 END-ONLY
 
 ONLY:mingw32


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:50:59 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:50:59 +0100
Subject: [Box Backup-commit] COMMIT r1883 - box/trunk/bin/bbackupd/win32
Message-ID: <E1Ii8MV-0005uk-Jd@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:50:59 +0100 (Wed, 17 Oct 2007)
New Revision: 1883

Modified:
   box/trunk/bin/bbackupd/win32/bbackupd.conf
Log:
Undo bad changes (not all exclude options take a regex). (merges [1847])


Modified: box/trunk/bin/bbackupd/win32/bbackupd.conf
===================================================================
--- box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-17 12:50:10 UTC (rev 1882)
+++ box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-17 12:50:59 UTC (rev 1883)
@@ -12,64 +12,35 @@
 # If you do not install it in the default location - also do not forget to 
 # change the pid file location (below)
 
-# This script is run whenever bbackupd changes state or encounters a
-# problem which requires the system administrator to assist:
-#
+
+# This script is run whenever bbackupd encounters a problem which requires
+# the system administrator to assist:
 # 1) The store is full, and no more data can be uploaded.
 # 2) Some files or directories were not readable.
-# 3) A backup run starts or finishes.
-#
-# The default script emails the system administrator, except for backups
-# starting and stopping, where it does nothing.
-#
-# NOTE: If your client does not run a local SMTP server then you MUST
-# edit this script and uncomment the lines near the end, which specify
-# the remote SMTP server to use for sending mail.
+# The default script emails the system administrator.
 
-NotifyScript = cscript "C:\Program Files\Box Backup\NotifySysAdmin.vbs"
+# NotifyScript = NotifySysadmin.sh
 
 
-# The number of seconds between backup runs under normal conditions. To avoid 
-# cycles of load on the server, this time is randomly adjusted by a small 
+# A scan of the local discs will be made once an hour (approximately).
+# To avoid cycles of load on the server, this time is randomly adjusted by a small
 # percentage as the daemon runs.
 
 UpdateStoreInterval = 3600
 
 
-# The minimum age of a file, in seconds, that will be uploaded. Avoids 
-# repeated uploads of a file which is constantly being modified.
+# A file must have been modified at least 6 hours ago before it will be uploaded.
 
 MinimumFileAge = 21600
 
 
-# If a file is modified repeated, it won't be uploaded immediately in case 
-# it's modified again, due to the MinimumFileAge specified above. However, it 
-# should be uploaded eventually even if it is being modified repeatedly. This 
-# is how long we should wait, in seconds, after first noticing a change. 
-# (86400 seconds = 1 day)
+# If a file is modified repeated, it won't be uploaded immediately in case it's modified again.
+# However, it should be uploaded eventually. This is how long we should wait after first noticing
+# a change. (1 day)
 
 MaxUploadWait = 86400
 
-# If the connection is idle for some time (e.g. over 10 minutes or 600
-# seconds, not sure exactly how long) then the server will give up and
-# disconnect the client, resulting in Connection Protocol_Timeout errors
-# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
-# Also, some firewalls and NAT gateways will kill idle connections after
-# similar lengths of time. 
-#
-# This can happen for example when most files are backed up already and
-# don't need to be sent to the store again, while scanning a large
-# directory, or while calculating diffs of a large file. To avoid this,
-# KeepAliveTime specifies that special keep-alive messages should be sent
-# when the connection is otherwise idle for a certain length of time,
-# specified here in seconds.
-#
-# The default is that these messages are never sent, equivalent to setting
-# this option to zero, but we recommend that all users enable this.
 
-KeepAliveTime = 120
-
-
 # Files above this size (in bytes) are tracked, and if they are renamed they will simply be
 # renamed on the server, rather than being uploaded again. (64k - 1)
 
@@ -82,38 +53,30 @@
 DiffingUploadSizeThreshold = 8192
 
 
-# The limit on how much time is spent diffing files, in seconds. Most files 
-# shouldn't take very long, but if you have really big files you can use this 
-# to limit the time spent diffing them.
-#
+# The limit on how much time is spent diffing files. Most files shouldn't take very long,
+# but if you have really big files you can use this to limit the time spent diffing them.
 # * Reduce if you are having problems with processor usage.
-#
-# * Increase if you have large files, and think the upload of changes is too 
-#   large and you want bbackupd to spend more time searching for unchanged
-#   blocks.
+# * Increase if you have large files, and think the upload of changes is too large and want
+#   to spend more time searching for unchanged blocks.
 
-MaximumDiffingTime = 120
+MaximumDiffingTime = 20
 
+# KeepAliveTime requires Gary's SSL KeepAlive patches
+# KeepAliveTime = 250
 
 # Uncomment this line to see exactly what the daemon is going when it's connected to the server.
 
 # ExtendedLogging = yes
 
 
-# This specifies a program or script script which is run just before each 
-# sync, and ideally the full path to the interpreter. It will be run as the 
-# same user bbackupd is running as, usually root.
-#
-# The script must output (print) either "now" or a number to STDOUT (and a 
-# terminating newline, no quotes).
-#
-# If the result was "now", then the sync will happen. If it's a number, then 
-# no backup will happen for that number of seconds (bbackupd will pause) and 
-# then the script will be run again.
-#
-# Use this to temporarily stop bbackupd from syncronising or connecting to the 
-# store. For example, you could use this on a laptop to only backup when on a 
-# specific network, or when it has a working Internet connection.
+# Use this to temporarily stop bbackupd from syncronising or connecting to the store.
+# This specifies a program or script script which is run just before each sync, and ideally
+# the full path to the interpreter. It will be run as the same user bbackupd is running as,
+# usually root.
+# The script prints either "now" or a number to STDOUT (and a terminating newline, no quotes).
+# If the result was "now", then the sync will happen. If it's a number, then the script will
+# be asked again in that number of seconds.
+# For example, you could use this on a laptop to only backup when on a specific network.
 
 # SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
 
@@ -122,21 +85,16 @@
 
 CommandSocket = pipe
 
-# 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 = C:\Program Files\Box Backup\bbackupd\bbackupd.state
-
 Server
 {
 	PidFile = C:\Program Files\Box Backup\bbackupd\bbackupd.pid
 }
 
+# StoreObjectInfoFile requires Gary's client marker serialisation patch
+# StoreObjectInfoFile = C:\Program Files\Box Backup\bbackupd\bbackupd.dat
 
+# 
 # BackupLocations specifies which locations on disc should be backed up. Each
 # directory is in the format
 # 
@@ -158,12 +116,19 @@
 # For example:
 # 
 # 	ExcludeDir = /home/guest-user
-# 	ExcludeFilesRegex = *.(mp3|MP3)$
+# 	ExcludeFilesRegex = \.(mp3|MP3)$
 # 	AlwaysIncludeFile = /home/username/veryimportant.mp3
 # 
 # This excludes the directory /home/guest-user from the backup along with all mp3
 # files, except one MP3 file in particular.
-# 
+#
+# If a directive ends in Regex, then it is a regular expression rather than a
+# explicit full pathname. See:
+#
+#       http://bbdev.fluffy.co.uk/trac/wiki/Win32Regex
+#
+# for more information about regular expressions on Windows.
+#
 # In general, Exclude excludes a file or directory, unless the directory is
 # explicitly mentioned in a AlwaysInclude directive. However, Box Backup
 # does NOT scan inside excluded directories and will never back up an
@@ -173,23 +138,47 @@
 # To back up a directory inside an excluded directory, use a configuration
 # like this, to ensure that each directory in the path to the important
 # files is included, but none of their contents will be backed up except
-# the directories futher down that path to the important one.
+# the directories further down that path to the important one.
 #
-# ExcludeDirsRegex = /home/user/bigfiles/.*
-# ExcludeFilesRegex = /home/user/bigfiles/.*
+# ExcludeDirsRegex = ^/home/user/bigfiles/
+# ExcludeFilesRegex = ^/home/user/bigfiles/
 # AlwaysIncludeDir = /home/user/bigfiles/path
 # AlwaysIncludeDir = /home/user/bigfiles/path/to
 # AlwaysIncludeDir = /home/user/bigfiles/path/important
 # AlwaysIncludeDir = /home/user/bigfiles/path/important/files
-# AlwaysIncludeDirsRegex = /home/user/bigfiles/path/important/files/.*
-# AlwaysIncludeFilesRegex = /home/user/bigfiles/path/important/files/.*
-# 
-# If a directive ends in Regex, then it is a regular expression rather than a 
-# explicit full pathname. See
-# 
-# 	man 7 re_format
-# 
-# for the regex syntax on your platform.
+# AlwaysIncludeDirsRegex = ^/home/user/bigfiles/path/important/files/
+# AlwaysIncludeFilesRegex = ^/home/user/bigfiles/path/important/files/
+#
+# Here are some more examples of possible regular expressions for Windows:
+#
+#       ExcludeDir = C:\Documents and Settings\Owner
+#       ExcludeFilesRegex = \.(mp3|MP3)$
+#       AlwaysIncludeFile = C:\Documents and Settings\Owner\My Documents\My Music\veryimportant.mp3
+#       ExcludeFilesRegex = \.pst$
+#       AlwaysIncludeFilesRegex = \.*backup.*\.pst$
+#       ExcludeFilesRegex = \.avi$
+#       ExcludeDirsRegex  = \\Temporary Internet Files$
+#       ExcludeFilesRegex = \\pagefile\.sys$
+#       ExcludeDirsRegex  = \\pagefile\.sys$
+#       ExcludeFilesRegex = \\boot\.ini$
+#       ExcludeFilesRegex = \\NTDETECT\.COM$
+#       ExcludeFilesRegex = \\UsrClass\.dat\.LOG$
+#       ExcludeDirsRegex  = \\System Volume Information$
+#       ExcludeFilesRegex = \\ntldr$
+#       ExcludeDirsRegex  = \\Local Settings\\.*\\Cache$
+#       ExcludeFilesRegex = \\thumbs\.db$
+#       ExcludeFilesRegex = \\~.*
+#       ExcludeFilesRegex = \\Perflib.*
+#       ExcludeDirsRegex  = \\Application Data$
+#       ExcludeFilesRegex = \.bk[~!0-9]$
+#       ExcludeFilesRegex = \.iso$
+#       ExcludeFilesRegex = \.mpe?[2345g]$
+#       ExcludeFilesRegex = \.qbw$
+#       AlwaysIncludeFilesRegex = \.qbb$
+#       ExcludeFilesRegex = \.tif[f]$
+#       ExcludeFilesRegex = \.wmv$
+#       ExcludeFilesRegex = \.avi$
+#       ExcludeFilesRegex = \.(avi|iso|mp(e)?[g345]|bk[~!1-9]|[mt]bk)$
 
 BackupLocations
 {


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:51:40 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:51:40 +0100
Subject: [Box Backup-commit] COMMIT r1884 - box/trunk/lib/win32
Message-ID: <E1Ii8NA-000MIG-Ka@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:51:40 +0100 (Wed, 17 Oct 2007)
New Revision: 1884

Modified:
   box/trunk/lib/win32/getopt_long.cxx
Log:
Fix compilation on MinGW. Not yet actually used on MinGW due to the
file extension, but it might be soon, if the default implementation
doesn't do what I want. (merges [1848])


Modified: box/trunk/lib/win32/getopt_long.cxx
===================================================================
--- box/trunk/lib/win32/getopt_long.cxx	2007-10-17 12:50:59 UTC (rev 1883)
+++ box/trunk/lib/win32/getopt_long.cxx	2007-10-17 12:51:40 UTC (rev 1884)
@@ -57,14 +57,17 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "Box.h"
+// #include "Box.h"
 
 #include <errno.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
-#ifdef _MSC_VER
+#include "getopt.h"
+
+#if defined _MSC_VER || defined __MINGW32__
 #define	REPLACE_GETOPT		/* use this getopt as the system getopt(3) */
 #endif
 


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:52:06 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:52:06 +0100
Subject: [Box Backup-commit] COMMIT r1885 - box/trunk/lib/server
Message-ID: <E1Ii8Na-0005g6-38@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:52:05 +0100 (Wed, 17 Oct 2007)
New Revision: 1885

Modified:
   box/trunk/lib/server/Daemon.cpp
   box/trunk/lib/server/Daemon.h
Log:
Refactor out command-line option processing, so that it can be extended
by subclasses. (merges [1849])


Modified: box/trunk/lib/server/Daemon.cpp
===================================================================
--- box/trunk/lib/server/Daemon.cpp	2007-10-17 12:51:40 UTC (rev 1884)
+++ box/trunk/lib/server/Daemon.cpp	2007-10-17 12:52:05 UTC (rev 1885)
@@ -50,7 +50,8 @@
 	  mTerminateWanted(false),
 	  mSingleProcess(false),
 	  mRunInForeground(false),
-	  mKeepConsoleOpenAfterFork(false)
+	  mKeepConsoleOpenAfterFork(false),
+	  mHaveConfigFile(false);
 {
 	if(spDaemon != NULL)
 	{
@@ -87,6 +88,126 @@
 // --------------------------------------------------------------------------
 //
 // Function
+//		Name:    Daemon::GetOptionString()
+//		Purpose: Returns the valid Getopt command-line options.
+//			 This should be overridden by subclasses to add
+//			 their own options, which should override 
+//			 ProcessOption, handle their own, and delegate to
+//			 ProcessOption for the standard options.
+//		Created: 2007/09/18
+//
+// --------------------------------------------------------------------------
+std::string Daemon::GetOptionString()
+{
+	return "c:DFqvVt:Tk";
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+//		Name:    Daemon::ProcessOption(int option)
+//		Purpose: Processes the supplied option (equivalent to the
+//			 return code from getopt()). Return zero if the
+//			 option was handled successfully, or nonzero to
+//			 abort the program with that return value.
+//		Created: 2007/09/18
+//
+// --------------------------------------------------------------------------
+int Daemon::ProcessOption(signed int option)
+{
+	switch(option)
+	{
+		case 'c':
+		{
+			mConfigFileName = optarg;
+			mHaveConfigFile = true;
+		}
+		break;
+
+		case 'D':
+		{
+			mSingleProcess = true;
+		}
+		break;
+
+		case 'F':
+		{
+			mRunInForeground = true;
+		}
+		break;
+
+		case 'q':
+		{
+			if(mLogLevel == Log::NOTHING)
+			{
+				BOX_FATAL("Too many '-q': "
+					"Cannot reduce logging "
+					"level any more");
+				return 2;
+			}
+			mLogLevel--;
+		}
+		break;
+
+		case 'v':
+		{
+			if(mLogLevel == Log::EVERYTHING)
+			{
+				BOX_FATAL("Too many '-v': "
+					"Cannot increase logging "
+					"level any more");
+				return 2;
+			}
+			mLogLevel++;
+		}
+		break;
+
+		case 'V':
+		{
+			mLogLevel = Log::EVERYTHING;
+		}
+		break;
+
+		case 't':
+		{
+			Console::SetTag(optarg);
+		}
+		break;
+
+		case 'T':
+		{
+			Console::SetShowTime(true);
+		}
+		break;
+
+		case 'k':
+		{
+			mKeepConsoleOpenAfterFork = true;
+		}
+		break;
+
+		case '?':
+		{
+			BOX_FATAL("Unknown option on command line: " 
+				<< "'" << (char)optopt << "'");
+			return 2;
+		}
+		break;
+
+		default:
+		{
+			BOX_FATAL("Unknown error in getopt: returned "
+				<< "'" << option << "'");
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
 //		Name:    Daemon::Main(const char *, int, const char *[])
 //		Purpose: Parses command-line options, and then calls
 //			Main(std::string& configFile, bool singleProcess)
@@ -98,12 +219,11 @@
 {
 	// Find filename of config file
 	mConfigFileName = DefaultConfigFile;
-	bool haveConfigFile = false;
 
 	#ifdef NDEBUG
-	int masterLevel = Log::NOTICE; // need an int to do math with
+	mLogLevel = Log::NOTICE; // need an int to do math with
 	#else
-	int masterLevel = Log::INFO; // need an int to do math with
+	mLogLevel = Log::INFO; // need an int to do math with
 	#endif
 
 	signed int c;
@@ -118,97 +238,18 @@
 		optreset = 1;
 	#endif
 
-	while((c = getopt(argc, (char * const *)argv, "c:DFqvVt:Tk")) != -1)
+	while((c = getopt(argc, (char * const *)argv, 
+		GetOptionString().c_str())) != -1)
 	{
-		switch(c)
+		int returnCode = ProcessOption(c);
+
+		if (returnCode != 0)
 		{
-			case 'c':
-			{
-				mConfigFileName = optarg;
-				haveConfigFile = true;
-			}
-			break;
-
-			case 'D':
-			{
-				mSingleProcess = true;
-			}
-			break;
-
-			case 'F':
-			{
-				mRunInForeground = true;
-			}
-			break;
-
-			case 'q':
-			{
-				if(masterLevel == Log::NOTHING)
-				{
-					BOX_FATAL("Too many '-q': "
-						"Cannot reduce logging "
-						"level any more");
-					return 2;
-				}
-				masterLevel--;
-			}
-			break;
-
-			case 'v':
-			{
-				if(masterLevel == Log::EVERYTHING)
-				{
-					BOX_FATAL("Too many '-v': "
-						"Cannot increase logging "
-						"level any more");
-					return 2;
-				}
-				masterLevel++;
-			}
-			break;
-
-			case 'V':
-			{
-				masterLevel = Log::EVERYTHING;
-			}
-			break;
-
-			case 't':
-			{
-				Console::SetTag(optarg);
-			}
-			break;
-
-			case 'T':
-			{
-				Console::SetShowTime(true);
-			}
-			break;
-
-			case 'k':
-			{
-				mKeepConsoleOpenAfterFork = true;
-			}
-			break;
-
-			case '?':
-			{
-				BOX_FATAL("Unknown option on command line: " 
-					<< "'" << (char)optopt << "'");
-				return 2;
-			}
-			break;
-
-			default:
-			{
-				BOX_FATAL("Unknown error in getopt: returned "
-					<< "'" << c << "'");
-				return 1;
-			}
+			return returnCode;
 		}
 	}
 
-	if (argc > optind && !haveConfigFile)
+	if (argc > optind && !mHaveConfigFile)
 	{
 		mConfigFileName = argv[optind]; optind++;
 	}
@@ -225,7 +266,7 @@
 		return 2;
 	}
 
-	Logging::SetGlobalLevel((Log::Level)masterLevel);
+	Logging::SetGlobalLevel((Log::Level)mLogLevel);
 
 	return Main(mConfigFileName);
 }

Modified: box/trunk/lib/server/Daemon.h
===================================================================
--- box/trunk/lib/server/Daemon.h	2007-10-17 12:51:40 UTC (rev 1884)
+++ box/trunk/lib/server/Daemon.h	2007-10-17 12:52:05 UTC (rev 1885)
@@ -67,12 +67,13 @@
 protected:
 	box_time_t GetLoadedConfigModifiedTime() const;
 	bool IsSingleProcess() { return mSingleProcess; }
+	std::string GetOptionString();
+	int ProcessOption(signed int option);
 	
 private:
 	static void SignalHandler(int sigraised);
 	box_time_t GetConfigFileModifiedTime() const;
 	
-private:
 	std::string mConfigFileName;
 	Configuration *mpConfiguration;
 	box_time_t mLoadedConfigModifiedTime;
@@ -81,6 +82,8 @@
 	bool mSingleProcess;
 	bool mRunInForeground;
 	bool mKeepConsoleOpenAfterFork;
+	bool mHaveConfigFile;
+	int mLogLevel; // need an int to do math with
 	static Daemon *spDaemon;
 };
 


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:52:25 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:52:25 +0100
Subject: [Box Backup-commit] COMMIT r1886 - box/trunk/lib/server
Message-ID: <E1Ii8Nt-000OQi-Er@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:52:25 +0100 (Wed, 17 Oct 2007)
New Revision: 1886

Modified:
   box/trunk/lib/server/Daemon.cpp
Log:
Compile fix. (merges [1850])


Modified: box/trunk/lib/server/Daemon.cpp
===================================================================
--- box/trunk/lib/server/Daemon.cpp	2007-10-17 12:52:05 UTC (rev 1885)
+++ box/trunk/lib/server/Daemon.cpp	2007-10-17 12:52:25 UTC (rev 1886)
@@ -51,7 +51,7 @@
 	  mSingleProcess(false),
 	  mRunInForeground(false),
 	  mKeepConsoleOpenAfterFork(false),
-	  mHaveConfigFile(false);
+	  mHaveConfigFile(false)
 {
 	if(spDaemon != NULL)
 	{


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:52:47 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:52:47 +0100
Subject: [Box Backup-commit] COMMIT r1887 - box/trunk/lib/server
Message-ID: <E1Ii8OF-0007zZ-Fg@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:52:47 +0100 (Wed, 17 Oct 2007)
New Revision: 1887

Modified:
   box/trunk/lib/server/SocketStream.cpp
Log:
Report more useful error messages on connect() failure on Windows. 
(merges [1851])


Modified: box/trunk/lib/server/SocketStream.cpp
===================================================================
--- box/trunk/lib/server/SocketStream.cpp	2007-10-17 12:52:25 UTC (rev 1886)
+++ box/trunk/lib/server/SocketStream.cpp	2007-10-17 12:52:47 UTC (rev 1887)
@@ -161,17 +161,26 @@
 	{
 		// Dispose of the socket
 #ifdef WIN32
+		DWORD err = WSAGetLastError();
 		::closesocket(mSocketHandle);
 #else
+		int err = errno;
 		::close(mSocketHandle);
 #endif
+
 		BOX_ERROR("Failed to connect to socket (type " << Type <<
 			", name " << Name << ", port " << Port << "): " <<
-			"error " << errno << " (" << strerror(errno) << 
-			")");
+			#ifdef WIN32
+				GetErrorMessage(err)
+			#else
+				strerror(err) << " (" << err << ")"
+			#endif
+			);
+
 		mSocketHandle = INVALID_SOCKET_VALUE;
 		THROW_EXCEPTION(ConnectionException, Conn_SocketConnectError)
 	}
+
 	ResetCounters();
 }
 


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:53:07 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:53:07 +0100
Subject: [Box Backup-commit] COMMIT r1888 - box/trunk/lib/server
Message-ID: <E1Ii8OZ-000E88-G2@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:53:07 +0100 (Wed, 17 Oct 2007)
New Revision: 1888

Modified:
   box/trunk/lib/server/Daemon.h
Log:
Make Main(), GetOptionString() and ProcessOption virtual so that they
can actually be overridden. (merges [1852])


Modified: box/trunk/lib/server/Daemon.h
===================================================================
--- box/trunk/lib/server/Daemon.h	2007-10-17 12:52:47 UTC (rev 1887)
+++ box/trunk/lib/server/Daemon.h	2007-10-17 12:53:07 UTC (rev 1888)
@@ -41,7 +41,9 @@
 public:
 
 	int Main(const char *DefaultConfigFile, int argc, const char *argv[]);
-	int Main(const std::string &rConfigFile);
+
+	/* override this Main() if you want custom option processing: */
+	virtual int Main(const std::string &rConfigFile);
 	
 	virtual void Run();
 	const Configuration &GetConfiguration() const;
@@ -67,8 +69,8 @@
 protected:
 	box_time_t GetLoadedConfigModifiedTime() const;
 	bool IsSingleProcess() { return mSingleProcess; }
-	std::string GetOptionString();
-	int ProcessOption(signed int option);
+	virtual std::string GetOptionString();
+	virtual int ProcessOption(signed int option);
 	
 private:
 	static void SignalHandler(int sigraised);


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:53:30 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:53:30 +0100
Subject: [Box Backup-commit] COMMIT r1889 - box/trunk/bin/bbackupd
Message-ID: <E1Ii8Ow-000I6N-3h@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:53:29 +0100 (Wed, 17 Oct 2007)
New Revision: 1889

Modified:
   box/trunk/bin/bbackupd/Win32BackupService.cpp
   box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp
   box/trunk/bin/bbackupd/Win32ServiceFunctions.h
Log:
Record the exit status of the daemon when running as a service, and
return it to Windows so that Windows doesn't tell the admin that
"the service did not report an error" when it stopped unexpectedly.

When failing to contact the SCM, report a textual error message as
well as the error code.

Make OurService() take a const char * instead of char *, so that we can
pass it a std::string.c_str().

InstallService creates service using "-s" option instead of "--service",
which no longer works once we use getopt() for option processing
(to follow).

(merges [1853])


Modified: box/trunk/bin/bbackupd/Win32BackupService.cpp
===================================================================
--- box/trunk/bin/bbackupd/Win32BackupService.cpp	2007-10-17 12:53:07 UTC (rev 1888)
+++ box/trunk/bin/bbackupd/Win32BackupService.cpp	2007-10-17 12:53:29 UTC (rev 1889)
@@ -14,10 +14,12 @@
 
 Win32BackupService* gpDaemonService = NULL;
 extern HANDLE gStopServiceEvent;
+extern DWORD gServiceReturnCode;
 
 unsigned int WINAPI RunService(LPVOID lpParameter)
 {
 	DWORD retVal = gpDaemonService->WinService((const char*) lpParameter);
+	gServiceReturnCode = retVal;
 	SetEvent(gStopServiceEvent);
 	return retVal;
 }

Modified: box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp
===================================================================
--- box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp	2007-10-17 12:53:07 UTC (rev 1888)
+++ box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp	2007-10-17 12:53:29 UTC (rev 1889)
@@ -30,6 +30,7 @@
 SERVICE_STATUS gServiceStatus;
 SERVICE_STATUS_HANDLE gServiceStatusHandle = 0;
 HANDLE gStopServiceEvent = 0;
+DWORD gServiceReturnCode = 0;
 
 #define SERVICE_NAME "boxbackup"
 
@@ -43,7 +44,8 @@
 {
 	char buf[256];
 	memset(buf, 0, sizeof(buf));
-	_snprintf(buf, sizeof(buf)-1, "%s (%d)", s, err);
+	_snprintf(buf, sizeof(buf)-1, "%s: %s", s,
+		GetErrorMessage(err).c_str());
 	BOX_ERROR(buf);
 	MessageBox(0, buf, "Error", 
 		MB_OK | MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY);
@@ -156,14 +158,22 @@
 		// service is now stopped
 		gServiceStatus.dwControlsAccepted &= 
 			~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
+
 		gServiceStatus.dwCurrentState = SERVICE_STOPPED;
+
+		if (gServiceReturnCode != 0)
+		{
+			gServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+			gServiceStatus.dwServiceSpecificExitCode = gServiceReturnCode;
+		}
+
 		SetServiceStatus(gServiceStatusHandle, &gServiceStatus);
 	}
 }
 
-int OurService(char* pConfigFileName)
+int OurService(const char* pConfigFileName)
 {
-	spConfigFileName = pConfigFileName;
+	spConfigFileName = strdup(pConfigFileName);
 
 	SERVICE_TABLE_ENTRY serviceTable[] = 
 	{ 
@@ -175,6 +185,9 @@
 	// Register with the SCM
 	success = StartServiceCtrlDispatcher(serviceTable);
 
+	free(spConfigFileName);
+	spConfigFileName = NULL;
+
 	if (!success)
 	{
 		ErrorHandler("Failed to start service. Did you start "
@@ -222,7 +235,7 @@
 	cmd[sizeof(cmd)-1] = 0;
 
 	std::string cmdWithArgs(cmd);
-	cmdWithArgs += " --service";
+	cmdWithArgs += " -s";
 
 	if (pConfigFileName != NULL)
 	{

Modified: box/trunk/bin/bbackupd/Win32ServiceFunctions.h
===================================================================
--- box/trunk/bin/bbackupd/Win32ServiceFunctions.h	2007-10-17 12:53:07 UTC (rev 1888)
+++ box/trunk/bin/bbackupd/Win32ServiceFunctions.h	2007-10-17 12:53:29 UTC (rev 1889)
@@ -14,6 +14,6 @@
 
 int RemoveService  (void);
 int InstallService (const char* pConfigFilePath);
-int OurService     (char* pConfigFileName);
+int OurService     (const char* pConfigFileName);
 
 #endif


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:53:52 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:53:52 +0100
Subject: [Box Backup-commit] COMMIT r1890 - box/trunk/bin/bbackupd
Message-ID: <E1Ii8PI-0006ty-6L@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:53:52 +0100 (Wed, 17 Oct 2007)
New Revision: 1890

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
   box/trunk/bin/bbackupd/BackupDaemon.h
   box/trunk/bin/bbackupd/bbackupd.cpp
Log:
Use Daemon's delegated option processing instead of our own hacks.

Move Windows service startup, installation and removal to BackupDaemon. 
(merges [1854])


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:53:29 UTC (rev 1889)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:53:52 UTC (rev 1890)
@@ -76,6 +76,13 @@
 #include "Logging.h"
 #include "autogen_ClientException.h"
 
+#ifdef WIN32
+	#include "Win32ServiceFunctions.h"
+	#include "Win32BackupService.h"
+
+	extern Win32BackupService* gpDaemonService;
+#endif
+
 #include "MemLeakFindOn.h"
 
 static const time_t MAX_SLEEP_TIME = 1024;
@@ -116,6 +123,11 @@
 	  mpCommandSocketInfo(0),
 	  mDeleteUnusedRootDirEntriesAfter(0),
 	  mLogAllFileAccess(false)
+	#ifdef WIN32
+	, mInstallService(false),
+	  mRemoveService(false),
+	  mRunAsService(false)
+	#endif
 {
 	// Only ever one instance of a daemon
 	SSLLib::Initialise();
@@ -276,6 +288,83 @@
 }
 
 #ifdef WIN32
+std::string BackupDaemon::GetOptionString()
+{
+	std::string oldOpts = this->Daemon::GetOptionString();
+	ASSERT(oldOpts.find("s") == std::string::npos);
+	ASSERT(oldOpts.find("S") == std::string::npos);
+	ASSERT(oldOpts.find("i") == std::string::npos);
+	ASSERT(oldOpts.find("r") == std::string::npos);
+	return oldOpts + "sS:ir";
+}
+
+int BackupDaemon::ProcessOption(signed int option)
+{
+	switch(option)
+	{
+		case 's':
+		{
+			mRunAsService = true;
+			return 0;
+		}
+
+		case 'S':
+		{
+			mServiceName = optarg;
+			return 0;
+		}
+
+		case 'i':
+		{
+			mInstallService = true;
+			return 0;
+		}
+
+		case 'r':
+		{
+			mRemoveService = true;
+			return 0;
+		}
+
+		default:
+		{
+			return this->Daemon::ProcessOption(option);
+		}
+	}
+}
+
+int BackupDaemon::Main(const std::string &rConfigFileName)
+{
+	if (mInstallService)
+	{
+		return InstallService(rConfigFileName.c_str());
+	}
+
+	if (mRemoveService)
+	{
+		return RemoveService();
+	}
+
+	int returnCode;
+
+	if (mRunAsService)
+	{
+		// We will be called reentrantly by the Service Control
+		// Manager, and we had better not call OurService again!
+		mRunAsService = false;
+
+		BOX_INFO("Box Backup service starting");
+		returnCode = OurService(rConfigFileName.c_str());
+		BOX_INFO("Box Backup service shut down");
+	}
+	else
+	{
+		returnCode = this->Daemon::Main(rConfigFileName);
+	}
+	
+	return returnCode;
+}
+
 void BackupDaemon::RunHelperThread(void)
 {
 	const Configuration &conf(GetConfiguration());

Modified: box/trunk/bin/bbackupd/BackupDaemon.h
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-17 12:53:29 UTC (rev 1889)
+++ box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-17 12:53:52 UTC (rev 1890)
@@ -58,7 +58,14 @@
 		box_time_t & theLastSyncTime, box_time_t & theNextSyncTime);
 	bool DeleteStoreObjectInfo() const;
 	BackupDaemon(const BackupDaemon &);
+
 public:
+	#ifdef WIN32
+		// add command-line options to handle Windows services
+		std::string GetOptionString();
+		int ProcessOption(signed int option);
+		int Main(const std::string &rConfigFileName);
+	#endif
 
 	void Run();
 	virtual const char *DaemonName() const;
@@ -418,6 +425,8 @@
 
 	private:
 	bool mDoSyncFlagOut, mSyncIsForcedOut;
+	bool mInstallService, mRemoveService, mRunAsService;
+	std::string mServiceName;
 	HANDLE mhMessageToSendEvent, mhCommandReceivedEvent;
 	CRITICAL_SECTION mMessageQueueLock;
 	std::vector<std::string> mMessageList;

Modified: box/trunk/bin/bbackupd/bbackupd.cpp
===================================================================
--- box/trunk/bin/bbackupd/bbackupd.cpp	2007-10-17 12:53:29 UTC (rev 1889)
+++ box/trunk/bin/bbackupd/bbackupd.cpp	2007-10-17 12:53:52 UTC (rev 1890)
@@ -35,63 +35,12 @@
 	
 #ifdef WIN32
 
-	if(argc == 2 &&
-		(::strcmp(argv[1], "--help") == 0 ||
-		 ::strcmp(argv[1], "-h") == 0))
-	{
-		printf("-h help, -i install service, -r remove service,\n"
-			"-c <config file> start daemon now");
-		return 2;
-	}
-	if(argc == 2 && ::strcmp(argv[1], "-r") == 0)
-	{
-		return RemoveService();
-	}
-	if((argc == 2 || argc == 3) && ::strcmp(argv[1], "-i") == 0)
-	{
-		const char* config = NULL;
-		if (argc == 3)
-		{
-			config = argv[2];
-		}
-		return InstallService(config);
-	}
-
-	bool runAsWin32Service = false;
-	if (argc >= 2 && ::strcmp(argv[1], "--service") == 0)
-	{
-		runAsWin32Service = true;
-	}
-
-	gpDaemonService = new Win32BackupService();
-
 	EnableBackupRights();
 
-	if (runAsWin32Service)
-	{
-		BOX_INFO("Box Backup service starting");
-
-		char* config = NULL;
-		if (argc >= 3)
-		{
-			config = strdup(argv[2]);
-		}
-
-		ExitCode = OurService(config);
-
-		if (config)
-		{
-			free(config);
-		}
-
-		BOX_INFO("Box Backup service shut down");
-	}
-	else
-	{
-		ExitCode = gpDaemonService->Main(
-			BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE, argc, argv);
-	}
-
+	gpDaemonService = new Win32BackupService();
+	ExitCode = gpDaemonService->Daemon::Main(
+		BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE,
+		argc, argv);
 	delete gpDaemonService;
 
 #else // !WIN32


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:54:17 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:54:17 +0100
Subject: [Box Backup-commit] COMMIT r1891 - in box/trunk: bin/bbackupd bin/bbstored lib/server
Message-ID: <E1Ii8Ph-0009g2-Dq@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:54:17 +0100 (Wed, 17 Oct 2007)
New Revision: 1891

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
   box/trunk/bin/bbackupd/BackupDaemon.h
   box/trunk/bin/bbstored/BackupStoreDaemon.cpp
   box/trunk/bin/bbstored/BackupStoreDaemon.h
   box/trunk/lib/server/Daemon.cpp
   box/trunk/lib/server/Daemon.h
Log:
Add "-h" and "/?" options to display usage in Daemon.

Extend usage info with service commands in BackupDaemon.

Disable useless -D, -V and -k options on Windows.

(merges 1855])


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:54:17 UTC (rev 1891)
@@ -38,6 +38,8 @@
 	#include <process.h>
 #endif
 
+#include <iostream>
+
 #include "Configuration.h"
 #include "IOStream.h"
 #include "MemBlockStream.h"
@@ -209,13 +211,21 @@
 //		Created: 1/1/04
 //
 // --------------------------------------------------------------------------
-const char *BackupDaemon::DaemonBanner() const
+std::string BackupDaemon::DaemonBanner() const
 {
-#ifndef NDEBUG
-	// Don't display banner in debug builds
-	return 0;
-#else
 	return BANNER_TEXT("Backup Client");
+}
+
+void BackupDaemon::Usage()
+{
+	this->Daemon::Usage();
+
+#ifdef WIN32
+	std::cout <<
+	"  -s         Run as a Windows Service, for internal use only\n"
+	"  -i         Install Windows Service (you may want to specify a config file)\n"
+	"  -r         Remove Windows Service\n"
+	"  -S <name>  Service name for -i and -r options\n";
 #endif
 }
 

Modified: box/trunk/bin/bbackupd/BackupDaemon.h
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/bin/bbackupd/BackupDaemon.h	2007-10-17 12:54:17 UTC (rev 1891)
@@ -69,7 +69,8 @@
 
 	void Run();
 	virtual const char *DaemonName() const;
-	virtual const char *DaemonBanner() const;
+	virtual std::string DaemonBanner() const;
+	virtual void Usage();
 	const ConfigurationVerify *GetConfigVerify() const;
 
 	bool FindLocationPathName(const std::string &rLocationName, std::string &rPathOut) const;

Modified: box/trunk/bin/bbstored/BackupStoreDaemon.cpp
===================================================================
--- box/trunk/bin/bbstored/BackupStoreDaemon.cpp	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/bin/bbstored/BackupStoreDaemon.cpp	2007-10-17 12:54:17 UTC (rev 1891)
@@ -93,14 +93,9 @@
 //		Created: 1/1/04
 //
 // --------------------------------------------------------------------------
-const char *BackupStoreDaemon::DaemonBanner() const
+std::string BackupStoreDaemon::DaemonBanner() const
 {
-#ifndef NDEBUG
-	// Don't display banner in debug builds
-	return 0;
-#else
 	return BANNER_TEXT("Backup Store Server");
-#endif
 }
 
 

Modified: box/trunk/bin/bbstored/BackupStoreDaemon.h
===================================================================
--- box/trunk/bin/bbstored/BackupStoreDaemon.h	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/bin/bbstored/BackupStoreDaemon.h	2007-10-17 12:54:17 UTC (rev 1891)
@@ -56,7 +56,7 @@
 	void Connection2(SocketStreamTLS &rStream);
 	
 	virtual const char *DaemonName() const;
-	virtual const char *DaemonBanner() const;
+	virtual std::string DaemonBanner() const;
 
 	const ConfigurationVerify *GetConfigVerify() const;
 	

Modified: box/trunk/lib/server/Daemon.cpp
===================================================================
--- box/trunk/lib/server/Daemon.cpp	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/lib/server/Daemon.cpp	2007-10-17 12:54:17 UTC (rev 1891)
@@ -23,6 +23,8 @@
 	#include <ws2tcpip.h>
 #endif
 
+#include <iostream>
+
 #include "Daemon.h"
 #include "Configuration.h"
 #include "ServerException.h"
@@ -51,7 +53,8 @@
 	  mSingleProcess(false),
 	  mRunInForeground(false),
 	  mKeepConsoleOpenAfterFork(false),
-	  mHaveConfigFile(false)
+	  mHaveConfigFile(false),
+	  mAppName(DaemonName())
 {
 	if(spDaemon != NULL)
 	{
@@ -99,9 +102,35 @@
 // --------------------------------------------------------------------------
 std::string Daemon::GetOptionString()
 {
-	return "c:DFqvVt:Tk";
+	return "c:"
+	#ifndef WIN32
+		"DFk"
+	#endif
+		"hqvVt:T";
 }
 
+void Daemon::Usage()
+{
+	std::cout << 
+	DaemonBanner() << "\n"
+	"\n"
+	"Usage: " << mAppName << " [options] [config file]\n" <<
+	"\n"
+	"Options:\n"
+	"  -c <file>  Use the specified configuration file. If -c is omitted, the last\n"
+	"             argument is the configuration file\n"
+#ifndef WIN32
+	"  -D         Debugging mode, do not fork, one process only, one client only\n"
+	"  -F         Do not fork into background, but fork to serve multiple clients\n"
+	"  -k         Keep console open after fork, keep writing log messages to it\n"
+#endif
+	"  -q         Run more quietly, reduce verbosity level by one, can repeat\n"
+	"  -v         Run more verbosely, increase verbosity level by one, can repeat\n"
+	"  -V         Run at maximum verbosity\n"
+	"  -t <tag>   Tag console output with specified marker\n"
+	"  -T         Timestamp console output\n";
+}
+
 // --------------------------------------------------------------------------
 //
 // Function
@@ -124,6 +153,7 @@
 		}
 		break;
 
+#ifndef WIN32
 		case 'D':
 		{
 			mSingleProcess = true;
@@ -136,6 +166,20 @@
 		}
 		break;
 
+		case 'k':
+		{
+			mKeepConsoleOpenAfterFork = true;
+		}
+		break;
+#endif
+
+		case 'h':
+		{
+			Usage();
+			return 2;
+		}
+		break;
+
 		case 'q':
 		{
 			if(mLogLevel == Log::NOTHING)
@@ -180,12 +224,6 @@
 		}
 		break;
 
-		case 'k':
-		{
-			mKeepConsoleOpenAfterFork = true;
-		}
-		break;
-
 		case '?':
 		{
 			BOX_FATAL("Unknown option on command line: " 
@@ -219,6 +257,7 @@
 {
 	// Find filename of config file
 	mConfigFileName = DefaultConfigFile;
+	mAppName = argv[0];
 
 	#ifdef NDEBUG
 	mLogLevel = Log::NOTICE; // need an int to do math with
@@ -226,6 +265,12 @@
 	mLogLevel = Log::INFO; // need an int to do math with
 	#endif
 
+	if (argc == 2 && strcmp(argv[1], "/?") == 0)
+	{
+		Usage();
+		return 2;
+	}
+
 	signed int c;
 
 	// reset getopt, just in case anybody used it before.
@@ -283,11 +328,9 @@
 {
 	// Banner (optional)
 	{
-		const char *banner = DaemonBanner();
-		if(banner != 0)
-		{
-			BOX_NOTICE(banner);
-		}
+		#ifndef NDEBUG
+		BOX_NOTICE(DaemonBanner());
+		#endif
 	}
 
 	std::string pidFileName;
@@ -671,9 +714,9 @@
 //		Created: 1/1/04
 //
 // --------------------------------------------------------------------------
-const char *Daemon::DaemonBanner() const
+std::string Daemon::DaemonBanner() const
 {
-	return 0;
+	return "Generic daemon using the Box Application Framework";
 }
 
 

Modified: box/trunk/lib/server/Daemon.h
===================================================================
--- box/trunk/lib/server/Daemon.h	2007-10-17 12:53:52 UTC (rev 1890)
+++ box/trunk/lib/server/Daemon.h	2007-10-17 12:54:17 UTC (rev 1891)
@@ -50,8 +50,9 @@
 	const std::string &GetConfigFileName() const {return mConfigFileName;}
 
 	virtual const char *DaemonName() const;
-	virtual const char *DaemonBanner() const;
+	virtual std::string DaemonBanner() const;
 	virtual const ConfigurationVerify *GetConfigVerify() const;
+	virtual void Usage();
 	
 	bool StopRun() {return mReloadConfigWanted | mTerminateWanted;}
 	bool IsReloadConfigWanted() {return mReloadConfigWanted;}
@@ -87,6 +88,7 @@
 	bool mHaveConfigFile;
 	int mLogLevel; // need an int to do math with
 	static Daemon *spDaemon;
+	std::string mAppName;
 };
 
 #define DAEMON_VERIFY_SERVER_KEYS 	{"PidFile", 0, ConfigTest_Exists, 0}, \


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:55:06 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:55:06 +0100
Subject: [Box Backup-commit] COMMIT r1892 - box/trunk/bin/bbackupd
Message-ID: <E1Ii8QU-0006Rr-0l@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:55:05 +0100 (Wed, 17 Oct 2007)
New Revision: 1892

Modified:
   box/trunk/bin/bbackupd/BackupDaemon.cpp
   box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp
   box/trunk/bin/bbackupd/Win32ServiceFunctions.h
Log:
Use the specified service name when installing and removing the service.

Pass the service name on the service command line, and use it for event
log messages.

(merges [1856])


Modified: box/trunk/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:54:17 UTC (rev 1891)
+++ box/trunk/bin/bbackupd/BackupDaemon.cpp	2007-10-17 12:55:05 UTC (rev 1892)
@@ -128,7 +128,8 @@
 	#ifdef WIN32
 	, mInstallService(false),
 	  mRemoveService(false),
-	  mRunAsService(false)
+	  mRunAsService(false),
+	  mServiceName("bbackupd")
 	#endif
 {
 	// Only ever one instance of a daemon
@@ -347,14 +348,16 @@
 {
 	if (mInstallService)
 	{
-		return InstallService(rConfigFileName.c_str());
+		return InstallService(rConfigFileName.c_str(), mServiceName);
 	}
 
 	if (mRemoveService)
 	{
-		return RemoveService();
+		return RemoveService(mServiceName);
 	}
 
+	Logging::SetProgramName("Box Backup (" + mServiceName + ")");
+
 	int returnCode;
 
 	if (mRunAsService)

Modified: box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp
===================================================================
--- box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp	2007-10-17 12:54:17 UTC (rev 1891)
+++ box/trunk/bin/bbackupd/Win32ServiceFunctions.cpp	2007-10-17 12:55:05 UTC (rev 1892)
@@ -199,7 +199,7 @@
 	return 0;
 }
 
-int InstallService(const char* pConfigFileName)
+int InstallService(const char* pConfigFileName, const std::string& rServiceName)
 {
 	if (pConfigFileName != NULL)
 	{
@@ -235,7 +235,7 @@
 	cmd[sizeof(cmd)-1] = 0;
 
 	std::string cmdWithArgs(cmd);
-	cmdWithArgs += " -s";
+	cmdWithArgs += " -s -S \"" + rServiceName + "\"";
 
 	if (pConfigFileName != NULL)
 	{
@@ -244,10 +244,12 @@
 		cmdWithArgs += "\"";
 	}
 
+	std::string serviceDesc = "Box Backup (" + rServiceName + ")";
+
 	SC_HANDLE newService = CreateService(
 		scm, 
-		SERVICE_NAME, 
-		"Box Backup", 
+		rServiceName.c_str(),
+		serviceDesc.c_str(),
 		SERVICE_ALL_ACCESS, 
 		SERVICE_WIN32_OWN_PROCESS, 
 		SERVICE_AUTO_START, 
@@ -312,7 +314,7 @@
 	return 0;
 }
 
-int RemoveService(void)
+int RemoveService(const std::string& rServiceName)
 {
 	SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
 
@@ -323,7 +325,7 @@
 		return 1;
 	}
 
-	SC_HANDLE service = OpenService(scm, SERVICE_NAME, 
+	SC_HANDLE service = OpenService(scm, rServiceName.c_str(), 
 		SERVICE_ALL_ACCESS|DELETE);
 	DWORD err = GetLastError();
 	CloseServiceHandle(scm);

Modified: box/trunk/bin/bbackupd/Win32ServiceFunctions.h
===================================================================
--- box/trunk/bin/bbackupd/Win32ServiceFunctions.h	2007-10-17 12:54:17 UTC (rev 1891)
+++ box/trunk/bin/bbackupd/Win32ServiceFunctions.h	2007-10-17 12:55:05 UTC (rev 1892)
@@ -12,8 +12,8 @@
 #ifndef WIN32SERVICEFUNCTIONS_H
 #define WIN32SERVICEFUNCTIONS_H
 
-int RemoveService  (void);
-int InstallService (const char* pConfigFilePath);
+int RemoveService  (const std::string& rServiceName);
+int InstallService (const char* pConfigFilePath, const std::string& rServiceName);
 int OurService     (const char* pConfigFileName);
 
 #endif


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:55:24 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:55:24 +0100
Subject: [Box Backup-commit] COMMIT r1893 - box/trunk/lib/common
Message-ID: <E1Ii8Qm-0007mY-IJ@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:55:24 +0100 (Wed, 17 Oct 2007)
New Revision: 1893

Modified:
   box/trunk/lib/common/Timer.cpp
Log:
Make detailed timer debugging work on Windows as well.

Add a couple of macros to clean up the code.

(merges [1857])


Modified: box/trunk/lib/common/Timer.cpp
===================================================================
--- box/trunk/lib/common/Timer.cpp	2007-10-17 12:55:05 UTC (rev 1892)
+++ box/trunk/lib/common/Timer.cpp	2007-10-17 12:55:24 UTC (rev 1893)
@@ -129,6 +129,14 @@
 	Reschedule();
 }
 
+#define FORMAT_BOX_TIME(t) \
+	(BoxTimeToSeconds(t)) << "." << \
+	(BoxTimeToMicroSeconds(t) % MICRO_SEC_IN_SEC)
+
+#define FORMAT_MICROSECONDS(t) \
+	(int)(t / 1000000) << "." << \
+	(int)(t % 1000000)
+
 // --------------------------------------------------------------------------
 //
 // Function
@@ -178,8 +186,7 @@
 		
 			if (timeToExpiry <= 0)
 			{
-				BOX_TRACE((int)(timeNow / 1000000) << "." <<
-					(int)(timeNow % 1000000) <<
+				BOX_TRACE(FORMAT_MICROSECONDS(timeNow) <<
 					": timer " << *i << " has expired, "
 					"triggering it");
 				rTimer.OnExpire();
@@ -189,12 +196,10 @@
 			}
 			else
 			{
-				BOX_TRACE((int)(timeNow / 1000000) << "." <<
-					(int)(timeNow % 1000000) <<
+				BOX_TRACE(FORMAT_MICROSECONDS(timeNow) <<
 					": timer " << *i << " has not "
 					"expired, triggering in " <<
-					(int)(timeToExpiry / 1000000) << "." <<
-					(int)(timeToExpiry % 1000000) <<
+					FORMAT_MICROSECONDS(timeToExpiry) <<
 					" seconds");
 			}
 		}
@@ -260,22 +265,20 @@
 : mExpires(GetCurrentBoxTime() + SecondsToBoxTime(timeoutSecs)),
   mExpired(false)
 {
-	#if !defined NDEBUG && !defined WIN32
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
+	#ifndef NDEBUG
+	box_time_t timeNow = GetCurrentBoxTime();
 	if (timeoutSecs == 0)
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised for " <<
 			timeoutSecs << " secs, will not fire");
 	}
 	else
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised for " <<
 			timeoutSecs << " secs, to fire at " <<
-			(int)(mExpires / 1000000) << "." <<
-			(int)(mExpires % 1000000));
+			FORMAT_MICROSECONDS(mExpires));
 	}
 	#endif
 
@@ -291,10 +294,9 @@
 
 Timer::~Timer()
 {
-	#if !defined NDEBUG && !defined WIN32
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+	#ifndef NDEBUG
+	box_time_t timeNow = GetCurrentBoxTime();
+	BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 		": timer " << this << " destroyed");
 	#endif
 
@@ -305,24 +307,23 @@
 : mExpires(rToCopy.mExpires),
   mExpired(rToCopy.mExpired)
 {
-	#if !defined NDEBUG && !defined WIN32
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
+	#ifndef NDEBUG
+	box_time_t timeNow = GetCurrentBoxTime();
 	if (mExpired)
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << ", already expired, will not fire");
 	}
 	else if (mExpires == 0)
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << ", no expiry, will not fire");
 	}
 	else
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << " to fire at " <<
 			(int)(mExpires / 1000000) << "." <<
@@ -338,24 +339,23 @@
 
 Timer& Timer::operator=(const Timer& rToCopy)
 {
-	#if !defined NDEBUG && !defined WIN32
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
+	#ifndef NDEBUG
+	box_time_t timeNow = GetCurrentBoxTime();
 	if (rToCopy.mExpired)
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << ", already expired, will not fire");
 	}
 	else if (rToCopy.mExpires == 0)
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << ", no expiry, will not fire");
 	}
 	else
 	{
-		BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
+		BOX_TRACE(FORMAT_BOX_TIME(timeNow) <<
 			": timer " << this << " initialised from timer " <<
 			&rToCopy << " to fire at " <<
 			(int)(rToCopy.mExpires / 1000000) << "." <<
@@ -375,11 +375,9 @@
 
 void Timer::OnExpire()
 {
-	#if !defined NDEBUG && !defined WIN32
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	BOX_TRACE(tv.tv_sec << "." << tv.tv_usec <<
-		": timer " << this << " fired");
+	#ifndef NDEBUG
+	box_time_t timeNow = GetCurrentBoxTime();
+	BOX_TRACE(FORMAT_BOX_TIME(timeNow) << ": timer " << this << " fired");
 	#endif
 
 	mExpired = true;


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:55:46 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:55:46 +0100
Subject: [Box Backup-commit] COMMIT r1894 - box/trunk/lib/server
Message-ID: <E1Ii8R8-0008wb-7G@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:55:46 +0100 (Wed, 17 Oct 2007)
New Revision: 1894

Modified:
   box/trunk/lib/server/SocketStream.cpp
Log:
Compile fix for MSVC (Gary) (merges [1861])


Modified: box/trunk/lib/server/SocketStream.cpp
===================================================================
--- box/trunk/lib/server/SocketStream.cpp	2007-10-17 12:55:24 UTC (rev 1893)
+++ box/trunk/lib/server/SocketStream.cpp	2007-10-17 12:55:46 UTC (rev 1894)
@@ -168,14 +168,17 @@
 		::close(mSocketHandle);
 #endif
 
+#ifdef WIN32
 		BOX_ERROR("Failed to connect to socket (type " << Type <<
 			", name " << Name << ", port " << Port << "): " <<
-			#ifdef WIN32
 				GetErrorMessage(err)
-			#else
+			);
+#else
+		BOX_ERROR("Failed to connect to socket (type " << Type <<
+			", name " << Name << ", port " << Port << "): " <<
 				strerror(err) << " (" << err << ")"
-			#endif
 			);
+#endif
 
 		mSocketHandle = INVALID_SOCKET_VALUE;
 		THROW_EXCEPTION(ConnectionException, Conn_SocketConnectError)


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:56:38 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:56:38 +0100
Subject: [Box Backup-commit] COMMIT r1895 - in box/chris/general/distribution/boxbackup/contrib: . debian
Message-ID: <E1Ii8Ry-000Lpu-DZ@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:56:38 +0100 (Wed, 17 Oct 2007)
New Revision: 1895

Added:
   box/chris/general/distribution/boxbackup/contrib/debian/
   box/chris/general/distribution/boxbackup/contrib/debian/README.txt
   box/chris/general/distribution/boxbackup/contrib/debian/bbackupd
   box/chris/general/distribution/boxbackup/contrib/debian/bbstored
Removed:
   box/chris/general/distribution/boxbackup/contrib/debian/README.txt
   box/chris/general/distribution/boxbackup/contrib/debian/bbackupd
   box/chris/general/distribution/boxbackup/contrib/debian/bbstored
Log:
Added Debian initscripts, thanks to James Stark. (merges [1844])


Copied: box/chris/general/distribution/boxbackup/contrib/debian (from rev 1844, box/trunk/distribution/boxbackup/contrib/debian)

Deleted: box/chris/general/distribution/boxbackup/contrib/debian/README.txt
===================================================================
--- box/trunk/distribution/boxbackup/contrib/debian/README.txt	2007-09-19 22:32:50 UTC (rev 1844)
+++ box/chris/general/distribution/boxbackup/contrib/debian/README.txt	2007-10-17 12:56:38 UTC (rev 1895)
@@ -1,9 +0,0 @@
-These start scripts are for Debian GNU/Linux.  If installed manually they should
-be placed in /etc/init.d.  To create the symbolic links for the appropriate run
-levels execute the following commands:
-
-update-rc.d bbackupd defaults 90
-update-rc.d bbstored defaults 80
-
-James Stark
-<jstark@ieee.org>

Copied: box/chris/general/distribution/boxbackup/contrib/debian/README.txt (from rev 1844, box/trunk/distribution/boxbackup/contrib/debian/README.txt)
===================================================================
--- box/chris/general/distribution/boxbackup/contrib/debian/README.txt	                        (rev 0)
+++ box/chris/general/distribution/boxbackup/contrib/debian/README.txt	2007-10-17 12:56:38 UTC (rev 1895)
@@ -0,0 +1,9 @@
+These start scripts are for Debian GNU/Linux.  If installed manually they should
+be placed in /etc/init.d.  To create the symbolic links for the appropriate run
+levels execute the following commands:
+
+update-rc.d bbackupd defaults 90
+update-rc.d bbstored defaults 80
+
+James Stark
+<jstark@ieee.org>

Deleted: box/chris/general/distribution/boxbackup/contrib/debian/bbackupd
===================================================================
--- box/trunk/distribution/boxbackup/contrib/debian/bbackupd	2007-09-19 22:32:50 UTC (rev 1844)
+++ box/chris/general/distribution/boxbackup/contrib/debian/bbackupd	2007-10-17 12:56:38 UTC (rev 1895)
@@ -1,38 +0,0 @@
-#! /bin/sh
-
-# Start and stop the Box Backup client daemon.
-
-test -x /usr/local/bin/bbackupd || exit 0
-test -f /etc/box/bbackupd.conf || exit 0
-
-case $1 in
-	start)
-		echo -n "Starting Box Backup Client daemon: bbackupd"
-		start-stop-daemon --start --quiet --exec /usr/local/bin/bbackupd > /dev/null
-		echo "."
-		;;
-		
-	stop)
-		echo -n "Stopping Box Backup Client daemon: bbackupd"
-		start-stop-daemon --stop --quiet --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
-		echo "."
-		;;
-	
-	reload|force-reload)
-		echo -n "Reloading the Box Backup Client daemon's configuration"
-		start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
-		echo "."
-		;;
-		
-	restart)
-		echo -n "Restarting the Box Backup Client daemon: bbackupd"	
-		start-stop-daemon --stop --quiet --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
-		start-stop-daemon --start --quiet --exec /usr/local/bin/bbackupd > dev/null
-		echo "."
-		;;
-	*)
-		echo "Usage: /etc/init.d/bbackupd {start|stop|reload|force-reload|restart}"
-		exit 1
-esac
-
-exit 0

Copied: box/chris/general/distribution/boxbackup/contrib/debian/bbackupd (from rev 1844, box/trunk/distribution/boxbackup/contrib/debian/bbackupd)
===================================================================
--- box/chris/general/distribution/boxbackup/contrib/debian/bbackupd	                        (rev 0)
+++ box/chris/general/distribution/boxbackup/contrib/debian/bbackupd	2007-10-17 12:56:38 UTC (rev 1895)
@@ -0,0 +1,38 @@
+#! /bin/sh
+
+# Start and stop the Box Backup client daemon.
+
+test -x /usr/local/bin/bbackupd || exit 0
+test -f /etc/box/bbackupd.conf || exit 0
+
+case $1 in
+	start)
+		echo -n "Starting Box Backup Client daemon: bbackupd"
+		start-stop-daemon --start --quiet --exec /usr/local/bin/bbackupd > /dev/null
+		echo "."
+		;;
+		
+	stop)
+		echo -n "Stopping Box Backup Client daemon: bbackupd"
+		start-stop-daemon --stop --quiet --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
+		echo "."
+		;;
+	
+	reload|force-reload)
+		echo -n "Reloading the Box Backup Client daemon's configuration"
+		start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
+		echo "."
+		;;
+		
+	restart)
+		echo -n "Restarting the Box Backup Client daemon: bbackupd"	
+		start-stop-daemon --stop --quiet --pidfile /var/run/bbackupd.pid --exec /usr/local/bin/bbackupd
+		start-stop-daemon --start --quiet --exec /usr/local/bin/bbackupd > dev/null
+		echo "."
+		;;
+	*)
+		echo "Usage: /etc/init.d/bbackupd {start|stop|reload|force-reload|restart}"
+		exit 1
+esac
+
+exit 0

Deleted: box/chris/general/distribution/boxbackup/contrib/debian/bbstored
===================================================================
--- box/trunk/distribution/boxbackup/contrib/debian/bbstored	2007-09-19 22:32:50 UTC (rev 1844)
+++ box/chris/general/distribution/boxbackup/contrib/debian/bbstored	2007-10-17 12:56:38 UTC (rev 1895)
@@ -1,38 +0,0 @@
-#! /bin/sh
-
-# Start and stop the Box Backup Server.
-
-test -x /usr/local/bin/bbstored || exit 0
-test -f /etc/box/bbstored.conf || exit 0
-
-case $1 in
-	start)
-		echo -n "Starting the Box Backup Server daemon: bbstored"
-		start-stop-daemon --start --quiet --exec /usr/local/bin/bbstored > /dev/null
-		echo "."
-		;;
-	
-	stop)
-		echo -n "Stopping the Box Backup Server daemon: bbstored"
-		start-stop-daemon --stop --quiet --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
-		echo "."
-		;;
-	
-	reload|force-reload)
-		echo -n "Reloading the Box Backup Server's configuration"
-			start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
-		echo "."
-		;;
-	
-	restart)
-		echo -n "Restarting the Box Backup Server daemon: bbstored"
-		start-stop-daemon --stop --quiet --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
-		start-stop-daemon --start --quiet --exec /usr/local/bin/bbstored > /dev/null
-		echo "."
-		;;
-	
-	*)
-		echo "Usage /etc/init.d/bbstored {start|stop|reload|force-reload|restart}"
-esac
-
-exit 0

Copied: box/chris/general/distribution/boxbackup/contrib/debian/bbstored (from rev 1844, box/trunk/distribution/boxbackup/contrib/debian/bbstored)
===================================================================
--- box/chris/general/distribution/boxbackup/contrib/debian/bbstored	                        (rev 0)
+++ box/chris/general/distribution/boxbackup/contrib/debian/bbstored	2007-10-17 12:56:38 UTC (rev 1895)
@@ -0,0 +1,38 @@
+#! /bin/sh
+
+# Start and stop the Box Backup Server.
+
+test -x /usr/local/bin/bbstored || exit 0
+test -f /etc/box/bbstored.conf || exit 0
+
+case $1 in
+	start)
+		echo -n "Starting the Box Backup Server daemon: bbstored"
+		start-stop-daemon --start --quiet --exec /usr/local/bin/bbstored > /dev/null
+		echo "."
+		;;
+	
+	stop)
+		echo -n "Stopping the Box Backup Server daemon: bbstored"
+		start-stop-daemon --stop --quiet --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
+		echo "."
+		;;
+	
+	reload|force-reload)
+		echo -n "Reloading the Box Backup Server's configuration"
+			start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
+		echo "."
+		;;
+	
+	restart)
+		echo -n "Restarting the Box Backup Server daemon: bbstored"
+		start-stop-daemon --stop --quiet --pidfile /var/run/bbstored.pid --exec /usr/local/bin/bbstored
+		start-stop-daemon --start --quiet --exec /usr/local/bin/bbstored > /dev/null
+		echo "."
+		;;
+	
+	*)
+		echo "Usage /etc/init.d/bbstored {start|stop|reload|force-reload|restart}"
+esac
+
+exit 0


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:57:11 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:57:11 +0100
Subject: [Box Backup-commit] COMMIT r1896 - box/chris/general/lib/common
Message-ID: <E1Ii8SV-000Ebu-7p@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:57:11 +0100 (Wed, 17 Oct 2007)
New Revision: 1896

Modified:
   box/chris/general/lib/common/ExcludeList.cpp
Log:
Compile fix. (merges [1859])


Modified: box/chris/general/lib/common/ExcludeList.cpp
===================================================================
--- box/chris/general/lib/common/ExcludeList.cpp	2007-10-17 12:56:38 UTC (rev 1895)
+++ box/chris/general/lib/common/ExcludeList.cpp	2007-10-17 12:57:11 UTC (rev 1896)
@@ -194,9 +194,15 @@
 				#endif
 
 				// Compile
-				if(::regcomp(pregex, entry.c_str(), 
-					REG_EXTENDED | REG_NOSUB) != 0)
+				int errcode = ::regcomp(pregex, entry.c_str(), 
+					REG_EXTENDED | REG_NOSUB);
+
+				if (errcode != 0)
 				{
+					char buf[1024];
+					regerror(errcode, pregex, buf, sizeof(buf));
+					BOX_ERROR("Invalid regular expression: " <<
+						entry << ": " << buf);
 					THROW_EXCEPTION(CommonException, BadRegularExpression)
 				}
 				


From boxbackup-dev@fluffy.co.uk  Wed Oct 17 13:57:38 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Wed, 17 Oct 2007 13:57:38 +0100
Subject: [Box Backup-commit] COMMIT r1897 - box/chris/general/bin/bbackupquery
Message-ID: <E1Ii8Sw-000MUz-H6@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-17 13:57:38 +0100 (Wed, 17 Oct 2007)
New Revision: 1897

Modified:
   box/chris/general/bin/bbackupquery/bbackupquery.cpp
Log:
Set the locale from the environment, so that international characters
may be entered when using editline. (merges [1860])


Modified: box/chris/general/bin/bbackupquery/bbackupquery.cpp
===================================================================
--- box/chris/general/bin/bbackupquery/bbackupquery.cpp	2007-10-17 12:57:11 UTC (rev 1896)
+++ box/chris/general/bin/bbackupquery/bbackupquery.cpp	2007-10-17 12:57:38 UTC (rev 1897)
@@ -303,7 +303,16 @@
 	}
 	
 	// Get commands from input
+
 #ifdef HAVE_LIBREADLINE
+	// Must initialise the locale before using editline's readline(),
+	// otherwise cannot enter international characters.
+	if (setlocale(LC_ALL, "") == NULL)
+	{
+		BOX_ERROR("Failed to initialise locale. International "
+			"character support may not work.");
+	}
+
 #ifdef HAVE_READLINE_HISTORY
 	using_history();
 #endif


From boxbackup-dev@fluffy.co.uk  Sat Oct 20 23:49:16 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Sat, 20 Oct 2007 23:49:16 +0100
Subject: [Box Backup-commit] COMMIT r1898 - box/trunk/bin/bbackupd/win32
Message-ID: <E1IjN88-000HZy-Ig@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-20 23:49:16 +0100 (Sat, 20 Oct 2007)
New Revision: 1898

Modified:
   box/trunk/bin/bbackupd/win32/bbackupd.conf
Log:
Re-merge the good bits of [1873] with James' suggested improvements.


Modified: box/trunk/bin/bbackupd/win32/bbackupd.conf
===================================================================
--- box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-17 12:57:38 UTC (rev 1897)
+++ box/trunk/bin/bbackupd/win32/bbackupd.conf	2007-10-20 22:49:16 UTC (rev 1898)
@@ -12,35 +12,70 @@
 # If you do not install it in the default location - also do not forget to 
 # change the pid file location (below)
 
-
-# This script is run whenever bbackupd encounters a problem which requires
-# the system administrator to assist:
+# This script is run whenever bbackupd changes state or encounters a
+# problem which requires the system administrator to assist:
+#
 # 1) The store is full, and no more data can be uploaded.
 # 2) Some files or directories were not readable.
-# The default script emails the system administrator.
+# 3) A backup run starts or finishes.
+#
+# The default script emails the system administrator, except for backups
+# starting and stopping, where it does nothing.
+#
+# NOTE: You need to edit the following variables in the script before
+# enabling it:
+#
+# account = "accountnumber"
+# sendto = "your@email.address"
+# smtpserver = "your.smtp.server"
+#
+# You do not need to set smtpserver if the client has the SMTP Service
+# installed, the script will connect directly to the SMTP service.
 
-# NotifyScript = NotifySysadmin.sh
+NotifyScript = cscript "C:\Program Files\Box Backup\NotifySysAdmin.vbs"
 
 
-# A scan of the local discs will be made once an hour (approximately).
-# To avoid cycles of load on the server, this time is randomly adjusted by a small
+# The number of seconds between backup runs under normal conditions. To avoid 
+# cycles of load on the server, this time is randomly adjusted by a small 
 # percentage as the daemon runs.
 
 UpdateStoreInterval = 3600
 
 
-# A file must have been modified at least 6 hours ago before it will be uploaded.
+# The minimum age of a file, in seconds, that will be uploaded. Avoids 
+# repeated uploads of a file which is constantly being modified.
 
 MinimumFileAge = 21600
 
 
-# If a file is modified repeated, it won't be uploaded immediately in case it's modified again.
-# However, it should be uploaded eventually. This is how long we should wait after first noticing
-# a change. (1 day)
+# If a file is modified repeated, it won't be uploaded immediately in case 
+# it's modified again, due to the MinimumFileAge specified above. However, it 
+# should be uploaded eventually even if it is being modified repeatedly. This 
+# is how long we should wait, in seconds, after first noticing a change. 
+# (86400 seconds = 1 day)
 
 MaxUploadWait = 86400
 
+# If the connection is idle for some time (e.g. over 10 minutes or 600
+# seconds, not sure exactly how long) then the server will give up and
+# disconnect the client, resulting in Connection Protocol_Timeout errors
+# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
+# Also, some firewalls and NAT gateways will kill idle connections after
+# similar lengths of time. 
+#
+# This can happen for example when most files are backed up already and
+# don't need to be sent to the store again, while scanning a large
+# directory, or while calculating diffs of a large file. To avoid this,
+# KeepAliveTime specifies that special keep-alive messages should be sent
+# when the connection is otherwise idle for a certain length of time,
+# specified here in seconds.
+#
+# The default is that these messages are never sent, equivalent to setting
+# this option to zero, but we recommend that all users enable this.
 
+KeepAliveTime = 120
+
+
 # Files above this size (in bytes) are tracked, and if they are renamed they will simply be
 # renamed on the server, rather than being uploaded again. (64k - 1)
 
@@ -53,30 +88,38 @@
 DiffingUploadSizeThreshold = 8192
 
 
-# The limit on how much time is spent diffing files. Most files shouldn't take very long,
-# but if you have really big files you can use this to limit the time spent diffing them.
+# The limit on how much time is spent diffing files, in seconds. Most files 
+# shouldn't take very long, but if you have really big files you can use this 
+# to limit the time spent diffing them.
+#
 # * Reduce if you are having problems with processor usage.
-# * Increase if you have large files, and think the upload of changes is too large and want
-#   to spend more time searching for unchanged blocks.
+#
+# * Increase if you have large files, and think the upload of changes is too 
+#   large and you want bbackupd to spend more time searching for unchanged
+#   blocks.
 
-MaximumDiffingTime = 20
+MaximumDiffingTime = 120
 
-# KeepAliveTime requires Gary's SSL KeepAlive patches
-# KeepAliveTime = 250
 
 # Uncomment this line to see exactly what the daemon is going when it's connected to the server.
 
 # ExtendedLogging = yes
 
 
-# Use this to temporarily stop bbackupd from syncronising or connecting to the store.
-# This specifies a program or script script which is run just before each sync, and ideally
-# the full path to the interpreter. It will be run as the same user bbackupd is running as,
-# usually root.
-# The script prints either "now" or a number to STDOUT (and a terminating newline, no quotes).
-# If the result was "now", then the sync will happen. If it's a number, then the script will
-# be asked again in that number of seconds.
-# For example, you could use this on a laptop to only backup when on a specific network.
+# This specifies a program or script script which is run just before each 
+# sync, and ideally the full path to the interpreter. It will be run as the 
+# same user bbackupd is running as, usually root.
+#
+# The script must output (print) either "now" or a number to STDOUT (and a 
+# terminating newline, no quotes).
+#
+# If the result was "now", then the sync will happen. If it's a number, then 
+# no backup will happen for that number of seconds (bbackupd will pause) and 
+# then the script will be run again.
+#
+# Use this to temporarily stop bbackupd from syncronising or connecting to the 
+# store. For example, you could use this on a laptop to only backup when on a 
+# specific network, or when it has a working Internet connection.
 
 # SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
 
@@ -85,16 +128,21 @@
 
 CommandSocket = pipe
 
+# 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 = C:\Program Files\Box Backup\bbackupd\bbackupd.state
+
 Server
 {
 	PidFile = C:\Program Files\Box Backup\bbackupd\bbackupd.pid
 }
 
-# StoreObjectInfoFile requires Gary's client marker serialisation patch
-# StoreObjectInfoFile = C:\Program Files\Box Backup\bbackupd\bbackupd.dat
 
-# 
 # BackupLocations specifies which locations on disc should be backed up. Each
 # directory is in the format
 # 


From boxbackup-dev@fluffy.co.uk  Sat Oct 20 23:50:01 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Sat, 20 Oct 2007 23:50:01 +0100
Subject: [Box Backup-commit] COMMIT r1899 - box/chris/general/bin/bbackupd/win32
Message-ID: <E1IjN8r-000C3z-TJ@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-20 23:50:01 +0100 (Sat, 20 Oct 2007)
New Revision: 1899

Modified:
   box/chris/general/bin/bbackupd/win32/bbackupd.conf
Log:
Re-merge the good bits of [1873] with James' suggested improvements. 
(merges [1898])


Modified: box/chris/general/bin/bbackupd/win32/bbackupd.conf
===================================================================
--- box/chris/general/bin/bbackupd/win32/bbackupd.conf	2007-10-20 22:49:16 UTC (rev 1898)
+++ box/chris/general/bin/bbackupd/win32/bbackupd.conf	2007-10-20 22:50:01 UTC (rev 1899)
@@ -12,35 +12,70 @@
 # If you do not install it in the default location - also do not forget to 
 # change the pid file location (below)
 
-
-# This script is run whenever bbackupd encounters a problem which requires
-# the system administrator to assist:
+# This script is run whenever bbackupd changes state or encounters a
+# problem which requires the system administrator to assist:
+#
 # 1) The store is full, and no more data can be uploaded.
 # 2) Some files or directories were not readable.
-# The default script emails the system administrator.
+# 3) A backup run starts or finishes.
+#
+# The default script emails the system administrator, except for backups
+# starting and stopping, where it does nothing.
+#
+# NOTE: You need to edit the following variables in the script before
+# enabling it:
+#
+# account = "accountnumber"
+# sendto = "your@email.address"
+# smtpserver = "your.smtp.server"
+#
+# You do not need to set smtpserver if the client has the SMTP Service
+# installed, the script will connect directly to the SMTP service.
 
-# NotifyScript = NotifySysadmin.sh
+NotifyScript = cscript "C:\Program Files\Box Backup\NotifySysAdmin.vbs"
 
 
-# A scan of the local discs will be made once an hour (approximately).
-# To avoid cycles of load on the server, this time is randomly adjusted by a small
+# The number of seconds between backup runs under normal conditions. To avoid 
+# cycles of load on the server, this time is randomly adjusted by a small 
 # percentage as the daemon runs.
 
 UpdateStoreInterval = 3600
 
 
-# A file must have been modified at least 6 hours ago before it will be uploaded.
+# The minimum age of a file, in seconds, that will be uploaded. Avoids 
+# repeated uploads of a file which is constantly being modified.
 
 MinimumFileAge = 21600
 
 
-# If a file is modified repeated, it won't be uploaded immediately in case it's modified again.
-# However, it should be uploaded eventually. This is how long we should wait after first noticing
-# a change. (1 day)
+# If a file is modified repeated, it won't be uploaded immediately in case 
+# it's modified again, due to the MinimumFileAge specified above. However, it 
+# should be uploaded eventually even if it is being modified repeatedly. This 
+# is how long we should wait, in seconds, after first noticing a change. 
+# (86400 seconds = 1 day)
 
 MaxUploadWait = 86400
 
+# If the connection is idle for some time (e.g. over 10 minutes or 600
+# seconds, not sure exactly how long) then the server will give up and
+# disconnect the client, resulting in Connection Protocol_Timeout errors
+# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
+# Also, some firewalls and NAT gateways will kill idle connections after
+# similar lengths of time. 
+#
+# This can happen for example when most files are backed up already and
+# don't need to be sent to the store again, while scanning a large
+# directory, or while calculating diffs of a large file. To avoid this,
+# KeepAliveTime specifies that special keep-alive messages should be sent
+# when the connection is otherwise idle for a certain length of time,
+# specified here in seconds.
+#
+# The default is that these messages are never sent, equivalent to setting
+# this option to zero, but we recommend that all users enable this.
 
+KeepAliveTime = 120
+
+
 # Files above this size (in bytes) are tracked, and if they are renamed they will simply be
 # renamed on the server, rather than being uploaded again. (64k - 1)
 
@@ -53,30 +88,38 @@
 DiffingUploadSizeThreshold = 8192
 
 
-# The limit on how much time is spent diffing files. Most files shouldn't take very long,
-# but if you have really big files you can use this to limit the time spent diffing them.
+# The limit on how much time is spent diffing files, in seconds. Most files 
+# shouldn't take very long, but if you have really big files you can use this 
+# to limit the time spent diffing them.
+#
 # * Reduce if you are having problems with processor usage.
-# * Increase if you have large files, and think the upload of changes is too large and want
-#   to spend more time searching for unchanged blocks.
+#
+# * Increase if you have large files, and think the upload of changes is too 
+#   large and you want bbackupd to spend more time searching for unchanged
+#   blocks.
 
-MaximumDiffingTime = 20
+MaximumDiffingTime = 120
 
-# KeepAliveTime requires Gary's SSL KeepAlive patches
-# KeepAliveTime = 250
 
 # Uncomment this line to see exactly what the daemon is going when it's connected to the server.
 
 # ExtendedLogging = yes
 
 
-# Use this to temporarily stop bbackupd from syncronising or connecting to the store.
-# This specifies a program or script script which is run just before each sync, and ideally
-# the full path to the interpreter. It will be run as the same user bbackupd is running as,
-# usually root.
-# The script prints either "now" or a number to STDOUT (and a terminating newline, no quotes).
-# If the result was "now", then the sync will happen. If it's a number, then the script will
-# be asked again in that number of seconds.
-# For example, you could use this on a laptop to only backup when on a specific network.
+# This specifies a program or script script which is run just before each 
+# sync, and ideally the full path to the interpreter. It will be run as the 
+# same user bbackupd is running as, usually root.
+#
+# The script must output (print) either "now" or a number to STDOUT (and a 
+# terminating newline, no quotes).
+#
+# If the result was "now", then the sync will happen. If it's a number, then 
+# no backup will happen for that number of seconds (bbackupd will pause) and 
+# then the script will be run again.
+#
+# Use this to temporarily stop bbackupd from syncronising or connecting to the 
+# store. For example, you could use this on a laptop to only backup when on a 
+# specific network, or when it has a working Internet connection.
 
 # SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
 
@@ -85,16 +128,21 @@
 
 CommandSocket = pipe
 
+# 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 = C:\Program Files\Box Backup\bbackupd\bbackupd.state
+
 Server
 {
 	PidFile = C:\Program Files\Box Backup\bbackupd\bbackupd.pid
 }
 
-# StoreObjectInfoFile requires Gary's client marker serialisation patch
-# StoreObjectInfoFile = C:\Program Files\Box Backup\bbackupd\bbackupd.dat
 
-# 
 # BackupLocations specifies which locations on disc should be backed up. Each
 # directory is in the format
 # 


From boxbackup-dev@fluffy.co.uk  Mon Oct 22 18:25:42 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Mon, 22 Oct 2007 18:25:42 +0100
Subject: [Box Backup-commit] COMMIT r1900 - box/trunk/lib/common
Message-ID: <E1Ik126-000FGr-3z@starbug.netinertia.co.uk>

Author: chris
Date: 2007-10-22 18:25:41 +0100 (Mon, 22 Oct 2007)
New Revision: 1900

Modified:
   box/trunk/lib/common/Timer.cpp
Log:
Bite the bullet and use sigaction() instead, since [1803] shows that
signal() works badly on SuckOS, and James reports that BSD doesn't
have sigset().


Modified: box/trunk/lib/common/Timer.cpp
===================================================================
--- box/trunk/lib/common/Timer.cpp	2007-10-20 22:50:01 UTC (rev 1899)
+++ box/trunk/lib/common/Timer.cpp	2007-10-22 17:25:41 UTC (rev 1900)
@@ -39,9 +39,16 @@
 		InitTimer();
 		SetTimerHandler(Timers::SignalHandler);
 	#else
-		sighandler_t oldHandler = ::sigset(SIGALRM, 
-			Timers::SignalHandler);
-		ASSERT(oldHandler == 0);
+		struct sigaction newact, oldact;
+		newact.sa_handler = Timers::SignalHandler;
+		newact.sa_flags = SA_RESTART;
+		::sigemptyset(&newact.sa_mask);
+		if (::sigaction(SIGALRM, &newact, &oldact) != 0)
+		{
+			BOX_ERROR("Failed to install signal handler");
+			THROW_EXCEPTION(CommonException, Internal);
+		}
+		ASSERT(oldact.sa_handler == 0);
 	#endif // WIN32 && !PLATFORM_CYGWIN
 	
 	spTimers = new std::vector<Timer*>;
@@ -70,8 +77,16 @@
 		int result = ::setitimer(ITIMER_REAL, &timeout, NULL);
 		ASSERT(result == 0);
 
-		sighandler_t oldHandler = ::sigset(SIGALRM, NULL);
-		ASSERT(oldHandler == Timers::SignalHandler);
+		struct sigaction newact, oldact;
+		newact.sa_handler = SIG_DFL;
+		newact.sa_flags = SA_RESTART;
+		::sigemptyset(&newact.sa_mask);
+		if (::sigaction(SIGALRM, &newact, &oldact) != 0)
+		{
+			BOX_ERROR("Failed to remove signal handler");
+			THROW_EXCEPTION(CommonException, Internal);
+		}
+		ASSERT(oldact.sa_handler == Timers::SignalHandler);
 	#endif // WIN32 && !PLATFORM_CYGWIN
 
 	spTimers->clear();
@@ -154,13 +169,21 @@
 	}
 
 	#ifndef WIN32
-	void (*oldhandler)(int) = ::sigset(SIGALRM, Timers::SignalHandler);
-	if (oldhandler != Timers::SignalHandler)
-	{
-		printf("Signal handler was %p, expected %p\n", 
-			oldhandler, Timers::SignalHandler);
-		THROW_EXCEPTION(CommonException, Internal)
-	}
+		struct sigaction oldact;
+		if (::sigaction(SIGALRM, NULL, &oldact) != 0)
+		{
+			BOX_ERROR("Failed to check signal handler");
+			THROW_EXCEPTION(CommonException, Internal)
+		}
+
+		ASSERT(oldact.sa_handler == Timers::SignalHandler);
+
+		if (oldact.sa_handler != Timers::SignalHandler)
+		{
+			printf("Signal handler was %p, expected %p\n", 
+				oldact.sa_handler, Timers::SignalHandler);
+			THROW_EXCEPTION(CommonException, Internal)
+		}
 	#endif
 
 	// Clear the reschedule-needed flag to false before we start.


From boxbackup-dev@fluffy.co.uk  Tue Oct 23 12:11:06 2007
From: boxbackup-dev@fluffy.co.uk (boxbackup-dev@fluffy.co.uk)
Date: Tue, 23 Oct 2007 12:11:06 +0100
Subject: [Box Backup-commit] COMMIT r1901 - in box: . boxbackup-web boxbackup-web/images
Message-ID: <E1IkHf8-000PnD-6t@starbug.netinertia.co.uk>

Author: ben
Date: 2007-10-23 12:11:05 +0100 (Tue, 23 Oct 2007)
New Revision: 1901

Added:
   box/boxbackup-web/
   box/boxbackup-web/004-005.html
   box/boxbackup-web/005-006.html
   box/boxbackup-web/006-007.html
   box/boxbackup-web/accounts.html
   box/boxbackup-web/bbackupctl.html
   box/boxbackup-web/bbstyles.css
   box/boxbackup-web/client.html
   box/boxbackup-web/comparison.html
   box/boxbackup-web/description.html
   box/boxbackup-web/images/
   box/boxbackup-web/images/arrow.png
   box/boxbackup-web/images/bblogo.png
   box/boxbackup-web/images/stepahead.png
   box/boxbackup-web/index.html
   box/boxbackup-web/install.html
   box/boxbackup-web/license.html
   box/boxbackup-web/nonroot.html
   box/boxbackup-web/openssl.html
   box/boxbackup-web/restore.html
   box/boxbackup-web/retrieve.html
   box/boxbackup-web/server.html
   box/boxbackup-web/serverfix.html
   box/boxbackup-web/space.html
   box/boxbackup-web/trouble.html
Log:
Make box backup web site available.

Added: box/boxbackup-web/004-005.html
===================================================================
--- box/boxbackup-web/004-005.html	                        (rev 0)
+++ box/boxbackup-web/004-005.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Changing configuration from 0.04 to 0.05</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Changing configuration from 0.04 to 0.05</h1>
+
+<p>When upgrading from 0.04 to 0.05, you can either rename the 0.04 configuration
+directory, run <tt>bbackup-config</tt> again, and copy the keys and certificates
+to the new directory, or follow the instructions below to modify your configuration files.</p>
+
+<p>Edit <tt>bbackup.conf</tt>. Change <tt>StoreFullNotifyScript</tt> to just
+<tt>NotifyScript</tt>, so it looks like this:</p>
+
+<pre>
+# This script is run whenever bbackupd encounters a problem which requires
+# the system administrator to assist:
+# 1) The store is full, and no more data can be uploaded.
+# 2) Some files or directories were not readable.
+# The default script emails the system administrator.
+
+NotifyScript = /etc/box/bbackupd/NotifySysadmin.sh
+</pre>
+
+<p>This script now takes an argument which specifies what is to be reported, so
+you may wish to edit the script to reflect this. (An example is at the end of this
+page.)</p>
+
+<p>Add this section:</p>
+
+<pre>
+# The limit on how much time is spent diffing files. Most files shouldn't take very long,
+# but if you have really big files you can use this to limit the time spent diffing them.
+# * Reduce if you are having problems with processor usage.
+# * Increase if you have large files, and think the upload of changes is too large and want
+#   to spend more time searching for unchanged blocks.
+
+MaximumDiffingTime = 20
+</pre>
+
+<p>Make any changes to the notify script requried. This is an example script
+generated by <tt>bbackupd-config</tt></p>
+
+
+<pre>
+#!/bin/sh
+
+SUBJECT="BACKUP PROBLEM on host boxdevel.fluffy.co.uk"
+SENDTO="ben"
+
+if [ $1 = store-full ]
+then
+/usr/sbin/sendmail $SENDTO &lt;&lt;EOM
+Subject: $SUBJECT (store full)
+To: $SENDTO
+
+
+The store account for boxdevel.fluffy.co.uk is full.
+
+=============================
+FILES ARE NOT BEING BACKED UP
+=============================
+
+Please adjust the limits on account 45 on server localhost.
+
+EOM
+elif [ $1 = read-error ]
+then
+/usr/sbin/sendmail $SENDTO &lt;&lt;EOM
+Subject: $SUBJECT (read errors)
+To: $SENDTO
+
+
+Errors occured reading some files or directories for backup on boxdevel.fluffy.co.uk.
+
+===================================
+THESE FILES ARE NOT BEING BACKED UP
+===================================
+
+Check the logs on boxdevel.fluffy.co.uk for the files and directories which caused
+these errors, and take appropraite action.
+
+Other files are being backed up.
+
+EOM
+else
+/usr/sbin/sendmail $SENDTO &lt;&lt;EOM
+Subject: $SUBJECT (unknown)
+To: $SENDTO
+
+
+The backup daemon on boxdevel.fluffy.co.uk reported an unknown error.
+
+==========================
+FILES MAY NOT BE BACKED UP
+==========================
+
+Please check the logs on boxdevel.fluffy.co.uk.
+
+EOM
+fi
+</pre>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/005-006.html
===================================================================
--- box/boxbackup-web/005-006.html	                        (rev 0)
+++ box/boxbackup-web/005-006.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Changing configuration from 0.05 to 0.06</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Upgrading from 0.05 to 0.06</h1>
+
+<p><b>A 0.06 server requires all clients to be version 0.06 too.</b> Existing backup store accounts
+are compatible with 0.06, and do not require conversion.</p>
+
+<p>Once a 0.06 client has made changes to a store, it can no longer be read by a previous version, since
+new files will be encrypted using AES. In addition, there has been a format change which is incompatible.
+0.06 clients can read both old and new formats.</p>
+
+<p>The first time a 0.06 client connects to a store previously written by an older version, attribute data
+must be updated. This will result in a comparatively large amount of data transfer, about 120 bytes per file.
+This is because of a change in the way that attribute changes are detected, which is more
+efficient than the old version (after the initial conversion).</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/006-007.html
===================================================================
--- box/boxbackup-web/006-007.html	                        (rev 0)
+++ box/boxbackup-web/006-007.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Changing configuration from 0.06 to 0.07</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Upgrading from 0.06 to 0.07</h1>
+
+<h2>Client</h2>
+
+<p>The following command has been added to the <tt>bbackupd.conf</tt> configuration file:</p>
+
+<pre>
+  SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
+</pre>
+<p>Use this to temporarily stop bbackupd from syncronising or connecting to the store.
+This specifies a program or script script which is run just before each sync, and ideally
+the full path to the interpreter. It will be run as the same user bbackupd is running as,
+usually root.</p>
+<p>The script prints either "now" or a number to STDOUT (and a terminating newline, no quotes).
+If the result was "now", then the sync will happen. If it's a number, then the script will
+be asked again in that number of seconds.</p>
+<p>For example, you could use this on a laptop to only backup when on a specific network.</p>
+
+
+<h2>Server -- non-RAID configurations only</h2>
+
+<p>Version 0.06 and below had a bug where the space used on the server was incorrect if (and only 
+if) you were running it in non-userland RAID mode (that is, only specify one directory to
+<tt>raidfile-config</tt>). Space used would be 50% greater than actually used, meaning that housekeeping would trim files from the accounts prematurely.</p>
+
+<p>This bug has been fixed, but you need to correct the store accounts on the server to get the storage spaced, and hence the housekeeping, working correctly.</p>
+
+<p>Firstly, upgrade the server. Make sure the bbstored daemon is stopped, then for each account do</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts check 12345 fix
+</pre>
+
+<p>where 12345 is the account number. Then, start the server again. After housekeeping has run, which will take a few minutes, the accounts should be corrected, and <tt>bbstoreaccounts</tt> and the <tt>usage</tt> command within <tt>bbackupquery</tt> will report the correct size.</p>
+
+<p>RAID disc sets don't need to do this as the bug only affected non-RAID configurations.</p>
+
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/accounts.html
===================================================================
--- box/boxbackup-web/accounts.html	                        (rev 0)
+++ box/boxbackup-web/accounts.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup certificates and accounts</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+
+<h1>Box Backup certificates and accounts</h1>
+
+<p>There are two steps involved to create an account. You need to create the account on the
+server, and sign a certificate to give the client permission to connect to the server.</p>
+
+<p>Running a Certification Authority for TLS (SSL) connections is not trivial. However,
+I have written a script to do most of the work in a way which is good enough for most
+deployments.</p>
+
+<h2>Warning about clock times</h2>
+
+<p>SSL certificates contain validity dates, including a "valid from" time. If the clock on the
+machine which signs the certificates is not syncronised to the clocks of the machines using these
+certificates, you will probably get strange errors until the start time is reached on all
+machines.</p>
+
+<p>If you get strange errors when attempting to use new certificates, check the clocks! You will
+probably just need to wait a while until the certificates become valid, rather than having to
+regenerate them.</p>
+
+<h2>Set up CA</h2>
+
+<p>It's best to do this on a machine other than your server, probably without direct network access.
+The contents of this directory control who can access your backup store server.</p>
+
+<p>To setup the basic key structure, do</p>
+
+<pre>
+/usr/local/bin/bbstored-certs ca init
+</pre>
+
+<p>(See <a href="openssl.html">OpenSSL notes</a> if you get an OpenSSL error)</p>
+
+<p>This creates the directory 'ca' in the current directory, and initialises it with basic keys.</p>
+
+<h2>Sign a server certificate</h2>
+
+<p>When you use the <tt>bbstored-config</tt> script to set up a config file for a server, it will
+generate a certificate request (CSR) for you. Transfer it to the machine with your CA, then do</p>
+
+<pre>
+/usr/local/bin/bbstored-certs ca sign-server hostname-csr.pem
+</pre>
+
+<p>which signs the certificate for the server. Follow the instructions in the output on which files to install
+on the server. The CSR file is now no longer needed. Make sure you run this command from the directory above
+the directory 'ca'.</p>
+
+<h2>Setting up an account.</h2>
+
+<p>Choose an account number for the user. This must be unique on the server, and is presented as a 31 bit
+number in hex greater than 0, for example, 1 or 75AB23C. Then on the backup store server, create the account
+with</p>
+
+<pre>
+/usr/local/bin/bbstoreaccounts create 75AB23C 0 4096M 4505M
+</pre>
+
+<p>This looks complicated. The numbers are, in order...</p>
+<ul>
+<li>The account number allocated (hex)
+<li>The RAID disc set (0 if you use raidfile-config and don't add a new set)
+<li>Soft limit (size)
+<li>Hard limit (size)
+</ul>
+
+<p>The sizes are are specified in Mb, Gb, or blocks, depending on the suffix. <tt>1M</tt> specifies 1 Mb,
+<tt>1G</tt> specifies 1 Gb, and <tt>1B</tt> specifies 1 block, the size of which depends on how you have
+configured the raidfile system with <tt>raidfile-config</tt>.</p>
+
+<p>In this example, I have allocated 4Gb (assuming you use 2048 byte blocks as per my example) as the soft limit,
+and 4Gb + 10% as the hard limit.</p>
+
+<p><b>NOTE</b> The sizes specified here are pre-RAID. So if you are using userland RAID, you are
+actually allocating two-thirds of this amount. This means that, when you take compression into account, that
+if you allocate 2Gb on the server, it'll probably hold about 2Gb of backed up files (depending on the 
+compressability of those files).</p>
+
+<p>The backup client will (voluntarily) try not to upload more data than is allowed by the soft limit.
+The store server will refuse to accept a file if it would take it over the hard limit, and when doing
+housekeeping for this account, try and delete old versions and deleted files to reduce the space taken
+to below the soft limit.</p>
+
+<p>This command will create some files on disc in the raid file directories (if you run as root, the utility will
+change to the user specified in the bbstored.conf file to write them) and update the accounts file. A server
+restart is not required.</p>
+
+<p><b>NOTE</b> If you get a message saying '<tt>Exception: RaidFile (2/8)</tt>', the directories you specified
+in the raidfile.conf are not writable by the _bbstored user -- fix it, and try again.</p>
+
+<p>Finally, tell the user their account number, and the hostname of your server. They will use this to
+set up the backup client, and send you a CSR. This has the account number embedded in it, and you should
+be sure that it has the right account number in it.</p>
+
+<p>Sign this CSR with</p>
+
+<pre>
+/usr/local/bin/bbstored-certs ca sign 75AB23C-csr.pem
+</pre>
+
+<p>Don't forget to check that the embedded account number is correct! Then send the two files back to the user,
+as instructed by the script.</p>
+
+<p>Please read the <a href="trouble.html">Troubleshooting</a> page if you have problems.</p>
+
+
+<h2>Finding disc space used, and changing limits.</h2>
+
+<p>To display the space used on the server for an account, use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts info 75AB23C
+</pre>
+
+<p>To adjust the soft and hard limits on an account, use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts setlimit 75AB23C new-soft-limit new-hard-limit
+</pre>
+
+<p>You do not need to restart the server if the limits are changed.</p>
+
+
+<h2>Deleting an account</h2>
+
+<p>To remove an account, deleting all the stored files on the server and removing
+the account information which allows a client to log in, use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts delete 75AB23C
+</pre>
+
+<p>This will ask for confirmation. Append <tt>yes</tt> to the command to delete
+without confirmation.</p>
+
+
+<h2>Verifying a store account</h2>
+
+<p>To check that a store account is not corrupt, and optionally fix any errors,
+use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts check 75AB23C
+  /usr/local/bin/bbstoreaccounts check 75AB23C fix
+</pre>
+
+<p>The second command will fix errors it finds, the first will merely report them.</p>
+
+<p>Append <tt>quiet</tt> to reduce the amount of output, although errors are always reported.</p>
+
+<p>See <a href="serverfix.html">fixing problems with corruption on the server</a> for more information.</p>
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
+
+

Added: box/boxbackup-web/bbackupctl.html
===================================================================
--- box/boxbackup-web/bbackupctl.html	                        (rev 0)
+++ box/boxbackup-web/bbackupctl.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Controlling a backup client</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Controlling a backup client</h1>
+
+<p>The <tt>bbackupctl</tt> program sends control commands to the <tt>bbackupd</tt>
+daemon. It must be run as the same user as the daemon, and there is no exception for
+root.</p>
+
+<p>The command line syntax is</p>
+
+<pre>
+  /usr/local/bin/bbackupctl [-q] [-c config-file] command
+</pre>
+
+<p>The <tt>-q</tt> option reduces the amount of output the program emits, and
+<tt>-c</tt> allows an alternative configuration file to be specified.</p>
+
+<p>Valid commands are</p>
+
+<dl>
+<dt>terminate
+<dd>Stop the <tt>bbackupd</tt> daemon now (equivalent to <tt>kill</tt>)
+
+<dt>reload
+<dd>Reload the configuration file (equivalent to <tt>kill -HUP</tt>)
+
+<dt>sync
+<dd>Connect to the server and syncronise files now. (See below)
+</dl>
+
+<p>It communicates with the server via a UNIX domain socket, specified in
+<tt>bbackupd.conf</tt> with the <tt>CommandSocket</tt> directive. This does not
+need to be specified, and <tt>bbackupd</tt> will run without the command socket,
+but in this case <tt>bbackupctl</tt> will not be able to communicate with the daemon.</p>
+
+<p>Some platforms cannot check the user id of the connecting process, so this
+command socket becomes a denial of service security risk. <tt>bbackupd</tt> will
+warn you when it starts up if this is the case on your platform, and you should
+consider removing the <tt>CommandSocket</tt> directive on these platforms.</p>
+
+
+<h2>Using bbackupctl to perform snapshots</h2>
+
+<p><tt>bbackupctl</tt>'s main purpose is to implement snapshot based backups,
+emulating the behaviour of traditional backup software.</p>
+
+<p>Use <tt>bbackupd-config</tt> to write a configuration file in <tt>snapshot</tt>
+mode, and then run the following command as a cron job.</p>
+
+<pre>
+  /usr/local/bin/bbackupctl -q sync
+</pre>
+
+<p>This will cause the backup daemon to upload all changed files immediately.
+<tt>bbackupctl</tt> will exit almost immediately, and will not output anything
+unless there is an error.</p>
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/bbstyles.css
===================================================================
--- box/boxbackup-web/bbstyles.css	                        (rev 0)
+++ box/boxbackup-web/bbstyles.css	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,79 @@
+body {
+	font-family: Verdana, Geneva, Arial, sans-serif;
+	background-color: #edeef3;
+	margin: 0 }
+	
+#header {
+	background-color: #e4e6ed;
+	text-align: left;
+	padding-top: 10px;
+	position: relative;
+	top: 20px;
+	width: 100%;
+	border-top: 1px solid #c4c4d5;
+	border-bottom: 1px solid white }
+	
+#logo {
+	position: relative; 
+	margin-left: 180px }
+	
+	
+#page {
+	font-size: .75em;
+	line-height: 180%;
+	text-align: left;
+	margin-top: 50px;
+	margin-right: 100px;
+	margin-left: 250px;
+	position: relative;
+	width: auto }
+	
+tr,td {font-size: 1em;
+	line-height: 180%;
+	text-align: left;
+	background-color: #e4e6ed;
+	padding: 4px }
+	
+pre, tt { font-size: 1.3em; 
+	color: #088;
+	letter-spacing: 1px;
+	word-spacing: 2px}
+	
+h1 {
+	color: #c00;
+	font-size: medium;
+	margin-bottom: 2em;
+	margin-left: -4em }
+	
+h2 {
+	color: #324e95;
+	font-size: small;
+	margin-top: 2em;
+	margin-left: -4em }
+	
+dt { font-weight: bold }
+	
+ul {
+	list-style-image: url(images/arrow.png) }
+	
+ul li {
+	background-color: #e4e6ed;
+	margin: 1em 6em 1em -2em;
+	padding: 0.2em 0.5em 0.2em 1em;
+	border-style: solid;
+	border-width: 1px;
+	border-color: #c4c4d5 #fff #fff #c4c4d5 }
+	
+a:link {
+	color: #324e95;
+	text-decoration: none;
+	background-color: transparent }
+	
+a:visited {
+	color: #90c;
+	text-decoration: none }
+	
+a:hover {
+	color: #c00;
+	text-decoration: underline;
+	background-color: transparent }
\ No newline at end of file

Added: box/boxbackup-web/client.html
===================================================================
--- box/boxbackup-web/client.html	                        (rev 0)
+++ box/boxbackup-web/client.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup client configuration</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+
+<h1>Box Backup client configuration</h1>
+
+<h2>Before you start</h2>
+
+<p>Before you can do any configuration, you need to know the hostname of the server
+you will be using, and your account number on that server.</p>
+
+<p>Later in the process, you will need to send a certificate request to the administrator
+of that server for it to be signed.</p>
+
+<p>Installation is covered in the <a href="install.html">compiling and installing</a> section.
+You only need the backup-client parcel.</p>
+
+<p><b>It is important that you read all the output of the config scripts.</b> See the end
+of this page for an example.</p>
+
+<p>The backup client has to be run as root, because it needs to read all your files to
+back them up, although it is possible to back up a single user's files by running it as that user.
+(Tip: specify a directory other than /etc/box, and then give the alternate config file
+as the first argument to bbackupd). However, it will fall over if you don't give yourself
+read access to one of your files.</p>
+
+<h2>Step 1</h2>
+
+<p>Run the <tt>bbackupd-config</tt> script to generate the configuration files
+and generate a private key and certificate request.</p>
+
+<pre>
+/usr/local/bin/bbackupd-config /etc/box lazy <b>999</b> <b>hostname</b> /var/bbackupd <b>/home</b>
+</pre>
+
+<p>(See <a href="openssl.html">OpenSSL notes</a> if you get an OpenSSL error)</p>
+
+<p>The items in bold need to be changed. In order, they are the account number, the hostname
+of the server you're using, and finally, the directories you want backed up. You can include as
+many you want here.</p>
+
+<p>However, the directories you specify <b>must not</b> contain other mounted file systems within them
+at any depth. Specify them separately, one per mount point. No checks are currently made to
+catch bad configuration of this nature!</p>
+
+<p>You may also want to consider changing the mode from <i>lazy</i> to <i>snapshot</i>, depending on
+what your system is used for.</p>
+
+<dl>
+<dt>lazy
+<dd>This mode regularly scans the files, with only a rough schedule. It uploads files as and
+when they are changed, if the latest version is more than a set age. This is good for backing up
+user's documents stored on a server, and spreads the load out over the day.
+<dt>snapshot
+<dd>This mode emulates the traditional backup behaviour of taking a snapshot of the filesystem.
+The backup daemon does absolutely nothing until it is instructed to make a backup using the
+<tt>bbackupctl</tt> utility (probably as a cron job), at which point it uploads all files which
+have been changed since the last time it uploaded.
+</dl>
+
+<p>When you run the config script, it will tell you what you need to do next. Don't forget to read
+all the output. An example is shown at the end of this page, but the instructions for your installation
+may be different.</p>
+
+<h2>Step 2</h2>
+
+<p>After you have sent your certificate request off to the server administrator and received your
+certificate and CA root back, install them where instructed by the <tt>bbackupd-config</tt> script in step 1.</p>
+
+<p>You can then run the daemon (as root) by typing <tt>/usr/local/bin/bbackupd</tt>, and of course, adding
+it to your system's startup scripts. The first time it's run it will upload everything. Interrupting
+it and restarting it will only upload files which were not uploaded before - it's very tolerant.</p>
+
+<p>If you run in snapshot mode, you will need to add a cron job to schedule backups. The config
+script will tell you the exact command to use for your system.</p>
+
+<p>Please read the <a href="trouble.html">Troubleshooting</a> page if you have problems.</p>
+
+
+<p><b>Remember</b> to make a traditional backup of the keys file, as instructed. You cannot restore
+files without it.</p>
+
+<p>It is recommended that you backup up all of <tt>/etc/box</tt> as it will make things easier if you
+need to restore files. But only the keys are absolutely essential.</p>
+
+<p>If you want to see what it's doing in more detail (probably a good idea), follow the instructions in the server setup
+to create new log files with syslog.</p>
+
+
+<h2>Adding and removing backed up locations</h2>
+
+<p>By editing the <tt>/etc/box/bbackupd.conf</tt> file, you can add and remove directories
+to back up -- see comments in this file for help. Send <tt>bbackupd</tt> a HUP signal after you modify it.</p>
+
+<p>When you remove a location, it will not be marked as deleted immediately. Instead,
+<tt>bbackupd</tt> waits about two days before doing so, just in case you change your mind.
+After this, it will be eventually removed from the store by the housekeeping process.</p>
+
+
+<h2>Run as root</h2>
+
+<p>The backup client is designed to be run as root. It is possible to
+<a href="nonroot.html">run without root</a>, but this is not recommended.</p>
+
+
+<h2>Clock synchronisation for file servers</h2>
+
+<p>If you are using the backup client to backup a filesystem served from a fileserver,
+you should ideally ensure that the fileserver clocks are synchronised with the fileserver.</p>
+
+<p><tt>bbackupd</tt> will cope perfectly well if the clocks are not synchronised. Errors up
+to about half an hour cause no problems. Larger discrepancies cause a loss of efficiency
+and the potential to back up a file during a write process.</p>
+
+<p>There is a configuration parameter <tt>MaxFileTimeInFuture</tt>, which specifies how far
+in the future a file must be for it to be uploaded as soon as it is seen. You should not need
+to adjust this (default is 2 days). Instead, get those clocks synchronised.</p>
+
+
+<h2>Excluding files and directories from the backup</h2>
+
+<p>Within the <tt>bbackupd.conf</tt> file, there is a section named
+<tt>BackupLocations</tt> which specifies which locations on disc should be backed up.
+It has subsections, each of which is in the format</p>
+
+<pre>
+  <i>name</i>
+  {
+     Path = <i>/path/of/directory</i>
+     <i>(optional exclude directives)</i>
+  }
+</pre>
+
+<p><i>name</i> is derived from the Path by the config script, but should merely be
+unique.</p>
+
+<p>The exclude directives are of the form</p>
+
+<pre>
+  [Exclude|AlwaysInclude][File|Dir][|sRegex] = regex or full pathname
+</pre>
+
+<p>(The regex suffix is shown as 'sRegex' to make File or Dir plural)</p>
+
+<p>For example:</p>
+
+<pre>
+  ExcludeDir = /home/guest-user
+  ExcludeFilesRegex = *.(mp3|MP3)\$
+  AlwaysIncludeFile = /home/username/veryimportant.mp3
+</pre>
+
+<p>This excludes the directory /home/guest-user from the backup along with all mp3
+files, except one MP3 file in particular.</p>
+
+<p>In general, Exclude excludes a file or directory, unless the directory is
+explicitly mentioned in a AlwaysInclude directive.</p>
+
+<p>If a directive ends in Regex, then it is a regular expression rather than a
+explicit full pathname. See</p>
+
+<pre>
+  man 7 re_format
+</pre>
+
+<p>for the regex syntax on your platform.</p>
+
+
+
+
+<h2>Example configuration output</h2>
+
+<p>This is an example of output from the bbstored-config script. <b>Important:</b>
+Follow the instructions output by your script, not the ones here -- they may be different
+for your system.</p>
+
+<pre>
+# /usr/local/bin/bbackupd-config /etc/box lazy 51 server.example.com /var/bbackupd /home /etc/samba
+
+Setup bbackupd config utility.
+
+Configuration:
+   Writing configuration file: /etc/box/bbackupd.conf
+   Account: 51
+   Server hostname: server.example.com
+   Directories to back up:
+      /home
+      /etc/samba
+
+Note: If other file systems are mounted inside these directories, then problems may occur
+with files on the store server being renamed incorrectly. This will cause efficiency
+problems, but not affect the integrity of the backups.
+
+WARNING: Directories not checked against mountpoints. Check mounted filesystems manually.
+
+Creating /etc/box...
+Creating /etc/box/bbackupd
+Generating private key...
+ [OpenSSL output omitted]
+
+Generating keys for file backup
+Writing notify script /etc/box/bbackupd/NotifyStoreFull.sh
+Writing configuration file /etc/box/bbackupd.conf
+
+===================================================================
+
+bbackupd basic configuration complete.
+
+What you need to do now...
+
+1) Make a backup of /etc/box/bbackupd/51-FileEncKeys.raw
+   This should be a secure offsite backup.
+   Without it, you cannot restore backups. Everything else can
+   be replaced. But this cannot.
+   KEEP IT IN A SAFE PLACE, OTHERWISE YOUR BACKUPS ARE USELESS.
+
+2) Send /etc/box/bbackupd/51-csr.pem
+   to the administrator of the backup server, and ask for it to
+   be signed.
+
+3) The administrator will send you two files. Install them as
+      /etc/box/bbackupd/51-cert.pem
+      /etc/box/bbackupd/serverCA.pem
+   after checking their authenticity.
+
+4) You may wish to read the configuration file
+      /etc/box/bbackupd.conf
+   and adjust as appropraite.
+   
+   There are some notes in it on excluding files you do not
+   wish to be backed up.
+
+5) Review the script
+      /etc/box/bbackupd/NotifyStoreFull.sh
+   and check that it will email the right person when the store
+   becomes full. This is important -- when the store is full, no
+   more files will be backed up. You want to know about this.
+
+6) Start the backup daemon with the command
+      /usr/local/bin/bbackupd
+   in /etc/rc.local, or your local equivalent.
+   Note that bbackupd must run as root.
+
+===================================================================
+
+Remember to make a secure, offsite backup of your backup keys,
+as described in step 1 above. If you do not, you have no backups.
+</pre>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
+

Added: box/boxbackup-web/comparison.html
===================================================================
--- box/boxbackup-web/comparison.html	                        (rev 0)
+++ box/boxbackup-web/comparison.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Comparisons to other backup systems</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Comparisons to other backup systems</h1>
+
+<p>Within this document, <i>encrypted</i> and <i>on-line</i> are used in very specific ways to describe backup systems.</p>
+
+<dl>
+<dt>encrypted</dt>
+<dd>The data to be backed up is transmitted and stored on the server so that the data can only be recovered if secret encryption keys are available.</dd>
+
+<dt>on-line</dt>
+<dd>The backup server does not use tape or any other removable archive media. All data is stored within the server file system on conventional hard discs, and every (current) file is always available.</dd>
+</dl>
+
+<p>Only backup systems which are both encrypted and on-line are compared in depth. Other systems have brief notes at the end of this document.</p>
+
+<p>Please email me with any systems I have missed, or corrections to my analysis. This is not intended to promote Box Backup, but as an objective comparison to allow you to decide which system to adopt.</p>
+
+<h2>Encrypted, on-line systems</h2>
+
+<table border="0" cellspacing="4" cellpadding="1">
+<tr><td></td><td><b>Box Backup</b></td>
+<td><b><a href="http://www.nongnu.org/duplicity/">duplicity</a></b></td>
+<td><b><a href="http://miek.nl/projects/hdup16/hdup16.html">hdup</a></b></td>
+</tr>
+
+<tr><td>Development status
+</td><td>stable, under development, not feature complete</td>
+<td>"not stable yet" <a href="http://www.nongnu.org/duplicity/#ToC4">(details)</a></td>
+<td>stable, maintainance only</td>
+</tr>
+
+<tr><td>Changes only when uploading new versions of existing files (like rsync)
+</td><td>yes</td>
+<td>yes</td>
+<td>no</td>
+</tr>
+
+<tr><td>Connects to server using
+</td><td>TLS (SSL)</td>
+<td>ssh/scp, local file access, rsync, ftp</td>
+<td>ssh, local files</td>
+</tr>
+
+<tr><td>Authentication
+</td><td>SSL certificates (client and server)</td>
+<td>Traditional file storage accounts on server (eg unix username,
+virtual FTP etc)</td>
+<td>Traditional file storage accounts on server (eg unix username,
+virtual FTP etc)</td>
+</tr>
+
+<tr><td>Dependencies
+</td><td>OpenSSL</td>
+<td>Python installation, librsync, GnuPG, remote shell</td>
+<td>ssh, mcrypt/GPG, GNU tar</td>
+</tr>
+
+<tr><td>Signed data storage
+</td><td>Implicit</td>
+<td>Explicit with GnuPG</td>
+<td>Implicit/Explicit with GnuPG</td>
+</tr>
+
+<tr><td>Scheduling
+</td><td>Self-contained with randomised element to avoid cyclic server loading, or cron job</td>
+<td>cron job</td>
+<td>cron job</td>
+</tr>
+
+<tr><td>Continuous backup
+</td><td>Yes -- backs up files a configured time after being changed, or...<br>No -- in snapshot mode</td>
+<td>No -- takes a snapshot of the filesystem when it is run</td>
+<td>No -- takes a snapshot of the filesystem when it is run</td>
+</tr>
+
+<tr><td>Handling of old versions and deleted files
+</td><td>Old and deleted files remain on server until store reaches a set limit, after which they are removed. No particular limits on availiability apart from this size limit.</td>
+<td>Full and incremental backups, deletion by user scripts</td>
+<td>Monthly full backups, weekly and daily incremental, deletion of archives by user scripts</td>
+</tr>
+
+<tr><td>Resources used on client
+</td><td>Few Mb of memory, very small amount of disc space</td>
+<td>Status and checksums for all files backed up, plus potentially large temporary files. (however, disc space is cheap, so this is not an issue unless the clients are older machines with small hard drives)</td>
+<td>Minimal (latest versions can stream archives directly to server)</td>
+</tr>
+
+<tr><td>Resources used on server
+</td><td>Disc space</td>
+<td>Disc space, remote shell server, UNIX accounts</td>
+<td>Disc space, ssh, UNIX accounts</td>
+</tr>
+
+<tr><td>Redundant storage on server
+</td><td>Optional built in userland RAID storage</td>
+<td>Relies on OS to provide RAID</td>
+<td>Relies on OS to provide RAID</td>
+</tr>
+
+<tr><td>Restore
+</td><td>FTP-like client, or simple command to restore entire directories</td>
+<td>Simple command to restore entire directories, fetch files or directories by name.</td>
+<td>Simple command to restore entire directories, fetch files or directories by name, will fetch entire archives for single files.</td>
+</tr>
+
+</table>
+
+
+<h2>Other systems</h2>
+
+<table border="0" cellspacing="4" cellpadding="1">
+
+<tr><td></td><td>Encrypted?</td><td>On-line?</td><td>Network</td><td>Notes</td></tr>
+
+<tr><td><a href="http://www.amanda.org/">Amanda</a></td>
+<td>no</td>
+<td>no</td>
+<td>LAN</td>
+<td>The classic network backup system</td>
+</tr>
+
+<tr><td><a href="http://www.bacula.org/">Bacula</a></td>
+<td>no</td>
+<td>yes</td>
+<td>LAN</td>
+<td>Comprehensive job control. Stores lists of backed up files in a database for faster retrieval.
+Can backup to disk as well as tape. Supports encrypted transfer, but not storage.</td>
+</tr>
+
+<tr><td><a href="http://rdiff-backup.stanford.edu/">rdiff-backup</a></td>
+<td>no</td>
+<td>yes</td>
+<td>Remote</td>
+<td>"The idea is to combine the best features of a mirror and an incremental backup."</td>
+</tr>
+
+<tr><td><a href="http://www.rsnapshot.org/">rsnapshot</a></td>
+<td>no</td>
+<td>yes</td>
+<td>Remote</td>
+<td>Perl script. Pulls files over ssh from the source server to the backup server. Creates efficient
+snapshots of the source filesystem.</td>
+</tr>
+
+<tr><td><a href="http://samba.anu.edu.au/rsync/">rsync</a></td>
+<td>no</td>
+<td>yes</td>
+<td>Remote</td>
+<td>Requires extra scripts for automatic scheduling and old version archival. May be less efficient than Box Backup, as it needs to check for existence of every file on the remote side, whereas Box Backup keeps an efficient record.</td>
+</tr>
+
+<tr><td><a href="http://www.mondorescue.org/">Mondo Rescue</a></td>
+<td>no</td>
+<td>no</td>
+<td>n/a</td>
+<td>Backup to local media, aimed at full system recovery.</td>
+</tr>
+
+
+</table>
+
+<p>"Network" is marked as LAN if the system uses so much bandwidth it can only be used on a LAN, Remote if it uses bandwidth conservation techniques which make it suitable for use over an internet connection.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
+
Added: box/boxbackup-web/description.html
===================================================================
--- box/boxbackup-web/description.html	                        (rev 0)
+++ box/boxbackup-web/description.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Description of Box Backup</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Description of Box Backup</h1>
+
+<p>The backup daemon, <tt>bbackupd</tt>, runs on all machines to be backed up. The store server daemon, <tt>bbstored</tt> runs on a central server. Data is sent to the store server, which stores all data on local filesystems, that is, only on local hard drives. Tape or other archive media is <b>not used.</b></p>
+
+<p>The system is designed to be easy to set up and run, and cheap to use. Once set up, there should be no need for user or administrative intervention, apart from usual system maintenance.</p>
+
+<h2>Client daemon</h2>
+
+<p><tt>bbackupd</tt> is configured with a list of directories to back up. It has a <b>lazy</b> approach to backing up data. Every so often, the directories are scanned, and new data is uploaded to the server. This new data must be over a set age before it is uploaded. This prevents rapid revisions of a file resulting in many uploads of the same file in a short period of time.</p>
+
+<p>It can also operate in a <b>snapshot</b> mode, which behaves like traditional backup software. When instructed by an external <tt>bbackupctl</tt> program, it will upload all changed files to the server.</p>
+
+<p>The daemon is always running, although sleeping most of the time. In lazy mode, it is completely self contained -- scripts running under cron jobs are not used. The objective is to keep files backed up, not to make snapshots of the filesystem at particular points in time available.</p>
+
+<p>If an old version of the file is present on the server, a modified version of the rsync algorithm is used to upload only the changed portions of the file.</p>
+
+<p>After a new version is uploaded, the old version is still available (subject to disc space on the server). Similarly, a deleted file is still available. The only limit to their availability is space allocated to this account on the server.</p>
+
+<p>Future versions will add the ability to mark the current state of files on the server, and restore from this mark. This will emulate the changing of tapes in a tape backup system.</p>
+
+<h2>Restoration</h2>
+
+<p>Restoring files is performed using a query tool, <tt>bbackupquery</tt>. This can be used to restore entire directories, or as an 'FTP-like' tool to list and retrieve individual files. Old versions and deleted files can be retrieved using this tool for as long as they are kept on the server.</p>
+
+<h2>Client resource usage</h2>
+
+<p><tt>bbackupd</tt> uses only a minimal amount of disc space to store records on uploaded files -- less than 32 bytes per directory and file over a set size threshold. However, it minimises the amount of queries it must make to the server by storing, in memory, a data structure which allows it to determine what data is new. It does not need to store a record of all files, essentially just the directory names and last modification times. This is not a huge amount of memory.</p>
+
+<p>If there are no changes to the directories, then the client will not even connect to the server.</p>
+
+<h2>Encryption</h2>
+
+<p>The files, directories, filenames and file attributes are all encrypted. By examining the stored files on the server, it is only possible to determine the approximate sizes of a files and the tree structure of the disc (not names, just number of files and subdirectories in a directory). By monitoring the actions performed by a client, it is possible to determine the frequency and approximate scope of changes to files and directories.</p>
+
+<p>The connections between the server and client are encrypted using TLS (latest version of SSL). Traffic analysis is possible to some degree, but limited in usefulness.</p>
+
+<p>An attacker will not be able to recover the backed up data without the encryption keys. Of course, you won't be able to recover your files without the keys either, so you must make a conventional, secure, backup of these keys.</p>
+
+<h2>Authentication</h2>
+
+<p>SSL certificates are used to authenticate clients. UNIX user accounts are not used to minimise the dependence on the configuration of the operating system hosting the server.</p>
+
+<p>A script is provided to run the necessary certification authority with minimal effort.</p>
+
+<h2>Server daemon</h2>
+
+<p>The server daemon is designed to be simple to deploy, and run on the cheapest hardware possible. To avoid the necessity to use expensive hardware RAID or software RAID with complex setup, it (optionally) stores files using RAID techniques.</p>
+
+<p>It does not need to run as a privileged user.</p>
+
+<p>Each account has a set amount of disc space allocated, with a soft and a hard limit. If the account exceeds the soft limit, a housekeeping process will start deleting old versions and deleted files to reduce the space used to below the soft limit. If the backup client attempts to upload a file which causes the store to exceed the hard limit, the upload will be refused.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/images/arrow.png
===================================================================
(Binary files differ)


Property changes on: box/boxbackup-web/images/arrow.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: box/boxbackup-web/images/bblogo.png
===================================================================
(Binary files differ)


Property changes on: box/boxbackup-web/images/bblogo.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: box/boxbackup-web/images/stepahead.png
===================================================================
(Binary files differ)


Property changes on: box/boxbackup-web/images/stepahead.png
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:mime-type
   + application/octet-stream

Added: box/boxbackup-web/index.html
===================================================================
--- box/boxbackup-web/index.html	                        (rev 0)
+++ box/boxbackup-web/index.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup</h1>
+
+<p>An open source, completely automatic on-line backup system for UNIX.
+<ul>
+<li>All backed up data is stored on the server in files on a filesystem -- no tape or archive devices are used
+<li>The server is trusted only to make files available when they are required -- all data is encrypted
+<li>A backup daemon runs on systems to be backed up, and copies encrypted data to the server when it notices changes
+<li>Only changes within files are sent to the server, just like rsync
+<li>Old versions of files on the server are stored as changes from the current version
+<li>Behaves like tape -- old versions and deleted files are available
+<li>Choice of backup behaviour, optimised for document or server backup
+<li>Designed to be easy and cheap to run a server. Portable implementation, and RAID implemented in
+userland for reliability without complex server setup or expensive hardware. (optional)
+</ul>
+</p>
+
+<p>Project status: <b>Stable</b>, but not feature complete</p>
+
+<p><a href="description.html">More information</a>: what it is, and how it works.</p>
+
+<p><a href="comparison.html">Comparisons to other backup systems</a></p>
+
+<p>Distributed under a BSD license. Please read the <a href="license.html">license and commentary</a> now.</p>
+
+<h2>Development team</h2>
+
+<p>Main developers for 0.10: Martin Ebourne, Nick Knight, Jonathan Morton, Gary Niemcewicz, Ben Summers, Chris Wilson</p>
+
+<p>Pre-0.10: Ben Summers, <a href="mailto:ben@fluffy.co.uk">ben@fluffy.co.uk</a></p>
+
+
+<h2>Project status</h2>
+
+<p>This project should be considered as <b>stable, but not feature complete</b>. Over 18 months of testing
+suggests it will be reliable enough to will back up your data, and make it available for restoration.</p>
+
+<p>It has always been possible to <a href="retrieve.html">retrieve old versions</a> of files. 
+Planned features will implement marked versions of the store to emulute backing up onto sets of tapes
+in a controlled manner. This will make restoration of old versions much easier, although in the case
+of retrieving a single old file will not make much difference to the usability as the FTP-like utility
+is already effective.</p>
+
+<p>Given that this is a backup system, I am being very conservative about when I consider it
+ready for production use. That said, I trust my data to it!
+However, as this is quite a young system compared to the alternatives, and operates in a slightly
+different manner, for production use I must recommend that you regularly
+<a href="restore.html">verify your backups</a>.</p>
+
+<p>The documentation is not yet complete, and the error messages you get when things
+go wrong are not as clear as they should be. (see the <a href="trouble.html">troubleshooting</a> page.)
+Please <b>follow the instructions</b> carefully and read everything to avoid problems -- following the
+instructions on this web site will result in a working installation.</p>
+
+
+<h2>Why online backup?</h2>
+
+<p>Because tape is not a reliable solution, unless you...</p>
+<ul>
+<li>spend lots of money on hardware and tapes (cheap hardware is not reliable)
+<li>change the tape daily
+<li>store the tapes off-site
+</ul>
+<p>which is hardly likely to happen in real life.</p>
+
+<p>Backing up to media such as CDROMs is not really a solution either. It needs to be something which 
+just happens without user intervention, and without media which is liable to be corrupted.</p>
+
+<p>So, for the same price as a decent tape backup system, you could buy a server with three big hard discs.
+And for the money you spend on tapes per year (you do replace them regularly, don't you?), you could host
+it in a nice data centre somewhere.</p>
+
+<p>We all have internet connections these days, so connectivity isn't really a problem.
+Although it might be best to archive those
+static files, like MP3s and images, to CDROM or something.</p>
+
+<p>The costs are even less if you pool resources amongst a group of friends. Remember, you don't have 
+to trust the server admin to not look at your files as they're encrypted. You just have to trust them to
+make the files available when you need them.</p>
+
+<h2>Mailing list</h2>
+
+<p>Please join the project mailing list, boxbackup@fluffy.co.uk, for announcements of new versions
+and discussion of the system. Join at the <a href="http://lists.warhead.org.uk/mailman/listinfo/boxbackup">sign up page</a>.</p>
+
+<p>Many thanks to <a href="http://www.warhead.org.uk">Alaric</a> for hosting this list.</p>
+
+<h2>Implementation</h2>
+
+<p>There are three main elements</p>
+<ul>
+<li>bbstored -- backup store server.
+<li>bbackupd -- backup client daemon, which scans for changes and uploads them to the server.
+<li>bbackupquery -- backup query and restore tool.
+</ul>
+<p>Running the store server is a multi-step process, but the backup client is easy.</p>
+
+<p>TLS (SSL revised) is used to encrypt connections, and more importantly, to authenticate servers
+and clients with both server and client side certificates. Scripts are provided to generate and
+manage these certificates.</p>
+
+<p>Stored files are encrypted using AES for file data and Blowfish for metadata. This does mean that the one thing you do need to
+back up off-site and look after is a 1k file containing your keys -- the data on the server is useless
+without it. But it never changes, so that's OK.</p>
+
+<h2>Platforms</h2>
+
+<p>I develop under Darwin and deploy on OpenBSD. The software is designed to take advantage of BSD features
+where useful, but not to rely on them. It should be easily portable to other UNIX like operating
+systems. Ports are available for the following platforms:</p>
+<ul>
+<li><b>OpenBSD</b> (primary platform)
+<li><b>Linux</b>
+<li><b>NetBSD</b> (minor issues with dates on symlinks)
+<li><b>FreeBSD</b>
+<li><b>Darwin</b> / Mac OS X 10.5
+<li><b>Cygwin (Windows)</b> (client only)
+<li><b>Native Windows</b> (client only, not complete)
+<li><b>Solaris</b>
+</ul>
+<p>On these platforms, the software compiles and the tests pass. I do all my deployment on OpenBSD, but I know of
+several people who have had good results under Linux.</p>
+
+<p>More platforms will arrive over time. It takes in general a couple of hours to get it compiling on a BSD-like
+UNIX, and a bit longer on something like Linux which deviates from the BSD way of doing things.</p>
+
+<p>I welcome patches for other platforms, and volunteers to look after ports for a particular platform.
+Programmers notes describing how everything works are included
+in the <tt>notes</tt> directory within the distribution archive.</p>
+
+<h2>Related projects</h2>
+
+<p>There are a number of separate projects which are related to Box Backup. These include:</p>
+
+<p><b><a href="http://boxi.sourceforge.net/">Boxi</a></b> -- a cross platform GUI front end
+for Box Backup.</p>
+
+<h2>Download</h2>
+
+<p>Source only distribution. See documentation on this web site for compilation and installation notes.
+See <tt>notes</tt> directory inside distribution archive for programmers notes.</p>
+
+<p><tt><a href="http://prdownloads.sourceforge.net/boxbackup/boxbackup-0.10.tgz?download">boxbackup-0.10.tgz</a></tt> (823k, MD5=2dc02d87932fdb222ed019443ddcf444, released 23 February 2006)<br>
+(download via SourceForge)</p>
+
+<!--<p><tt><a href="bin/boxbackup-0.04.tgz">boxbackup-0.04.tgz</a></tt> (417k, released 16 Mar 2004)</p>-->
+
+<p><a href="006-007.html">Notes on upgrading from 0.06 to 0.07</a>,
+<a href="005-006.html">0.05 to 0.06</a>,
+<a href="004-005.html">0.04 to 0.05</a></p>
+
+<p><b>A 0.10 or later server requires all clients to be version 0.10 or later too.</b> Existing backup store accounts
+are compatible with 0.10, and do not require conversion.</p>
+
+<p><b>Changes:</b></p>
+<dl>
+<dt>0.10 (23 February 2006)
+<dd>Optimised diffing algorithm -- massive speed improvements<br>
+Improved diff timeout<br>
+Bug fixes<br>
+Solaris support<br>
+Portability improvements, including new autoconf based build<br>
+xattr support (on Linux and Darwin -- backs up resource forks under Mac OS X)<br>
+Readline usage clarified for licensing.<br>
+<i>Experimental</i>: Keep-alive on long diffing operations<br>
+<i>Experimental</i>: Save state for non-server use, speeds up first sync after bbackupd starts (not enabled by default)<br>
+<i>Experimental</i>: Native win32 port integrated into main source tree, fixes and improved build<br>
+<i>Experimental</i>: Support for MinGW and MSVC under Win32<br>
+<b>NOTE</b> Features are marked as experimental if no automated test exists. However, the developers have
+been running them on live systems. Win32 support is not totally complete. 
+
+<dt>0.09 (06 December 2004)
+<dd>Maintenance release<br>
+Bug fixes and reliability changes<br>
+Add support for large files under Linux<br>
+Compile on new platforms<br>
+Solaris and Win32 ports for testing
+
+<dt>0.08 (23 September 2004)
+<dd>Minor bug fixes<br>
+Server stores old versions of files as patches from the current version<br>
+Adjust behaviour of client<br>
+Works under 64bit systems<br>
+Client recovers cleanly from corruption of its working files<br>
+Improvements to build system<br>
+Add contributed code for building RPMs
+
+<dt>0.07 (28 June 2004)
+<dd>Minor bug fixes<br>
+Improvements to build process, including better detection of environment on Linux, especially SuSE 9.x<br>
+Fix wrong space used sizes on store with non-RAID (<a href="006-007.html">see notes</a>)<br>
+Be more paranoid about crypto startup<br>
+Extra checking for file modifications<br>
+SyncAllowScript to allow temporary disabling of syncs, eg only backup from a laptop on certain network connections<br>
+Add force-sync command to bbackupctl, like sync but ignores AllowSyncScript
+
+<dt>0.06 (21 May 2004)
+<dd>Bug fixes<br>
+Use AES for file data<br>
+Cygwin port of client<br>
+Add usage command to bbackupquery<br>
+Add delete [yes] command to bbstoreaccounts<br>
+Add check [fix] [quiet] command to bbstoreaccounts<br>
+Deleted locations in conf file get deleted from server
+
+<dt>0.05 (10 Apr 2004)
+<dd>Bug fixes<br>
+Added configurable "max diffing time" parameter, improved speed of diffing algorithm in edge cases<br>
+Added support for old versions of OpenSSL -- experimental only (but appears to work fine)<br>
+Read errors on files and directories are reported neatly, and no longer abort the backup scan<br>
+NetBSD port fixed<br>
+Server more tolerant of being unexpectedly aborted
+
+<dt>0.04 (16 Mar 2004)
+<dd>Bug fixes and code clean up<br>
+Change to standard BSD license<br>
+Expanded error messages<br>
+Improved flexibility with backup timing, including the ability to do snapshot backups<br>
+Exclude files explictly or with regular expressions<br>
+More work arounds for memory issues with STL in gcc 2.95.x (the gcc 3 version is fine)<br>
+In bbackupquery, add a 'ls' alias, and include 'help' command to document all commands<br>
+The *-config programs are improved and validates options and the configuration more to catch common problems<br>
+bbackupd-config excludes keys file if it might be backed up<br>
+Add bbackupctl program for controlling bbackupd daemon<br>
+bbstoreaccounts takes sizes in blocks, Mb or Gb with unit suffix<br>
+Start and end of last sync recorded in bbackupd working dir<br>
+bbackupquery compares check last modification time to see if this explains any difference<br>
+bbackupd will run a script run to alert administator that store is full (the default script sends an email)
+
+<dt>0.03 (27 Jan 2004)
+<dd>Improvements to the build system, especially configuring for random Linux systems.<br>
+Worked round an issue with the gcc 2.95.x libraries which meant that the backup daemon
+slowly used more and more memory.<br>
+Efficiency improvements.
+
+<dt>0.02 (22 Jan 2004)
+<dd>First public release
+</dl>
+
+<h2>Documentation</h2>
+
+<div style="border:2px solid gray; padding:4px">
+The <a href="http://bbdev.fluffy.co.uk/trac/wiki">Box Backup wiki</a> contains user contributed
+documentation, based on the documents below. Please use it for up to date information about
+Box Backup.
+</div>
+
+<p>This is basic documentation, which will be improved. Note that configuration uses a number
+of scripts to do the hard work -- these all output a lot of detailed instructions on exactly
+what to do. Please read it.</p>
+<ul>
+<li><a href="license.html">License and commentary</a> -- please read
+<li><a href="install.html">Compilation and installation</a>
+<li><a href="client.html">Configuring a client</a>
+<li><a href="server.html">Configuring a server</a>
+<li><a href="accounts.html">Certificates and accounts management</a>
+<li><a href="restore.html">Verify and restore backups</a>
+<li><a href="retrieve.html">Retrieving deleted and old files</a>
+<li><a href="bbackupctl.html">Controlling a backup client</a>
+<li><a href="space.html">Checking the storage space used on the server</a>
+<li><a href="serverfix.html">Fixing problems with corruption on the server</a>
+<li><a href="nonroot.html">Running without root</a>
+<li><b><a href="trouble.html">Troubleshooting</a></b>
+</ul>
+
+
+<p>Programmers notes on how the system works can be found within the notes directory inside the
+distribution archive. In particular, read <tt>notes/backup_encryption.txt</tt> for details of how
+the encryption scheme works, and where to look in the code to verify it.</p>
+
+<h2>Planned future work</h2>
+
+<ul>
+<li>Mark state (marks the current state of the filesystem, to emulate a tape change and restoring from that tape later)
+<li>Bandwidth throttling with timed limits
+<li>Make a OpenBSD "port" for easy installation, when the system is stable enough for general use
+</ul>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004, 2006</p>
+<p>&nbsp;</p>
+<p>Web design by <a href="http://www.wpdfd.com">Joe Gillespie</a></p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/install.html
===================================================================
--- box/boxbackup-web/install.html	                        (rev 0)
+++ box/boxbackup-web/install.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup compile and install</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup compile and install</h1>
+
+<p>In the following instructions, replace <tt>0.00</tt> with the actual version number
+of the archive you have downloaded.</p>
+
+<p>You need the latest version of OpenSSL, as some of the extra APIs it provides are required.
+You should have this anyway, as earlier versions have security flaws. (If you have an earlier
+version installed, the configuration script will give you instructions on enabling experimental
+support for older versions.)</p>
+
+<p>See <a href="openssl.html">OpenSSL notes</a> for more information on OpenSSL issues.</p>
+
+<p>There are some notes in the archive about compiling on various platforms within the
+<tt>boxbackup-0.00</tt> directory -- <b>read them first</b>. For example, if you are compiling under Linux,
+look for <tt>LINUX.txt</tt> as <tt>boxbackup-0.00/LINUX.txt</tt> after untaring the archive.</p>
+
+<p>Download the archive, then in that directory type</p>
+
+<pre>
+tar xvzf boxbackup-0.00.tgz
+cd boxbackup-0.00
+./configure
+make
+</pre>
+
+<p>The server and client will be built and packaged up for installation on this machine,
+or ready to be transferred as tar files to another machine for installation.</p>
+
+<p>This builds two parcels of binaries and scripts, 'backup-client' and 'backup-server'.
+The generated installation scripts assumes you want everything installed in
+<tt>/usr/local/bin</tt></p>
+
+<p>Optionally, type <tt>make test</tt> to run all the tests.</p>
+
+<h2>Local installation</h2>
+
+<p>Type <tt>make install-backup-client</tt> to install the backup client.</p>
+
+<h2>Remote installation</h2>
+
+<p>In the <tt>parcels</tt> directory, there are tar files for each parcel. The name reflects
+the version and platform you have built it for.</p>
+
+<p>Transfer this tar file to the remote server, and unpack it, then run the install script.
+For example:</p>
+
+<pre>
+tar xvzf boxbackup-0.00-backup-server-OpenBSD.tgz
+cd boxbackup-0.00-backup-server-OpenBSD
+./install-backup-server
+</pre>
+
+<h2>Configure options</h2>
+
+<p>You can use arguments to the <tt>configure</tt> script to adjust the compile and
+link lines in the generated Makefiles, should this be necessary for your platform.</p>
+
+<p>Arguments of the form <tt>compile:-option</tt> add the text <tt>-option</tt> to all
+compile statements, and arguments of the form <tt>link:-option</tt> add the text
+<tt>-option</tt> to all link statements.</p>
+
+<p>For example, the line</p>
+
+<pre>
+  ./configure compile:-I/usr/local/share/include link:-lspecial
+</pre>
+
+<p>would configure the system to also search the <tt>/usr/local/share/include</tt> path
+for include files and link with the <tt>special</tt> library.</p>
+
+<p>You may include as many arguments as you need, and they are applied in order.</p>
+
+<p>See <a href="openssl.html">OpenSSL notes</a> for the OpenSSL specific options.</p>
+
+<h2>Tests</h2>
+
+<p>There are a number of unit tests provided. To compile and run one type...</p>
+
+<pre>
+./runtest.pl bbackupd release
+./runtest.pl common debug
+./runtest.pl ALL
+</pre>
+
+<p>The runtest.pl script will compile and run the test. The first argument is the test name,
+and the second the type of build. Use ALL as a test name to run all the tests.</p>
+
+<p>The output from the tests is slightly muddled using this script. If you're developing, porting
+or trying out new things, it might be better to use the following scheme:</p>
+
+<pre>
+cd test/bbackupd
+make
+cd ../../debug/test/bbackupd
+./t
+</pre>
+
+<p>or in release mode...</p>
+
+<pre>
+cd test/bbackupd
+make -D RELEASE
+cd ../../release/test/bbackupd
+./t
+</pre>
+
+<p>(use RELEASE=1 with GNU make)</p>
+
+<p>I tend to use two windows, one for compilation, and one for running tests.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/license.html
===================================================================
--- box/boxbackup-web/license.html	                        (rev 0)
+++ box/boxbackup-web/license.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup license</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup license</h1>
+
+<p>This software is licensed to you under the following terms. If you are intending
+to exploit this software commercially, please contact me for information about the additional
+tools available.</p>
+
+<h2>License</h2>
+
+<pre> 
+Copyright (c) 2003, 2004
+     Ben Summers.  All rights reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   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:
+       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
+   permission.
+
+[Where legally impermissible the Authors do not disclaim liability for 
+direct physical injury or death caused solely by defects in the software 
+unless it is modified by a third party.]
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+</pre>
+
+<h2>Commentary</h2>
+
+<p>This license is based on a standard BSD license. Some minor changes
+in wording have been made to fit in with English law.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/nonroot.html
===================================================================
--- box/boxbackup-web/nonroot.html	                        (rev 0)
+++ box/boxbackup-web/nonroot.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Running without root</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Running without root</h1>
+
+<p>It is possible to run both the server and client without root privileges.</p>
+
+<h2>Server</h2>
+
+<p>The server, by default, runs as a non-root user. However, it expects to be run as root
+and changes user to a specified user as soon as it can, simply for administrative convenience.
+The server uses a port greater than 1024, so it doesn't need root to start.</p>
+
+<p>To run it entirely as a non-root user, edit the <tt>bbstored.conf</tt> file, and remove the
+<tt>User</tt> directive from the <tt>Server</tt> section. Then simply run the server as your
+desired user.</p>
+
+<h2>Client</h2>
+
+<p>The client requires root for normal operation, since it must be able to access all files
+to back them up. However, it is possible to run the client as a non-root user, with certain
+limitations.</p>
+
+<p>Follow the installation instructions, but install the executable files manually to somewhere
+in your home directory. Then use <tt>bbackupd-config</tt> to configure the daemon, but use a
+directory other than <tt>/etc/box</tt>, probably somewhere in your home directory.</p>
+
+<p>All directories you specify to be backed up must be readable, and all files must be owned
+by the user and readable to that user.</p>
+
+<p><b>Important:</b> If any file or directory is not readable by this user, the backup process
+will skip that file or directory. Keep an eye on the logs for reports of this failure.</p>
+
+<p>Non-root operation of the backup client is recommended only for testing, and should not
+be relied on in a production environment.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/openssl.html
===================================================================
--- box/boxbackup-web/openssl.html	                        (rev 0)
+++ box/boxbackup-web/openssl.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup OpenSSL notes</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup OpenSSL notes</h1>
+
+<p>Ideally, you need to use version 0.9.7 or later of OpenSSL. If this is installed on your system by default (and it is on most recent releases of UNIX like OSes) then everything should just work.</p>
+
+<p>However, if it isn't, you have a few options.</p>
+
+<h2>Upgrade installation</h2>
+
+<p>The best option is to upgrade your installation to use 0.9.7. Hopefully your package manager will make this easy for you. This may require reinstallation of lots of software which depends on OpenSSL, so may not be ideal.</p>
+
+<p>(But as there have been a few security flaws in OpenSSL recently, you probably want to upgrade it anyway.)</p>
+
+
+<h2>Install another OpenSSL</h2>
+
+<p>The second best option is to install another copy. If you download and install from source, it will probably install into <tt>/usr/local/ssl</tt>. You can then configure Box Backup to use it using</p>
+
+<pre>
+./configure openssl:/usr/local/ssl
+</pre>
+
+<p>which will set up the various includes and libraries for you.</p>
+
+<p>The configuration scripts may be a problem, depending on your installation. See below for more information.</p>
+
+
+<h2>Use the old version of OpenSSL</h2>
+
+<p>If you have an old version installed, the configuration script will give you instructions on how to enable support for older versions. Read the warnings, and please, whatever you do, don't release binary packages or ports which enable this option.</p>
+
+<p>You may have issues with the configuration scripts, see below.</p>
+
+<p>&nbsp;</p>
+
+
+<h1>If you have problems with the config scripts...</h1>
+
+<p>If you get OpenSSL related errors with the configuration scripts, there are two things to check.</p>
+
+<ol>
+<li>The <tt>bin</tt> directory within your OpenSSL directory is in the path (if you have installed another version)
+<li>You have an <tt>openssl.cnf</tt> file which works and can be found.
+</ol>
+
+<h2>OpenSSL config file</h2>
+
+<p>You need to have an <tt>openssl.cnf</tt> file. The default will generally work well (see example at end). Make sure the <tt>openssl</tt> utility can find it, either set the <tt>OPENSSL_CONF</tt> environment variable, or install it into the location that is mentioned in the error messages.</p>
+
+<h2>Example OpenSSL config file</h2>
+
+<pre>
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+RANDFILE                = /dev/arandom
+
+####################################################################
+[ req ]
+default_bits            = 1024
+default_keyfile         = privkey.pem
+distinguished_name      = req_distinguished_name
+attributes              = req_attributes
+
+[ req_distinguished_name ]
+countryName                     = Country Name (2 letter code)
+#countryName_default            = AU
+countryName_min                 = 2
+countryName_max                 = 2
+
+stateOrProvinceName             = State or Province Name (full name)
+#stateOrProvinceName_default    = Some-State
+
+localityName                    = Locality Name (eg, city)
+
+0.organizationName              = Organization Name (eg, company)
+#0.organizationName_default     = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName             = Second Organization Name (eg, company)
+#1.organizationName_default     = CryptSoft Pty Ltd
+
+organizationalUnitName          = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName                      = Common Name (eg, fully qualified host name)
+commonName_max                  = 64
+
+emailAddress                    = Email Address
+emailAddress_max                = 64
+
+[ req_attributes ]
+challengePassword               = A challenge password
+challengePassword_min           = 4
+challengePassword_max           = 20
+
+unstructuredName                = An optional company name
+
+[ x509v3_extensions ]
+
+nsCaRevocationUrl               = http://www.cryptsoft.com/ca-crl.pem
+nsComment                       = "This is a comment"
+
+# under ASN.1, the 0 bit would be encoded as 80
+nsCertType                      = 0x40
+</pre>
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/restore.html
===================================================================
--- box/boxbackup-web/restore.html	                        (rev 0)
+++ box/boxbackup-web/restore.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup verify and restore files</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup verify and restore files</h1>
+
+<p>Backups are no use unless you can restore them. The <tt>bbackupquery</tt> utility does
+this and more.</p>
+
+<p>You don't provide any login information to it, as it just picks up the data it needs
+from <tt>/etc/box/bbackupd.conf</tt>. You should run it as root so it can find everything
+it needs.</p>
+
+<p>Full documentation can be found in <tt>bin/bbackupquery/documentation.txt</tt> in the distribution
+archive. It follows the model of a command line sftp client quite closely.</p>
+
+<p>On systems where GNU readline is available (by default) it uses that for command line history and
+editing. Otherwise it falls back to very basic UNIX text entry.</p>
+
+
+<h2>Verify backups</h2>
+
+<p>Since this is a development system, you'll be keen to verify that your backups are 
+correct. This is easy.</p>
+
+<pre>
+/usr/local/bin/bbackupquery "compare -a" quit
+</pre>
+
+<p>It will report all the differences between the store and the files on disc. It will download
+everything, so may take a while. You should expect to see some differences on a typical compare,
+because files which have recently changed are unlikely to have been uploaded yet. Consider checking the
+timestamps on the files, or keeping a record of these messages and comparing them with a future verification.</p>
+
+<p>If you would like to do a "quick" check which just downloads file
+checksums and compares against that, then do</p>
+
+<pre>
+/usr/local/bin/bbackupquery "compare -aq" quit
+</pre>
+
+<p>However, this does not check that the file attributes are correct, and since the checksums are generated
+on the client they may not reflect the data on the server if there is a problem -- the server cannot check
+the encrypted contents. View this as a good indication, rather than a definite check that your backup
+verifies correctly.</p>
+
+<p>You may wish to run either one as a cron job while testing this system.</p>
+
+
+<h2>Restore backups</h2>
+
+<p>You will need the keys file created when you configured the server. Without it, <b>you cannot
+restore the files</b>; this is the downside of encrypted backups. However, by keeping the small
+keys file safe, you indirectly keep your entire backup safe.</p>
+
+<p>The first step is to recreate the configuration of the backup client. It's probably best
+to have stored the /etc/box directory with your keys. But if you're recreating it, all you really
+need is to have got the login infomation correct (ie the certs and keys).</p>
+
+<p><b>Don't run bbackupd yet!</b> It will mark all your files as deleted if you do, which is not
+hugely bad in terms of losing data, just a major inconvenience. (This assumes that 
+you are working from a blank slate. If you want to restore some files to a different location,
+it's fine to restore while bbackupd is running, just do it outside a backed up directory to make
+sure it doesn't start uploading the restored files.)</p>
+
+<p>Type <tt>/usr/local/bin/bbackupquery</tt> to run it in interactive mode.</p>
+
+<p>Type <tt>list</tt> to see a list of the locations stored on the server.</p>
+
+<p>For each location you want to restore, type <tt>restore name-on-server local-dir-name</tt>. The 
+directory specified by local-dir-name must not exist yet.</p>
+
+<p>If the restore is interrupted for any reason, repeat the above steps, but add the <tt>-r</tt>
+flag to the restore command to tell it to resume.</p>
+
+
+<h2>Other tricks</h2>
+
+<p>bbackupquery can also...
+<ul>
+<li>List files on the server
+<li>Restore arbitary parts of the file system
+<li><a href="retrieve.html">Recover deleted files</a> (either if the backup daemon hasn't deleted them from the store,
+or if they are marked on the store as deleted but not actually gone yet.)
+<li><a href="retrieve.html">Recover old versions</a> of files which are still on the server.
+</ul>
+</p>
+
+<p>Read <tt>bin/bbackupquery/documentation.txt</tt> for more details.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/retrieve.html
===================================================================
--- box/boxbackup-web/retrieve.html	                        (rev 0)
+++ box/boxbackup-web/retrieve.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Retrieving deleted and old files</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Retrieving deleted and old files</h1>
+
+<p>Box Backup makes old versions of files and files you have deleted available, subject to there
+being enough disc space on the server to hold them.</p>
+
+<p>This is how to retrieve them using <tt>bbackupquery</tt>. Future versions will make this far
+more user-friendly.</p>
+
+<p>Firstly, run <tt>bbackupquery</tt> in interactive mode. It behaves in a similar manner to 
+a command line sftp client.</p>
+
+<pre>
+/usr/local/bin/bbackupquery
+</pre>
+
+<p>Then navigate to the directory containing the file you want, using <tt>list</tt>, <tt>cd</tt>
+and <tt>pwd</tt>.</p>
+
+<pre>
+query &gt; cd home/profiles/USERNAME
+</pre>
+
+<p>List the directory, using the "o" option to list the files available without filtering out
+everything apart from the current version. (if you want to see deleted files as well, use
+<tt>list -odt</tt>)</p>
+
+<pre>
+query &gt; list -ot
+00000078 f--o- 2004-01-21T20:17:48 NTUSER.DAT
+00000079 f--o- 2004-01-21T20:17:48 ntuser.dat.LOG
+0000007a f--o- 2004-01-21T17:55:12 ntuser.ini
+0000007b f---- 2004-01-12T15:32:00 ntuser.pol
+0000007c -d--- 1970-01-01T00:00:00 Templates
+00000089 -d--- 1970-01-01T00:00:00 Start Menu
+000000a0 -d--- 1970-01-01T00:00:00 SendTo
+000000a6 -d--- 1970-01-01T00:00:00 Recent
+00000151 -d--- 1970-01-01T00:00:00 PrintHood
+00000152 -d--- 1970-01-01T00:00:00 NetHood
+00000156 -d--- 1970-01-01T00:00:00 My Documents
+0000018d -d--- 1970-01-01T00:00:00 Favorites
+00000215 -d--- 1970-01-01T00:00:00 Desktop
+00000219 -d--- 1970-01-01T00:00:00 Cookies
+0000048b -d--- 1970-01-01T00:00:00 Application Data
+000005da -d--- 1970-01-01T00:00:00 UserData
+0000437e f--o- 2004-01-24T02:45:43 NTUSER.DAT
+0000437f f--o- 2004-01-24T02:45:43 ntuser.dat.LOG
+00004380 f--o- 2004-01-23T17:01:29 ntuser.ini
+00004446 f--o- 2004-01-24T02:45:43 NTUSER.DAT
+00004447 f--o- 2004-01-24T02:45:43 ntuser.dat.LOG
+000045f4 f---- 2004-01-26T15:54:16 NTUSER.DAT
+000045f5 f---- 2004-01-26T15:54:16 ntuser.dat.LOG
+000045f6 f---- 2004-01-26T16:54:31 ntuser.ini
+</pre>
+
+<p>(this is a listing from a server which is used as a Samba server for a network of
+Windows clients.)</p>
+
+<p>You now need to fetch the file using it's ID, rather than it's name. The ID is the
+hex number in the first column. Fetch it like this:</p>
+
+<pre>
+query &gt; get -i 0000437e NTUSER.DAT
+Object ID 0000437e fetched successfully.
+</pre>
+
+<p>The object is now available on your local machine. You can use <tt>lcd</tt> to move
+around, and <tt>sh ls</tt> to list directories on your local machine.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
+
+
Added: box/boxbackup-web/server.html
===================================================================
--- box/boxbackup-web/server.html	                        (rev 0)
+++ box/boxbackup-web/server.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Box Backup server configuration</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Box Backup server configuration</h1>
+
+<h2>Log files</h2>
+
+<p>You may wish to see what's going on with the server. Edit /etc/syslog.conf, and add</p>
+
+<pre>
+local6.info                         /var/log/box
+local5.info                         /var/log/raidfile
+</pre>
+
+<p>Note separators must be tabs, otherwise it ignores you.</p>
+
+<pre>
+touch /var/log/box
+touch /var/log/raidfile
+</pre>
+
+<p>And then get them rotated, by adding in /etc/newsyslog.conf</p>
+
+<pre>
+/var/log/box                644  7    2000 *     Z
+/var/log/raidfile           644  7    2000 *     Z
+</pre>
+
+<p>Then restart syslogd.</p>
+
+<h2>RAID setup</h2>
+
+<p>The server does RAID in userland for that extra bit of reliability. You need to
+set this up separately from the server. To create <tt>/etc/box/raidfile.conf</tt>,</p>
+
+<pre>
+/usr/local/bin/raidfile-config /etc/box 2048 /raid/0.0 /raid/0.1 /raid/0.2
+</pre>
+
+<p>But adjust it for your system. 2048 is the block size. Under BSD with FFS, set this to
+your filing system's fragment size (most likely an 8th of the block size), otherwise the block size of
+the filing system, for maximum efficiency.</p>
+
+<p>The three directories are the locations of the roots of the raid file directories.
+These are probably the mount points of three big partitions on three <b>separate physical discs</b>.
+If you don't have this, see below on how to disable userland RAID.</p>
+
+<p>Edit <tt>/etc/box/raidfile.conf</tt> if you have another set of three discs you want
+to use -- just add another section for each set.</p>
+
+<h3>Disabling userland RAID</h3>
+
+<p>If you only have one disc, or a hardware RAID array, you probably won't want to use userland
+RAID.</p>
+
+<p>In this case, follow the above instructions, but only specify one directory for the
+<tt>raidfile-config</tt> script. This will generate a raidfile.conf which disables userland
+RAID, and stores files in the single directory you specify.</p>
+
+<p><b>NOTE</b> Running the server in non-RAID mode has not been tested as extensively as
+in RAID file mode.</p>
+
+
+<h2>Server basic setup</h2>
+
+<p>Create a user to run the server under:</p>
+
+<pre>
+useradd _bbstored
+</pre>
+
+<p>Create <tt>/etc/box/bbstored.conf</tt> with:</p>
+
+<pre>
+/usr/local/bin/bbstored-config /etc/box <b>hostname</b> _bbstored
+</pre>
+
+<p>(See <a href="openssl.html">OpenSSL notes</a> if you get an OpenSSL error)</p>
+
+<p>(set hostname to the address the clients
+will use to contact this server) <b>Are you using a NAT device or firewall?</b> See the note below.</p>
+
+<p><b>Read the output</b> for details of what to do next. There is an example at the end of this page,
+but do follow the instructions output when you run the script yourself.</p>
+
+<p>Make sure the user can write to the raid file directories! For more precise control,
+create a <tt>backup</tt> directory within each of the raid root directories, and change
+their permissions accordingly.</p>
+
+<p>If there are other users on this server, you will probably want to stop other users
+reading the certificates.</p>
+
+<pre>
+chown -R _bbstored /etc/box/bbstored
+chmod -R go-rwx /etc/box/bbstored
+</pre>
+
+<h2>Configuration for hosts behind a NAT device or firewall</h2>
+
+<p>The hostname specified is used for 1) the name in the server's certificate and 2) the
+address the server will listen on.</p>
+
+<p>If the IP address of the machine isn't the same as the IP address it appears to have to
+the outside world (because the NAT device or firewall translates it), then this will fail.
+The server will look up the hostname, and then fail to bind to that address since it is not a local
+address.</p>
+
+<p>To get around this, you have two options. Either specify the local IP address with the
+<tt>bbstored-config</tt> command (the name in the certificate won't match the real address, but
+this is not a problem at the moment), or specify the real address, but edit the <tt>bbstored.conf</tt>
+file and correct the <tt>ListenAddresses</tt> directive later to reflect the local address.</p>
+
+<h2>Get certified</h2>
+
+<p>As per the instructions in the <a href="accounts.html">certificates and accounts management</a> page,
+sign your certificate and install it as directed.</p>
+
+<h2>Start the server</h2>
+
+<pre>
+/usr/local/bin/bbstored
+</pre>
+
+<p>Add this to your system startup scripts.</p>
+
+<p>Please read the <a href="trouble.html">Troubleshooting</a> page if you have problems.</p>
+
+<p>If you configured the server so the configuration file is somewhere other than <tt>/etc/box/bbstored.conf</tt>,
+run the server as, for example,<p>
+
+<pre>
+/usr/local/bin/bbstored /some/other/config/dir/bbstored.conf
+</pre>
+
+<h2>root not required</h2>
+
+<p>The backup server is configured to be run as root, but changes user to the user
+you specify as soon as it can -- this is simply for convenience when starting the daemon
+in system start up scripts. However, you can <a href="nonroot.html">run without root</a>
+entirely by making a small change to the configuration file.</p>
+
+
+<h2>Example configuration output</h2>
+
+<p>This is an example of output from the bbstored-config script. <b>Important:</b>
+Follow the instructions output by your script, not the ones here -- they may be different
+for your system.</p>
+
+<pre>
+# /usr/local/bin/bbstored-config /etc/box server.example.com _bbstored                                    
+Checking permissions on /raid/0.0/backup
+Checking permissions on /raid/0.1/backup
+Checking permissions on /raid/0.2/backup
+
+Setup bbstored config utility.
+
+Configuration:
+   Writing configuration file: /etc/box/bbstored.conf
+   Writing empty accounts file: /etc/box/bbstored/accounts.txt
+   Server hostname: server.example.com
+   RaidFile config: /etc/box/raidfile.conf
+
+Creating /etc/box/bbstored
+Creating blank accounts file
+Generating private key...
+ [OpenSSL output omitted]
+
+Writing configuration file /etc/box/bbstored.conf
+
+===================================================================
+
+bbstored basic configuration complete.
+
+What you need to do now...
+
+1) Sign /etc/box/bbstored/server.example.com-csr.pem
+   using the bbstored-certs utility.
+
+2) Install the server certificate and root CA certificate as
+      /etc/box/bbstored/server.example.com-cert.pem
+      /etc/box/bbstored/clientCA.pem
+
+3) You may wish to read the configuration file
+      /etc/box/bbstored.conf
+   and adjust as appropraite.
+
+4) Create accounts with bbstoreaccounts
+
+5) Start the backup store daemon with the command
+      /usr/local/bin/bbstored
+   in /etc/rc.local, or your local equivalent.
+
+===================================================================
+</pre>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: box/boxbackup-web/serverfix.html
===================================================================
--- box/boxbackup-web/serverfix.html	                        (rev 0)
+++ box/boxbackup-web/serverfix.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Fixing problems with corruption on the server</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Fixing problems with corruption on the server</h1>
+
+<p>This page gives help on what to do if your server has suffered corruption, for example,
+after an unclean shutdown or other OS or hardware problem.</p>
+
+<p>In general, as updates to the store are made in an atomic manner, the most
+likely result is wasted disc space. However, if really bad things happen, or you believe that
+there is a lot of wasted space, then these instructions will help to restore your data.</p>
+
+<p>You know you will need to do something if you get strange errors, and <tt>bbackupd</tt> attempts
+to contact the server every 100 seconds or so. Or if one of the discs in your RAID disc set has failed.</p>
+
+<p>After following these instructions, the end result will be that <tt>bbackupquery</tt> will be able to see all the files which
+were stored on your server, and retrieve them. Some of them may be in <tt>lost+found</tt>
+directories in the root of the store (or in their original position if they have been moved) but they will all
+be able to be retrieved.</p>
+
+<p>After you have retrieved the files you want, <tt>bbackupd</tt> will upload new versions
+where necessary, and after about two days, mark any <tt>lost+found</tt> directories as deleted.
+Finally, those directories will be removed by the housekeeping process on the server.</p>
+
+<p>These instructions assume you're working on account 1234, subsitute this for whatever account
+you're actually working on. These will need to be repeated for all affected accounts.</p>
+
+<h2>1. Stop bbackupd</h2>
+
+<p>First, make sure that <tt>bbackupd</tt> is not running on the client machine for the account
+you are going to recover. Use <tt>kill</tt> to terminate it.</p>
+
+<p>(This step is not strictly necessary, but is recommended. During any checks on the account,
+<tt>bbackupd</tt> will be unable to log in, and after they are complete, the account is marked
+as changed on the server so <tt>bbackupd</tt> will perform a complete scan.)</p>
+
+<h2>2. Are you using RAID on the server?</h2>
+
+<p>At the moment, the raidfile recovery tools have not been written. However, when two out of
+three files are available, the server will run succesfully, even if it complains a lot in the logs.
+So, your best bet here is to fix the accounts, if necessary, and retrieve any files you need. Then move
+the old store directories aside (in case you need them) and start afresh with new accounts, and 
+let the clients upload all their data again.</p>
+
+<p>These utilities will be written shortly!</p>
+
+<h2>3. Check and fix the account</h2>
+
+<p>First, run the check utility, and see what errors it reports.</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts check 1234
+</pre>
+
+<p>This will take some time, and use a fair bit of memory (about 16 bytes per file and directory).
+If the output looks plausible and reports errors which need fixing, run it again but with the
+<tt>fix</tt> flag:</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts check 1234 fix
+</pre>
+
+<p>This will fix any errors, and remove unrecoverable files. Directories will be recreated if necessary.</p>
+
+<p><b>NOTE</b>: The utility may adjust the soft and hard limits on the account to make sure that
+housekeeping will not remove anything -- check these afterwards.</p>
+
+<h2>4. Grab any files you need with bbackupquery</h2>
+
+<p>At this point, you will have a working store. Every file which was on the server, and wasn't corrupt,
+will be available.<p>
+
+<p>On the client, use <tt>bbackupquery</tt> to log in and examine the store. (type <tt>help</tt> at the
+prompt for instructions). Retrieve any files you need, paying attention to any <tt>lost+found</tt>
+directories in the root directory of the store.</p>
+
+<p>You can skip this step if you are sure that the client machine is fine -- in this case, <tt>bbackupd</tt>
+will bring the store up to date.</p>
+
+<h2>5. Restart bbackupd</h2>
+
+<p>Restart <tt>bbackupd</tt> on the client machine. The store account will be brought up to date, and
+files in the wrong place will be marked for eventual deletion.</p>
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/space.html
===================================================================
--- box/boxbackup-web/space.html	                        (rev 0)
+++ box/boxbackup-web/space.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Checking the storage space used on the server</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Checking the storage space used on the server</h1>
+
+<h2>From the machine being backed up</h2>
+
+<p><tt>bbackupquery</tt> can tell you how much space is used on the server for this account.</p>
+
+<p>Either use the <tt>usage</tt> command in interactive mode, or type</p>
+
+<pre>
+  /usr/local/bin/bbackupquery -q usage quit
+</pre>
+
+<p>to show the space used as a single command.</p>
+
+
+<h2>On the server</h2>
+
+<p><tt>bbstoreaccounts</tt> allows you to query the space used, and change the limits.
+To display the space used on the server for an account, use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts info 75AB23C
+</pre>
+
+<p>To adjust the soft and hard limits on an account, use</p>
+
+<pre>
+  /usr/local/bin/bbstoreaccounts setlimit 75AB23C new-soft-limit new-hard-limit
+</pre>
+
+<p>You do not need to restart the server.</p>
+
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>

Added: box/boxbackup-web/trouble.html
===================================================================
--- box/boxbackup-web/trouble.html	                        (rev 0)
+++ box/boxbackup-web/trouble.html	2007-10-23 11:11:05 UTC (rev 1901)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+<title>Troubleshooting Box Backup</title>
+<link rel="stylesheet" href="bbstyles.css" type="text/css" />
+</head>
+<body>
+<div align="center">
+<div id="header">
+<div id="logo">
+<img src="images/bblogo.png" alt="logo" height="65" width="331" border="0" vspace="5" align="middle" /> <img src="images/stepahead.png" alt="a step ahead in data security" width="182" height="11" hspace="10" vspace="20" border="0" align="middle" /></div>
+</div>
+<div id="page">
+
+<h1>Troubleshooting Box Backup</h1>
+
+<p><ul><li><b>Note</b>: If you are trying to fix a store after your disc has been corrupted, see
+<a href="serverfix.html">fixing problems with corruption on the server</a>.</ul></p>
+
+<p>Unfortunately, the error messages are not particularly helpful at the moment. This page lists
+some of the common errors, and the most likely causes of them.</p>
+
+<p>When an error occurs, you will see a message like '<tt>Exception: RaidFile/OSFileError (2/8)</tt>' either
+on the screen or in your log files. (it is recommended you set up another log file as recommended
+in the <a href="server.html">server setup instructions</a>.)</p>
+
+<p>This error may not be particularly helpful, although some do have extra information about probable causes.
+To get further information, check the <tt>ExceptionCodes.txt</tt> file in the root of the distribution.
+This file is generated by the <tt>./configure</tt> script, so you will need to have run that first.</p>
+
+<p>Some common causes of exceptions are listed below.</p>
+
+<p>Please email me with any other codes you get, and I will let you know what they mean, and add
+notes here.</p>
+
+
+<h2>RaidFile (2/8)</h2>
+
+<p>This is found either when running <tt>bbstoreaccounts</tt> or in the <tt>bbstored</tt> logs.</p>
+
+<p><b>Problem:</b> The directories you specified in the raidfile.conf are not writable by the _bbstored user.</p>
+
+<p><b>Resolution:</b> Change permissions appropriately.</p>
+
+
+<h2>Common (1/2)</h2>
+
+<p>This usually occurs when the configuration files can't be opened.</p>
+
+<p><b>Problem:</b> You created your configurations in non-standard locations, and the programs
+cannot find them.</p>
+
+<p><b>Resolution:</b> Explicitly specify configuration file locations to daemons and programs. For example</p>
+<pre>
+/usr/local/bin/bbstored /some/other/dir/bbstored.config
+/usr/local/bin/bbackupquery -c /some/other/dir/bbackupd.config
+</pre>
+<p>(daemons specify the name as the first argument, utility programs with the <tt>-c</tt> option.</p>
+
+<p><b>Problem:</b> <tt>bbstored</tt> can't find the <tt>raidfile.conf</tt> file specified in <tt>bbstored.conf</tt>.</p>
+
+<p><b>Resolution:</b> Edit <tt>bbstored.conf</tt> to point to the correct location of this additional configuration file.</p>
+
+
+<h2>Server (3/16)</h2>
+
+<p>The server can't listen for connections on the IP address specified when you configured it.</p>
+
+<p><b>Problem:</b> This probably means you've specified the wrong hostname to bbstored-config --
+maybe your server is behind a NAT firewall?</p>
+
+<p><b>Resolution:</b> Edit <tt>bbstored.conf</tt> and correct the <tt>ListenAddresses</tt> line. You
+should replace the server address with the IP address of your machine.</p>
+
+
+<h2>Connection (7/x)</h2>
+
+<p>These errors all relate to connections failing -- you may see them during operation if there
+are network failures or other problems between the client and server. The backup system will recover
+from them automatically.</p>
+
+
+<p>&nbsp;</p>
+
+<h1>Advanced troubleshooting</h1>
+
+<p>If this really doesn't help, then using the DEBUG builds of the system will give you much more
+information -- a more descriptive exception message and the file and line number where the error occurred.</p>
+
+<p>For example, if you are having problems with <tt>bbstoreaccounts</tt>, build the debug version with</p>
+
+<pre>
+cd boxbackup-0.0
+cd bin/bbstoreaccounts
+make
+</pre>
+
+<p>(within the module directories, <tt>make</tt> defaults to building the debug version. At the top level, 
+it defaults to release.)</p>
+
+<p>This will build an executable in <tt>debug/bin/bbstoreaccounts</tt> which you can then use instead
+of the release version. It will give far more useful error messages.</p>
+
+<p>When you get an error message, use the file and line number to locate where the error occurs in the
+code. There will be comments around that line to explain why the exception happened.</p>
+
+<p>If you are using a debug version of a daemon, these extended messages are found in the log files.</p>
+
+<p>Please get in touch if you need any help.</p>
+
+<p>&nbsp;</p>
+<p>&copy; Ben Summers, 2003, 2004</p>
+<p>&nbsp;</p>
+</div>
+</div>
+</body>
+</html>
+
+
+


