예제 #1
0
/*static*/ status_t
FSUtils::CompareSymLinks(BSymLink& symLink1, BSymLink& symLink2, bool& _equal)
{
    char buffer1[B_PATH_NAME_LENGTH];
    ssize_t bytesRead1 = symLink1.ReadLink(buffer1, sizeof(buffer1));
    if (bytesRead1 < 0)
        return bytesRead1;

    char buffer2[B_PATH_NAME_LENGTH];
    ssize_t bytesRead2 = symLink2.ReadLink(buffer2, sizeof(buffer2));
    if (bytesRead2 < 0)
        return bytesRead2;

    _equal = bytesRead1 == bytesRead2
             && memcmp(buffer1, buffer2, bytesRead1) == 0;
    return B_OK;
}
예제 #2
0
/*static*/ status_t
FSUtils::_OpenSymLink(const Entry& entry, BSymLink& symLink)
{
    BPath pathBuffer;
    const char* path;
    status_t error = entry.GetPath(pathBuffer, path);
    if (error != B_OK)
        return error;

    return symLink.SetTo(path);
}
예제 #3
0
status_t
PackageLink::WriteToPath(const char *path, ItemState *state)
{
	if (state == NULL)
		return B_ERROR;

	status_t ret = B_OK;
	BSymLink symlink;
	parser_debug("Symlink: %s WriteToPath() called!\n", fPath.String());

	BPath &destination = state->destination;
	BDirectory *dir = &state->parent;

	if (state->status == B_NO_INIT || destination.InitCheck() != B_OK
		|| dir->InitCheck() != B_OK) {
		// Not yet initialized
		ret = InitPath(path, &destination);
		if (ret != B_OK)
			return ret;

		BString linkName(destination.Leaf());
		parser_debug("%s:%s:%s\n", fPath.String(), destination.Path(),
			linkName.String());

		BPath dirPath;
		ret = destination.GetParent(&dirPath);
		ret = dir->SetTo(dirPath.Path());

		if (ret == B_ENTRY_NOT_FOUND) {
			ret = create_directory(dirPath.Path(), kDefaultMode);
			if (ret != B_OK) {
				parser_debug("create_directory()) failed\n");
				return B_ERROR;
			}
		}
		if (ret != B_OK) {
			parser_debug("destination InitCheck failed %s for %s\n",
				strerror(ret), dirPath.Path());
			return ret;
		}

		ret = dir->CreateSymLink(destination.Path(), fLink.String(), &symlink);
		if (ret == B_FILE_EXISTS) {
			// We need to check if the existing symlink is pointing at the same path
			// as our new one - if not, let's prompt the user
			symlink.SetTo(destination.Path());
			BPath oldLink;

			ret = symlink.MakeLinkedPath(dir, &oldLink);
			chdir(dirPath.Path());

			if (ret == B_BAD_VALUE || oldLink != fLink.String())
				state->status = ret = B_FILE_EXISTS;
			else
				ret = B_OK;
		}
	}

	if (state->status == B_FILE_EXISTS) {
		switch (state->policy) {
			case P_EXISTS_OVERWRITE:
			{
				BEntry entry;
				ret = entry.SetTo(destination.Path());
				if (ret != B_OK)
					return ret;

				entry.Remove();
				ret = dir->CreateSymLink(destination.Path(), fLink.String(),
					&symlink);
				break;
			}

			case P_EXISTS_NONE:
			case P_EXISTS_ASK:
				ret = B_FILE_EXISTS;
				break;

			case P_EXISTS_SKIP:
				return B_OK;
		}
	}

	if (ret != B_OK) {
		parser_debug("CreateSymLink failed\n");
		return ret;
	}

	parser_debug(" Symlink created!\n");

	ret = symlink.SetPermissions(static_cast<mode_t>(fMode));

	if (fCreationTime && ret == B_OK)
		ret = symlink.SetCreationTime(static_cast<time_t>(fCreationTime));

	if (fModificationTime && ret == B_OK) {
		ret = symlink.SetModificationTime(static_cast<time_t>(
			fModificationTime));
	}

	if (ret != B_OK) {
		parser_debug("Failed to set symlink attributes\n");
		return ret;
	}

	if (fOffset) {
		// Symlinks also seem to have attributes - so parse them
		ret = HandleAttributes(&destination, &symlink, "LnDa");
	}

	return ret;
}
예제 #4
0
// InitTest1
void
SymLinkTest::InitTest1()
{
	const char *dirLink = dirLinkname;
	const char *dirSuperLink = dirSuperLinkname;
	const char *dirRelLink = dirRelLinkname;
	const char *fileLink = fileLinkname;
	const char *existingDir = existingDirname;
	const char *existingSuperDir = existingSuperDirname;
	const char *existingRelDir = existingRelDirname;
	const char *existingFile = existingFilename;
	const char *existingSuperFile = existingSuperFilename;
	const char *existingRelFile = existingRelFilename;
	const char *nonExisting = nonExistingDirname;
	const char *nonExistingSuper = nonExistingSuperDirname;
	const char *nonExistingRel = nonExistingRelDirname;
	// 1. default constructor
	NextSubTest();
	{
		BSymLink link;
		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
	}

	// 2. BSymLink(const char*)
	NextSubTest();
	{
		BSymLink link(fileLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BSymLink link(nonExisting);
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
	NextSubTest();
	{
		BSymLink link((const char *)NULL);
		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
	}
	NextSubTest();
	{
		BSymLink link("");
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
	NextSubTest();
	{
		BSymLink link(existingFile);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BSymLink link(existingDir);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BSymLink link(tooLongEntryname);
		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
	}

	// 3. BSymLink(const BEntry*)
	NextSubTest();
	{
		BEntry entry(dirLink);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		BSymLink link(&entry);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BEntry entry(nonExisting);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		BSymLink link(&entry);
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
	NextSubTest();
	{
		BSymLink link((BEntry *)NULL);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BEntry entry;
		BSymLink link(&entry);
		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
	}
	NextSubTest();
	{
		BEntry entry(existingFile);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		BSymLink link(&entry);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );

	}
	NextSubTest();
	{
		BEntry entry(existingDir);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		BSymLink link(&entry);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );

	}
	NextSubTest();
	{
		BEntry entry(tooLongEntryname);
		// R5 returns E2BIG instead of B_NAME_TOO_LONG
		CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
		BSymLink link(&entry);
		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
	}

	// 4. BSymLink(const entry_ref*)
	NextSubTest();
	{
		BEntry entry(dirLink);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		entry_ref ref;
		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
		BSymLink link(&ref);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BEntry entry(nonExisting);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		entry_ref ref;
		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
		BSymLink link(&ref);
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
	NextSubTest();
	{
		BSymLink link((entry_ref *)NULL);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BEntry entry(existingFile);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		entry_ref ref;
		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
		BSymLink link(&ref);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BEntry entry(existingDir);
		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
		entry_ref ref;
		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
		BSymLink link(&ref);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}

	// 5. BSymLink(const BDirectory*, const char*)
	NextSubTest();
	{
		BDirectory pathDir(dirSuperLink);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, dirRelLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BDirectory pathDir(dirSuperLink);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, dirLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BDirectory pathDir(nonExistingSuper);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, nonExistingRel);
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
	NextSubTest();
	{
		BSymLink link((BDirectory *)NULL, (const char *)NULL);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BSymLink link((BDirectory *)NULL, dirLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BDirectory pathDir(dirSuperLink);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, (const char *)NULL);
		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
	}
	NextSubTest();
	{
		BDirectory pathDir(dirSuperLink);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, "");
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BDirectory pathDir(existingSuperFile);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, existingRelFile);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BDirectory pathDir(existingSuperDir);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, existingRelDir);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
	}
	NextSubTest();
	{
		BDirectory pathDir(tooLongSuperEntryname);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, tooLongRelEntryname);
		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
	}
	NextSubTest();
	{
		BDirectory pathDir(fileSuperDirname);
		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
		BSymLink link(&pathDir, fileRelDirname);
		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
	}
}
예제 #5
0
// AssignmentTest
void
SymLinkTest::AssignmentTest()
{
	const char *dirLink = dirLinkname;
	const char *fileLink = fileLinkname;
	// 1. copy constructor
	// uninitialized
	NextSubTest();
	{
		BSymLink link;
		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
		BSymLink link2(link);
		// R5 returns B_BAD_VALUE instead of B_NO_INIT
		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
	}
	// existing dir link
	NextSubTest();
	{
		BSymLink link(dirLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
		BSymLink link2(link);
		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
	}
	// existing file link
	NextSubTest();
	{
		BSymLink link(fileLink);
		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
		BSymLink link2(link);
		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
	}

	// 2. assignment operator
	// uninitialized
	NextSubTest();
	{
		BSymLink link;
		BSymLink link2;
		link2 = link;
		// R5 returns B_BAD_VALUE instead of B_NO_INIT
		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
	}
	NextSubTest();
	{
		BSymLink link;
		BSymLink link2(dirLink);
		link2 = link;
		// R5 returns B_BAD_VALUE instead of B_NO_INIT
		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
	}
	// existing dir link
	NextSubTest();
	{
		BSymLink link(dirLink);
		BSymLink link2;
		link2 = link;
		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
	}
	// existing file link
	NextSubTest();
	{
		BSymLink link(fileLink);
		BSymLink link2;
		link2 = link;
		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
	}
}
예제 #6
0
// IsAbsoluteTest
void
SymLinkTest::IsAbsoluteTest()
{
	const char *dirLink = dirLinkname;
	const char *relFileLink = relFileLinkname;
	const char *existingDir = existingDirname;
	const char *existingFile = existingFilename;
	const char *nonExisting = nonExistingDirname;
	BSymLink link;
	// uninitialized
	NextSubTest();
	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
	CPPUNIT_ASSERT( link.IsAbsolute() == false );
	link.Unset();
	// existing absolute dir link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( link.IsAbsolute() == true );
	link.Unset();
	// existing relative file link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
	CPPUNIT_ASSERT( link.IsAbsolute() == false );
	link.Unset();
	// non-existing link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
	CPPUNIT_ASSERT( link.IsAbsolute() == false );
	link.Unset();
	// dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
	CPPUNIT_ASSERT( link.IsAbsolute() == false );
	link.Unset();
	// file
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
	CPPUNIT_ASSERT( link.IsAbsolute() == false );
	link.Unset();
}
예제 #7
0
// MakeLinkedPathTest
void
SymLinkTest::MakeLinkedPathTest()
{
	const char *dirLink = dirLinkname;
	const char *fileLink = fileLinkname;
	const char *relDirLink = relDirLinkname;
	const char *relFileLink = relFileLinkname;
	const char *cyclicLink1 = cyclicLinkname1;
	const char *cyclicLink2 = cyclicLinkname2;
	const char *existingDir = existingDirname;
	const char *existingSuperDir = existingSuperDirname;
	const char *existingFile = existingFilename;
	const char *existingSuperFile = existingSuperFilename;
	const char *nonExisting = nonExistingDirname;
	BSymLink link;
	BPath path;
	// 1. MakeLinkedPath(const char*, BPath*)
	// uninitialized
	NextSubTest();
	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
	CPPUNIT_ASSERT( equals(link.MakeLinkedPath("/boot", &path), B_BAD_ADDRESS,
						   B_FILE_ERROR) );
	link.Unset();
	path.Unset();
	// existing absolute dir link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
					== (ssize_t)strlen(existingDir) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
	link.Unset();
	path.Unset();
	// existing absolute file link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
					== (ssize_t)strlen(existingFile) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
	link.Unset();
	path.Unset();
	// existing absolute cyclic link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
					== (ssize_t)strlen(cyclicLink2) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
	link.Unset();
	path.Unset();
	// existing relative dir link
	NextSubTest();
	BEntry entry;
	BPath entryPath;
	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperDir, &path)
					== (ssize_t)strlen(entryPath.Path()) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( entryPath == path );
	link.Unset();
	path.Unset();
	entry.Unset();
	entryPath.Unset();
	// existing relative file link
	NextSubTest();
	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperFile, &path)
					== (ssize_t)strlen(entryPath.Path()) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( entryPath == path );
	link.Unset();
	path.Unset();
	entry.Unset();
	entryPath.Unset();
	// bad args
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
// R5: crashs, when passing a NULL path
#if !TEST_R5
	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", NULL) == B_BAD_VALUE );
#endif
	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, &path)
					== B_BAD_VALUE );
// R5: crashs, when passing a NULL path
#if !TEST_R5
	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, NULL)
					== B_BAD_VALUE );
#endif
	link.Unset();
	path.Unset();

	// 2. MakeLinkedPath(const BDirectory*, BPath*)
	// uninitialized
	NextSubTest();
	link.Unset();
	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
	BDirectory dir;
	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_BAD_ADDRESS,
						   B_FILE_ERROR) );
	link.Unset();
	path.Unset();
	dir.Unset();
	// existing absolute dir link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(existingDir) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
	link.Unset();
	path.Unset();
	dir.Unset();
	// existing absolute file link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(existingFile) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
	link.Unset();
	path.Unset();
	dir.Unset();
	// existing absolute cyclic link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(cyclicLink2) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
	link.Unset();
	path.Unset();
	dir.Unset();
	// existing relative dir link
	NextSubTest();
	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo(existingSuperDir) == B_OK);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(entryPath.Path()) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( entryPath == path );
	link.Unset();
	path.Unset();
	dir.Unset();
	entry.Unset();
	entryPath.Unset();
	// existing relative file link
	NextSubTest();
	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(entryPath.Path()) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( entryPath == path );
	link.Unset();
	path.Unset();
	dir.Unset();
	entry.Unset();
	entryPath.Unset();
	// absolute link, uninitialized dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(existingDir) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
	// absolute link, badly initialized dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
					== (ssize_t)strlen(existingDir) );
	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
	link.Unset();
	path.Unset();
	dir.Unset();
	// relative link, uninitialized dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
						   B_BAD_VALUE) );
	link.Unset();
	// relative link, badly initialized dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
						   B_BAD_VALUE) );
	link.Unset();
	path.Unset();
	dir.Unset();
	// bad args
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
// R5: crashs, when passing a NULL path
#if !TEST_R5
	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, NULL) == B_BAD_VALUE );
#endif

	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, &path)
					== B_BAD_VALUE );
// R5: crashs, when passing a NULL path
#if !TEST_R5
	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, NULL)
					== B_BAD_VALUE );
#endif
	link.Unset();
	path.Unset();
	dir.Unset();
}
예제 #8
0
// ReadLinkTest
void
SymLinkTest::ReadLinkTest()
{
	const char *dirLink = dirLinkname;
	const char *fileLink = fileLinkname;
	const char *badLink = badLinkname;
	const char *cyclicLink1 = cyclicLinkname1;
	const char *cyclicLink2 = cyclicLinkname2;
	const char *existingDir = existingDirname;
	const char *existingFile = existingFilename;
	const char *nonExisting = nonExistingDirname;
	BSymLink link;
	char buffer[B_PATH_NAME_LENGTH + 1];
	// uninitialized
	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
	NextSubTest();
	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
						   B_BAD_ADDRESS, B_FILE_ERROR) );
	// existing dir link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
					== (ssize_t)strlen(existingDir) );
	CPPUNIT_ASSERT( strcmp(buffer, existingDir) == 0 );
	// existing file link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
					== (ssize_t)strlen(existingFile) );
	CPPUNIT_ASSERT( strcmp(buffer, existingFile) == 0 );
	// existing cyclic link
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
					== (ssize_t)strlen(cyclicLink2) );
	CPPUNIT_ASSERT( strcmp(buffer, cyclicLink2) == 0 );
	// existing link to non-existing entry
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(badLink) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
					== (ssize_t)strlen(nonExisting) );
	CPPUNIT_ASSERT( strcmp(buffer, nonExisting) == 0 );
	// non-existing link
	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
						   B_BAD_ADDRESS, B_FILE_ERROR) );
	// dir
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
	// file
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
	// small buffer
	// R5: returns the size of the contents, not the number of bytes copied
	// OBOS: ... so do we
	NextSubTest();
	char smallBuffer[2];
	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
	CPPUNIT_ASSERT( link.ReadLink(smallBuffer, sizeof(smallBuffer))
					== (ssize_t)strlen(dirLink) );
	CPPUNIT_ASSERT( strncmp(smallBuffer, existingDir, sizeof(smallBuffer)) == 0 );
	// bad args
	NextSubTest();
	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
	CPPUNIT_ASSERT( equals(link.ReadLink(NULL, sizeof(buffer)), B_BAD_ADDRESS,
						   B_BAD_VALUE) );
}
bool GenesisCopyWindow::CopyLink(const char *linkname, const char *destination, const char *destfilename)
////////////////////////////////////////////////////////////////////////
{
	BSymLink srclink;
	BSymLink dstlink;
	BDirectory dstdir;
	BEntry srcentry;
	BEntry symlinkentry;
	BPath LinkPath;
	char name[B_FILE_NAME_LENGTH];
	struct stat statbuf;
	entry_ref ref;
		
	srcentry.SetTo(linkname);
	srcentry.GetName(name);
	srcentry.GetRef(&ref);
	symlinkentry.SetTo(&ref, true);
	symlinkentry.GetPath(&LinkPath);

	if (destfilename)
		sprintf(name,"%s",destfilename);
	
	if (srcentry.GetStat(&statbuf)!=B_OK)
		return false;

	dstdir.SetTo(destination);
	
	if (dstdir.InitCheck()!=B_OK)
		return false;

	Lock();
	m_FileBar->Update(-m_FileBar->CurrentValue());	// Reset to 0.0
	m_FileBar->SetMaxValue(1);
	m_FileBar->SetTrailingText(name);
	Unlock();

	if (dstdir.CreateSymLink(name, LinkPath.Path(), &dstlink)!=B_OK && !m_SkipSymLinkCreationError)
	{
		BString text;
		
		text << "Cannot create '" << name << "' symbolic link in '" << LinkPath.Path() << "'";
		
		BAlert *myAlert = new BAlert("Copy",text.String(),"Abort","Skip all","Skip",B_WIDTH_AS_USUAL,B_OFFSET_SPACING,B_WARNING_ALERT);
		myAlert->SetShortcut(0, B_ESCAPE);
		switch (myAlert->Go())
		{
			case 0:
				Close();
				kill_thread(m_CopyThread);
				break;
			case 1:
				m_SkipSymLinkCreationError = true;
				break;
		}	

		return false;
	}

	Lock();
	m_FileBar->Update(1);
	Unlock();
		
	dstlink.SetPermissions(statbuf.st_mode);
	dstlink.SetOwner(statbuf.st_uid);
	dstlink.SetGroup(statbuf.st_gid);
	dstlink.SetModificationTime(statbuf.st_mtime);
	dstlink.SetCreationTime(statbuf.st_crtime);

	// Copy attributes...
	BString destlinkname;
	destlinkname.SetTo("");
	destlinkname << destination << "/" << name;
	CopyAttr(linkname, destlinkname.String());

	return true;
}