Add ability to optionally *not* resolve uid/gid to name, to accomodate the Linux static binary vs. nsswitch name resolution issue; add RESOLVE_IDS_TO_NAMES config option to control this feature; avoid redundant lstats when turning IDs into names, since the lstat is to fetch the ID we already have; remove a bunch of unused code in UnixFSServices
This commit is contained in:
parent
3d304eb1af
commit
f9aa5de896
|
@ -112,10 +112,10 @@ typedef int64 cFSType;
|
|||
|
||||
// filesystem access control lists
|
||||
// it is the union of MAX(elem) for all the file systems that we support
|
||||
class cACLElem {
|
||||
/*class cACLElem {
|
||||
// TODO this is just a place holder
|
||||
// uint32 mUid;
|
||||
};
|
||||
};*/
|
||||
|
||||
// this class is used only to pass arguments to iFSServices
|
||||
// it is the union of MAX(elem) for all the file systems that we support
|
||||
|
@ -155,8 +155,8 @@ struct cFSStatArgs {
|
|||
FileType mFileType; // redundant with other information in this struct, but
|
||||
// broken out for convenience
|
||||
|
||||
// access control list should go here, too
|
||||
std::list <cACLElem> mACL; // indep
|
||||
//TODO: access control list should go here, too
|
||||
//std::list <cACLElem> mACL; // indep
|
||||
};
|
||||
|
||||
|
||||
|
@ -252,16 +252,6 @@ class iFSServices
|
|||
// TSTRING must have the form ("baseXXXXXX"), where the X's are replaced with
|
||||
// characters to make it a unique file. There must be at least 6 Xs.
|
||||
|
||||
// TODO: remove this function
|
||||
// Matt theorized that this is no longer used - dmb Aug 23 1999
|
||||
// virtual int CreateLockedTemporaryFile( const TCHAR* szFilename, int perm ) const = 0;
|
||||
// creates a temporary file to which only the current process has read or write access.
|
||||
// returns an open C file descriptor on success and -1 on error. Returns error if filename already exists on the filesystem.
|
||||
// the file will automatically be deleted when the file descriptor is closed.
|
||||
// perm should be zero or more of:
|
||||
// O_WRONLY: create with read write only permission
|
||||
// O_RDWR: create with read and write permission
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// minor filesystem functions
|
||||
|
@ -286,29 +276,29 @@ class iFSServices
|
|||
// short names.
|
||||
virtual void GetCurrentDir( TSTRING& strCurDir ) const throw( eFSServices ) = 0;
|
||||
// returns the current working directory
|
||||
virtual void ChangeDir( const TSTRING& strName ) const throw( eFSServices ) = 0;
|
||||
// sets the current working directory
|
||||
virtual void Mkdir( const TSTRING& strName ) const throw( eFSServices ) = 0;
|
||||
|
||||
virtual bool Rmdir( const TSTRING& strName ) const = 0;
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// file specific functions
|
||||
////////////////////////////////////////
|
||||
virtual bool FileDelete( const TSTRING& name ) const = 0;
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// directory and file functions
|
||||
////////////////////////////////////////
|
||||
virtual bool Rename( const TSTRING& strOldName, const TSTRING& strNewName, bool fOverWrite = true ) const = 0;
|
||||
// rename a file
|
||||
|
||||
virtual bool GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tstrUser ) const = 0;
|
||||
|
||||
virtual bool GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tstrGroup ) const = 0;
|
||||
virtual bool GetUserName( uid_t user_id, TSTRING& tstrUser ) const = 0;
|
||||
virtual bool GetGroupName( gid_t group_id, TSTRING& tstrGroup ) const = 0;
|
||||
|
||||
|
||||
//Set whether we try to resolve uid/gid to a name, since Linux static binaries can
|
||||
//have trouble (read: segfaulting) with name resolution given the right nsswitch.conf setup.
|
||||
//This defaults to true if not specified.
|
||||
virtual void SetResolveNames(bool resolve)=0;
|
||||
|
||||
////////////////////////////////////////
|
||||
// miscellaneous utility functions
|
||||
////////////////////////////////////////
|
||||
|
@ -347,44 +337,6 @@ class iFSServices
|
|||
///////////////////////////////////////////////////////////////
|
||||
private:
|
||||
static iFSServices* mpInstance;
|
||||
|
||||
//virtual cFSStatArgs::FileType GetFileType(const cFCOName &filename) throw(eFSServices) = 0;
|
||||
// returns the type of the file specified by filename. Separated from Stat() for convenience
|
||||
// and potential efficiency (if a file system doesn't need to do a stat to get the file type)
|
||||
|
||||
//virtual char*& MakeTempFile( char*& name) throw(eFSServices) = 0;
|
||||
//virtual wchar_t*& MakeTempFile( wchar_t*& name) throw(eFSServices) = 0;
|
||||
|
||||
//
|
||||
// file ops
|
||||
//
|
||||
// these are commented out for timeliness reasons; we should uncomment and implement as needed...
|
||||
// -- mdb
|
||||
/*
|
||||
virtual int Create(cFSName &name, Mode mode = MODE_DEFAULT) = 0;
|
||||
virtual bool Mkdir(cFSName &name, Mode mode = MODE_DEFAULT) = 0;
|
||||
virtual bool Delete(cFSName &name) = 0;
|
||||
virtual bool Link(cFSName &src, cFSName &dest) = 0;
|
||||
|
||||
virtual bool Chmod(cFSName &name, Mode mode) = 0;
|
||||
virtual Mode Umask(Mode mode) = 0;
|
||||
// file system types (e.g., "FAT", "NTFS", "UFS", "NFS")
|
||||
virtual bool FSTypeAsString(cFSName &name, TSTRING &str) = 0;
|
||||
// file type (e.g., "file", "symbolic link", "block device")
|
||||
// TODO -- this should either be static or in another utility class, since it does not rely on the
|
||||
// instance of the class (there is a global enumeration of file types; this fn should take a
|
||||
// cFSStatArgs::FileType instead of a name.
|
||||
virtual bool FileTypeAsString(cFSName &filename, TSTRING &str) = 0;
|
||||
// TODO -- does this beling here? Is it always true that st_dev defines the file system? If not, then the
|
||||
// Stat() call should add some extra piece of data that identifies the file system.
|
||||
virtual bool IsSameFileSystem(cFSStatArgs &file1, cFSStatArgs &file2) = 0;
|
||||
// to determine whether to recurse - musn't traverse mount points
|
||||
|
||||
// capabilities
|
||||
virtual bool IsUnicodeFilename(cFSName &name) = 0;
|
||||
virtual bool IsACLCapable(cFSName &name) = 0;
|
||||
virtual bool Is8bitFilename(cFSName &name) = 0;
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ template< typename T > static inline void util_ZeroMemory( T& obj );
|
|||
// PUBLIC METHOD CODE
|
||||
//=========================================================================
|
||||
|
||||
cUnixFSServices::cUnixFSServices()
|
||||
cUnixFSServices::cUnixFSServices() : mResolveNames(true)
|
||||
{}
|
||||
|
||||
cUnixFSServices::~cUnixFSServices()
|
||||
|
@ -257,12 +257,6 @@ void cUnixFSServices::GetCurrentDir( TSTRING& strCurDir ) const throw(eFSService
|
|||
strCurDir = pathname;
|
||||
}
|
||||
|
||||
void cUnixFSServices::ChangeDir( const TSTRING& strDir ) const throw(eFSServices)
|
||||
{
|
||||
if( chdir( strDir.c_str() ) < 0 )
|
||||
throw eFSServicesGeneric( strDir, iFSServices::GetInstance()->GetErrString() );
|
||||
}
|
||||
|
||||
|
||||
TSTRING& cUnixFSServices::MakeTempFilename( TSTRING& strName ) const throw(eFSServices)
|
||||
{
|
||||
|
@ -296,29 +290,11 @@ TSTRING& cUnixFSServices::MakeTempFilename( TSTRING& strName ) const throw(eFSSe
|
|||
|
||||
// Linux creates the file!! Doh!
|
||||
// So I'll always attempt to delete it -bam
|
||||
FileDelete( strName );
|
||||
FileDelete( strName.c_str() );
|
||||
|
||||
return( strName );
|
||||
}
|
||||
|
||||
void cUnixFSServices::Mkdir( const TSTRING& strName ) const throw ( eFSServices )
|
||||
{
|
||||
if( 0 != _tmkdir( strName.c_str(), 0777 ) )
|
||||
{
|
||||
// if mkdir failed because the dir existed, that's OK
|
||||
if( errno != EEXIST )
|
||||
throw eFSServicesGeneric( strName, iFSServices::GetInstance()->GetErrString() );
|
||||
}
|
||||
}
|
||||
|
||||
bool cUnixFSServices::Rmdir( const TSTRING& strName ) const
|
||||
{
|
||||
if( 0 == rmdir( strName.c_str() ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void cUnixFSServices::GetTempDirName( TSTRING& strName ) const throw(eFSServices)
|
||||
{
|
||||
strName = mTempPath;
|
||||
|
@ -516,35 +492,27 @@ bool cUnixFSServices::IsCaseSensitive() const
|
|||
}
|
||||
|
||||
|
||||
void cUnixFSServices::SetResolveNames(bool resolve)
|
||||
{
|
||||
mResolveNames=resolve;
|
||||
}
|
||||
|
||||
bool cUnixFSServices::GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tstrUser ) const
|
||||
{
|
||||
bool fSuccess = true;
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
int ret = lstat(tstrFilename.c_str(), &statbuf);
|
||||
if(ret < 0)
|
||||
{
|
||||
fSuccess = false;
|
||||
}
|
||||
|
||||
if( fSuccess )
|
||||
else
|
||||
{
|
||||
struct passwd* pp = getpwuid( statbuf.st_uid );
|
||||
//ASSERT( pp );
|
||||
// We shouldn't assert this, because it might be the case that a file
|
||||
// is associated with some old user that no longer exists... we should
|
||||
// not fail this case. Instead, the method will just return false per
|
||||
// the test below.
|
||||
if( pp == NULL )
|
||||
{
|
||||
fSuccess = false;
|
||||
}
|
||||
else
|
||||
tstrUser = pp->pw_name;
|
||||
fSuccess = GetUserName(statbuf.st_uid, tstrUser);
|
||||
}
|
||||
|
||||
return( fSuccess );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -558,12 +526,48 @@ bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tst
|
|||
{
|
||||
fSuccess = false;
|
||||
}
|
||||
|
||||
if( fSuccess )
|
||||
else
|
||||
{
|
||||
struct group* pg = getgrgid( statbuf.st_gid );
|
||||
//ASSERT( pg ); this assert stops everything in debug mode if we can't lookup a groupid
|
||||
fSuccess = GetGroupName(statbuf.st_gid, tstrGroup);
|
||||
}
|
||||
|
||||
return( fSuccess );
|
||||
}
|
||||
|
||||
|
||||
bool cUnixFSServices::GetUserName( uid_t user_id, TSTRING& tstrUser ) const
|
||||
{
|
||||
bool fSuccess = true;
|
||||
|
||||
if( mResolveNames )
|
||||
{
|
||||
struct passwd* pp = getpwuid( user_id );
|
||||
if( pp == NULL )
|
||||
{
|
||||
fSuccess = false;
|
||||
tstrUser = TSS_GetString(cCore, core::STR_UNKNOWN);
|
||||
}
|
||||
else
|
||||
tstrUser = pp->pw_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << user_id;
|
||||
tstrUser = sstr.str();
|
||||
}
|
||||
|
||||
return( fSuccess );
|
||||
}
|
||||
|
||||
|
||||
bool cUnixFSServices::GetGroupName( gid_t group_id, TSTRING& tstrGroup ) const
|
||||
{
|
||||
bool fSuccess = true;
|
||||
|
||||
if( mResolveNames )
|
||||
{
|
||||
struct group* pg = getgrgid( group_id );
|
||||
if( pg == NULL )
|
||||
{
|
||||
fSuccess = false;
|
||||
|
@ -571,11 +575,19 @@ bool cUnixFSServices::GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tst
|
|||
}
|
||||
else
|
||||
tstrGroup = pg->gr_name;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << group_id;
|
||||
tstrGroup = sstr.str();
|
||||
}
|
||||
|
||||
return( fSuccess );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef S_ISVTX // DOS/DJGPP doesn't have this
|
||||
# define S_ISVTX 0
|
||||
#endif
|
||||
|
@ -750,7 +762,7 @@ bool cUnixFSServices::GetExecutableFilename( TSTRING& strFullPath, const TSTRING
|
|||
// a bool? I think it is ... mdb
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool cUnixFSServices::FullPath( TSTRING& strFullPath, const TSTRING& strRelPathC, const TSTRING& pathRelFromC ) const
|
||||
{
|
||||
{
|
||||
// don't do anything with an empty path
|
||||
if( strRelPathC.empty() )
|
||||
return false;
|
||||
|
@ -843,39 +855,6 @@ const TCHAR* cUnixFSServices::GetStandardBackupExtension() const
|
|||
}
|
||||
|
||||
|
||||
// TODO: remove this function
|
||||
// Matt theorized that this is no longer used - dmb Aug 23 1999
|
||||
/*
|
||||
int cUnixFSServices::CreateLockedTemporaryFile( const TCHAR* szFilename, int perm ) const
|
||||
{
|
||||
// make sure perm is AT LEAST one of: O_RDWR, O_WRONLY
|
||||
ASSERT( 0 != ( perm & ( O_RDWR | O_WRONLY ) ) );
|
||||
// make sure perm is ONLY composed of: O_RDWR, O_WRONLY
|
||||
ASSERT( 0 == ( perm & ~( O_RDWR | O_WRONLY ) ) );
|
||||
// get rid of any unsupported bits caller may have supplied
|
||||
perm &= ( O_RDWR | O_WRONLY );
|
||||
|
||||
// set flags
|
||||
int oflags = perm |
|
||||
O_CREAT | O_EXCL; // only create a new file -- error if it exists already
|
||||
|
||||
// create file
|
||||
int fh = _topen( szFilename, oflags, 0666 );
|
||||
if( fh >= 0 )
|
||||
{
|
||||
// file was created. Now unlink it
|
||||
if( 0 != unlink( szFilename ) )
|
||||
{
|
||||
// we weren't able to unlink file, so close handle and fail
|
||||
close( fh );
|
||||
fh = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return( fh );
|
||||
}
|
||||
*/
|
||||
|
||||
void cUnixFSServices::Sleep( int nSeconds ) const
|
||||
{
|
||||
sleep( nSeconds );
|
||||
|
|
|
@ -54,38 +54,8 @@
|
|||
// DECLARATION OF CLASSES
|
||||
//=========================================================================
|
||||
|
||||
//Set up in constructor. Stores pertinent information about the filesystem
|
||||
//serviced by each instantiation.
|
||||
|
||||
struct UnixSysInfo
|
||||
{
|
||||
uint32 maxcomplen;
|
||||
//max name length of a file on filesystem
|
||||
uint32 fsflags;
|
||||
//bitmask of flags
|
||||
TSTRING fsname;
|
||||
//The filesystem basename
|
||||
uint32 fsid;
|
||||
//unique indentifier for the filesystem
|
||||
};
|
||||
|
||||
class cUnixFSServices : public iFSServices
|
||||
{
|
||||
///////////////////////////////////////////////////////////////
|
||||
// ENUMS
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////
|
||||
// file system types
|
||||
////////////////////////////////////////
|
||||
enum FSType
|
||||
{
|
||||
FS_UFS = 0,
|
||||
FS_NFS,
|
||||
FS_HSFS,
|
||||
FS_PCFS
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// MEMBER FUNCTIONS
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
@ -127,10 +97,6 @@ class cUnixFSServices : public iFSServices
|
|||
// strName must have the form ("baseXXXXXX"), where the X's are replaced with
|
||||
// characters to make it a unique file. There must be at least 6 Xs.
|
||||
|
||||
// TODO: remove this function
|
||||
// Matt theorized that this is no longer used - dmb Aug 23 1999
|
||||
//virtual int CreateLockedTemporaryFile( const TCHAR* szFilename, int perm ) const;
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// minor filesystem functions
|
||||
|
@ -153,29 +119,29 @@ class cUnixFSServices : public iFSServices
|
|||
// puts the contents of the specified directory, except for . and .., into the supplied vector.
|
||||
virtual void GetCurrentDir( TSTRING& strCurDir ) const throw( eFSServices );
|
||||
// returns the current working directory
|
||||
virtual void ChangeDir( const TSTRING& strName ) const throw( eFSServices );
|
||||
// sets the current working directory
|
||||
virtual void Mkdir( const TSTRING& strName ) const throw( eFSServices );
|
||||
|
||||
virtual bool Rmdir( const TSTRING& strName ) const;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// file specific functions
|
||||
////////////////////////////////////////
|
||||
virtual bool FileDelete( const TSTRING& name ) const;
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// directory and file functions
|
||||
////////////////////////////////////////
|
||||
virtual bool Rename( const TSTRING& strOldName, const TSTRING& strNewName, bool fOverWrite = true ) const;
|
||||
// rename a file
|
||||
|
||||
virtual bool GetOwnerForFile( const TSTRING& tstrFilename, TSTRING& tstrUser ) const;
|
||||
|
||||
virtual bool GetGroupForFile( const TSTRING& tstrFilename, TSTRING& tstrGroup ) const;
|
||||
virtual bool GetUserName( uid_t user_id, TSTRING& tstrUser ) const;
|
||||
virtual bool GetGroupName( gid_t group_id, TSTRING& tstrGroup ) const;
|
||||
|
||||
|
||||
//Set whether we try to resolve uid/gid to a name, since Linux static binaries can
|
||||
//have trouble (read: segfaulting) with name resolution given the right nsswitch.conf setup.
|
||||
//This defaults to true if not specified.
|
||||
virtual void SetResolveNames(bool resolve);
|
||||
|
||||
////////////////////////////////////////
|
||||
// miscellaneous utility functions
|
||||
////////////////////////////////////////
|
||||
|
@ -195,11 +161,9 @@ class cUnixFSServices : public iFSServices
|
|||
virtual TSTRING GetErrString() const;
|
||||
|
||||
private:
|
||||
UnixSysInfo info;
|
||||
//struct stores pertinent system info. to be used by member functions
|
||||
|
||||
TSTRING mTempPath;
|
||||
|
||||
bool mResolveNames;
|
||||
};
|
||||
|
||||
#endif //__UNIXFSSERVICES_H
|
||||
|
|
|
@ -270,7 +270,7 @@ void cFSPropDisplayer::InitForProp( const iFCO* const pFCO, const int propIdx)
|
|||
if( ! GetUsername( i64UID, tstrDummy ) )
|
||||
{
|
||||
TSTRING tstrUsername;
|
||||
if( iFSServices::GetInstance()->GetOwnerForFile( pFCO->GetName().AsString(), tstrUsername ) )
|
||||
if( iFSServices::GetInstance()->GetUserName( i64UID, tstrUsername ) )
|
||||
AddUsernameMapping ( i64UID, tstrUsername );
|
||||
else
|
||||
AddUsernameMapping ( i64UID, _T("") ); // on failure, enter error value into mapping so we don't search for this value again.
|
||||
|
@ -286,7 +286,7 @@ void cFSPropDisplayer::InitForProp( const iFCO* const pFCO, const int propIdx)
|
|||
if( ! GetGroupname( i64GID, tstrDummy ) )
|
||||
{
|
||||
TSTRING tstrGroupname;
|
||||
if( iFSServices::GetInstance()->GetGroupForFile( pFCO->GetName().AsString(), tstrGroupname ) )
|
||||
if( iFSServices::GetInstance()->GetGroupName( i64GID, tstrGroupname ) )
|
||||
AddGroupnameMapping( i64GID, tstrGroupname );
|
||||
else
|
||||
AddGroupnameMapping( i64GID, _T("") ); // on failure, enter error value into mapping so we don't search for this value again.
|
||||
|
|
|
@ -455,7 +455,14 @@ static void FillOutConfigInfo(cTWModeCommon* pModeInfo, const cConfigFile& cf)
|
|||
#else
|
||||
throw eTWDirectIONotSupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
if(cf.Lookup(TSTRING(_T("RESOLVE_IDS_TO_NAMES")), str))
|
||||
{
|
||||
if (_tcsicmp(str.c_str(), _T("true")) == 0)
|
||||
iFSServices::GetInstance()->SetResolveNames(true);
|
||||
else
|
||||
iFSServices::GetInstance()->SetResolveNames(false);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -119,23 +119,6 @@ void TestUnixFSServices()
|
|||
d.TraceDetail("Testing MakeTempFilename: \n");
|
||||
d.TraceDetail("%s \n", _template.c_str() );
|
||||
|
||||
//Test ChangeDir
|
||||
d.TraceDetail("Testing ChangeDir: (should be /usr)\n");
|
||||
TSTRING newdir(_T("/usr"));
|
||||
pFSServices->ChangeDir(newdir);
|
||||
pFSServices->GetCurrentDir(currpath);
|
||||
d.TraceDetail("%s \n", currpath.c_str() );
|
||||
//Did we get there??
|
||||
|
||||
//Test Mkdir:
|
||||
d.TraceDetail("Testing Mkdir: \n");
|
||||
TSTRING makedir(_T("/tmp/tw_mkdir"));
|
||||
pFSServices->Mkdir(makedir); // throws on error
|
||||
|
||||
//Test Rmdir
|
||||
d.TraceDetail("Testing Rmdir:\n");
|
||||
TEST( pFSServices->Rmdir(makedir) );
|
||||
|
||||
// Test GetMachineName
|
||||
d.TraceDetail("Testing GetMachineName:\n");
|
||||
TSTRING uname;
|
||||
|
|
Loading…
Reference in New Issue