diff --git a/src/core/file.h b/src/core/file.h index 2092968..da9f45b 100644 --- a/src/core/file.h +++ b/src/core/file.h @@ -138,13 +138,37 @@ 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); +}; + +class cRiscosPath +{ +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 +#elif IS_RISCOS +#define cDevicePath cRiscosPath #endif diff --git a/src/core/file_unix.cpp b/src/core/file_unix.cpp index 49f5e3c..ae9fed9 100644 --- a/src/core/file_unix.cpp +++ b/src/core/file_unix.cpp @@ -62,6 +62,10 @@ #include "core/fsservices.h" #include "core/errorutil.h" +#if IS_RISCOS +#include +#endif + /////////////////////////////////////////////////////////////////////////// // cFile_i : Insulated implementation for cFile objects. /////////////////////////////////////////////////////////////////////////// @@ -79,28 +83,28 @@ struct cFile_i //Ctor cFile_i::cFile_i() : - mpCurrStream(NULL) + m_fd(-1), mpCurrStream(NULL), mFlags(0) {} //Dtor cFile_i::~cFile_i() { if (mpCurrStream != NULL) - fclose( mpCurrStream ); - mpCurrStream = NULL; - -#if IS_AROS - if( mFlags & cFile::OPEN_LOCKED_TEMP ) { - // unlink this file - if( 0 != unlink(mFileName.c_str())) - { - throw( eFileOpen( mFileName, iFSServices::GetInstance()->GetErrString() ) ); - } - } -#endif + fclose( mpCurrStream ); + mpCurrStream = NULL; - mFileName.empty(); +#if IS_AROS || IS_RISCOS + if( mFlags & cFile::OPEN_LOCKED_TEMP ) + { + // unlink this file + if( 0 != unlink(mFileName.c_str())) + { + throw( eFileOpen( mFileName, iFSServices::GetInstance()->GetErrString() ) ); + } + } +#endif + } } /////////////////////////////////////////////////////////////////////////// @@ -205,7 +209,7 @@ void cFile::Open( const TSTRING& sFileNameC, uint32 flags ) } mpData->m_fd = fh; -#if !IS_AROS +#if !IS_AROS && !IS_RISCOS if( flags & OPEN_LOCKED_TEMP ) { // unlink this file @@ -449,31 +453,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 +501,133 @@ TSTRING cDevicePath::AsNative( const TSTRING& in ) if (in.length() >= 8) out.append(in.substr(7)); - - return out; - -#elif IS_AROS - int x = 1; - for ( x; in[x] == '/' && x buf(buf_size); + __riscosify(in.c_str(), 0,0, &buf[0], buf_size, 0); + if(buf[0]) + { + out.assign(&buf[0]); + return out; + } + return in; +#else + return in; #endif +} + diff --git a/src/core/platform.h b/src/core/platform.h index 05194fe..92b8d82 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -311,7 +311,7 @@ #define SUPPORTS_SYSLOG (HAVE_SYSLOG_H && !IS_SKYOS && !IS_RISCOS) #define NEEDS_SWAB_IMPL (IS_CYGWIN || IS_SYLLABLE || IS_ANDROID || IS_SORTIX) #define USES_MBLEN (!IS_ANDROID && !IS_AROS) -#define USES_DEVICE_PATH (IS_AROS || IS_DOS_DJGPP) +#define USES_DEVICE_PATH (IS_AROS || IS_DOS_DJGPP || IS_RISCOS) #define ICONV_CONST_SOURCE (IS_MINIX) #define SUPPORTS_DIRECT_IO (IS_LINUX) // Linux is the only platform where direct i/o hashing has been tested & works properly so far. diff --git a/src/core/unixfsservices.cpp b/src/core/unixfsservices.cpp index 92ba8e8..7ad946b 100644 --- a/src/core/unixfsservices.cpp +++ b/src/core/unixfsservices.cpp @@ -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,15 @@ bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC strFullPath += TW_SLASH; strFullPath += strElem; } + + d.TraceDebug("FullPath is now %s\n", strFullPath.c_str()); } +#if IS_AROS + strFullPath = cDevicePath::AsNative(strFullPath); +#endif + + d.TraceDebug("Done, returning %s\n", strFullPath.c_str()); return true; } diff --git a/src/fs/fsparserutil.cpp b/src/fs/fsparserutil.cpp index d93bbf8..28843d0 100644 --- a/src/fs/fsparserutil.cpp +++ b/src/fs/fsparserutil.cpp @@ -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 } diff --git a/src/fs/fspropcalc.cpp b/src/fs/fspropcalc.cpp index 2c3fd65..9c2e8de 100644 --- a/src/fs/fspropcalc.cpp +++ b/src/fs/fspropcalc.cpp @@ -90,7 +90,7 @@ bool cFSPropCalc::GetSymLinkStr(const TSTRING& strName, cArchive& arch, size_t s std::vector data(size+1); char* buf = &data[0]; -#if defined(O_PATH) +#if defined(O_PATH) // A Linuxism that lets us read symlinks w/o bumping the access time. int fd = open(strName.c_str(), (O_PATH | O_NOFOLLOW | O_NOATIME)); int rtn = readlinkat(fd, 0, buf, size); close(fd); @@ -98,13 +98,13 @@ bool cFSPropCalc::GetSymLinkStr(const TSTRING& strName, cArchive& arch, size_t s int rtn = readlink( strName.c_str(), buf, size ); #endif - if(rtn == -1) + if(rtn < 0) { // Some OSes (like HP-UX) return ERANGE if buffer is too small. // This is nonstandard but better than the usual truncate-and-say-you-succeeded // if(ERANGE == errno) - return GetSymLinkStr(strName, arch, size*2); + return GetSymLinkStr(strName, arch, size*2); return false; } diff --git a/src/test-harness/tests/dbupdate.pm b/src/test-harness/tests/dbupdate.pm index 9bab52b..d9c5875 100644 --- a/src/test-harness/tests/dbupdate.pm +++ b/src/test-harness/tests/dbupdate.pm @@ -158,9 +158,10 @@ sub RunBasicTest # Make sure we got 4 violations: 2 mod, 1 add, 1 rm. # + my $dir_mods = (($^O eq "skyos") || ($^O eq "dragonfly")) ? 0 : 1; my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); - my $n_expected = ($^O ne "skyos") ? 4 : 3; - my $c_expected = ($^O ne "skyos") ? 2 : 1; + my $n_expected = $dir_mods ? 4 : 3; + my $c_expected = $dir_mods ? 2 : 1; if( ($n != $n_expected) || ($a != 1) || ($r != 1) || ($c != $c_expected) ) { diff --git a/src/test-harness/tests/dirs.pm b/src/test-harness/tests/dirs.pm index 071b76f..dfbb37a 100644 --- a/src/test-harness/tests/dirs.pm +++ b/src/test-harness/tests/dirs.pm @@ -123,9 +123,9 @@ sub run() { twtools::logStatus("*** Beginning $description\n"); printf("%-30s", "-- $description"); - if ($^O eq "skyos") { + if (($^O eq "skyos") || ($^O eq "dragonfly")) { ++$twtools::twskippedtests; - print "SKIPPED; TODO: SkyOS has fewer expected changes here; refactor so we can test for correct values\n"; + print "SKIPPED; TODO: OS has fewer expected changes here; refactor so we can test for correct values\n"; return; } diff --git a/src/test-harness/tests/integritycheck.pm b/src/test-harness/tests/integritycheck.pm index e37dcc3..b72383b 100644 --- a/src/test-harness/tests/integritycheck.pm +++ b/src/test-harness/tests/integritycheck.pm @@ -160,12 +160,18 @@ sub PrepareForTest # sub run { + twtools::logStatus("*** Beginning $description\n"); + printf("%-30s", "-- $description"); + + if ($^O eq "dragonfly") { + ++$twtools::twskippedtests; + print "SKIPPED; TODO: DragonflyBSD has fewer expected changes here; refactor so we can test for correct values\n"; + return; + } + my $twpassed = 1; my $dir_mods = ($^O eq "skyos") ? 0 : 1; - twtools::logStatus("*** Beginning integrity check test\n"); - printf("%-30s", "-- $description"); - PrepareForTest(); # make some violations... diff --git a/src/tripwire/twcmdline.cpp b/src/tripwire/twcmdline.cpp index 4cf28f9..39e9577 100644 --- a/src/tripwire/twcmdline.cpp +++ b/src/tripwire/twcmdline.cpp @@ -249,6 +249,183 @@ 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/"; +#elif IS_RISCOS + temp_directory = "/!BOOT/Resources/!Scrap/ScrapDirs/ScrapDir"; +#else + temp_directory = "/tmp/"; +#endif + } + +#if !IS_RISCOS + // make sure we have a trailing slash -- thanks Jarno... + // + if (*temp_directory.rbegin() != '/') + { + temp_directory.push_back('/'); + } +#endif + + // make sure it exists... + // + +#if IS_AROS || IS_RISCOS + 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 + { +#if IS_RISCOS + if (*temp_directory.rbegin() != '.') + { + temp_directory.push_back('.'); + } +#endif + + 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( 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 +474,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( 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)) diff --git a/src/tw/twinit.cpp b/src/tw/twinit.cpp index 63afb63..5d98cc5 100644 --- a/src/tw/twinit.cpp +++ b/src/tw/twinit.cpp @@ -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('/') ); diff --git a/src/twtest/debug_t.cpp b/src/twtest/debug_t.cpp index 2b3be0f..c30e353 100644 --- a/src/twtest/debug_t.cpp +++ b/src/twtest/debug_t.cpp @@ -88,6 +88,11 @@ void TestDebug() if(oldOutTarget & cDebug::OUT_FILE) cDebug::AddOutTarget(cDebug::OUT_FILE); else cDebug::RemoveOutTarget(cDebug::OUT_FILE); d.TraceDebug("Exiting...\n"); + +#ifndef DEBUG + TEST("Should always succeed in release builds & cDebug should do nothing"); +#endif + } void RegisterSuite_Debug() diff --git a/src/twtest/file_t.cpp b/src/twtest/file_t.cpp index 1e55a96..1961926 100644 --- a/src/twtest/file_t.cpp +++ b/src/twtest/file_t.cpp @@ -58,7 +58,141 @@ 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) +{ + 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) +{ + 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); + + RegisterTest("File", "ArosAsPosix", TestArosAsPosix); + RegisterTest("File", "ArosAsNative", TestArosAsNative); + RegisterTest("File", "ArosIsAbsolute", TestArosIsAbsolute); } diff --git a/src/twtest/fsspec_t.cpp b/src/twtest/fsspec_t.cpp index c354434..c948d2f 100644 --- a/src/twtest/fsspec_t.cpp +++ b/src/twtest/fsspec_t.cpp @@ -41,6 +41,7 @@ #include "fco/fcospechelper.h" #include "core/fsservices.h" +#include /////////////////////////////////////////////////////////////////////////////// // 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... diff --git a/src/twtest/policyparser_t.cpp b/src/twtest/policyparser_t.cpp index 828080b..6dfba0f 100644 --- a/src/twtest/policyparser_t.cpp +++ b/src/twtest/policyparser_t.cpp @@ -45,7 +45,9 @@ #include "fco/fcospeclist.h" #include "twtest/test.h" #include "util/fileutil.h" + #include +#include // 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() ) diff --git a/src/twtest/unixfsservices_t.cpp b/src/twtest/unixfsservices_t.cpp index ac82a24..34a5654 100644 --- a/src/twtest/unixfsservices_t.cpp +++ b/src/twtest/unixfsservices_t.cpp @@ -42,6 +42,8 @@ #include "twtest/test.h" #endif +#include + using namespace std; @@ -177,6 +179,9 @@ void TestGetIPAddress() void TestGetExecutableFilename() { + if( -1 == access("/bin/sh", F_OK)) + skip("/bin/sh not found/accessible"); + TSTRING filename = _T("sh"); TSTRING fullpath = _T("/bin/"); TEST( iFSServices::GetInstance()->GetExecutableFilename(fullpath, filename)); diff --git a/src/util/fileutil.cpp b/src/util/fileutil.cpp index c608d55..37e5cac 100644 --- a/src/util/fileutil.cpp +++ b/src/util/fileutil.cpp @@ -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