Path fixes for FreeDOS/DJGPP

This commit is contained in:
Brian Cox 2017-09-13 21:35:56 -07:00
parent 4abec97664
commit 769874d34b
10 changed files with 456 additions and 168 deletions

View File

@ -138,13 +138,27 @@ public:
};
#if USES_DEVICE_PATH
class cDevicePath
class cDosPath
{
public:
static TSTRING AsPosix(const TSTRING& in);
static TSTRING AsNative(const TSTRING& in);
static bool IsAbsolutePath(const TSTRING& in);
static TSTRING BackupName(const TSTRING& in);
};
class cArosPath
{
public:
static TSTRING AsPosix(const TSTRING& in);
static TSTRING AsNative(const TSTRING& in);
static bool IsAbsolutePath(const TSTRING& in);
};
#if IS_DOS_DJGPP
#define cDevicePath cDosPath
#elif IS_AROS
#define cDevicePath cArosPath
#endif

View File

@ -449,31 +449,46 @@ void cFile::Truncate( File_t offset ) // throw(eFile)
}
#if USES_DEVICE_PATH
// For paths of type DH0:/dir/file
TSTRING cDevicePath::AsPosix( const TSTRING& in )
/////////////////////////////////////////////////////////////////////////
// Platform path conversion methods
/////////////////////////////////////////////////////////////////////////
bool cDosPath::IsAbsolutePath(const TSTRING& in)
{
if (in.empty())
return false;
if (in[0] == '/')
return true;
if (in.length() >= 2 && in[1] == ':')
return true;
return false;
}
// For paths of type C:\DOS
TSTRING cDosPath::AsPosix( const TSTRING& in )
{
if (in[0] == '/')
{
return in;
}
#if IS_DOS_DJGPP
TSTRING out = "/dev/" + in;
TSTRING out = (cDosPath::IsAbsolutePath(in)) ? ("/dev/" + in) : in;
std::replace(out.begin(), out.end(), '\\', '/');
#else
TSTRING out = '/' + in;
#endif
std::replace(out.begin(), out.end(), ':', '/');
out.erase( std::remove(out.begin(), out.end(), ':'), out.end());
return out;
}
TSTRING cDevicePath::AsNative( const TSTRING& in )
TSTRING cDosPath::AsNative( const TSTRING& in )
{
if (in[0] != '/')
{
return in;
}
#if IS_DOS_DJGPP
if (in.find("/dev") != 0 || in.length() < 6)
return in;
@ -482,18 +497,70 @@ TSTRING cDevicePath::AsNative( const TSTRING& in )
if (in.length() >= 8)
out.append(in.substr(7));
std::replace(out.begin(), out.end(), '/', '\\');
return out;
}
TSTRING cDosPath::BackupName( const TSTRING& in )
{
TSTRING out = in;
std::string::size_type pos = out.find_last_of("\\");
if( std::string::npos == pos)
return in;
TSTRING path = in.substr(0, pos);
TSTRING name = in.substr(pos,9);
std::replace(name.begin(), name.end(), '.', '_');
path.append(name);
return path;
}
#elif IS_AROS
bool cArosPath::IsAbsolutePath(const TSTRING& in)
{
if (in.empty())
return false;
if (in[0] == '/')
return true;
if (in.find(":/") != std::string::npos)
return true;
return false;
}
// For paths of type DH0:dir/file
TSTRING cArosPath::AsPosix( const TSTRING& in )
{
if (in[0] == '/')
{
return in;
}
TSTRING out = IsAbsolutePath(in) ? '/' + in : in;
std::replace(out.begin(), out.end(), ':', '/');
return out;
}
TSTRING cArosPath::AsNative( const TSTRING& in )
{
if (in[0] != '/')
{
return in;
}
int x = 1;
for ( x; in[x] == '/' && x<in.length(); x++);
TSTRING out = in.substr(x);
TSTRING::size_type t = out.find_first_of('/');
out[t] = ':';
return out;
#endif
}
#endif
}

View File

@ -730,12 +730,18 @@ bool cUnixFSServices::GetExecutableFilename( TSTRING& strFullPath, const TSTRING
///////////////////////////////////////////////////////////////////////////////
bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC, const TSTRING& pathRelFromC ) const
{
cDebug d("cUnixFSServices::FullPath");
d.TraceDebug("strRelPathC = %s, pathRelFromC = %s\n", strRelPathC.c_str(), pathRelFromC.c_str());
// don't do anything with an empty path
if( strRelPathC.empty() )
return false;
#if USES_DEVICE_PATH
TSTRING strRelPath = cDevicePath::AsPosix(strRelPathC); // make non-const temp var
#else
TSTRING strRelPath = strRelPathC; // make non-const temp var
#endif
//
// get base name (where strRelPath will be relative to), which will either be;
// 1. the root directory if strRelPath is an absolute path
@ -748,6 +754,7 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
if( IsRoot( strRelPath ) ) // if it's root, don't monkey with it, just return it.
{
strFullPath = strRelPath;
d.TraceDebug("Is root; returning %s\n", strFullPath.c_str());
return true;
}
else
@ -766,18 +773,30 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
try
{
GetCurrentDir( strFullPath );
#if USES_DEVICE_PATH
strFullPath = cDevicePath::AsPosix(strFullPath);
#endif
util_TrailingSep( strFullPath, false );
}
catch( eFSServices& )
{
return false;
}
d.TraceDebug("Creating prefix relative to CWD: %s\n", strFullPath.c_str());
}
else // we're relative to a given dir
{
#if USES_DEVICE_PATH
strFullPath = cDevicePath::AsPosix(pathRelFromC);
#else
strFullPath = pathRelFromC;
#endif
util_RemoveDuplicateSeps( strFullPath );
util_TrailingSep( strFullPath, false );
d.TraceDebug("Creating prefix from supplied path: %s\n", strFullPath.c_str());
}
}
@ -790,6 +809,7 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
int index = 0;
while( util_GetNextPathElement( strRelPath, strElem, index++ ) )
{
d.TraceDebug("Path element = %s\n", strElem.c_str());
if( 0 == strElem.compare( _T(".") ) )
{
// ignore it
@ -805,8 +825,11 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC
strFullPath += TW_SLASH;
strFullPath += strElem;
}
d.TraceDebug("FullPath is now %s\n", strFullPath.c_str());
}
d.TraceDebug("Done, returning %s\n", strFullPath.c_str());
return true;
}

View File

@ -212,6 +212,10 @@ bool cFSParserUtil::EnumPredefinedVariables( int index, TSTRING& sName, TSTRING&
bool cFSParserUtil::IsAbsolutePath( const TSTRING& strPath ) const
{
// IF there's a first character AND it is ( '/' OR '\\' ), THEN it's absolute
return( strPath.size() > 0 && ( _T('/') == strPath[0] || _T('\\') == strPath[0] ) );
#if USES_DEVICE_PATH
return cDevicePath::IsAbsolutePath(strPath);
#else
// IF there's a first character AND it's a '/', it's absolute.
return( strPath.size() > 0 && ( _T('/') == strPath[0] ) );
#endif
}

View File

@ -249,6 +249,172 @@ static void InitCmdLineCommon(cCmdLineParser& parser)
}
///////////////////////////////////////////////////////////////////////////////
// Set up temp directory
///////////////////////////////////////////////////////////////////////////////
static void util_InitTempDirectory(const cConfigFile& cf)
{
TSTRING temp_directory;
cf.Lookup(TSTRING(_T("TEMPDIRECTORY")), temp_directory);
if (temp_directory.empty())
{
#if IS_AROS
temp_directory = "T:";
#elif IS_DOS_DJGPP
temp_directory = "/dev/c/temp/";
#else
temp_directory = "/tmp/";
#endif
}
// make sure we have a trailing slash -- thanks Jarno...
//
if (*temp_directory.rbegin() != '/')
{
temp_directory.push_back('/');
}
// make sure it exists...
//
#if IS_AROS
temp_directory = cDevicePath::AsNative(temp_directory);
#elif IS_DOS_DJGPP
temp_directory = cDevicePath::AsPosix(temp_directory);
#endif
if (access(temp_directory.c_str(), F_OK) != 0)
{
TSTRING errStr = TSS_GetString( cCore, core::STR_BAD_TEMPDIRECTORY );
TSTRING tmpStr = _T("Directory: ");
tmpStr += (temp_directory + _T("\n"));
tmpStr += errStr;
throw eTWInvalidTempDirectory(tmpStr);
}
else
{
iFSServices::GetInstance()->SetTempDirName(temp_directory);
}
}
///////////////////////////////////////////////////////////////////////////////
// Set up various email reporting options
///////////////////////////////////////////////////////////////////////////////
static void util_InitEmailOptions(cTWModeCommon* pModeInfo, const cConfigFile& cf)
{
TSTRING str;
if (cf.Lookup(TSTRING(_T("GLOBALEMAIL")), str))
{
if (str.length() != 0)
pModeInfo->mGlobalEmail = str;
}
//
// Set the report-viewing level if one has been specified, use
// default level otherwise.
//
if(cf.Lookup(TSTRING(_T("EMAILREPORTLEVEL")), str))
{
if (_tcsicmp(str.c_str(), _T("0")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::SINGLE_LINE;
else if (_tcsicmp(str.c_str(), _T("1")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::PARSEABLE;
else if (_tcsicmp(str.c_str(), _T("2")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::SUMMARY_ONLY;
else if (_tcsicmp(str.c_str(), _T("3")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::CONCISE_REPORT;
else if (_tcsicmp(str.c_str(), _T("4")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::FULL_REPORT;
else
{
// They specified an illegal level, error.
TSTRING errStr = _T("Invalid Level: ");
errStr += str;
throw eTWInvalidReportLevelCfg( errStr );
}
}
else
{
// no level was specified in the configuration file, use default.
pModeInfo->mEmailReportLevel = cTextReportViewer::CONCISE_REPORT;
}
// Decide what mail method should be used to email reports
if(cf.Lookup(TSTRING(_T("MAILMETHOD")), str))
{
if (_tcsicmp(str.c_str(), _T("SENDMAIL")) == 0)
pModeInfo->mMailMethod = cMailMessage::MAIL_BY_PIPE;
else if( _tcsicmp( str.c_str(), _T("SMTP") ) == 0 )
pModeInfo->mMailMethod = cMailMessage::MAIL_BY_SMTP;
else
pModeInfo->mMailMethod = cMailMessage::INVALID_METHOD;
}
else
{
pModeInfo->mMailMethod = cMailMessage::NO_METHOD;
}
#if !SUPPORTS_NETWORKING
if (pModeInfo->mMailMethod == cMailMessage::MAIL_BY_SMTP)
throw eMailSMTPNotSupported();
#endif
// Get the SMTP server
if(cf.Lookup(TSTRING(_T("SMTPHOST")), str))
{
pModeInfo->mSmtpHost = str;
}
else
{
pModeInfo->mSmtpHost = _T("127.0.0.1"); // this is the default
}
// Get the SMTP port number
if(cf.Lookup(TSTRING(_T("SMTPPORT")), str))
{
int i = _ttoi( str.c_str() );
if( i < 0 || i > SHRT_MAX )
throw eTWInvalidPortNumber( str );
pModeInfo->mSmtpPort = static_cast<unsigned short>( i );
}
else
{
pModeInfo->mSmtpPort = 25; // this is the default
}
// Get the mail program to use if we're piping our email
if(cf.Lookup(TSTRING(_T("MAILPROGRAM")), str))
{
pModeInfo->mMailProgram = str;
}
else
{
pModeInfo->mMailProgram.erase(); // MAILPROGRAM is not required to be specified
}
// Get the mail program to use if we're piping our email
if(cf.Lookup(TSTRING(_T("MAILNOVIOLATIONS")), str))
{
if (_tcsicmp(str.c_str(), _T("true")) == 0)
pModeInfo->mMailNoViolations = true;
else
pModeInfo->mMailNoViolations = false;
}
else
{
pModeInfo->mMailNoViolations = true; // MAILPROGRAM is not required to be specified
}
if(cf.Lookup(TSTRING(_T("MAILFROMADDRESS")), str))
{
pModeInfo->mMailFrom = str;
}
}
///////////////////////////////////////////////////////////////////////////////
// FillOutConfigInfo -- fills out all the common info with config file information
///////////////////////////////////////////////////////////////////////////////
@ -297,151 +463,9 @@ static void FillOutConfigInfo(cTWModeCommon* pModeInfo, const cConfigFile& cf)
pModeInfo->mfLooseDirs = true;
}
TSTRING temp_directory;
cf.Lookup(TSTRING(_T("TEMPDIRECTORY")), temp_directory);
util_InitTempDirectory(cf);
if (temp_directory.empty())
{
#if IS_AROS
temp_directory = "T:";
#else
temp_directory = "/tmp/";
#endif
}
// make sure we have a trailing slash -- thanks Jarno...
//
if (*temp_directory.rbegin() != '/')
{
temp_directory.push_back('/');
}
// make sure it exists...
//
#if USES_DEVICE_PATH
temp_directory = cDevicePath::AsNative(temp_directory);
#endif
if (access(temp_directory.c_str(), F_OK) != 0)
{
TSTRING errStr = TSS_GetString( cCore, core::STR_BAD_TEMPDIRECTORY );
TSTRING tmpStr = _T("Directory: ");
tmpStr += (temp_directory + _T("\n"));
tmpStr += errStr;
throw eTWInvalidTempDirectory(tmpStr);
}
else
{
iFSServices::GetInstance()->SetTempDirName(temp_directory);
}
if (cf.Lookup(TSTRING(_T("GLOBALEMAIL")), str))
{
if (str.length() != 0)
pModeInfo->mGlobalEmail = str;
}
//
// Set the report-viewing level if one has been specified, use
// default level otherwise.
//
if(cf.Lookup(TSTRING(_T("EMAILREPORTLEVEL")), str))
{
if (_tcsicmp(str.c_str(), _T("0")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::SINGLE_LINE;
else if (_tcsicmp(str.c_str(), _T("1")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::PARSEABLE;
else if (_tcsicmp(str.c_str(), _T("2")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::SUMMARY_ONLY;
else if (_tcsicmp(str.c_str(), _T("3")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::CONCISE_REPORT;
else if (_tcsicmp(str.c_str(), _T("4")) == 0)
pModeInfo->mEmailReportLevel = cTextReportViewer::FULL_REPORT;
else
{
// They specified an illegal level, error.
TSTRING errStr = _T("Invalid Level: ");
errStr += str;
throw eTWInvalidReportLevelCfg( errStr );
}
}
else
{
// no level was specified in the configuration file, use default.
pModeInfo->mEmailReportLevel = cTextReportViewer::CONCISE_REPORT;
}
// Decide what mail method should be used to email reports
if(cf.Lookup(TSTRING(_T("MAILMETHOD")), str))
{
if (_tcsicmp(str.c_str(), _T("SENDMAIL")) == 0)
pModeInfo->mMailMethod = cMailMessage::MAIL_BY_PIPE;
else if( _tcsicmp( str.c_str(), _T("SMTP") ) == 0 )
pModeInfo->mMailMethod = cMailMessage::MAIL_BY_SMTP;
else
pModeInfo->mMailMethod = cMailMessage::INVALID_METHOD;
}
else
{
pModeInfo->mMailMethod = cMailMessage::NO_METHOD;
}
#if !SUPPORTS_NETWORKING
if (pModeInfo->mMailMethod == cMailMessage::MAIL_BY_SMTP)
throw eMailSMTPNotSupported();
#endif
// Get the SMTP server
if(cf.Lookup(TSTRING(_T("SMTPHOST")), str))
{
pModeInfo->mSmtpHost = str;
}
else
{
pModeInfo->mSmtpHost = _T("127.0.0.1"); // this is the default
}
// Get the SMTP port number
if(cf.Lookup(TSTRING(_T("SMTPPORT")), str))
{
int i = _ttoi( str.c_str() );
if( i < 0 || i > SHRT_MAX )
throw eTWInvalidPortNumber( str );
pModeInfo->mSmtpPort = static_cast<unsigned short>( i );
}
else
{
pModeInfo->mSmtpPort = 25; // this is the default
}
// Get the mail program to use if we're piping our email
if(cf.Lookup(TSTRING(_T("MAILPROGRAM")), str))
{
pModeInfo->mMailProgram = str;
}
else
{
pModeInfo->mMailProgram.erase(); // MAILPROGRAM is not required to be specified
}
// Get the mail program to use if we're piping our email
if(cf.Lookup(TSTRING(_T("MAILNOVIOLATIONS")), str))
{
if (_tcsicmp(str.c_str(), _T("true")) == 0)
pModeInfo->mMailNoViolations = true;
else
pModeInfo->mMailNoViolations = false;
}
else
{
pModeInfo->mMailNoViolations = true; // MAILPROGRAM is not required to be specified
}
if(cf.Lookup(TSTRING(_T("MAILFROMADDRESS")), str))
{
pModeInfo->mMailFrom = str;
}
util_InitEmailOptions(pModeInfo, cf);
// SYSLOG reporting
if(cf.Lookup(TSTRING(_T("SYSLOGREPORTING")), str))

View File

@ -157,6 +157,9 @@ static bool SetExeDir( const TSTRING& strArgv0 )
TSTRING strFullPath;
if( iFSServices::GetInstance()->GetExecutableFilename( strFullPath, strArgv0 ) && !strFullPath.empty() )
{
#if USES_DEVICE_PATH
strFullPath = cDevicePath::AsPosix(strFullPath);
#endif
cSystemInfo::SetExePath(strFullPath);
TSTRING::size_type s = strFullPath.find_last_of( _T('/') );

View File

@ -58,7 +58,146 @@ void TestFile()
TEST(testStream);
}
//////////////////
void testDosAsPosix(const std::string& in, const std::string& expected)
{
TEST( expected == cDosPath::AsPosix(in) );
}
void TestDosAsPosix()
{
testDosAsPosix("c:\\foo", "/dev/c/foo");
testDosAsPosix("c:\\foo\\bar\\baz.txt", "/dev/c/foo/bar/baz.txt");
testDosAsPosix("c:/foo/bar/baz.txt", "/dev/c/foo/bar/baz.txt");
testDosAsPosix("c:\\", "/dev/c/");
testDosAsPosix("c:", "/dev/c");
testDosAsPosix("foo.txt", "foo.txt");
testDosAsPosix("bar\\foo.txt", "bar/foo.txt");
testDosAsPosix("bar/foo.txt", "bar/foo.txt");
testDosAsPosix("/foo/bar/baz.txt", "/foo/bar/baz.txt");
}
void testDosAsNative(const std::string& in, const std::string& expected)
{
TEST( expected == cDosPath::AsNative(in) );
}
void TestDosAsNative()
{
testDosAsNative("/dev/c/foo", "c:\\foo");
testDosAsNative("/dev/c/", "c:\\");
testDosAsNative("/dev/c", "c:\\");
testDosAsNative("/foo/bar/baz", "/foo/bar/baz");
}
void testDosIsAbsolute(const std::string& in, bool expected)
{
TEST( expected == cDosPath::IsAbsolutePath(in) );
}
void TestDosIsAbsolute()
{
testDosIsAbsolute("C:\\", true);
testDosIsAbsolute("C:", true);
testDosIsAbsolute("C:\\foo", true);
testDosIsAbsolute("C:\\foo\\bar\\baz.txt", true);
testDosIsAbsolute("/foo", true);
testDosIsAbsolute("foo.txt", false);
testDosIsAbsolute("bar\\foo.txt", false);
testDosIsAbsolute("bar/foo.txt", false);
}
void testDosBackupName(const std::string& in, const std::string& expected)
{
TCERR << "In: " << in << " | Expected: " << expected << " | Observed: " << cDosPath::BackupName(in) << std::endl;
TEST( expected == cDosPath::BackupName(in) );
}
void TestDosBackupName()
{
testDosBackupName("C:\\12345678.123", "C:\\12345678");
testDosBackupName("C:\\12345678", "C:\\12345678");
testDosBackupName("C:\\1.123", "C:\\1_123");
testDosBackupName("C:\\1", "C:\\1");
testDosBackupName("C:\\FOO\\12345678.123", "C:\\FOO\\12345678");
testDosBackupName("C:\\FOO.BAR\\1234.123", "C:\\FOO.BAR\\1234_123");
}
void testArosAsPosix(const std::string& in, const std::string& expected)
{
TCERR << "In: " << in << " | Expected: " << expected << " | Observed: " << cArosPath::AsPosix(in) << std::endl ;
TEST( expected == cArosPath::AsPosix(in) );
}
void TestArosAsPosix()
{
// testArosAsPosix("DH0:", "/DH0/");
testArosAsPosix("DH0:Foo", "/DH0/Foo");
testArosAsPosix("DH0:Foo/Bar", "/DH0/Foo/Bar");
testArosAsPosix("/DH0/Foo/Bar", "/DH0/Foo/Bar");
testArosAsPosix("Foo", "Foo");
testArosAsPosix("Foo/Bar", "Foo/Bar");
}
void testArosAsNative(const std::string& in, const std::string& expected)
{
TEST( expected == cArosPath::AsNative(in) );
}
void TestArosAsNative()
{
testArosAsNative("/DH0", "DH0:");
testArosAsNative("/DH0/Foo", "DH0:Foo" );
testArosAsNative("/DH0/Foo/Bar", "DH0:Foo/Bar" );
testArosAsNative("DH0:Foo/Bar", "DH0:Foo/Bar");
testArosAsNative("Foo", "Foo");
testArosAsNative("Foo/Bar", "Foo/Bar");
}
void testArosIsAbsolute(const std::string& in, bool expected)
{
TEST( expected == cArosPath::IsAbsolutePath(in) );
}
void TestArosIsAbsolute()
{
testArosIsAbsolute("DH0:", true);
testArosIsAbsolute("DH0:Foo", true);
testArosIsAbsolute("DH0:Foo/bar", true);
testArosIsAbsolute("/DH0/Foo/bar", true);
testArosIsAbsolute("Foo/bar", false);
testArosIsAbsolute("Foo", false);
}
void RegisterSuite_File()
{
RegisterTest("File", "Basic", TestFile);
RegisterTest("File", "DosAsPosix", TestDosAsPosix);
RegisterTest("File", "DosAsNative", TestDosAsNative);
RegisterTest("File", "DosIsAbsolute", TestDosIsAbsolute);
RegisterTest("File", "DosBackupName", TestDosBackupName);
// TODO: Finish these
/*
RegisterTest("File", "ArosAsPosix", TestArosAsPosix);
RegisterTest("File", "ArosAsNative", TestArosAsNative);
RegisterTest("File", "ArosIsAbsolute", TestArosIsAbsolute);
*/
}

View File

@ -41,6 +41,7 @@
#include "fco/fcospechelper.h"
#include "core/fsservices.h"
#include <unistd.h>
///////////////////////////////////////////////////////////////////////////////
// PrintFCOTree -- recursively prints an fco's name and all of it's children's
@ -92,6 +93,9 @@ void TestFCOSpecImpl2()
cDebug d("TestFCOSpecImpl2");
d.TraceDebug("Entering...\n");
if( -1 == access("/etc", F_OK))
skip("/etc not found/accessible");
cFSDataSourceIter dataSrc;
// create an FSSpec and set up some start and stop points...

View File

@ -45,7 +45,9 @@
#include "fco/fcospeclist.h"
#include "twtest/test.h"
#include "util/fileutil.h"
#include <fstream>
#include <unistd.h>
// helper class that checks output of each fcospec
class cPolicyParserTester {
@ -71,7 +73,10 @@ void test_policy_file(const std::string& polfile)
TSTRING pol_path = get_test_file_dir();
pol_path.append("/");
pol_path.append(polfile);
if(-1 == access(pol_path.c_str(), F_OK))
skip("policy parser test file not found/accessible");
std::ifstream in;
in.open(pol_path.c_str());
if( ! in.good() )

View File

@ -208,7 +208,12 @@ bool cFileUtil::BackupFile(const TSTRING& filename, bool printWarningOnFailure)
throw eFileWrite(filename, iFSServices::GetInstance()->GetErrString() );
}
#if IS_DOS_DJGPP
TSTRING backup_filename = cDosPath::BackupName( cDosPath::AsNative(filename) );
#else
TSTRING backup_filename = filename;
#endif
backup_filename += iFSServices::GetInstance()->GetStandardBackupExtension();
// remove the backup file if it exists. We ingore the return value from