JError
JFormatPartition
	(
	const JCharacter*	path,
	const JCharacter*	type,
	JProcess**			process
	)
{
	JBoolean writable, isTop;
	JString device;
	if (JIsMounted(path, &writable, &isTop, &device) && isTop)
		{
		JMount(path, kJFalse, kJTrue);
		if (!JIsMounted(path))
			{
			const JCharacter* argv[] = { "xterm", "-T", "Format disk", "-n", "Format disk",
										 "-e", "/sbin/mkfs", "-t", type, "-c", device, NULL };
			const JError err = JProcess::Create(process, argv, sizeof(argv));
			if (err.OK())
				{
				JThisProcess::Ignore(*process);
				}
			return err;
			}
		}

	*process = NULL;
	return JAccessDenied(path);
}
Пример #2
0
JError
JXImage::WriteXPM
	(
	const JCharacter* fileName
	)
	const
{
#ifdef _J_HAS_XPM

	XpmAttributes attr;
	attr.valuemask = XpmColormap;
	attr.colormap  = itsXColormap->GetXColormap();

	int xpmErr;
	if (itsImage != NULL)
		{
		XImage* mask_image = NULL;
		if (itsMask != NULL)
			{
			itsMask->ConvertToImage();
			mask_image = ((JXImage*) itsMask)->itsImage;
			}

		xpmErr = XpmWriteFileFromImage(*itsDisplay, const_cast<JCharacter*>(fileName),
									   itsImage, mask_image, &attr);
		}
	else
		{
		assert( itsPixmap != None );

		Pixmap mask_pixmap = None;
		if (itsMask != NULL)
			{
			itsMask->ConvertToPixmap();
			mask_pixmap = ((JXImage*) itsMask)->itsPixmap;
			}

		xpmErr = XpmWriteFileFromPixmap(*itsDisplay, const_cast<JCharacter*>(fileName),
										itsPixmap, mask_pixmap, &attr);
		}

	if (xpmErr == XpmOpenFailed)
		{
		return JAccessDenied(fileName);
		}
	else if (xpmErr == XpmNoMemory)
		{
		return JNoProcessMemory();
		}
	else
		{
		return JNoError();
		}

#else

	return XPMNotAvailable();

#endif
}
Пример #3
0
JError
JMkDir
	(
	const JCharacter*	dirName,
	const mode_t		mode
	)
{
	jclear_errno();
	if (mkdir(dirName, mode) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EEXIST)
		{
		return JDirEntryAlreadyExists(dirName);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == EACCES)
		{
		return JAccessDenied(dirName);
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(dirName);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(dirName);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(dirName);
		}
	else if (err == ENOSPC)
		{
		return JFileSystemFull();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #4
0
JError
JGetSymbolicLinkTarget
	(
	const char*	linkFullName,
	JString*	targetFullName
	)
{
	const JSize kBufferSize = 10000;
	char buf[ kBufferSize ];
	const long linkNameSize = readlink(linkFullName, buf, kBufferSize-1);
	if (linkNameSize != -1)
		{
		targetFullName->Set(buf, linkNameSize);
		return JNoError();
		}

	targetFullName->Clear();
	const int err = jerrno();
	if (err == ENOTDIR)
		{
		return JComponentNotDirectory(linkFullName);
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JDirEntryDoesNotExist(linkFullName);
		}
	else if (err == EPERM || err == EACCES)
		{
		return JAccessDenied(linkFullName);
		}
	else if (err == ELOOP)
		{
		return JTooManyLinks(linkFullName);
		}
	else if (err == EINVAL)
		{
		return JNotSymbolicLink(linkFullName);
		}
	else if (err == EIO)
		{
		return JGeneralIO();
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #5
0
JError
JRemoveDirectory
	(
	const JCharacter* dirName
	)
{
	jclear_errno();
	if (rmdir(dirName) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EPERM || err == EACCES)
		{
		return JAccessDenied(dirName);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(dirName);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(dirName);
		}
	else if (err == ENOTEMPTY)
		{
		return JDirectoryNotEmpty(dirName);
		}
	else if (err == EBUSY)
		{
		return JDirectoryBusy(dirName);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(dirName);
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #6
0
JError
JCreateTempFile
	(
	const JCharacter*	path,
	const JCharacter*	prefix,
	JString*			fullName
	)
{
	JString p;
	if (!JStringEmpty(path))
		{
		p = path;
		}
	else if (!JGetTempDirectory(&p))
		{
		return JDirEntryDoesNotExist("/tmp");
		}

	if (!JStringEmpty(prefix))
		{
		p = JCombinePathAndName(p, prefix);
		}
	else
		{
		p = JCombinePathAndName(p, "temp_file_");
		}

	p      += "XXXXXX";
	char* s = p.AllocateCString();

	jclear_errno();
	int fd = mkstemp(s);
	if (fd != -1)
		{
		close(fd);
		*fullName = s;
		delete [] s;
		return JNoError();
		}

	fullName->Clear();
	delete [] s;

	// EINVAL counts as unexpected

	const int err = jerrno();
	if (err == EEXIST)
		{
		return JAccessDenied(p);
		}
	else
		{
		return JUnexpectedError(err);
		}
}
JError
JDirInfo::BuildInfo()
{
	if (!JDirectoryReadable(*itsCWD))
		{
		return JAccessDenied(*itsCWD);
		}

	const JString origDir = JGetCurrentDirectory();

	JError err = JChangeDirectory(*itsCWD);
	if (!err.OK())
		{
		return err;
		}

	// clear old information

	itsDirEntries->CleanOut();

	// update instance variables

	JStripTrailingDirSeparator(itsCWD);		// keep Windows happy

	ACE_stat stbuf;
	ACE_OS::stat(*itsCWD, &stbuf);
	itsIsValidFlag    = kJTrue;
	itsIsWritableFlag = JDirectoryWritable(*itsCWD);
	itsModTime        = stbuf.st_mtime;
	itsStatusTime     = stbuf.st_ctime;

	JAppendDirSeparator(itsCWD);

	// process files in the directory

	JLatentPG pg(itsContentRegex == NULL ? 100 : 10);
	if (itsPG != NULL)
		{
		pg.SetPG(itsPG, kJFalse);
		}
	pg.VariableLengthProcessBeginning("Scanning directory...", kJTrue, kJFalse);

	BuildInfo1(pg);

	pg.ProcessFinished();

	err = JChangeDirectory(origDir);
	assert_ok( err );

	ApplyFilters(kJFalse);
	return JNoError();
}
Пример #8
0
JError
JSetPermissions
	(
	const JCharacter*	name,
	const mode_t		perms
	)
{
	jclear_errno();
	if (chmod(name, perms) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EPERM || err == EACCES)
		{
		return JAccessDenied(name);
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JDirEntryDoesNotExist(name);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(name);
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(name);
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #9
0
JError
JRemoveFile
	(
	const JCharacter* fileName
	)
{
	jclear_errno();
	if (remove(fileName) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == EACCES || err == EPERM)
		{
		return JAccessDenied(fileName);
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(fileName);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(fileName);
		}
	else if (err == EISDIR)
		{
		return JTriedToRemoveDirectory();
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #10
0
JError
JChangeDirectory
	(
	const JCharacter* dirName
	)
{
	jclear_errno();
	if (chdir(dirName) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EPERM || err == EACCES)
		{
		return JAccessDenied(dirName);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(dirName);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(dirName);
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(dirName);
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #11
0
JError
JRenameDirEntry
	(
	const JCharacter* oldName,
	const JCharacter* newName
	)
{
	if (JNameUsed(newName))
		{
		return JDirEntryAlreadyExists(newName);
		}
	else if (JSameDirEntry(oldName, newName))
		{
		return JNoError();
		}

	jclear_errno();
	if (rename(oldName, newName) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EISDIR)
		{
		return JCantRenameFileToDirectory(oldName, newName);
		}
	else if (err == EXDEV)
		{
		return JCantRenameAcrossFilesystems();
		}
	else if (err == ENOTEMPTY)
		{
		return JCantRenameToNonemptyDirectory();
		}
	else if (err == EEXIST)
		{
		return JDirEntryAlreadyExists(newName);
		}
	else if (err == EBUSY)
		{
		return JFileBusy(newName);
		}
	else if (err == EINVAL)
		{
		return JDirectoryCantBeOwnChild();
		}
	else if (err == EMLINK)
		{
		return JTooManyLinks(oldName);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(oldName, newName);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == EACCES || err == EPERM)
		{
		return JAccessDenied(oldName, newName);
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(oldName, newName);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(oldName, newName);
		}
	else if (err == ENOSPC)
		{
		return JFileSystemFull();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #12
0
JError
JCreateSymbolicLink
	(
	const JCharacter* src,
	const JCharacter* dest
	)
{
	jclear_errno();
	if (symlink(src, dest) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EPERM || err == EACCES)
		{
		return JAccessDenied(dest);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(dest);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(dest);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == EEXIST)
		{
		return JDirEntryAlreadyExists(dest);
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(dest);
		}
	else if (err == ENOSPC)
		{
		return JFileSystemFull();
		}
	else if (err == EIO)
		{
		return JGeneralIO();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #13
0
JError
JXImage::CreateFromXPM
	(
	JXDisplay*			display,
	const JCharacter*	fileName,
	JXImage**			image
	)
{
#ifdef _J_HAS_XPM

	JXColormap* colormap = display->GetColormap();

	Pixmap image_pixmap = None;
	Pixmap mask_pixmap  = None;

	XpmAttributes attr;
	attr.valuemask          = XpmVisual | XpmColormap | XpmDepth |
							  XpmExactColors | XpmCloseness |
							  XpmColorKey | XpmAllocCloseColors |
							  XpmReturnAllocPixels;
	attr.visual             = colormap->GetVisual();
	attr.colormap           = colormap->GetXColormap();
	attr.depth              = display->GetDepth();
	attr.color_key          = XPM_COLOR;
	attr.alloc_pixels       = NULL;
	attr.nalloc_pixels      = 0;
	attr.alloc_close_colors = kJTrue;	// so we can free all resulting pixels
	attr.exactColors        = 1;
	attr.closeness          = 0;

	const int xpmErr =
		XpmReadFileToPixmap(*display, display->GetRootWindow(),
							const_cast<JCharacter*>(fileName),
							&image_pixmap, &mask_pixmap, &attr);
	if (xpmErr == XpmOpenFailed && JFileExists(fileName))
		{
		return JAccessDenied(fileName);
		}
	else if (xpmErr == XpmOpenFailed)
		{
		return JDirEntryDoesNotExist(fileName);
		}
	else if (xpmErr == XpmFileInvalid)
		{
		return FileIsNotXPM(fileName);
		}
	else if (xpmErr == XpmNoMemory)
		{
		return JNoProcessMemory();
		}
	else if (xpmErr == XpmColorFailed || xpmErr == XpmColorError)
		{
		if (image_pixmap != None)
			{
			XFreePixmap(*display, image_pixmap);
			}
		if (mask_pixmap != None)
			{
			XFreePixmap(*display, mask_pixmap);
			}
		if (attr.alloc_pixels != NULL)
			{
			XFreeColors(*display, attr.colormap, attr.alloc_pixels, attr.nalloc_pixels, 0);
			}
		XpmFreeAttributes(&attr);
		return TooManyColors();
		}

	// create image and mask

	*image = new JXImage(display, image_pixmap);
	assert( *image != NULL );

	XFreePixmap(*display, image_pixmap);

	if (mask_pixmap != None)
		{
		JXImageMask* mask = new JXImageMask(display, mask_pixmap);
		assert( mask != NULL );
		(**image).SetMask(mask);

		XFreePixmap(*display, mask_pixmap);
		}

	// free pixels so X has usage count of 1

	XFreeColors(*display, attr.colormap, attr.alloc_pixels, attr.nalloc_pixels, 0);

	// clean up

	XpmFreeAttributes(&attr);
	return JNoError();

#else

	return XPMNotAvailable();

#endif
}
Пример #14
0
JError
JFOpen
	(
	const JCharacter*	fileName,
	const JCharacter*	mode,
	FILE**				stream
	)
{
	jclear_errno();
	*stream = fopen(fileName, mode);
	if (*stream != NULL)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EINVAL)
		{
		return JInvalidOpenMode(fileName);
		}
	else if (err == EEXIST)
		{
		return JDirEntryAlreadyExists(fileName);
		}
	else if (err == EISDIR)
		{
		return JIsADirectory();
		}
	else if (err == EACCES || err == ETXTBSY)
		{
		return JAccessDenied(fileName);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(fileName);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(fileName);
		}
	else if (err == EMFILE || err == ENFILE)
		{
		return JTooManyDescriptorsOpen();
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(fileName);
		}
	else if (err == ENOSPC)
		{
		return JFileSystemFull();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Пример #15
0
JError
JRemoveVCS
	(
	const JCharacter*	fullName,
	const JBoolean		sync,
	JProcess**			returnP
	)
{
	if (returnP != NULL)
		{
		*returnP = NULL;
		}

	if (!JNameUsed(fullName))
		{
		return JDirEntryDoesNotExist(fullName);
		}

	JString path, name;
	JSplitPathAndName(fullName, &path, &name);

	const JString origPath = JGetCurrentDirectory();
	if (JChangeDirectory(path) != kJNoError)
		{
		return JAccessDenied(path);
		}

	JVCSType type     = JGetVCSType(path);
	JError err        = JNoError();
	JBoolean tryPlain = kJFalse;
	JString cmd;
	JProcess* p = NULL;
	if (type == kJSVNType || type == kJGitType)
		{
		const JCharacter *binary = NULL;
		if (type == kJSVNType)
			{
			binary = "svn rm --force ";
			}
		else if (type == kJGitType)
			{
			binary = "git rm -rf ";
			}

		cmd  = binary;
		cmd += JPrepArgForExec(name);
		err  = JProcess::Create(&p, cmd);
		if (err.OK())
			{
			p->WaitUntilFinished();
			}

		if (p != NULL && !p->SuccessfulFinish())
			{
			err      = JAccessDenied(fullName);
			tryPlain = kJTrue;
			}
		}
	else if (type == kJUnknownVCSType)
		{
		tryPlain = kJTrue;
		}
	else
		{
		err = JUnsupportedVCS(fullName);
		}

	if (tryPlain && JKillDirectory(fullName, sync, returnP))
		{
		err = JNoError();
		}
	else if (tryPlain)
		{
		err = JAccessDenied(fullName);
		}

	delete p;
	JChangeDirectory(origPath);
	return err;
}
Пример #16
0
JError
JRenameVCS
	(
	const JCharacter* oldFullName,
	const JCharacter* newFullName
	)
{
	if (!JNameUsed(oldFullName))
		{
		return JDirEntryDoesNotExist(oldFullName);
		}

	JString oldPath, newPath, name;
	JSplitPathAndName(newFullName, &newPath, &name);
	JSplitPathAndName(oldFullName, &oldPath, &name);	// must be second

	const JString origPath = JGetCurrentDirectory();
	if (JChangeDirectory(oldPath) != kJNoError)
		{
		return JAccessDenied(oldPath);
		}

	JVCSType type1    = JGetVCSType(oldPath);
	JVCSType type2    = JGetVCSType(newPath);
	JError err        = JNoError();
	JBoolean tryPlain = kJFalse;
	JString cmd;
	JProcess* p = NULL;
	if (type1 != type2)
		{
		tryPlain = kJTrue;
		}
	else if (type1 == kJSVNType || type1 == kJGitType)
		{
		if (type1 == kJSVNType)
			{
			cmd  = "svn mv --force ";
			cmd += JPrepArgForExec(oldFullName);
			cmd += " ";
			cmd += JPrepArgForExec(newFullName);
			}
		else if (type1 == kJGitType)
			{
			cmd  = "git mv -f ";
			cmd += JPrepArgForExec(name);
			cmd += " ";
			cmd += JPrepArgForExec(newFullName);
			}

		err = JProcess::Create(&p, cmd);
		if (err.OK())
			{
			p->WaitUntilFinished();
			}

		if (p != NULL && !p->SuccessfulFinish())
			{
			err      = JAccessDenied(oldFullName, newFullName);
			tryPlain = kJTrue;
			}
		}
	else if (type1 == kJUnknownVCSType)
		{
		tryPlain = kJTrue;
		}
	else
		{
		err = JUnsupportedVCS(oldFullName);
		}

	if (tryPlain && JProgramAvailable("mv"))
		{
		cmd  = "mv ";
		cmd += JPrepArgForExec(oldFullName);
		cmd += " ";
		cmd += JPrepArgForExec(newFullName);

		JSimpleProcess* p1;
		err = JSimpleProcess::Create(&p1, cmd);
		p   = p1;
		if (err.OK())
			{
			p->WaitUntilFinished();
			if (!p->SuccessfulFinish())
				{
				err = JAccessDenied(oldFullName, newFullName);
				}
			}
		}
	else if (tryPlain)
		{
		err = JRenameDirEntry(oldFullName, newFullName);
		}

	delete p;
	JChangeDirectory(origPath);
	return err;
}
Пример #17
0
JError
JCreateTempDirectory
	(
	const JCharacter*	path,
	const JCharacter*	prefix,
	JString*			fullName
	)
{
	JString p;
	if (!JStringEmpty(path))
		{
		p = path;
		}
	else if (!JGetTempDirectory(&p))
		{
		return JDirEntryDoesNotExist("/tmp");
		}

	if (!JStringEmpty(prefix))
		{
		p = JCombinePathAndName(p, prefix);
		}
	else
		{
		p = JCombinePathAndName(p, "temp_dir_");
		}

	p      += "XXXXXX";
	char* s = p.AllocateCString();

	jclear_errno();
	char* d = mkdtemp(s);
	if (d != NULL)
		{
		*fullName = s;
		JAppendDirSeparator(fullName);
		delete [] s;
		return JNoError();
		}

	fullName->Clear();
	delete [] s;

	// EINVAL counts as unexpected

	const int err = jerrno();
	if (err == EEXIST)
		{
		return JDirEntryAlreadyExists(p);
		}
	else if (err == EFAULT)
		{
		return JSegFault();
		}
	else if (err == EACCES)
		{
		return JAccessDenied(p);
		}
	else if (err == ENAMETOOLONG)
		{
		return JNameTooLong();
		}
	else if (err == ENOENT)
		{
		return JBadPath(p);
		}
	else if (err == ENOTDIR)
		{
		return JComponentNotDirectory(p);
		}
	else if (err == ENOMEM)
		{
		return JNoKernelMemory();
		}
	else if (err == EROFS)
		{
		return JFileSystemReadOnly();
		}
	else if (err == ELOOP)
		{
		return JPathContainsLoop(p);
		}
	else if (err == ENOSPC)
		{
		return JFileSystemFull();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
JBoolean
CBFileNameDisplay::InputValid()
{
	const JString& text = GetText();
	if (itsUnfocusAction == kCancel)
		{
		return kJTrue;
		}
	else if (text.IsEmpty())
		{
		(JGetUserNotification())->ReportError(JGetString(kEmptyErrorID));
		return kJFalse;
		}
	else if (text.EndsWith(ACE_DIRECTORY_SEPARATOR_STR))
		{
		(JGetUserNotification())->ReportError(JGetString(kNoFileNameID));
		return kJFalse;
		}
	else if (JIsRelativePath(text))
		{
		return kJTrue;	// open Choose File dialog
		}

	JString path, fullPath, name;
	JSplitPathAndName(text, &path, &name);
	if (!JExpandHomeDirShortcut(path, &fullPath))
		{
		return kJFalse;
		}

	const JString fullName = JCombinePathAndName(fullPath, name);
	JBoolean onDisk;
	const JString origFullName = itsDoc->GetFullName(&onDisk);
	if (onDisk && JSameDirEntry(origFullName, fullName))
		{
		itsUnfocusAction = kCancel;
		return kJTrue;
		}

	if (JFileExists(fullName))
		{
		const JCharacter* map[] =
			{
			"f", text
			};
		const JString msg = JGetString(kOKToReplaceID, map, sizeof(map));
		if (!(JGetUserNotification())->AskUserNo(msg))
			{
			return kJFalse;
			}
		}

	if (!JDirectoryExists(fullPath))
		{
		const JError err = JCreateDirectory(fullPath);
		if (!err.OK())
			{
			err.ReportIfError();
			return kJFalse;
			}
		}
	else if (!JDirectoryWritable(fullPath))
		{
		const JError err = JAccessDenied(fullPath);
		err.ReportIfError();
		return kJFalse;
		}

	if (itsUnfocusAction == kRename)
		{
		const JError err = JRenameVCS(origFullName, fullName);
		err.ReportIfError();
		return err.OK();
		}
	else
		{
		return kJTrue;
		}
}