add IsChildOf, and dougt's relative-path-handling diff

This commit is contained in:
shaver%netscape.com 1999-09-03 23:44:59 +00:00
parent a24fec8ebe
commit 90e6e9f4e7
5 changed files with 60 additions and 36 deletions

View File

@ -1023,6 +1023,42 @@ const char* nsFileSpec::GetCString() const
}
#endif
/* Is our spec a child of the provided parent? */
PRBool
nsFileSpec::IsChildOf(nsFileSpec &possibleParent)
{
nsFileSpec iter = *this, parent;
#ifdef DEBUG
int depth = 0;
#endif
while (1) {
#ifdef DEBUG
// sanity
NS_ASSERTION(depth < 100, "IsChildOf has lost its little mind");
if (depth > 100)
return PR_FALSE;
#endif
if (iter == possibleParent)
return PR_TRUE;
iter.GetParent(parent); // shouldn't this be an error on parent?
if (iter.Failed())
return PR_FALSE;
if (iter == parent) // hit bottom
return PR_FALSE;
iter = parent;
#ifdef DEBUG
depth++;
#endif
}
/* not reached, but I bet some compiler will whine */
return PR_FALSE;
}
//========================================================================================
// class nsPersistentFileDescriptor
//========================================================================================

View File

@ -332,6 +332,7 @@ class NS_COM nsFileSpec
// so do not delete (or free) it. See also nsNSPRPath below,
// if you really must pass a string to PR_OpenFile().
// Doing so will introduce two automatic bugs.
PRBool IsChildOf(nsFileSpec &possibleParent);
#ifdef XP_MAC
// For Macintosh people, this is meant to be useful in its own right as a C++ version

View File

@ -80,6 +80,15 @@ NS_IMETHODIMP nsFileSpecImpl::FromFileSpec(const nsIFileSpec *original)
return mFileSpec.Error();
}
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsFileSpecImpl::IsChildOf(nsIFileSpec *possibleParent,
PRBool *_retval)
{
*_retval = mFileSpec.IsChildOf(FILESPEC(possibleParent));
return mFileSpec.Error();
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
NS_IMETHODIMP nsFileSpecImpl::GetURLString(char * *aURLString)
//----------------------------------------------------------------------------------------

View File

@ -84,44 +84,21 @@ void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
const mode_t mode = 0700;
nsFileSpecHelpers::MakeAllDirectories((const char*)ioPath, mode);
}
char buffer[MAXPATHLEN];
errno = 0;
#if defined(SOLARIS)
memset(buffer, '\0', sizeof(buffer)); // realpath reads it all, initialized or not.
#else
*buffer = '\0';
#endif
char* canonicalPath = realpath((const char*)ioPath, buffer);
if (!canonicalPath)
errno = 0; // needed?
if (ioPath[0] != '/')
{
// Linux's realpath() is pathetically buggy. If the reason for the nil
// result is just that the leaf does not exist, strip the leaf off,
// process that, and then add the leaf back.
nsSimpleCharString allButLeaf(ioPath);
if (allButLeaf.IsEmpty())
return;
char* lastSeparator = strrchr((char*)allButLeaf, '/');
if (lastSeparator)
{
*lastSeparator = '\0';
canonicalPath = realpath((const char*)allButLeaf, buffer);
strcat(buffer, "/");
// Add back the leaf
strcat(buffer, ++lastSeparator);
}
// the ioPath that was passed in is relative. We must cat it to the cwd.
char buffer[MAXPATHLEN];
(void) getcwd(buffer, MAXPATHLEN);
strcat(buffer, "/");
strcat(buffer, ioPath);
ioPath = buffer;
}
if (!canonicalPath && ioPath[0] != '/' && !inMakeDirs)
{
// Well, if it's a relative path, hack it ourselves.
canonicalPath = realpath(".", buffer);
if (canonicalPath)
{
strcat(canonicalPath, "/");
strcat(canonicalPath, ioPath);
}
}
if (canonicalPath)
ioPath = canonicalPath;
} // nsFileSpecHelpers::Canonify
//----------------------------------------------------------------------------------------

View File

@ -68,6 +68,7 @@ interface nsIFileSpec : nsISupports
readonly attribute nsIFileSpec parent;
readonly attribute nsIInputStream inputStream;
readonly attribute nsIOutputStream outputStream;
boolean isChildOf(in nsIFileSpec possibleParent);
[noscript] readonly attribute nsFileSpec fileSpec;
[noscript] void setFromFileSpec([const] in nsFileSpecRef spec);