summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-28 01:14:48 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-28 01:14:48 +0200
commit30f0736d2135659658153e7b62d92e5b28548991 (patch)
treee2cd46c25f343b1c816ea8fb14e938245ef1d740
parent99045ebf0b442a8f4be9e6944ba71abf8786ac87 (diff)
parent7b4540ae3c9ac331eed17fdf15a33f64b103cb4d (diff)
New upstream release.
-rw-r--r--.svnrevision2
-rw-r--r--bin/bbackupd/BackupClientContext.cpp2
-rw-r--r--bin/bbackupd/BackupClientContext.h4
-rw-r--r--bin/bbackupd/BackupClientDirectoryRecord.cpp12
-rw-r--r--bin/bbackupd/BackupDaemon.cpp11
-rw-r--r--bin/bbackupquery/BackupQueries.cpp49
-rw-r--r--bin/bbstored/BackupCommands.cpp11
-rw-r--r--bin/bbstored/BackupStoreContext.cpp22
-rwxr-xr-xbin/bbstored/bbstored-certs.in4
-rw-r--r--configure.ac4
-rw-r--r--debian/changelog6
-rw-r--r--distribution/boxbackup/VERSION.txt2
-rw-r--r--docs/api-notes/win32_build_on_cygwin_using_mingw.txt28
-rwxr-xr-xinfrastructure/makebuildenv.pl.in6
-rwxr-xr-xinfrastructure/makeparcels.pl.in12
-rwxr-xr-xinfrastructure/mingw/configure.sh10
-rw-r--r--lib/backupclient/BackupClientFileAttributes.cpp7
-rw-r--r--lib/backupclient/BackupClientRestore.cpp29
-rw-r--r--lib/backupclient/BackupClientRestore.h1
-rw-r--r--lib/backupclient/BackupDaemonConfigVerify.cpp2
-rw-r--r--lib/backupclient/BackupStoreFile.cpp10
-rw-r--r--lib/common/BufferedStream.cpp2
-rw-r--r--lib/common/BufferedStream.h2
-rw-r--r--lib/common/BufferedWriteStream.cpp181
-rw-r--r--lib/common/BufferedWriteStream.h44
-rw-r--r--lib/common/Configuration.cpp48
-rw-r--r--lib/common/Configuration.h6
-rw-r--r--lib/common/Logging.h5
-rw-r--r--lib/httpserver/HTTPRequest.h3
-rw-r--r--lib/raidfile/RaidFileWrite.cpp2
-rw-r--r--lib/server/Daemon.cpp4
-rw-r--r--lib/win32/emu.cpp4
-rw-r--r--parcels.txt2
-rw-r--r--test/bbackupd/testbbackupd.cpp19
34 files changed, 458 insertions, 98 deletions
diff --git a/.svnrevision b/.svnrevision
index 091d5b0a..f1293228 100644
--- a/.svnrevision
+++ b/.svnrevision
@@ -1 +1 @@
-2714
+2837
diff --git a/bin/bbackupd/BackupClientContext.cpp b/bin/bbackupd/BackupClientContext.cpp
index b978f54c..6b51b9e8 100644
--- a/bin/bbackupd/BackupClientContext.cpp
+++ b/bin/bbackupd/BackupClientContext.cpp
@@ -45,7 +45,7 @@ BackupClientContext::BackupClientContext
TLSContext &rTLSContext,
const std::string &rHostname,
int Port,
- int32_t AccountNumber,
+ uint32_t AccountNumber,
bool ExtendedLogging,
bool ExtendedLogToFile,
std::string ExtendedLogFile,
diff --git a/bin/bbackupd/BackupClientContext.h b/bin/bbackupd/BackupClientContext.h
index 4665df2b..404d2d77 100644
--- a/bin/bbackupd/BackupClientContext.h
+++ b/bin/bbackupd/BackupClientContext.h
@@ -45,7 +45,7 @@ public:
TLSContext &rTLSContext,
const std::string &rHostname,
int32_t Port,
- int32_t AccountNumber,
+ uint32_t AccountNumber,
bool ExtendedLogging,
bool ExtendedLogToFile,
std::string ExtendedLogFile,
@@ -213,7 +213,7 @@ private:
TLSContext &mrTLSContext;
std::string mHostname;
int mPort;
- int32_t mAccountNumber;
+ uint32_t mAccountNumber;
SocketStreamTLS *mpSocket;
BackupProtocolClient *mpConnection;
bool mExtendedLogging;
diff --git a/bin/bbackupd/BackupClientDirectoryRecord.cpp b/bin/bbackupd/BackupClientDirectoryRecord.cpp
index e03d53c2..84c17dab 100644
--- a/bin/bbackupd/BackupClientDirectoryRecord.cpp
+++ b/bin/bbackupd/BackupClientDirectoryRecord.cpp
@@ -364,14 +364,14 @@ void BackupClientDirectoryRecord::SyncDirectory(
// Store on list
dirs.push_back(std::string(en->d_name));
}
- else if (type == S_IFSOCK || type == S_IFIFO)
- {
- // removed notification for these types
- // see Debian bug 479145, no objections
- }
else
{
- if(rParams.mrContext.ExcludeFile(filename))
+ if (type == S_IFSOCK || type == S_IFIFO)
+ {
+ // removed notification for these types
+ // see Debian bug 479145, no objections
+ }
+ else if(rParams.mrContext.ExcludeFile(filename))
{
rNotifier.NotifyFileExcluded(
this,
diff --git a/bin/bbackupd/BackupDaemon.cpp b/bin/bbackupd/BackupDaemon.cpp
index 5134d234..b6f90cad 100644
--- a/bin/bbackupd/BackupDaemon.cpp
+++ b/bin/bbackupd/BackupDaemon.cpp
@@ -743,7 +743,7 @@ void BackupDaemon::RunSyncNow()
mTlsContext,
conf.GetKeyValue("StoreHostname"),
conf.GetKeyValueInt("StorePort"),
- conf.GetKeyValueInt("AccountNumber"),
+ conf.GetKeyValueUint32("AccountNumber"),
conf.GetKeyValueBool("ExtendedLogging"),
conf.KeyExists("ExtendedLogFile"),
extendedLogFile, *mpProgressNotifier
@@ -1731,7 +1731,14 @@ void BackupDaemon::SetupLocations(BackupClientContext &rClientContext, const Con
}
// Any entries in the root directory which need deleting?
- if(dir.GetNumberOfEntries() > 0)
+ if(dir.GetNumberOfEntries() > 0 &&
+ mDeleteRedundantLocationsAfter == 0)
+ {
+ BOX_NOTICE(dir.GetNumberOfEntries() << " redundant locations "
+ "in root directory found, but will not delete because "
+ "DeleteRedundantLocationsAfter = 0");
+ }
+ else if(dir.GetNumberOfEntries() > 0)
{
box_time_t now = GetCurrentBoxTime();
diff --git a/bin/bbackupquery/BackupQueries.cpp b/bin/bbackupquery/BackupQueries.cpp
index f799ab43..60724800 100644
--- a/bin/bbackupquery/BackupQueries.cpp
+++ b/bin/bbackupquery/BackupQueries.cpp
@@ -223,8 +223,8 @@ void BackupQueries::DoCommand(const char *Command, bool isFromCommandLine)
{ "restore", "drif" },
{ "help", "" },
{ "usage", "m" },
- { "undelete", "" },
- { "delete", "" },
+ { "undelete", "i" },
+ { "delete", "i" },
{ NULL, NULL }
};
@@ -324,8 +324,9 @@ void BackupQueries::DoCommand(const char *Command, bool isFromCommandLine)
case Command_pwd:
{
// Simple implementation, so do it here
- BOX_INFO(GetCurrentDirectoryName() << " (" <<
- BOX_FORMAT_OBJECTID(GetCurrentDirectoryID()));
+ BOX_NOTICE(GetCurrentDirectoryName() << " (" <<
+ BOX_FORMAT_OBJECTID(GetCurrentDirectoryID()) <<
+ ")");
}
break;
@@ -1008,8 +1009,7 @@ void BackupQueries::CommandGetObject(const std::vector<std::string> &args, const
// object ID, depending on opts['i'], where name can
// include a path) and return the file ID, placing the
// directory ID in *pDirIdOut and the filename part
-// of the path (if not looking up by ID and not NULL)
-// in *pFileNameOut.
+// of the path in *pFileNameOut (if not NULL).
// Created: 2008-09-12
//
// --------------------------------------------------------------------------
@@ -1039,11 +1039,6 @@ int64_t BackupQueries::FindFileID(const std::string& rNameOrIdString,
return 0;
}
}
-
- if(pFileNameOut)
- {
- *pFileNameOut = fileName;
- }
}
BackupStoreFilenameClear fn(fileName);
@@ -1106,6 +1101,12 @@ int64_t BackupQueries::FindFileID(const std::string& rNameOrIdString,
*pFlagsOut = en->GetFlags();
}
+ if(pFileNameOut)
+ {
+ BackupStoreFilenameClear entryName(en->GetName());
+ *pFileNameOut = entryName.GetClearFilename();
+ }
+
return fileId;
}
@@ -1862,7 +1863,7 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir,
for(std::set<std::pair<std::string, BackupStoreDirectory::Entry *> >::const_iterator i = storeDirs.begin(); i != storeDirs.end(); ++i)
{
std::string localPath(MakeFullPath(rLocalDir, i->first));
- std::string storePath(rLocalDir + "/" + i->first);
+ std::string storePath(rStoreDir + "/" + i->first);
// Does the directory exist locally?
string_set_iter_t local(localDirs.find(i->first));
@@ -1875,8 +1876,8 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir,
else if(local == localDirs.end())
{
// Not found -- report
- rParams.NotifyRemoteFileMissing(localPath,
- storePath, false);
+ rParams.NotifyLocalFileMissing(localPath,
+ storePath);
}
else if(rParams.IsExcludedDir(localPath))
{
@@ -1886,8 +1887,7 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir,
{
// Compare directory
Compare(i->second->GetObjectID(),
- rStoreDir + "/" + i->first,
- localPath, rParams);
+ storePath, localPath, rParams);
// Remove from set so that we know it's been compared
localDirs.erase(local);
@@ -1956,6 +1956,8 @@ void BackupQueries::CommandRestore(const std::vector<std::string> &args, const b
// Restoring deleted things?
bool restoreDeleted = opts['d'];
+ std::string storeDirEncoded;
+
// Get directory ID
int64_t dirID = 0;
if(opts['i'])
@@ -1967,15 +1969,17 @@ void BackupQueries::CommandRestore(const std::vector<std::string> &args, const b
BOX_ERROR("Not a valid object ID (specified in hex)");
return;
}
+ std::ostringstream oss;
+ oss << BOX_FORMAT_OBJECTID(args[0]);
+ storeDirEncoded = oss.str();
}
else
{
#ifdef WIN32
- std::string storeDirEncoded;
if(!ConvertConsoleToUtf8(args[0].c_str(), storeDirEncoded))
return;
#else
- const std::string& storeDirEncoded(args[0]);
+ storeDirEncoded = args[0];
#endif
// Look up directory ID
@@ -2008,9 +2012,14 @@ void BackupQueries::CommandRestore(const std::vector<std::string> &args, const b
try
{
+ // At TRACE level, we print a line for each file and
+ // directory, so we don't need dots.
+
+ bool printDots = ! Logging::IsEnabled(Log::TRACE);
+
result = BackupClientRestore(mrConnection, dirID,
- localName.c_str(),
- true /* print progress dots */, restoreDeleted,
+ storeDirEncoded.c_str(), localName.c_str(),
+ printDots /* print progress dots */, restoreDeleted,
false /* don't undelete after restore! */,
opts['r'] /* resume? */,
opts['f'] /* force continue after errors */);
diff --git a/bin/bbstored/BackupCommands.cpp b/bin/bbstored/BackupCommands.cpp
index 38cda234..c27cb7ab 100644
--- a/bin/bbstored/BackupCommands.cpp
+++ b/bin/bbstored/BackupCommands.cpp
@@ -388,11 +388,12 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto
std::auto_ptr<IOStream> diff2(rContext.OpenObject(patchID));
// Choose a temporary filename for the result of the combination
- std::ostringstream fs(rContext.GetStoreRoot());
- fs << ".recombinetemp.";
- fs << p;
- std::string tempFn(fs.str());
- tempFn = RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), tempFn, p + 16);
+ std::ostringstream fs;
+ fs << rContext.GetStoreRoot() << ".recombinetemp." << p;
+ std::string tempFn =
+ RaidFileController::DiscSetPathToFileSystemPath(
+ rContext.GetStoreDiscSet(), fs.str(),
+ p + 16);
// Open the temporary file
std::auto_ptr<IOStream> combined;
diff --git a/bin/bbstored/BackupStoreContext.cpp b/bin/bbstored/BackupStoreContext.cpp
index 2e915f57..5ee13faa 100644
--- a/bin/bbstored/BackupStoreContext.cpp
+++ b/bin/bbstored/BackupStoreContext.cpp
@@ -11,21 +11,22 @@
#include <stdio.h>
+#include "BackupConstants.h"
#include "BackupStoreContext.h"
-#include "RaidFileWrite.h"
-#include "RaidFileRead.h"
+#include "BackupStoreDaemon.h"
#include "BackupStoreDirectory.h"
#include "BackupStoreException.h"
-#include "BackupStoreInfo.h"
-#include "BackupConstants.h"
#include "BackupStoreFile.h"
+#include "BackupStoreInfo.h"
#include "BackupStoreObjectMagic.h"
-#include "StoreStructure.h"
-#include "BackupStoreDaemon.h"
-#include "RaidFileController.h"
+#include "BufferedStream.h"
+#include "BufferedWriteStream.h"
#include "FileStream.h"
#include "InvisibleTempFileStream.h"
-#include "BufferedStream.h"
+#include "RaidFileController.h"
+#include "RaidFileRead.h"
+#include "RaidFileWrite.h"
+#include "StoreStructure.h"
#include "MemLeakFindOn.h"
@@ -919,7 +920,10 @@ void BackupStoreContext::SaveDirectory(BackupStoreDirectory &rDir, int64_t Objec
{
RaidFileWrite writeDir(mStoreDiscSet, dirfn);
writeDir.Open(true /* allow overwriting */);
- rDir.WriteToStream(writeDir);
+
+ BufferedWriteStream buffer(writeDir);
+ rDir.WriteToStream(buffer);
+ buffer.Flush();
// get the disc usage (must do this before commiting it)
int64_t dirSize = writeDir.GetDiscUsageInBlocks();
diff --git a/bin/bbstored/bbstored-certs.in b/bin/bbstored/bbstored-certs.in
index e0554d94..85560748 100755
--- a/bin/bbstored/bbstored-certs.in
+++ b/bin/bbstored/bbstored-certs.in
@@ -1,8 +1,8 @@
#!@PERL@
use strict;
-# validity period for root certificates -- default is a very long time
-my $root_sign_period = '10000';
+# validity period for root certificates -- default is 2038, the best we can do for now
+my $root_sign_period = int(((1<<31) - time()) / 86400);
# but less so for client certificates
my $sign_period = '5000';
diff --git a/configure.ac b/configure.ac
index e171d4ad..48fb510f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,7 @@ AC_CHECK_HEADERS([syslog.h time.h cxxabi.h])
AC_CHECK_HEADERS([netinet/in.h])
AC_CHECK_HEADERS([sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h])
AC_CHECK_HEADERS([sys/uio.h sys/xattr.h])
+AC_CHECK_HEADERS([bsd/unistd.h])
AC_CHECK_HEADER([regex.h], [have_regex_h=yes])
@@ -223,6 +224,7 @@ AC_FUNC_ERROR_AT_LINE
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_CHECK_FUNCS([getpeereid lchown setproctitle getpid gettimeofday waitpid])
+AC_SEARCH_LIBS([setproctitle], ["bsd"])
# NetBSD implements kqueue too differently for us to get it fixed by 0.10
# TODO: Remove this when NetBSD kqueue implementation is working
@@ -383,7 +385,7 @@ if ! $PERL ./infrastructure/makebuildenv.pl \
fi
# Write summary of important info
-cat <<EOC
+tee config.log.features <<EOC
A summary of the build configuration is below. Box Backup will function
without these features, but will work better where they are present. Refer
to the documentation for more information on each feature.
diff --git a/debian/changelog b/debian/changelog
index bdf3d75b..9b02ee84 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+boxbackup (0.11.1~r2837-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Reinhard Tartler <siretart@tauware.de> Fri, 28 Oct 2011 01:13:55 +0200
+
boxbackup (0.11~rc8~r2714-1) unstable; urgency=low
* New upstream release.
diff --git a/distribution/boxbackup/VERSION.txt b/distribution/boxbackup/VERSION.txt
index 3d50f849..129b41fa 100644
--- a/distribution/boxbackup/VERSION.txt
+++ b/distribution/boxbackup/VERSION.txt
@@ -1,2 +1,2 @@
-0.11rc8
+0.11.1
boxbackup
diff --git a/docs/api-notes/win32_build_on_cygwin_using_mingw.txt b/docs/api-notes/win32_build_on_cygwin_using_mingw.txt
index 9c82cf76..e93af6cd 100644
--- a/docs/api-notes/win32_build_on_cygwin_using_mingw.txt
+++ b/docs/api-notes/win32_build_on_cygwin_using_mingw.txt
@@ -25,25 +25,31 @@ Make sure to select the following packages during installation:
If you already have Cygwin installed, please re-run the installer and
ensure that those packages are installed.
+You may also want to install the debugger, Devel/gdb.
+
== Base Directory ==
Choose a directory where you will unpack and compile OpenSSL, Zlib and Box Backup. We will call this the ''base directory''. An example might be:
- C:\Cygwin\Home\Your Username
+ C:\Cygwin\Home\YourUsername
Make sure you know the full path to this directory.
+If your user name has spaces in it, which is quite common on Windows,
+please rename your home directory to one without any spaces, and change
+your user's home directory in /etc/passwd to match.
+
== OpenSSL ==
-Download OpenSSL from [http://www.openssl.org/source/openssl-0.9.7i.tar.gz]
+Download OpenSSL from [http://www.openssl.org/source/openssl-1.0.0a.tar.gz]
Open a Cygwin shell, go to the base directory, and unpack OpenSSL:
- tar xzvf openssl-0.9.7i.tar.gz
+ tar xzvf openssl-1.0.0a.tar.gz
Configure OpenSSL for MinGW compilation, and build and install it:
- cd openssl-0.9.7i
+ cd openssl-1.0.0a
./Configure --prefix=/usr/i686-pc-mingw32/ mingw
make
make install
@@ -53,20 +59,20 @@ Configure OpenSSL for MinGW compilation, and build and install it:
This step is only required to support regular expressions in including/excluding files from backups. However, this is a very useful feature.
Download PCRE from
-[http://prdownloads.sourceforge.net/pcre/pcre-6.3.tar.bz2?download]
+[http://prdownloads.sourceforge.net/pcre/pcre-8.10.tar.bz2?download]
Open a Cygwin shell, go to the base directory, and unpack PCRE:
- tar xjvf pcre-6.3.tar.bz2
+ tar xjvf pcre-8.10.tar.bz2
Configure PCRE for MinGW compilation, and build and install it:
- cd pcre-6.3
+ cd pcre-8.10
export CFLAGS="-mno-cygwin"
- ./configure
- make winshared
- cp .libs/libpcre.a .libs/libpcreposix.a /lib/mingw
- cp pcreposix.h /usr/include/mingw
+ export CXXFLAGS="-mno-cygwin"
+ ./configure --prefix=/usr/i686-pc-mingw32
+ make
+ make install
== Download Box Backup ==
diff --git a/infrastructure/makebuildenv.pl.in b/infrastructure/makebuildenv.pl.in
index 9f53e2c6..33b0b635 100755
--- a/infrastructure/makebuildenv.pl.in
+++ b/infrastructure/makebuildenv.pl.in
@@ -98,7 +98,11 @@ while(<FINDAUTOGEN>)
}
# run command
- die "Couldn't run command $c" unless (0 == system("(cd $dir; $c)"))
+ unless (0 == system("(cd $dir; $c)"))
+ {
+ die "Couldn't run command $c " .
+ "(in $dir) for $file";
+ }
}
}
}
diff --git a/infrastructure/makeparcels.pl.in b/infrastructure/makeparcels.pl.in
index 41dab287..4dc94925 100755
--- a/infrastructure/makeparcels.pl.in
+++ b/infrastructure/makeparcels.pl.in
@@ -132,8 +132,9 @@ my @clean_deps;
for my $parcel (@parcels)
{
- my $target = BoxPlatform::parcel_target($parcel);
- my $dir = BoxPlatform::parcel_dir($parcel);
+ my $version = BoxPlatform::parcel_root($parcel);
+ my $target = BoxPlatform::parcel_target($parcel);
+ my $dir = BoxPlatform::parcel_dir($parcel);
my @parcel_deps;
unless ($target_windows)
@@ -288,13 +289,18 @@ EOF
($type,$name,$dest) = @args;
}
-
if ($type eq 'script')
{
# remove path from script name
$name =~ s{.*/}{};
}
+ if ($type eq 'html')
+ {
+ $dest = "share/doc/$version";
+ $name = "docs/$name.html";
+ }
+
if ($type eq 'man')
{
$name =~ /([0-9])$/;
diff --git a/infrastructure/mingw/configure.sh b/infrastructure/mingw/configure.sh
index f1ad353f..0486b20d 100755
--- a/infrastructure/mingw/configure.sh
+++ b/infrastructure/mingw/configure.sh
@@ -1,14 +1,16 @@
#!/bin/sh
-if [ ! -r "/usr/i686-pc-mingw32/lib/libssl.a" ]; then
+DEP_PATH=/usr/i686-pc-mingw32
+
+if [ ! -r "$DEP_PATH/lib/libssl.a" ]; then
echo "Error: install OpenSSL as instructed by" \
"docs/backup/win32_build_on_cygwin_using_mingw.txt" >&2
exit 2
fi
-if [ ! -r "/usr/lib/mingw/libpcreposix.a" \
- -o ! -r "/usr/lib/mingw/libpcre.a" \
- -o ! -r "/usr/include/mingw/pcreposix.h" ]; then
+if [ ! -r "$DEP_PATH/lib/libpcreposix.a" \
+ -o ! -r "$DEP_PATH/lib/libpcre.a" \
+ -o ! -r "$DEP_PATH/include/pcreposix.h" ]; then
echo "Error: install PCRE as instructed by" \
"docs/backup/win32_build_on_cygwin_using_mingw.txt" >&2
exit 2
diff --git a/lib/backupclient/BackupClientFileAttributes.cpp b/lib/backupclient/BackupClientFileAttributes.cpp
index af156a1d..b25ed9c7 100644
--- a/lib/backupclient/BackupClientFileAttributes.cpp
+++ b/lib/backupclient/BackupClientFileAttributes.cpp
@@ -843,9 +843,10 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename,
// Try to apply
if(::utimes(Filename, times) != 0)
{
- BOX_LOG_SYS_ERROR("Failed to change times of "
- "file '" << Filename << "'");
- THROW_EXCEPTION(CommonException, OSFileError)
+ BOX_LOG_SYS_WARNING("Failed to change times of "
+ "file '" << Filename << "' to ctime=" <<
+ BOX_FORMAT_TIMESPEC(times[0]) << ", mtime=" <<
+ BOX_FORMAT_TIMESPEC(times[1]));
}
}
diff --git a/lib/backupclient/BackupClientRestore.cpp b/lib/backupclient/BackupClientRestore.cpp
index b1c5cd0f..fa61bb59 100644
--- a/lib/backupclient/BackupClientRestore.cpp
+++ b/lib/backupclient/BackupClientRestore.cpp
@@ -211,7 +211,8 @@ typedef struct
//
// --------------------------------------------------------------------------
static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
- int64_t DirectoryID, std::string &rLocalDirectoryName,
+ int64_t DirectoryID, const std::string &rRemoteDirectoryName,
+ const std::string &rLocalDirectoryName,
RestoreParams &Params, RestoreResumeInfo &rLevel)
{
// If we're resuming... check that we haven't got a next level to
@@ -223,7 +224,9 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
DIRECTORY_SEPARATOR_ASCHAR +
rLevel.mNextLevelLocalName);
BackupClientRestoreDir(rConnection, rLevel.mNextLevelID,
- localDirname, Params, *rLevel.mpNextLevel);
+ rRemoteDirectoryName + '/' +
+ rLevel.mNextLevelLocalName, localDirname,
+ Params, *rLevel.mpNextLevel);
// Add it to the list of done itmes
rLevel.mRestoredObjects.insert(rLevel.mNextLevelID);
@@ -526,6 +529,11 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
}
}
+ BOX_TRACE("Restoring file: " <<
+ rRemoteDirectoryName + '/' +
+ nm.GetClearFilename() << " (" <<
+ en->GetSizeInBlocks() << " blocks)");
+
// Request it from the store
rConnection.QueryGetFile(DirectoryID,
en->GetObjectID());
@@ -739,9 +747,16 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
nm.GetClearFilename()));
// Recurse
+
+ BOX_TRACE("Entering directory: " <<
+ rRemoteDirectoryName + '/' +
+ nm.GetClearFilename());
+
int result = BackupClientRestoreDir(
rConnection, en->GetObjectID(),
- localDirname, Params, rnextLevel);
+ rRemoteDirectoryName + '/' +
+ nm.GetClearFilename(), localDirname,
+ Params, rnextLevel);
if (result != Restore_Complete)
{
@@ -824,8 +839,8 @@ static int BackupClientRestoreDir(BackupProtocolClient &rConnection,
//
// --------------------------------------------------------------------------
int BackupClientRestore(BackupProtocolClient &rConnection,
- int64_t DirectoryID, const char *LocalDirectoryName,
- bool PrintDots, bool RestoreDeleted,
+ int64_t DirectoryID, const char *RemoteDirectoryName,
+ const char *LocalDirectoryName, bool PrintDots, bool RestoreDeleted,
bool UndeleteAfterRestoreDeleted, bool Resume,
bool ContinueAfterErrors)
{
@@ -872,9 +887,9 @@ int BackupClientRestore(BackupProtocolClient &rConnection,
}
// Restore the directory
- std::string localName(LocalDirectoryName);
int result = BackupClientRestoreDir(rConnection, DirectoryID,
- localName, params, params.mResumeInfo);
+ RemoteDirectoryName, LocalDirectoryName, params,
+ params.mResumeInfo);
if (result != Restore_Complete)
{
return result;
diff --git a/lib/backupclient/BackupClientRestore.h b/lib/backupclient/BackupClientRestore.h
index 7e492238..311a15bd 100644
--- a/lib/backupclient/BackupClientRestore.h
+++ b/lib/backupclient/BackupClientRestore.h
@@ -24,6 +24,7 @@ enum
int BackupClientRestore(BackupProtocolClient &rConnection,
int64_t DirectoryID,
+ const char *RemoteDirectoryName,
const char *LocalDirectoryName,
bool PrintDots = false,
bool RestoreDeleted = false,
diff --git a/lib/backupclient/BackupDaemonConfigVerify.cpp b/lib/backupclient/BackupDaemonConfigVerify.cpp
index e70ba865..dfef5b03 100644
--- a/lib/backupclient/BackupDaemonConfigVerify.cpp
+++ b/lib/backupclient/BackupDaemonConfigVerify.cpp
@@ -65,7 +65,7 @@ static const ConfigurationVerify verifyserver[] =
static const ConfigurationVerifyKey verifyrootkeys[] =
{
ConfigurationVerifyKey("AccountNumber",
- ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigTest_Exists | ConfigTest_IsUint32),
ConfigurationVerifyKey("UpdateStoreInterval",
ConfigTest_Exists | ConfigTest_IsInt),
ConfigurationVerifyKey("MinimumFileAge",
diff --git a/lib/backupclient/BackupStoreFile.cpp b/lib/backupclient/BackupStoreFile.cpp
index 27e12bc8..17e145a3 100644
--- a/lib/backupclient/BackupStoreFile.cpp
+++ b/lib/backupclient/BackupStoreFile.cpp
@@ -311,7 +311,15 @@ void BackupStoreFile::DecodeFile(IOStream &rEncodedFile, const char *DecodedFile
// ASSERT(drained == 0);
// Write the attributes
- stream->GetAttributes().WriteAttributes(DecodedFilename);
+ try
+ {
+ stream->GetAttributes().WriteAttributes(DecodedFilename);
+ }
+ catch (std::exception& e)
+ {
+ BOX_WARNING("Failed to restore attributes on " <<
+ DecodedFilename << ": " << e.what());
+ }
}
catch(...)
{
diff --git a/lib/common/BufferedStream.cpp b/lib/common/BufferedStream.cpp
index 288e1ed1..b58253f3 100644
--- a/lib/common/BufferedStream.cpp
+++ b/lib/common/BufferedStream.cpp
@@ -2,7 +2,7 @@
//
// File
// Name: BufferedStream.cpp
-// Purpose: Buffering wrapper around IOStreams
+// Purpose: Buffering read-only wrapper around IOStreams
// Created: 2007/01/16
//
// --------------------------------------------------------------------------
diff --git a/lib/common/BufferedStream.h b/lib/common/BufferedStream.h
index 234061c4..079c482a 100644
--- a/lib/common/BufferedStream.h
+++ b/lib/common/BufferedStream.h
@@ -2,7 +2,7 @@
//
// File
// Name: BufferedStream.h
-// Purpose: Buffering wrapper around IOStreams
+// Purpose: Buffering read-only wrapper around IOStreams
// Created: 2007/01/16
//
// --------------------------------------------------------------------------
diff --git a/lib/common/BufferedWriteStream.cpp b/lib/common/BufferedWriteStream.cpp
new file mode 100644
index 00000000..797be00d
--- /dev/null
+++ b/lib/common/BufferedWriteStream.cpp
@@ -0,0 +1,181 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: BufferedWriteStream.cpp
+// Purpose: Buffering write-only wrapper around IOStreams
+// Created: 2010/09/13
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+#include "BufferedWriteStream.h"
+#include "CommonException.h"
+
+#include <string.h>
+
+#include "MemLeakFindOn.h"
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::BufferedWriteStream(const char *, int, int)
+// Purpose: Constructor, set up buffer
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+BufferedWriteStream::BufferedWriteStream(IOStream& rSink)
+: mrSink(rSink), mBufferPosition(0)
+{ }
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::Read(void *, int)
+// Purpose: Reads bytes from the file - throws exception
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+int BufferedWriteStream::Read(void *pBuffer, int NBytes, int Timeout)
+{
+ THROW_EXCEPTION(CommonException, NotSupported);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::BytesLeftToRead()
+// Purpose: Returns number of bytes to read (may not be most efficient function ever)
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+IOStream::pos_type BufferedWriteStream::BytesLeftToRead()
+{
+ THROW_EXCEPTION(CommonException, NotSupported);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::Write(void *, int)
+// Purpose: Writes bytes to the underlying stream (not supported)
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedWriteStream::Write(const void *pBuffer, int NBytes)
+{
+ int numBytesRemain = NBytes;
+
+ do
+ {
+ int maxWritable = sizeof(mBuffer) - mBufferPosition;
+ int numBytesToWrite = (numBytesRemain < maxWritable) ?
+ numBytesRemain : maxWritable;
+
+ if(numBytesToWrite > 0)
+ {
+ memcpy(mBuffer + mBufferPosition, pBuffer,
+ numBytesToWrite);
+ mBufferPosition += numBytesToWrite;
+ pBuffer = ((const char *)pBuffer) + numBytesToWrite;
+ numBytesRemain -= numBytesToWrite;
+ }
+
+ if(numBytesRemain > 0)
+ {
+ Flush();
+ }
+ }
+ while(numBytesRemain > 0);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::GetPosition()
+// Purpose: Get position in stream
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+IOStream::pos_type BufferedWriteStream::GetPosition() const
+{
+ return mrSink.GetPosition() + mBufferPosition;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::Seek(pos_type, int)
+// Purpose: Seeks within file, as lseek, invalidate buffer
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedWriteStream::Seek(IOStream::pos_type Offset, int SeekType)
+{
+ // Always flush the buffer before seeking
+ Flush();
+
+ mrSink.Seek(Offset, SeekType);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::Flush();
+// Purpose: Write out current buffer contents and invalidate
+// Created: 2010/09/13
+//
+// --------------------------------------------------------------------------
+void BufferedWriteStream::Flush(int Timeout)
+{
+ if(mBufferPosition > 0)
+ {
+ mrSink.Write(mBuffer, mBufferPosition);
+ }
+
+ mBufferPosition = 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::Close()
+// Purpose: Closes the underlying stream (not needed)
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedWriteStream::Close()
+{
+ Flush();
+ mrSink.Close();
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::StreamDataLeft()
+// Purpose: Any data left to write?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool BufferedWriteStream::StreamDataLeft()
+{
+ THROW_EXCEPTION(CommonException, NotSupported);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedWriteStream::StreamClosed()
+// Purpose: Is the stream closed?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool BufferedWriteStream::StreamClosed()
+{
+ return mrSink.StreamClosed();
+}
+
diff --git a/lib/common/BufferedWriteStream.h b/lib/common/BufferedWriteStream.h
new file mode 100644
index 00000000..7a1c8c17
--- /dev/null
+++ b/lib/common/BufferedWriteStream.h
@@ -0,0 +1,44 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: BufferedWriteStream.h
+// Purpose: Buffering write-only wrapper around IOStreams
+// Created: 2010/09/13
+//
+// --------------------------------------------------------------------------
+
+#ifndef BUFFEREDWRITESTREAM__H
+#define BUFFEREDWRITESTREAM__H
+
+#include "IOStream.h"
+
+class BufferedWriteStream : public IOStream
+{
+private:
+ IOStream& mrSink;
+ char mBuffer[4096];
+ int mBufferPosition;
+
+public:
+ BufferedWriteStream(IOStream& rSource);
+ virtual ~BufferedWriteStream() { Close(); }
+
+ virtual int Read(void *pBuffer, int NBytes, int Timeout = IOStream::TimeOutInfinite);
+ virtual pos_type BytesLeftToRead();
+ virtual void Write(const void *pBuffer, int NBytes);
+ virtual pos_type GetPosition() const;
+ virtual void Seek(IOStream::pos_type Offset, int SeekType);
+ virtual void Flush(int Timeout = IOStream::TimeOutInfinite);
+ virtual void Close();
+
+ virtual bool StreamDataLeft();
+ virtual bool StreamClosed();
+
+private:
+ BufferedWriteStream(const BufferedWriteStream &rToCopy)
+ : mrSink(rToCopy.mrSink) { /* do not call */ }
+};
+
+#endif // BUFFEREDWRITESTREAM__H
+
+
diff --git a/lib/common/Configuration.cpp b/lib/common/Configuration.cpp
index 2eb5fbca..f49f3c6e 100644
--- a/lib/common/Configuration.cpp
+++ b/lib/common/Configuration.cpp
@@ -453,7 +453,8 @@ int Configuration::GetKeyValueInt(const std::string& rKeyName) const
}
else
{
- long value = ::strtol((i->second).c_str(), NULL, 0 /* C style handling */);
+ long value = ::strtol((i->second).c_str(), NULL,
+ 0 /* C style handling */);
if(value == LONG_MAX || value == LONG_MIN)
{
THROW_EXCEPTION(CommonException, ConfigBadIntValue)
@@ -466,6 +467,36 @@ int Configuration::GetKeyValueInt(const std::string& rKeyName) const
// --------------------------------------------------------------------------
//
// Function
+// Name: Configuration::GetKeyValueUint32(const std::string& rKeyName)
+// Purpose: Gets a key value as a 32-bit unsigned integer
+// Created: 2003/07/23
+//
+// --------------------------------------------------------------------------
+uint32_t Configuration::GetKeyValueUint32(const std::string& rKeyName) const
+{
+ std::map<std::string, std::string>::const_iterator i(mKeys.find(rKeyName));
+
+ if(i == mKeys.end())
+ {
+ THROW_EXCEPTION(CommonException, ConfigNoKey)
+ }
+ else
+ {
+ errno = 0;
+ long value = ::strtoul((i->second).c_str(), NULL,
+ 0 /* C style handling */);
+ if(errno != 0)
+ {
+ THROW_EXCEPTION(CommonException, ConfigBadIntValue)
+ }
+ return (int)value;
+ }
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
// Name: Configuration::GetKeyValueBool(const std::string&)
// Purpose: Gets a key value as a boolean
// Created: 17/2/04
@@ -680,6 +711,21 @@ bool Configuration::Verify(const ConfigurationVerify &rVerify,
rErrorMsg += rLevel + mName + "." + pvkey->Name() + " (key) is not a valid integer.\n";
}
}
+
+ // Check it's a number?
+ if(pvkey->Flags() & ConfigTest_IsUint32)
+ {
+ // Test it...
+ char *end;
+ errno = 0;
+ uint32_t r = ::strtoul(val, &end, 0);
+ if(errno != 0 || end != (val + rval.size()))
+ {
+ // not a good value
+ ok = false;
+ rErrorMsg += rLevel + mName + "." + pvkey->Name() + " (key) is not a valid unsigned 32-bit integer.\n";
+ }
+ }
// Check it's a bool?
if((pvkey->Flags() & ConfigTest_IsBool) == ConfigTest_IsBool)
diff --git a/lib/common/Configuration.h b/lib/common/Configuration.h
index 2babd753..4828b315 100644
--- a/lib/common/Configuration.h
+++ b/lib/common/Configuration.h
@@ -22,8 +22,9 @@ enum
ConfigTest_LastEntry = 1,
ConfigTest_Exists = 2,
ConfigTest_IsInt = 4,
- ConfigTest_MultiValueAllowed = 8,
- ConfigTest_IsBool = 16
+ ConfigTest_IsUint32 = 8,
+ ConfigTest_MultiValueAllowed = 16,
+ ConfigTest_IsBool = 32
};
class ConfigurationVerifyKey
@@ -112,6 +113,7 @@ public:
bool KeyExists(const std::string& rKeyName) const;
const std::string &GetKeyValue(const std::string& rKeyName) const;
int GetKeyValueInt(const std::string& rKeyName) const;
+ uint32_t GetKeyValueUint32(const std::string& rKeyName) const;
bool GetKeyValueBool(const std::string& rKeyName) const;
std::vector<std::string> GetKeyNames() const;
diff --git a/lib/common/Logging.h b/lib/common/Logging.h
index 24863d2c..15400711 100644
--- a/lib/common/Logging.h
+++ b/lib/common/Logging.h
@@ -105,6 +105,11 @@ inline std::string GetNativeErrorMessage()
(objectid) << \
std::dec
+#define BOX_FORMAT_TIMESPEC(timespec) \
+ timespec.tv_sec << \
+ std::setw(6) << \
+ timespec.tv_usec
+
#undef ERROR
namespace Log
diff --git a/lib/httpserver/HTTPRequest.h b/lib/httpserver/HTTPRequest.h
index ca50e60f..25effb70 100644
--- a/lib/httpserver/HTTPRequest.h
+++ b/lib/httpserver/HTTPRequest.h
@@ -49,7 +49,8 @@ private:
HTTPRequest &operator=(const HTTPRequest &);
public:
typedef std::multimap<std::string, std::string> Query_t;
- typedef std::pair<std::string, std::string> QueryEn_t, Header;
+ typedef Query_t::value_type QueryEn_t;
+ typedef std::pair<std::string, std::string> Header;
enum
{
diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp
index 2d852f86..f24c2422 100644
--- a/lib/raidfile/RaidFileWrite.cpp
+++ b/lib/raidfile/RaidFileWrite.cpp
@@ -836,9 +836,9 @@ int RaidFileWrite::Read(void *pBuffer, int NBytes, int Timeout)
// --------------------------------------------------------------------------
void RaidFileWrite::Close()
{
- BOX_WARNING("RaidFileWrite::Close() called, discarding file");
if(mOSFileHandle != -1)
{
+ BOX_WARNING("RaidFileWrite::Close() called, discarding file");
Discard();
}
}
diff --git a/lib/server/Daemon.cpp b/lib/server/Daemon.cpp
index c4026395..8b4f1d0c 100644
--- a/lib/server/Daemon.cpp
+++ b/lib/server/Daemon.cpp
@@ -19,6 +19,10 @@
#include <string.h>
#include <stdarg.h>
+#ifdef HAVE_BSD_UNISTD_H
+ #include <bsd/unistd.h>
+#endif
+
#ifdef WIN32
#include <ws2tcpip.h>
#endif
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp
index 3a56661a..db9974d2 100644
--- a/lib/win32/emu.cpp
+++ b/lib/win32/emu.cpp
@@ -1365,7 +1365,7 @@ void closelog(void)
void syslog(int loglevel, const char *frmt, ...)
{
WORD errinfo;
- char buffer[1024];
+ char buffer[4096];
std::string sixfour(frmt);
switch (loglevel)
@@ -1814,7 +1814,7 @@ bool ConvertTime_tToFileTime(const time_t from, FILETIME *pTo)
if (time_breakdown == NULL)
{
::syslog(LOG_ERR, "Error: failed to convert time format: "
- "%d is not a valid time\n", from);
+ "%d is not a valid time\n", adjusted);
return false;
}
diff --git a/parcels.txt b/parcels.txt
index 168653c3..718fb995 100644
--- a/parcels.txt
+++ b/parcels.txt
@@ -35,6 +35,8 @@ END-ONLY
ONLY:mingw32
script /bin/mgwz.dll
script /bin/mingwm10.dll
+ script /usr/i686-pc-mingw32/bin/cygpcreposix-0.dll
+ script /usr/i686-pc-mingw32/bin/cygpcre-0.dll
END-ONLY
ONLY:SunOS
diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp
index 32f3c176..77c463ba 100644
--- a/test/bbackupd/testbbackupd.cpp
+++ b/test/bbackupd/testbbackupd.cpp
@@ -521,7 +521,10 @@ void do_interrupted_restore(const TLSContext &context, int64_t restoredirid)
std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, BackupProtocolClientLogin::Flags_ReadOnly));
// Test the restoration
- TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-interrupt", true /* print progress dots */) == Restore_Complete);
+ TEST_THAT(BackupClientRestore(protocol, restoredirid,
+ "Test1", "testfiles/restore-interrupt",
+ true /* print progress dots */)
+ == Restore_Complete);
// Log out
protocol.QueryFinished();
@@ -3406,7 +3409,7 @@ int test_bbackupd()
// Test the restoration
TEST_THAT(BackupClientRestore(*client, restoredirid,
- "testfiles/restore-Test1",
+ "Test1", "testfiles/restore-Test1",
true /* print progress dots */)
== Restore_Complete);
@@ -3415,7 +3418,7 @@ int test_bbackupd()
// Make sure you can't restore a restored directory
TEST_THAT(BackupClientRestore(*client, restoredirid,
- "testfiles/restore-Test1",
+ "Test1", "testfiles/restore-Test1",
true /* print progress dots */)
== Restore_TargetExists);
@@ -3426,7 +3429,7 @@ int test_bbackupd()
// Just check it doesn't bomb out -- will check this
// properly later (when bbackupd is stopped)
TEST_THAT(BackupClientRestore(*client, deldirid,
- "testfiles/restore-Test1-x1",
+ "Test1", "testfiles/restore-Test1-x1",
true /* print progress dots */,
true /* deleted files */)
== Restore_Complete);
@@ -3439,7 +3442,7 @@ int test_bbackupd()
{
Logging::Guard guard(Log::FATAL);
TEST_THAT(BackupClientRestore(*client,
- restoredirid,
+ restoredirid, "Test1",
"testfiles/no-such-path/subdir",
true /* print progress dots */)
== Restore_TargetPathNotFound);
@@ -3787,13 +3790,13 @@ int test_bbackupd()
// Check that the restore fn returns resume possible,
// rather than doing anything
TEST_THAT(BackupClientRestore(*client, restoredirid,
- "testfiles/restore-interrupt",
+ "Test1", "testfiles/restore-interrupt",
true /* print progress dots */)
== Restore_ResumePossible);
// Then resume it
TEST_THAT(BackupClientRestore(*client, restoredirid,
- "testfiles/restore-interrupt",
+ "Test1", "testfiles/restore-interrupt",
true /* print progress dots */,
false /* deleted files */,
false /* undelete server */,
@@ -3828,7 +3831,7 @@ int test_bbackupd()
// Do restore and undelete
TEST_THAT(BackupClientRestore(*client, deldirid,
- "testfiles/restore-Test1-x1-2",
+ "Test1", "testfiles/restore-Test1-x1-2",
true /* print progress dots */,
true /* deleted files */,
true /* undelete on server */)