summaryrefslogtreecommitdiff
path: root/lib/win32
diff options
context:
space:
mode:
Diffstat (limited to 'lib/win32')
-rw-r--r--lib/win32/WinNamedPipeStream.cpp350
-rw-r--r--lib/win32/WinNamedPipeStream.h98
-rw-r--r--lib/win32/config.h.win32396
-rw-r--r--lib/win32/emu.cpp1267
-rw-r--r--lib/win32/emu.h520
5 files changed, 2631 insertions, 0 deletions
diff --git a/lib/win32/WinNamedPipeStream.cpp b/lib/win32/WinNamedPipeStream.cpp
new file mode 100644
index 00000000..2a27a206
--- /dev/null
+++ b/lib/win32/WinNamedPipeStream.cpp
@@ -0,0 +1,350 @@
+// distribution boxbackup-0.10 (svn version: 494)
+//
+// Copyright (c) 2003 - 2006
+// Ben Summers and contributors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. All use of this software and associated advertising materials must
+// display the following acknowledgment:
+// This product includes software developed by Ben Summers.
+// 4. The names of the Authors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// [Where legally impermissible the Authors do not disclaim liability for
+// direct physical injury or death caused solely by defects in the software
+// unless it is modified by a third party.]
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//
+//
+// --------------------------------------------------------------------------
+//
+// File
+// Name: WinNamedPipeStream.cpp
+// Purpose: I/O stream interface for Win32 named pipes
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#ifdef WIN32
+
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+#include <windows.h>
+
+#include "WinNamedPipeStream.h"
+#include "ServerException.h"
+#include "CommonException.h"
+#include "Socket.h"
+
+#include "MemLeakFindOn.h"
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::WinNamedPipeStream()
+// Purpose: Constructor (create stream ready for Open() call)
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+WinNamedPipeStream::WinNamedPipeStream()
+ : mSocketHandle(NULL),
+ mReadClosed(false),
+ mWriteClosed(false),
+ mIsServer(false),
+ mIsConnected(false)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::~WinNamedPipeStream()
+// Purpose: Destructor, closes stream if open
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+WinNamedPipeStream::~WinNamedPipeStream()
+{
+ if (mSocketHandle != NULL)
+ {
+ Close();
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::Accept(const char* Name)
+// Purpose: Creates a new named pipe with the given name,
+// and wait for a connection on it
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+void WinNamedPipeStream::Accept(const wchar_t* pName)
+{
+ if (mSocketHandle != NULL || mIsConnected)
+ {
+ THROW_EXCEPTION(ServerException, SocketAlreadyOpen)
+ }
+
+ mSocketHandle = CreateNamedPipeW(
+ pName, // pipe name
+ PIPE_ACCESS_DUPLEX, // read/write access
+ PIPE_TYPE_MESSAGE | // message type pipe
+ PIPE_READMODE_MESSAGE | // message-read mode
+ PIPE_WAIT, // blocking mode
+ 1, // max. instances
+ 4096, // output buffer size
+ 4096, // input buffer size
+ NMPWAIT_USE_DEFAULT_WAIT, // client time-out
+ NULL); // default security attribute
+
+ if (mSocketHandle == NULL)
+ {
+ ::syslog(LOG_ERR, "CreateNamedPipeW failed: %d",
+ GetLastError());
+ THROW_EXCEPTION(ServerException, SocketOpenError)
+ }
+
+ bool connected = ConnectNamedPipe(mSocketHandle, (LPOVERLAPPED) NULL);
+
+ if (!connected)
+ {
+ ::syslog(LOG_ERR, "ConnectNamedPipe failed: %d",
+ GetLastError());
+ Close();
+ THROW_EXCEPTION(ServerException, SocketOpenError)
+ }
+
+ mReadClosed = false;
+ mWriteClosed = false;
+ mIsServer = true; // must flush and disconnect before closing
+ mIsConnected = true;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::Connect(const char* Name)
+// Purpose: Opens a connection to a listening named pipe
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+void WinNamedPipeStream::Connect(const wchar_t* pName)
+{
+ if (mSocketHandle != NULL || mIsConnected)
+ {
+ THROW_EXCEPTION(ServerException, SocketAlreadyOpen)
+ }
+
+ mSocketHandle = CreateFileW(
+ pName, // pipe name
+ GENERIC_READ | // read and write access
+ GENERIC_WRITE,
+ 0, // no sharing
+ NULL, // default security attributes
+ OPEN_EXISTING,
+ 0, // default attributes
+ NULL); // no template file
+
+ if (mSocketHandle == INVALID_HANDLE_VALUE)
+ {
+ ::syslog(LOG_ERR, "Failed to connect to server's named pipe: "
+ "error %d", GetLastError());
+ THROW_EXCEPTION(ServerException, SocketOpenError)
+ }
+
+ mReadClosed = false;
+ mWriteClosed = false;
+ mIsServer = false; // just close the socket
+ mIsConnected = true;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::Read(void *pBuffer, int NBytes)
+// Purpose: Reads data from stream. Maybe returns less than asked for.
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+int WinNamedPipeStream::Read(void *pBuffer, int NBytes, int Timeout)
+{
+ // TODO no support for timeouts yet
+ ASSERT(Timeout == IOStream::TimeOutInfinite)
+
+ if (mSocketHandle == NULL || !mIsConnected)
+ {
+ THROW_EXCEPTION(ServerException, BadSocketHandle)
+ }
+
+ DWORD NumBytesRead;
+
+ bool Success = ReadFile(
+ mSocketHandle, // pipe handle
+ pBuffer, // buffer to receive reply
+ NBytes, // size of buffer
+ &NumBytesRead, // number of bytes read
+ NULL); // not overlapped
+
+ if (!Success)
+ {
+ THROW_EXCEPTION(ConnectionException, Conn_SocketReadError)
+ }
+
+ // Closed for reading at EOF?
+ if (NumBytesRead == 0)
+ {
+ mReadClosed = true;
+ }
+
+ return NumBytesRead;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::Write(void *pBuffer, int NBytes)
+// Purpose: Writes data, blocking until it's all done.
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void WinNamedPipeStream::Write(const void *pBuffer, int NBytes)
+{
+ if (mSocketHandle == NULL || !mIsConnected)
+ {
+ THROW_EXCEPTION(ServerException, BadSocketHandle)
+ }
+
+ // Buffer in byte sized type.
+ ASSERT(sizeof(char) == 1);
+ const char *pByteBuffer = (char *)pBuffer;
+
+ int NumBytesWrittenTotal = 0;
+
+ while (NumBytesWrittenTotal < NBytes)
+ {
+ DWORD NumBytesWrittenThisTime = 0;
+
+ bool Success = WriteFile(
+ mSocketHandle, // pipe handle
+ pByteBuffer + NumBytesWrittenTotal, // message
+ NBytes - NumBytesWrittenTotal, // message length
+ &NumBytesWrittenThisTime, // bytes written this time
+ NULL); // not overlapped
+
+ if (!Success)
+ {
+ mWriteClosed = true; // assume can't write again
+ THROW_EXCEPTION(ConnectionException,
+ Conn_SocketWriteError)
+ }
+
+ NumBytesWrittenTotal += NumBytesWrittenThisTime;
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::Close()
+// Purpose: Closes connection to remote socket
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void WinNamedPipeStream::Close()
+{
+ if (mSocketHandle == NULL && mIsConnected)
+ {
+ fprintf(stderr, "Inconsistent connected state\n");
+ ::syslog(LOG_ERR, "Inconsistent connected state");
+ mIsConnected = false;
+ }
+
+ if (mSocketHandle == NULL)
+ {
+ THROW_EXCEPTION(ServerException, BadSocketHandle)
+ }
+
+ if (mIsServer)
+ {
+ if (!FlushFileBuffers(mSocketHandle))
+ {
+ ::syslog(LOG_INFO, "FlushFileBuffers failed: %d",
+ GetLastError());
+ }
+
+ if (!DisconnectNamedPipe(mSocketHandle))
+ {
+ ::syslog(LOG_ERR, "DisconnectNamedPipe failed: %d",
+ GetLastError());
+ }
+
+ mIsServer = false;
+ }
+
+ bool result = CloseHandle(mSocketHandle);
+
+ mSocketHandle = NULL;
+ mIsConnected = false;
+
+ if (!result)
+ {
+ ::syslog(LOG_ERR, "CloseHandle failed: %d", GetLastError());
+ THROW_EXCEPTION(ServerException, SocketCloseError)
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::StreamDataLeft()
+// Purpose: Still capable of reading data?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool WinNamedPipeStream::StreamDataLeft()
+{
+ return !mReadClosed;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: WinNamedPipeStream::StreamClosed()
+// Purpose: Connection been closed?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool WinNamedPipeStream::StreamClosed()
+{
+ return mWriteClosed;
+}
+
+#endif // WIN32
diff --git a/lib/win32/WinNamedPipeStream.h b/lib/win32/WinNamedPipeStream.h
new file mode 100644
index 00000000..4779de08
--- /dev/null
+++ b/lib/win32/WinNamedPipeStream.h
@@ -0,0 +1,98 @@
+// distribution boxbackup-0.10 (svn version: 494)
+//
+// Copyright (c) 2003 - 2006
+// Ben Summers and contributors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. All use of this software and associated advertising materials must
+// display the following acknowledgment:
+// This product includes software developed by Ben Summers.
+// 4. The names of the Authors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// [Where legally impermissible the Authors do not disclaim liability for
+// direct physical injury or death caused solely by defects in the software
+// unless it is modified by a third party.]
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//
+//
+// --------------------------------------------------------------------------
+//
+// File
+// Name: WinNamedPipeStream.h
+// Purpose: I/O stream interface for Win32 named pipes
+// Created: 2005/12/07
+//
+// --------------------------------------------------------------------------
+
+#if ! defined WINNAMEDPIPESTREAM__H && defined WIN32
+#define WINNAMEDPIPESTREAM__H
+
+#include "IOStream.h"
+
+// --------------------------------------------------------------------------
+//
+// Class
+// Name: WinNamedPipeStream
+// Purpose: I/O stream interface for Win32 named pipes
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+class WinNamedPipeStream : public IOStream
+{
+public:
+ WinNamedPipeStream();
+ ~WinNamedPipeStream();
+
+ // server side - create the named pipe and listen for connections
+ void Accept(const wchar_t* Name);
+
+ // client side - connect to a waiting server
+ void Connect(const wchar_t* Name);
+
+ // both sides
+ virtual int Read(void *pBuffer, int NBytes,
+ int Timeout = IOStream::TimeOutInfinite);
+ virtual void Write(const void *pBuffer, int NBytes);
+ virtual void Close();
+ virtual bool StreamDataLeft();
+ virtual bool StreamClosed();
+ bool IsConnected() { return mIsConnected; }
+
+protected:
+ HANDLE GetSocketHandle();
+ void MarkAsReadClosed() {mReadClosed = true;}
+ void MarkAsWriteClosed() {mWriteClosed = true;}
+
+private:
+ WinNamedPipeStream(const WinNamedPipeStream &rToCopy)
+ { /* do not call */ }
+
+ HANDLE mSocketHandle;
+ bool mReadClosed;
+ bool mWriteClosed;
+ bool mIsServer;
+ bool mIsConnected;
+};
+
+#endif // WINNAMEDPIPESTREAM__H
diff --git a/lib/win32/config.h.win32 b/lib/win32/config.h.win32
new file mode 100644
index 00000000..42298545
--- /dev/null
+++ b/lib/win32/config.h.win32
@@ -0,0 +1,396 @@
+/* lib/common/BoxConfig.h. Generated by configure. */
+/* lib/common/BoxConfig.h.in. Generated from configure.ac by autoheader. */
+/* Hacked by hand to work for MSVC by Chris Wilson */
+
+/* Define to major version for BDB_VERSION */
+/* #undef BDB_VERSION_MAJOR */
+
+/* Define to minor version for BDB_VERSION */
+/* #undef BDB_VERSION_MINOR */
+
+/* Define to point version for BDB_VERSION */
+/* #undef BDB_VERSION_POINT */
+
+/* Name of the 64 bit endian swapping function */
+/* #undef BSWAP64 */
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#define CLOSEDIR_VOID 1
+
+/* Define to 1 if non-aligned int16 access will fail */
+/* #undef HAVE_ALIGNED_ONLY_INT16 */
+
+/* Define to 1 if non-aligned int32 access will fail */
+/* #undef HAVE_ALIGNED_ONLY_INT32 */
+
+/* Define to 1 if non-aligned int64 access will fail */
+/* #undef HAVE_ALIGNED_ONLY_INT64 */
+
+/* Define to 1 if you have the <asm/byteorder.h> header file. */
+/* #undef HAVE_ASM_BYTEORDER_H */
+
+/* Define to 1 if BSWAP64 is defined to the name of a valid 64 bit endian
+ swapping function */
+/* #undef HAVE_BSWAP64 */
+
+/* Define to 1 if you have the <db.h> header file. */
+/* #undef HAVE_DB_H */
+
+/* Define to 1 if you have the declaration of `F_SETLK', and to 0 if you
+ don't. */
+#define HAVE_DECL_F_SETLK 0
+
+/* Define to 1 if you have the declaration of `INFTIM', and to 0 if you don't.
+ */
+#define HAVE_DECL_INFTIM 0
+
+/* Define to 1 if you have the declaration of `O_EXLOCK', and to 0 if you
+ don't. */
+#define HAVE_DECL_O_EXLOCK 0
+
+/* Define to 1 if you have the declaration of `SO_PEERCRED', and to 0 if you
+ don't. */
+#define HAVE_DECL_SO_PEERCRED 0
+
+/* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if
+ you don't. */
+#define HAVE_DECL_XATTR_NOFOLLOW 0
+
+/* Define to 1 if #define of pragmas works */
+/* #undef HAVE_DEFINE_PRAGMA */
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_DIRENT_H */
+
+/* Define to 1 if you have the <editline/readline.h> header file. */
+/* #undef HAVE_EDITLINE_READLINE_H */
+
+/* define if the compiler supports exceptions */
+#define HAVE_EXCEPTIONS
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+/* #undef HAVE_EXECINFO_H */
+
+/* Define to 1 if you have the `flock' function. */
+/* #undef HAVE_FLOCK */
+
+/* Define to 1 if you have the `getmntent' function. */
+/* #undef HAVE_GETMNTENT */
+
+/* Define to 1 if you have the `getpeereid' function. */
+/* #undef HAVE_GETPEEREID */
+
+/* Define to 1 if you have the `getpid' function. */
+#define HAVE_GETPID 1
+
+/* Define to 1 if you have the `getxattr' function. */
+/* #undef HAVE_GETXATTR */
+
+/* Define to 1 if you have the <history.h> header file. */
+/* #undef HAVE_HISTORY_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+// #define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `kqueue' function. */
+/* #undef HAVE_KQUEUE */
+
+/* Define to 1 if you have the `lchown' function. */
+/* #undef HAVE_LCHOWN */
+
+/* Define to 1 if you have the `lgetxattr' function. */
+/* #undef HAVE_LGETXATTR */
+
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#define HAVE_LIBCRYPTO 1
+
+/* Define if you have a readline compatible library */
+/* #undef HAVE_LIBREADLINE */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#define HAVE_LIBSSL 1
+
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the `listxattr' function. */
+/* #undef HAVE_LISTXATTR */
+
+/* Define to 1 if you have the `llistxattr' function. */
+/* #undef HAVE_LLISTXATTR */
+
+/* Define to 1 if syscall lseek requires a dummy middle parameter */
+/* #undef HAVE_LSEEK_DUMMY_PARAM */
+
+/* Define to 1 if you have the `lsetxattr' function. */
+/* #undef HAVE_LSETXATTR */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <mntent.h> header file. */
+/* #undef HAVE_MNTENT_H */
+
+/* Define to 1 if this platform supports mounts */
+/* #undef HAVE_MOUNTS */
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+/* #undef HAVE_NETINET_IN_H */
+
+/* Define to 1 if SSL is pre-0.9.7 */
+/* #undef HAVE_OLD_SSL */
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <process.h> header file. */
+#define HAVE_PROCESS_H 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 (and set RANDOM_DEVICE) if a random device is available */
+/* #undef HAVE_RANDOM_DEVICE */
+
+/* Define to 1 if you have the <readline.h> header file. */
+/* #undef HAVE_READLINE_H */
+
+/* Define if your readline library has add_history */
+/* #undef HAVE_READLINE_HISTORY */
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+/* #undef HAVE_READLINE_HISTORY_H */
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+/* #undef HAVE_READLINE_READLINE_H */
+
+/* Define to 1 if you have the <regex.h> header file. */
+// #define HAVE_REGEX_H 1
+
+/* Define to 1 if you have the `setproctitle' function. */
+/* #undef HAVE_SETPROCTITLE */
+
+/* Define to 1 if you have the `setxattr' function. */
+/* #undef HAVE_SETXATTR */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if SSL is available */
+#define HAVE_SSL 1
+
+/* Define to 1 if you have the `statfs' function. */
+/* #undef HAVE_STATFS */
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+/* #undef HAVE_STAT_EMPTY_STRING_BUG */
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+// #define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if `d_type' is member of `struct dirent'. */
+/* #undef HAVE_STRUCT_DIRENT_D_TYPE */
+
+/* Define to 1 if `mnt_dir' is member of `struct mntent'. */
+/* #undef HAVE_STRUCT_MNTENT_MNT_DIR */
+
+/* Define to 1 if `mnt_mountp' is member of `struct mnttab'. */
+/* #undef HAVE_STRUCT_MNTTAB_MNT_MOUNTP */
+
+/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */
+/* #undef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+
+/* Define to 1 if `f_mntonname' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_MNTONNAME */
+
+/* Define to 1 if `st_flags' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_FLAGS */
+
+/* Define to 1 if `st_mtimespec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_MTIMESPEC */
+
+/* Define to 1 if you have the `syscall' function. */
+/* #undef HAVE_SYSCALL */
+
+/* Define to 1 if you have the <syslog.h> header file. */
+/* #undef HAVE_SYSLOG_H */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+/* #undef HAVE_SYS_ENDIAN_H */
+
+/* Define to 1 if you have the <sys/mnttab.h> header file. */
+/* #undef HAVE_SYS_MNTTAB_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+/* #undef HAVE_SYS_MOUNT_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+// #define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+/* #undef HAVE_SYS_SYSCALL_H */
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+// #define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+/* #undef HAVE_SYS_XATTR_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#define HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#define HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#define HAVE_UINT8_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+// #define HAVE_UNISTD_H 1
+
+/* Define to 1 if the system has the type `u_int16_t'. */
+/* #undef HAVE_U_INT16_T */
+
+/* Define to 1 if the system has the type `u_int32_t'. */
+/* #undef HAVE_U_INT32_T */
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+/* #undef HAVE_U_INT64_T */
+
+/* Define to 1 if the system has the type `u_int8_t'. */
+/* #undef HAVE_U_INT8_T */
+
+/* Define to 1 if struct dirent.d_type is valid */
+/* #undef HAVE_VALID_DIRENT_D_TYPE */
+
+/* Define to 1 if the system has the type `_Bool'. */
+/* #undef HAVE__BOOL */
+
+/* Define to 1 if you have the `__syscall' function. */
+/* #undef HAVE___SYSCALL */
+
+/* Define to 1 if __syscall is available but needs a definition */
+/* #undef HAVE___SYSCALL_NEED_DEFN */
+
+/* max value of long long calculated by configure */
+/* #undef LLONG_MAX */
+
+/* min value of long long calculated by configure */
+/* #undef LLONG_MIN */
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "box@fluffy.co.uk"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Box Backup"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Box Backup 0.09"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "box-backup"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.09"
+
+/* Define to the filename of the random device (and set HAVE_RANDOM_DEVICE) */
+/* #undef RANDOM_DEVICE */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* TMP directory name */
+#define TEMP_DIRECTORY_NAME "/tmp"
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to 1 if __USE_MALLOC is required work around STL memory leaks */
+/* #undef __USE_MALLOC */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#define gid_t int
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef mode_t */
+
+/* Define to `long' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#define uid_t int
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp
new file mode 100644
index 00000000..c3c0b6f2
--- /dev/null
+++ b/lib/win32/emu.cpp
@@ -0,0 +1,1267 @@
+// distribution boxbackup-0.10 (svn version: 494)
+//
+// Copyright (c) 2003 - 2006
+// Ben Summers and contributors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. All use of this software and associated advertising materials must
+// display the following acknowledgment:
+// This product includes software developed by Ben Summers.
+// 4. The names of the Authors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// [Where legally impermissible the Authors do not disclaim liability for
+// direct physical injury or death caused solely by defects in the software
+// unless it is modified by a third party.]
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//
+//
+// Box Backup Win32 native port by Nick Knight
+
+// Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW
+#define WINVER 0x0500
+
+#include "Box.h"
+
+#ifdef WIN32
+
+// #include "emu.h"
+
+#include <windows.h>
+#include <fcntl.h>
+// #include <atlenc.h>
+
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+#ifdef HAVE_PROCESS_H
+ #include <process.h>
+#endif
+
+#include <string>
+#include <list>
+
+// our implementation for a timer, based on a
+// simple thread which sleeps for a period of time
+
+static bool gFinishTimer;
+static CRITICAL_SECTION gLock;
+
+typedef struct
+{
+ int countDown;
+ int interval;
+}
+Timer_t;
+
+std::list<Timer_t> gTimerList;
+static void (__cdecl *gTimerFunc) (int) = NULL;
+
+int setitimer(int type, struct itimerval *timeout, void *arg)
+{
+ if (ITIMER_VIRTUAL == type)
+ {
+ EnterCriticalSection(&gLock);
+ // we only need seconds for the mo!
+ if (timeout->it_value.tv_sec == 0 &&
+ timeout->it_value.tv_usec == 0)
+ {
+ gTimerList.clear();
+ }
+ else
+ {
+ Timer_t ourTimer;
+ ourTimer.countDown = timeout->it_value.tv_sec;
+ ourTimer.interval = timeout->it_interval.tv_sec;
+ gTimerList.push_back(ourTimer);
+ }
+ LeaveCriticalSection(&gLock);
+ }
+
+ // indicate success
+ return 0;
+}
+
+static unsigned int WINAPI RunTimer(LPVOID lpParameter)
+{
+ gFinishTimer = false;
+
+ while (!gFinishTimer)
+ {
+ std::list<Timer_t>::iterator it;
+ EnterCriticalSection(&gLock);
+
+ for (it = gTimerList.begin(); it != gTimerList.end(); it++)
+ {
+ Timer_t& rTimer(*it);
+
+ rTimer.countDown --;
+ if (rTimer.countDown == 0)
+ {
+ if (gTimerFunc != NULL)
+ {
+ gTimerFunc(0);
+ }
+ if (rTimer.interval)
+ {
+ rTimer.countDown = rTimer.interval;
+ }
+ else
+ {
+ // mark for deletion
+ rTimer.countDown = -1;
+ }
+ }
+ }
+
+ for (it = gTimerList.begin(); it != gTimerList.end(); it++)
+ {
+ Timer_t& rTimer(*it);
+
+ if (rTimer.countDown == -1)
+ {
+ gTimerList.erase(it);
+
+ // the iterator is now invalid, so restart search
+ it = gTimerList.begin();
+
+ // if the list is now empty, don't try to increment
+ // the iterator again
+ if (it == gTimerList.end()) break;
+ }
+ }
+
+ LeaveCriticalSection(&gLock);
+ // we only need to have a 1 second resolution
+ Sleep(1000);
+ }
+
+ return 0;
+}
+
+int SetTimerHandler(void (__cdecl *func ) (int))
+{
+ gTimerFunc = func;
+ return 0;
+}
+
+void InitTimer(void)
+{
+ InitializeCriticalSection(&gLock);
+
+ // create our thread
+ HANDLE ourThread = (HANDLE)_beginthreadex(NULL, 0, RunTimer, 0,
+ CREATE_SUSPENDED, NULL);
+ SetThreadPriority(ourThread, THREAD_PRIORITY_LOWEST);
+ ResumeThread(ourThread);
+}
+
+void FiniTimer(void)
+{
+ gFinishTimer = true;
+ EnterCriticalSection(&gLock);
+ DeleteCriticalSection(&gLock);
+}
+
+//Our constants we need to keep track of
+//globals
+struct passwd gTempPasswd;
+
+bool EnableBackupRights( void )
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES token_priv;
+
+ //open current process to adjust privileges
+ if( !OpenProcessToken( GetCurrentProcess( ),
+ TOKEN_ADJUST_PRIVILEGES,
+ &hToken ))
+ {
+ printf( "Cannot open process token: error %d\n",
+ (int)GetLastError() );
+ return false;
+ }
+
+ //let's build the token privilege struct -
+ //first, look up the LUID for the backup privilege
+
+ if( !LookupPrivilegeValue( NULL, //this system
+ SE_BACKUP_NAME, //the name of the privilege
+ &( token_priv.Privileges[0].Luid )) ) //result
+ {
+ printf( "Cannot lookup backup privilege: error %d\n",
+ (int)GetLastError( ) );
+ return false;
+ }
+
+ token_priv.PrivilegeCount = 1;
+ token_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ // now set the privilege
+ // because we're going exit right after dumping the streams, there isn't
+ // any need to save current state
+
+ if( !AdjustTokenPrivileges( hToken, //our process token
+ false, //we're not disabling everything
+ &token_priv, //address of structure
+ sizeof( token_priv ), //size of structure
+ NULL, NULL )) //don't save current state
+ {
+ //this function is a little tricky - if we were adjusting
+ //more than one privilege, it could return success but not
+ //adjust them all - in the general case, you need to trap this
+ printf( "Could not enable backup privileges: error %d\n",
+ (int)GetLastError( ) );
+ return false;
+
+ }
+ else
+ {
+ return true;
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertToWideString
+// Purpose: Converts a string from specified codepage to
+// a wide string (WCHAR*). Returns a buffer which
+// MUST be freed by the caller with delete[].
+// In case of fire, logs the error and returns NULL.
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+WCHAR* ConvertToWideString(const char* pString, unsigned int codepage)
+{
+ int len = MultiByteToWideChar
+ (
+ codepage, // source code page
+ 0, // character-type options
+ pString, // string to map
+ -1, // number of bytes in string - auto detect
+ NULL, // wide-character buffer
+ 0 // size of buffer - work out
+ // how much space we need
+ );
+
+ if (len == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert string to wide string: "
+ "error %d", GetLastError());
+ errno = EINVAL;
+ return NULL;
+ }
+
+ WCHAR* buffer = new WCHAR[len];
+
+ if (buffer == NULL)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert string to wide string: "
+ "out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ len = MultiByteToWideChar
+ (
+ codepage, // source code page
+ 0, // character-type options
+ pString, // string to map
+ -1, // number of bytes in string - auto detect
+ buffer, // wide-character buffer
+ len // size of buffer
+ );
+
+ if (len == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert string to wide string: "
+ "error %i", GetLastError());
+ errno = EACCES;
+ delete [] buffer;
+ return NULL;
+ }
+
+ return buffer;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertUtf8ToWideString
+// Purpose: Converts a string from UTF-8 to a wide string.
+// Returns a buffer which MUST be freed by the caller
+// with delete[].
+// In case of fire, logs the error and returns NULL.
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+WCHAR* ConvertUtf8ToWideString(const char* pString)
+{
+ return ConvertToWideString(pString, CP_UTF8);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertFromWideString
+// Purpose: Converts a wide string to a narrow string in the
+// specified code page. Returns a buffer which MUST
+// be freed by the caller with delete[].
+// In case of fire, logs the error and returns NULL.
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+char* ConvertFromWideString(const WCHAR* pString, unsigned int codepage)
+{
+ int len = WideCharToMultiByte
+ (
+ codepage, // destination code page
+ 0, // character-type options
+ pString, // string to map
+ -1, // number of bytes in string - auto detect
+ NULL, // output buffer
+ 0, // size of buffer - work out
+ // how much space we need
+ NULL, // replace unknown chars with system default
+ NULL // don't tell us when that happened
+ );
+
+ if (len == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert wide string to narrow: "
+ "error %d", GetLastError());
+ errno = EINVAL;
+ return NULL;
+ }
+
+ char* buffer = new char[len];
+
+ if (buffer == NULL)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert wide string to narrow: "
+ "out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ len = WideCharToMultiByte
+ (
+ codepage, // source code page
+ 0, // character-type options
+ pString, // string to map
+ -1, // number of bytes in string - auto detect
+ buffer, // output buffer
+ len, // size of buffer
+ NULL, // replace unknown chars with system default
+ NULL // don't tell us when that happened
+ );
+
+ if (len == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to convert wide string to narrow: "
+ "error %i", GetLastError());
+ errno = EACCES;
+ delete [] buffer;
+ return NULL;
+ }
+
+ return buffer;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertUtf8ToConsole
+// Purpose: Converts a string from UTF-8 to the console
+// code page. On success, replaces contents of rDest
+// and returns true. In case of fire, logs the error
+// and returns false.
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+bool ConvertUtf8ToConsole(const char* pString, std::string& rDest)
+{
+ WCHAR* pWide = ConvertToWideString(pString, CP_UTF8);
+ if (pWide == NULL)
+ {
+ return false;
+ }
+
+ char* pConsole = ConvertFromWideString(pWide, GetConsoleOutputCP());
+ delete [] pWide;
+
+ if (!pConsole)
+ {
+ return false;
+ }
+
+ rDest = pConsole;
+ delete [] pConsole;
+
+ return true;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertConsoleToUtf8
+// Purpose: Converts a string from the console code page
+// to UTF-8. On success, replaces contents of rDest
+// and returns true. In case of fire, logs the error
+// and returns false.
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+bool ConvertConsoleToUtf8(const char* pString, std::string& rDest)
+{
+ WCHAR* pWide = ConvertToWideString(pString, GetConsoleCP());
+ if (pWide == NULL)
+ {
+ return false;
+ }
+
+ char* pConsole = ConvertFromWideString(pWide, CP_UTF8);
+ delete [] pWide;
+
+ if (!pConsole)
+ {
+ return false;
+ }
+
+ rDest = pConsole;
+ delete [] pConsole;
+
+ return true;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ConvertPathToAbsoluteUnicode
+// Purpose: Converts relative paths to absolute (with unicode marker)
+// Created: 4th February 2006
+//
+// --------------------------------------------------------------------------
+std::string ConvertPathToAbsoluteUnicode(const char *pFileName)
+{
+ std::string tmpStr("\\\\?\\");
+
+ // Is the path relative or absolute?
+ // Absolute paths on Windows are always a drive letter
+ // followed by ':'
+
+ if (pFileName[1] != ':')
+ {
+ // Must be relative. We need to get the
+ // current directory to make it absolute.
+
+ char wd[PATH_MAX];
+ if (::getcwd(wd, PATH_MAX) == 0)
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to open '%s': path too long",
+ pFileName);
+ errno = ENAMETOOLONG;
+ tmpStr = "";
+ return tmpStr;
+ }
+
+ tmpStr += wd;
+ if (tmpStr[tmpStr.length()] != '\\')
+ {
+ tmpStr += '\\';
+ }
+ }
+
+ tmpStr += pFileName;
+ return tmpStr;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: openfile
+// Purpose: replacement for any open calls - handles unicode filenames - supplied in utf8
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+HANDLE openfile(const char *pFileName, int flags, int mode)
+{
+ std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName);
+
+ if (AbsPathWithUnicode.size() == 0)
+ {
+ // error already logged by ConvertPathToAbsoluteUnicode()
+ return NULL;
+ }
+
+ WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
+ // We are responsible for freeing pBuffer
+
+ if (pBuffer == NULL)
+ {
+ // error already logged by ConvertUtf8ToWideString()
+ return NULL;
+ }
+
+ // flags could be O_WRONLY | O_CREAT | O_RDONLY
+ DWORD createDisposition = OPEN_EXISTING;
+ DWORD shareMode = FILE_SHARE_READ;
+ DWORD accessRights = FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA;
+
+ if (flags & O_WRONLY)
+ {
+ shareMode = FILE_SHARE_WRITE;
+ }
+ if (flags & O_RDWR)
+ {
+ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ }
+ if (flags & O_CREAT)
+ {
+ createDisposition = OPEN_ALWAYS;
+ shareMode |= FILE_SHARE_WRITE;
+ accessRights |= FILE_WRITE_ATTRIBUTES
+ | FILE_WRITE_DATA | FILE_WRITE_EA
+ | FILE_ALL_ACCESS;
+ }
+ if (flags & O_TRUNC)
+ {
+ createDisposition = CREATE_ALWAYS;
+ }
+ if (flags & O_EXCL)
+ {
+ shareMode = 0;
+ }
+
+ HANDLE hdir = CreateFileW(pBuffer,
+ accessRights,
+ shareMode,
+ NULL,
+ createDisposition,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ delete [] pBuffer;
+
+ if (hdir == INVALID_HANDLE_VALUE)
+ {
+ ::syslog(LOG_WARNING, "Failed to open file %s: "
+ "error %i", pFileName, GetLastError());
+ return NULL;
+ }
+
+ return hdir;
+}
+
+// MinGW provides a getopt implementation
+#ifndef __MINGW32__
+//works with getopt
+char *optarg;
+//optind looks like an index into the string - how far we have moved along
+int optind = 1;
+char nextchar = -1;
+#endif
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: emu_fstat
+// Purpose: replacement for fstat supply a windows handle
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+int emu_fstat(HANDLE hdir, struct stat * st)
+{
+ ULARGE_INTEGER conv;
+
+ if (hdir == INVALID_HANDLE_VALUE)
+ {
+ ::syslog(LOG_ERR, "Error: invalid file handle in emu_fstat()");
+ errno = EBADF;
+ return -1;
+ }
+
+ BY_HANDLE_FILE_INFORMATION fi;
+ if (!GetFileInformationByHandle(hdir, &fi))
+ {
+ ::syslog(LOG_WARNING, "Failed to read file information: "
+ "error %d", GetLastError());
+ errno = EACCES;
+ return -1;
+ }
+
+ memset(st, 0, sizeof(*st));
+
+ // This next example is how we get our INODE (equivalent) information
+ conv.HighPart = fi.nFileIndexHigh;
+ conv.LowPart = fi.nFileIndexLow;
+ st->st_ino = (_ino_t)conv.QuadPart;
+
+ // get the time information
+ st->st_ctime = ConvertFileTimeToTime_t(&fi.ftCreationTime);
+ st->st_atime = ConvertFileTimeToTime_t(&fi.ftLastAccessTime);
+ st->st_mtime = ConvertFileTimeToTime_t(&fi.ftLastWriteTime);
+
+ // size of the file
+ LARGE_INTEGER st_size;
+ if (!GetFileSizeEx(hdir, &st_size))
+ {
+ ::syslog(LOG_WARNING, "Failed to get file size: error %d",
+ GetLastError());
+ errno = EACCES;
+ return -1;
+ }
+
+ conv.HighPart = st_size.HighPart;
+ conv.LowPart = st_size.LowPart;
+ st->st_size = (_off_t)conv.QuadPart;
+
+ //the mode of the file
+ st->st_mode = 0;
+ //DWORD res = GetFileAttributes((LPCSTR)tmpStr.c_str());
+
+ if (INVALID_FILE_ATTRIBUTES != fi.dwFileAttributes)
+ {
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ st->st_mode |= S_IFDIR;
+ }
+ else
+ {
+ st->st_mode |= S_IFREG;
+ }
+ }
+ else
+ {
+ ::syslog(LOG_WARNING, "Failed to get file attributes: "
+ "error %d", GetLastError());
+ errno = EACCES;
+ return -1;
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: OpenFileByNameUtf8
+// Purpose: Converts filename to Unicode and returns
+// a handle to it. In case of error, sets errno,
+// logs the error and returns NULL.
+// Created: 10th December 2004
+//
+// --------------------------------------------------------------------------
+HANDLE OpenFileByNameUtf8(const char* pFileName)
+{
+ std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName);
+
+ if (AbsPathWithUnicode.size() == 0)
+ {
+ // error already logged by ConvertPathToAbsoluteUnicode()
+ return NULL;
+ }
+
+ WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
+ // We are responsible for freeing pBuffer
+
+ if (pBuffer == NULL)
+ {
+ // error already logged by ConvertUtf8ToWideString()
+ return NULL;
+ }
+
+ HANDLE handle = CreateFileW(pBuffer,
+ FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA,
+ FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ // if our open fails we should always be able to
+ // open in this mode - to get the inode information
+ // at least one process must have the file open -
+ // in this case someone else does.
+ handle = CreateFileW(pBuffer,
+ 0,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ }
+
+ delete [] pBuffer;
+
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ DWORD err = GetLastError();
+
+ if (err == ERROR_FILE_NOT_FOUND)
+ {
+ errno = ENOENT;
+ }
+ else
+ {
+ ::syslog(LOG_WARNING,
+ "Failed to open '%s': error %d", pFileName, err);
+ errno = EACCES;
+ }
+
+ return NULL;
+ }
+
+ return handle;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: emu_stat
+// Purpose: replacement for the lstat and stat functions,
+// works with unicode filenames supplied in utf8 format
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+int emu_stat(const char * pName, struct stat * st)
+{
+ // at the mo
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_nlink = 1;
+
+ HANDLE handle = OpenFileByNameUtf8(pName);
+
+ if (handle == NULL)
+ {
+ // errno already set and error logged by OpenFileByNameUtf8()
+ return -1;
+ }
+
+ int retVal = emu_fstat(handle, st);
+ if (retVal != 0)
+ {
+ // error logged, but without filename
+ ::syslog(LOG_WARNING, "Failed to get file information "
+ "for '%s'", pName);
+ }
+
+ // close the handle
+ CloseHandle(handle);
+
+ return retVal;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: statfs
+// Purpose: returns the mount point of where a file is located -
+// in this case the volume serial number
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+int statfs(const char * pName, struct statfs * s)
+{
+ HANDLE handle = OpenFileByNameUtf8(pName);
+
+ if (handle == NULL)
+ {
+ // errno already set and error logged by OpenFileByNameUtf8()
+ return -1;
+ }
+
+ BY_HANDLE_FILE_INFORMATION fi;
+ if (!GetFileInformationByHandle(handle, &fi))
+ {
+ ::syslog(LOG_WARNING, "Failed to get file information "
+ "for '%s': error %d", pName, GetLastError());
+ CloseHandle(handle);
+ errno = EACCES;
+ return -1;
+ }
+
+ // convert volume serial number to a string
+ _ui64toa(fi.dwVolumeSerialNumber, s->f_mntonname + 1, 16);
+
+ // pseudo unix mount point
+ s->f_mntonname[0] = DIRECTORY_SEPARATOR_ASCHAR;
+
+ CloseHandle(handle); // close the handle
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: opendir
+// Purpose: replacement for unix function, uses win32 findfirst routines
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+DIR *opendir(const char *name)
+{
+ if (!name || !name[0])
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ std::string dirName(name);
+
+ //append a '\' win32 findfirst is sensitive to this
+ if ( dirName[dirName.size()] != '\\' || dirName[dirName.size()] != '/' )
+ {
+ dirName += '\\';
+ }
+
+ // what is the search string? - everything
+ dirName += '*';
+
+ DIR *pDir = new DIR;
+ if (pDir == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ pDir->name = ConvertUtf8ToWideString(dirName.c_str());
+ // We are responsible for freeing dir->name
+
+ if (pDir->name == NULL)
+ {
+ delete pDir;
+ return NULL;
+ }
+
+ pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info));
+
+ if (pDir->fd == -1)
+ {
+ delete [] pDir->name;
+ delete pDir;
+ return NULL;
+ }
+
+ pDir->result.d_name = 0;
+ return pDir;
+}
+
+// this kinda makes it not thread friendly!
+// but I don't think it needs to be.
+char tempbuff[MAX_PATH];
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: readdir
+// Purpose: as function above
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+struct dirent *readdir(DIR *dp)
+{
+ try
+ {
+ struct dirent *den = NULL;
+
+ if (dp && dp->fd != -1)
+ {
+ if (!dp->result.d_name ||
+ _wfindnext(dp->fd, &dp->info) != -1)
+ {
+ den = &dp->result;
+ std::wstring input(dp->info.name);
+ memset(tempbuff, 0, sizeof(tempbuff));
+ WideCharToMultiByte(CP_UTF8, 0, dp->info.name,
+ -1, &tempbuff[0], sizeof (tempbuff),
+ NULL, NULL);
+ //den->d_name = (char *)dp->info.name;
+ den->d_name = &tempbuff[0];
+ }
+ }
+ else
+ {
+ errno = EBADF;
+ }
+ return den;
+ }
+ catch (...)
+ {
+ printf("Caught readdir");
+ }
+ return NULL;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: closedir
+// Purpose: as function above
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+int closedir(DIR *dp)
+{
+ try
+ {
+ int finres = -1;
+ if (dp)
+ {
+ if(dp->fd != -1)
+ {
+ finres = _findclose(dp->fd);
+ }
+
+ delete [] dp->name;
+ delete dp;
+ }
+
+ if (finres == -1) // errors go to EBADF
+ {
+ errno = EBADF;
+ }
+
+ return finres;
+ }
+ catch (...)
+ {
+ printf("Caught closedir");
+ }
+ return -1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: poll
+// Purpose: a weak implimentation (just enough for box)
+// of the unix poll for winsock2
+// Created: 25th October 2004
+//
+// --------------------------------------------------------------------------
+int poll (struct pollfd *ufds, unsigned long nfds, int timeout)
+{
+ try
+ {
+ fd_set readfd;
+ fd_set writefd;
+
+ readfd.fd_count = 0;
+ writefd.fd_count = 0;
+
+ struct pollfd *ufdsTmp = ufds;
+
+ timeval timOut;
+ timeval *tmpptr;
+
+ if (timeout == INFTIM)
+ tmpptr = NULL;
+ else
+ tmpptr = &timOut;
+
+ timOut.tv_sec = timeout / 1000;
+ timOut.tv_usec = timeout * 1000;
+
+ if (ufds->events & POLLIN)
+ {
+ for (unsigned long i = 0; i < nfds; i++)
+ {
+ readfd.fd_array[i] = ufdsTmp->fd;
+ readfd.fd_count++;
+ }
+ }
+
+ if (ufds->events & POLLOUT)
+ {
+ for (unsigned long i = 0; i < nfds; i++)
+ {
+
+ writefd.fd_array[i]=ufdsTmp->fd;
+ writefd.fd_count++;
+ }
+ }
+
+ int noffds = select(0, &readfd, &writefd, 0, tmpptr);
+
+ if (noffds == SOCKET_ERROR)
+ {
+ // int errval = WSAGetLastError();
+
+ ufdsTmp = ufds;
+ for (unsigned long i = 0; i < nfds; i++)
+ {
+ ufdsTmp->revents = POLLERR;
+ ufdsTmp++;
+ }
+ return (-1);
+ }
+
+ return noffds;
+ }
+ catch (...)
+ {
+ printf("Caught poll");
+ }
+
+ return -1;
+}
+
+HANDLE gSyslogH = 0;
+static bool sHaveWarnedEventLogFull = false;
+
+void syslog(int loglevel, const char *frmt, ...)
+{
+ WORD errinfo;
+ char buffer[1024];
+ std::string sixfour(frmt);
+
+ switch (loglevel)
+ {
+ case LOG_INFO:
+ errinfo = EVENTLOG_INFORMATION_TYPE;
+ break;
+ case LOG_ERR:
+ errinfo = EVENTLOG_ERROR_TYPE;
+ break;
+ case LOG_WARNING:
+ errinfo = EVENTLOG_WARNING_TYPE;
+ break;
+ default:
+ errinfo = EVENTLOG_WARNING_TYPE;
+ break;
+ }
+
+ // taken from MSDN
+ int sixfourpos;
+ while ( (sixfourpos = (int)sixfour.find("%ll")) != -1 )
+ {
+ // maintain portability - change the 64 bit formater...
+ std::string temp = sixfour.substr(0,sixfourpos);
+ temp += "%I64";
+ temp += sixfour.substr(sixfourpos+3, sixfour.length());
+ sixfour = temp;
+ }
+
+ // printf("parsed string is:%s\r\n", sixfour.c_str());
+
+ va_list args;
+ va_start(args, frmt);
+
+ int len = vsnprintf(buffer, sizeof(buffer)-1, sixfour.c_str(), args);
+ ASSERT(len < sizeof(buffer))
+ buffer[sizeof(buffer)-1] = 0;
+
+ va_end(args);
+
+ LPCSTR strings[] = { buffer, NULL };
+
+ if (!ReportEvent(gSyslogH, // event log handle
+ errinfo, // event type
+ 0, // category zero
+ MSG_ERR_EXIST, // event identifier -
+ // we will call them all the same
+ NULL, // no user security identifier
+ 1, // one substitution string
+ 0, // no data
+ strings, // pointer to string array
+ NULL)) // pointer to data
+
+ {
+ DWORD err = GetLastError();
+ if (err == ERROR_LOG_FILE_FULL)
+ {
+ if (!sHaveWarnedEventLogFull)
+ {
+ printf("Unable to send message to Event Log "
+ "(Event Log is full):\r\n");
+ sHaveWarnedEventLogFull = TRUE;
+ }
+ }
+ else
+ {
+ printf("Unable to send message to Event Log: "
+ "error %i:\r\n", (int)err);
+ }
+ }
+ else
+ {
+ sHaveWarnedEventLogFull = false;
+ }
+
+ printf("%s\r\n", buffer);
+}
+
+int emu_chdir(const char* pDirName)
+{
+ WCHAR* pBuffer = ConvertUtf8ToWideString(pDirName);
+ if (!pBuffer) return -1;
+ int result = SetCurrentDirectoryW(pBuffer);
+ delete [] pBuffer;
+ if (result != 0) return 0;
+ errno = EACCES;
+ return -1;
+}
+
+char* emu_getcwd(char* pBuffer, int BufSize)
+{
+ DWORD len = GetCurrentDirectoryW(0, NULL);
+ if (len == 0)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (len > BufSize)
+ {
+ errno = ENAMETOOLONG;
+ return NULL;
+ }
+
+ WCHAR* pWide = new WCHAR [len];
+ if (!pWide)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ DWORD result = GetCurrentDirectoryW(len, pWide);
+ if (result <= 0 || result >= len)
+ {
+ errno = EACCES;
+ return NULL;
+ }
+
+ char* pUtf8 = ConvertFromWideString(pWide, CP_UTF8);
+ delete [] pWide;
+
+ if (!pUtf8)
+ {
+ return NULL;
+ }
+
+ strncpy(pBuffer, pUtf8, BufSize - 1);
+ pBuffer[BufSize - 1] = 0;
+ delete [] pUtf8;
+
+ return pBuffer;
+}
+
+int emu_mkdir(const char* pPathName)
+{
+ WCHAR* pBuffer = ConvertToWideString(pPathName, CP_UTF8);
+ if (!pBuffer)
+ {
+ return -1;
+ }
+
+ BOOL result = CreateDirectoryW(pBuffer, NULL);
+ delete [] pBuffer;
+
+ if (!result)
+ {
+ errno = EACCES;
+ return -1;
+ }
+
+ return 0;
+}
+
+int emu_unlink(const char* pFileName)
+{
+ WCHAR* pBuffer = ConvertToWideString(pFileName, CP_UTF8);
+ if (!pBuffer)
+ {
+ return -1;
+ }
+
+ BOOL result = DeleteFileW(pBuffer);
+ delete [] pBuffer;
+
+ if (!result)
+ {
+ errno = EACCES;
+ return -1;
+ }
+
+ return 0;
+}
+
+int console_read(char* pBuffer, size_t BufferSize)
+{
+ HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
+
+ if (hConsole == INVALID_HANDLE_VALUE)
+ {
+ ::fprintf(stderr, "Failed to get a handle on standard input: "
+ "error %d\n", GetLastError());
+ return -1;
+ }
+
+ int WideSize = BufferSize / 5;
+ WCHAR* pWideBuffer = new WCHAR [WideSize];
+
+ if (!pWideBuffer)
+ {
+ ::perror("Failed to allocate wide character buffer");
+ return -1;
+ }
+
+ DWORD numCharsRead = 0;
+
+ if (!ReadConsoleW(
+ hConsole,
+ pWideBuffer,
+ WideSize - 1,
+ &numCharsRead,
+ NULL // reserved
+ ))
+ {
+ ::fprintf(stderr, "Failed to read from console: error %d\n",
+ GetLastError());
+ return -1;
+ }
+
+ pWideBuffer[numCharsRead] = 0;
+
+ char* pUtf8 = ConvertFromWideString(pWideBuffer, GetConsoleCP());
+ strncpy(pBuffer, pUtf8, BufferSize);
+ delete [] pUtf8;
+
+ return strlen(pBuffer);
+}
+
+#endif // WIN32
diff --git a/lib/win32/emu.h b/lib/win32/emu.h
new file mode 100644
index 00000000..304d3bd1
--- /dev/null
+++ b/lib/win32/emu.h
@@ -0,0 +1,520 @@
+// distribution boxbackup-0.10 (svn version: 494)
+//
+// Copyright (c) 2003 - 2006
+// Ben Summers and contributors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. All use of this software and associated advertising materials must
+// display the following acknowledgment:
+// This product includes software developed by Ben Summers.
+// 4. The names of the Authors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// [Where legally impermissible the Authors do not disclaim liability for
+// direct physical injury or death caused solely by defects in the software
+// unless it is modified by a third party.]
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//
+//
+// emulates unix syscalls to win32 functions
+
+#if ! defined EMU_INCLUDE && defined WIN32
+#define EMU_INCLUDE
+
+#define _INO_T_DEFINED
+
+#include <winsock2.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <direct.h>
+#include <errno.h>
+#include <io.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include <string>
+
+#define gmtime_r( _clock, _result ) \
+ ( *(_result) = *gmtime( (_clock) ), \
+ (_result) )
+
+#define ITIMER_VIRTUAL 0
+
+#ifdef _MSC_VER
+// Microsoft decided to deprecate the standard POSIX functions. Great!
+#define open(file,flags,mode) _open(file,flags,mode)
+#define close(fd) _close(fd)
+#define dup(fd) _dup(fd)
+#define read(fd,buf,count) _read(fd,buf,count)
+#define write(fd,buf,count) _write(fd,buf,count)
+#define lseek(fd,off,whence) _lseek(fd,off,whence)
+#define fileno(struct_file) _fileno(struct_file)
+#endif
+
+int SetTimerHandler(void (__cdecl *func ) (int));
+int setitimer(int type, struct itimerval *timeout, void *arg);
+void InitTimer(void);
+void FiniTimer(void);
+
+inline int geteuid(void)
+{
+ //lets pretend to be root!
+ return 0;
+}
+
+struct passwd {
+ char *pw_name;
+ char *pw_passwd;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ time_t pw_change;
+ char *pw_class;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+ time_t pw_expire;
+};
+
+extern passwd gTempPasswd;
+inline struct passwd * getpwnam(const char * name)
+{
+ //for the mo pretend to be root
+ gTempPasswd.pw_uid = 0;
+ gTempPasswd.pw_gid = 0;
+
+ return &gTempPasswd;
+}
+
+#define S_IRWXG 1
+#define S_IRWXO 2
+#define S_ISUID 4
+#define S_ISGID 8
+#define S_ISVTX 16
+
+#ifndef __MINGW32__
+ //not sure if these are correct
+ //S_IWRITE - writing permitted
+ //_S_IREAD - reading permitted
+ //_S_IREAD | _S_IWRITE -
+ #define S_IRUSR S_IWRITE
+ #define S_IWUSR S_IREAD
+ #define S_IRWXU (S_IREAD|S_IWRITE|S_IEXEC)
+
+ #define S_ISREG(x) (S_IFREG & x)
+ #define S_ISDIR(x) (S_IFDIR & x)
+#endif
+
+inline int utimes(const char * Filename, timeval[])
+{
+ //again I am guessing this is quite important to
+ //be functioning, as large restores would be a problem
+
+ //indicate success
+ return 0;
+}
+inline int chown(const char * Filename, u_int32_t uid, u_int32_t gid)
+{
+ //important - this needs implementing
+ //If a large restore is required then
+ //it needs to restore files AND permissions
+ //reference AdjustTokenPrivileges
+ //GetAccountSid
+ //InitializeSecurityDescriptor
+ //SetSecurityDescriptorOwner
+ //The next function looks like the guy to use...
+ //SetFileSecurity
+
+ //indicate success
+ return 0;
+}
+
+int emu_chdir (const char* pDirName);
+int emu_unlink(const char* pFileName);
+char* emu_getcwd(char* pBuffer, int BufSize);
+
+#ifdef _MSC_VER
+ inline int emu_chmod(const char * Filename, int mode)
+ {
+ // indicate success
+ return 0;
+ }
+
+ #define chmod(file, mode) emu_chmod(file, mode)
+ #define chdir(directory) emu_chdir(directory)
+ #define unlink(file) emu_unlink(file)
+ #define getcwd(buffer, size) emu_getcwd(buffer, size)
+#else
+ inline int chmod(const char * Filename, int mode)
+ {
+ // indicate success
+ return 0;
+ }
+
+ inline int chdir(const char* pDirName)
+ {
+ return emu_chdir(pDirName);
+ }
+
+ inline char* getcwd(char* pBuffer, int BufSize)
+ {
+ return emu_getcwd(pBuffer, BufSize);
+ }
+
+ inline int unlink(const char* pFileName)
+ {
+ return emu_unlink(pFileName);
+ }
+#endif
+
+//I do not perceive a need to change the user or group on a backup client
+//at any rate the owner of a service can be set in the service settings
+inline int setegid(int)
+{
+ return true;
+}
+inline int seteuid(int)
+{
+ return true;
+}
+inline int setgid(int)
+{
+ return true;
+}
+inline int setuid(int)
+{
+ return true;
+}
+inline int getgid(void)
+{
+ return 0;
+}
+inline int getuid(void)
+{
+ return 0;
+}
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+// MinGW provides a getopt implementation
+#ifndef __MINGW32__
+
+// this will need to be implemented if we see fit that command line
+// options are going to be used! (probably then:)
+// where the calling function looks for the parsed parameter
+extern char *optarg;
+
+// optind looks like an index into the string - how far we have moved along
+extern int optind;
+extern char nextchar;
+
+inline int getopt(int count, char * const * args, const char * tolookfor)
+{
+ if (optind >= count) return -1;
+
+ std::string str((const char *)args[optind]);
+ std::string interestin(tolookfor);
+ int opttolookfor = 0;
+ int index = -1;
+ // just initialize the string - just in case it is used.
+ // optarg[0] = 0;
+ std::string opt;
+
+ if (count == 0) return -1;
+
+ do
+ {
+ if (index != -1)
+ {
+ str = str.substr(index+1, str.size());
+ }
+
+ index = (int)str.find('-');
+
+ if (index == -1) return -1;
+
+ opt = str[1];
+
+ optind ++;
+ str = args[optind];
+ }
+ while ((opttolookfor = (int)interestin.find(opt)) == -1);
+
+ if (interestin[opttolookfor+1] == ':')
+ {
+
+ // strcpy(optarg, str.c_str());
+ optarg = args[optind];
+ optind ++;
+ }
+
+ // indicate we have finished
+ return opt[0];
+}
+#endif // !__MINGW32__
+
+#define timespec timeval
+
+//not available in win32
+struct itimerval
+{
+ timeval it_interval;
+ timeval it_value;
+};
+
+//win32 deals in usec not nsec - so need to ensure this follows through
+#define tv_nsec tv_usec
+
+#ifndef __MINGW32__
+ typedef unsigned __int64 u_int64_t;
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int32 u_int32_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int16 uint16_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int8 int8_t;
+
+ typedef int socklen_t;
+#endif
+
+// I (re-)defined here for the moment; has to be removed later !!!
+#ifndef BOX_VERSION
+#define BOX_VERSION "0.09hWin32"
+#endif
+
+#define S_IRGRP S_IWRITE
+#define S_IWGRP S_IREAD
+#define S_IROTH S_IWRITE | S_IREAD
+#define S_IWOTH S_IREAD | S_IREAD
+
+//again need to verify these
+#define S_IFLNK 1
+
+#define S_ISLNK(x) ( false )
+
+#define vsnprintf _vsnprintf
+
+#ifndef __MINGW32__
+typedef unsigned int mode_t;
+#endif
+
+int emu_mkdir(const char* pPathName);
+
+inline int mkdir(const char *pPathName, mode_t mode)
+{
+ return emu_mkdir(pPathName);
+}
+
+#ifndef __MINGW32__
+inline int strcasecmp(const char *s1, const char *s2)
+{
+ return _stricmp(s1,s2);
+}
+#endif
+
+struct dirent
+{
+ char *d_name;
+};
+
+struct DIR
+{
+ intptr_t fd; // filedescriptor
+ // struct _finddata_t info;
+ struct _wfinddata_t info;
+ // struct _finddata_t info;
+ struct dirent result; // d_name (first time null)
+ wchar_t *name; // null-terminated byte string
+};
+
+DIR *opendir(const char *name);
+struct dirent *readdir(DIR *dp);
+int closedir(DIR *dp);
+
+HANDLE openfile(const char *filename, int flags, int mode);
+
+#define LOG_INFO 6
+#define LOG_WARNING 4
+#define LOG_ERR 3
+#define LOG_PID 0
+#define LOG_DAEMON 0
+
+extern HANDLE gSyslogH;
+void MyReportEvent(LPCTSTR *szMsg, DWORD errinfo);
+inline void openlog(const char * daemonName, int, int)
+{
+ gSyslogH = RegisterEventSource(
+ NULL, // uses local computer
+ daemonName); // source name
+ if (gSyslogH == NULL)
+ {
+ }
+}
+
+inline void closelog(void)
+{
+ DeregisterEventSource(gSyslogH);
+}
+
+void syslog(int loglevel, const char *fmt, ...);
+
+#ifndef __MINGW32__
+#define strtoll _strtoi64
+#endif
+
+inline unsigned int sleep(unsigned int secs)
+{
+ Sleep(secs*1000);
+ return(ERROR_SUCCESS);
+}
+
+#define INFTIM -1
+#define POLLIN 0x1
+#define POLLERR 0x8
+#define POLLOUT 0x4
+
+#define SHUT_RDWR SD_BOTH
+#define SHUT_RD SD_RECEIVE
+#define SHUT_WR SD_SEND
+
+struct pollfd
+{
+ SOCKET fd;
+ short int events;
+ short int revents;
+};
+
+inline int ioctl(SOCKET sock, int flag, int * something)
+{
+ //indicate success
+ return 0;
+}
+
+inline int waitpid(pid_t pid, int *status, int)
+{
+ return 0;
+}
+
+//this shouldn't be needed.
+struct statfs
+{
+ TCHAR f_mntonname[MAX_PATH];
+};
+
+#if 0
+// I think this should get us going
+// Although there is a warning about
+// mount points in win32 can now exists - which means inode number can be
+// duplicated, so potential of a problem - perhaps this needs to be
+// implemented with a little more thought... TODO
+
+struct stat {
+ //_dev_t st_dev;
+ u_int64_t st_ino;
+ DWORD st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ //_dev_t st_rdev;
+ u_int64_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+};
+
+#ifndef __MINGW32__
+typedef u_int64_t _ino_t;
+#endif
+#endif
+
+int emu_stat(const char * name, struct stat * st);
+int emu_fstat(HANDLE file, struct stat * st);
+int statfs(const char * name, struct statfs * s);
+
+//need this for converstions
+inline time_t ConvertFileTimeToTime_t(FILETIME *fileTime)
+{
+ SYSTEMTIME stUTC;
+ struct tm timeinfo;
+
+ // Convert the last-write time to local time.
+ FileTimeToSystemTime(fileTime, &stUTC);
+ // SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
+
+ memset(&timeinfo, 0, sizeof(timeinfo));
+ timeinfo.tm_sec = stUTC.wSecond;
+ timeinfo.tm_min = stUTC.wMinute;
+ timeinfo.tm_hour = stUTC.wHour;
+ timeinfo.tm_mday = stUTC.wDay;
+ timeinfo.tm_wday = stUTC.wDayOfWeek;
+ timeinfo.tm_mon = stUTC.wMonth - 1;
+ // timeinfo.tm_yday = ...;
+ timeinfo.tm_year = stUTC.wYear - 1900;
+
+ time_t retVal = mktime(&timeinfo) - _timezone;
+ return retVal;
+}
+
+#ifdef _MSC_VER
+ #define stat(filename, struct) emu_stat (filename, struct)
+ #define lstat(filename, struct) emu_stat (filename, struct)
+ #define fstat(handle, struct) emu_fstat(handle, struct)
+#else
+ inline int stat(const char* filename, struct stat* stat)
+ {
+ return emu_stat(filename, stat);
+ }
+ inline int lstat(const char* filename, struct stat* stat)
+ {
+ return emu_stat(filename, stat);
+ }
+ inline int fstat(HANDLE handle, struct stat* stat)
+ {
+ return emu_fstat(handle, stat);
+ }
+#endif
+
+int poll(struct pollfd *ufds, unsigned long nfds, int timeout);
+bool EnableBackupRights( void );
+
+bool ConvertUtf8ToConsole(const char* pString, std::string& rDest);
+bool ConvertConsoleToUtf8(const char* pString, std::string& rDest);
+
+//
+// MessageId: MSG_ERR_EXIST
+// MessageText:
+// Box Backup.
+//
+#define MSG_ERR_EXIST ((DWORD)0xC0000004L)
+
+// replacement for _cgetws which requires a relatively recent C runtime lib
+int console_read(char* pBuffer, size_t BufferSize);
+
+#endif // !EMU_INCLUDE && WIN32