[Box Backup] PATCH: Partial Solaris port

Martin Ebourne boxbackup@fluffy.co.uk
Tue, 23 Nov 2004 11:40:30 +0000


This message is in MIME format.

--=_2prwfsrdqaps
Content-Type: text/plain; charset="windows-1256"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit

Here's most of a Solaris port. Currently it all compiles but does not pass
the testsuite. I don't have time to look at this just at the moment so
posting here for others to play with. Diff is against 0.08PLUS2.

Things to note:

1. This has been made and tested using Solaris 8 and gcc 3.3.3.

2. You will need GNU make to build box. (Usually called 'gmake' on solaris)

3. You will need OpenSSL installed, naturally. I had to link it against the
static libcrypto since for some reason linking against the dynamic one broke
exception handling. I've not had chance to look into that. If using static
you also need -lsocket.

4. GNU readline is required. This is present by default on Solaris 9 or
later, but needs to be installed separately on prior versions.
http://www.sunfreeware.com/ has a package for it.

5. In lib/server/SocketStreamTLS.cpp I have replaced use of ioctl(FIONBIO)
with fcntl(O_NONBLOCK). The latter should be much more portable and achieve
the same thing. I read somewhere out on the web that cygwin may not support
O_NONBLOCK though, in which case the old code will need to be used for that.
I didn't make it conditional because I think this needs to be tested, maybe
cygwin is fixed already.

6. Solaris does not support either of O_EXLOCK or flock. Instead I have used
fcntl(F_SETLK). This has an important semantic difference though: locks are
based on an inode, not an open file descriptor. Hence if the same process
tries to exclusive lock a file twice it will get it. I don't know if this is
a problem for box or not. I know it breaks some of the tests
(eg. test/common/testcommon.cpp:441). If it isn't an issue then the tests
should be conditionally removed (which I have done in the patch).

7. signal has been replaced with sigaction, which is POSIX and should be
portable. Needs testing on other platforms.

8. Took me ages to find why lseek was behaving bizarrely. Eventually I
discovered lseek in intercept.cpp, but only after resorting to machine
level debugging. Not sure why it was assumed that the 'default' platform
has the bizarre mapping to the system call. That must be a BSD thing. :)

9. SPARC does not allow int32 access on non-aligned boundaries. This
breaks the protocol handling code of course. I've put a work around in
for now, but really the protocol should be changed to be word aligned
because otherwise there'll be a significant hit on most RISC processors.

10. For (9) I had to add processor detection to the build system. One
step closer towards autoconf...

I've also attached the log files from the test that's failing on the
off-chance Ben knows exactly what the fix is, like last time.

Cheers,

Martin.
--=_2prwfsrdqaps
Content-Type: text/x-patch; charset="UTF-8"; name="bb-solaris.patch"
Content-Disposition: inline; filename="bb-solaris.patch"
Content-Transfer-Encoding: 7bit

diff -ur boxbackup-0.08PLUS2.orig/bin/bbackupd/BackupDaemon.cpp boxbackup-0.08PLUS2/bin/bbackupd/BackupDaemon.cpp
--- boxbackup-0.08PLUS2.orig/bin/bbackupd/BackupDaemon.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/bin/bbackupd/BackupDaemon.cpp	Tue Nov 23 09:44:02 2004
@@ -54,7 +54,12 @@
 #include <sys/mount.h>
 #include <signal.h>
 #ifdef PLATFORM_USES_MTAB_FILE_FOR_MOUNTS
-	#include <mntent.h>
+	#ifdef PLATFORM_SUNOS
+		#include <cstdio>
+		#include <sys/mnttab.h>
+	#else
+		#include <mntent.h>
+	#endif
 #endif
 #include <sys/wait.h>
 
@@ -992,21 +997,53 @@
 	int numIDMaps = 0;
 
 #ifdef PLATFORM_USES_MTAB_FILE_FOR_MOUNTS
-	// Linux can't tell you where a directory is mounted. So we have to
-	// read the mount entries from /etc/mtab! Bizarre that the OS itself
-	// can't tell you, but there you go.
+	// Linux and others can't tell you where a directory is mounted. So we
+	// have to read the mount entries from /etc/mtab! Bizarre that the OS
+	// itself can't tell you, but there you go.
 	std::set<std::string, mntLenCompare> mountPoints;
 	// BLOCK
 	FILE *mountPointsFile = 0;
+#ifdef PLATFORM_SUNOS
+	// Open mounts file
+	mountPointsFile = ::fopen("/etc/mnttab", "r");
+	if(mountPointsFile == 0)
+	{
+		THROW_EXCEPTION(CommonException, OSFileError);
+	}
+
 	try
 	{
+
+		// Read all the entries, and put them in the set
+		struct mnttab entry;
+		while(getmntent(mountPointsFile, &entry) == 0)
+		{
+			TRACE1("Found mount point at %s\n", entry.mnt_mountp);
+			mountPoints.insert(std::string(entry.mnt_mountp));
+		}
+
+		// Close mounts file
+		::fclose(mountPointsFile);
+	}
+	catch(...)
+	{
+		::fclose(mountPointsFile);
+		throw;
+	}
+#else
 		// Open mounts file
+	mountPointsFile = ::setmntent("/proc/mounts", "r");
+	if(mountPointsFile == 0)
+	{
 		mountPointsFile = ::setmntent("/etc/mtab", "r");
+	}
 		if(mountPointsFile == 0)
 		{
 			THROW_EXCEPTION(CommonException, OSFileError);
 		}
 		
+	try
+	{
 		// Read all the entries, and put them in the set
 		struct mntent *entry = 0;
 		while((entry = ::getmntent(mountPointsFile)) != 0)
@@ -1020,12 +1057,10 @@
 	}
 	catch(...)
 	{
-		if(mountPointsFile != 0)
-		{
 			::endmntent(mountPointsFile);
-		}
 		throw;
 	}
+#endif
 	// Check sorting and that things are as we expect
 	ASSERT(mountPoints.size() > 0);
 #ifndef NDEBUG
diff -ur boxbackup-0.08PLUS2.orig/infrastructure/BoxPlatform.pm boxbackup-0.08PLUS2/infrastructure/BoxPlatform.pm
--- boxbackup-0.08PLUS2.orig/infrastructure/BoxPlatform.pm	Thu Nov 18 14:47:08 2004
+++ boxbackup-0.08PLUS2/infrastructure/BoxPlatform.pm	Thu Nov 18 17:39:55 2004
@@ -40,7 +40,7 @@
 package BoxPlatform;
 use Exporter;
 @ISA = qw/Exporter/;
-@EXPORT = qw/$build_os $make_command $bsd_make $platform_define $gcc_v3 $product_version $product_name $install_into_dir $sub_make_options $platform_compile_line_extra $platform_link_line_extra/;
+@EXPORT = qw/$build_os $build_cpu $make_command $bsd_make $platform_define $platform_cpu $gcc_v3 $product_version $product_name $install_into_dir $sub_make_options $platform_compile_line_extra $platform_link_line_extra/;
 
 BEGIN
 {
@@ -48,13 +48,17 @@
 	# which OS are we building under?
 	$build_os = `uname`;
 	chomp $build_os;
+	$build_cpu = `uname -p`;
+	chomp $build_cpu;
 	# Cygwin Builds usually something like CYGWIN_NT-5.0, CYGWIN_NT-5.1
 	# Box Backup tried on Win2000,XP only :)
+	
     $build_os = 'CYGWIN' if $build_os =~ m/CYGWIN/;
 
-	$make_command = ($build_os ne 'Darwin')?'make':'bsdmake';
-	$bsd_make = ($build_os ne 'Linux' && $build_os ne 'CYGWIN');
+	$make_command = ($build_os eq 'Darwin') ? 'bsdmake' : ($build_os eq 'SunOS') ? 'gmake' : 'make';
+	$bsd_make = ($build_os ne 'Linux' && $build_os ne 'CYGWIN' && $build_os ne "SunOS");
     $platform_define = 'PLATFORM_'.uc($build_os);
+	$platform_cpu = 'PLATFORM_'.uc($build_cpu);
 
 	# blank extra flags by default
 	$platform_compile_line_extra = '';
@@ -98,6 +102,11 @@
 			$platform_compile_line_extra = '-I/sw/include ';
 			$platform_link_line_extra = '-L/sw/lib ';
 		}
+	}
+
+	if($build_os eq 'SunOS')
+	{
+		$platform_link_line_extra = '-lrt ';
 	}
 }
 
diff -ur boxbackup-0.08PLUS2.orig/infrastructure/makebuildenv.pl boxbackup-0.08PLUS2/infrastructure/makebuildenv.pl
--- boxbackup-0.08PLUS2.orig/infrastructure/makebuildenv.pl	Thu Nov 18 14:47:08 2004
+++ boxbackup-0.08PLUS2/infrastructure/makebuildenv.pl	Tue Nov 23 09:47:52 2004
@@ -784,13 +784,13 @@
 AR = ar
 RANLIB = ranlib
 .ifdef RELEASE
-CXXFLAGS = -DNDEBUG -O2 -Wall $include_paths -D$platform_define$extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
+CXXFLAGS = -DNDEBUG -O2 -Wall $include_paths -D$platform_define -D$platform_cpu$extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
 OUTBASE = ../../release
 OUTDIR = ../../release/$mod
 DEPENDMAKEFLAGS = -D RELEASE
 VARIENT = RELEASE
 .else
-CXXFLAGS = -g -Wall $include_paths -D$platform_define$extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
+CXXFLAGS = -g -Wall $include_paths -D$platform_define -D$platform_cpu$extra_platform_defines -DBOX_VERSION="\\"$product_version\\""
 OUTBASE = ../../debug
 OUTDIR = ../../debug/$mod
 DEPENDMAKEFLAGS =
@@ -912,7 +912,7 @@
 		# run make for things we require
 		for my $dep (@all_deps_for_module)
 		{
-			$deps_makeinfo .= "\t\t(cd ../../$dep; $make_command$sub_make_options \$(DEPENDMAKEFLAGS) -D NODEPS)\n";
+			$deps_makeinfo .= "\t\t(cd ../../$dep; \$(MAKE)$sub_make_options \$(DEPENDMAKEFLAGS) -D NODEPS)\n";
 		}
 		$deps_makeinfo .= ".\tendif\n.endif\n\n";
 	}
@@ -986,7 +986,7 @@
 	print MAKE "clean:\n\t-rm -rf \$(OUTDIR)/*\n.\tifndef SUBCLEAN\n";
 	for my $dep (@all_deps_for_module)
 	{
-		print MAKE "\t(cd ../../$dep; $make_command \$(DEPENDMAKEFLAGS) -D SUBCLEAN clean)\n";
+		print MAKE "\t(cd ../../$dep; \$(MAKE) \$(DEPENDMAKEFLAGS) -D SUBCLEAN clean)\n";
 	}
 	print MAKE ".\tendif\n";
 	
diff -ur boxbackup-0.08PLUS2.orig/infrastructure/makeparcels.pl boxbackup-0.08PLUS2/infrastructure/makeparcels.pl
--- boxbackup-0.08PLUS2.orig/infrastructure/makeparcels.pl	Thu Nov 18 14:47:08 2004
+++ boxbackup-0.08PLUS2/infrastructure/makeparcels.pl	Tue Nov 23 09:28:35 2004
@@ -138,7 +138,7 @@
 		if($type eq 'bin')
 		{
 			my $exeext = ($build_os eq 'CYGWIN')?'.exe':'';
-			print MAKE "\t(cd bin/$name; $make_command $release_flag)\n";
+			print MAKE "\t(cd bin/$name; \$(MAKE) $release_flag)\n";
 			print MAKE "\tcp release/bin/$name/$name$exeext $dir\n";
 		}
 		elsif ($type eq 'script')
@@ -183,7 +183,7 @@
 
 for(@parcels)
 {
-	print INSTALLMSG "    make install-".$_."\n";
+	print INSTALLMSG "    $make_command install-".$_."\n";
 }
 print INSTALLMSG "\n";
 
diff -ur boxbackup-0.08PLUS2.orig/lib/common/BoxPlatform.h boxbackup-0.08PLUS2/lib/common/BoxPlatform.h
--- boxbackup-0.08PLUS2.orig/lib/common/BoxPlatform.h	Thu Nov 18 14:47:07 2004
+++ boxbackup-0.08PLUS2/lib/common/BoxPlatform.h	Thu Nov 18 17:48:40 2004
@@ -169,7 +169,7 @@
 	#define PLATFORM_stat_SHORT_mtime
 	#define PLATFORM_stat_NO_st_flags
 	#define PLATFORM_USES_MTAB_FILE_FOR_MOUNTS
-	#define PLATFORM_open_NO_O_EXLOCK
+	#define PLATFORM_open_USE_flock
 	#define PLATFORM_sockaddr_NO_len
 
 	#define PLATFORM_RANDOM_DEVICE	"/dev/urandom"
@@ -181,6 +181,41 @@
 
 #endif // PLATFORM_LINUX
 
+#ifdef PLATFORM_SUNOS
+
+	#include <sys/types.h>
+
+	// for ntohl etc...
+	#include <netinet/in.h>
+
+	// types 'missing'
+	typedef uint8_t u_int8_t;
+//	typedef signed char int8_t;
+	typedef uint32_t u_int32_t;
+	typedef uint16_t u_int16_t;
+	typedef uint64_t u_int64_t;
+
+	// not defined in Solaris, a BSD thing
+	#define INFTIM -1
+
+	//#define LLONG_MAX    9223372036854775807LL
+	//#define LLONG_MIN    (-LLONG_MAX - 1LL)
+
+	#define PLATFORM_STATIC_TEMP_DIRECTORY_NAME	"/tmp"
+
+	#define PLATFORM_BERKELEY_DB_NOT_SUPPORTED
+	#define PLATFORM_KQUEUE_NOT_SUPPORTED       // This may be in Solaris 10
+	#define PLATFORM_dirent_BROKEN_d_type       // Well, no d_type at all actually
+	#define PLATFORM_stat_SHORT_mtime
+	#define PLATFORM_stat_NO_st_flags
+	#define PLATFORM_USES_MTAB_FILE_FOR_MOUNTS
+	#define PLATFORM_open_USE_fcntl
+	#define PLATFORM_sockaddr_NO_len
+
+	#define PLATFORM_RANDOM_DEVICE	"/dev/urandom"
+
+#endif // PLATFORM_SUNOS
+
 #ifdef PLATFORM_CYGWIN
 
 	#define PLATFORM_BERKELEY_DB_NOT_SUPPORTED
@@ -190,7 +225,7 @@
 	#define PLATFORM_stat_SHORT_mtime
 	#define PLATFORM_stat_NO_st_flags
 	#define PLATFORM_USES_MTAB_FILE_FOR_MOUNTS
-	#define PLATFORM_open_NO_O_EXLOCK
+	#define PLATFORM_open_USE_flock
 	#define PLATFORM_sockaddr_NO_len
 	#define PLATFORM_NO_BUILT_IN_SWAP64
 
@@ -226,6 +261,16 @@
 	#define PLATFORM_RANDOM_DEVICE_NONE
 
 #endif // PLATFORM_CYGWIN
+
+
+// Check the processor type
+#ifdef PLATFORM_SPARC
+	#define PLATFORM_ALIGN_INT
+#endif
+
+#ifdef PLATFORM_ARM
+	#define PLATFORM_ALIGN_INT
+#endif
 
 
 // Find out if credentials on UNIX sockets can be obtained
diff -ur boxbackup-0.08PLUS2.orig/lib/common/NamedLock.cpp boxbackup-0.08PLUS2/lib/common/NamedLock.cpp
--- boxbackup-0.08PLUS2.orig/lib/common/NamedLock.cpp	Thu Nov 18 14:47:07 2004
+++ boxbackup-0.08PLUS2/lib/common/NamedLock.cpp	Thu Nov 18 17:39:55 2004
@@ -51,12 +51,9 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
-#ifdef PLATFORM_LINUX
+#ifdef PLATFORM_open_USE_flock
 	#include <sys/file.h>
-#endif // PLATFORM_LINUX
-#ifdef PLATFORM_CYGWIN
-	#include <sys/file.h>
-#endif // PLATFORM_CYGWIN
+#endif // PLATFORM_open_USE_flock
 
 #include "NamedLock.h"
 #include "CommonException.h"
@@ -110,12 +107,14 @@
 	}
 
 	// See if the lock can be got
-#ifdef PLATFORM_open_NO_O_EXLOCK
+#if defined(PLATFORM_open_USE_flock) || defined(PLATFORM_open_USE_fcntl)
 	int fd = ::open(Filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
 	if(fd == -1)
 	{
 		THROW_EXCEPTION(CommonException, OSFileError)
 	}
+
+#ifdef PLATFORM_open_USE_flock
 	if(::flock(fd, LOCK_EX | LOCK_NB) != 0)
 	{
 		::close(fd);
@@ -128,6 +127,25 @@
 			THROW_EXCEPTION(CommonException, OSFileError)
 		}
 	}
+#else
+	struct flock desc;
+	desc.l_type = F_WRLCK;
+	desc.l_whence = SEEK_SET;
+	desc.l_start = 0;
+	desc.l_len = 0;
+	if(::fcntl(fd, F_SETLK, &desc) != 0)
+	{
+		::close(fd);
+		if(errno == EAGAIN)
+		{
+			return false;
+		}
+		else
+		{
+			THROW_EXCEPTION(CommonException, OSFileError)
+		}
+	}
+#endif
 
 	// Success
 	mFileDescriptor = fd;
diff -ur boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileRead.cpp boxbackup-0.08PLUS2/lib/raidfile/RaidFileRead.cpp
--- boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileRead.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/lib/raidfile/RaidFileRead.cpp	Thu Nov 18 17:39:55 2004
@@ -356,11 +356,7 @@
 	  mEOF(false)
 {
 	// Make sure size of the IOStream::pos_type matches the pos_type used
-#ifdef PLATFORM_LINUX
 	ASSERT(sizeof(pos_type) >= sizeof(off_t));
-#else
-	ASSERT(sizeof(pos_type) == sizeof(off_t));
-#endif
 	
 	// Sanity check handles
 	if(mStripe1Handle != -1 && mStripe2Handle != -1)
@@ -1585,18 +1581,22 @@
 					continue;
 				}
 				
+				// Entry...
+				std::string name;
+				unsigned int countToAdd = 1;
+
 				// stat the file to find out what type it is
-/*				struct stat st;
+#ifdef PLATFORM_SUNOS
+				struct stat st;
 				std::string fullName(dn + DIRECTORY_SEPARATOR + en->d_name);
-				if(::stat(fullName.c_str(), &st) != 0)
+				if(::lstat(fullName.c_str(), &st) != 0)
 				{
 					THROW_EXCEPTION(RaidFileException, OSError)
-				}*/
-				
-				// Entry...
-				std::string name;
-				unsigned int countToAdd = 1;
-				if(DirReadType == DirReadType_FilesOnly && en->d_type == DT_REG) // (st.st_mode & S_IFDIR) == 0)
+				}
+				if(DirReadType == DirReadType_FilesOnly && (st.st_mode & S_IFDIR) == 0)
+#else
+				if(DirReadType == DirReadType_FilesOnly && en->d_type == DT_REG)
+#endif
 				{
 					// File. Complex, need to check the extension
 					int dot = -1;
@@ -1624,7 +1624,11 @@
 						}
 					}
 				}
-				if(DirReadType == DirReadType_DirsOnly && en->d_type == DT_DIR) // (st.st_mode & S_IFDIR))
+#ifdef PLATFORM_SUNOS
+				if(DirReadType == DirReadType_DirsOnly && (st.st_mode & S_IFDIR))
+#else
+				if(DirReadType == DirReadType_DirsOnly && en->d_type == DT_DIR)
+#endif
 				{
 					// Directory, and we want directories
 					name = en->d_name;
diff -ur boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileUtil.cpp boxbackup-0.08PLUS2/lib/raidfile/RaidFileUtil.cpp
--- boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileUtil.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/lib/raidfile/RaidFileUtil.cpp	Thu Nov 18 17:39:55 2004
@@ -93,7 +93,7 @@
 			if(pRevisionID != 0)
 			{
 				(*pRevisionID) = FileModificationTime(st);
-#ifdef PLATFORM_LINUX
+#ifdef PLATFORM_stat_SHORT_mtime
 				// On linux, the time resolution is very low for modification times.
 				// So add the size to it to give a bit more chance of it changing.
 				// TODO: Make this better.
@@ -110,7 +110,7 @@
 	int64_t revisionID = 0;
 	int setSize = rDiscSet.size();
 	int rfCount = 0;
-#ifdef PLATFORM_LINUX
+#ifdef PLATFORM_stat_SHORT_mtime
 	// TODO: replace this with better linux revision ID detection
 	int64_t revisionIDplus = 0;
 #endif
@@ -131,7 +131,7 @@
 			{
 				int64_t rid = FileModificationTime(st);
 				if(rid > revisionID) revisionID = rid;
-#ifdef PLATFORM_LINUX
+#ifdef PLATFORM_stat_SHORT_mtime
 				revisionIDplus += st.st_size;
 #endif
 			}
@@ -140,7 +140,7 @@
 	if(pRevisionID != 0)
 	{
 		(*pRevisionID) = revisionID;
-#ifdef PLATFORM_LINUX
+#ifdef PLATFORM_stat_SHORT_mtime
 		(*pRevisionID) += revisionIDplus;
 #endif
 	}
diff -ur boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileWrite.cpp boxbackup-0.08PLUS2/lib/raidfile/RaidFileWrite.cpp
--- boxbackup-0.08PLUS2.orig/lib/raidfile/RaidFileWrite.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/lib/raidfile/RaidFileWrite.cpp	Tue Nov 23 10:18:19 2004
@@ -151,10 +151,21 @@
 	}
 	
 	// Get a lock on the write file
+#ifdef PLATFORM_open_USE_fcntl
+	int errnoBlock = EAGAIN;
+	struct flock desc;
+	desc.l_type = F_WRLCK;
+	desc.l_whence = SEEK_SET;
+	desc.l_start = 0;
+	desc.l_len = 0;
+	if(::fcntl(mOSFileHandle, F_SETLK, &desc) != 0)
+#else
+	int errnoBlock = EWOULDBLOCK;
 	if(::flock(mOSFileHandle, LOCK_EX | LOCK_NB) != 0)
+#endif
 	{
 		// Lock was not obtained.
-		bool wasLocked = (errno == EWOULDBLOCK);
+		bool wasLocked = (errno == errnoBlock);
 		// Close the file
 		::close(mOSFileHandle);
 		mOSFileHandle = -1;
@@ -415,7 +426,7 @@
 	// Then open them all for writing (in strict order)
 	try
 	{
-#ifdef PLATFORM_LINUX
+#if defined(PLATFORM_open_USE_flock) || defined(PLATFORM_open_USE_fcntl)
 		FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> stripe1(stripe1FilenameW.c_str());
 		FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> stripe2(stripe2FilenameW.c_str());
 		FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> parity(parityFilenameW.c_str());
@@ -487,11 +498,7 @@
 					{
 						// XOR in the size at the end of the parity block
 						ASSERT(sizeof(RaidFileRead::FileSizeType) == (2*sizeof(unsigned int)));
-#ifdef PLATFORM_LINUX
 						ASSERT(sizeof(RaidFileRead::FileSizeType) >= sizeof(off_t));
-#else
-						ASSERT(sizeof(RaidFileRead::FileSizeType) == sizeof(off_t));
-#endif
 						int sizePos = (blockSize/sizeof(unsigned int)) - 2;
 						RaidFileRead::FileSizeType sw = hton64(writeFileStat.st_size);
 						unsigned int *psize = (unsigned int *)(&sw);
@@ -548,11 +555,7 @@
 		// if it can't be worked out some other means -- size is required to rebuild the file if one of the stripe files is missing
 		if(sizeRecordRequired)
 		{
-#ifdef PLATFORM_LINUX
 			ASSERT(sizeof(writeFileStat.st_size) <= sizeof(RaidFileRead::FileSizeType));
-#else
-			ASSERT(sizeof(writeFileStat.st_size) == sizeof(RaidFileRead::FileSizeType));
-#endif
 			RaidFileRead::FileSizeType sw = hton64(writeFileStat.st_size);
 			ASSERT((::lseek(parity, 0, SEEK_CUR) % blockSize) == 0);
 			if(::write(parity, &sw, sizeof(sw)) != sizeof(sw))
diff -ur boxbackup-0.08PLUS2.orig/lib/server/Daemon.cpp boxbackup-0.08PLUS2/lib/server/Daemon.cpp
--- boxbackup-0.08PLUS2.orig/lib/server/Daemon.cpp	Thu Nov 18 14:47:07 2004
+++ boxbackup-0.08PLUS2/lib/server/Daemon.cpp	Thu Nov 18 17:39:55 2004
@@ -180,7 +180,11 @@
 		SetupInInitialProcess();
 		
 		// Set signal handler
-		if(::signal(SIGHUP, SignalHandler) == SIG_ERR || ::signal(SIGTERM, SignalHandler) == SIG_ERR)
+		struct sigaction sa;
+		sa.sa_handler = SignalHandler;
+		sa.sa_flags = 0;
+		::sigemptyset(&sa.sa_mask);
+		if(::sigaction(SIGHUP, &sa, NULL) != 0 || ::sigaction(SIGTERM, &sa, NULL) != 0)
 		{
 			THROW_EXCEPTION(ServerException, DaemoniseFailed)
 		}
@@ -393,8 +397,12 @@
 void Daemon::EnterChild()
 {
 	// Unset signal handlers
-	::signal(SIGHUP, SIG_DFL);
-	::signal(SIGTERM, SIG_DFL);
+	struct sigaction sa;
+	sa.sa_handler = SIG_DFL;
+	sa.sa_flags = 0;
+	::sigemptyset(&sa.sa_mask);
+	::sigaction(SIGHUP, &sa, NULL);
+	::sigaction(SIGTERM, &sa, NULL);
 }
 
 
diff -ur boxbackup-0.08PLUS2.orig/lib/server/Protocol.cpp boxbackup-0.08PLUS2/lib/server/Protocol.cpp
--- boxbackup-0.08PLUS2.orig/lib/server/Protocol.cpp	Thu Nov 18 14:47:07 2004
+++ boxbackup-0.08PLUS2/lib/server/Protocol.cpp	Thu Nov 18 17:39:55 2004
@@ -462,7 +462,14 @@
 	READ_START_CHECK
 	READ_CHECK_BYTES_AVAILABLE(sizeof(int64_t))
 	
-	rOut = ntoh64(*((int64_t*)(mpBuffer + mReadOffset)));
+#ifdef PLATFORM_ALIGN_INT
+	int64_t nvalue;
+	memcpy(&nvalue, mpBuffer + mReadOffset, sizeof(int64_t));
+#else
+	int64_t nvalue = *((int64_t*)(mpBuffer + mReadOffset));
+#endif
+	rOut = ntoh64(nvalue);
+
 	mReadOffset += sizeof(int64_t);
 }
 
@@ -479,7 +486,13 @@
 	READ_START_CHECK
 	READ_CHECK_BYTES_AVAILABLE(sizeof(int32_t))
 	
-	rOut = ntohl(*((int32_t*)(mpBuffer + mReadOffset)));
+#ifdef PLATFORM_ALIGN_INT
+	int32_t nvalue;
+	memcpy(&nvalue, mpBuffer + mReadOffset, sizeof(int32_t));
+#else
+	int32_t nvalue = *((int32_t*)(mpBuffer + mReadOffset));
+#endif
+	rOut = ntohl(nvalue);
 	mReadOffset += sizeof(int32_t);
 }
 
@@ -584,7 +597,12 @@
 	WRITE_START_CHECK
 	WRITE_ENSURE_BYTES_AVAILABLE(sizeof(int64_t))
 
-	*((int64_t*)(mpBuffer + mWriteOffset)) = hton64(Value);
+	int64_t nvalue = hton64(Value);
+#ifdef PLATFORM_ALIGN_INT
+	memcpy(mpBuffer + mWriteOffset, &nvalue, sizeof(int64_t));
+#else
+	*((int64_t*)(mpBuffer + mWriteOffset)) = nvalue;
+#endif
 	mWriteOffset += sizeof(int64_t);
 }
 
@@ -602,7 +620,12 @@
 	WRITE_START_CHECK
 	WRITE_ENSURE_BYTES_AVAILABLE(sizeof(int32_t))
 
-	*((int32_t*)(mpBuffer + mWriteOffset)) = htonl(Value);
+	int32_t nvalue = htonl(Value);
+#ifdef PLATFORM_ALIGN_INT
+	memcpy(mpBuffer + mWriteOffset, &nvalue, sizeof(int32_t));
+#else
+	*((int32_t*)(mpBuffer + mWriteOffset)) = nvalue;
+#endif
 	mWriteOffset += sizeof(int32_t);
 }
 
diff -ur boxbackup-0.08PLUS2.orig/lib/server/SocketStreamTLS.cpp boxbackup-0.08PLUS2/lib/server/SocketStreamTLS.cpp
--- boxbackup-0.08PLUS2.orig/lib/server/SocketStreamTLS.cpp	Thu Nov 18 14:47:07 2004
+++ boxbackup-0.08PLUS2/lib/server/SocketStreamTLS.cpp	Tue Nov 23 10:19:52 2004
@@ -53,7 +53,7 @@
 #include <openssl/bio.h>
 #include <poll.h>
 #include <errno.h>
-#include <sys/ioctl.h>
+#include <fcntl.h>
 
 #include "SocketStreamTLS.h"
 #include "SSLLib.h"
@@ -171,12 +171,23 @@
 	}
 
 	// Make the socket non-blocking so timeouts on Read work
-	int nonblocking = true;
-	if(::ioctl(socket, FIONBIO, &nonblocking) == -1)
+	// This is more portable than using ioctl with FIONBIO
+	int statusFlags = 0;
+	if(::fcntl(socket, F_GETFL, &statusFlags) < 0
+	   || ::fcntl(socket, F_SETFL, statusFlags | O_NONBLOCK) == -1)
 	{
 		THROW_EXCEPTION(ServerException, SocketSetNonBlockingFailed)
 	}
 	
+	// FIXME: This is less portable than the above. However, it MAY be needed
+	// for cygwin, which has/had bugs with fcntl
+	//
+	// int nonblocking = true;
+	// if(::ioctl(socket, FIONBIO, &nonblocking) == -1)
+	// {
+	// 	THROW_EXCEPTION(ServerException, SocketSetNonBlockingFailed)
+	// }
+
 	// Set the two to know about each other
 	::SSL_set_bio(mpSSL, mpBIO, mpBIO);
 
diff -ur boxbackup-0.08PLUS2.orig/test/backupstore/testbackupstore.cpp boxbackup-0.08PLUS2/test/backupstore/testbackupstore.cpp
--- boxbackup-0.08PLUS2.orig/test/backupstore/testbackupstore.cpp	Thu Nov 18 14:47:10 2004
+++ boxbackup-0.08PLUS2/test/backupstore/testbackupstore.cpp	Thu Nov 18 17:39:55 2004
@@ -623,9 +623,9 @@
 	int objectsNotDel;
 	int deleted;
 	int old;
-} recusive_count_objects_results;
+} recursive_count_objects_results;
 
-void recusive_count_objects_r(BackupProtocolClient &protocol, int64_t id, recusive_count_objects_results &results)
+void recursive_count_objects_r(BackupProtocolClient &protocol, int64_t id, recursive_count_objects_results &results)
 {
 	// Command
 	std::auto_ptr<BackupProtocolClientSuccess> dirreply(protocol.QueryListDirectory(
@@ -650,12 +650,12 @@
 		
 		if(en->GetFlags() & BackupStoreDirectory::Entry::Flags_Dir)
 		{
-			recusive_count_objects_r(protocol, en->GetObjectID(), results);
+			recursive_count_objects_r(protocol, en->GetObjectID(), results);
 		}
 	}
 }
 
-void recusive_count_objects(const char *hostname, int64_t id, recusive_count_objects_results &results)
+void recursive_count_objects(const char *hostname, int64_t id, recursive_count_objects_results &results)
 {
 	// Context
 	TLSContext context;
@@ -676,7 +676,7 @@
 	}
 	
 	// Count objects
-	recusive_count_objects_r(protocolReadOnly, id, results);
+	recursive_count_objects_r(protocolReadOnly, id, results);
 
 	// Close it
 	protocolReadOnly.QueryFinished();
@@ -1745,9 +1745,9 @@
 		
 		// Test the deletion of objects by the housekeeping system
 		// First, things as they are now.
-		recusive_count_objects_results before = {0,0,0};
+		recursive_count_objects_results before = {0,0,0};
 
-		recusive_count_objects("localhost", BackupProtocolClientListDirectory::RootDirectory, before);
+		recursive_count_objects("localhost", BackupProtocolClientListDirectory::RootDirectory, before);
 		
 		TEST_THAT(before.objectsNotDel != 0);
 		TEST_THAT(before.deleted != 0);
@@ -1780,8 +1780,9 @@
 		printf("\n");
 
 		// Count the objects again
-		recusive_count_objects_results after = {0,0,0};
-		recusive_count_objects("localhost", BackupProtocolClientListDirectory::RootDirectory, after);
+		recursive_count_objects_results after = {0,0,0};
+		recursive_count_objects("localhost", BackupProtocolClientListDirectory::RootDirectory, after);
+printf("after.objectsNotDel=%i, deleted=%i, old=%i\n",after.objectsNotDel, after.deleted, after.old);
 		
 		TEST_THAT(after.objectsNotDel == before.objectsNotDel);
 		TEST_THAT(after.deleted == 0);
diff -ur boxbackup-0.08PLUS2.orig/test/common/testcommon.cpp boxbackup-0.08PLUS2/test/common/testcommon.cpp
--- boxbackup-0.08PLUS2.orig/test/common/testcommon.cpp	Thu Nov 18 14:47:08 2004
+++ boxbackup-0.08PLUS2/test/common/testcommon.cpp	Thu Nov 18 17:39:55 2004
@@ -436,9 +436,11 @@
 		TEST_THAT(lock1.TryAndGetLock("testfiles/lock1") == true);
 		// Try to lock something using the same lock
 		TEST_CHECK_THROWS(lock1.TryAndGetLock("testfiles/non-exist/lock2"), CommonException, NamedLockAlreadyLockingSomething);		
+#ifndef PLATFORM_open_USE_fcntl
 		// And again on that name
 		NamedLock lock2;
 		TEST_THAT(lock2.TryAndGetLock("testfiles/lock1") == false);
+#endif
 	}
 	{
 		// Check that it unlocked when it went out of scope
diff -ur boxbackup-0.08PLUS2.orig/test/raidfile/intercept.cpp boxbackup-0.08PLUS2/test/raidfile/intercept.cpp
--- boxbackup-0.08PLUS2.orig/test/raidfile/intercept.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/test/raidfile/intercept.cpp	Thu Nov 18 17:39:55 2004
@@ -73,7 +73,7 @@
 	extern "C" off_t
 	TEST_lseek(int fildes, off_t offset, int whence);
 #else
-	#ifdef PLATFORM_LINUX
+	#if defined(PLATFORM_LINUX) || defined(PLATFORM_SUNOS)
 		#undef __syscall
 		#define __syscall syscall
 	#else
@@ -90,7 +90,7 @@
 bool intercept_enabled = false;
 const char *intercept_filename = 0;
 int intercept_filedes = -1;
-unsigned int intercept_errorafter = 0;
+off_t intercept_errorafter = 0;
 int intercept_errno = 0;
 int intercept_syscall = 0;
 off_t intercept_filepos = 0;
@@ -136,7 +136,7 @@
 			return true;
 		}
 		// where are we in the file?
-		if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((int)intercept_errorafter - size))
+		if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((off_t)intercept_errorafter - size))
 		{
 			TRACE3("Returning error %d for syscall %d, file pos %d\n", intercept_errno, syscallnum, (int)intercept_filepos);
 			return true;
@@ -275,9 +275,11 @@
 #ifdef PLATFORM_DARWIN
 	int r = TEST_lseek(fildes, offset, whence);
 #else
-	#ifdef PLATFORM_LINUX
+	#if defined(PLATFORM_LINUX) || defined(PLATFORM_SUNOS)
 		off_t r = __syscall(SYS_lseek, fildes, offset, whence);
 	#else
+		// Should swap this condition round. No reason to assume that most OS
+		// do this syscall wierdness, default should be the sensible way
 		off_t r = __syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence);
 	#endif
 #endif
diff -ur boxbackup-0.08PLUS2.orig/test/raidfile/testraidfile.cpp boxbackup-0.08PLUS2/test/raidfile/testraidfile.cpp
--- boxbackup-0.08PLUS2.orig/test/raidfile/testraidfile.cpp	Thu Nov 18 14:47:09 2004
+++ boxbackup-0.08PLUS2/test/raidfile/testraidfile.cpp	Thu Nov 18 17:39:55 2004
@@ -564,8 +564,10 @@
 		writeA.Write("TESTTEST", 8);
 	
 		{
+#ifndef PLATFORM_open_USE_fcntl
 			RaidFileWrite writeA2(0, "overwrite_A");
 			TEST_CHECK_THROWS(writeA2.Open(), RaidFileException, FileIsCurrentlyOpenForWriting);
+#endif
 		}
 	}
 	

--=_2prwfsrdqaps
Content-Type: application/x-gzip; name="backupstore.log.gz"
Content-Disposition: attachment; filename="backupstore.log.gz"
Content-Transfer-Encoding: base64

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
fPApAAA=

--=_2prwfsrdqaps
Content-Type: application/x-gzip; name="protocol.log.gz"
Content-Disposition: attachment; filename="protocol.log.gz"
Content-Transfer-Encoding: base64

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
nAMBAA==

--=_2prwfsrdqaps
Content-Type: application/x-gzip; name="protocolReadOnly.log.gz"
Content-Disposition: attachment; filename="protocolReadOnly.log.gz"
Content-Transfer-Encoding: base64

H4sICMsbo0EAA3Byb3RvY29sUmVhZE9ubHkubG9nALVawWobMRC99yt8TCGHHWklrc4tPfXUQO/S
SkoXEhu8Tmn79V2HliSlMm8eOGCS2OJJvHkzI8/bu7ovu6/1uC6H/c3wQ96/+1Lnunyvb9+8Oy/7
fLhfnv83dnQ+3L5Z/vzhh8O+LcfHWrZVU7DGGZvy9tqWmvMryLD9GqsZ/kIu6+njcqzz6XD8eYbe
Pm5/frY/h9uWHtb6ssvd0zzXdX190mV/v1tPx5oeb3fr8qvuxuF62GL9dEX0ceqhm3/hT8en/6Ob
PvwQPArfP30fP15CPwe+Uae25prxvC4lZrggF8+euku0x8/su+h2GDvwAYcPBPyEw08EfMThIwGf
cPhEwGccPhPwMw4/69VuBhj+3BrU8LgwDSFMgwvT9IXZPz3OvSG4t3hRsERRsDj3luDe4txbgnuL
c28J7kcLw49WT8444vAjcXqc+5Hg3jkY3jk9OQ7XvSN073DdO0L3DufeMdzjuneE7j2ue0/o3uO6
94TuPc69J7gP+M0y9G+WXXICzn0guA8494HgPuDcB4b7hsM3PTkTfs+ZiHvOhHM/EdxHHD724bvk
RLzeR6LeR7zeR6LeR7zeR6LeR1z3kdB9xOt9JOp9wmtOImpOwoWZCN0nnPtEcJ/xep+Jep9x7jPB
fca5zwT3Gec+M9zj9T4T9X7G6/1M1PsZ534muC/4BK30h1Fdcgqu+0LovuC6L4TuC859YbjHdV8I
3Rdc94XQfcV1XwndV5z7SnBfKw5fCXJw7ivBfcO5bwT3Dee+Edw3fI7ZiDlmw+85jbjnyICTv60l
NhC8qm1riUGv4PHd1jIb4Nf8bS2zgcLloGwOjc9BGR0ap+OC1XFBRYpxPjPPF6OQqWFkahQyNUQd
EsVQX5ipvliFgWiJ+49YRQwsEwOriIFlYqAY7gsz3ReLt+JtLUHRqOgHI9MPFCN+YWb84hQ2uiO+
BYhT5IFj8sAp8sAxeeAUMXBUDBR5wEz7xSnywDF54BV54Jk8UIz8hZn5i8e/FGxrGYoUMfBMDIIi
BoGJgWL0L8zsX4LiIYfAPOUQFPeiwNyLFAaAMA6ARMUGsb/BhadkFP0gMv0gKvpBZPpBVPSDyPQD
hU8iF4ySC0FW9APGDZCoqEWRqUVJIdPE5IHCEhDGE5Ck6AeJ6QdJEYPExCArYpCZGCisAWG8Acma
h96YfpAV/SAz/UBhEAjjEMhcFBsUgqJZkQczkwezIg9mJg+KIgaFiYHCKhDGK5CiyIPC5EFR5EFh
8kBhGAjjGEhVPH5bmedvqyIGlYlBVcSgMjFQGAfCOAfSFHPTxsxNm+Je1Jh7UVPEAPEPPi37Zf1W
y80Lwqu3fgNaYYXTfDMAAA==

--=_2prwfsrdqaps--