1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/RepoStatus.cc
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/RepoStatus.h"
18 #include "zypp/PathInfo.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
28 // CLASS NAME : RepoStatus::Impl
30 /** RepoStatus implementation. */
31 struct RepoStatus::Impl
37 /** Recursive computation of max dir timestamp. */
38 static void recursive_timestamp( const Pathname & dir_r, time_t & max_r )
40 std::list<std::string> dircontent;
41 if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 )
42 return; // readdir logged the error
44 for_( it, dircontent.begin(), dircontent.end() )
46 PathInfo pi( dir_r + *it, PathInfo::LSTAT );
49 if ( pi.mtime() > max_r )
51 recursive_timestamp( pi.path(), max_r );
57 friend Impl * rwcowClone<Impl>( const Impl * rhs );
58 /** clone for RWCOW_pointer */
60 { return new Impl( *this ); }
62 ///////////////////////////////////////////////////////////////////
64 /** \relates RepoStatus::Impl Stream output */
65 inline std::ostream & operator<<( std::ostream & str, const RepoStatus::Impl & obj )
66 { return str << obj._checksum << " " << (time_t)obj._timestamp; }
68 ///////////////////////////////////////////////////////////////////
70 // CLASS NAME : RepoStatus
72 ///////////////////////////////////////////////////////////////////
74 RepoStatus::RepoStatus()
75 : _pimpl( new Impl() )
78 RepoStatus::RepoStatus( const Pathname & path_r )
79 : _pimpl( new Impl() )
81 PathInfo info( path_r );
86 _pimpl->_timestamp = Date( info.mtime() );
87 _pimpl->_checksum = filesystem::sha1sum( path_r );
89 else if ( info.isDir() )
91 time_t t = info.mtime();
92 Impl::recursive_timestamp( path_r, t );
93 _pimpl->_timestamp = Date(t);
94 _pimpl->_checksum = CheckSum::sha1FromString( str::numstring( t ) ).checksum();
97 // NOTE: changing magic will once invalidate all solv file caches
98 // Helpfull if solv file content must be refreshed (e.g. due to different
99 // repo2* arguments) even if raw metadata are unchanged.
100 static const std::string magic( "42" );
101 _pimpl->_checksum += magic;
105 RepoStatus::~RepoStatus()
108 RepoStatus RepoStatus::fromCookieFile( const Pathname & path_r )
111 std::ifstream file( path_r.c_str() );
114 WAR << "No cookie file " << path_r << endl;
118 // line := "[checksum] time_t"
119 std::string line( str::getline( file ) );
120 ret._pimpl->_timestamp = Date( str::strtonum<time_t>( str::stripLastWord( line ) ) );
121 ret._pimpl->_checksum = line;
126 void RepoStatus::saveToCookieFile( const Pathname & path_r ) const
128 std::ofstream file(path_r.c_str());
130 ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) );
132 file << _pimpl->_checksum << " " << (time_t)_pimpl->_timestamp << endl;
136 bool RepoStatus::empty() const
137 { return _pimpl->_checksum.empty(); }
139 Date RepoStatus::timestamp() const
140 { return _pimpl->_timestamp; }
142 std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
143 { return str << *obj._pimpl; }
145 RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
151 else if ( rhs.empty() )
155 // order strings to assert && is kommutativ
156 std::string lchk( lhs._pimpl->_checksum );
157 std::string rchk( rhs._pimpl->_checksum );
158 stringstream ss( lchk < rchk ? lchk+rchk : rchk+lchk );
160 result._pimpl->_checksum = CheckSum::sha1(ss).checksum();
161 result._pimpl->_timestamp = std::max( lhs._pimpl->_timestamp, rhs._pimpl->_timestamp );
166 bool operator==( const RepoStatus & lhs, const RepoStatus & rhs )
167 { return lhs._pimpl->_checksum == rhs._pimpl->_checksum; }
169 /////////////////////////////////////////////////////////////////
171 ///////////////////////////////////////////////////////////////////