Mozilla/mozilla/xpcom/io/nsLocalFileMac.cpp
dougt%netscape.com 5e6a51e582 1. First cut of a Special System Directory replacement (nsDirectoryService).
It is a nsIProperty.

2. Updates to the nsIFile and nsILocalFile interfaces based on conversations
   with warren. (thanks)

3. Updated windows mac and unix implementations based on interface changes.
   Mac and windows changes need to be reviewed.


                          Not part of build.


git-svn-id: svn://10.0.0.236/trunk@56336 18797224-902f-48f8-a5cc-f745e15eee43
1999-12-22 01:56:45 +00:00

1081 lines
24 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Steve Dagley <sdagley@netscape.com>
* John R. McMullen
*/
#include "nsCOMPtr.h"
#include "nsIAllocator.h"
#include "nsLocalFileMac.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
#include "prtypes.h"
#include "prio.h"
#include "FullPath.h"
#include "FileCopy.h"
#include "MoreFilesExtras.h"
#include <Errors.h>
#include <Script.h>
#include <Processes.h>
// Simple func to map Mac OS errors into nsresults
static nsresult MacErrorMapper(OSErr inErr)
{
nsresult outErr;
switch (inErr)
{
case fnfErr:
outErr = NS_ERROR_FILE_NOT_FOUND;
break;
case dupFNErr:
outErr = NS_ERROR_FILE_ALREADY_EXISTS;
break;
// Can't find good map for some
case bdNamErr:
outErr = NS_ERROR_FAILURE;
break;
case noErr:
outErr = NS_OK;
default:
outErr = NS_ERROR_FAILURE;
}
return outErr;
}
static void myPLstrcpy(Str255 dst, const char* src)
{
int srcLength = strlen(src);
NS_ASSERTION(srcLength <= 255, "Oops, Str255 can't hold >255 chars");
if (srcLength > 255)
srcLength = 255;
dst[0] = srcLength;
memcpy(&dst[1], src, srcLength);
}
static void myPLstrncpy(Str255 dst, const char* src, int inMax)
{
int srcLength = strlen(src);
if (srcLength > inMax)
srcLength = inMax;
dst[0] = srcLength;
memcpy(&dst[1], src, srcLength);
}
class nsDirEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
nsDirEnumerator() : mDir(nsnull)
{
NS_INIT_REFCNT();
}
nsresult Init(nsILocalFile* parent)
{
char* filepath;
parent->GetTarget(&filepath);
if (filepath == nsnull)
{
parent->GetPath(&filepath);
}
if (filepath == nsnull)
{
return NS_ERROR_OUT_OF_MEMORY;
}
mDir = PR_OpenDir(filepath);
if (mDir == nsnull) // not a directory?
return NS_ERROR_FAILURE;
mParent = parent;
return NS_OK;
}
NS_IMETHOD HasMoreElements(PRBool *result)
{
nsresult rv;
if (mNext == nsnull && mDir)
{
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH);
if (entry == nsnull)
{
// end of dir entries
PRStatus status = PR_CloseDir(mDir);
if (status != PR_SUCCESS)
return NS_ERROR_FAILURE;
mDir = nsnull;
*result = PR_FALSE;
return NS_OK;
}
nsCOMPtr<nsIFile> file;
mParent->Clone(getter_AddRefs(file));
rv = file->AppendPath(entry->name);
if (NS_FAILED(rv))
return rv;
mNext = do_QueryInterface(file);
}
*result = mNext != nsnull;
return NS_OK;
}
NS_IMETHOD GetNext(nsISupports **result)
{
nsresult rv;
PRBool hasMore;
rv = HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
*result = mNext; // might return nsnull
NS_IF_ADDREF(*result);
mNext = null_nsCOMPtr();
return NS_OK;
}
virtual ~nsDirEnumerator()
{
if (mDir)
{
PRStatus status = PR_CloseDir(mDir);
NS_ASSERTION(status == PR_SUCCESS, "close failed");
}
}
protected:
PRDir* mDir;
nsCOMPtr<nsILocalFile> mParent;
nsCOMPtr<nsILocalFile> mNext;
};
NS_IMPL_ISUPPORTS(nsDirEnumerator, NS_GET_IID(nsISimpleEnumerator));
nsLocalFile::nsLocalFile()
{
NS_INIT_REFCNT();
MakeDirty();
}
nsLocalFile::~nsLocalFile()
{
}
/* nsISupports interface implementation. */
NS_IMPL_ISUPPORTS2(nsLocalFile, nsILocalFile, nsIFile)
NS_METHOD
nsLocalFile::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
NS_ENSURE_PROPER_AGGREGATION(outer, aIID);
nsLocalFile* inst = new nsLocalFile();
if (inst == NULL)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = inst->QueryInterface(aIID, aInstancePtr);
if (NS_FAILED(rv))
{
delete inst;
return rv;
}
return NS_OK;
}
// This function resets any cached information about the file.
void
nsLocalFile::MakeDirty()
{
mStatDirty = PR_TRUE;
}
NS_IMETHODIMP
nsLocalFile::Clone(nsIFile **file)
{
NS_ENSURE_ARG(file);
*file = nsnull;
nsCOMPtr<nsILocalFile> localFile;
nsresult rv = nsComponentManager::CreateInstance(NS_LOCAL_FILE_PROGID,
nsnull,
nsCOMTypeInfo<nsILocalFile>::GetIID(),
getter_AddRefs(localFile));
if (NS_FAILED(rv))
return rv;
char* aFilePath;
GetPath(&aFilePath);
rv = localFile->InitWithPath(aFilePath);
nsAllocator::Free(aFilePath);
if (NS_FAILED(rv))
return rv;
*file = localFile;
NS_ADDREF(*file);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::InitWithPath(const char *filePath)
{
MakeDirty();
NS_ENSURE_ARG(filePath);
// Make sure there's a colon in the path and it is not the first character
// so we know we got a full path, not a partial one
if (strchr(filePath, ':') == 0 || *filePath == ':')
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// Just save the specified file path since we can't actually do anything
// about turniung it into an FSSpec until the Create() method is called
mWorkingPath.SetString(filePath);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::Open(PRInt32 flags, PRInt32 mode, PRFileDesc **_retval)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsLocalFile::Create(PRUint32 type, PRUint32 attributes)
{
if (type != NORMAL_FILE_TYPE && type != DIRECTORY_TYPE)
return NS_ERROR_FILE_UNKNOWN_TYPE;
OSErr err = noErr;
char* filePath = (char*) nsAllocator::Clone( mWorkingPath, strlen(mWorkingPath)+1 );
size_t inLength = strlen(filePath);
if (inLength < 255)
{
Str255 pascalpath;
myPLstrcpy(pascalpath, filePath);
err = ::FSMakeFSSpec(0, 0, pascalpath, &mSpec);
}
else
err = FSpLocationFromFullPath(inLength, filePath, &mSpec);
if ((err == dirNFErr || err == bdNamErr))
{
const char* path = filePath;
mSpec.vRefNum = 0;
mSpec.parID = 0;
do
{
// Locate the colon that terminates the node.
// But if we've a partial path (starting with a colon), find the second one.
const char* nextColon = strchr(path + (*path == ':'), ':');
// Well, if there are no more colons, point to the end of the string.
if (!nextColon)
nextColon = path + strlen(path);
// Make a pascal string out of this node. Include initial
// and final colon, if any!
Str255 ppath;
myPLstrncpy(ppath, path, nextColon - path + 1);
// Use this string as a relative path using the directory created
// on the previous round (or directory 0,0 on the first round).
err = ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, ppath, &mSpec);
// If this was the leaf node, then we are done.
if (!*nextColon)
break;
// Since there's more to go, we have to get the directory ID, which becomes
// the parID for the next round.
if (err == noErr)
{
// The directory (or perhaps a file) exists. Find its dirID.
long dirID;
Boolean isDirectory;
err = ::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory);
if (!isDirectory)
err = dupFNErr; // oops! a file exists with that name.
if (err != noErr)
break; // bail if we've got an error
mSpec.parID = dirID;
}
else if (err == fnfErr)
{
// If we got "file not found", then we need to create a directory.
err = ::FSpDirCreate(&mSpec, smCurrentScript, &mSpec.parID);
// For some reason, this usually returns fnfErr, even though it works.
if (err == fnfErr)
err = noErr;
}
if (err != noErr)
break;
path = nextColon; // next round
} while (true);
}
if (err != noErr)
return (MacErrorMapper(err));
switch (type)
{
case NORMAL_FILE_TYPE:
// We really should use some sort of meaningful file type/creator but where
// do we get the info from?
err = ::FSpCreate(&mSpec, '????', '????', smCurrentScript);
return (MacErrorMapper(err));
break;
case DIRECTORY_TYPE:
err = ::FSpDirCreate(&mSpec, smCurrentScript, &mSpec.parID);
// For some reason, this usually returns fnfErr, even though it works.
if (err == fnfErr)
err = noErr;
return (MacErrorMapper(err));
break;
default:
// For now just fall out of the switch into the default return NS_ERROR_FILE_UNKNOWN_TYPE
break;
}
return NS_ERROR_FILE_UNKNOWN_TYPE;
}
NS_IMETHODIMP
nsLocalFile::AppendPath(const char *node)
{
if ( (node == nsnull) || (*node == '/') || strchr(node, '\\') )
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
MakeDirty();
// We only can append relative unix styles strings.
// Convert '\' to '/'
nsString path(node);
char* nodeCString = path.ToNewCString();
char* temp = nodeCString;
for (; *temp; temp++)
{
if (*temp == '/')
*temp = '\\';
}
// kill any trailing seperator
if(nodeCString)
{
temp = nodeCString;
int len = strlen(temp) - 1;
if(temp[len] == '\\')
temp[len] = '\0';
}
mWorkingPath.Append("\\");
mWorkingPath.Append(nodeCString);
Recycle(nodeCString);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::Normalize()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::GetLeafName(char * *aLeafName)
{
NS_ENSURE_ARG_POINTER(aLeafName);
const char* temp = mWorkingPath.GetBuffer();
if(temp == nsnull)
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
const char* leaf = strrchr(temp, '\\');
// if the working path is just a node without any lashes.
if (leaf == nsnull)
leaf = temp;
else
leaf++;
*aLeafName = (char*) nsAllocator::Clone(leaf, strlen(leaf)+1);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetPath(char **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = (char*) nsAllocator::Clone(mWorkingPath, strlen(mWorkingPath)+1);
return NS_OK;
}
nsresult
nsLocalFile::CopySingleFile(nsIFile *sourceFile, nsIFile *destParent, const char * newName, PRBool followSymlinks, PRBool move)
{
nsresult rv;
char* filePath;
// get the path that we are going to copy to.
// Since windows does not know how to auto
// resolve shortcust, we must work with the
// target.
char* inFilePath;
destParent->GetTarget(&inFilePath);
nsCString destPath = inFilePath;
nsAllocator::Free(inFilePath);
destPath.Append("\\");
if (newName == nsnull)
{
char *aFileName;
sourceFile->GetLeafName(&aFileName);
destPath.Append(aFileName);
nsAllocator::Free(aFileName);
}
else
{
destPath.Append(newName);
}
if (followSymlinks)
{
rv = sourceFile->GetTarget(&filePath);
}
else
{
rv = sourceFile->GetPath(&filePath);
}
if (NS_FAILED(rv))
return rv;
//int copyOK;
if (!move)
{
//copyOK = CopyFile(filePath, destPath, PR_TRUE);
}
else
{
//copyOK = MoveFile(filePath, destPath);
}
//if (!copyOK) // CopyFile and MoveFile returns non-zero if succeeds (backward if you ask me).
nsAllocator::Free(filePath);
return rv;
}
nsresult
nsLocalFile::CopyMove(nsIFile *newParentDir, const char *newName, PRBool followSymlinks, PRBool move)
{
NS_ENSURE_ARG(newParentDir);
nsresult rv = NS_OK;
// check to see if this exists, otherwise return an error.
PRBool sourceExists;
Exists(&sourceExists);
if (sourceExists == PR_FALSE)
{
return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST;
}
// make sure destination exists and is a directory. Create it if not there.
PRBool parentExists;
newParentDir->Exists(&parentExists);
if (parentExists == PR_FALSE)
{
rv = newParentDir->Create(DIRECTORY_TYPE, 0);
if (NS_FAILED(rv))
return rv;
}
else
{
PRBool isDir;
newParentDir->IsDirectory(&isDir);
if (isDir == PR_FALSE)
{
if (followSymlinks)
{
PRBool isLink;
newParentDir->IsSymlink(&isLink);
if (isLink)
{
char* target;
newParentDir->GetTarget(&target);
nsCOMPtr<nsILocalFile> realDest;
rv = nsComponentManager::CreateInstance(NS_LOCAL_FILE_PROGID,
nsnull,
nsCOMTypeInfo<nsILocalFile>::GetIID(),
getter_AddRefs(realDest));
if (NS_FAILED(rv))
return rv;
rv = realDest->InitWithPath(target);
nsAllocator::Free(target);
if (NS_FAILED(rv))
return rv;
return CopyMove(realDest, newName, followSymlinks, move);
}
}
else
{
return NS_ERROR_FILE_DESTINATION_NOT_DIR;
}
}
}
// check to see if we are a directory, if so enumerate it.
PRBool isDir;
IsDirectory(&isDir);
if (!isDir)
{
rv = CopySingleFile(this, newParentDir, newName, followSymlinks, move);
if (NS_FAILED(rv))
return rv;
}
else
{
// create a new target destination in the new parentDir;
nsCOMPtr<nsILocalFile> target;
newParentDir->Clone(getter_AddRefs(target));
char *allocatedNewName;
if (!newName)
{
GetLeafName(&allocatedNewName);// this should be the leaf name of the
}
else
{
allocatedNewName = (char*) nsAllocator::Clone( newName, strlen(newName)+1 );
}
rv = target->AppendPath(allocatedNewName);
if (NS_FAILED(rv))
return rv;
nsAllocator::Free(allocatedNewName);
target->Create(DIRECTORY_TYPE, 0);
if (NS_FAILED(rv))
return rv;
nsDirEnumerator* dirEnum = new nsDirEnumerator();
if (!dirEnum)
return NS_ERROR_OUT_OF_MEMORY;
rv = dirEnum->Init(this);
nsCOMPtr<nsISimpleEnumerator> iterator = do_QueryInterface(dirEnum);
PRBool more;
iterator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> item;
nsCOMPtr<nsIFile> file;
iterator->GetNext(getter_AddRefs(item));
file = do_QueryInterface(item);
PRBool isDir, isLink;
file->IsDirectory(&isDir);
file->IsSymlink(&isLink);
if (move)
{
rv = file->MoveTo(target, nsnull);
}
else
{
if (followSymlinks)
rv = file->CopyToFollowingLinks(target, nsnull);
else
rv = file->CopyTo(target, nsnull);
}
iterator->HasMoreElements(&more);
}
}
// If we moved, we want to adjust this.
if (move)
{
if (newName == nsnull)
{
char *aFileName;
GetLeafName(&aFileName);
InitWithFile(newParentDir);
AppendPath(aFileName);
nsAllocator::Free(aFileName);
}
else
{
InitWithFile(newParentDir);
AppendPath(newName);
}
MakeDirty();
}
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::CopyTo(nsIFile *newParentDir, const char *newName)
{
return CopyMove(newParentDir, newName, PR_FALSE, PR_FALSE);
}
NS_IMETHODIMP
nsLocalFile::CopyToFollowingLinks(nsIFile *newParentDir, const char *newName)
{
return CopyMove(newParentDir, newName, PR_TRUE, PR_FALSE);
}
NS_IMETHODIMP
nsLocalFile::MoveTo(nsIFile *newParentDir, const char *newName)
{
return CopyMove(newParentDir, newName, PR_FALSE, PR_TRUE);
}
NS_IMETHODIMP
nsLocalFile::Spawn(const char *args)
{
PRBool isFile;
nsresult rv = IsFile(&isFile);
if (NS_FAILED(rv))
return rv;
return NS_ERROR_FILE_EXECUTION_FAILED;
}
NS_IMETHODIMP
nsLocalFile::Delete(PRBool recursive)
{
MakeDirty();
PRBool isDir;
nsresult rv = IsDirectory(&isDir);
if (NS_FAILED(rv))
return rv;
const char *filePath = mResolvedPath.GetBuffer();
if (isDir)
{
if (recursive)
{
nsDirEnumerator* dirEnum = new nsDirEnumerator();
if (dirEnum)
return NS_ERROR_OUT_OF_MEMORY;
rv = dirEnum->Init(this);
nsCOMPtr<nsISimpleEnumerator> iterator = do_QueryInterface(dirEnum);
PRBool more;
iterator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> item;
nsCOMPtr<nsIFile> file;
iterator->GetNext(getter_AddRefs(item));
file = do_QueryInterface(item);
file->Delete(recursive);
iterator->HasMoreElements(&more);
}
}
//rmdir(filePath); // todo: save return value?
}
else
{
//remove(filePath); // todo: save return value?
}
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetLastModificationDate(PRInt64 *aLastModificationDate)
{
NS_ENSURE_ARG(aLastModificationDate);
aLastModificationDate->hi = 0;
aLastModificationDate->lo = 0;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::SetLastModificationDate(PRInt64 aLastModificationDate)
{
MakeDirty();
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetLastModificationDateOfLink(PRInt64 *aLastModificationDate)
{
NS_ENSURE_ARG(aLastModificationDate);
aLastModificationDate->hi = 0;
aLastModificationDate->lo = 0;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::SetLastModificationDateOfLink(PRInt64 aLastModificationDate)
{
MakeDirty();
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetPermissions(PRUint32 *aPermissions)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::GetPermissionsOfLink(PRUint32 *aPermissionsOfLink)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::SetPermissions(PRUint32 aPermissions)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::SetPermissionsOfLink(PRUint32 aPermissions)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::GetFileSize(PRInt64 *aFileSize)
{
NS_ENSURE_ARG(aFileSize);
aFileSize->hi = 0;
aFileSize->lo = 0;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::SetFileSize(PRInt64 aFileSize)
{
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetFileSizeOfLink(PRInt64 *aFileSize)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
{
NS_ENSURE_ARG(aDiskSpaceAvailable);
PRInt64 space64Bits;
LL_I2L(space64Bits , LONG_MAX);
XVolumeParam pb;
pb.ioCompletion = nsnull;
pb.ioVolIndex = 0;
pb.ioNamePtr = nsnull;
pb.ioVRefNum = mSpec.vRefNum;
OSErr err = ::PBXGetVolInfoSync(&pb);
if (err == noErr)
{
space64Bits.lo = pb.ioVFreeBytes.lo;
space64Bits.hi = pb.ioVFreeBytes.hi;
}
*aDiskSpaceAvailable = space64Bits;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetParent(nsIFile * *aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
nsCString parentPath = mWorkingPath;
PRInt32 offset = parentPath.RFindChar('\\');
if (offset == -1)
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
parentPath.Truncate(offset);
const char* filePath = parentPath.GetBuffer();
nsLocalFile* file = new nsLocalFile();
if (file == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
file->AddRef();
file->InitWithPath(filePath);
*aParent = file;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::Exists(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsWritable(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsReadable(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
*_retval = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsExecutable(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsDirectory(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsFile(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsHidden(PRBool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::IsSymlink(PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsSpecial(PRBool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::Equals(nsIFile *inFile, PRBool *_retval)
{
NS_ENSURE_ARG(inFile);
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
char* inFilePath;
inFile->GetPath(&inFilePath);
char* filePath;
GetPath(&filePath);
if (strcmp(inFilePath, filePath) == 0)
*_retval = PR_TRUE;
nsAllocator::Free(inFilePath);
nsAllocator::Free(filePath);
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::IsContainedIn(nsIFile *inFile, PRBool recur, PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = PR_FALSE;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsLocalFile::GetTarget(char **_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = nsnull;
PRBool symLink;
nsresult rv = IsSymlink(&symLink);
if (NS_FAILED(rv))
return rv;
if (!symLink)
{
return NS_ERROR_FILE_INVALID_PATH;
}
*_retval = (char*) nsAllocator::Clone( mResolvedPath, strlen(mResolvedPath)+1 );
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetDirectoryEntries(nsISimpleEnumerator * *entries)
{
nsresult rv;
*entries = nsnull;
PRBool isDir;
rv = IsDirectory(&isDir);
if (NS_FAILED(rv))
return rv;
if (!isDir)
return NS_ERROR_FILE_NOT_DIRECTORY;
nsDirEnumerator* dirEnum = new nsDirEnumerator();
if (dirEnum == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(dirEnum);
rv = dirEnum->Init(this);
if (NS_FAILED(rv))
{
NS_RELEASE(dirEnum);
return rv;
}
*entries = dirEnum;
return NS_OK;
}