Fix for bug 10177 and 10041.

This commit is contained in:
dougt%netscape.com 1999-07-26 22:09:42 +00:00
parent 2ff37fbe4e
commit 5adb63dcaf
25 changed files with 394 additions and 83 deletions

View File

@ -1515,7 +1515,7 @@ nsMsgAccountManager::MigrateNewsAccounts(nsIMsgIdentity *identity, PRInt32 baseA
dirWithTheNewsrcFiles = homeDir;
}
for (nsDirectoryIterator i(dirWithTheNewsrcFiles); i.Exists(); i++) {
for (nsDirectoryIterator i(dirWithTheNewsrcFiles, PR_FALSE); i.Exists(); i++) {
nsFileSpec possibleRcFile = i.Spec();
char *filename = possibleRcFile.GetLeafName();

View File

@ -297,7 +297,7 @@ nsresult nsImapMailFolder::CreateSubFolders(nsFileSpec &path)
nsAutoString currentFolderNameStr;
nsCOMPtr<nsIMsgFolder> child;
char *folderName;
for (nsDirectoryIterator dir(path); dir.Exists(); dir++)
for (nsDirectoryIterator dir(path, PR_FALSE); dir.Exists(); dir++)
{
nsFileSpec currentFolderPath = (nsFileSpec&)dir;

View File

@ -199,7 +199,7 @@ nsMsgLocalMailFolder::CreateSubFolders(nsFileSpec &path)
nsAutoString currentFolderNameStr;
nsCOMPtr<nsIMsgFolder> child;
char *folderName;
for (nsDirectoryIterator dir(path); dir.Exists(); dir++) {
for (nsDirectoryIterator dir(path, PR_FALSE); dir.Exists(); dir++) {
nsFileSpec currentFolderPath = (nsFileSpec&)dir;
folderName = currentFolderPath.GetLeafName();

View File

@ -305,7 +305,7 @@ ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr)
short appRefNum = ::CurResFile();
short pluginRefNum;
for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++)
for(nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++)
{
const nsFileSpec& file = iter;
if (pluginsDir.IsPluginFile(file))

View File

@ -2216,7 +2216,7 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
if (! pluginsDir.Valid())
break;
for (nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) {
for (nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++) {
const nsFileSpec& file = iter;
if (pluginsDir.IsPluginFile(file)) {
nsPluginFile pluginFile(file);

View File

@ -305,7 +305,7 @@ ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr)
short appRefNum = ::CurResFile();
short pluginRefNum;
for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++)
for(nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++)
{
const nsFileSpec& file = iter;
if (pluginsDir.IsPluginFile(file))

View File

@ -2216,7 +2216,7 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
if (! pluginsDir.Valid())
break;
for (nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) {
for (nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++) {
const nsFileSpec& file = iter;
if (pluginsDir.IsPluginFile(file)) {
nsPluginFile pluginFile(file);

View File

@ -362,7 +362,7 @@ Test(CreateFun create, PRUint32 count,
NS_ASSERTION(NS_SUCCEEDED(rv), "NS_NewISupportsArray failed");
nsFileSpec inDirSpec(inDir);
nsDirectoryIterator iter(inDirSpec);
nsDirectoryIterator iter(inDirSpec, PR_TRUE);
for (i = 0; i < count && iter.Exists(); i++, iter++) {
nsIThread* thread;
nsIRunnable* worker;

View File

@ -343,7 +343,7 @@ nsPrefMigration::GetSizes(nsFileSpec inputPath, PRBool readSubdirs, PRUint32 *si
nsAutoString fileOrDirNameStr;
PRInt32 len;
for (nsDirectoryIterator dir(inputPath); dir.Exists(); dir++)
for (nsDirectoryIterator dir(inputPath, PR_FALSE); dir.Exists(); dir++)
{
nsFileSpec fileOrDirName = (nsFileSpec&)dir;
folderName = fileOrDirName.GetLeafName();
@ -409,7 +409,7 @@ nsPrefMigration::DoTheCopy(nsFileSpec oldPath, nsFileSpec newPath, PRBool readSu
char* folderName;
nsAutoString fileOrDirNameStr;
for (nsDirectoryIterator dir(oldPath); dir.Exists(); dir++)
for (nsDirectoryIterator dir(oldPath, PR_FALSE); dir.Exists(); dir++)
{
nsFileSpec fileOrDirName = (nsFileSpec&)dir; //set first file or dir to a nsFileSpec
folderName = fileOrDirName.GetLeafName(); //get the filename without the full path

View File

@ -1024,7 +1024,7 @@ FileSystemDataSource::GetFolderList(nsIRDFResource *source, nsISimpleEnumerator*
nsFileURL parentDir(uri);
nsNativeFileSpec nativeDir(parentDir);
for (nsDirectoryIterator i(nativeDir); i.Exists(); i++)
for (nsDirectoryIterator i(nativeDir, PR_FALSE); i.Exists(); i++)
{
const nsNativeFileSpec nativeSpec = (const nsNativeFileSpec &)i;
if (!isVisible(nativeSpec)) continue;

View File

@ -1079,7 +1079,7 @@ SearchDataSource::GetSearchEngineList()
searchSitesDir += "search";
nsFileSpec nativeDir(searchSitesDir);
#endif
for (nsDirectoryIterator i(nativeDir); i.Exists(); i++)
for (nsDirectoryIterator i(nativeDir, PR_FALSE); i.Exists(); i++)
{
const nsFileSpec fileSpec = (const nsFileSpec &)i;
const char *childURL = fileSpec;
@ -1229,7 +1229,7 @@ SearchDataSource::ReadFileContents(char *baseFilename, nsString& sourceContents)
// on Mac, use system's search files
nsSpecialSystemDirectory searchSitesDir(nsSpecialSystemDirectory::Mac_InternetSearchDirectory);
nsFileSpec nativeDir(searchSitesDir);
for (nsDirectoryIterator i(nativeDir); i.Exists(); i++)
for (nsDirectoryIterator i(nativeDir, PR_FALSE); i.Exists(); i++)
{
const nsFileSpec fileSpec = (const nsFileSpec &)i;
const char *childURL = fileSpec;

View File

@ -131,6 +131,14 @@ class nsFileSpecWithUIImpl
/* boolean isHidden (); */
NS_IMETHOD isHidden(PRBool *_retval)
{ return mBaseFileSpec ? mBaseFileSpec->isHidden(_retval) : NS_ERROR_NOT_INITIALIZED; }
/* boolean isSymlink (); */
NS_IMETHOD isSymlink(PRBool *_retval)
{ return mBaseFileSpec ? mBaseFileSpec->isSymlink(_retval) : NS_ERROR_NOT_INITIALIZED; }
/* void resolveSymlink (); */
NS_IMETHOD resolveSymlink()
{ return mBaseFileSpec ? mBaseFileSpec->resolveSymlink() : NS_ERROR_NOT_INITIALIZED; }
/* readonly attribute unsigned long FileSize; */
NS_IMETHOD GetFileSize(PRUint32 *aFileSize)

View File

@ -74,6 +74,7 @@ LLIBS = \
WIN_LIBS = \
shell32.lib \
ole32.lib \
!if defined(MOZ_TRACE_XPCOM_REFCNT)
imagehlp.lib \
!endif

View File

@ -339,8 +339,10 @@ class NS_COM nsFileSpec
nsFileSpec(
short vRefNum,
long parID,
ConstStr255Param name);
nsFileSpec(const FSSpec& inSpec);
ConstStr255Param name,
PRBool resolveAlias = PR_TRUE);
nsFileSpec(const FSSpec& inSpec, PRBool resolveAlias = PR_TRUE);
void operator = (const FSSpec& inSpec);
operator FSSpec* () { return &mSpec; }
@ -357,8 +359,7 @@ class NS_COM nsFileSpec
// a secret temp directory and modifies the spec to point
// to it. Sets mError.
void ResolveAlias(PRBool& wasAliased);
// Called for the spec of an alias. Modifies the spec to
// point to the original. Sets mError.
// ** do not use this function, instead us ResolveSymlink()
void MakeUnique(ConstStr255Param inSuggestedLeafName);
StringPtr GetLeafPName() { return mSpec.name; }
ConstStr255Param GetLeafPName() const { return mSpec.name; }
@ -458,10 +459,15 @@ class NS_COM nsFileSpec
PRBool IsHidden() const;
PRBool IsSymlink() const;
//--------------------------------------------------
// Creation and deletion of objects. These can modify the disk.
//--------------------------------------------------
nsresult ResolveSymlink(PRBool& wasSymlink);
// Called for the spec of an alias. Modifies the spec to
// point to the original. Sets mError.
void CreateDirectory(int mode = 0700 /* for unix */);
void CreateDir(int mode = 0700) { CreateDirectory(mode); }
// workaround for yet another VC++ bug with long identifiers.
@ -664,26 +670,23 @@ class NS_COM nsDirectoryIterator
// Example:
//
// nsFileSpec parentDir(...); // directory over whose children we shall iterate
// for (nsDirectoryIterator i(parentDir); i.Exists(); i++)
// for (nsDirectoryIterator i(parentDir, PR_FALSE); i.Exists(); i++)
// {
// // do something with i.Spec()
// }
//
// or:
// - or -
//
// for (nsDirectoryIterator i(parentDir, -1); i.Exists(); i--)
// for (nsDirectoryIterator i(parentDir, PR_TRUE); i.Exists(); i--)
// {
// // do something with i.Spec()
// }
//
// Currently, the only platform on which backwards iteration actually goes backwards
// is Macintosh. On other platforms, both styles will work, but will go forwards.
// This one passed the PR_TRUE flag which will resolve any symlink encountered.
//========================================================================================
{
public:
nsDirectoryIterator(
const nsFileSpec& parent,
int iterateDirection = +1);
nsDirectoryIterator( const nsFileSpec& parent,
PRBool resoveSymLinks);
#ifndef XP_MAC
// Macintosh currently doesn't allocate, so needn't clean up.
virtual ~nsDirectoryIterator();
@ -711,6 +714,7 @@ class NS_COM nsDirectoryIterator
nsFileSpec mCurrent;
PRBool mExists;
PRBool mResoveSymLinks;
#if defined(XP_UNIX) || defined(XP_BEOS)
DIR* mDir;

View File

@ -118,9 +118,50 @@ PRBool nsFileSpec::IsDirectory() const
PRBool nsFileSpec::IsHidden() const
//----------------------------------------------------------------------------------------
{
return PR_FALSE; // FIX!!!!!
PRBool hidden = PR_TRUE;
char *leafname = GetLeafName();
if (nsnull != leafname)
{
if ((!strcmp(leafname, ".")) || (!strcmp(leafname, "..")))
{
hidden = PR_FALSE;
}
nsCRT::free(leafname);
}
return hidden;
} // nsFileSpec::IsHidden
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsSymlink() const
//----------------------------------------------------------------------------------------
{
struct stat st;
if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode))
return PR_TRUE;
return PR_FALSE;
} // nsFileSpec::IsSymlink
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
//----------------------------------------------------------------------------------------
{
wasAliased = PR_FALSE;
char resolvedPath[MAXPATHLEN];
int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN);
if (0 < charCount)
{
if (MAXPATHLEN > charCount)
resolvedPath[charCount] = '\0';
wasAliased = PR_TRUE;
mPath = (char*)&resolvedPath;
}
return NS_OK;
} // nsFileSpec::ResolveSymlink
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
@ -167,7 +208,7 @@ void nsFileSpec::Delete(PRBool inRecursive) const
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
@ -190,7 +231,7 @@ void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
newDir.CreateDirectory();
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
@ -398,11 +439,12 @@ PRUint32 nsFileSpec::GetDiskSpaceAvailable() const
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int /*inIterateDirection*/)
, PRBool resolveSymlinks)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mExists(PR_FALSE)
, mDir(nsnull)
, mResoveSymLinks(resolveSymlinks)
{
mCurrent += "sysygy"; // prepare the path for SetLeafName
mDir = opendir((const char*)nsFilePath(inDirectory));
@ -435,6 +477,11 @@ nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
{
mExists = PR_TRUE;
mCurrent.SetLeafName(entry->d_name);
if (mResoveSymLinks)
{
PRBool ignore;
mCurrent.ResolveSymlink(ignore);
}
}
return *this;
} // nsDirectoryIterator::operator ++

View File

@ -309,6 +309,23 @@ NS_IMETHODIMP nsFileSpecImpl::isHidden(PRBool *_retval)
return mFileSpec.Error();
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsFileSpecImpl::isSymlink(PRBool *_retval)
//----------------------------------------------------------------------------------------
{
TEST_OUT_PTR(_retval)
*_retval = mFileSpec.IsSymlink();
return mFileSpec.Error();
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsFileSpecImpl::resolveSymlink()
//----------------------------------------------------------------------------------------
{
PRBool ignore;
return mFileSpec.ResolveSymlink(ignore);
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsFileSpecImpl::GetFileSize(PRUint32 *aFileSize)
//----------------------------------------------------------------------------------------
@ -646,7 +663,7 @@ NS_IMETHODIMP nsDirectoryIteratorImpl::Init(nsIFileSpec *parent)
//----------------------------------------------------------------------------------------
{
delete mDirectoryIterator;
mDirectoryIterator = new nsDirectoryIterator(FILESPEC(parent));
mDirectoryIterator = new nsDirectoryIterator(FILESPEC(parent), PR_FALSE);
if (!mDirectoryIterator)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;

View File

@ -92,6 +92,12 @@ class NS_COM nsFileSpecImpl
/* boolean isHidden (); */
NS_IMETHOD isHidden(PRBool *_retval);
/* boolean isSymlink (); */
NS_IMETHOD isSymlink(PRBool *_retval);
/* void resolveSymlink (); */
NS_IMETHOD resolveSymlink();
/* readonly attribute unsigned long FileSize; */
NS_IMETHOD GetFileSize(PRUint32 *aFileSize);

View File

@ -599,13 +599,16 @@ nsFileSpec::nsFileSpec()
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const FSSpec& inSpec)
nsFileSpec::nsFileSpec(const FSSpec& inSpec, PRBool resolveAlias)
//----------------------------------------------------------------------------------------
: mSpec(inSpec)
, mError(NS_OK)
{
PRBool dummy;
ResolveAlias(dummy);
if (resolveAlias)
{
PRBool dummy;
ResolveSymlink(dummy);
}
}
//----------------------------------------------------------------------------------------
@ -614,8 +617,6 @@ void nsFileSpec::operator = (const FSSpec& inSpec)
{
mSpec = inSpec;
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
}
//----------------------------------------------------------------------------------------
@ -639,8 +640,7 @@ nsFileSpec::nsFileSpec(const char* inNativePathString, PRBool inCreateDirs)
mSpec, inCreateDirs));
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
@ -656,19 +656,22 @@ nsFileSpec::nsFileSpec(const nsString& inNativePathString, PRBool inCreateDirs)
mSpec, inCreateDirs));
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(short vRefNum, long parID, ConstStr255Param name)
nsFileSpec::nsFileSpec(short vRefNum, long parID, ConstStr255Param name, PRBool resolveAlias)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, name, &mSpec));
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
if (resolveAlias)
{
PRBool dummy;
ResolveSymlink(dummy);
}
}
//----------------------------------------------------------------------------------------
@ -691,8 +694,7 @@ void nsFileSpec::operator = (const char* inString)
MacFileHelpers::FSSpecFromPathname(inString, mSpec, true));
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
@ -792,6 +794,8 @@ void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
void nsFileSpec::ResolveAlias(PRBool& wasAliased)
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(0, "Use ResolveSymlink not ResolveAlias!");
Boolean wasAliased2; // Type conversion Boolean <--> PRBool
OSErr err = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2);
if (wasAliased2)
@ -835,6 +839,37 @@ PRBool nsFileSpec::IsHidden() const
return hidden;
} // nsFileSpec::IsHidden
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsSymlink() const
//----------------------------------------------------------------------------------------
{
CInfoPBRec cInfo;
PRBool hidden = PR_FALSE;
if (noErr == GetCatInfo(cInfo))
if (cInfo.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias)
hidden = PR_TRUE;
return hidden;
} // nsFileSpec::IsSymlink
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
//----------------------------------------------------------------------------------------
{
Boolean wasAliased2; // Type conversion Boolean <--> PRBool
OSErr err = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2);
if (wasAliased2)
{
mError = NS_FILE_RESULT(err);
wasAliased = PR_TRUE;
}
else
wasAliased = PR_FALSE;
return mError;
} // nsFileSpec::ResolveSymlink
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
@ -884,8 +919,7 @@ void nsFileSpec::operator += (const char* inRelativePath)
}
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
PRBool dummy;
ResolveAlias(dummy);
} // nsFileSpec::operator +=
//----------------------------------------------------------------------------------------
@ -931,7 +965,7 @@ void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
newDir.CreateDirectory();
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
@ -1276,11 +1310,12 @@ void nsFileURL::operator = (const char* inString)
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int inIterateDirection)
, PRBool resolveSymLinks)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mExists(false)
, mIndex(-1)
, mResoveSymLinks(resolveSymLinks)
{
CInfoPBRec pb;
OSErr err = inDirectory.GetCatInfo(pb);
@ -1294,16 +1329,9 @@ nsDirectoryIterator::nsDirectoryIterator(
mVRefNum = currentSpec.vRefNum;
mParID = dipb->ioDrDirID;
mMaxIndex = pb.dirInfo.ioDrNmFls;
if (inIterateDirection > 0)
{
mIndex = 0; // ready to increment
++(*this); // the pre-increment operator
}
else
{
mIndex = mMaxIndex + 1; // ready to decrement
--(*this); // the pre-decrement operator
}
mIndex = 0; // ready to increment
++(*this); // the pre-increment operator
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
@ -1324,8 +1352,14 @@ OSErr nsDirectoryIterator::SetToIndex()
FSSpec temp;
if (err == noErr)
err = FSMakeFSSpec(mVRefNum, mParID, objectName, &temp);
mCurrent = temp; // use the operator: it clears the string cache and resolves the alias.
mCurrent = temp; // use the operator: it clears the string cache.
mExists = err == noErr;
if (mExists && mResoveSymLinks)
{
PRBool ignore;
mCurrent.ResolveSymlink(ignore);
}
return err;
} // nsDirectoryIterator::SetToIndex()

View File

@ -194,11 +194,35 @@ PRBool nsFileSpec::IsDirectory() const
return (0 == stat( mPath, &st)) && (S_IFDIR == (st.st_mode & S_IFDIR));
}
// Really should factor out DosQPI() call to an internal GetFS3() method and then use
// here, in IsDirectory(), IsFile(), GetModDate(), GetFileSize() [and a future IsReadOnly()]
// and lose the clumsy stat() calls. Exists() too.
PRBool nsFileSpec::IsHidden() const
{
return PR_FALSE; // FIX!
FILESTATUS3 fs3;
APIRET rc;
PRBool bHidden = PR_FALSE; // XXX how do I return an error?
rc = DosQueryPathInfo( mPath, FIL_STANDARD, &fs3, sizeof fs3);
if( !rc)
bHidden = fs3.attrFile & FILE_HIDDEN ? PR_TRUE : PR_FALSE;
return bHidden;
}
// On FAT or HPFS there's no such thing as a symlink; it's possible that JFS
// (new with Warp Server for e-business) does know what they are. Someone
// with a recent toolkit should check it out, but this will be OK for now.
PRBool nsFileSpec::IsSymlink() const
{
return PR_FALSE;
}
nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
{
return NS_OK;
}
void nsFileSpec::GetModDate( TimeStamp& outStamp) const
{
struct stat st;
@ -280,7 +304,7 @@ void nsFileSpec::Delete( PRBool inRecursive) const
{
if( inRecursive)
{
for( nsDirectoryIterator i(*this); i.Exists(); i++)
for( nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec &child = (nsFileSpec &) i;
child.Delete( inRecursive);
@ -404,8 +428,11 @@ nsresult nsFileSpec::Execute( const char *inArgs) const
// nsDirectoryIterator ------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator( const nsFileSpec &aDirectory,
int inIterateDirection)
: mCurrent( aDirectory), mDir( nsnull), mExists(PR_FALSE)
PRBool resolveSymlinks)
: mCurrent( aDirectory),
mDir( nsnull),
mExists(PR_FALSE),
mResoveSymLinks(resolveSymlinks)
{
mDir = PR_OpenDir( aDirectory);
mCurrent += "dummy";
@ -428,6 +455,11 @@ nsDirectoryIterator &nsDirectoryIterator::operator ++ ()
{
mExists = PR_TRUE;
mCurrent.SetLeafName( entry->name);
if (mResoveSymLinks)
{
PRBool ignore;
mCurrent.ResolveSymlink(ignore);
}
}
return *this;
}

View File

@ -200,6 +200,38 @@ PRBool nsFileSpec::IsHidden() const
return hidden;
} // nsFileSpec::IsHidden
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsSymlink() const
//----------------------------------------------------------------------------------------
{
struct stat st;
if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode))
return PR_TRUE;
return PR_FALSE;
} // nsFileSpec::IsSymlink
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
//----------------------------------------------------------------------------------------
{
wasAliased = PR_FALSE;
char resolvedPath[MAXPATHLEN];
int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN);
if (0 < charCount)
{
if (MAXPATHLEN > charCount)
resolvedPath[charCount] = '\0';
wasAliased = PR_TRUE;
mPath = (char*)&resolvedPath;
}
return NS_OK;
} // nsFileSpec::ResolveSymlink
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
@ -246,7 +278,7 @@ void nsFileSpec::Delete(PRBool inRecursive) const
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
@ -269,7 +301,7 @@ void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
newDir.CreateDirectory();
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
@ -445,6 +477,9 @@ nsresult nsFileSpec::Execute(const char* inArgs ) const
PRUint32 nsFileSpec::GetDiskSpaceAvailable() const
//----------------------------------------------------------------------------------------
{
#if defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_STATVFS_H)
char curdir [MAXPATHLEN];
if (mPath.IsEmpty())
{
@ -467,7 +502,17 @@ PRUint32 nsFileSpec::GetDiskSpaceAvailable() const
printf("DiskSpaceAvailable: %d bytes\n",
fs_buf.f_bsize * (fs_buf.f_bavail - 1));
#endif
return fs_buf.f_bsize * (fs_buf.f_bavail - 1);
#else
/*
** This platform doesn't have statfs or statvfs, so we don't have much
** choice but to "hope for the best as we did in cheddar".
*/
return ULONG_MAX;
#endif /* HAVE_SYS_STATFS_H or HAVE_SYS_STATVFS_H */
} // nsFileSpec::GetDiskSpace()
//========================================================================================
@ -475,13 +520,12 @@ PRUint32 nsFileSpec::GetDiskSpaceAvailable() const
//========================================================================================
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int /*inIterateDirection*/)
nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymLinks)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mExists(PR_FALSE)
, mDir(nsnull)
, mResoveSymLinks(resolveSymLinks)
{
mCurrent += "sysygy"; // prepare the path for SetLeafName
mDir = opendir((const char*)nsFilePath(inDirectory));
@ -514,6 +558,11 @@ nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
{
mExists = PR_TRUE;
mCurrent.SetLeafName(entry->d_name);
if (mResoveSymLinks)
{
PRBool ignore;
mCurrent.ResolveSymlink(ignore);
}
}
return *this;
} // nsDirectoryIterator::operator ++

View File

@ -27,6 +27,9 @@
#include "nsError.h"
#include "windows.h"
#include "shlobj.h"
#include "shellapi.h"
#include "shlguid.h"
#ifdef UNICODE
#define CreateDirectoryW CreateDirectory
@ -235,6 +238,113 @@ PRBool nsFileSpec::IsHidden() const
}
// nsFileSpec::IsHidden
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsSymlink() const
//----------------------------------------------------------------------------------------
{
HRESULT hres;
IShellLink* psl;
PRBool isSymlink = PR_FALSE;
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
WORD wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres))
{
isSymlink = PR_TRUE;
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
return isSymlink;
}
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::ResolveSymlink(PRBool& wasSymlink)
//----------------------------------------------------------------------------------------
{
wasSymlink = PR_FALSE; // assume failure
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
WORD wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres))
{
wasSymlink = PR_TRUE;
// Resolve the link.
hres = psl->Resolve(nsnull, SLR_NO_UI );
if (SUCCEEDED(hres))
{
char szGotPath[MAX_PATH];
WIN32_FIND_DATA wfd;
// Get the path to the link target.
hres = psl->GetPath( szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY );
if (SUCCEEDED(hres))
{
// Here we modify the nsFileSpec;
mPath = szGotPath;
mError = NS_OK;
}
}
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
if (SUCCEEDED(hres))
return NS_OK;
return NS_FILE_FAILURE;
}
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
@ -282,7 +392,7 @@ void nsFileSpec::Delete(PRBool inRecursive) const
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
@ -308,7 +418,7 @@ void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
newDir.CreateDirectory();
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
@ -474,13 +584,12 @@ PRUint32 nsFileSpec::GetDiskSpaceAvailable() const
//========================================================================================
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int inIterateDirection)
nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mDir(nsnull)
, mExists(PR_FALSE)
, mResoveSymLinks(resolveSymlink)
{
mDir = PR_OpenDir(inDirectory);
mCurrent += "dummy";
@ -507,6 +616,11 @@ nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
{
mExists = PR_TRUE;
mCurrent.SetLeafName(entry->name);
if (mResoveSymLinks)
{
PRBool ignore;
mCurrent.ResolveSymlink(ignore);
}
}
return *this;
} // nsDirectoryIterator::operator ++

View File

@ -91,6 +91,10 @@ interface nsIFileSpec : nsISupports
void createDir();
void touch();
boolean isSymlink();
void resolveSymlink();
void rename([const] in string newLeafName);
void copyToDir([const] in nsIFileSpec newParentDir);
void moveToDir([const] in nsIFileSpec newParentDir);

View File

@ -165,7 +165,8 @@ static void GetCurrentProcessDirectory(nsFileSpec& aFileSpec)
{
aFileSpec = nsFileSpec(appFSSpec.vRefNum,
catInfo.dirInfo.ioDrParID,
name);
name,
PR_TRUE);
return;
}
}

View File

@ -347,7 +347,7 @@ nsInterfaceInfoManager::initInterfaceTables()
int which = 0;
#endif
for (nsDirectoryIterator i(sysdir); i.Exists(); i++) {
for (nsDirectoryIterator i(sysdir, PR_FALSE); i.Exists(); i++) {
// XXX need to copy?
nsFileSpec spec = i.Spec();

View File

@ -675,14 +675,8 @@ nsGlobalHistory::ReadHistory()
rv = GetHistoryDir(&dir);
if (NS_FAILED(rv)) return rv;
for (nsDirectoryIterator i(dir); i.Exists(); i++) {
for (nsDirectoryIterator i(dir, PR_TRUE); i.Exists(); i++) {
const nsFileSpec spec = i.Spec();
#ifdef XP_MAC
{
PRBool wasAlias;
spec.ResolveAlias(wasAlias);
}
#endif
// convert to a path so we can inspect it: we only want to read
const char* path = (const char*) spec;