Author: coolo Date: Fri Feb 8 09:52:29 2008 New Revision: 8555 URL: http://svn.opensuse.org/viewcvs/zypp?rev=8555&view=rev Log: ------------------------------------------------------------------------ r8177 | jkupec | 2008-01-02 18:02:39 +0100 (Mi, 02 Jan 2008) | 8 lines - expandlink(Pathname) added - TODO: could be made so that it throws on bad links (better error reporting) - TODO: cyclic links protection can be improved by remembering paths alredy visited and checking them (again better error reporting and performance) ------------------------------------------------------------------------ Modified: branches/tmp/ma/jump_sat/libzypp/tests/zypp/PathInfo.cc branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.cc branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.h Modified: branches/tmp/ma/jump_sat/libzypp/tests/zypp/PathInfo.cc URL: http://svn.opensuse.org/viewcvs/zypp/branches/tmp/ma/jump_sat/libzypp/tests/zypp/PathInfo.cc?rev=8555&r1=8554&r2=8555&view=diff ============================================================================== --- branches/tmp/ma/jump_sat/libzypp/tests/zypp/PathInfo.cc (original) +++ branches/tmp/ma/jump_sat/libzypp/tests/zypp/PathInfo.cc Fri Feb 8 09:52:29 2008 @@ -71,13 +71,59 @@ void pathinfo_misc_test() { TmpDir dir; - - - + PathInfo info(dir.path()); BOOST_CHECK(info.isDir()); } +void pathinfo_expandlink_test() +{ + TmpDir dir; + + // ---- not a link + + // create a file + Pathname file(dir / "file"); + ofstream str(file.asString().c_str(),ofstream::out); + str << "foo bar" << endl; + str.flush(); + str.close(); + + // expandlink should return the original Pathname if it does not point to a link + BOOST_CHECK_EQUAL( file, filesystem::expandlink(file) ); + + // ---- valid link + + // create a link to that file + Pathname link1(dir / "link1"); + BOOST_CHECK_EQUAL( filesystem::symlink(file, link1), 0); + + // does the link expand to the file? + BOOST_CHECK_EQUAL( file, filesystem::expandlink(link1) ); + + // ---- broken link + + // create a link to a non-existent file + Pathname brokenlink(dir / "brokenlink"); + Pathname non_existent(dir / "non-existent"); + BOOST_CHECK_EQUAL( filesystem::symlink(non_existent, brokenlink), 0); + PathInfo info(brokenlink, PathInfo::LSTAT); + BOOST_CHECK(info.isLink()); + + // expandlink should return an empty Pathname for a broken link + BOOST_CHECK_EQUAL( Pathname(), filesystem::expandlink(brokenlink) ); + + // ---- cyclic link + + // make the 'non-existent' a link to 'brokenlink' :O) + BOOST_CHECK_EQUAL( filesystem::symlink(brokenlink, non_existent), 0); + // expandlink should return an empty Pathname for such a cyclic link + BOOST_CHECK_EQUAL( Pathname(), filesystem::expandlink(brokenlink) ); + BOOST_CHECK_EQUAL( Pathname(), filesystem::expandlink(non_existent) ); + + cout << brokenlink << " -> " << filesystem::expandlink(brokenlink) << endl; +} + test_suite* init_unit_test_suite( int, char* [] ) { @@ -85,6 +131,7 @@ test->add( BOOST_TEST_CASE( &pathinfo_checksum_test ), 0 /* expected zero error */ ); test->add( BOOST_TEST_CASE( &pathinfo_misc_test ), 0 /* expected zero error */ ); test->add( BOOST_TEST_CASE( &pathinfo_is_exist_test ), 0 /* expected zero error */ ); + test->add( BOOST_TEST_CASE( &pathinfo_expandlink_test ), 0 /* expected zero error */ ); return test; } Modified: branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.cc URL: http://svn.opensuse.org/viewcvs/zypp/branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.cc?rev=8555&r1=8554&r2=8555&view=diff ============================================================================== --- branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.cc (original) +++ branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.cc Fri Feb 8 09:52:29 2008 @@ -756,6 +756,50 @@ /////////////////////////////////////////////////////////////////// // + // METHOD NAME : expandlink + // METHOD TYPE : Pathname + // + Pathname expandlink( const Pathname & path_r ) + { + static const unsigned int level_limit = 256; + static unsigned int count; + Pathname path(path_r); + PathInfo info(path_r, PathInfo::LSTAT); + + for (count = level_limit; info.isLink() && count; count--) + { + DBG << "following symlink " << path << std::endl; + path = readlink(path); + info = PathInfo(path, PathInfo::LSTAT); + } + + // expand limit reached + if (count == 0) + { + ERR << "Expand level limit reached. Probably a cyclic symbolic link." << endl; + return Pathname(); + } + // symlink + else if (count < level_limit) + { + // check for a broken link + if (PathInfo(path).isExist()) + return path; + // broken link, return and empty path + else + { + ERR << path << " is broken (expanded from " << path_r << ")" << endl; + return Pathname(); + } + } + + // not a symlink, return the original pathname + DBG << "not a symlink" << endl; + return path; + } + + /////////////////////////////////////////////////////////////////// + // // METHOD NAME : copy_file2dir // METHOD TYPE : int // Modified: branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.h URL: http://svn.opensuse.org/viewcvs/zypp/branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.h?rev=8555&r1=8554&r2=8555&view=diff ============================================================================== --- branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.h (original) +++ branches/tmp/ma/jump_sat/libzypp/zypp/PathInfo.h Fri Feb 8 09:52:29 2008 @@ -582,6 +582,20 @@ } /** + * Recursively follows the symlink pointed to by \a path_r and returns + * the Pathname to the real file or directory pointed to by the link. + * + * There is a recursion limit of 256 iterations to protect against a cyclic + * link. + * + * @return Pathname of the file or directory pointed to by the given link + * if it is a valid link. If \a path_r is not a link, an exact copy of + * it is returned. If \a path_r is a broken or a cyclic link, an empty + * Pathname is returned and the event logged. + */ + Pathname expandlink( const Pathname & path_r ); + + /** * Like 'cp file dest'. Copy file to dest dir. * * @return 0 on success, EINVAL if file is not a file, ENOTDIR if dest -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org