21 #include <zypp-core/base/DefaultIntegral> 23 #include <zypp-media/MediaException> 27 #include <zypp-core/base/UserRequestException> 31 #undef ZYPP_BASE_LOGGER_LOGGROUP 32 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::fetcher" 40 inline void fixup( Pathname & path_r )
42 const std::string & s { path_r.
asString() };
45 if ( s.size() < 4 || s.compare(0, 2,
"./" ) != 0 )
52 while ( pos + 3 <= s.size() && s.compare(pos, 3,
"../") == 0 ) {
61 std::string s { path_r.asString() };
64 size_t original_size = s.size();
65 size_t added_space = count * 4;
66 s.resize(original_size + added_space);
69 size_t tail_start = 2 + (count * 3);
70 size_t tail_length = original_size - tail_start;
71 if (tail_length > 0) {
72 std::copy_backward(s.begin() + tail_start, s.begin() + original_size, s.end());
77 for (
size_t i = 0; i < count; ++i) {
78 s.replace(write_pos, 7,
"%2E%2E/");
117 if ( lhs->location.medianr() == rhs->location.medianr() )
118 return lhs->location.filename() < rhs->location.filename();
120 return lhs->location.medianr() < rhs->location.medianr();
167 return str << obj->location;
194 return a._pathName <
b._pathName;
199 Fetcher::Options
options()
const;
220 static shared_ptr<Impl> _nullimpl(
new Impl );
263 void validate(
const Pathname & localfile_r,
const std::list<FileChecker> & checkers_r );
269 const Pathname &dest_dir, FetcherJob::Flags flags );
284 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
287 {
return new Impl( *
this ); }
290 std::set<FetcherIndex_Ptr,SameFetcherIndex>
_indexes;
332 job->checkers.push_back(checker);
337 _resources.push_back(job);
347 job->checkers.push_back(checker);
353 _resources.push_back(job);
359 if ( _mediaSetAccess )
360 _mediaSetAccess->precacheFiles( {resource} );
365 job->checkers.push_back(checker);
366 _resources.push_back(job);
371 MIL <<
"adding index " << resource << endl;
386 _mediaSetAccess = &media;
396 DBG <<
"Adding fetcher cache: '" << cache_dir <<
"'." << endl;
397 _caches.insert( { cache_dir,
options } );
402 ERR <<
"Not adding cache: '" << cache_dir <<
"'. Not a directory." << endl;
407 WAR <<
"Not adding cache '" << cache_dir <<
"'. Path does not exists." << endl;
419 ManagedFile cacheLocation { destDir_r / inCachePath_r };
421 pMIL(
"file", inCachePath_r,
"found at", destDir_r );
422 return cacheLocation;
425 for(
const CacheInfo & cacheInfo : _caches ) {
426 cacheLocation =
ManagedFile( cacheInfo._pathName / inCachePath_r );
429 pMIL(
"file", inCachePath_r,
"found in cache", cacheInfo._pathName );
432 return cacheLocation;
443 MIL <<
"Checking job [" << localfile_r <<
"] (" << checkers_r.size() <<
" checkers )" << endl;
448 chkfnc( localfile_r );
450 ERR <<
"Invalid checker for '" << localfile_r <<
"'" << endl;
473 auto fnc_addIfInContent( [&](
const std::string & index_r ) ->
bool 482 downloadAndReadIndexList( media, dest_dir );
488 fnc_addIfInContent(
"CHECKSUMS" ) || fnc_addIfInContent(
"SHA1SUMS" );
492 fnc_addIfInContent(
"content" );
501 != _dircontent.end() )
505 std::copy(filled.begin(), filled.end(), std::back_inserter(content));
514 std::copy(tofill.begin(), tofill.end(), std::back_inserter(content));
521 const Pathname &dest_dir, FetcherJob::Flags flags )
525 MIL <<
"Adding directory " << resource.
filename() << endl;
528 getDirectoryContent(media, resource, content);
533 WAR <<
"Skipping subtree hidden at " << resource.
filename() << endl;
539 autoaddIndexes(content, media, resource, dest_dir);
541 for ( filesystem::DirContent::const_iterator it = content.begin();
557 if ( _checksums.find(filename.
asString()) != _checksums.end() )
560 chksm = _checksums[filename.
asString()];
564 WAR <<
"Resource " << filename <<
" has no checksum in the index either." << endl;
574 addDirJobs(media, filename, dest_dir, flags);
587 Pathname finalDestination { destDir_r / inCachePath };
591 scoped_ptr<MediaSetAccess::ReleaseFileGuard> releaseFileGuard;
595 ManagedFile cachedFile = locateInCache( resource, destDir_r, inCachePath );
596 if ( (*cachedFile).empty() ) {
597 pMIL(
"file", inCachePath,
"not found in cache, retrieving..." );
601 candidate = cachedFile;
604 if ( candidate == finalDestination ) {
611 validate( candidate, jobp_r->checkers );
614 if ( candidate == finalDestination )
618 if (
assert_dir( finalDestination.dirname() ) != 0 )
630 WAR <<
"Optional resource " << resource <<
" could not be transferred." << endl;
659 readChecksumsIndex(index, basedir);
660 else if ( index.
basename() ==
"content" )
661 readContentFileIndex(index, basedir);
663 WAR << index <<
": index file format not known" << endl;
671 MIL << index <<
" contains " << reader.
_repoindex->mediaFileChecksums.size() <<
" checksums." << endl;
675 _checksums[(basedir + it->first).
asString()] = it->second;
682 std::ifstream in( index.
c_str() );
686 while (
getline( in, buffer ) )
689 if ( buffer[0] ==
'#' )
696 if ( buffer.empty() )
698 WAR <<
"Missing filename in CHECKSUMS file: " << index.
asString() <<
" (" <<
checksum <<
")" << endl;
711 MIL <<
"downloading index " << resource << endl;
737 fetcher.
start( dest_dir, media );
746 fetcher.
start( dest_dir, media );
753 WAR <<
"No public key specified by user for index '" << keyloc.
filename() <<
"'"<< endl;
757 fetcher.
start( dest_dir, media );
768 if ( _indexes.empty() )
770 MIL <<
"No indexes to read." << endl;
774 for_( it_idx, _indexes.begin(), _indexes.end() )
776 if ( (*it_idx)->read )
778 DBG <<
"Already read index " <<
PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
783 downloadIndex( media, (*it_idx)->location, dest_dir );
785 readIndex( dest_dir + (*it_idx)->location.filename(), (*it_idx)->location.filename().
dirname() );
787 MIL <<
"Remember read index " <<
PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
788 (*it_idx)->read =
true;
791 MIL <<
"done reading indexes" << endl;
797 if ( !_mediaSetAccess )
799 start( dest_dir, *_mediaSetAccess, progress );
808 _mediaSetAccess =
nullptr;
811 progress.
sendTo(progress_receiver);
813 downloadAndReadIndexList(media, dest_dir);
820 addDirJobs(media, location, dest_dir, jobp->flags);
834 getDirectoryContent(media, jobp->location.filename().dirname(), content);
837 MIL <<
"Autodiscovering signed indexes on '" 838 << jobp->location.filename().dirname() <<
"' for '" 839 << jobp->location.filename() <<
"'" << endl;
841 autoaddIndexes(content, media, jobp->location.filename().dirname(), dest_dir);
845 getDirectoryContent(media,
Pathname(
"/"), content);
848 MIL <<
"Autodiscovering signed indexes on '" 850 << jobp->location.filename() <<
"'" << endl;
852 autoaddIndexes(content, media,
Pathname(
"/"), dest_dir);
857 if ( jobp->location.checksum().empty() )
859 if ( _checksums.find(jobp->location.filename().asString())
860 != _checksums.end() )
862 CheckSum chksm = _checksums[jobp->location.filename().asString()];
864 jobp->checkers.push_back(digest_check);
874 jobp->checkers.push_back(digest_check);
882 jobp->checkers.push_back(digest_check);
887 provideToDest( media, dest_dir, jobp );
889 if ( ! progress.incr() )
897 for ( std::list<FetcherJob_Ptr>::const_iterator it_res = obj.
_resources.begin(); it_res != obj.
_resources.end(); ++it_res )
992 fixup( remotePath_r );
void consumeIndex(const parser::susetags::RepoIndex_Ptr &data_r)
std::set< CacheInfo > _caches
void readContentFileIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for content file
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
void setOptions(Options options)
Set the Fetcher options.
Listentry returned by readdir.
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Checks for the validity of a signature.
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
FetcherJob & operator=(const FetcherJob &)=default
void addIndex(const OnMediaLocation &resource)
Adds an index containing metadata (for example checksums ) that will be retrieved and read before the...
parser::susetags::RepoIndex_Ptr _repoindex
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
ZYPP_DECLARE_OPERATORS_FOR_FLAGS(DiskUsageCounter::MountPoint::HintFlags)
const char * c_str() const
String representation.
String related utilities and Regular expression matching.
void provideToDest(MediaSetAccess &media_r, const Pathname &destDir_r, const FetcherJob_Ptr &jobp_r)
Provide the resource to dest_dir.
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
std::string getline(std::istream &str)
Read one line from stream.
void addCachePath(const Pathname &cache_dir)
adds a directory to the list of directories where to look for cached files
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
If a content file is found, it is downloaded and read.
std::string basename() const
Return the last component of this path.
static Pathname mapToCachePath(Pathname remotePath_r)
Map a resource filename to a local path below a destDir.
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory and always check for checksums.
OnMediaLocation location
Index localtion.
std::list< DirEntry > DirContent
Returned by readdir.
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
std::list< FileChecker > checkers
shared_ptr< FetcherJob > FetcherJob_Ptr
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
static shared_ptr< Impl > nullimpl()
Offer default Impl.
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
void remember(const Exception &old_r)
Store an other Exception as history.
void setMediaSetAccess(MediaSetAccess &media)
Sets the media set access that will be used to precache and to download the files when start is calle...
void start(const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
start the transfer to a destination directory dest_dir The media has to be provides with setMediaSetA...
Impl & operator=(const Impl &)=delete
bool operator()(const FetcherIndex_Ptr &lhs, const FetcherIndex_Ptr &rhs) const
std::set< FetcherIndex_Ptr, SameFetcherIndex > _indexes
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void addCachePath(const Pathname &cache_dir, Fetcher::CacheOptions options)
FetcherJob(const FetcherJob &)=default
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Fetcher::Options _options
const std::string & asString() const
String representation.
void setMediaSetAccess(MediaSetAccess &media)
bool isExist() const
Return whether valid stat info exists.
friend bool operator<(const CacheInfo &a, const CacheInfo &b)
void reset()
Reset the transfer (jobs) list.
MediaSetAccess * _mediaSetAccess
Pathname dirname() const
Return all but the last component od this path.
void readIndex(const Pathname &index, const Pathname &basedir)
reads a downloaded index file and updates internal attributes table
Parse repoindex part from a content file.
FetcherJob(const OnMediaLocation &loc)
std::set ordering (less semantic)
Fetcher::Options options() const
Maintain [min,max] and counter (value) for progress counting.
void enqueueDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
friend std::ostream & operator<<(std::ostream &str, const Fetcher &obj)
relates: Fetcher Stream output
DefaultIntegral< bool, false > read
Whether we read this index.
std::map< std::string, filesystem::DirContent > _dircontent
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Enqueue a object for transferal, they will not be transferred until start() is called.
void downloadIndex(MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
download the indexes and reads them
std::list< FetcherJob_Ptr > _resources
void start(const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress)
int unlink(const Pathname &path)
Like 'unlink'.
void resetDispose()
Set no dispose function.
void enqueueDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory.
void validate(const Pathname &localfile_r, const std::list< FileChecker > &checkers_r)
Validates the provided file against its checkers.
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
ZYPP_DECLARE_FLAGS(Flags, Flag)
shared_ptr< FetcherIndex > FetcherIndex_Ptr
void getDirectoryContent(MediaSetAccess &media, const OnMediaLocation &resource, filesystem::DirContent &content)
reads the content of a directory but keeps a cache
If a CHECKSUMS file is found, it is downloaded and read.
void setDispose(const Dispose &dispose_r)
Set a new dispose function.
ZYpp::Ptr getZYpp()
relates: ZYppFactory Convenience to get the Pointer to the ZYpp instance.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Class to encapsulate the OnMediaLocation object and the FileChecker together.
void setOptions(Fetcher::Options options)
FetcherIndex(const OnMediaLocation &loc)
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
void readChecksumsIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for CHECKSUMS file
void downloadAndReadIndexList(MediaSetAccess &media, const Pathname &dest_dir)
download the indexes and reads them
Base class for Exception.
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
std::map< std::string, CheckSum > _checksums
Wrapper class for ::stat/::lstat.
ManagedFile locateInCache(const OnMediaLocation &resource_r, const Pathname &destDir_r, const Pathname &inCachePath_r)
Tries to locate the file represented by the job by looking at it's final destination first and at the...
class that represents indexes which add metadata to fetcher jobs and therefore need to be retrieved i...
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
function< void(const Pathname &file)> FileChecker
Functor signature used to check files.
Options options() const
Get current options.
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Enqueue a object for transferal, they will not be transferred until start() is called.
Easy-to use interface to the ZYPP dependency resolver.
std::string sprint(Args &&... args)
Print words as string.
void autoaddIndexes(const filesystem::DirContent &content, MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
auto discovery and reading of indexes
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
virtual void parse(const InputStream &imput_r, const ProgressData::ReceiverFnc &fnc_r=ProgressData::ReceiverFnc())
Parse the stream.
This class allows to retrieve a group of files in a confortable way, providing some smartness that do...
Fetcher::CacheOptions _options
void addIndex(const OnMediaLocation &resource)
bool is_checksum(const Pathname &file, const CheckSum &checksum)
check files checksum
void addDirJobs(MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir, FetcherJob::Flags flags)
scan the directory and adds the individual jobs
friend std::ostream & operator<<(std::ostream &str, const Fetcher::Impl &obj)
relates: Fetcher::Impl Stream output
Impl * clone() const
clone for RWCOW_pointer
RepoManager::RefreshServiceOptions _options