From 830aa82e44381c85d8486e46de7ae0e26830457e Mon Sep 17 00:00:00 2001 From: Ben Summers Date: Mon, 13 Feb 2006 13:30:21 +0000 Subject: Merge chris/win32/vc2005-compile-fixes @ r455, add infrastructure/msvc to distribution --- lib/win32/WinNamedPipeStream.cpp | 43 +- lib/win32/config.h.win32 | 396 +++++++++++++++++ lib/win32/emu.cpp | 913 +++++++++++++++++++++++++-------------- lib/win32/emu.h | 196 ++++++--- 4 files changed, 1131 insertions(+), 417 deletions(-) create mode 100644 lib/win32/config.h.win32 (limited to 'lib/win32') diff --git a/lib/win32/WinNamedPipeStream.cpp b/lib/win32/WinNamedPipeStream.cpp index 17a2227b..c5b7eaa5 100644 --- a/lib/win32/WinNamedPipeStream.cpp +++ b/lib/win32/WinNamedPipeStream.cpp @@ -11,7 +11,10 @@ #ifdef WIN32 -#include +#ifdef HAVE_UNISTD_H + #include +#endif + #include #include #include @@ -97,15 +100,14 @@ void WinNamedPipeStream::Accept(const wchar_t* pName) { ::syslog(LOG_ERR, "ConnectNamedPipe failed: %d", GetLastError()); - CloseHandle(mSocketHandle); - mSocketHandle = NULL; + Close(); THROW_EXCEPTION(ServerException, SocketOpenError) } - mReadClosed = FALSE; - mWriteClosed = FALSE; - mIsServer = TRUE; // must flush and disconnect before closing - mIsConnected = TRUE; + mReadClosed = false; + mWriteClosed = false; + mIsServer = true; // must flush and disconnect before closing + mIsConnected = true; } // -------------------------------------------------------------------------- @@ -140,10 +142,10 @@ void WinNamedPipeStream::Connect(const wchar_t* pName) THROW_EXCEPTION(ServerException, SocketOpenError) } - mReadClosed = FALSE; - mWriteClosed = FALSE; - mIsServer = FALSE; // just close the socket - mIsConnected = TRUE; + mReadClosed = false; + mWriteClosed = false; + mIsServer = false; // just close the socket + mIsConnected = true; } // -------------------------------------------------------------------------- @@ -240,7 +242,14 @@ void WinNamedPipeStream::Write(const void *pBuffer, int NBytes) // -------------------------------------------------------------------------- void WinNamedPipeStream::Close() { - if (mSocketHandle == NULL || !mIsConnected) + 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) } @@ -262,14 +271,16 @@ void WinNamedPipeStream::Close() mIsServer = false; } - if (!CloseHandle(mSocketHandle)) + bool result = CloseHandle(mSocketHandle); + + mSocketHandle = NULL; + mIsConnected = false; + + if (!result) { ::syslog(LOG_ERR, "CloseHandle failed: %d", GetLastError()); THROW_EXCEPTION(ServerException, SocketCloseError) } - - mSocketHandle = NULL; - mIsConnected = FALSE; } // -------------------------------------------------------------------------- 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 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 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 header file, and it defines `DIR'. + */ +/* #undef HAVE_DIRENT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_READLINE_H */ + +/* define if the compiler supports exceptions */ +#define HAVE_EXCEPTIONS + +/* Define to 1 if you have the 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 header file. */ +/* #undef HAVE_HISTORY_H */ + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the 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 header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the 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 header file. */ +#define HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PROCESS_H 1 + +/* Define to 1 if you have the 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 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 header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define to 1 if you have the 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 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 header file. */ +// #define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the 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 header file. */ +/* #undef HAVE_SYSLOG_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_ENDIAN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MNTTAB_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MOUNT_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +// #define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSCALL_H */ + +/* Define to 1 if you have the header file. */ +// #define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_XATTR_H */ + +/* Define to 1 if you have the 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 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 and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your 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 doesn't define. */ +#define gid_t int + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `long' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if doesn't define. */ +#define uid_t int diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp index 17ac698f..00d43122 100644 --- a/lib/win32/emu.cpp +++ b/lib/win32/emu.cpp @@ -12,14 +12,20 @@ #include #include // #include -#include + +#ifdef HAVE_UNISTD_H + #include +#endif +#ifdef HAVE_PROCESS_H + #include +#endif #include #include -//our implimentation for a timer -//based on a simple thread which sleeps for a -//period of time +// our implementation for a timer, based on a +// simple thread which sleeps for a period of time + static bool gFinishTimer; static CRITICAL_SECTION gLock; @@ -28,14 +34,14 @@ typedef struct int countDown; int interval; } -tTimer; +Timer_t; -std::list gTimerList; +std::list gTimerList; static void (__cdecl *gTimerFunc) (int) = NULL; -int setitimer(int type , struct itimerval *timeout, int) +int setitimer(int type, struct itimerval *timeout, void *arg) { - if ( SIGVTALRM == type || ITIMER_VIRTUAL == type ) + if (ITIMER_VIRTUAL == type) { EnterCriticalSection(&gLock); // we only need seconds for the mo! @@ -46,7 +52,7 @@ int setitimer(int type , struct itimerval *timeout, int) } else { - tTimer ourTimer; + Timer_t ourTimer; ourTimer.countDown = timeout->it_value.tv_sec; ourTimer.interval = timeout->it_interval.tv_sec; gTimerList.push_back(ourTimer); @@ -64,12 +70,12 @@ static unsigned int WINAPI RunTimer(LPVOID lpParameter) while (!gFinishTimer) { - std::list::iterator it; + std::list::iterator it; EnterCriticalSection(&gLock); for (it = gTimerList.begin(); it != gTimerList.end(); it++) { - tTimer& rTimer(*it); + Timer_t& rTimer(*it); rTimer.countDown --; if (rTimer.countDown == 0) @@ -92,13 +98,18 @@ static unsigned int WINAPI RunTimer(LPVOID lpParameter) for (it = gTimerList.begin(); it != gTimerList.end(); it++) { - tTimer& rTimer(*it); + Timer_t& rTimer(*it); if (rTimer.countDown == -1) { gTimerList.erase(it); - //if we don't do this the search is on a corrupt list + + // 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; } } @@ -148,7 +159,8 @@ bool EnableBackupRights( void ) TOKEN_ADJUST_PRIVILEGES, &hToken )) { - printf( "Cannot open process token - err = %d\n", GetLastError( ) ); + printf( "Cannot open process token: error %d\n", + (int)GetLastError() ); return false; } @@ -159,7 +171,8 @@ bool EnableBackupRights( void ) SE_BACKUP_NAME, //the name of the privilege &( token_priv.Privileges[0].Luid )) ) //result { - printf( "Cannot lookup backup privilege - err = %d\n", GetLastError( ) ); + printf( "Cannot lookup backup privilege: error %d\n", + (int)GetLastError( ) ); return false; } @@ -179,7 +192,8 @@ bool EnableBackupRights( void ) //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 - err = %d\n", GetLastError( ) ); + printf( "Could not enable backup privileges: error %d\n", + (int)GetLastError( ) ); return false; } @@ -192,115 +206,342 @@ bool EnableBackupRights( void ) // -------------------------------------------------------------------------- // // Function -// Name: openfile -// Purpose: replacement for any open calls - handles unicode filenames - supplied in utf8 -// Created: 25th October 2004 +// 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 // // -------------------------------------------------------------------------- -HANDLE openfile(const char *filename, int flags, int mode) +WCHAR* ConvertToWideString(const char* pString, unsigned int codepage) { - try{ + 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_t *buffer; - std::string fileN(filename); + WCHAR* buffer = new WCHAR[len]; - std::string tmpStr("\\\\?\\"); - //is the path relative or otherwise - if ( fileN[1] != ':' ) - { - //we need to get the current directory - char wd[PATH_MAX]; - if(::getcwd(wd, PATH_MAX) == 0) - { - return NULL; - } - tmpStr += wd; - if (tmpStr[tmpStr.length()] != '\\') - { - tmpStr += '\\'; - } - } - tmpStr += filename; - - int strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - tmpStr.c_str(), // string to map - (int)tmpStr.length(), // number of bytes in string - NULL, // wide-character buffer - 0 // size of buffer - work out how much space we need - ); - - buffer = new wchar_t[strlen+1]; - if ( buffer == NULL ) - { - return NULL; - } + if (buffer == NULL) + { + ::syslog(LOG_WARNING, + "Failed to convert string to wide string: " + "out of memory"); + errno = ENOMEM; + return NULL; + } - strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - tmpStr.c_str(), // string to map - (int)tmpStr.length(), // number of bytes in string - buffer, // wide-character buffer - strlen // size of buffer - ); + 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; + } - if ( strlen == 0 ) - { - delete [] buffer; - return NULL; - } + return buffer; +} - buffer[strlen] = L'\0'; +// -------------------------------------------------------------------------- +// +// 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); +} - //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; +// -------------------------------------------------------------------------- +// +// 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; + } - if ( flags & O_WRONLY ) - { - createDisposition = OPEN_EXISTING; - shareMode |= FILE_SHARE_READ ;//| FILE_SHARE_WRITE; - } - if ( flags & O_CREAT ) + 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) { - createDisposition = OPEN_ALWAYS; - shareMode |= FILE_SHARE_READ ;//| FILE_SHARE_WRITE; - accessRights |= FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA | FILE_ALL_ACCESS; + ::syslog(LOG_WARNING, + "Failed to open '%s': path too long", + pFileName); + errno = ENAMETOOLONG; + tmpStr = ""; + return tmpStr; } - if ( flags & O_TRUNC ) + + tmpStr += wd; + if (tmpStr[tmpStr.length()] != '\\') { - createDisposition = OPEN_ALWAYS; + tmpStr += '\\'; } + } + + tmpStr += pFileName; + return tmpStr; +} - HANDLE hdir = CreateFileW(buffer, - accessRights, - shareMode, - NULL, - createDisposition, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if ( hdir == INVALID_HANDLE_VALUE ) - { - // DWORD err = GetLastError(); - // syslog(EVENTLOG_WARNING_TYPE, "Couldn't open file %s, err %i\n", filename, err); - delete [] buffer; - return NULL; - } +// -------------------------------------------------------------------------- +// +// 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; + } - delete [] buffer; - return hdir; + // 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; } - catch(...) + if (flags & O_RDWR) { - printf("Caught openfile:%s\r\n", filename); + 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 NULL; + return hdir; } // MinGW provides a getopt implementation @@ -315,18 +556,18 @@ char nextchar = -1; // -------------------------------------------------------------------------- // // Function -// Name: ourfstat +// Name: emu_fstat // Purpose: replacement for fstat supply a windows handle // Created: 25th October 2004 // // -------------------------------------------------------------------------- -int ourfstat(HANDLE hdir, struct stat * st) +int emu_fstat(HANDLE hdir, struct stat * st) { ULARGE_INTEGER conv; if (hdir == INVALID_HANDLE_VALUE) { - ::syslog(LOG_ERR, "Error: invalid file handle in ourfstat()"); + ::syslog(LOG_ERR, "Error: invalid file handle in emu_fstat()"); errno = EBADF; return -1; } @@ -343,7 +584,7 @@ int ourfstat(HANDLE hdir, struct stat * st) // This next example is how we get our INODE (equivalent) information conv.HighPart = fi.nFileIndexHigh; conv.LowPart = fi.nFileIndexLow; - st->st_ino = conv.QuadPart; + st->st_ino = (_ino_t)conv.QuadPart; // get the time information st->st_ctime = ConvertFileTimeToTime_t(&fi.ftCreationTime); @@ -362,7 +603,7 @@ int ourfstat(HANDLE hdir, struct stat * st) conv.HighPart = st_size.HighPart; conv.LowPart = st_size.LowPart; - st->st_size = conv.QuadPart; + st->st_size = (_off_t)conv.QuadPart; //the mode of the file st->st_mode = 0; @@ -400,76 +641,26 @@ int ourfstat(HANDLE hdir, struct stat * st) // Created: 10th December 2004 // // -------------------------------------------------------------------------- -HANDLE OpenFileByNameUtf8(const char* pName) +HANDLE OpenFileByNameUtf8(const char* pFileName) { - //some string thing - required by ms to indicate long/unicode filename - std::string tmpStr("\\\\?\\"); - - // is the path relative or otherwise - std::string fileN(pName); - if (fileN[1] != ':') - { - // we need to get the current directory - char wd[PATH_MAX]; - if(::getcwd(wd, PATH_MAX) == 0) - { - ::syslog(LOG_WARNING, - "Failed to open '%s': path too long", pName); - errno = ENAMETOOLONG; - return NULL; - } - - tmpStr += wd; - if (tmpStr[tmpStr.length()] != '\\') - { - tmpStr += '\\'; - } - } - - tmpStr += fileN; - - int strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - tmpStr.c_str(), // string to map - (int)tmpStr.length(), // number of bytes in string - NULL, // wide-character buffer - 0 // size of buffer - work out - // how much space we need - ); - - wchar_t* buffer = new wchar_t[strlen+1]; - - if (buffer == NULL) + std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName); + + if (AbsPathWithUnicode.size() == 0) { - ::syslog(LOG_WARNING, - "Failed to open '%s': out of memory", pName); - errno = ENOMEM; + // error already logged by ConvertPathToAbsoluteUnicode() return NULL; } - - strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - tmpStr.c_str(), // string to map - (int)tmpStr.length(), // number of bytes in string - buffer, // wide-character buffer - strlen // size of buffer - ); - - if (strlen == 0) + + WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); + // We are responsible for freeing pBuffer + + if (pBuffer == NULL) { - ::syslog(LOG_WARNING, - "Failed to open '%s': could not convert " - "file name to Unicode", pName); - errno = EACCES; - delete [] buffer; + // error already logged by ConvertUtf8ToWideString() return NULL; } - buffer[strlen] = L'\0'; - - HANDLE handle = CreateFileW(buffer, + HANDLE handle = CreateFileW(pBuffer, FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY | FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, @@ -483,7 +674,7 @@ HANDLE OpenFileByNameUtf8(const char* pName) // 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(buffer, + handle = CreateFileW(pBuffer, 0, FILE_SHARE_READ, NULL, @@ -492,7 +683,7 @@ HANDLE OpenFileByNameUtf8(const char* pName) NULL); } - delete [] buffer; + delete [] pBuffer; if (handle == INVALID_HANDLE_VALUE) { @@ -505,7 +696,7 @@ HANDLE OpenFileByNameUtf8(const char* pName) else { ::syslog(LOG_WARNING, - "Failed to open '%s': error %d", pName); + "Failed to open '%s': error %d", pFileName, err); errno = EACCES; } @@ -518,13 +709,13 @@ HANDLE OpenFileByNameUtf8(const char* pName) // -------------------------------------------------------------------------- // // Function -// Name: ourstat +// Name: emu_stat // Purpose: replacement for the lstat and stat functions, // works with unicode filenames supplied in utf8 format // Created: 25th October 2004 // // -------------------------------------------------------------------------- -int ourstat(const char * pName, struct stat * st) +int emu_stat(const char * pName, struct stat * st) { // at the mo st->st_uid = 0; @@ -539,7 +730,7 @@ int ourstat(const char * pName, struct stat * st) return -1; } - int retVal = ourfstat(handle, st); + int retVal = emu_fstat(handle, st); if (retVal != 0) { // error logged, but without filename @@ -593,14 +784,6 @@ int statfs(const char * pName, struct statfs * s) return 0; } - - - - -// MinGW provides opendir(), etc. via -// MSVC does not provide these, so emulation is needed - -#ifndef __MINGW32__ // -------------------------------------------------------------------------- // // Function @@ -611,110 +794,56 @@ int statfs(const char * pName, struct statfs * s) // -------------------------------------------------------------------------- DIR *opendir(const char *name) { - try + if (!name || !name[0]) { - DIR *dir = 0; - 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 += '*'; - - if(name && name[0]) - { - if ( ( dir = new DIR ) != 0 ) - { - //mbstowcs(dir->name, dirName.c_str(),100); - //wcscpy((wchar_t*)dir->name, (const wchar_t*)dirName.c_str()); - //mbstowcs(dir->name, dirName.c_str(), dirName.size()+1); - //wchar_t *buffer; - - int strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - dirName.c_str(), // string to map - (int)dirName.length(), // number of bytes in string - NULL, // wide-character buffer - 0 // size of buffer - work out how much space we need - ); - - dir->name = new wchar_t[strlen+1]; - - if (dir->name == NULL) - { - delete dir; - dir = 0; - errno = ENOMEM; - return NULL; - } - - strlen = MultiByteToWideChar( - CP_UTF8, // code page - 0, // character-type options - dirName.c_str(), // string to map - (int)dirName.length(), // number of bytes in string - dir->name, // wide-character buffer - strlen // size of buffer - ); + errno = EINVAL; + return NULL; + } + + std::string dirName(name); - if (strlen == 0) - { - delete dir->name; - delete dir; - dir = 0; - errno = ENOMEM; - return NULL; - } + //append a '\' win32 findfirst is sensitive to this + if ( dirName[dirName.size()] != '\\' || dirName[dirName.size()] != '/' ) + { + dirName += '\\'; + } - dir->name[strlen] = L'\0'; + // what is the search string? - everything + dirName += '*'; - - dir->fd = _wfindfirst( - (const wchar_t*)dir->name, - &dir->info); + DIR *pDir = new DIR; + if (pDir == NULL) + { + errno = ENOMEM; + return NULL; + } - if (dir->fd != -1) - { - dir->result.d_name = 0; - } - else // go back - { - delete [] dir->name; - delete dir; - dir = 0; - } - } - else // backwards again - { - delete dir; - dir = 0; - errno = ENOMEM; - } - } - else - { - errno = EINVAL; - } + pDir->name = ConvertUtf8ToWideString(dirName.c_str()); + // We are responsible for freeing dir->name + + if (pDir->name == NULL) + { + delete pDir; + return NULL; + } - return dir; + pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info)); - } - catch(...) + if (pDir->fd == -1) { - printf("Caught opendir"); + delete [] pDir->name; + delete pDir; + return NULL; } - - 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. +// this kinda makes it not thread friendly! +// but I don't think it needs to be. char tempbuff[MAX_PATH]; + // -------------------------------------------------------------------------- // // Function @@ -794,7 +923,6 @@ int closedir(DIR *dp) } return -1; } -#endif // !__MINGW32__ // -------------------------------------------------------------------------- // @@ -873,11 +1001,12 @@ int poll (struct pollfd *ufds, unsigned long nfds, int timeout) } HANDLE gSyslogH = 0; +static bool sHaveWarnedEventLogFull = false; void syslog(int loglevel, const char *frmt, ...) { - DWORD errinfo; - char* buffer; + WORD errinfo; + char buffer[1024]; std::string sixfour(frmt); switch (loglevel) @@ -896,81 +1025,203 @@ void syslog(int loglevel, const char *frmt, ...) break; } - - //taken from MSDN - try + // 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 - int sixfourpos; - while ( ( sixfourpos = sixfour.find("%ll")) != -1 ) + { + 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 { - //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("Unable to send message to Event Log: " + "error %i:\r\n", (int)err); } + } + else + { + sHaveWarnedEventLogFull = false; + } - //printf("parsed string is:%s\r\n", sixfour.c_str()); + printf("%s\r\n", buffer); +} - va_list args; - va_start(args, frmt); +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; +} -#ifdef __MINGW32__ - // no _vscprintf, use a fixed size buffer - buffer = new char[1024]; - int len = 1023; -#else - int len = _vscprintf( sixfour.c_str(), args ); - ASSERT(len > 0) +char* emu_getcwd(char* pBuffer, int BufSize) +{ + DWORD len = GetCurrentDirectoryW(0, NULL); + if (len == 0) + { + errno = EINVAL; + return NULL; + } - len = len + 1; - char* buffer = new char[len]; -#endif + if (len > BufSize) + { + errno = ENAMETOOLONG; + return NULL; + } - ASSERT(buffer) - memset(buffer, 0, len); + WCHAR* pWide = new WCHAR [len]; + if (!pWide) + { + errno = ENOMEM; + return NULL; + } - int len2 = vsnprintf(buffer, len, sixfour.c_str(), args); - ASSERT(len2 <= len); + DWORD result = GetCurrentDirectoryW(len, pWide); + if (result <= 0 || result >= len) + { + errno = EACCES; + return NULL; + } + + char* pUtf8 = ConvertFromWideString(pWide, CP_UTF8); + delete [] pWide; - va_end(args); + if (!pUtf8) + { + return NULL; } - catch (...) + + 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) { - printf("Caught syslog: %s", sixfour.c_str()); - return; + return -1; } - try + BOOL result = CreateDirectoryW(pBuffer, NULL); + delete [] pBuffer; + + if (!result) { + errno = EACCES; + return -1; + } - 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 - (LPCSTR*)&buffer, // pointer to string array - NULL)) // pointer to data + return 0; +} - { - DWORD err = GetLastError(); - printf("Unable to send message to Event Log " - "(error %i):\r\n", err); - } +int emu_unlink(const char* pFileName) +{ + WCHAR* pBuffer = ConvertToWideString(pFileName, CP_UTF8); + if (!pBuffer) + { + return -1; + } - printf("%s\r\n", buffer); + BOOL result = DeleteFileW(pBuffer); + delete [] pBuffer; - if (buffer) delete [] buffer; + if (!result) + { + errno = EACCES; + return -1; } - catch (...) + + return 0; +} + +int console_read(char* pBuffer, size_t BufferSize) +{ + HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); + + if (hConsole == INVALID_HANDLE_VALUE) { - printf("Caught syslog ReportEvent"); + ::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 index 5b506206..ce0c884f 100644 --- a/lib/win32/emu.h +++ b/lib/win32/emu.h @@ -3,7 +3,6 @@ #if ! defined EMU_INCLUDE && defined WIN32 #define EMU_INCLUDE -#define _STAT_DEFINED #define _INO_T_DEFINED #include @@ -17,9 +16,6 @@ #include #include #include -//#include -//#include -//#include #include @@ -27,13 +23,21 @@ ( *(_result) = *gmtime( (_clock) ), \ (_result) ) - -//signal in unix SIGVTALRM does not exist in win32 - but looking at the -#define SIGVTALRM 254 -#define SIGALRM SIGVTALRM #define ITIMER_VIRTUAL 0 -int setitimer(int type , struct itimerval *timeout, int); +#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); @@ -109,11 +113,43 @@ inline int chown(const char * Filename, u_int32_t uid, u_int32_t gid) return 0; } -inline int chmod(const char * Filename, int uid) -{ - //indicate sucsess - 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 @@ -149,55 +185,56 @@ inline int getuid(void) // MinGW provides a getopt implementation #ifndef __MINGW32__ -//this will need to be implimented if we see fit that command line -//options are going to be used! (probably then:) -//where the calling function looks for the parsed parameter +// 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 + +// 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, char * tolookfor) +inline int getopt(int count, char * const * args, const char * tolookfor) { - if ( optind >= count ) return -1; + 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; + // just initialize the string - just in case it is used. + // optarg[0] = 0; std::string opt; - if ( count == 0 ) return -1; + if (count == 0) return -1; do { - if ( index != -1 ) + if (index != -1) { str = str.substr(index+1, str.size()); } - index = str.find('-'); + index = (int)str.find('-'); - if ( index == -1 ) return -1; + if (index == -1) return -1; opt = str[1]; optind ++; str = args[optind]; } - while ( ( opttolookfor = interestin.find(opt)) == -1 ); + while ((opttolookfor = (int)interestin.find(opt)) == -1); - if ( interestin[opttolookfor+1] == ':' ) + if (interestin[opttolookfor+1] == ':') { - //strcpy(optarg, str.c_str()); + // strcpy(optarg, str.c_str()); optarg = args[optind]; optind ++; } - //indicate we have finished + // indicate we have finished return opt[0]; } #endif // !__MINGW32__ @@ -244,49 +281,44 @@ struct itimerval #define S_ISLNK(x) ( false ) -// nasty implementation to get working - TODO get the win32 equiv -#ifdef _DEBUG -#define getpid() 1 -#endif - #define vsnprintf _vsnprintf #ifndef __MINGW32__ typedef unsigned int mode_t; #endif -inline int mkdir(const char *pathname, mode_t mode) +int emu_mkdir(const char* pPathName); + +inline int mkdir(const char *pPathName, mode_t mode) { - return mkdir(pathname); + return emu_mkdir(pPathName); } -#ifdef __MINGW32__ - #include -#else - inline int strcasecmp(const char *s1, const char *s2) - { - return _stricmp(s1,s2); - } +#ifndef __MINGW32__ +inline int strcasecmp(const char *s1, const char *s2) +{ + return _stricmp(s1,s2); +} +#endif - struct dirent - { - char *d_name; - }; +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); -#endif +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); @@ -358,6 +390,7 @@ 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 @@ -381,9 +414,10 @@ struct stat { #ifndef __MINGW32__ typedef u_int64_t _ino_t; #endif +#endif -int ourstat(const char * name, struct stat * st); -int ourfstat(HANDLE file, struct stat * st); +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 @@ -395,7 +429,8 @@ inline time_t ConvertFileTimeToTime_t(FILETIME *fileTime) // 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; @@ -405,17 +440,35 @@ inline time_t ConvertFileTimeToTime_t(FILETIME *fileTime) // timeinfo.tm_yday = ...; timeinfo.tm_year = stUTC.wYear - 1900; - time_t retVal = mktime(&timeinfo); + time_t retVal = mktime(&timeinfo) - _timezone; return retVal; } -#define stat(x,y) ourstat(x,y) -#define fstat(x,y) ourfstat(x,y) -#define lstat(x,y) ourstat(x,y) +#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); +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: @@ -423,4 +476,7 @@ bool EnableBackupRights( void ); // #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 -- cgit v1.2.3