Changeset 3055


Ignore:
Timestamp:
Jan 19, 2012, 6:27:44 PM (3 years ago)
Author:
invisnet
Message:

Big batch of EMU changes for new Win32 lib

Location:
box/invisnet/vs2010/0.11
Files:
23 added
1 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • box/invisnet/vs2010/0.11/bin/bbackupd/BackupClientDirectoryRecord.cpp

    r2714 r3055  
    291291                                // DT_DIR, etc, but we only use it here and
    292292                                // prefer S_IFREG, S_IFDIR...
    293                                 int type = en->d_type;
     293                                int type = 0;
     294                                type = (DT_DIR == en->d_type) ? S_IFDIR : type;
     295                                type = (DT_REG == en->d_type) ? S_IFREG : type;
    294296                                #else
    295297                                if(EMU_LSTAT(filename.c_str(), &file_st) != 0)
  • box/invisnet/vs2010/0.11/bin/bbackupd/Win32ServiceFunctions.cpp

    r2771 r3055  
    2222#endif
    2323
     24using namespace Win32;
     25
    2426extern void TerminateService(void);
    2527extern unsigned int WINAPI RunService(LPVOID lpParameter);
     
    101103{
    102104        // initialise service status
    103         gServiceStatus.dwServiceType = SERVICE_WIN32;
     105        gServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    104106        gServiceStatus.dwCurrentState = SERVICE_STOPPED;
    105107        gServiceStatus.dwControlsAccepted = 0;
     
    191193        if (!success)
    192194        {
    193                 ErrorHandler("Failed to start service. Did you start "
    194                         "Box Backup from the Service Control Manager? "
    195                         "(StartServiceCtrlDispatcher)", GetLastError());
     195//              ErrorHandler("Failed to start service. Did you start "
     196//                      "Box Backup from the Service Control Manager? "
     197//                      "(StartServiceCtrlDispatcher)", GetLastError());
    196198                return 1;
    197199        }
  • box/invisnet/vs2010/0.11/bin/bbackupd/bbackupd.cpp

    r2180 r3055  
    3636#ifdef WIN32
    3737
    38         EnableBackupRights();
     38        Win32::EnableBackupRights();
    3939
    4040        gpDaemonService = new Win32BackupService();
  • box/invisnet/vs2010/0.11/bin/bbackupquery/bbackupquery.cpp

    r2663 r3055  
    5959#include "MemLeakFindOn.h"
    6060
     61#ifdef WIN32
     62using namespace Win32;
     63#endif
     64
    6165void PrintUsageAndExit()
    6266{
     
    293297                return 1;
    294298        }
     299#ifdef WIN32
     300        char path[MAX_PATH];
     301
     302        if(FAILED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA,NULL,0,path)) || !PathAppend(path,"Box Backup"))
     303        {
     304                BOX_FATAL("Can't build DataDirectory");
     305                return 1;
     306        }
     307
     308        config->AddKeyValue("DataDirectory",path);
     309#endif
    295310        // Easier coding
    296311        const Configuration &conf(*config);
     
    301316        // Read in the certificates creating a TLS context
    302317        TLSContext tlsContext;
     318#ifdef WIN32
     319        std::string certFile(conf.GetKeyValue("AccountNumber"));
     320        std::string keyFile;
     321        std::string caFile;
     322        std::string keysFile;
     323#else
    303324        std::string certFile(conf.GetKeyValue("CertificateFile"));
    304325        std::string keyFile(conf.GetKeyValue("PrivateKeyFile"));
    305326        std::string caFile(conf.GetKeyValue("TrustedCAsFile"));
     327        std::string keysFile(conf.GetKeyValue("KeysFile"));
     328#endif
    306329        tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str());
    307330       
    308331        // Initialise keys
    309         BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str());
     332        BackupClientCryptoKeys_Setup(keysFile.c_str());
    310333
    311334        // 2. Connect to server
  • box/invisnet/vs2010/0.11/lib/backupclient/BackupClientFileAttributes.cpp

    r2811 r3055  
    844844
    845845                // Try to apply
    846                 if(::utimes(Filename, times) != 0)
     846                if(EMU_UTIMES(Filename, times) != 0)
    847847                {
    848848                        BOX_LOG_SYS_ERROR("Failed to change times of "
  • box/invisnet/vs2010/0.11/lib/backupclient/BackupClientRestore.cpp

    r2813 r3055  
    386386        if((exists == ObjectExists_NoObject ||
    387387                exists == ObjectExists_File) &&
    388                 ::mkdir(rLocalDirectoryName.c_str(), S_IRWXU) != 0)
     388                EMU_MKDIR(rLocalDirectoryName.c_str(), S_IRWXU) != 0)
    389389        {
    390390                BOX_LOG_SYS_ERROR("Failed to create directory '" <<
  • box/invisnet/vs2010/0.11/lib/common/Box.h

    r2663 r3055  
    182182inline int8_t   ntoh(int8_t in)   { return in; }
    183183
     184using namespace BoxBackup;
     185
    184186#endif // BOX__H
    185187
  • box/invisnet/vs2010/0.11/lib/common/BoxConfig-MSVC.h

    r2067 r3055  
    204204
    205205/* Define to 1 if you have the <stdint.h> header file. */
    206 // #define HAVE_STDINT_H 1
     206#define HAVE_STDINT_H 1
    207207
    208208/* Define to 1 if you have the <stdlib.h> header file. */
  • box/invisnet/vs2010/0.11/lib/common/BoxPlatform.h

    r2801 r3055  
    121121#endif
    122122
    123 #if defined WIN32 && !defined __MINGW32__
    124         typedef __int8  int8_t;
    125         typedef __int16 int16_t;
    126         typedef __int32 int32_t;
    127         typedef __int64 int64_t;
    128 
    129         typedef unsigned __int8  u_int8_t;
    130         typedef unsigned __int16 u_int16_t;
    131         typedef unsigned __int32 u_int32_t;
    132         typedef unsigned __int64 u_int64_t;
    133 
    134         #define HAVE_U_INT8_T
    135         #define HAVE_U_INT16_T
    136         #define HAVE_U_INT32_T
    137         #define HAVE_U_INT64_T
    138 #endif // WIN32 && !__MINGW32__
    139 
    140123// Define missing types
    141124#ifndef HAVE_UINT8_T
     
    181164#endif
    182165
    183 #ifdef WIN32
    184         #define WIN32_LEAN_AND_MEAN
    185 #endif
    186 
    187166#include "emu.h"
    188167
  • box/invisnet/vs2010/0.11/lib/common/FileStream.cpp

    r2792 r3055  
    6868                MEMLEAKFINDER_NOT_A_LEAK(this);
    6969
    70                 #ifdef WIN32
    71                 BOX_LOG_WIN_WARNING_NUMBER("Failed to open file: " <<
    72                         mFileName, winerrno);
    73                 #else
     70                #ifndef WIN32
    7471                BOX_LOG_SYS_WARNING("Failed to open file: " <<
    7572                        mFileName);
  • box/invisnet/vs2010/0.11/lib/common/Logging.cpp

    r2663 r3055  
    1717#include <cstdio>
    1818
     19#ifdef HAVE_PROCESS_H
     20        #include <process.h>
     21#endif
    1922#ifdef HAVE_SYSLOG_H
    2023        #include <syslog.h>
  • box/invisnet/vs2010/0.11/lib/common/Logging.h

    r2663 r3055  
    6060{
    6161#ifdef WIN32
    62         return GetErrorMessage(GetLastError());
     62        return BoxBackup::Win32::GetErrorMessage(GetLastError());
    6363#else
    6464        std::ostringstream _box_log_line;
     
    7070#ifdef WIN32
    7171        #define BOX_LOG_WIN_ERROR(stuff) \
    72                 BOX_ERROR(stuff << ": " << GetErrorMessage(GetLastError()))
     72                BOX_ERROR(stuff << ": " << Win32::GetErrorMessage(GetLastError()))
    7373        #define BOX_LOG_WIN_WARNING(stuff) \
    74                 BOX_WARNING(stuff << ": " << GetErrorMessage(GetLastError()))
     74                BOX_WARNING(stuff << ": " << Win32::GetErrorMessage(GetLastError()))
    7575        #define BOX_LOG_WIN_ERROR_NUMBER(stuff, number) \
    76                 BOX_ERROR(stuff << ": " << GetErrorMessage(number))
     76                BOX_ERROR(stuff << ": " << Win32::GetErrorMessage(number))
    7777        #define BOX_LOG_WIN_WARNING_NUMBER(stuff, number) \
    78                 BOX_WARNING(stuff << ": " << GetErrorMessage(number))
     78                BOX_WARNING(stuff << ": " << Win32::GetErrorMessage(number))
    7979        #define BOX_LOG_NATIVE_ERROR(stuff)   BOX_LOG_WIN_ERROR(stuff)
    8080        #define BOX_LOG_NATIVE_WARNING(stuff) BOX_LOG_WIN_WARNING(stuff)
  • box/invisnet/vs2010/0.11/lib/common/Timer.cpp

    r2767 r3055  
    429429                == FALSE)
    430430        {
    431                 BOX_ERROR(TIMER_ID "failed to create timer: " <<
    432                         GetErrorMessage(GetLastError()));
     431                BOX_LOG_WIN_ERROR(TIMER_ID "failed to create timer");
    433432                mTimerHandle = INVALID_HANDLE_VALUE;
    434433        }
     
    455454                        INVALID_HANDLE_VALUE) == FALSE)
    456455                {
    457                         BOX_ERROR(TIMER_ID "failed to delete timer: " <<
    458                                 GetErrorMessage(GetLastError()));
     456                        BOX_LOG_WIN_ERROR(TIMER_ID "failed to delete timer");
    459457                }
    460458                mTimerHandle = INVALID_HANDLE_VALUE;
  • box/invisnet/vs2010/0.11/lib/common/WaitForEvent.cpp

    r456 r3055  
    164164       
    165165        // Poll!
    166         switch(::poll(mpPollInfo, mItems.size(), mTimeout))
     166        switch(EMU_POLL(mpPollInfo, mItems.size(), mTimeout))
    167167        {
    168168        case -1:
  • box/invisnet/vs2010/0.11/lib/server/Daemon.cpp

    r2500 r3055  
    1010#include "Box.h"
    1111
     12#ifdef HAVE_PROCESS_H
     13        #include <process.h>
     14#endif
    1215#ifdef HAVE_UNISTD_H
    1316        #include <unistd.h>
  • box/invisnet/vs2010/0.11/lib/server/LocalProcessStream.cpp

    r2659 r3055  
    122122        if(!CreatePipe(&readFromChild, &writeInChild, &secAttr, 0))
    123123        {
    124                 BOX_ERROR("Failed to CreatePipe for child process: " <<
    125                         GetErrorMessage(GetLastError()));
     124                BOX_LOG_WIN_ERROR("Failed to CreatePipe for child process");
    126125                THROW_EXCEPTION(ServerException, SocketPairFailed)
    127126        }
     
    157156        if(!result)
    158157        {
    159                 BOX_ERROR("Failed to CreateProcess: '" << rCommandLine <<
    160                         "': " << GetErrorMessage(GetLastError()));
     158                BOX_LOG_WIN_ERROR("Failed to CreateProcess: '" << rCommandLine);
    161159                CloseHandle(writeInChild);
    162160                CloseHandle(readFromChild);
  • box/invisnet/vs2010/0.11/lib/server/SocketStream.cpp

    r2451 r3055  
    214214                p.events = POLLIN;
    215215                p.revents = 0;
    216                 switch(::poll(&p, 1, (Timeout == IOStream::TimeOutInfinite)?INFTIM:Timeout))
     216                switch(EMU_POLL(&p, 1, (Timeout == IOStream::TimeOutInfinite)?INFTIM:Timeout))
    217217                {
    218218                case -1:
     
    333333                        p.revents = 0;
    334334                       
    335                         if(::poll(&p, 1, 16000 /* 16 seconds */) == -1)
     335                        if(EMU_POLL(&p, 1, 16000 /* 16 seconds */) == -1)
    336336                        {
    337337                                // Don't exception if it's just a signal
  • box/invisnet/vs2010/0.11/lib/server/SocketStreamTLS.cpp

    r2792 r3055  
    262262                        poll_timeout = INFTIM;
    263263                }
    264                 result = ::poll(&p, 1, poll_timeout);
     264                result = EMU_POLL(&p, 1, poll_timeout);
    265265        }
    266266        while(result == -1 && errno == EINTR);
  • box/invisnet/vs2010/0.11/lib/server/WinNamedPipeStream.cpp

    r2792 r3055  
    2626
    2727#include "MemLeakFindOn.h"
     28
     29using namespace Win32;
    2830
    2931std::string WinNamedPipeStream::sPipeNamePrefix = "\\\\.\\pipe\\";
  • box/invisnet/vs2010/0.11/lib/win32/emu.cpp

    r2790 r3055  
    1 // Box Backup Win32 native port by Nick Knight
     1#include "Box.h"
    22
    3 // Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW
    4 #define WINVER 0x0500
     3#include <cstdio>
    54
    6 #include "emu.h"
    75
    8 #ifdef WIN32
     6using namespace Win32;
    97
    10 #include <assert.h>
    11 #include <fcntl.h>
    12 #include <process.h>
    13 #include <windows.h>
    14 #include "Shlobj.h"
    15 #include "Shlwapi.h"
    168
    17 #ifdef HAVE_UNISTD_H
    18         #include <unistd.h>
    19 #endif
    20 
    21 #include <string>
    22 #include <list>
    23 #include <sstream>
    24 
    25 // message resource definitions for syslog()
    26 #include "messages.h"
    27 
    28 DWORD winerrno;
    299struct passwd gTempPasswd;
    3010
    31 bool EnableBackupRights()
    32 {
    33         HANDLE hToken;
    34         TOKEN_PRIVILEGES token_priv;
    35 
    36         //open current process to adjust privileges
    37         if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
    38                 &hToken))
    39         {
    40                 ::syslog(LOG_ERR, "Failed to open process token: %s",
    41                         GetErrorMessage(GetLastError()).c_str());
    42                 return false;
    43         }
    44 
    45         //let's build the token privilege struct -
    46         //first, look up the LUID for the backup privilege
    47 
    48         if (!LookupPrivilegeValue(
    49                 NULL, //this system
    50                 SE_BACKUP_NAME, //the name of the privilege
    51                 &( token_priv.Privileges[0].Luid ))) //result
    52         {
    53                 ::syslog(LOG_ERR, "Failed to lookup backup privilege: %s",
    54                         GetErrorMessage(GetLastError()).c_str());
    55                 CloseHandle(hToken);
    56                 return false;
    57         }
    58 
    59         token_priv.PrivilegeCount = 1;
    60         token_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    61 
    62         // now set the privilege
    63         // because we're going exit right after dumping the streams, there isn't
    64         // any need to save current state
    65 
    66         if (!AdjustTokenPrivileges(
    67                 hToken, //our process token
    68                 false,  //we're not disabling everything
    69                 &token_priv, //address of structure
    70                 sizeof(token_priv), //size of structure
    71                 NULL, NULL)) //don't save current state
    72         {
    73                 //this function is a little tricky - if we were adjusting
    74                 //more than one privilege, it could return success but not
    75                 //adjust them all - in the general case, you need to trap this
    76                 ::syslog(LOG_ERR, "Failed to enable backup privilege: %s",
    77                         GetErrorMessage(GetLastError()).c_str());
    78                 CloseHandle(hToken);
    79                 return false;
    80 
    81         }
    82 
    83         CloseHandle(hToken);
    84         return true;
    85 }
    86 
    87 // forward declaration
    88 char* ConvertFromWideString(const WCHAR* pString, unsigned int codepage);
    8911
    9012// --------------------------------------------------------------------------
     
    9921//
    10022// --------------------------------------------------------------------------
    101 std::string GetDefaultConfigFilePath(const std::string& rName)
     23std::string GetDefaultConfigFilePath(const std::string& rName) throw()
    10224{
    10325        // we just ask the system where to get the file...
    104         char path[MAX_PATH];
     26        wchar_t path[MAX_PATH];
    10527
    106         if(FAILED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA,NULL,0,path))
    107                 || FALSE == PathAppend(path,"Box Backup")
    108                 || FALSE == PathAppend(path,rName.c_str()))
     28        try
    10929        {
    110                 return "";
    111         }
    112 
    113         return std::string(path);
    114 }
    115 
    116 // --------------------------------------------------------------------------
    117 //
    118 // Function
    119 //              Name:    ConvertToWideString
    120 //              Purpose: Converts a string from specified codepage to
    121 //                       a wide string (WCHAR*). Returns a buffer which
    122 //                       MUST be freed by the caller with delete[].
    123 //                       In case of fire, logs the error and returns NULL.
    124 //              Created: 4th February 2006
    125 //
    126 // --------------------------------------------------------------------------
    127 WCHAR* ConvertToWideString(const char* pString, unsigned int codepage,
    128         bool logErrors)
    129 {
    130         int len = MultiByteToWideChar
    131         (
    132                 codepage, // source code page
    133                 0,        // character-type options
    134                 pString,  // string to map
    135                 -1,       // number of bytes in string - auto detect
    136                 NULL,     // wide-character buffer
    137                 0         // size of buffer - work out
    138                           //   how much space we need
    139         );
    140 
    141         if (len == 0)
    142         {
    143                 winerrno = GetLastError();
    144                 if (logErrors)
     30                if(SUCCEEDED(SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,path))
     31                        && PathAppendW(path,L"Box Backup")
     32                        && PathAppendW(path,multi2wide(rName.c_str()).c_str()))
    14533                {
    146                         ::syslog(LOG_WARNING,
    147                                 "Failed to convert string to wide string: "
    148                                 "%s", GetErrorMessage(winerrno).c_str());
    149                 }
    150                 errno = EINVAL;
    151                 return NULL;
    152         }
    153 
    154         WCHAR* buffer = new WCHAR[len];
    155 
    156         if (buffer == NULL)
    157         {
    158                 if (logErrors)
    159                 {
    160                         ::syslog(LOG_WARNING,
    161                                 "Failed to convert string to wide string: "
    162                                 "out of memory");
    163                 }
    164                 winerrno = ERROR_OUTOFMEMORY;
    165                 errno = ENOMEM;
    166                 return NULL;
    167         }
    168 
    169         len = MultiByteToWideChar
    170         (
    171                 codepage, // source code page
    172                 0,        // character-type options
    173                 pString,  // string to map
    174                 -1,       // number of bytes in string - auto detect
    175                 buffer,   // wide-character buffer
    176                 len       // size of buffer
    177         );
    178 
    179         if (len == 0)
    180         {
    181                 winerrno = GetLastError();
    182                 if (logErrors)
    183                 {
    184                         ::syslog(LOG_WARNING,
    185                                 "Failed to convert string to wide string: "
    186                                 "%s", GetErrorMessage(winerrno).c_str());
    187                 }
    188                 errno = EACCES;
    189                 delete [] buffer;
    190                 return NULL;
    191         }
    192 
    193         return buffer;
    194 }
    195 
    196 // --------------------------------------------------------------------------
    197 //
    198 // Function
    199 //              Name:    ConvertUtf8ToWideString
    200 //              Purpose: Converts a string from UTF-8 to a wide string.
    201 //                       Returns a buffer which MUST be freed by the caller
    202 //                       with delete[].
    203 //                       In case of fire, logs the error and returns NULL.
    204 //              Created: 4th February 2006
    205 //
    206 // --------------------------------------------------------------------------
    207 WCHAR* ConvertUtf8ToWideString(const char* pString)
    208 {
    209         return ConvertToWideString(pString, CP_UTF8, true);
    210 }
    211 
    212 // --------------------------------------------------------------------------
    213 //
    214 // Function
    215 //              Name:    ConvertFromWideString
    216 //              Purpose: Converts a wide string to a narrow string in the
    217 //                       specified code page. Returns a buffer which MUST
    218 //                       be freed by the caller with delete[].
    219 //                       In case of fire, logs the error and returns NULL.
    220 //              Created: 4th February 2006
    221 //
    222 // --------------------------------------------------------------------------
    223 char* ConvertFromWideString(const WCHAR* pString, unsigned int codepage)
    224 {
    225         int len = WideCharToMultiByte
    226         (
    227                 codepage, // destination code page
    228                 0,        // character-type options
    229                 pString,  // string to map
    230                 -1,       // number of bytes in string - auto detect
    231                 NULL,     // output buffer
    232                 0,        // size of buffer - work out
    233                           //   how much space we need
    234                 NULL,     // replace unknown chars with system default
    235                 NULL      // don't tell us when that happened
    236         );
    237 
    238         if (len == 0)
    239         {
    240                 ::syslog(LOG_WARNING,
    241                         "Failed to convert wide string to narrow: "
    242                         "error %d", GetLastError());
    243                 errno = EINVAL;
    244                 return NULL;
    245         }
    246 
    247         char* buffer = new char[len];
    248 
    249         if (buffer == NULL)
    250         {
    251                 ::syslog(LOG_WARNING,
    252                         "Failed to convert wide string to narrow: "
    253                         "out of memory");
    254                 errno = ENOMEM;
    255                 return NULL;
    256         }
    257 
    258         len = WideCharToMultiByte
    259         (
    260                 codepage, // source code page
    261                 0,        // character-type options
    262                 pString,  // string to map
    263                 -1,       // number of bytes in string - auto detect
    264                 buffer,   // output buffer
    265                 len,      // size of buffer
    266                 NULL,     // replace unknown chars with system default
    267                 NULL      // don't tell us when that happened
    268         );
    269 
    270         if (len == 0)
    271         {
    272                 ::syslog(LOG_WARNING,
    273                         "Failed to convert wide string to narrow: "
    274                         "error %i", GetLastError());
    275                 errno = EACCES;
    276                 delete [] buffer;
    277                 return NULL;
    278         }
    279 
    280         return buffer;
    281 }
    282 
    283 // --------------------------------------------------------------------------
    284 //
    285 // Function
    286 //              Name:    ConvertEncoding(const std::string&, int,
    287 //                       std::string&, int)
    288 //              Purpose: Converts a string from one code page to another.
    289 //                       On success, replaces contents of rDest and returns
    290 //                       true. In case of fire, logs the error and returns
    291 //                       false.
    292 //              Created: 15th October 2006
    293 //
    294 // --------------------------------------------------------------------------
    295 bool ConvertEncoding(const std::string& rSource, int sourceCodePage,
    296         std::string& rDest, int destCodePage)
    297 {
    298         WCHAR* pWide = ConvertToWideString(rSource.c_str(), sourceCodePage,
    299                 true);
    300         if (pWide == NULL)
    301         {
    302                 ::syslog(LOG_ERR, "Failed to convert string '%s' from "
    303                         "current code page %d to wide string: %s",
    304                         rSource.c_str(), sourceCodePage,
    305                         GetErrorMessage(GetLastError()).c_str());
    306                 return false;
    307         }
    308 
    309         char* pConsole = ConvertFromWideString(pWide, destCodePage);
    310         delete [] pWide;
    311 
    312         if (!pConsole)
    313         {
    314                 // Error should have been logged by ConvertFromWideString
    315                 return false;
    316         }
    317 
    318         rDest = pConsole;
    319         delete [] pConsole;
    320 
    321         return true;
    322 }
    323 
    324 bool ConvertToUtf8(const std::string& rSource, std::string& rDest,
    325         int sourceCodePage)
    326 {
    327         return ConvertEncoding(rSource, sourceCodePage, rDest, CP_UTF8);
    328 }
    329 
    330 bool ConvertFromUtf8(const std::string& rSource, std::string& rDest,
    331         int destCodePage)
    332 {
    333         return ConvertEncoding(rSource, CP_UTF8, rDest, destCodePage);
    334 }
    335 
    336 bool ConvertConsoleToUtf8(const std::string& rSource, std::string& rDest)
    337 {
    338         return ConvertToUtf8(rSource, rDest, GetConsoleCP());
    339 }
    340 
    341 bool ConvertUtf8ToConsole(const std::string& rSource, std::string& rDest)
    342 {
    343         return ConvertFromUtf8(rSource, rDest, GetConsoleOutputCP());
    344 }
    345 
    346 // --------------------------------------------------------------------------
    347 //
    348 // Function
    349 //              Name:    ConvertPathToAbsoluteUnicode
    350 //              Purpose: Converts relative paths to absolute (with unicode marker)
    351 //              Created: 4th February 2006
    352 //
    353 // --------------------------------------------------------------------------
    354 std::string ConvertPathToAbsoluteUnicode(const char *pFileName)
    355 {
    356         std::string filename;
    357         for (int i = 0; pFileName[i] != 0; i++)
    358         {
    359                 if (pFileName[i] == '/')
    360                 {
    361                         filename += '\\';
    362                 }
    363                 else
    364                 {
    365                         filename += pFileName[i];
     34                        return wide2multi(path);
    36635                }
    36736        }
    368 
    369         std::string tmpStr("\\\\?\\");
    370 
    371         // Is the path relative or absolute?
    372         // Absolute paths on Windows are always a drive letter
    373         // followed by ':'
    374 
    375         char wd[PATH_MAX];
    376         if (::getcwd(wd, PATH_MAX) == 0)
    377         {
    378                 ::syslog(LOG_WARNING,
    379                         "Failed to open '%s': path too long",
    380                         pFileName);
    381                 errno = ENAMETOOLONG;
    382                 winerrno = ERROR_INVALID_NAME;
    383                 tmpStr = "";
    384                 return tmpStr;
    385         }
    386 
    387         if (filename.length() > 2 && filename[0] == '\\' &&
    388                 filename[1] == '\\')
    389         {
    390                 tmpStr += "UNC\\";
    391                 filename.replace(0, 2, "");
    392                 // \\?\UNC\<server>\<share>
    393                 // see http://msdn2.microsoft.com/en-us/library/aa365247.aspx
    394         }
    395         else if (filename.length() >= 1 && filename[0] == '\\')
    396         {
    397                 // root directory of current drive.
    398                 tmpStr = wd;
    399                 tmpStr.resize(2); // drive letter and colon
    400         }
    401         else if (filename.length() >= 2 && filename[1] != ':')
    402         {
    403                 // Must be relative. We need to get the
    404                 // current directory to make it absolute.
    405                 tmpStr += wd;
    406                 if (tmpStr[tmpStr.length()] != '\\')
    407                 {
    408                         tmpStr += '\\';
    409                 }
    410         }
    411 
    412         tmpStr += filename;
    413 
    414         // We are using direct filename access, which does not support ..,
    415         // so we need to implement it ourselves.
    416 
    417         for (std::string::size_type i = 1; i < tmpStr.size() - 3; i++)
    418         {
    419                 if (tmpStr.substr(i, 3) == "\\..")
    420                 {
    421                         std::string::size_type lastSlash =
    422                                 tmpStr.rfind('\\', i - 1);
    423 
    424                         if (lastSlash == std::string::npos)
    425                         {
    426                                 // no previous directory, ignore it,
    427                                 // CreateFile will fail with error 123
    428                         }
    429                         else
    430                         {
    431                                 tmpStr.replace(lastSlash, i + 3 - lastSlash,
    432                                         "");
    433                         }
    434 
    435                         i = lastSlash;
    436                 }
    437         }
    438 
    439         return tmpStr;
    440 }
    441 
    442 std::string GetErrorMessage(DWORD errorCode)
    443 {
    444         char* pMsgBuf = NULL;
    445 
    446         DWORD chars = FormatMessage
    447         (
    448                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
    449                 FORMAT_MESSAGE_FROM_SYSTEM,
    450                 NULL,
    451                 errorCode,
    452                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    453                 (char *)(&pMsgBuf),
    454                 0, NULL
    455         );
    456 
    457         if (chars == 0 || pMsgBuf == NULL)
    458         {
    459                 return std::string("failed to get error message");
    460         }
    461 
    462         // remove embedded newline
    463         pMsgBuf[chars - 1] = 0;
    464         pMsgBuf[chars - 2] = 0;
    465 
    466         std::ostringstream line;
    467         line << pMsgBuf << " (" << errorCode << ")";
    468         LocalFree(pMsgBuf);
    469 
    470         return line.str();
    471 }
    472 
    473 // --------------------------------------------------------------------------
    474 //
    475 // Function
    476 //              Name:    openfile
    477 //              Purpose: replacement for any open calls - handles unicode
    478 //                      filenames - supplied in utf8
    479 //              Created: 25th October 2004
    480 //
    481 // --------------------------------------------------------------------------
    482 HANDLE openfile(const char *pFileName, int flags, int mode)
    483 {
    484         winerrno = ERROR_INVALID_FUNCTION;
    485 
    486         std::string AbsPathWithUnicode =
    487                 ConvertPathToAbsoluteUnicode(pFileName);
    488 
    489         if (AbsPathWithUnicode.size() == 0)
    490         {
    491                 // error already logged by ConvertPathToAbsoluteUnicode()
    492                 return INVALID_HANDLE_VALUE;
    493         }
    494 
    495         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    496         // We are responsible for freeing pBuffer
    497 
    498         if (pBuffer == NULL)
    499         {
    500                 // error already logged by ConvertUtf8ToWideString()
    501                 return INVALID_HANDLE_VALUE;
    502         }
    503 
    504         // flags could be O_WRONLY | O_CREAT | O_RDONLY
    505         DWORD createDisposition = OPEN_EXISTING;
    506         DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE
    507                 | FILE_SHARE_DELETE;
    508         DWORD accessRights = FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY
    509                 | FILE_READ_EA;
    510 
    511         if (flags & O_WRONLY)
    512         {
    513                 accessRights = FILE_WRITE_DATA;
    514         }
    515         else if (flags & O_RDWR)
    516         {
    517                 accessRights |= FILE_WRITE_ATTRIBUTES
    518                         | FILE_WRITE_DATA | FILE_WRITE_EA;
    519         }
    520 
    521         if (flags & O_CREAT)
    522         {
    523                 createDisposition = OPEN_ALWAYS;
    524         }
    525 
    526         if (flags & O_TRUNC)
    527         {
    528                 createDisposition = CREATE_ALWAYS;
    529         }
    530 
    531         if ((flags & O_CREAT) && (flags & O_EXCL))
    532         {
    533                 createDisposition = CREATE_NEW;
    534         }
    535 
    536         if (flags & O_LOCK)
    537         {
    538                 shareMode = 0;
    539         }
    540 
    541         DWORD winFlags = FILE_FLAG_BACKUP_SEMANTICS;
    542         if (flags & O_TEMPORARY)
    543         {
    544                 winFlags  |= FILE_FLAG_DELETE_ON_CLOSE;
    545         }
    546 
    547         HANDLE hdir = CreateFileW(pBuffer,
    548                 accessRights,
    549                 shareMode,
    550                 NULL,
    551                 createDisposition,
    552                 winFlags,
    553                 NULL);
    554 
    555         delete [] pBuffer;
    556 
    557         if (hdir == INVALID_HANDLE_VALUE)
    558         {
    559                 winerrno = GetLastError();
    560                 switch(winerrno)
    561                 {
    562                         case ERROR_SHARING_VIOLATION:
    563                         errno = EBUSY;
    564                         break;
    565 
    566                         default:
    567                         errno = EINVAL;
    568                 }
    569 
    570                 ::syslog(LOG_WARNING, "Failed to open file '%s': "
    571                         "%s", pFileName,
    572                         GetErrorMessage(GetLastError()).c_str());
    573 
    574                 return INVALID_HANDLE_VALUE;
    575         }
    576 
    577         if (flags & O_APPEND)
    578         {
    579                 if (SetFilePointer(hdir, 0, NULL, FILE_END) ==
    580                         INVALID_SET_FILE_POINTER)
    581                 {
    582                         winerrno = GetLastError();
    583                         errno = EINVAL;
    584                         CloseHandle(hdir);
    585                         return INVALID_HANDLE_VALUE;
    586                 }
    587         }
    588 
    589         winerrno = NO_ERROR;
    590         return hdir;
    591 }
    592 
    593 // --------------------------------------------------------------------------
    594 //
    595 // Function
    596 //              Name:    emu_fstat
    597 //              Purpose: replacement for fstat. Supply a windows handle.
    598 //                       Returns a struct emu_stat to have room for 64-bit
    599 //                       file identifier in st_ino (mingw allows only 16!)
    600 //              Created: 25th October 2004
    601 //
    602 // --------------------------------------------------------------------------
    603 int emu_fstat(HANDLE hdir, struct emu_stat * st)
    604 {
    605         if (hdir == INVALID_HANDLE_VALUE)
    606         {
    607                 ::syslog(LOG_ERR, "Error: invalid file handle in emu_fstat()");
    608                 errno = EBADF;
    609                 return -1;
    610         }
    611 
    612         BY_HANDLE_FILE_INFORMATION fi;
    613         if (!GetFileInformationByHandle(hdir, &fi))
    614         {
    615                 ::syslog(LOG_WARNING, "Failed to read file information: "
    616                         "%s", GetErrorMessage(GetLastError()).c_str());
    617                 errno = EACCES;
    618                 return -1;
    619         }
    620 
    621         if (INVALID_FILE_ATTRIBUTES == fi.dwFileAttributes)
    622         {
    623                 ::syslog(LOG_WARNING, "Failed to get file attributes: "
    624                         "%s", GetErrorMessage(GetLastError()).c_str());
    625                 errno = EACCES;
    626                 return -1;
    627         }
    628 
    629         memset(st, 0, sizeof(*st));
    630 
    631         // This is how we get our INODE (equivalent) information
    632         ULARGE_INTEGER conv;
    633         conv.HighPart = fi.nFileIndexHigh;
    634         conv.LowPart  = fi.nFileIndexLow;
    635         st->st_ino = conv.QuadPart;
    636 
    637         // get the time information
    638         st->st_ctime = ConvertFileTimeToTime_t(&fi.ftCreationTime);
    639         st->st_atime = ConvertFileTimeToTime_t(&fi.ftLastAccessTime);
    640         st->st_mtime = ConvertFileTimeToTime_t(&fi.ftLastWriteTime);
    641 
    642         if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    643         {
    644                 st->st_size = 0;
    645         }
    646         else
    647         {
    648                 conv.HighPart = fi.nFileSizeHigh;
    649                 conv.LowPart  = fi.nFileSizeLow;
    650                 st->st_size = (_off_t)conv.QuadPart;
    651         }
    652 
    653         // at the mo
    654         st->st_uid = 0;
    655         st->st_gid = 0;
    656         st->st_nlink = 1;
    657 
    658         // the mode of the file
    659         // mode zero will make it impossible to restore on Unix
    660         // (no access to anybody, including the owner).
    661         // we'll fake a sensible mode:
    662         // all objects get user read (0400)
    663         // if it's a directory it gets user execute (0100)
    664         // if it's not read-only it gets user write (0200)
    665         st->st_mode = S_IREAD;
    666 
    667         if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    668         {
    669                 st->st_mode |= S_IFDIR | S_IEXEC;
    670         }
    671         else
    672         {
    673                 st->st_mode |= S_IFREG;
    674         }
    675 
    676         if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
    677         {
    678                 st->st_mode |= S_IWRITE;
    679         }
    680 
    681         // st_dev is normally zero, regardless of the drive letter,
    682         // since backup locations can't normally span drives. However,
    683         // a reparse point does allow all kinds of weird stuff to happen.
    684         // We set st_dev to 1 for a reparse point, so that Box will detect
    685         // a change of device number (from 0) and refuse to recurse down
    686         // the reparse point (which could lead to havoc).
    687 
    688         if (fi.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
    689         {
    690                 st->st_dev = 1;
    691         }
    692         else
    693         {
    694                 st->st_dev = 0;
    695         }
    696 
    697         return 0;
    698 }
    699 
    700 // --------------------------------------------------------------------------
    701 //
    702 // Function
    703 //              Name:    OpenFileByNameUtf8
    704 //              Purpose: Converts filename to Unicode and returns
    705 //                      a handle to it. In case of error, sets errno,
    706 //                      logs the error and returns NULL.
    707 //              Created: 10th December 2004
    708 //
    709 // --------------------------------------------------------------------------
    710 HANDLE OpenFileByNameUtf8(const char* pFileName, DWORD flags)
    711 {
    712         std::string AbsPathWithUnicode =
    713                 ConvertPathToAbsoluteUnicode(pFileName);
    714 
    715         if (AbsPathWithUnicode.size() == 0)
    716         {
    717                 // error already logged by ConvertPathToAbsoluteUnicode()
    718                 return NULL;
    719         }
    720 
    721         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    722         // We are responsible for freeing pBuffer
    723 
    724         if (pBuffer == NULL)
    725         {
    726                 // error already logged by ConvertUtf8ToWideString()
    727                 return NULL;
    728         }
    729 
    730         HANDLE handle = CreateFileW(pBuffer,
    731                 flags,
    732                 FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,
    733                 NULL,
    734                 OPEN_EXISTING,
    735                 FILE_FLAG_BACKUP_SEMANTICS,
    736                 NULL);
    737 
    738         if (handle == INVALID_HANDLE_VALUE)
    739         {
    740                 // if our open fails we should always be able to
    741                 // open in this mode - to get the inode information
    742                 // at least one process must have the file open -
    743                 // in this case someone else does.
    744                 handle = CreateFileW(pBuffer,
    745                         READ_CONTROL,
    746                         FILE_SHARE_READ,
    747                         NULL,
    748                         OPEN_EXISTING,
    749                         FILE_FLAG_BACKUP_SEMANTICS,
    750                         NULL);
    751         }
    752 
    753         delete [] pBuffer;
    754 
    755         if (handle == INVALID_HANDLE_VALUE)
    756         {
    757                 DWORD err = GetLastError();
    758 
    759                 if (err == ERROR_FILE_NOT_FOUND ||
    760                         err == ERROR_PATH_NOT_FOUND)
    761                 {
    762                         errno = ENOENT;
    763                 }
    764                 else
    765                 {
    766                         ::syslog(LOG_WARNING, "Failed to open '%s': "
    767                                 "%s", pFileName,
    768                                 GetErrorMessage(err).c_str());
    769                         errno = EACCES;
    770                 }
    771 
    772                 return NULL;
    773         }
    774 
    775         return handle;
    776 }
    777 
    778 // --------------------------------------------------------------------------
    779 //
    780 // Function
    781 //              Name:    emu_stat
    782 //              Purpose: replacement for the lstat and stat functions.
    783 //                       Works with unicode filenames supplied in utf8.
    784 //                       Returns a struct emu_stat to have room for 64-bit
    785 //                       file identifier in st_ino (mingw allows only 16!)
    786 //              Created: 25th October 2004
    787 //
    788 // --------------------------------------------------------------------------
    789 int emu_stat(const char * pName, struct emu_stat * st)
    790 {
    791         HANDLE handle = OpenFileByNameUtf8(pName,
    792                 FILE_READ_ATTRIBUTES | FILE_READ_EA);
    793 
    794         if (handle == NULL)
    795         {
    796                 // errno already set and error logged by OpenFileByNameUtf8()
    797                 return -1;
    798         }
    799 
    800         int retVal = emu_fstat(handle, st);
    801         if (retVal != 0)
    802         {
    803                 // error logged, but without filename
    804                 ::syslog(LOG_WARNING, "Failed to get file information "
    805                         "for '%s'", pName);
    806         }
    807 
    808         // close the handle
    809         CloseHandle(handle);
    810 
    811         return retVal;
    812 }
    813 
    814 // --------------------------------------------------------------------------
    815 //
    816 // Function
    817 //              Name:    statfs
    818 //              Purpose: returns the mount point of where a file is located -
    819 //                      in this case the volume serial number
    820 //              Created: 25th October 2004
    821 //
    822 // --------------------------------------------------------------------------
    823 int statfs(const char * pName, struct statfs * s)
    824 {
    825         HANDLE handle = OpenFileByNameUtf8(pName,
    826                 FILE_READ_ATTRIBUTES | FILE_READ_EA);
    827 
    828         if (handle == NULL)
    829         {
    830                 // errno already set and error logged by OpenFileByNameUtf8()
    831                 return -1;
    832         }
    833 
    834         BY_HANDLE_FILE_INFORMATION fi;
    835         if (!GetFileInformationByHandle(handle, &fi))
    836         {
    837                 ::syslog(LOG_WARNING, "Failed to get file information "
    838                         "for '%s': %s", pName,
    839                         GetErrorMessage(GetLastError()).c_str());
    840                 CloseHandle(handle);
    841                 errno = EACCES;
    842                 return -1;
    843         }
    844 
    845         // convert volume serial number to a string
    846         _ui64toa(fi.dwVolumeSerialNumber, s->f_mntonname + 1, 16);
    847 
    848         // pseudo unix mount point
    849         s->f_mntonname[0] = '\\';
    850 
    851         CloseHandle(handle);   // close the handle
    852 
    853         return 0;
    854 }
    855 
    856 // --------------------------------------------------------------------------
    857 //
    858 // Function
    859 //              Name:    emu_utimes
    860 //              Purpose: replacement for the POSIX utimes() function,
    861 //                      works with unicode filenames supplied in utf8 format,
    862 //                      sets creation time instead of last access time.
    863 //              Created: 25th July 2006
    864 //
    865 // --------------------------------------------------------------------------
    866 int emu_utimes(const char * pName, const struct timeval times[])
    867 {
    868         FILETIME creationTime;
    869         if (!ConvertTime_tToFileTime(times[0].tv_sec, &creationTime))
    870         {
    871                 errno = EINVAL;
    872                 return -1;
    873         }
    874 
    875         FILETIME modificationTime;
    876         if (!ConvertTime_tToFileTime(times[1].tv_sec, &modificationTime))
    877         {
    878                 errno = EINVAL;
    879                 return -1;
    880         }
    881 
    882         HANDLE handle = OpenFileByNameUtf8(pName, FILE_WRITE_ATTRIBUTES);
    883 
    884         if (handle == NULL)
    885         {
    886                 // errno already set and error logged by OpenFileByNameUtf8()
    887                 return -1;
    888         }
    889 
    890         if (!SetFileTime(handle, &creationTime, NULL, &modificationTime))
    891         {
    892                 ::syslog(LOG_ERR, "Failed to set times on '%s': %s", pName,
    893                         GetErrorMessage(GetLastError()).c_str());
    894                 CloseHandle(handle);
    895                 return 1;
    896         }
    897 
    898         CloseHandle(handle);
    899         return 0;
    900 }
    901 
    902 // --------------------------------------------------------------------------
    903 //
    904 // Function
    905 //              Name:    emu_chmod
    906 //              Purpose: replacement for the POSIX chmod function,
    907 //                      works with unicode filenames supplied in utf8 format
    908 //              Created: 26th July 2006
    909 //
    910 // --------------------------------------------------------------------------
    911 int emu_chmod(const char * pName, mode_t mode)
    912 {
    913         std::string AbsPathWithUnicode =
    914                 ConvertPathToAbsoluteUnicode(pName);
    915 
    916         if (AbsPathWithUnicode.size() == 0)
    917         {
    918                 // error already logged by ConvertPathToAbsoluteUnicode()
    919                 return -1;
    920         }
    921 
    922         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    923         // We are responsible for freeing pBuffer
    924 
    925         if (pBuffer == NULL)
    926         {
    927                 // error already logged by ConvertUtf8ToWideString()
    928                 free(pBuffer);
    929                 return -1;
    930         }
    931 
    932         DWORD attribs = GetFileAttributesW(pBuffer);
    933         if (attribs == INVALID_FILE_ATTRIBUTES)
    934         {
    935                 ::syslog(LOG_ERR, "Failed to get file attributes of '%s': %s",
    936                         pName, GetErrorMessage(GetLastError()).c_str());
    937                 errno = EACCES;
    938                 free(pBuffer);
    939                 return -1;
    940         }
    941 
    942         if (mode & S_IWRITE)
    943         {
    944                 attribs &= ~FILE_ATTRIBUTE_READONLY;
    945         }
    946         else
    947         {
    948                 attribs |= FILE_ATTRIBUTE_READONLY;
    949         }
    950 
    951         if (!SetFileAttributesW(pBuffer, attribs))
    952         {
    953                 ::syslog(LOG_ERR, "Failed to set file attributes of '%s': %s",
    954                         pName, GetErrorMessage(GetLastError()).c_str());
    955                 errno = EACCES;
    956                 free(pBuffer);
    957                 return -1;
    958         }
    959 
    960         delete [] pBuffer;
    961         return 0;
     37        EMU_EXCEPTION_HANDLING_RETURN("")
    96238}
    96339
    96440
    965 // --------------------------------------------------------------------------
    966 //
    967 // Function
    968 //              Name:    opendir
    969 //              Purpose: replacement for unix function, uses win32 findfirst routines
    970 //              Created: 25th October 2004
    971 //
    972 // --------------------------------------------------------------------------
    973 DIR *opendir(const char *name)
     41int console_read(char* pBuffer, const size_t BufferSize) throw()
    97442{
    975         if (!name || !name[0])
    976         {
    977                 errno = EINVAL;
    978                 return NULL;
    979         }
    980 
    981         std::string dirName(name);
    982 
    983         //append a '\' win32 findfirst is sensitive to this
    984         if ( dirName[dirName.size()-1] != '\\' || dirName[dirName.size()-1] != '/' )
    985         {
    986                 dirName += '\\';
    987         }
    988 
    989         // what is the search string? - everything
    990         dirName += '*';
    991 
    992         DIR *pDir = new DIR;
    993         if (pDir == NULL)
    994         {
    995                 errno = ENOMEM;
    996                 return NULL;
    997         }
    998 
    999         pDir->name = ConvertUtf8ToWideString(dirName.c_str());
    1000         // We are responsible for freeing dir->name with delete[]
    1001 
    1002         if (pDir->name == NULL)
    1003         {
    1004                 delete pDir;
    1005                 return NULL;
    1006         }
    1007 
    1008         pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info));
    1009 
    1010         if (pDir->fd == -1)
    1011         {
    1012                 delete [] pDir->name;
    1013                 delete pDir;
    1014                 return NULL;
    1015         }
    1016 
    1017         pDir->result.d_name = 0;
    1018         return pDir;
    1019 }
    1020 
    1021 // this kinda makes it not thread friendly!
    1022 // but I don't think it needs to be.
    1023 char tempbuff[MAX_PATH];
    1024 
    1025 // --------------------------------------------------------------------------
    1026 //
    1027 // Function
    1028 //              Name:    readdir
    1029 //              Purpose: as function above
    1030 //              Created: 25th October 2004
    1031 //
    1032 // --------------------------------------------------------------------------
    1033 struct dirent *readdir(DIR *dp)
    1034 {
     43        HANDLE hConsole;
     44       
    103545        try
    103646        {
    1037                 struct dirent *den = NULL;
     47                if (INVALID_HANDLE_VALUE == (hConsole = GetStdHandle(STD_INPUT_HANDLE)))
     48                        throw Win32Exception(Win32Exception::API_GetStdHandle);
    103849
    1039                 if (dp && dp->fd != -1)
    1040                 {
    1041                         if (!dp->result.d_name ||
    1042                                 _wfindnext(dp->fd, &dp->info) != -1)
    1043                         {
    1044                                 den = &dp->result;
    1045                                 std::wstring input(dp->info.name);
    1046                                 memset(tempbuff, 0, sizeof(tempbuff));
    1047                                 WideCharToMultiByte(CP_UTF8, 0, dp->info.name,
    1048                                         -1, &tempbuff[0], sizeof (tempbuff),
    1049                                         NULL, NULL);
    1050                                 //den->d_name = (char *)dp->info.name;
    1051                                 den->d_name = &tempbuff[0];
    1052                                 if (dp->info.attrib & FILE_ATTRIBUTE_DIRECTORY)
    1053                                 {
    1054                                         den->d_type = S_IFDIR;
    1055                                 }
    1056                                 else
    1057                                 {
    1058                                         den->d_type = S_IFREG;
    1059                                 }
    1060                         }
    1061                 }
    1062                 else
    1063                 {
    1064                         errno = EBADF;
    1065                 }
    1066                 return den;
     50                size_t wideSize = BufferSize / 5;
     51                std::unique_ptr<wchar_t[]> wide(new wchar_t[wideSize+1]);
     52
     53                DWORD numCharsRead = 0;
     54                if (!ReadConsoleW(hConsole,wide.get(),static_cast<DWORD>(wideSize),&numCharsRead,NULL))
     55                        throw Win32Exception(Win32Exception::API_ReadConsole);
     56
     57                wide[numCharsRead] = '\0';
     58                std::string multi(wide2multi(wide.get()));
     59                strcpy(pBuffer,multi.c_str());
     60
     61                return static_cast<int>(multi.size());
    106762        }
    1068         catch (...)
    1069         {
    1070                 printf("Caught readdir");
    1071         }
    1072         return NULL;
     63        EMU_EXCEPTION_HANDLING_RETURN(-1)
    107364}
    1074 
    1075 // --------------------------------------------------------------------------
    1076 //
    1077 // Function
    1078 //              Name:    closedir
    1079 //              Purpose: as function above
    1080 //              Created: 25th October 2004
    1081 //
    1082 // --------------------------------------------------------------------------
    1083 int closedir(DIR *dp)
    1084 {
    1085         try
    1086         {
    1087                 int finres = -1;
    1088                 if (dp)
    1089                 {
    1090                         if(dp->fd != -1)
    1091                         {
    1092                                 finres = _findclose(dp->fd);
    1093                         }
    1094 
    1095                         delete [] dp->name;
    1096                         delete dp;
    1097                 }
    1098 
    1099                 if (finres == -1) // errors go to EBADF
    1100                 {
    1101                         errno = EBADF;
    1102                 }
    1103 
    1104                 return finres;
    1105         }
    1106         catch (...)
    1107         {
    1108                 printf("Caught closedir");
    1109         }
    1110         return -1;
    1111 }
    1112 
    1113 // --------------------------------------------------------------------------
    1114 //
    1115 // Function
    1116 //              Name:    poll
    1117 //              Purpose: a weak implimentation (just enough for box)
    1118 //                      of the unix poll for winsock2
    1119 //              Created: 25th October 2004
    1120 //
    1121 // --------------------------------------------------------------------------
    1122 int poll (struct pollfd *ufds, unsigned long nfds, int timeout)
    1123 {
    1124         try
    1125         {
    1126                 fd_set readfd;
    1127                 fd_set writefd;
    1128 
    1129                 FD_ZERO(&readfd);
    1130                 FD_ZERO(&writefd);
    1131 
    1132                 // struct pollfd *ufdsTmp = ufds;
    1133 
    1134                 timeval timOut;
    1135                 timeval *tmpptr;
    1136 
    1137                 if (timeout == INFTIM)
    1138                         tmpptr = NULL;
    1139                 else
    1140                         tmpptr = &timOut;
    1141 
    1142                 timOut.tv_sec  = timeout / 1000;
    1143                 timOut.tv_usec = timeout * 1000;
    1144 
    1145                 for (unsigned long i = 0; i < nfds; i++)
    1146                 {
    1147                         struct pollfd* ufd = &(ufds[i]);
    1148 
    1149                         if (ufd->events & POLLIN)
    1150                         {
    1151                                 FD_SET(ufd->fd, &readfd);
    1152                         }
    1153 
    1154                         if (ufd->events & POLLOUT)
    1155                         {
    1156                                 FD_SET(ufd->fd, &writefd);
    1157                         }
    1158 
    1159                         if (ufd->events & ~(POLLIN | POLLOUT))
    1160                         {
    1161                                 printf("Unsupported poll bits %d",
    1162                                         ufd->events);
    1163                                 return -1;
    1164                         }
    1165                 }
    1166 
    1167                 int nready = select(0, &readfd, &writefd, 0, tmpptr);
    1168 
    1169                 if (nready == SOCKET_ERROR)
    1170                 {
    1171                         // int errval = WSAGetLastError();
    1172 
    1173                         struct pollfd* pufd = ufds;
    1174                         for (unsigned long i = 0; i < nfds; i++)
    1175                         {
    1176                                 pufd->revents = POLLERR;
    1177                                 pufd++;
    1178                         }
    1179                         return (-1);
    1180                 }
    1181                 else if (nready > 0)
    1182                 {
    1183                         for (unsigned long i = 0; i < nfds; i++)
    1184                         {
    1185                                 struct pollfd *ufd = &(ufds[i]);
    1186 
    1187                                 if (FD_ISSET(ufd->fd, &readfd))
    1188                                 {
    1189                                         ufd->revents |= POLLIN;
    1190                                 }
    1191 
    1192                                 if (FD_ISSET(ufd->fd, &writefd))
    1193                                 {
    1194                                         ufd->revents |= POLLOUT;
    1195                                 }
    1196                         }
    1197                 }
    1198 
    1199                 return nready;
    1200         }
    1201         catch (...)
    1202         {
    1203                 printf("Caught poll");
    1204         }
    1205 
    1206         return -1;
    1207 }
    1208 
    1209 // copied from MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/eventlog/base/adding_a_source_to_the_registry.asp
    1210 
    1211 BOOL AddEventSource
    1212 (
    1213         LPTSTR pszSrcName, // event source name
    1214         DWORD  dwNum       // number of categories
    1215 )
    1216 {
    1217         // Work out the executable file name, to register ourselves
    1218         // as the event source
    1219 
    1220         WCHAR cmd[MAX_PATH];
    1221         DWORD len = GetModuleFileNameW(NULL, cmd, MAX_PATH);
    1222 
    1223         if (len == 0)
    1224         {
    1225                 ::syslog(LOG_ERR, "Failed to get the program file name: %s",
    1226                         GetErrorMessage(GetLastError()).c_str());
    1227                 return FALSE;
    1228         }
    1229 
    1230         // Create the event source as a subkey of the log.
    1231 
    1232         std::string regkey("SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
    1233                 "Application\\");
    1234         regkey += pszSrcName;
    1235 
    1236         HKEY hk;
    1237         DWORD dwDisp;
    1238 
    1239         if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, regkey.c_str(),
    1240                          0, NULL, REG_OPTION_NON_VOLATILE,
    1241                          KEY_WRITE, NULL, &hk, &dwDisp))
    1242         {
    1243                 ::syslog(LOG_ERR, "Failed to create the registry key: %s",
    1244                         GetErrorMessage(GetLastError()).c_str());
    1245                 return FALSE;
    1246         }
    1247 
    1248         // Set the name of the message file.
    1249 
    1250         if (RegSetValueExW(hk,                 // subkey handle
    1251                            L"EventMessageFile", // value name
    1252                            0,                  // must be zero
    1253                            REG_EXPAND_SZ,      // value type
    1254                            (LPBYTE)cmd,        // pointer to value data
    1255                            len*sizeof(WCHAR))) // data size
    1256         {
    1257                 ::syslog(LOG_ERR, "Failed to set the event message file: %s",
    1258                         GetErrorMessage(GetLastError()).c_str());
    1259                 RegCloseKey(hk);
    1260                 return FALSE;
    1261         }
    1262 
    1263         // Set the supported event types.
    1264 
    1265         DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
    1266                   EVENTLOG_INFORMATION_TYPE;
    1267 
    1268         if (RegSetValueEx(hk,               // subkey handle
    1269                           "TypesSupported", // value name
    1270                           0,                // must be zero
    1271                           REG_DWORD,        // value type
    1272                           (LPBYTE) &dwData, // pointer to value data
    1273                           sizeof(DWORD)))   // length of value data
    1274         {
    1275                 ::syslog(LOG_ERR, "Failed to set the supported types: %s",
    1276                         GetErrorMessage(GetLastError()).c_str());
    1277                 RegCloseKey(hk);
    1278                 return FALSE;
    1279         }
    1280 
    1281         // Set the category message file and number of categories.
    1282 
    1283         if (RegSetValueExW(hk,                    // subkey handle
    1284                            L"CategoryMessageFile", // value name
    1285                            0,                     // must be zero
    1286                            REG_EXPAND_SZ,         // value type
    1287                            (LPBYTE)cmd,           // pointer to value data
    1288                            len*sizeof(WCHAR)))    // data size
    1289         {
    1290                 ::syslog(LOG_ERR, "Failed to set the category message file: "
    1291                         "%s", GetErrorMessage(GetLastError()).c_str());
    1292                 RegCloseKey(hk);
    1293                 return FALSE;
    1294         }
    1295 
    1296         if (RegSetValueEx(hk,              // subkey handle
    1297                           "CategoryCount", // value name
    1298                           0,               // must be zero
    1299                           REG_DWORD,       // value type
    1300                           (LPBYTE) &dwNum, // pointer to value data
    1301                           sizeof(DWORD)))  // length of value data
    1302         {
    1303                 ::syslog(LOG_ERR, "Failed to set the category count: %s",
    1304                         GetErrorMessage(GetLastError()).c_str());
    1305                 RegCloseKey(hk);
    1306                 return FALSE;
    1307         }
    1308 
    1309         RegCloseKey(hk);
    1310         return TRUE;
    1311 }
    1312 
    1313 static HANDLE gSyslogH = 0;
    1314 static bool sHaveWarnedEventLogFull = false;
    1315 
    1316 void openlog(const char * daemonName, int, int)
    1317 {
    1318         std::string nameStr = "Box Backup (";
    1319         nameStr += daemonName;
    1320         nameStr += ")";
    1321 
    1322         // register a default event source, so that we can
    1323         // log errors with the process of adding or registering our own.
    1324         gSyslogH = RegisterEventSource(
    1325                 NULL,        // uses local computer
    1326                 nameStr.c_str()); // source name
    1327         if (gSyslogH == NULL)
    1328         {
    1329         }
    1330 
    1331         char* name = strdup(nameStr.c_str());
    1332         BOOL success = AddEventSource(name, 0);
    1333         free(name);
    1334 
    1335         if (!success)
    1336         {
    1337                 ::syslog(LOG_ERR, "Failed to add our own event source");
    1338                 return;
    1339         }
    1340 
    1341         HANDLE newSyslogH = RegisterEventSource(NULL, nameStr.c_str());
    1342         if (newSyslogH == NULL)
    1343         {
    1344                 ::syslog(LOG_ERR, "Failed to register our own event source: "
    1345                         "%s", GetErrorMessage(GetLastError()).c_str());
    1346                 return;
    1347         }
    1348 
    1349         DeregisterEventSource(gSyslogH);
    1350         gSyslogH = newSyslogH;
    1351 }
    1352 
    1353 void closelog(void)
    1354 {
    1355         DeregisterEventSource(gSyslogH);
    1356 }
    1357 
    1358 void syslog(int loglevel, const char *frmt, ...)
    1359 {
    1360         WORD errinfo;
    1361         char buffer[1024];
    1362         std::string sixfour(frmt);
    1363 
    1364         switch (loglevel)
    1365         {
    1366         case LOG_INFO:
    1367                 errinfo = EVENTLOG_INFORMATION_TYPE;
    1368                 break;
    1369         case LOG_ERR:
    1370                 errinfo = EVENTLOG_ERROR_TYPE;
    1371                 break;
    1372         case LOG_WARNING:
    1373                 errinfo = EVENTLOG_WARNING_TYPE;
    1374                 break;
    1375         default:
    1376                 errinfo = EVENTLOG_WARNING_TYPE;
    1377                 break;
    1378         }
    1379 
    1380         // taken from MSDN
    1381         int sixfourpos;
    1382         while ( (sixfourpos = (int)sixfour.find("%ll")) != -1 )
    1383         {
    1384                 // maintain portability - change the 64 bit formater...
    1385                 std::string temp = sixfour.substr(0,sixfourpos);
    1386                 temp += "%I64";
    1387                 temp += sixfour.substr(sixfourpos+3, sixfour.length());
    1388                 sixfour = temp;
    1389         }
    1390 
    1391         // printf("parsed string is:%s\r\n", sixfour.c_str());
    1392 
    1393         va_list args;
    1394         va_start(args, frmt);
    1395 
    1396         int len = vsnprintf(buffer, sizeof(buffer)-1, sixfour.c_str(), args);
    1397         assert(len >= 0);
    1398         if (len < 0)
    1399         {
    1400                 printf("%s\r\n", buffer);
    1401                 fflush(stdout);
    1402                 return;
    1403         }
    1404 
    1405         assert((size_t)len < sizeof(buffer));
    1406         buffer[sizeof(buffer)-1] = 0;
    1407 
    1408         va_end(args);
    1409 
    1410         if (gSyslogH == 0)
    1411         {
    1412                 printf("%s\r\n", buffer);
    1413                 fflush(stdout);
    1414                 return;
    1415         }
    1416 
    1417         WCHAR* pWide = ConvertToWideString(buffer, CP_UTF8, false);
    1418         // must delete[] pWide
    1419 
    1420         DWORD result;
    1421 
    1422         if (pWide == NULL)
    1423         {
    1424                 std::string buffer2 = buffer;
    1425                 buffer2 += " (failed to convert string encoding)";
    1426                 LPCSTR strings[] = { buffer2.c_str(), NULL };
    1427 
    1428                 result = ReportEventA(gSyslogH, // event log handle
    1429                         errinfo,               // event type
    1430                         0,                     // category zero
    1431                         MSG_ERR,               // event identifier -
    1432                                                // we will call them all the same
    1433                         NULL,                  // no user security identifier
    1434                         1,                     // one substitution string
    1435                         0,                     // no data
    1436                         strings,               // pointer to string array
    1437                         NULL);                 // pointer to data
    1438         }
    1439         else
    1440         {
    1441                 LPCWSTR strings[] = { pWide, NULL };
    1442                 result = ReportEventW(gSyslogH, // event log handle
    1443                         errinfo,               // event type
    1444                         0,                     // category zero
    1445                         MSG_ERR,               // event identifier -
    1446                                                // we will call them all the same
    1447                         NULL,                  // no user security identifier
    1448                         1,                     // one substitution string
    1449                         0,                     // no data
    1450                         strings,               // pointer to string array
    1451                         NULL);                 // pointer to data
    1452                 delete [] pWide;
    1453         }
    1454 
    1455         if (result == 0)
    1456         {
    1457                 DWORD err = GetLastError();
    1458                 if (err == ERROR_LOG_FILE_FULL)
    1459                 {
    1460                         if (!sHaveWarnedEventLogFull)
    1461                         {
    1462                                 printf("Unable to send message to Event Log "
    1463                                         "(Event Log is full):\r\n");
    1464                                 fflush(stdout);
    1465                                 sHaveWarnedEventLogFull = TRUE;
    1466                         }
    1467                 }
    1468                 else
    1469                 {
    1470                         printf("Unable to send message to Event Log: %s:\r\n",
    1471                                 GetErrorMessage(err).c_str());
    1472                         fflush(stdout);
    1473                 }
    1474         }
    1475         else
    1476         {
    1477                 sHaveWarnedEventLogFull = false;
    1478         }
    1479 }
    1480 
    1481 int emu_chdir(const char* pDirName)
    1482 {
    1483         /*
    1484         std::string AbsPathWithUnicode =
    1485                 ConvertPathToAbsoluteUnicode(pDirName);
    1486 
    1487         if (AbsPathWithUnicode.size() == 0)
    1488         {
    1489                 // error already logged by ConvertPathToAbsoluteUnicode()
    1490                 return -1;
    1491         }
    1492 
    1493         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    1494         */
    1495 
    1496         WCHAR* pBuffer = ConvertUtf8ToWideString(pDirName);
    1497         if (!pBuffer) return -1;
    1498 
    1499         int result = SetCurrentDirectoryW(pBuffer);
    1500         delete [] pBuffer;
    1501 
    1502         if (result != 0) return 0;
    1503 
    1504         errno = EACCES;
    1505         fprintf(stderr, "Failed to change directory to '%s': %s\n",
    1506                 pDirName, GetErrorMessage(GetLastError()).c_str());
    1507         return -1;
    1508 }
    1509 
    1510 char* emu_getcwd(char* pBuffer, int BufSize)
    1511 {
    1512         DWORD len = GetCurrentDirectoryW(0, NULL);
    1513         if (len == 0)
    1514         {
    1515                 errno = EINVAL;
    1516                 return NULL;
    1517         }
    1518 
    1519         if ((int)len > BufSize)
    1520         {
    1521                 errno = ENAMETOOLONG;
    1522                 return NULL;
    1523         }
    1524 
    1525         WCHAR* pWide = new WCHAR [len];
    1526         if (!pWide)
    1527         {
    1528                 errno = ENOMEM;
    1529                 return NULL;
    1530         }
    1531 
    1532         DWORD result = GetCurrentDirectoryW(len, pWide);
    1533         if (result <= 0 || result >= len)
    1534         {
    1535                 errno = EACCES;
    1536                 delete [] pWide;
    1537                 return NULL;
    1538         }
    1539 
    1540         char* pUtf8 = ConvertFromWideString(pWide, CP_UTF8);
    1541         delete [] pWide;
    1542 
    1543         if (!pUtf8)
    1544         {
    1545                 return NULL;
    1546         }
    1547 
    1548         strncpy(pBuffer, pUtf8, BufSize - 1);
    1549         pBuffer[BufSize - 1] = 0;
    1550         delete [] pUtf8;
    1551 
    1552         return pBuffer;
    1553 }
    1554 
    1555 int emu_mkdir(const char* pPathName)
    1556 {
    1557         std::string AbsPathWithUnicode =
    1558                 ConvertPathToAbsoluteUnicode(pPathName);
    1559 
    1560         if (AbsPathWithUnicode.size() == 0)
    1561         {
    1562                 // error already logged by ConvertPathToAbsoluteUnicode()
    1563                 return -1;
    1564         }
    1565 
    1566         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    1567         if (!pBuffer)
    1568         {
    1569                 return -1;
    1570         }
    1571 
    1572         BOOL result = CreateDirectoryW(pBuffer, NULL);
    1573         delete [] pBuffer;
    1574 
    1575         if (!result)
    1576         {
    1577                 errno = EACCES;
    1578                 return -1;
    1579         }
    1580 
    1581         return 0;
    1582 }
    1583 
    1584 int emu_unlink(const char* pFileName)
    1585 {
    1586         std::string AbsPathWithUnicode =
    1587                 ConvertPathToAbsoluteUnicode(pFileName);
    1588 
    1589         if (AbsPathWithUnicode.size() == 0)
    1590         {
    1591                 // error already logged by ConvertPathToAbsoluteUnicode()
    1592                 return -1;
    1593         }
    1594 
    1595         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str());
    1596         if (!pBuffer)
    1597         {
    1598                 return -1;
    1599         }
    1600 
    1601         BOOL result = DeleteFileW(pBuffer);
    1602         DWORD err = GetLastError();
    1603         delete [] pBuffer;
    1604 
    1605         if (!result)
    1606         {
    1607                 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
    1608                 {
    1609                         errno = ENOENT;
    1610                 }
    1611                 else if (err == ERROR_SHARING_VIOLATION)
    1612                 {
    1613                         errno = EBUSY;
    1614                 }
    1615                 else if (err == ERROR_ACCESS_DENIED)
    1616                 {
    1617                         errno = EACCES;
    1618                 }
    1619                 else
    1620                 {
    1621                         ::syslog(LOG_WARNING, "Failed to delete file "
    1622                                 "'%s': %s", pFileName,
    1623                                 GetErrorMessage(err).c_str());
    1624                         errno = ENOSYS;
    1625                 }
    1626                 return -1;
    1627         }
    1628 
    1629         return 0;
    1630 }
    1631 
    1632 int emu_rename(const char* pOldFileName, const char* pNewFileName)
    1633 {
    1634         std::string OldPathWithUnicode =
    1635                 ConvertPathToAbsoluteUnicode(pOldFileName);
    1636 
    1637         if (OldPathWithUnicode.size() == 0)
    1638         {
    1639                 // error already logged by ConvertPathToAbsoluteUnicode()
    1640                 return -1;
    1641         }
    1642 
    1643         WCHAR* pOldBuffer = ConvertUtf8ToWideString(OldPathWithUnicode.c_str());
    1644         if (!pOldBuffer)
    1645         {
    1646                 return -1;
    1647         }
    1648 
    1649         std::string NewPathWithUnicode =
    1650                 ConvertPathToAbsoluteUnicode(pNewFileName);
    1651 
    1652         if (NewPathWithUnicode.size() == 0)
    1653         {
    1654                 // error already logged by ConvertPathToAbsoluteUnicode()
    1655                 delete [] pOldBuffer;
    1656                 return -1;
    1657         }
    1658 
    1659         WCHAR* pNewBuffer = ConvertUtf8ToWideString(NewPathWithUnicode.c_str());
    1660         if (!pNewBuffer)
    1661         {
    1662                 delete [] pOldBuffer;
    1663                 return -1;
    1664         }
    1665 
    1666         BOOL result = MoveFileW(pOldBuffer, pNewBuffer);
    1667         DWORD err = GetLastError();
    1668         delete [] pOldBuffer;
    1669         delete [] pNewBuffer;
    1670 
    1671         if (!result)
    1672         {
    1673                 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
    1674                 {
    1675                         errno = ENOENT;
    1676                 }
    1677                 else if (err == ERROR_SHARING_VIOLATION)
    1678                 {
    1679                         errno = EBUSY;
    1680                 }
    1681                 else if (err == ERROR_ACCESS_DENIED)
    1682                 {
    1683                         errno = EACCES;
    1684                 }
    1685                 else
    1686                 {
    1687                         ::syslog(LOG_WARNING, "Failed to rename file "
    1688                                 "'%s' to '%s': %s", pOldFileName, pNewFileName,
    1689                                 GetErrorMessage(err).c_str());
    1690                         errno = ENOSYS;
    1691                 }
    1692                 return -1;
    1693         }
    1694 
    1695         return 0;
    1696 }
    1697 
    1698 int console_read(char* pBuffer, size_t BufferSize)
    1699 {
    1700         HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
    1701 
    1702         if (hConsole == INVALID_HANDLE_VALUE)
    1703         {
    1704                 ::fprintf(stderr, "Failed to get a handle on standard input: "
    1705                         "%s", GetErrorMessage(GetLastError()).c_str());
    1706                 return -1;
    1707         }
    1708 
    1709         size_t WideSize = BufferSize / 5;
    1710         WCHAR* pWideBuffer = new WCHAR [WideSize + 1];
    1711 
    1712         if (!pWideBuffer)
    1713         {
    1714                 ::perror("Failed to allocate wide character buffer");
    1715                 return -1;
    1716         }
    1717 
    1718         DWORD numCharsRead = 0;
    1719 
    1720         if (!ReadConsoleW(
    1721                         hConsole,
    1722                         pWideBuffer,
    1723                         WideSize, // will not be null terminated by ReadConsole
    1724                         &numCharsRead,
    1725                         NULL // reserved
    1726                 ))
    1727         {
    1728                 ::fprintf(stderr, "Failed to read from console: %s\n",
    1729                         GetErrorMessage(GetLastError()).c_str());
    1730                 return -1;
    1731         }
    1732 
    1733         pWideBuffer[numCharsRead] = 0;
    1734 
    1735         char* pUtf8 = ConvertFromWideString(pWideBuffer, GetConsoleCP());
    1736         delete [] pWideBuffer;
    1737 
    1738         strncpy(pBuffer, pUtf8, BufferSize);
    1739         delete [] pUtf8;
    1740 
    1741         return strlen(pBuffer);
    1742 }
    1743 
    1744 int readv (int filedes, const struct iovec *vector, size_t count)
    1745 {
    1746         int bytes = 0;
    1747 
    1748         for (size_t i = 0; i < count; i++)
    1749         {
    1750                 int result = read(filedes, vector[i].iov_base,
    1751                         vector[i].iov_len);
    1752                 if (result < 0)
    1753                 {
    1754                         return result;
    1755                 }
    1756                 bytes += result;
    1757         }
    1758 
    1759         return bytes;
    1760 }
    1761 
    1762 int writev(int filedes, const struct iovec *vector, size_t count)
    1763 {
    1764         int bytes = 0;
    1765 
    1766         for (size_t i = 0; i < count; i++)
    1767         {
    1768                 int result = write(filedes, vector[i].iov_base,
    1769                         vector[i].iov_len);
    1770                 if (result < 0)
    1771                 {
    1772                         return result;
    1773                 }
    1774                 bytes += result;
    1775         }
    1776 
    1777         return bytes;
    1778 }
    1779 
    1780 // need this for conversions
    1781 time_t ConvertFileTimeToTime_t(FILETIME *fileTime)
    1782 {
    1783         SYSTEMTIME stUTC;
    1784         struct tm timeinfo;
    1785 
    1786         // Convert the last-write time to local time.
    1787         FileTimeToSystemTime(fileTime, &stUTC);
    1788 
    1789         memset(&timeinfo, 0, sizeof(timeinfo));
    1790         timeinfo.tm_sec = stUTC.wSecond;
    1791         timeinfo.tm_min = stUTC.wMinute;
    1792         timeinfo.tm_hour = stUTC.wHour;
    1793         timeinfo.tm_mday = stUTC.wDay;
    1794         timeinfo.tm_wday = stUTC.wDayOfWeek;
    1795         timeinfo.tm_mon = stUTC.wMonth - 1;
    1796         // timeinfo.tm_yday = ...;
    1797         timeinfo.tm_year = stUTC.wYear - 1900;
    1798 
    1799         time_t retVal = mktime(&timeinfo) - _timezone;
    1800         return retVal;
    1801 }
    1802 
    1803 bool ConvertTime_tToFileTime(const time_t from, FILETIME *pTo)
    1804 {
    1805         time_t adjusted = from + _timezone;
    1806         struct tm *time_breakdown = gmtime(&adjusted);
    1807         if (time_breakdown == NULL)
    1808         {
    1809                 ::syslog(LOG_ERR, "Error: failed to convert time format: "
    1810                         "%d is not a valid time\n", from);
    1811                 return false;
    1812         }
    1813 
    1814         SYSTEMTIME stUTC;
    1815         stUTC.wSecond       = time_breakdown->tm_sec;
    1816         stUTC.wMinute       = time_breakdown->tm_min;
    1817         stUTC.wHour         = time_breakdown->tm_hour;
    1818         stUTC.wDay          = time_breakdown->tm_mday;
    1819         stUTC.wDayOfWeek    = time_breakdown->tm_wday;
    1820         stUTC.wMonth        = time_breakdown->tm_mon  + 1;
    1821         stUTC.wYear         = time_breakdown->tm_year + 1900;
    1822         stUTC.wMilliseconds = 0;
    1823 
    1824         // Convert the last-write time to local time.
    1825         if (!SystemTimeToFileTime(&stUTC, pTo))
    1826         {
    1827                 syslog(LOG_ERR, "Failed to convert between time formats: %s",
    1828                         GetErrorMessage(GetLastError()).c_str());
    1829                 return false;
    1830         }
    1831 
    1832         return true;
    1833 }
    1834 
    1835 #endif // WIN32
    1836 
  • box/invisnet/vs2010/0.11/lib/win32/emu.h

    r2773 r3055  
    1 // emulates unix syscalls to win32 functions
     1#ifndef EMU_INCLUDE
     2#       define EMU_INCLUDE
    23
    3 #ifdef WIN32
    4         #define EMU_STRUCT_STAT struct emu_stat
    5         #define EMU_STAT  emu_stat
    6         #define EMU_FSTAT emu_fstat
    7         #define EMU_LSTAT emu_stat
    8 #else
    9         #define EMU_STRUCT_STAT struct stat
    10         #define EMU_STAT  ::stat
    11         #define EMU_FSTAT ::fstat
    12         #define EMU_LSTAT ::lstat
    13 #endif
     4#       ifdef WIN32
     5#               pragma once
    146
    15 #if ! defined EMU_INCLUDE && defined WIN32
    16 #define EMU_INCLUDE
     7#               include "win32.h"
     8#               include "dirent.h"
     9#               include "getopt.h"
     10#               include "poll.h"
     11#               include "pwd.h"
     12#               include "unicode.h"
     13#               include "unistd.h"
     14
     15#               include "_sys/mount.h"
     16#               include "_sys/resource.h"
     17#               include "_sys/socket.h"
     18#               include "_sys/stat.h"
     19#               include "_sys/syslog.h"
     20#               include "_sys/time.h"
     21#               include "_sys/uio.h"
     22
     23
     24                extern passwd gTempPasswd;
     25
     26
     27#               define EMU_EXCEPTION_HANDLING \
     28                catch(std::bad_alloc &e) \
     29                { \
     30                        (void)e; /* make the compiler happy */ \
     31                        errno = ENOMEM; \
     32                } \
     33                catch(Win32Exception &e) \
     34                { \
     35                        BOX_LOG_WIN_ERROR_NUMBER(e.GetMessage(),e.GetLastError()); \
     36                } \
     37                catch(...) \
     38                { \
     39                        BOX_FATAL("Unexpected exception") \
     40                }
     41
     42#               define EMU_EXCEPTION_HANDLING_RETURN(rv) \
     43                catch(std::bad_alloc &e) \
     44                { \
     45                        (void)e; /* make the compiler happy */ \
     46                        errno = ENOMEM; \
     47                } \
     48                catch(Win32Exception &e) \
     49                { \
     50                        BOX_LOG_WIN_ERROR_NUMBER(e.GetMessage(),e.GetLastError()); \
     51                } \
     52                catch(...) \
     53                { \
     54                        BOX_FATAL("Unexpected exception") \
     55                } \
     56                return rv;
     57
     58
    1759
    1860// basic types, may be required by other headers since we
    1961// don't include sys/types.h
    2062
    21 #ifdef __MINGW32__
    22         #include <stdint.h>
    23 #else // MSVC
    24         typedef unsigned __int64 u_int64_t;
    25         typedef unsigned __int64 uint64_t;
    26         typedef          __int64 int64_t;
    27         typedef unsigned __int32 uint32_t;
    28         typedef unsigned __int32 u_int32_t;
    29         typedef          __int32 int32_t;
    30         typedef unsigned __int16 uint16_t;
    31         typedef          __int16 int16_t;
    32         typedef unsigned __int8  uint8_t;
    33         typedef          __int8  int8_t;
    34 #endif
    3563
    3664// emulated types, present on MinGW but not MSVC or vice versa
     
    3967        typedef uint32_t u_int32_t;
    4068#else
    41         typedef unsigned int mode_t;
    42         typedef unsigned int pid_t;
    4369#endif
    44 
    45 // set up to include the necessary parts of Windows headers
    46 
    47 #define WIN32_LEAN_AND_MEAN
    48 
    49 #ifndef __MSVCRT_VERSION__
    50 #define __MSVCRT_VERSION__ 0x0601
    51 #endif
    52 
    53 // Windows headers
    54 
    55 #include <winsock2.h>
    56 #include <fcntl.h>
    57 #include <sys/stat.h>
    58 #include <direct.h>
    59 #include <errno.h>
    60 #include <io.h>
    61 #include <stdlib.h>
    62 #include <string.h>
    63 #include <stdio.h>
    64 #include <stdarg.h>
    65 #include <time.h>
    66 
    67 #include <string>
    6870
    6971// emulated functions
     
    7577#define ITIMER_REAL 0
    7678
    77 struct passwd {
    78         char *pw_name;
    79         char *pw_passwd;
    80         int pw_uid;
    81         int pw_gid;
    82         time_t pw_change;
    83         char *pw_class;
    84         char *pw_gecos;
    85         char *pw_dir;
    86         char *pw_shell;
    87         time_t pw_expire;
    88 };
    8979
    90 extern passwd gTempPasswd;
    91 inline struct passwd * getpwnam(const char * name)
    92 {
    93         //for the mo pretend to be root
    94         gTempPasswd.pw_uid = 0;
    95         gTempPasswd.pw_gid = 0;
    9680
    97         return &gTempPasswd;
    98 }
    9981
    100 #define S_IRWXG 1
    101 #define S_IRWXO 2
    102 #define S_ISUID 4
    103 #define S_ISGID 8
    104 #define S_ISVTX 16
    10582
    106 #ifndef __MINGW32__
    107         //not sure if these are correct
    108         //S_IWRITE -   writing permitted
    109         //_S_IREAD -   reading permitted
    110         //_S_IREAD | _S_IWRITE -
    111         #define S_IRUSR S_IWRITE
    112         #define S_IWUSR S_IREAD
    113         #define S_IRWXU (S_IREAD|S_IWRITE|S_IEXEC)
    114 
    115         #define S_ISREG(x) (S_IFREG & x)
    116         #define S_ISDIR(x) (S_IFDIR & x)
    117 #endif
    118 
    119 inline int chown(const char * Filename, u_int32_t uid, u_int32_t gid)
    120 {
    121         //important - this needs implementing
    122         //If a large restore is required then
    123         //it needs to restore files AND permissions
    124         //reference AdjustTokenPrivileges
    125         //GetAccountSid
    126         //InitializeSecurityDescriptor
    127         //SetSecurityDescriptorOwner
    128         //The next function looks like the guy to use...
    129         //SetFileSecurity
    130 
    131         //indicate success
    132         return 0;
    133 }
    134 
    135 // Windows and Unix owners and groups are pretty fundamentally different.
    136 // Ben prefers that we kludge here rather than litter the code with #ifdefs.
    137 // Pretend to be root, and pretend that set...() operations succeed.
    138 inline int setegid(int)
    139 {
    140         return true;
    141 }
    142 inline int seteuid(int)
    143 {
    144         return true;
    145 }
    146 inline int setgid(int)
    147 {
    148         return true;
    149 }
    150 inline int setuid(int)
    151 {
    152         return true;
    153 }
    154 inline int getgid(void)
    155 {
    156         return 0;
    157 }
    158 inline int getuid(void)
    159 {
    160         return 0;
    161 }
    162 inline int geteuid(void)
    163 {
    164         return 0;
    165 }
    16683
    16784#ifndef PATH_MAX
     
    16986#endif
    17087
    171 // MinGW provides a getopt implementation
    172 #ifndef __MINGW32__
    173 #include "getopt.h"
    174 #endif // !__MINGW32__
    175 
    17688#define timespec timeval
    17789
    17890//win32 deals in usec not nsec - so need to ensure this follows through
    17991#define tv_nsec tv_usec
    180 
    181 #ifndef __MINGW32__
    182         typedef int socklen_t;
    183 #endif
    18492
    18593#define S_IRGRP S_IWRITE
     
    208116#endif
    209117
    210 struct dirent
    211 {
    212         char *d_name;
    213         unsigned long d_type;
    214 };
    215 
    216 struct DIR
    217 {
    218         intptr_t                fd;     // filedescriptor
    219         // struct _finddata_t   info;
    220         struct _wfinddata_t     info;
    221         // struct _finddata_t   info;
    222         struct dirent           result; // d_name (first time null)
    223         wchar_t                 *name;  // null-terminated byte string
    224 };
    225 
    226 DIR *opendir(const char *name);
    227 struct dirent *readdir(DIR *dp);
    228 int closedir(DIR *dp);
    229 
    230118// local constant to open file exclusively without shared access
    231119#define O_LOCK 0x10000
    232120
    233 extern DWORD winerrno; /* used to report errors from openfile() */
    234121HANDLE openfile(const char *filename, int flags, int mode);
    235122inline int closefile(HANDLE handle)
     
    243130}
    244131
    245 #define LOG_DEBUG LOG_INFO
    246 #define LOG_INFO 6
    247 #define LOG_NOTICE LOG_INFO
    248 #define LOG_WARNING 4
    249 #define LOG_ERR 3
    250 #define LOG_CRIT LOG_ERR
    251 #define LOG_PID 0
    252 #define LOG_LOCAL5 0
    253 #define LOG_LOCAL6 0
    254 
    255 void openlog (const char * daemonName, int, int);
    256 void closelog(void);
    257 void syslog  (int loglevel, const char *fmt, ...);
    258 
    259 #define LOG_LOCAL0 0
    260 #define LOG_LOCAL1 0
    261 #define LOG_LOCAL2 0
    262 #define LOG_LOCAL3 0
    263 #define LOG_LOCAL4 0
    264 #define LOG_LOCAL5 0
    265 #define LOG_LOCAL6 0
    266 #define LOG_DAEMON 0
    267132
    268133#ifndef __MINGW32__
     
    270135#endif
    271136
    272 inline unsigned int sleep(unsigned int secs)
    273 {
    274         Sleep(secs*1000);
    275         return(ERROR_SUCCESS);
    276 }
    277137
    278 #define INFTIM -1
    279 #if(_WIN32_WINNT < 0x0600)
    280 #define POLLIN 0x1
    281 #define POLLERR 0x8
    282 #define POLLOUT 0x4
    283 #endif
    284138
    285 #define SHUT_RDWR SD_BOTH
    286 #define SHUT_RD SD_RECEIVE
    287 #define SHUT_WR SD_SEND
    288139
    289 #if(_WIN32_WINNT < 0x0600)
    290 struct pollfd
    291 {
    292         SOCKET fd;
    293         short int events;
    294         short int revents;
    295 };
    296 #endif
    297 
    298 inline int ioctl(SOCKET sock, int flag,  int * something)
    299 {
    300         //indicate success
    301         return 0;
    302 }
    303 
    304 extern "C" inline int getpid()
    305 {
    306         return (int)GetCurrentProcessId();
    307 }
    308 
    309 inline int waitpid(pid_t pid, int *status, int)
    310 {
    311         return 0;
    312 }
    313 
    314 //this shouldn't be needed.
    315 struct statfs
    316 {
    317         TCHAR f_mntonname[MAX_PATH];
    318 };
    319 
    320 struct emu_stat {
    321         int st_dev;
    322         uint64_t st_ino;
    323         DWORD st_mode;
    324         short st_nlink;
    325         short st_uid;
    326         short st_gid;
    327         //_dev_t st_rdev;
    328         uint64_t st_size;
    329         time_t st_atime;
    330         time_t st_mtime;
    331         time_t st_ctime;
    332 };
    333 
    334 // need this for conversions
    335 time_t ConvertFileTimeToTime_t(FILETIME *fileTime);
    336 bool   ConvertTime_tToFileTime(const time_t from, FILETIME *pTo);
    337 
    338 int   emu_chdir  (const char* pDirName);
    339 int   emu_mkdir  (const char* pPathName);
    340 int   emu_unlink (const char* pFileName);
    341 int   emu_fstat  (HANDLE file,       struct emu_stat* st);
    342 int   emu_stat   (const char* pName, struct emu_stat* st);
    343 int   emu_utimes (const char* pName, const struct timeval[]);
    344 int   emu_chmod  (const char* pName, mode_t mode);
    345 char* emu_getcwd (char* pBuffer,     int BufSize);
    346 int   emu_rename (const char* pOldName, const char* pNewName);
    347 
    348 #define chdir(directory)        emu_chdir  (directory)
    349 #define mkdir(path,     mode)   emu_mkdir  (path)
    350 #define unlink(file)            emu_unlink (file)
    351 #define utimes(buffer,  times)  emu_utimes (buffer,   times)
    352 #define chmod(file,     mode)   emu_chmod  (file,     mode)
    353 #define getcwd(buffer,  size)   emu_getcwd (buffer,   size)
    354 #define rename(oldname, newname) emu_rename (oldname, newname)
    355 
    356 // Not safe to replace stat/fstat/lstat on mingw at least, as struct stat
    357 // has a 16-bit st_ino and we need a 64-bit one.
    358 //
    359 // #define stat(filename,  struct) emu_stat   (filename, struct)
    360 // #define lstat(filename, struct) emu_stat   (filename, struct)
    361 // #define fstat(handle,   struct) emu_fstat  (handle,   struct)
    362 //
    363 // But lstat doesn't exist on Windows, so we have to provide something:
    364 
    365 #define lstat(filename, struct) stat(filename, struct)
    366 
    367 int statfs(const char * name, struct statfs * s);
    368 
    369 int poll(struct pollfd *ufds, unsigned long nfds, int timeout);
    370 
    371 struct iovec {
    372         void *iov_base;   /* Starting address */
    373         size_t iov_len;   /* Number of bytes */
    374 };
    375 
    376 int readv (int filedes, const struct iovec *vector, size_t count);
    377 int writev(int filedes, const struct iovec *vector, size_t count);
    378140
    379141// The following functions are not emulations, but utilities for other
     
    383145bool EnableBackupRights( void );
    384146
    385 bool ConvertEncoding (const std::string& rSource, int sourceCodePage,
    386         std::string& rDest, int destCodePage);
    387 bool ConvertToUtf8   (const std::string& rSource, std::string& rDest,
    388         int sourceCodePage);
    389 bool ConvertFromUtf8 (const std::string& rSource, std::string& rDest,
    390         int destCodePage);
    391 bool ConvertUtf8ToConsole(const std::string& rSource, std::string& rDest);
    392 bool ConvertConsoleToUtf8(const std::string& rSource, std::string& rDest);
    393 
    394147// Utility function which returns a default config file name,
    395148// based on the path of the current executable.
    396149std::string GetDefaultConfigFilePath(const std::string& rName);
    397 
    398 // GetErrorMessage() returns a system error message, like strerror()
    399 // but for Windows error codes.
    400 std::string GetErrorMessage(DWORD errorCode);
    401150
    402151// console_read() is a replacement for _cgetws which requires a
     
    405154
    406155#endif // !EMU_INCLUDE && WIN32
     156
     157#endif
  • box/invisnet/vs2010/0.11/lib/win32/getopt.h

    r946 r3055  
    3737 * POSSIBILITY OF SUCH DAMAGE.
    3838 */
     39
     40#ifdef WIN32
     41#       pragma once
     42#       ifdef __MINGW32__
     43#               define _GETOPT_H_
     44#       else
     45
     46#       endif
     47#endif
    3948
    4049#ifndef _GETOPT_H_
Note: See TracChangeset for help on using the changeset viewer.