libzypp: zypp/RepoStatus.cc Source File

libzypp 17.38.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 <optional>
16#include <set>
17#include <zypp-core/base/Logger.h>
18#include <zypp-core/base/String.h>
19#include <zypp/RepoStatus.h>
20#include <zypp/RepoInfo.h>
21#include <zypp/PathInfo.h>
22
23using std::endl;
24
26namespace zypp
27{
29 namespace
30 {
32 void recursiveTimestamp( const Pathname & dir_r, time_t & max_r )
33 {
34 std::list<std::string> dircontent;
35 if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 )
36 return; // readdir logged the error
37
38 for_( it, dircontent.begin(), dircontent.end() )
39 {
40 PathInfo pi( dir_r + *it, PathInfo::LSTAT );
41 if ( pi.isDir() )
42 {
43 if ( pi.mtime() > max_r )
44 max_r = pi.mtime();
45 recursiveTimestamp( pi.path(), max_r );
46 }
47 }
48 }
49 } // namespace
51
53 //
54 // CLASS NAME : RepoStatus::Impl
55 //
57 struct RepoStatus::Impl
58 {
59 using Checksums = std::set<std::string>;
60
61 public:
69 void assignFromCtor( std::string && checksum_r, Date && timestamp_r )
70 {
71 if ( !checksum_r.empty() ) {
72 static const std::string magic( "43" );
73 checksum_r += magic;
74 _checksums.insert( std::move(checksum_r) );
75 }
76 _timestamp = std::move(timestamp_r);
77 }
78
80 void inject( std::string && checksum_r, Date && timestamp_r )
81 {
82 if ( !checksum_r.empty() ) {
83 _checksums.insert( std::move(checksum_r) );
84 _cachedchecksum.reset();
85 }
86
87 if ( timestamp_r > _timestamp )
88 _timestamp = std::move(timestamp_r);
89 }
90
92 void injectFrom( const Impl & rhs )
93 {
94 if ( &rhs == this ) // no self insert
95 return;
96
97 if ( !rhs._checksums.empty() ) {
98 _checksums.insert( rhs._checksums.begin(), rhs._checksums.end() );
99 _cachedchecksum.reset();
100 }
101
102 if ( rhs._timestamp > _timestamp )
103 _timestamp = rhs._timestamp;
104 }
105
106 bool empty() const
107 { return _checksums.empty(); }
108
109 std::string checksum() const
110 {
111 std::string ret;
112 if ( _checksums.empty() )
113 return ret;
114
115 if ( _checksums.size() == 1 )
116 ret = *_checksums.begin();
117 else {
118 if ( !_cachedchecksum ) {
119 std::stringstream ss;
120 for ( std::string_view c : _checksums )
121 ss << c;
122 _cachedchecksum = CheckSum::sha256(ss).checksum();
123 }
124 ret = *_cachedchecksum;
125 }
126 return ret;
127 }
128
129 Date timestamp() const
130 { return _timestamp; }
131
133 std::ostream & dumpOn( std::ostream & str ) const
134 { return str << ( empty() ? "NO_REPOSTATUS" : checksum() ) << " " << time_t(_timestamp); }
135
136 public:
137 void assignFromCookieFile( const Pathname & path_r, bool useMtime_r = false )
138 {
139 std::ifstream file( path_r.c_str() );
140 if ( not file ) {
141 WAR << "No cookie file " << path_r << endl;
142 return;
143 }
144 // line := "[checksum] time_t" !!! ALWAYS strip time from line
145 std::string line { str::getline( file ) };
146 const std::string & time { str::stripLastWord( line ) };
147
148 Date stmp { useMtime_r ? PathInfo( path_r ).mtime() : str::strtonum<time_t>( time ) };
149 inject( std::move(line), std::move(stmp) ); // raw inject to avoid magic being added
150 }
151
152 private:
153 Checksums _checksums;
154 Date _timestamp;
155
156 mutable std::optional<std::string> _cachedchecksum;
157
158 private:
159 friend Impl * rwcowClone<Impl>( const Impl * rhs );
161 Impl * clone() const
162 { return new Impl( *this ); }
163 };
164
165
167 //
168 // CLASS NAME : RepoStatus
169 //
171
172 RepoStatus::RepoStatus()
173 : _pimpl( new Impl() )
174 {}
175
176 RepoStatus::RepoStatus( const Pathname & path_r )
177 : _pimpl( new Impl() )
178 {
179 PathInfo info( path_r );
180 if ( info.isExist() )
181 {
182 if ( info.isFile() )
183 {
184 _pimpl->assignFromCtor( filesystem::checksum( path_r, "SHA256" ), Date( info.mtime() ) );
185 }
186 else if ( info.isDir() )
187 {
188 time_t t = info.mtime();
189 recursiveTimestamp( path_r, t );
190 _pimpl->assignFromCtor( CheckSum::sha256FromString( str::numstring( t ) ).checksum(), Date( t ) );
191 }
192 }
193 }
194
195 RepoStatus::RepoStatus( const RepoInfo & info_r )
196 : _pimpl( new Impl() )
197 {
198 _pimpl->assignFromCtor( CheckSum::sha256FromString( info_r.repoStatusString() ).checksum(), Date() );
199 }
200
201 RepoStatus::RepoStatus( std::string checksum_r, Date timestamp_r )
202 : _pimpl( new Impl() )
203 {
204 _pimpl->assignFromCtor( std::move(checksum_r), std::move(timestamp_r) );
205 }
206
207 RepoStatus::~RepoStatus()
208 {}
209
210 RepoStatus RepoStatus::fromCookieFile( const Pathname & path_r )
211 {
212 RepoStatus ret;
213 ret._pimpl->assignFromCookieFile( path_r );
214 return ret;
215 }
216
217 RepoStatus RepoStatus::fromCookieFileUseMtime( const Pathname & path_r )
218 {
219 RepoStatus ret;
220 ret._pimpl->assignFromCookieFile( path_r, /*useMtime*/true );
221 return ret;
222 }
223
224 void RepoStatus::saveToCookieFile( const Pathname & path_r ) const
225 {
226 std::ofstream file(path_r.c_str());
227 if (!file) {
228 ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) );
229 }
230 file << _pimpl->checksum() << " " << time_t(_pimpl->timestamp()) << endl;
231 file.close();
232 }
233
234 bool RepoStatus::empty() const
235 { return _pimpl->empty(); }
236
237 Date RepoStatus::timestamp() const
238 { return _pimpl->timestamp(); }
239
240 std::ostream & operator<<( std::ostream & str, const RepoStatus & obj )
241 { return obj._pimpl->dumpOn( str ); }
242
243 RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs )
244 {
245 RepoStatus result { lhs };
246 result._pimpl->injectFrom( *rhs._pimpl );
247 return result;
248 }
249
250 bool operator==( const RepoStatus & lhs, const RepoStatus & rhs )
251 { return lhs._pimpl->checksum() == rhs._pimpl->checksum(); }
252
254} // namespace zypp
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
Logger.h
WAR
#define WAR
Definition Logger.h:104
RepoInfo.h
RepoStatus.h
String.h
zypp::CheckSum::checksum
std::string checksum() const
Definition CheckSum.cc:170
zypp::CheckSum::sha256
static CheckSum sha256(const std::string &checksum)
Definition CheckSum.h:77
zypp::CheckSum::sha256FromString
static CheckSum sha256FromString(const std::string &input_r)
Definition CheckSum.h:107
zypp::Date
Store and operate on date (time_t).
Definition Date.h:33
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::PathInfo::LSTAT
@ LSTAT
Definition PathInfo.h:231
zypp::RepoInfo
What is known about a repository.
Definition RepoInfo.h:72
zypp::RepoInfo::repoStatusString
std::string repoStatusString() const
A string value to track changes requiring a refresh.
Definition RepoInfo.cc:709
zypp::RepoStatus::fromCookieFileUseMtime
static RepoStatus fromCookieFileUseMtime(const Pathname &path)
Reads the status from a cookie file but uses the files mtime.
Definition RepoStatus.cc:217
zypp::RepoStatus::_pimpl
RWCOW_pointer< Impl > _pimpl
Implementation.
Definition RepoStatus.h:107
zypp::RepoStatus::fromCookieFile
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Definition RepoStatus.cc:210
zypp::RepoStatus::timestamp
Date timestamp() const
The time the data were changed the last time.
Definition RepoStatus.cc:237
zypp::RepoStatus::~RepoStatus
~RepoStatus()
Dtor.
Definition RepoStatus.cc:207
zypp::RepoStatus::empty
bool empty() const
Whether the status is empty (empty checksum).
Definition RepoStatus.cc:234
zypp::RepoStatus::RepoStatus
RepoStatus()
Default ctor.
Definition RepoStatus.cc:172
zypp::RepoStatus::saveToCookieFile
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
Definition RepoStatus.cc:224
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::mtime
time_t mtime() const
Definition PathInfo.h:384
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition PathInfo.h:296
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition PathInfo.h:295
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:113
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:94
str
String related utilities and Regular expression matching.
zypp::filesystem::checksum
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition PathInfo.cc:1070
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:624
zypp::str::stripLastWord
std::string stripLastWord(std::string &line, const bool rtrim_first)
Definition String.cc:299
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
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:481
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::operator==
bool operator==(const Capability &lhs, const Capability &rhs)
relates: Capability
Definition Capability.h:309
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition Capabilities.cc:65
zypp::operator&&
RepoStatus operator&&(const RepoStatus &lhs, const RepoStatus &rhs)
relates: RepoStatus Combine two RepoStatus (combined checksum and newest timestamp)
Definition RepoStatus.cc:243
zypp::RepoStatus::Impl
RepoStatus implementation.
Definition RepoStatus.cc:58
zypp::RepoStatus::Impl::timestamp
Date timestamp() const
Definition RepoStatus.cc:129
zypp::RepoStatus::Impl::assignFromCtor
void assignFromCtor(std::string &&checksum_r, Date &&timestamp_r)
Assign data called from RepoStatus ctor (adds magic).
Definition RepoStatus.cc:69
zypp::RepoStatus::Impl::checksum
std::string checksum() const
Definition RepoStatus.cc:109
zypp::RepoStatus::Impl::injectFrom
void injectFrom(const Impl &rhs)
Inject the raw data from rhs.
Definition RepoStatus.cc:92
zypp::RepoStatus::Impl::empty
bool empty() const
Definition RepoStatus.cc:106
zypp::RepoStatus::Impl::assignFromCookieFile
void assignFromCookieFile(const Pathname &path_r, bool useMtime_r=false)
Definition RepoStatus.cc:137
zypp::RepoStatus::Impl::rwcowClone
friend Impl * rwcowClone(const Impl *rhs)
zypp::RepoStatus::Impl::dumpOn
std::ostream & dumpOn(std::ostream &str) const
Dump to log file (not to/from CookieFile).
Definition RepoStatus.cc:133
zypp::RepoStatus::Impl::Checksums
std::set< std::string > Checksums
Definition RepoStatus.cc:59
zypp::RepoStatus::Impl::_cachedchecksum
std::optional< std::string > _cachedchecksum
Definition RepoStatus.cc:156
zypp::RepoStatus::Impl::_checksums
Checksums _checksums
Definition RepoStatus.cc:153
zypp::RepoStatus::Impl::inject
void inject(std::string &&checksum_r, Date &&timestamp_r)
Inject raw data (no magic added).
Definition RepoStatus.cc:80
zypp::RepoStatus::Impl::clone
Impl * clone() const
clone for RWCOW_pointer
Definition RepoStatus.cc:161
zypp::RepoStatus::Impl::_timestamp
Date _timestamp
Definition RepoStatus.cc:154
PathInfo.h