libzypp  17.14.0
RepoStatus.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 #include <fstream>
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/RepoStatus.h"
18 #include "zypp/PathInfo.h"
19 
20 using namespace std;
21 
23 namespace zypp
24 {
25 
27  //
28  // CLASS NAME : RepoStatus::Impl
29  //
32  {
33  public:
34  string _checksum;
36 
38  static void recursive_timestamp( const Pathname & dir_r, time_t & max_r )
39  {
40  std::list<std::string> dircontent;
41  if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 )
42  return; // readdir logged the error
43 
44  for_( it, dircontent.begin(), dircontent.end() )
45  {
46  PathInfo pi( dir_r + *it, PathInfo::LSTAT );
47  if ( pi.isDir() )
48  {
49  if ( pi.mtime() > max_r )
50  max_r = pi.mtime();
51  recursive_timestamp( pi.path(), max_r );
52  }
53  }
54  }
55 
56  private:
57  friend Impl * rwcowClone<Impl>( const Impl * rhs );
59  Impl * clone() const
60  { return new Impl( *this ); }
61  };
63 
65  inline std::ostream & operator<<( std::ostream & str, const RepoStatus::Impl & obj )
66  { return str << obj._checksum << " " << (time_t)obj._timestamp; }
67 
69  //
70  // CLASS NAME : RepoStatus
71  //
73 
74  RepoStatus::RepoStatus()
75  : _pimpl( new Impl() )
76  {}
77 
78  RepoStatus::RepoStatus( const Pathname & path_r )
79  : _pimpl( new Impl() )
80  {
81  PathInfo info( path_r );
82  if ( info.isExist() )
83  {
84  if ( info.isFile() )
85  {
86  _pimpl->_timestamp = Date( info.mtime() );
88  }
89  else if ( info.isDir() )
90  {
91  time_t t = info.mtime();
92  Impl::recursive_timestamp( path_r, t );
93  _pimpl->_timestamp = Date(t);
95  }
96 
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( "43" );
101  _pimpl->_checksum += magic;
102  }
103  }
104 
106  {}
107 
108  RepoStatus RepoStatus::fromCookieFile( const Pathname & path_r )
109  {
110  RepoStatus ret;
111  std::ifstream file( path_r.c_str() );
112  if ( !file )
113  {
114  WAR << "No cookie file " << path_r << endl;
115  }
116  else
117  {
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;
122  }
123  return ret;
124  }
125 
126  void RepoStatus::saveToCookieFile( const Pathname & path_r ) const
127  {
128  std::ofstream file(path_r.c_str());
129  if (!file) {
130  ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) );
131  }
132  file << _pimpl->_checksum << " " << (time_t)_pimpl->_timestamp << endl;
133  file.close();
134  }
135 
136  bool RepoStatus::empty() const
137  { return _pimpl->_checksum.empty(); }
138 
140  { return _pimpl->_timestamp; }
141 
142  std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
143  { return str << *obj._pimpl; }
144 
145  RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
146  {
147  RepoStatus result;
148 
149  if ( lhs.empty() )
150  result = rhs;
151  else if ( rhs.empty() )
152  result = lhs;
153  else
154  {
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 );
159 
160  result._pimpl->_checksum = CheckSum::sha1(ss).checksum();
161  result._pimpl->_timestamp = std::max( lhs._pimpl->_timestamp, rhs._pimpl->_timestamp );
162  }
163  return result;
164  }
165 
166  bool operator==( const RepoStatus & lhs, const RepoStatus & rhs )
167  { return lhs._pimpl->_checksum == rhs._pimpl->_checksum; }
168 
170 } // namespace zypp