libzypp  17.23.5
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 std::endl;
21 
23 namespace zypp
24 {
25 
27  //
28  // CLASS NAME : RepoStatus::Impl
29  //
32  {
33  public:
34  std::string _checksum;
36 
37  // NOTE: Changing magic will at once invalidate all solv file caches.
38  // Helpfull if solv file content must be refreshed (e.g. due to different
39  // repo2* arguments) even if raw metadata are unchanged.
40  // Only values set from a RepoStatus ctor need magic to be added.
41  void assignFromCtor( std::string && checksum_r, Date && timestamp_r )
42  {
43  _checksum = std::move(checksum_r);
44  _timestamp = std::move(timestamp_r);
45  if ( !_checksum.empty() )
46  {
47  static const std::string magic( "43" );
48  _checksum += magic;
49  }
50  }
51 
53  static void recursive_timestamp( const Pathname & dir_r, time_t & max_r )
54  {
55  std::list<std::string> dircontent;
56  if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 )
57  return; // readdir logged the error
58 
59  for_( it, dircontent.begin(), dircontent.end() )
60  {
61  PathInfo pi( dir_r + *it, PathInfo::LSTAT );
62  if ( pi.isDir() )
63  {
64  if ( pi.mtime() > max_r )
65  max_r = pi.mtime();
66  recursive_timestamp( pi.path(), max_r );
67  }
68  }
69  }
70 
71  private:
72  friend Impl * rwcowClone<Impl>( const Impl * rhs );
74  Impl * clone() const
75  { return new Impl( *this ); }
76  };
78 
80  inline std::ostream & operator<<( std::ostream & str, const RepoStatus::Impl & obj )
81  { return str << obj._checksum << " " << (time_t)obj._timestamp; }
82 
84  //
85  // CLASS NAME : RepoStatus
86  //
88 
90  : _pimpl( new Impl() )
91  {}
92 
93  RepoStatus::RepoStatus( const Pathname & path_r )
94  : _pimpl( new Impl() )
95  {
96  PathInfo info( path_r );
97  if ( info.isExist() )
98  {
99  if ( info.isFile() )
100  {
101  _pimpl->assignFromCtor( filesystem::sha1sum( path_r ), Date( info.mtime() ) );
102  }
103  else if ( info.isDir() )
104  {
105  time_t t = info.mtime();
106  Impl::recursive_timestamp( path_r, t );
108  }
109  }
110  }
111 
112  RepoStatus::RepoStatus( std::string checksum_r, Date timestamp_r )
113  : _pimpl( new Impl() )
114  {
115  _pimpl->assignFromCtor( std::move(checksum_r), std::move(timestamp_r) );
116  }
117 
119  {}
120 
122  {
123  RepoStatus ret;
124  std::ifstream file( path_r.c_str() );
125  if ( !file )
126  {
127  WAR << "No cookie file " << path_r << endl;
128  }
129  else
130  {
131  // line := "[checksum] time_t"
132  std::string line( str::getline( file ) );
133  ret._pimpl->_timestamp = Date( str::strtonum<time_t>( str::stripLastWord( line ) ) );
134  ret._pimpl->_checksum = line;
135  }
136  return ret;
137  }
138 
139  void RepoStatus::saveToCookieFile( const Pathname & path_r ) const
140  {
141  std::ofstream file(path_r.c_str());
142  if (!file) {
143  ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) );
144  }
145  file << _pimpl->_checksum << " " << (time_t)_pimpl->_timestamp << endl;
146  file.close();
147  }
148 
149  bool RepoStatus::empty() const
150  { return _pimpl->_checksum.empty(); }
151 
153  { return _pimpl->_timestamp; }
154 
155  std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
156  { return str << *obj._pimpl; }
157 
158  RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
159  {
160  RepoStatus result;
161 
162  if ( lhs.empty() )
163  result = rhs;
164  else if ( rhs.empty() )
165  result = lhs;
166  else
167  {
168  // order strings to assert && is kommutativ
169  std::string lchk( lhs._pimpl->_checksum );
170  std::string rchk( rhs._pimpl->_checksum );
171  std::stringstream ss( lchk < rchk ? lchk+rchk : rchk+lchk );
172 
173  result._pimpl->_checksum = CheckSum::sha1(ss).checksum();
174  result._pimpl->_timestamp = std::max( lhs._pimpl->_timestamp, rhs._pimpl->_timestamp );
175  }
176  return result;
177  }
178 
179  bool operator==( const RepoStatus & lhs, const RepoStatus & rhs )
180  { return lhs._pimpl->_checksum == rhs._pimpl->_checksum; }
181 
183 } // namespace zypp
zypp::filesystem::PathInfo::mtime
time_t mtime() const
Definition: PathInfo.h:376
zypp::RepoStatus::Impl::recursive_timestamp
static void recursive_timestamp(const Pathname &dir_r, time_t &max_r)
Recursive computation of max dir timestamp.
Definition: RepoStatus.cc:53
zypp::RepoStatus::Impl::assignFromCtor
void assignFromCtor(std::string &&checksum_r, Date &&timestamp_r)
Definition: RepoStatus.cc:41
zypp::filesystem::readdir
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:584
zypp::RepoStatus
Track changing files or directories.
Definition: RepoStatus.h:38
RepoStatus.h
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
PathInfo.h
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:281
zypp::Exception
Base class for Exception.
Definition: Exception.h:145
zypp::RepoStatus::Impl::clone
Impl * clone() const
clone for RWCOW_pointer
Definition: RepoStatus.cc:74
zypp::RepoStatus::~RepoStatus
~RepoStatus()
Dtor.
Definition: RepoStatus.cc:118
zypp::RepoStatus::empty
bool empty() const
Whether the status is empty (default constucted)
Definition: RepoStatus.cc:149
zypp::RepoStatus::Impl::_timestamp
Date _timestamp
Definition: RepoStatus.cc:35
zypp::operator==
bool operator==(const SetRelation::Enum &lhs, const SetCompare &rhs)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SetRelationMixin.h:84
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition: PathInfo.h:290
zypp::RepoStatus::saveToCookieFile
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
Definition: RepoStatus.cc:139
zypp::filesystem::PathInfo::LSTAT
Definition: PathInfo.h:226
zypp::CheckSum::sha1
static CheckSum sha1(const std::string &checksum)
Definition: CheckSum.h:75
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
zypp::CheckSum::sha1FromString
static CheckSum sha1FromString(const std::string &input_r)
Definition: CheckSum.h:105
zypp::filesystem::sha1sum
std::string sha1sum(const Pathname &file)
Compute a files sha1sum.
Definition: PathInfo.cc:989
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition: Pathname.h:110
zypp::RepoStatus::Impl
RepoStatus implementation.
Definition: RepoStatus.cc:31
Logger.h
WAR
#define WAR
Definition: Logger.h:80
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition: PathInfo.h:289
zypp::RepoStatus::RepoStatus
RepoStatus()
Default ctor.
Definition: RepoStatus.cc:89
zypp::filesystem::checksum
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition: PathInfo.cc:999
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition: String.h:286
zypp::RepoStatus::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const RepoStatus::Impl &obj)
Definition: RepoStatus.cc:80
zypp::operator&&
RepoStatus operator&&(const RepoStatus &lhs, const RepoStatus &rhs)
Definition: RepoStatus.cc:158
zypp::str::getline
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:469
zypp::str::stripLastWord
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:287
zypp::RepoStatus::fromCookieFile
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Definition: RepoStatus.cc:121
zypp::CheckSum::checksum
std::string checksum() const
Definition: CheckSum.cc:170
zypp::RepoStatus::timestamp
Date timestamp() const
The time the data were changed the last time.
Definition: RepoStatus.cc:152
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
zypp::Date
Store and operate on date (time_t).
Definition: Date.h:32
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
zypp::RepoStatus::Impl::_checksum
std::string _checksum
Definition: RepoStatus.cc:34
String.h
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:44
str
String related utilities and Regular expression matching.
zypp::RepoStatus::_pimpl
RWCOW_pointer< Impl > _pimpl
Implementation.
Definition: RepoStatus.h:83
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91