libzypp  17.25.6
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 <set>
16 #include <zypp/base/Logger.h>
17 #include <zypp/base/String.h>
18 #include <zypp/RepoStatus.h>
19 #include <zypp/RepoInfo.h>
20 #include <zypp/PathInfo.h>
21 
22 using std::endl;
23 
25 namespace zypp
26 {
28  namespace
29  {
31  void recursiveTimestamp( const Pathname & dir_r, time_t & max_r )
32  {
33  std::list<std::string> dircontent;
34  if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 )
35  return; // readdir logged the error
36 
37  for_( it, dircontent.begin(), dircontent.end() )
38  {
39  PathInfo pi( dir_r + *it, PathInfo::LSTAT );
40  if ( pi.isDir() )
41  {
42  if ( pi.mtime() > max_r )
43  max_r = pi.mtime();
44  recursiveTimestamp( pi.path(), max_r );
45  }
46  }
47  }
48  } // namespace
50 
52  //
53  // CLASS NAME : RepoStatus::Impl
54  //
57  {
58  using Checksums = std::set<std::string>;
59 
60  public:
68  void assignFromCtor( std::string && checksum_r, Date && timestamp_r )
69  {
70  if ( !checksum_r.empty() ) {
71  static const std::string magic( "43" );
72  checksum_r += magic;
73  _checksums.insert( std::move(checksum_r) );
74  }
75  _timestamp = std::move(timestamp_r);
76  }
77 
79  void inject( std::string && checksum_r, Date && timestamp_r )
80  {
81  if ( !checksum_r.empty() ) {
82  _checksums.insert( std::move(checksum_r) );
83  _cachedchecksum.reset();
84  }
85 
86  if ( timestamp_r > _timestamp )
87  _timestamp = timestamp_r;
88  }
89 
91  void injectFrom( const Impl & rhs )
92  {
93  if ( &rhs == this ) // no self insert
94  return;
95 
96  if ( !rhs._checksums.empty() ) {
97  _checksums.insert( rhs._checksums.begin(), rhs._checksums.end() );
98  _cachedchecksum.reset();
99  }
100 
101  if ( rhs._timestamp > _timestamp )
102  _timestamp = rhs._timestamp;
103  }
104 
105  bool empty() const
106  { return _checksums.empty(); }
107 
108  std::string checksum() const
109  {
110  std::string ret;
111  if ( _checksums.empty() )
112  return ret;
113 
114  if ( _checksums.size() == 1 )
115  ret = *_checksums.begin();
116  else {
117  if ( !_cachedchecksum ) {
118  std::stringstream ss;
119  for ( std::string_view c : _checksums )
120  ss << c;
122  }
123  ret = *_cachedchecksum;
124  }
125  return ret;
126  }
127 
128  Date timestamp() const
129  { return _timestamp; }
130 
132  std::ostream & dumpOn( std::ostream & str ) const
133  { return str << ( empty() ? "NO_REPOSTATUS" : checksum() ) << " " << time_t(_timestamp); }
134 
135  private:
138 
139  mutable std::optional<std::string> _cachedchecksum;
140 
141  private:
142  friend Impl * rwcowClone<Impl>( const Impl * rhs );
144  Impl * clone() const
145  { return new Impl( *this ); }
146  };
148 
150  //
151  // CLASS NAME : RepoStatus
152  //
154 
156  : _pimpl( new Impl() )
157  {}
158 
160  : _pimpl( new Impl() )
161  {
162  PathInfo info( path_r );
163  if ( info.isExist() )
164  {
165  if ( info.isFile() )
166  {
167  _pimpl->assignFromCtor( filesystem::sha1sum( path_r ), Date( info.mtime() ) );
168  }
169  else if ( info.isDir() )
170  {
171  time_t t = info.mtime();
172  recursiveTimestamp( path_r, t );
174  }
175  }
176  }
177 
179  : _pimpl( new Impl() )
180  {
182  }
183 
184  RepoStatus::RepoStatus( std::string checksum_r, Date timestamp_r )
185  : _pimpl( new Impl() )
186  {
187  _pimpl->assignFromCtor( std::move(checksum_r), std::move(timestamp_r) );
188  }
189 
191  {}
192 
194  {
195  RepoStatus ret;
196  std::ifstream file( path_r.c_str() );
197  if ( !file )
198  {
199  WAR << "No cookie file " << path_r << endl;
200  }
201  else
202  {
203  // line := "[checksum] time_t" !!! strip time from line
204  std::string line { str::getline( file ) };
205  Date stmp { str::strtonum<time_t>( str::stripLastWord( line ) ) };
206  ret._pimpl->inject( std::move(line), std::move(stmp) ); // raw inject to avoid magic being added
207  }
208  return ret;
209  }
210 
211  void RepoStatus::saveToCookieFile( const Pathname & path_r ) const
212  {
213  std::ofstream file(path_r.c_str());
214  if (!file) {
215  ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) );
216  }
217  file << _pimpl->checksum() << " " << time_t(_pimpl->timestamp()) << endl;
218  file.close();
219  }
220 
221  bool RepoStatus::empty() const
222  { return _pimpl->empty(); }
223 
225  { return _pimpl->timestamp(); }
226 
227  std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
228  { return obj._pimpl->dumpOn( str ); }
229 
230  RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
231  {
232  RepoStatus result { lhs };
233  result._pimpl->injectFrom( *rhs._pimpl );
234  return result;
235  }
236 
237  bool operator==( const RepoStatus & lhs, const RepoStatus & rhs )
238  { return lhs._pimpl->checksum() == rhs._pimpl->checksum(); }
239 
241 } // namespace zypp
std::set< std::string > Checksums
Definition: RepoStatus.cc:58
bool empty() const
Whether the status is empty (empty checksum)
Definition: RepoStatus.cc:221
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
std::string sha1sum(const Pathname &file)
Compute a files sha1sum.
Definition: PathInfo.cc:1003
void injectFrom(const Impl &rhs)
Inject the raw data from rhs.
Definition: RepoStatus.cc:91
std::string checksum() const
Definition: CheckSum.cc:170
void inject(std::string &&checksum_r, Date &&timestamp_r)
Inject raw data (no magic added).
Definition: RepoStatus.cc:79
std::ostream & dumpOn(std::ostream &str) const
Dump to log file (not to/from CookieFile).
Definition: RepoStatus.cc:132
time_t mtime() const
Definition: PathInfo.h:376
const char * c_str() const
String representation.
Definition: Pathname.h:110
String related utilities and Regular expression matching.
What is known about a repository.
Definition: RepoInfo.h:71
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
bool operator==(const SetRelation::Enum &lhs, const SetCompare &rhs)
RepoStatus()
Default ctor.
Definition: RepoStatus.cc:155
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Definition: RepoStatus.cc:193
Url url() const
Pars pro toto: The first repository url.
Definition: RepoInfo.h:131
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
Definition: RepoStatus.cc:211
Store and operate on date (time_t).
Definition: Date.h:32
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:492
void assignFromCtor(std::string &&checksum_r, Date &&timestamp_r)
Assign data called from RepoStatus ctor (adds magic).
Definition: RepoStatus.cc:68
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
const std::string & asString() const
String representation.
Definition: Pathname.h:91
bool isExist() const
Return whether valid stat info exists.
Definition: PathInfo.h:281
#define WAR
Definition: Logger.h:80
Date timestamp() const
Definition: RepoStatus.cc:128
std::string getline(std::istream &str, const Trim trim_r)
Return stream content up to (but not returning) the next newline.
Definition: String.cc:478
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition: String.cc:296
std::string numstring(char n, int w=0)
Definition: String.h:286
std::optional< std::string > _cachedchecksum
Definition: RepoStatus.cc:139
RepoStatus implementation.
Definition: RepoStatus.cc:56
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:598
~RepoStatus()
Dtor.
Definition: RepoStatus.cc:190
Base class for Exception.
Definition: Exception.h:145
Date timestamp() const
The time the data were changed the last time.
Definition: RepoStatus.cc:224
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition: PathInfo.cc:1013
RWCOW_pointer< Impl > _pimpl
Implementation.
Definition: RepoStatus.h:88
Impl * clone() const
clone for RWCOW_pointer
Definition: RepoStatus.cc:144
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
static CheckSum sha1(const std::string &checksum)
Definition: CheckSum.h:75
Track changing files or directories.
Definition: RepoStatus.h:40
RepoStatus operator &&(const RepoStatus &lhs, const RepoStatus &rhs)
Definition: RepoStatus.cc:230
std::string checksum() const
Definition: RepoStatus.cc:108
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
static CheckSum sha1FromString(const std::string &input_r)
Definition: CheckSum.h:105