summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorBen Summers <ben@fluffy.co.uk>2006-02-13 13:30:21 +0000
committerBen Summers <ben@fluffy.co.uk>2006-02-13 13:30:21 +0000
commit830aa82e44381c85d8486e46de7ae0e26830457e (patch)
treef29edb3c3013990a3ae758e1ccfdb56a2d20923f /bin
parent2edd0a00e3244cc4dbc369d81ed1748768a06fb8 (diff)
Merge chris/win32/vc2005-compile-fixes @ r455, add infrastructure/msvc to distribution
Diffstat (limited to 'bin')
-rw-r--r--bin/bbackupctl/bbackupctl.cpp7
-rw-r--r--bin/bbackupd/BackupClientContext.cpp14
-rw-r--r--bin/bbackupd/BackupClientContext.h5
-rw-r--r--bin/bbackupd/BackupClientDirectoryRecord.cpp5
-rw-r--r--bin/bbackupd/BackupDaemon.cpp216
-rw-r--r--bin/bbackupd/BackupDaemon.h5
-rw-r--r--bin/bbackupd/Win32ServiceFunctions.cpp69
-rw-r--r--bin/bbackupd/bbackupd.cpp12
-rw-r--r--bin/bbackupquery/BackupQueries.cpp322
-rw-r--r--bin/bbackupquery/bbackupquery.cpp56
10 files changed, 515 insertions, 196 deletions
diff --git a/bin/bbackupctl/bbackupctl.cpp b/bin/bbackupctl/bbackupctl.cpp
index d39092e8..dfadc37d 100644
--- a/bin/bbackupctl/bbackupctl.cpp
+++ b/bin/bbackupctl/bbackupctl.cpp
@@ -10,7 +10,10 @@
#include "Box.h"
#include <stdio.h>
-#include <unistd.h>
+
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
#include "MainHelper.h"
#include "BoxPortsAndFiles.h"
@@ -212,7 +215,7 @@ int main(int argc, const char *argv[])
// No? Just send the command given plus a quit command.
std::string cmd(argv[0]);
cmd += "\nquit\n";
- connection.Write(cmd.c_str(), cmd.size());
+ connection.Write(cmd.c_str(), cmd.size());
}
// Read the response
diff --git a/bin/bbackupd/BackupClientContext.cpp b/bin/bbackupd/BackupClientContext.cpp
index ae4e1cad..25852b19 100644
--- a/bin/bbackupd/BackupClientContext.cpp
+++ b/bin/bbackupd/BackupClientContext.cpp
@@ -57,9 +57,7 @@ BackupClientContext::BackupClientContext(BackupDaemon &rDaemon, TLSContext &rTLS
mpExcludeFiles(0),
mpExcludeDirs(0),
mbIsManaged(false),
- mTimeMgmtEpoch(0),
- mMaximumDiffTime(600),
- mKeepAliveTime(0)
+ mTimeMgmtEpoch(0)
{
}
@@ -511,6 +509,9 @@ void BackupClientContext::ManageDiffProcess()
#ifdef PLATFORM_CYGWIN
::signal(SIGALRM, TimerSigHandler);
+#elif defined WIN32
+ // no support for SIGVTALRM
+ SetTimerHandler(TimerSigHandler);
#else
::signal(SIGVTALRM, TimerSigHandler);
#endif // PLATFORM_CYGWIN
@@ -599,7 +600,10 @@ void BackupClientContext::UnManageDiffProcess()
void BackupClientContext::DoKeepAlive()
{
if (!mpConnection)
+ {
+ ::syslog(LOG_ERR, "DoKeepAlive() called with no connection!");
return;
+ }
mpConnection->QueryGetIsAlive();
}
@@ -620,10 +624,10 @@ time_t BackupClientContext::GetTimeMgmtEpoch()
int BackupClientContext::GetMaximumDiffingTime()
{
- return mMaximumDiffTime;
+ return sMaximumDiffTime;
}
int BackupClientContext::GetKeepaliveTime()
{
- return mKeepAliveTime;
+ return sKeepAliveTime;
}
diff --git a/bin/bbackupd/BackupClientContext.h b/bin/bbackupd/BackupClientContext.h
index 234868db..a0cf6e1f 100644
--- a/bin/bbackupd/BackupClientContext.h
+++ b/bin/bbackupd/BackupClientContext.h
@@ -208,11 +208,6 @@ private:
bool mbIsManaged;
// unix time when diff was started
time_t mTimeMgmtEpoch;
- // maximum time to spend diffing, in seconds
- int mMaximumDiffTime;
- // maximum time of SSL inactivity (keep-alive interval), in seconds
- int mKeepAliveTime;
-
};
diff --git a/bin/bbackupd/BackupClientDirectoryRecord.cpp b/bin/bbackupd/BackupClientDirectoryRecord.cpp
index 49193ccf..5a566d84 100644
--- a/bin/bbackupd/BackupClientDirectoryRecord.cpp
+++ b/bin/bbackupd/BackupClientDirectoryRecord.cpp
@@ -9,7 +9,10 @@
#include "Box.h"
-#include <dirent.h>
+#ifdef HAVE_DIRENT_H
+ #include <dirent.h>
+#endif
+
#include <errno.h>
#include <string.h>
diff --git a/bin/bbackupd/BackupDaemon.cpp b/bin/bbackupd/BackupDaemon.cpp
index a6d25f0f..01e5bf36 100644
--- a/bin/bbackupd/BackupDaemon.cpp
+++ b/bin/bbackupd/BackupDaemon.cpp
@@ -11,8 +11,10 @@
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
@@ -35,6 +37,9 @@
#include <cstdio>
#include <sys/mnttab.h>
#endif
+#ifdef HAVE_PROCESS_H
+ #include <process.h>
+#endif
#include "Configuration.h"
#include "IOStream.h"
@@ -78,6 +83,25 @@ static const time_t MAX_SLEEP_TIME = 1024;
// This prevents repetative cycles of load on the server
#define SYNC_PERIOD_RANDOM_EXTRA_TIME_SHIFT_BY 6
+#ifdef WIN32
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: HelperThread()
+// Purpose: Background thread function, called by Windows,
+// calls the BackupDaemon's RunHelperThread method
+// to listen for and act on control communications
+// Created: 18/2/04
+//
+// --------------------------------------------------------------------------
+unsigned int WINAPI HelperThread(LPVOID lpParam)
+{
+ ((BackupDaemon *)lpParam)->RunHelperThread();
+
+ return 0;
+}
+#endif
+
// --------------------------------------------------------------------------
//
// Function
@@ -99,6 +123,20 @@ BackupDaemon::BackupDaemon()
{
mNotificationsSent[l] = false;
}
+
+#ifdef WIN32
+ // Create a thread to handle the named pipe
+ HANDLE hThread;
+ unsigned int dwThreadId;
+
+ 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
}
// --------------------------------------------------------------------------
@@ -185,11 +223,12 @@ void BackupDaemon::SetupInInitialProcess()
if(GetConfiguration().KeyExists("CommandSocket"))
{
printf(
- "============================================================================================\n" \
- "SECURITY WARNING: This platform cannot check the credentials of connections to the\n" \
- "command socket. This is a potential DoS security problem.\n" \
- "Remove the CommandSocket directive from the bbackupd.conf file if bbackupctl is not used.\n" \
- "============================================================================================\n"
+ "==============================================================================\n"
+ "SECURITY WARNING: This platform cannot check the credentials of connections to\n"
+ "the command socket. This is a potential DoS security problem.\n"
+ "Remove the CommandSocket directive from the bbackupd.conf file if bbackupctl\n"
+ "is not used.\n"
+ "==============================================================================\n"
);
}
}
@@ -221,30 +260,13 @@ void BackupDaemon::DeleteAllLocations()
}
#ifdef WIN32
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: HelperThread()
-// Purpose: Background thread function, called by Windows,
-// calls the BackupDaemon's RunHelperThread method
-// to listen for and act on control communications
-// Created: 18/2/04
-//
-// --------------------------------------------------------------------------
-unsigned int WINAPI HelperThread( LPVOID lpParam )
-{
- printf( "Parameter = %lu.\n", *(DWORD*)lpParam );
- ((BackupDaemon *)lpParam)->RunHelperThread();
-
- return 0;
-}
-
void BackupDaemon::RunHelperThread(void)
{
mpCommandSocketInfo = new CommandSocketInfo;
this->mReceivedCommandConn = false;
- while ( !IsTerminateWanted() )
+ // loop until the parent process exits
+ while (TRUE)
{
try
{
@@ -359,24 +381,21 @@ void BackupDaemon::RunHelperThread(void)
void BackupDaemon::Run()
{
#ifdef WIN32
-
- // Create a thread to handle the named pipe
- HANDLE hThread;
- unsigned int dwThreadId;
-
- 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
-
// init our own timer for file diff timeouts
InitTimer();
-#else // ! WIN32
+ try
+ {
+ Run2();
+ }
+ catch(...)
+ {
+ FiniTimer();
+ throw;
+ }
+ FiniTimer();
+#else // ! WIN32
// Ignore SIGPIPE (so that if a command connection is broken, the daemon doesn't terminate)
::signal(SIGPIPE, SIG_IGN);
@@ -390,8 +409,6 @@ void BackupDaemon::Run()
::unlink(socketName);
mpCommandSocketInfo->mListeningSocket.Listen(Socket::TypeUNIX, socketName);
}
-
-#endif // WIN32
// Handle things nicely on exceptions
try
@@ -402,23 +419,28 @@ void BackupDaemon::Run()
{
if(mpCommandSocketInfo != 0)
{
- delete mpCommandSocketInfo;
+ try
+ {
+ delete mpCommandSocketInfo;
+ }
+ catch(...)
+ {
+ ::syslog(LOG_WARNING,
+ "Error closing command socket "
+ "after exception, ignored.");
+ }
mpCommandSocketInfo = 0;
}
throw;
}
-
+
// Clean up
if(mpCommandSocketInfo != 0)
{
delete mpCommandSocketInfo;
mpCommandSocketInfo = 0;
}
-
-#ifdef WIN32
- // clean up windows specific stuff.
- FiniTimer();
#endif
}
@@ -482,8 +504,8 @@ void BackupDaemon::Run2()
BackupClientContext::ClientStoreMarker_NotKnown;
// haven't contacted the store yet
- DeserializeStoreObjectInfo(clientStoreMarker, lastSyncTime,
- nextSyncTime);
+ bool deserialised = DeserializeStoreObjectInfo(clientStoreMarker,
+ lastSyncTime, nextSyncTime);
// --------------------------------------------------------------------------------------------
@@ -585,6 +607,17 @@ void BackupDaemon::Run2()
// but this should be OK, because the changes only upload should upload no data.
syncPeriodEndExtended += SecondsToBoxTime((time_t)(356*24*3600));
}
+
+ // Delete the serialised store object file,
+ // so that we don't try to reload it after a
+ // partially completed backup
+ if(deserialised && !DeleteStoreObjectInfo())
+ {
+ ::syslog(LOG_ERR, "Failed to delete the "
+ "StoreObjectInfoFile, backup cannot "
+ "continue safely.");
+ continue;
+ }
// Do sync
bool errorOccurred = false;
@@ -751,7 +784,12 @@ void BackupDaemon::Run2()
"to retry...",
errorString, errorCode,
errorSubCode);
- ::sleep(100);
+ ::sleep(10);
+ nextSyncTime = currentSyncStartTime +
+ SecondsToBoxTime(90) +
+ Random::RandomInt(
+ updateStoreInterval >>
+ SYNC_PERIOD_RANDOM_EXTRA_TIME_SHIFT_BY);
}
}
@@ -863,7 +901,7 @@ void BackupDaemon::WaitOnCommandSocket(box_time_t RequiredDelay, bool &DoSyncFla
#ifdef WIN32
// Really could use some interprocess protection, mutex etc
// any side effect should be too bad???? :)
- DWORD timeout = BoxTimeToMilliSeconds(RequiredDelay);
+ DWORD timeout = (DWORD)BoxTimeToMilliSeconds(RequiredDelay);
while ( this->mReceivedCommandConn == false )
{
@@ -1065,25 +1103,23 @@ void BackupDaemon::WaitOnCommandSocket(box_time_t RequiredDelay, bool &DoSyncFla
// --------------------------------------------------------------------------
void BackupDaemon::CloseCommandConnection()
{
+#ifndef WIN32
try
{
TRACE0("Closing command connection\n");
-#ifdef WIN32
- mpCommandSocketInfo->mListeningSocket.Close();
-#else
if(mpCommandSocketInfo->mpGetLine)
{
delete mpCommandSocketInfo->mpGetLine;
mpCommandSocketInfo->mpGetLine = 0;
}
mpCommandSocketInfo->mpConnectedSocket.reset();
-#endif
}
catch(...)
{
// Ignore any errors
}
+#endif
}
@@ -1100,7 +1136,11 @@ void BackupDaemon::SendSyncStartOrFinish(bool SendStart)
{
// The bbackupctl program can't rely on a state change, because it may never
// change if the server doesn't need to be contacted.
-
+
+#ifdef __MINGW32__
+#warning race condition: what happens if socket is closed?
+#endif
+
if (mpCommandSocketInfo != NULL &&
#ifdef WIN32
mpCommandSocketInfo->mListeningSocket.IsConnected()
@@ -1114,7 +1154,7 @@ void BackupDaemon::SendSyncStartOrFinish(bool SendStart)
{
#ifdef WIN32
mpCommandSocketInfo->mListeningSocket.Write(message,
- strlen(message));
+ (int)strlen(message));
#else
mpCommandSocketInfo->mpConnectedSocket->Write(message,
strlen(message));
@@ -1711,7 +1751,10 @@ void BackupDaemon::SetState(int State)
char newStateSize = sprintf(newState, "state %d\n", State);
#ifdef WIN32
- #warning FIX ME: race condition
+ #ifndef _MSC_VER
+ #warning FIX ME: race condition
+ #endif
+
// what happens if the socket is closed by the other thread before
// we can write to it? Null pointer deref at best.
if (mpCommandSocketInfo &&
@@ -2196,7 +2239,7 @@ void BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time
// Created: 2005/04/11
//
// --------------------------------------------------------------------------
-void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime)
+bool BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime)
{
//
//
@@ -2208,7 +2251,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
//
if(!GetConfiguration().KeyExists("StoreObjectInfoFile"))
{
- return;
+ return false;
}
std::string StoreObjectInfoFile =
@@ -2216,7 +2259,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
if (StoreObjectInfoFile.size() <= 0)
{
- return;
+ return false;
}
try
@@ -2236,7 +2279,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
"is not a valid or compatible serialised "
"archive. Will re-cache from store.",
StoreObjectInfoFile.c_str());
- return;
+ return false;
}
//
@@ -2251,7 +2294,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
"is not a valid or compatible serialised "
"archive. Will re-cache from store.",
StoreObjectInfoFile.c_str());
- return;
+ return false;
}
//
@@ -2264,11 +2307,11 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
if (iVersion != STOREOBJECTINFO_VERSION)
{
::syslog(LOG_WARNING, "Store object info file '%s' "
- "version [%d] unsupported. "
+ "version %d unsupported. "
"Will re-cache from store.",
StoreObjectInfoFile.c_str(),
iVersion);
- return;
+ return false;
}
//
@@ -2283,7 +2326,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
::syslog(LOG_WARNING, "Store object info file '%s' "
"out of date. Will re-cache from store",
StoreObjectInfoFile.c_str());
- return;
+ return false;
}
//
@@ -2331,12 +2374,7 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
"version [%d]", StoreObjectInfoFile.c_str(),
iVersion);
- if (::unlink(StoreObjectInfoFile.c_str()) != 0)
- {
- ::syslog(LOG_ERR, "Failed to delete the old "
- "store object info file '%s': %s",
- StoreObjectInfoFile.c_str(), strerror(errno));
- }
+ return true;
}
catch (...)
{
@@ -2352,4 +2390,38 @@ void BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_
"Will re-cache from store.",
StoreObjectInfoFile.c_str());
}
+
+ return false;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupDaemon::DeleteStoreObjectInfo()
+// Purpose: Deletes the serialised state file, to prevent us
+// from using it again if a backup is interrupted.
+//
+// Created: 2006/02/12
+//
+// --------------------------------------------------------------------------
+
+bool BackupDaemon::DeleteStoreObjectInfo() const
+{
+ if(!GetConfiguration().KeyExists("StoreObjectInfoFile"))
+ {
+ return false;
+ }
+
+ std::string StoreObjectInfoFile =
+ GetConfiguration().GetKeyValue("StoreObjectInfoFile");
+
+ if (::unlink(StoreObjectInfoFile.c_str()) != 0)
+ {
+ ::syslog(LOG_ERR, "Failed to delete the old "
+ "store object info file '%s': %s",
+ StoreObjectInfoFile.c_str(), strerror(errno));
+ return false;
+ }
+
+ return true;
}
diff --git a/bin/bbackupd/BackupDaemon.h b/bin/bbackupd/BackupDaemon.h
index 8693fe9e..3bd15fad 100644
--- a/bin/bbackupd/BackupDaemon.h
+++ b/bin/bbackupd/BackupDaemon.h
@@ -45,10 +45,11 @@ public:
BackupDaemon();
~BackupDaemon();
+private:
// methods below do partial (specialized) serialization of client state only
void SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const;
- void DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime);
-private:
+ bool DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime);
+ bool DeleteStoreObjectInfo() const;
BackupDaemon(const BackupDaemon &);
public:
diff --git a/bin/bbackupd/Win32ServiceFunctions.cpp b/bin/bbackupd/Win32ServiceFunctions.cpp
index 89f02f62..b74c7e09 100644
--- a/bin/bbackupd/Win32ServiceFunctions.cpp
+++ b/bin/bbackupd/Win32ServiceFunctions.cpp
@@ -14,10 +14,12 @@
#include "Box.h"
-//#include <stdio.h>
-//#include <stdlib.h>
-#include <unistd.h>
-//#include <windows.h>
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+#ifdef HAVE_PROCESS_H
+ #include <process.h>
+#endif
extern void TerminateService(void);
extern unsigned int WINAPI RunService(LPVOID lpParameter);
@@ -31,18 +33,23 @@ HANDLE gStopServiceEvent = 0;
#define SERVICE_NAME "boxbackup"
+void ShowMessage(char *s)
+{
+ MessageBox(0, s, "Box Backup Message",
+ MB_OK | MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY);
+}
+
void ErrorHandler(char *s, DWORD err)
{
char buf[256];
memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf)-1, "%s (%d)", s, err);
+ _snprintf(buf, sizeof(buf)-1, "%s (%d)", s, err);
::syslog(LOG_ERR, "%s", buf);
MessageBox(0, buf, "Error",
MB_OK | MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY);
ExitProcess(err);
}
-
void WINAPI ServiceControlHandler( DWORD controlCode )
{
switch ( controlCode )
@@ -88,7 +95,7 @@ void WINAPI ServiceControlHandler( DWORD controlCode )
VOID ServiceMain(DWORD argc, LPTSTR *argv)
{
- // initialise service status
+ // initialise service status
gServiceStatus.dwServiceType = SERVICE_WIN32;
gServiceStatus.dwCurrentState = SERVICE_STOPPED;
gServiceStatus.dwControlsAccepted = 0;
@@ -178,14 +185,19 @@ void InstallService(void)
scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
- if (!scm) return;
+ if (!scm)
+ {
+ syslog(LOG_ERR, "Failed to open service control manager: "
+ "error %d", GetLastError());
+ return;
+ }
char cmd[MAX_PATH];
GetModuleFileName(NULL, cmd, sizeof(cmd)-1);
cmd[sizeof(cmd)-1] = 0;
char cmd_args[MAX_PATH];
- snprintf(cmd_args, sizeof(cmd_args)-1, "%s --service", cmd);
+ _snprintf(cmd_args, sizeof(cmd_args)-1, "%s --service", cmd);
cmd_args[sizeof(cmd_args)-1] = 0;
newService = CreateService(
@@ -194,12 +206,31 @@ void InstallService(void)
"Box Backup",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START,
+ SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
cmd_args,
0,0,0,0,0);
- if (newService) CloseServiceHandle(newService);
+ if (!newService)
+ {
+ ::syslog(LOG_ERR, "Failed to create Box Backup service: "
+ "error %d", GetLastError());
+ return;
+ }
+
+ ::syslog(LOG_INFO, "Created Box Backup service");
+
+ SERVICE_DESCRIPTION desc;
+ desc.lpDescription = "Backs up your data files over the Internet";
+
+ if (!ChangeServiceConfig2(newService, SERVICE_CONFIG_DESCRIPTION,
+ &desc))
+ {
+ ::syslog(LOG_WARNING, "Failed to set description for "
+ "Box Backup service: error %d", GetLastError());
+ }
+
+ CloseServiceHandle(newService);
CloseServiceHandle(scm);
}
@@ -210,23 +241,31 @@ void RemoveService(void)
scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
- if (!scm) return;
+ if (!scm)
+ {
+ syslog(LOG_ERR, "Failed to open service control manager: "
+ "error %d", GetLastError());
+ return;
+ }
service = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS|DELETE);
ControlService(service, SERVICE_CONTROL_STOP, &status);
if (!service)
{
- printf("Failed to open service manager");
+ syslog(LOG_ERR, "Failed to open Box Backup service: "
+ "error %d", GetLastError());
return;
}
+
if (DeleteService(service))
{
- printf("Service removed");
+ syslog(LOG_INFO, "Box Backup service deleted");
}
else
{
- printf("Failed to remove service");
+ syslog(LOG_ERR, "Failed to remove Box Backup service: "
+ "error %d", GetLastError());
}
CloseServiceHandle(service);
diff --git a/bin/bbackupd/bbackupd.cpp b/bin/bbackupd/bbackupd.cpp
index 1c870317..089b2d09 100644
--- a/bin/bbackupd/bbackupd.cpp
+++ b/bin/bbackupd/bbackupd.cpp
@@ -48,13 +48,19 @@ int main(int argc, const char *argv[])
InstallService();
return 0;
}
-
+
+ bool runAsWin32Service = false;
+ if (argc == 2 && ::strcmp(argv[1], "--service") == 0)
+ {
+ runAsWin32Service = true;
+ }
+
// Under win32 we must initialise the Winsock library
// before using sockets
WSADATA info;
- if (WSAStartup(MAKELONG(1, 1), &info) == SOCKET_ERROR)
+ if (WSAStartup(0x0101, &info) == SOCKET_ERROR)
{
// box backup will not run without sockets
::syslog(LOG_ERR, "Failed to initialise Windows Sockets");
@@ -65,7 +71,7 @@ int main(int argc, const char *argv[])
int ExitCode = 0;
- if (argc == 2 && ::strcmp(argv[1], "--service") == 0)
+ if (runAsWin32Service)
{
syslog(LOG_INFO,"Starting Box Backup Service");
OurService();
diff --git a/bin/bbackupquery/BackupQueries.cpp b/bin/bbackupquery/BackupQueries.cpp
index 473daaf6..916228c3 100644
--- a/bin/bbackupquery/BackupQueries.cpp
+++ b/bin/bbackupquery/BackupQueries.cpp
@@ -9,15 +9,21 @@
#include "Box.h"
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
#include <string.h>
#include <stdio.h>
-#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <dirent.h>
+
+#ifdef HAVE_DIRENT_H
+ #include <dirent.h>
+#endif
#include <set>
@@ -246,8 +252,9 @@ void BackupQueries::DoCommand(const char *Command)
case COMMAND_pwd:
{
// Simple implementation, so do it here
- std::string dir(GetCurrentDirectoryName());
- printf("%s (%08llx)\n", dir.c_str(), GetCurrentDirectoryID());
+ printf("%s (%08llx)\n",
+ GetCurrentDirectoryName().c_str(),
+ (long long)GetCurrentDirectoryID());
}
break;
@@ -325,11 +332,23 @@ void BackupQueries::CommandList(const std::vector<std::string> &args, const bool
// Got a directory in the arguments?
if(args.size() > 0)
{
+#ifdef WIN32
+ std::string storeDirEncoded;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), storeDirEncoded))
+ return;
+#else
+ const std::string& storeDirEncoded(args[0]);
+#endif
+
// Attempt to find the directory
- rootDir = FindDirectoryObjectID(args[0], opts[LIST_OPTION_ALLOWOLD], opts[LIST_OPTION_ALLOWDELETED]);
+ rootDir = FindDirectoryObjectID(storeDirEncoded,
+ opts[LIST_OPTION_ALLOWOLD],
+ opts[LIST_OPTION_ALLOWDELETED]);
+
if(rootDir == 0)
{
- printf("Directory %s not found on store\n", args[0].c_str());
+ printf("Directory '%s' not found on store\n",
+ args[0].c_str());
return;
}
}
@@ -373,19 +392,16 @@ void BackupQueries::List(int64_t DirID, const std::string &rListRoot, const bool
{
// Display this entry
BackupStoreFilenameClear clear(en->GetName());
- std::string line;
// Object ID?
if(!opts[LIST_OPTION_NOOBJECTID])
{
// add object ID to line
- char oid[32];
-#ifdef WIN32
- sprintf(oid, "%08I64x ", en->GetObjectID());
+#ifdef _MSC_VER
+ printf("%08I64x ", (int64_t)en->GetObjectID());
#else
- sprintf(oid, "%08llx ", en->GetObjectID());
+ printf("%08llx ", (long long)en->GetObjectID());
#endif
- line += oid;
}
// Flags?
@@ -412,57 +428,71 @@ void BackupQueries::List(int64_t DirID, const std::string &rListRoot, const bool
// terminate
*(f++) = ' ';
*(f++) = '\0';
- line += displayflags;
+ printf(displayflags);
+
if(en_flags != 0)
{
- line += "[ERROR: Entry has additional flags set] ";
+ printf("[ERROR: Entry has additional flags set] ");
}
}
if(opts[LIST_OPTION_TIMES])
{
// Show times...
- line += BoxTimeToISO8601String(en->GetModificationTime());
- line += ' ';
+ std::string time = BoxTimeToISO8601String(
+ en->GetModificationTime());
+ printf("%s ", time.c_str());
}
if(opts[LIST_OPTION_DISPLAY_HASH])
{
- char hash[64];
-#ifdef WIN32
- ::sprintf(hash, "%016I64x ", en->GetAttributesHash());
+#ifdef _MSC_VER
+ printf("%016I64x ", (int64_t)en->GetAttributesHash());
#else
- ::sprintf(hash, "%016llx ", en->GetAttributesHash());
+ printf("%016llx ", (long long)en->GetAttributesHash());
#endif
- line += hash;
}
if(opts[LIST_OPTION_SIZEINBLOCKS])
{
- char num[32];
-#ifdef WIN32
- sprintf(num, "%05I64d ", en->GetSizeInBlocks());
+#ifdef _MSC_VER
+ printf("%05I64d ", (int64_t)en->GetSizeInBlocks());
#else
- sprintf(num, "%05lld ", en->GetSizeInBlocks());
+ printf("%05lld ", (long long)en->GetSizeInBlocks());
#endif
- line += num;
}
// add name
if(!FirstLevel)
{
- line += rListRoot;
- line += '/';
+#ifdef WIN32
+ std::string listRootDecoded;
+ if(!ConvertUtf8ToConsole(rListRoot.c_str(),
+ listRootDecoded)) return;
+ printf("%s/", listRootDecoded.c_str());
+#else
+ printf("%s/", rListRoot.c_str());
+#endif
}
- line += clear.GetClearFilename().c_str();
- if(!en->GetName().IsEncrypted())
+#ifdef WIN32
{
- line += "[FILENAME NOT ENCRYPTED]";
+ std::string fileName;
+ if(!ConvertUtf8ToConsole(
+ clear.GetClearFilename().c_str(), fileName))
+ return;
+ printf("%s", fileName.c_str());
}
+#else
+ printf("%s", clear.GetClearFilename().c_str());
+#endif
- // print line
- printf("%s\n", line.c_str());
+ if(!en->GetName().IsEncrypted())
+ {
+ printf("[FILENAME NOT ENCRYPTED]");
+ }
+
+ printf("\n");
// Directory?
if((en->GetFlags() & BackupStoreDirectory::Entry::Flags_Dir) != 0)
@@ -495,7 +525,7 @@ int64_t BackupQueries::FindDirectoryObjectID(const std::string &rDirName, bool A
{
// Split up string into elements
std::vector<std::string> dirElements;
- SplitString(rDirName, DIRECTORY_SEPARATOR_ASCHAR, dirElements);
+ SplitString(rDirName, '/', dirElements);
// Start from current stack, or root, whichever is required
std::vector<std::pair<std::string, int64_t> > stack;
@@ -629,7 +659,14 @@ std::string BackupQueries::GetCurrentDirectoryName()
for(unsigned int l = 0; l < mDirStack.size(); ++l)
{
r += "/";
+#ifdef WIN32
+ std::string dirName;
+ if(!ConvertUtf8ToConsole(mDirStack[l].first.c_str(), dirName))
+ return "error";
+ r += dirName;
+#else
r += mDirStack[l].first;
+#endif
}
return r;
@@ -651,9 +688,17 @@ void BackupQueries::CommandChangeDir(const std::vector<std::string> &args, const
printf("Incorrect usage.\ncd [-o] [-d] <directory>\n");
return;
}
+
+#ifdef WIN32
+ std::string dirName;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), dirName)) return;
+#else
+ const std::string& dirName(args[0]);
+#endif
std::vector<std::pair<std::string, int64_t> > newStack;
- int64_t id = FindDirectoryObjectID(args[0], opts['o'], opts['d'], &newStack);
+ int64_t id = FindDirectoryObjectID(dirName, opts['o'], opts['d'],
+ &newStack);
if(id == 0)
{
@@ -683,7 +728,14 @@ void BackupQueries::CommandChangeLocalDir(const std::vector<std::string> &args)
}
// Try changing directory
- if(::chdir(args[0].c_str()) != 0)
+#ifdef WIN32
+ std::string dirName;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), dirName)) return;
+ int result = ::chdir(dirName.c_str());
+#else
+ int result = ::chdir(args[0].c_str());
+#endif
+ if(result != 0)
{
printf((errno == ENOENT || errno == ENOTDIR)?"Directory '%s' does not exist\n":"Error changing dir to '%s'\n",
args[0].c_str());
@@ -697,8 +749,13 @@ void BackupQueries::CommandChangeLocalDir(const std::vector<std::string> &args)
printf("Error getting current directory\n");
return;
}
-
+
+#ifdef WIN32
+ if(!ConvertUtf8ToConsole(wd, dirName)) return;
+ printf("Local current directory is now '%s'\n", dirName.c_str());
+#else
printf("Local current directory is now '%s'\n", wd);
+#endif
}
@@ -826,7 +883,14 @@ void BackupQueries::CommandGet(const std::vector<std::string> &args, const bool
{
// Specified by name, find the object in the directory to get the ID
BackupStoreDirectory::Iterator i(dir);
+#ifdef WIN32
+ std::string fileName;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), fileName))
+ return;
+ BackupStoreFilenameClear fn(fileName);
+#else
BackupStoreFilenameClear fn(args[0]);
+#endif
BackupStoreDirectory::Entry *en = i.FindMatchingClearName(fn);
if(en == 0)
@@ -868,7 +932,7 @@ void BackupQueries::CommandGet(const std::vector<std::string> &args, const bool
}
catch(...)
{
- ::unlink(args[1].c_str());
+ ::unlink(localName.c_str());
printf("Error occured fetching file.\n");
}
}
@@ -962,7 +1026,7 @@ void BackupQueries::CommandCompare(const std::vector<std::string> &args, const b
}
else
{
- printf("Warning: couldn't determine the time of the last syncronisation -- checks not performed.\n");
+ printf("Warning: couldn't determine the time of the last synchronisation -- checks not performed.\n");
}
}
@@ -1049,7 +1113,7 @@ void BackupQueries::CompareLocation(const std::string &rLocation, BackupQueries:
}
// Then get it compared
- Compare(std::string(DIRECTORY_SEPARATOR) + rLocation,
+ Compare(std::string("/") + rLocation,
loc.GetKeyValue("Path"), rParams);
}
catch(...)
@@ -1074,32 +1138,62 @@ void BackupQueries::CompareLocation(const std::string &rLocation, BackupQueries:
// --------------------------------------------------------------------------
void BackupQueries::Compare(const std::string &rStoreDir, const std::string &rLocalDir, BackupQueries::CompareParams &rParams)
{
+#ifdef WIN32
+ std::string storeDirEncoded;
+ if(!ConvertConsoleToUtf8(rStoreDir.c_str(), storeDirEncoded)) return;
+#else
+ const std::string& storeDirEncoded(rStoreDir);
+#endif
+
// Get the directory ID of the directory -- only use current data
- int64_t dirID = FindDirectoryObjectID(rStoreDir);
+ int64_t dirID = FindDirectoryObjectID(storeDirEncoded);
// Found?
if(dirID == 0)
{
- printf("Local directory '%s' exists, but server directory '%s' does not exist\n", rLocalDir.c_str(), rStoreDir.c_str());
+ printf("Local directory '%s' exists, but "
+ "server directory '%s' does not exist\n",
+ rLocalDir.c_str(), rStoreDir.c_str());
rParams.mDifferences ++;
return;
}
+
+#ifdef WIN32
+ std::string localDirEncoded;
+ if(!ConvertConsoleToUtf8(rLocalDir.c_str(), localDirEncoded)) return;
+#else
+ std::string localDirEncoded(rLocalDir);
+#endif
// Go!
- Compare(dirID, rStoreDir, rLocalDir, rParams);
+ Compare(dirID, storeDirEncoded, localDirEncoded, rParams);
}
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupQueries::Compare(int64_t, const std::string &, BackupQueries::CompareParams &)
+// Name: BackupQueries::Compare(int64_t, const std::string &,
+// const std::string &, BackupQueries::CompareParams &)
// Purpose: Compare a store directory against a local directory
// Created: 2003/10/13
//
// --------------------------------------------------------------------------
void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const std::string &rLocalDir, BackupQueries::CompareParams &rParams)
{
+#ifdef WIN32
+ // By this point, rStoreDir and rLocalDir should be in UTF-8 encoding
+
+ std::string localName;
+ std::string storeName;
+
+ if(!ConvertUtf8ToConsole(rLocalDir.c_str(), localName)) return;
+ if(!ConvertUtf8ToConsole(rStoreDir.c_str(), storeName)) return;
+#else
+ const std::string& localName(rLocalDir);
+ const std::string& storeName(rStoreDir);
+#endif
+
// Get info on the local directory
struct stat st;
if(::lstat(rLocalDir.c_str(), &st) != 0)
@@ -1107,16 +1201,21 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// What kind of error?
if(errno == ENOTDIR)
{
- printf("Local object '%s' is a file, server object '%s' is a directory\n", rLocalDir.c_str(), rStoreDir.c_str());
+ printf("Local object '%s' is a file, "
+ "server object '%s' is a directory\n",
+ localName.c_str(), storeName.c_str());
rParams.mDifferences ++;
}
else if(errno == ENOENT)
{
- printf("Local directory '%s' does not exist (compared to server directory '%s')\n", rLocalDir.c_str(), rStoreDir.c_str());
+ printf("Local directory '%s' does not exist "
+ "(compared to server directory '%s')\n",
+ localName.c_str(), storeName.c_str());
}
else
{
- printf("ERROR: stat on local dir '%s'\n", rLocalDir.c_str());
+ printf("ERROR: stat on local dir '%s'\n",
+ localName.c_str());
}
return;
}
@@ -1136,7 +1235,8 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// Test out the attributes
if(!dir.HasAttributes())
{
- printf("Store directory '%s' doesn't have attributes.\n", rStoreDir.c_str());
+ printf("Store directory '%s' doesn't have attributes.\n",
+ storeName.c_str());
}
else
{
@@ -1146,12 +1246,14 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// Get attributes of local directory
BackupClientFileAttributes localAttr;
- localAttr.ReadAttributes(rLocalDir.c_str(), true /* directories have zero mod times */);
+ localAttr.ReadAttributes(rLocalDir.c_str(),
+ true /* directories have zero mod times */);
if(!(attr.Compare(localAttr, true, true /* ignore modification times */)))
{
- printf("Local directory '%s' has different attributes to store directory '%s'.\n",
- rLocalDir.c_str(), rStoreDir.c_str());
+ printf("Local directory '%s' has different attributes "
+ "to store directory '%s'.\n",
+ localName.c_str(), storeName.c_str());
rParams.mDifferences ++;
}
}
@@ -1160,7 +1262,7 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
DIR *dirhandle = ::opendir(rLocalDir.c_str());
if(dirhandle == 0)
{
- printf("ERROR: opendir on local dir '%s'\n", rLocalDir.c_str());
+ printf("ERROR: opendir on local dir '%s'\n", localName.c_str());
return;
}
try
@@ -1217,7 +1319,8 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// Close directory
if(::closedir(dirhandle) != 0)
{
- printf("ERROR: closedir on local dir '%s'\n", rLocalDir.c_str());
+ printf("ERROR: closedir on local dir '%s'\n",
+ localName.c_str());
}
dirhandle = 0;
@@ -1244,17 +1347,26 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
storeDirs.insert(std::pair<std::string, BackupStoreDirectory::Entry *>(name.GetClearFilename(), storeDirEn));
}
}
+
+#ifdef _MSC_VER
+ typedef std::set<std::string>::iterator string_set_iter_t;
+#else
+ typedef std::set<std::string>::const_iterator string_set_iter_t;
+#endif
// Now compare files.
for(std::set<std::pair<std::string, BackupStoreDirectory::Entry *> >::const_iterator i = storeFiles.begin(); i != storeFiles.end(); ++i)
{
// Does the file exist locally?
- std::set<std::string>::const_iterator local(localFiles.find(i->first));
+ string_set_iter_t local(localFiles.find(i->first));
if(local == localFiles.end())
{
// Not found -- report
- printf("Local file '%s/%s' does not exist, but store file '%s/%s' does.\n",
- rLocalDir.c_str(), i->first.c_str(), rStoreDir.c_str(), i->first.c_str());
+ printf("Local file '%s" DIRECTORY_SEPARATOR
+ "%s' does not exist, "
+ "but store file '%s/%s' does.\n",
+ localName.c_str(), i->first.c_str(),
+ storeName.c_str(), i->first.c_str());
rParams.mDifferences ++;
}
else
@@ -1320,8 +1432,11 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
true /* ignore attr mod time */,
fileOnServerStream->IsSymLink() /* ignore modification time if it's a symlink */))
{
- printf("Local file '%s/%s' has different attributes to store file '%s/%s'.\n",
- rLocalDir.c_str(), i->first.c_str(), rStoreDir.c_str(), i->first.c_str());
+ printf("Local file '%s"
+ DIRECTORY_SEPARATOR
+ "%s' has different attributes "
+ "to store file '%s/%s'.\n",
+ localName.c_str(), i->first.c_str(), storeName.c_str(), i->first.c_str());
rParams.mDifferences ++;
if(modifiedAfterLastSync)
{
@@ -1385,8 +1500,11 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// Report if not equal.
if(!equal)
{
- printf("Local file '%s/%s' has different contents to store file '%s/%s'.\n",
- rLocalDir.c_str(), i->first.c_str(), rStoreDir.c_str(), i->first.c_str());
+ printf("Local file '%s"
+ DIRECTORY_SEPARATOR
+ "%s' has different contents "
+ "to store file '%s/%s'.\n",
+ localName.c_str(), i->first.c_str(), storeName.c_str(), i->first.c_str());
rParams.mDifferences ++;
if(modifiedAfterLastSync)
{
@@ -1404,11 +1522,12 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
printf("ERROR: (%d/%d) during file fetch and comparsion for '%s/%s'\n",
e.GetType(),
e.GetSubType(),
- rStoreDir.c_str(), i->first.c_str());
+ storeName.c_str(),
+ i->first.c_str());
}
catch(...)
{
- printf("ERROR: (unknown) during file fetch and comparsion for '%s/%s'\n", rStoreDir.c_str(), i->first.c_str());
+ printf("ERROR: (unknown) during file fetch and comparsion for '%s/%s'\n", storeName.c_str(), i->first.c_str());
}
// Remove from set so that we know it's been compared
@@ -1417,20 +1536,25 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
}
// Report any files which exist on the locally, but not on the store
- for(std::set<std::string>::const_iterator i = localFiles.begin(); i != localFiles.end(); ++i)
+ for(string_set_iter_t i = localFiles.begin(); i != localFiles.end(); ++i)
{
- std::string localName(rLocalDir + DIRECTORY_SEPARATOR + *i);
+ std::string localFileName(rLocalDir +
+ DIRECTORY_SEPARATOR + *i);
// Should this be ignored (ie is excluded)?
- if(rParams.mpExcludeFiles == 0 || !(rParams.mpExcludeFiles->IsExcluded(localName)))
+ if(rParams.mpExcludeFiles == 0 ||
+ !(rParams.mpExcludeFiles->IsExcluded(localFileName)))
{
- printf("Local file '%s/%s' exists, but store file '%s/%s' does not exist.\n",
- rLocalDir.c_str(), (*i).c_str(), rStoreDir.c_str(), (*i).c_str());
+ printf("Local file '%s" DIRECTORY_SEPARATOR
+ "%s' exists, but store file '%s/%s' "
+ "does not exist.\n",
+ localName.c_str(), (*i).c_str(),
+ storeName.c_str(), (*i).c_str());
rParams.mDifferences ++;
// Check the file modification time
{
struct stat st;
- if(::stat(localName.c_str(), &st) == 0)
+ if(::stat(localFileName.c_str(), &st) == 0)
{
if(FileModificationTime(st) > rParams.mLatestFileUploadTime)
{
@@ -1454,12 +1578,16 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
for(std::set<std::pair<std::string, BackupStoreDirectory::Entry *> >::const_iterator i = storeDirs.begin(); i != storeDirs.end(); ++i)
{
// Does the directory exist locally?
- std::set<std::string>::const_iterator local(localDirs.find(i->first));
+ string_set_iter_t local(localDirs.find(i->first));
if(local == localDirs.end())
{
// Not found -- report
- printf("Local directory '%s/%s' does not exist, but store directory '%s/%s' does.\n",
- rLocalDir.c_str(), i->first.c_str(), rStoreDir.c_str(), i->first.c_str());
+ printf("Local directory '%s"
+ DIRECTORY_SEPARATOR "%s' "
+ "does not exist, but store directory "
+ "'%s/%s' does.\n",
+ localName.c_str(), i->first.c_str(),
+ storeName.c_str(), i->first.c_str());
rParams.mDifferences ++;
}
else
@@ -1479,8 +1607,10 @@ void BackupQueries::Compare(int64_t DirID, const std::string &rStoreDir, const s
// Should this be ignored (ie is excluded)?
if(rParams.mpExcludeDirs == 0 || !(rParams.mpExcludeDirs->IsExcluded(localName)))
{
- printf("Local directory '%s/%s' exists, but store directory '%s/%s' does not exist.\n",
- rLocalDir.c_str(), (*i).c_str(), rStoreDir.c_str(), (*i).c_str());
+ printf("Local directory '%s/%s' exists, but "
+ "store directory '%s/%s' does not exist.\n",
+ localName.c_str(), (*i).c_str(),
+ storeName.c_str(), (*i).c_str());
rParams.mDifferences ++;
}
else
@@ -1534,14 +1664,24 @@ void BackupQueries::CommandRestore(const std::vector<std::string> &args, const b
}
else
{
+#ifdef WIN32
+ std::string storeDirEncoded;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), storeDirEncoded))
+ return;
+#else
+ const std::string& storeDirEncoded(args[0]);
+#endif
+
// Look up directory ID
- dirID = FindDirectoryObjectID(args[0], false /* no old versions */, restoreDeleted /* find deleted dirs */);
+ dirID = FindDirectoryObjectID(storeDirEncoded,
+ false /* no old versions */,
+ restoreDeleted /* find deleted dirs */);
}
// Allowable?
if(dirID == 0)
{
- printf("Directory %s not found on server\n", args[0].c_str());
+ printf("Directory '%s' not found on server\n", args[0].c_str());
return;
}
if(dirID == BackupProtocolClientListDirectory::RootDirectory)
@@ -1550,9 +1690,18 @@ void BackupQueries::CommandRestore(const std::vector<std::string> &args, const b
return;
}
+#ifdef WIN32
+ std::string localName;
+ if(!ConvertConsoleToUtf8(args[1].c_str(), localName)) return;
+#else
+ std::string localName(args[1]);
+#endif
+
// Go and restore...
- switch(BackupClientRestore(mrConnection, dirID, args[1].c_str(), true /* print progress dots */, restoreDeleted,
- false /* don't undelete after restore! */, opts['r'] /* resume? */))
+ switch(BackupClientRestore(mrConnection, dirID, localName.c_str(),
+ true /* print progress dots */, restoreDeleted,
+ false /* don't undelete after restore! */,
+ opts['r'] /* resume? */))
{
case Restore_Complete:
printf("Restore complete\n");
@@ -1691,26 +1840,29 @@ void BackupQueries::CommandUndelete(const std::vector<std::string> &args, const
return;
}
+#ifdef WIN32
+ std::string storeDirEncoded;
+ if(!ConvertConsoleToUtf8(args[0].c_str(), storeDirEncoded)) return;
+#else
+ const std::string& storeDirEncoded(args[0]);
+#endif
+
// Get directory ID
- int64_t dirID = FindDirectoryObjectID(args[0], false /* no old versions */, true /* find deleted dirs */);
+ int64_t dirID = FindDirectoryObjectID(storeDirEncoded,
+ false /* no old versions */, true /* find deleted dirs */);
// Allowable?
if(dirID == 0)
{
- printf("Directory %s not found on server\n", args[0].c_str());
+ printf("Directory '%s' not found on server\n", args[0].c_str());
return;
}
if(dirID == BackupProtocolClientListDirectory::RootDirectory)
{
- printf("Cannot restore the root directory -- restore locations individually.\n");
+ printf("Cannot undelete the root directory.\n");
return;
}
// Undelete
mrConnection.QueryUndeleteDirectory(dirID);
}
-
-
-
-
-
diff --git a/bin/bbackupquery/bbackupquery.cpp b/bin/bbackupquery/bbackupquery.cpp
index 629f0eeb..abd0177b 100644
--- a/bin/bbackupquery/bbackupquery.cpp
+++ b/bin/bbackupquery/bbackupquery.cpp
@@ -9,7 +9,9 @@
#include "Box.h"
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_LIBREADLINE
@@ -48,8 +50,13 @@
void PrintUsageAndExit()
{
- printf("Usage: bbackupquery [-q] [-c config_file] [-l log_file] [commands]\nAs many commands as you require.\n" \
- "If commands are multiple words, remember to enclose the command in quotes.\n" \
+ printf("Usage: bbackupquery [-q] [-w] "
+#ifdef WIN32
+ "[-u] "
+#endif
+ "\n\t[-c config_file] [-l log_file] [commands]\n"
+ "As many commands as you require.\n"
+ "If commands are multiple words, remember to enclose the command in quotes.\n"
"Remember to use quit command if you don't want to drop into interactive mode.\n");
exit(1);
}
@@ -64,7 +71,7 @@ int main(int argc, const char *argv[])
// Under Win32 we must initialise the Winsock library
// before using it.
- if (WSAStartup(MAKELONG(1, 1), &info) == SOCKET_ERROR)
+ if (WSAStartup(0x0101, &info) == SOCKET_ERROR)
{
// throw error? perhaps give it its own id in the furture
THROW_EXCEPTION(BackupStoreException, Internal)
@@ -88,10 +95,17 @@ int main(int argc, const char *argv[])
// Flags
bool quiet = false;
bool readWrite = false;
-
+
+#ifdef WIN32
+ const char* validOpts = "qwuc:l:";
+ bool unicodeConsole = false;
+#else
+ const char* validOpts = "qwc:l:";
+#endif
+
// See if there's another entry on the command line
int c;
- while((c = getopt(argc, (char * const *)argv, "qwc:l:")) != -1)
+ while((c = getopt(argc, (char * const *)argv, validOpts)) != -1)
{
switch(c)
{
@@ -118,6 +132,12 @@ int main(int argc, const char *argv[])
printf("Can't open log file '%s'\n", optarg);
}
break;
+
+#ifdef WIN32
+ case 'u':
+ unicodeConsole = true;
+ break;
+#endif
case '?':
default:
@@ -135,6 +155,30 @@ int main(int argc, const char *argv[])
printf(banner);
}
+#ifdef WIN32
+ if (unicodeConsole)
+ {
+ if (!SetConsoleCP(CP_UTF8))
+ {
+ fprintf(stderr, "Failed to set input codepage: "
+ "error %d\n", GetLastError());
+ }
+
+ if (!SetConsoleOutputCP(CP_UTF8))
+ {
+ fprintf(stderr, "Failed to set output codepage: "
+ "error %d\n", GetLastError());
+ }
+
+ // enable input of Unicode characters
+ if (_setmode(_fileno(stdin), _O_TEXT) == -1)
+ {
+ perror("Failed to set the console input to "
+ "binary mode");
+ }
+ }
+#endif // WIN32
+
// Read in the configuration file
if(!quiet) printf("Using configuration file %s\n", configFilename);
std::string errs;