libzypp 17.38.5
Fetcher.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <fstream>
14#include <list>
15#include <map>
16
17#include <zypp-core/base/Easy.h>
21#include <zypp-core/base/DefaultIntegral>
23#include <zypp-media/MediaException>
24#include <zypp/Fetcher.h>
25#include <zypp/ZYppFactory.h>
26#include <zypp/CheckSum.h>
27#include <zypp-core/base/UserRequestException>
30
31#undef ZYPP_BASE_LOGGER_LOGGROUP
32#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::fetcher"
33
35namespace zypp
36{
37
38 namespace {
39 // Translate leading "./(../)+" to "./(%2E%2E/)+" for Fetcher::mapToCachePath
40 inline void fixup( Pathname & path_r )
41 {
42 const std::string & s { path_r.asString() };
43
44 // 1. Quick exit if string is too short or doesn't start with ./
45 if ( s.size() < 4 || s.compare(0, 2, "./" ) != 0 )
46 return;
47
48 size_t count = 0;
49 size_t pos = 2;
50
51 // 2. Count consecutive "../" sequences
52 while ( pos + 3 <= s.size() && s.compare(pos, 3, "../") == 0 ) {
53 ++count;
54 pos += 3;
55 }
56
57 if (count == 0)
58 return;
59
60 {
61 std::string s { path_r.asString() };
62
63 // 3. Resize string once to avoid multiple reallocations
64 size_t original_size = s.size();
65 size_t added_space = count * 4; // ".."(2) becomes "%2E%2E"(6)
66 s.resize(original_size + added_space);
67
68 // 4. Move the 'tail' of the string to the new end
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());
73 }
74
75 // 5. Fill the gap with %2E%2E/
76 size_t write_pos = 2;
77 for (size_t i = 0; i < count; ++i) {
78 s.replace(write_pos, 7, "%2E%2E/");
79 write_pos += 7;
80 }
81
82 path_r = s;
83 }
84 }
85 } // namespace
86
102
104
107 {
108 bool operator()( const FetcherIndex_Ptr & lhs, const FetcherIndex_Ptr & rhs ) const
109 {
110 if ( lhs == rhs )
111 return false; // incl. NULL == NULL
112 if ( ! lhs )
113 return true; // NULL < nonNULL
114 if ( ! rhs )
115 return false; // nonNULL > NULL
116 // both nonNULL ==> compare medianr and path
117 if ( lhs->location.medianr() == rhs->location.medianr() )
118 return lhs->location.filename() < rhs->location.filename();
119 //else
120 return lhs->location.medianr() < rhs->location.medianr();
121 }
122 };
123
129 {
130 enum Flag
131 {
132 None = 0x0000,
133 Directory = 0x0001,
134 Recursive = 0x0002,
136 // check checksums even if there is no such
137 // checksum (warns of no checksum)
139 };
141
142 FetcherJob(const FetcherJob &) = default;
143 FetcherJob(FetcherJob &&) = default;
144 FetcherJob &operator=(const FetcherJob &) = default;
146
148 //MIL << location << endl;
149 }
150
152 {
153 //MIL << location << " | * " << checkers.size() << endl;
154 }
155
157 //CompositeFileChecker checkers;
158 std::list<FileChecker> checkers;
159 Flags flags;
160 };
161
164
165 std::ostream & operator<<( std::ostream & str, const FetcherJob_Ptr & obj )
166 {
167 return str << obj->location;
168 }
169
171 //
172 // CLASS NAME : Fetcher::Impl
173 //
176 {
177 friend std::ostream & operator<<( std::ostream & str, const Fetcher::Impl & obj );
178
179 public:
180 Impl();
181
182 Impl(const Impl &) = default;
183 Impl(Impl &&) = delete;
184 Impl &operator=(const Impl &) = delete;
185 Impl &operator=(Impl &&) = delete;
186
187 ~Impl() {}
188
189 struct CacheInfo{
192
193 friend bool operator<( const CacheInfo &a, const CacheInfo & b) {
194 return a._pathName < b._pathName;
195 }
196 };
197
198 void setOptions( Fetcher::Options options );
199 Fetcher::Options options() const;
200
201 void addIndex( const OnMediaLocation &resource );
202
203 void enqueueDir( const OnMediaLocation &resource, bool recursive, const FileChecker &checker = FileChecker() );
204 void enqueueDigestedDir( const OnMediaLocation &resource, bool recursive, const FileChecker &checker = FileChecker() );
205
206 void enqueue( const OnMediaLocation &resource, const FileChecker &checker = FileChecker() );
207 void enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker = FileChecker() );
208 void addCachePath( const Pathname &cache_dir, Fetcher::CacheOptions options );
209 void reset();
211 void start( const Pathname &dest_dir,
212 const ProgressData::ReceiverFnc &progress );
213 void start( const Pathname &dest_dir,
215 const ProgressData::ReceiverFnc & progress_receiver );
216
219 {
220 static shared_ptr<Impl> _nullimpl( new Impl );
221 return _nullimpl;
222 }
223 private:
227 void downloadAndReadIndexList( MediaSetAccess &media, const Pathname &dest_dir);
228
232 void downloadIndex( MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir);
233
241 void readIndex( const Pathname &index, const Pathname &basedir );
242
244 void readChecksumsIndex( const Pathname &index, const Pathname &basedir );
245
247 void readContentFileIndex( const Pathname &index, const Pathname &basedir );
248
251
258 ManagedFile locateInCache( const OnMediaLocation & resource_r, const Pathname & destDir_r, const Pathname & inCachePath_r );
263 void validate( const Pathname & localfile_r, const std::list<FileChecker> & checkers_r );
264
268 void addDirJobs( MediaSetAccess &media, const OnMediaLocation &resource,
269 const Pathname &dest_dir, FetcherJob::Flags flags );
270
274 void autoaddIndexes( const filesystem::DirContent &content,
276 const OnMediaLocation &resource,
277 const Pathname &dest_dir );
281 void provideToDest( MediaSetAccess & media_r, const Pathname & destDir_r , const FetcherJob_Ptr & jobp_r );
282
283 private:
284 friend Impl * rwcowClone<Impl>( const Impl * rhs );
286 Impl * clone() const
287 { return new Impl( *this ); }
288
289 std::list<FetcherJob_Ptr> _resources;
290 std::set<FetcherIndex_Ptr,SameFetcherIndex> _indexes;
291 std::set<CacheInfo> _caches;
292 // checksums read from the indexes
293 std::map<std::string, CheckSum> _checksums;
294 // cache of dir contents
295 std::map<std::string, filesystem::DirContent> _dircontent;
296
298
299 Fetcher::Options _options;
300 };
301
302
304 {
305 if ( _mediaSetAccess )
306 _mediaSetAccess->precacheFiles( {resource} );
307
308 FetcherJob_Ptr job;
309 job.reset(new FetcherJob(resource));
311 _resources.push_back(job);
312 }
313
315 : _options(0)
316 {
317 }
318
319 void Fetcher::Impl::setOptions( Fetcher::Options options )
320 { _options = options; }
321
322 Fetcher::Options Fetcher::Impl::options() const
323 { return _options; }
324
326 bool recursive,
327 const FileChecker &checker )
328 {
329 FetcherJob_Ptr job;
330 job.reset(new FetcherJob(resource));
331 if ( checker )
332 job->checkers.push_back(checker);
333 if ( recursive )
334 job->flags |= FetcherJob::Recursive;
335 job->flags |= FetcherJob::Directory;
336
337 _resources.push_back(job);
338 }
339
341 bool recursive,
342 const FileChecker &checker )
343 {
344 FetcherJob_Ptr job;
345 job.reset(new FetcherJob(resource));
346 if ( checker )
347 job->checkers.push_back(checker);
348 if ( recursive )
349 job->flags |= FetcherJob::Recursive;
350 job->flags |= FetcherJob::Directory;
352
353 _resources.push_back(job);
354
355 }
356
357 void Fetcher::Impl::enqueue( const OnMediaLocation &resource, const FileChecker &checker )
358 {
359 if ( _mediaSetAccess )
360 _mediaSetAccess->precacheFiles( {resource} );
361
362 FetcherJob_Ptr job;
363 job.reset(new FetcherJob(resource));
364 if ( checker )
365 job->checkers.push_back(checker);
366 _resources.push_back(job);
367 }
368
370 {
371 MIL << "adding index " << resource << endl;
372 _indexes.insert(FetcherIndex_Ptr(new FetcherIndex(resource)));
373 }
374
375
377 {
378 _resources.clear();
379 _indexes.clear();
380 _checksums.clear();
381 _dircontent.clear();
382 }
383
388
390 {
391 PathInfo info(cache_dir);
392 if ( info.isExist() )
393 {
394 if ( info.isDir() )
395 {
396 DBG << "Adding fetcher cache: '" << cache_dir << "'." << endl;
397 _caches.insert( { cache_dir, options } );
398 }
399 else
400 {
401 // don't add bad cache directory, just log the error
402 ERR << "Not adding cache: '" << cache_dir << "'. Not a directory." << endl;
403 }
404 }
405 else
406 {
407 WAR << "Not adding cache '" << cache_dir << "'. Path does not exists." << endl;
408 }
409
410 }
411
412 ManagedFile Fetcher::Impl::locateInCache( const OnMediaLocation & resource_r, const Pathname & destDir_r, const Pathname & inCachePath_r )
413 {
414 // No checksum - no match
415 if ( resource_r.checksum().empty() )
416 return {};
417
418 // first check in the final destination
419 ManagedFile cacheLocation { destDir_r / inCachePath_r };
420 if ( PathInfo(cacheLocation).isExist() && is_checksum( cacheLocation, resource_r.checksum() ) ) {
421 pMIL( "file", inCachePath_r, "found at", destDir_r );
422 return cacheLocation;
423 }
424
425 for( const CacheInfo & cacheInfo : _caches ) {
426 cacheLocation = ManagedFile( cacheInfo._pathName / inCachePath_r );
427 if ( PathInfo(cacheLocation).isExist() && is_checksum( cacheLocation, resource_r.checksum() ) )
428 {
429 pMIL( "file", inCachePath_r, "found in cache", cacheInfo._pathName );
430 if ( cacheInfo._options & Fetcher::CleanFiles )
431 cacheLocation.setDispose( filesystem::unlink );
432 return cacheLocation;
433 }
434 }
435
436 return {};
437 }
438
439 void Fetcher::Impl::validate( const Pathname & localfile_r, const std::list<FileChecker> & checkers_r )
440 {
441 try
442 {
443 MIL << "Checking job [" << localfile_r << "] (" << checkers_r.size() << " checkers )" << endl;
444
445 for ( const FileChecker & chkfnc : checkers_r )
446 {
447 if ( chkfnc )
448 chkfnc( localfile_r );
449 else
450 ERR << "Invalid checker for '" << localfile_r << "'" << endl;
451 }
452
453 }
454 catch ( const FileCheckException &e )
455 {
456 throw; // let known exceptions bypass silently
457 }
458 catch ( const Exception &e )
459 {
460 throw; // slet known exceptions bypass silently
461 }
462 catch (...)
463 {
464 ZYPP_THROW(Exception("Unknown error while validating " + localfile_r.asString()));
465 }
466 }
467
470 const OnMediaLocation &resource,
471 const Pathname &dest_dir )
472 {
473 auto fnc_addIfInContent( [&]( const std::string & index_r ) -> bool
474 {
475 if ( find( content.begin(), content.end(), filesystem::DirEntry(index_r,filesystem::FT_FILE) ) == content.end() )
476 return false;
477 // add the index of this directory
478 OnMediaLocation indexloc( resource );
479 indexloc.changeFilename( resource.filename() + index_r );
480 addIndex( indexloc );
481 // we need to read it now
482 downloadAndReadIndexList( media, dest_dir );
483 return true;
484 } );
485
487 {
488 fnc_addIfInContent( "CHECKSUMS" ) || fnc_addIfInContent( "SHA1SUMS" );
489 }
491 {
492 fnc_addIfInContent( "content" );
493 }
494 }
495
497 const OnMediaLocation &resource,
498 filesystem::DirContent &content )
499 {
500 if ( _dircontent.find(resource.filename().asString())
501 != _dircontent.end() )
502 {
504
505 std::copy(filled.begin(), filled.end(), std::back_inserter(content));
506 }
507 else
508 {
510 media.dirInfo( tofill,
511 resource.filename(),
512 false /* dots */,
513 resource.medianr());
514 std::copy(tofill.begin(), tofill.end(), std::back_inserter(content));
515 _dircontent[resource.filename().asString()] = tofill;
516 }
517 }
518
520 const OnMediaLocation &resource,
521 const Pathname &dest_dir, FetcherJob::Flags flags )
522 {
523 // first get the content of the directory so we can add
524 // individual transfer jobs
525 MIL << "Adding directory " << resource.filename() << endl;
527 try {
528 getDirectoryContent(media, resource, content);
529 }
530 catch ( media::MediaFileNotFoundException & exception )
531 {
532 ZYPP_CAUGHT( exception );
533 WAR << "Skipping subtree hidden at " << resource.filename() << endl;
534 return;
535 }
536
537 // this method test for the option flags so indexes are added
538 // only if the options are enabled
539 autoaddIndexes(content, media, resource, dest_dir);
540
541 for ( filesystem::DirContent::const_iterator it = content.begin();
542 it != content.end();
543 ++it )
544 {
545 // skip CHECKSUMS* as they were already retrieved
546 if ( str::hasPrefix(it->name, "CHECKSUMS") || str::hasPrefix(it->name, "SHA1SUMS") )
547 continue;
548
549 Pathname filename = resource.filename() + it->name;
550
551 switch ( it->type )
552 {
553 case filesystem::FT_NOT_AVAIL: // old directory.yast contains no typeinfo at all
555 {
556 CheckSum chksm(resource.checksum());
557 if ( _checksums.find(filename.asString()) != _checksums.end() )
558 {
559 // the checksum can be replaced with the one in the index.
560 chksm = _checksums[filename.asString()];
561 //MIL << "resource " << filename << " has checksum in the index file." << endl;
562 }
563 else
564 WAR << "Resource " << filename << " has no checksum in the index either." << endl;
565
567 enqueueDigested(OnMediaLocation(filename, resource.medianr()).setChecksum(chksm));
568 else
569 enqueue(OnMediaLocation(filename, resource.medianr()).setChecksum(chksm));
570 break;
571 }
572 case filesystem::FT_DIR: // newer directory.yast contain at least directory info
573 if ( flags & FetcherJob::Recursive )
574 addDirJobs(media, filename, dest_dir, flags);
575 break;
576 default:
577 // don't provide devices, sockets, etc.
578 break;
579 }
580 }
581 }
582
583 void Fetcher::Impl::provideToDest( MediaSetAccess & media_r, const Pathname & destDir_r , const FetcherJob_Ptr & jobp_r )
584 {
585 const OnMediaLocation & resource { jobp_r->location };
586 Pathname inCachePath { mapToCachePath( resource ) }; // Map remote filename to a local path below destDir_r.
587 Pathname finalDestination { destDir_r / inCachePath }; // The full destination path.
588
589 try
590 {
591 scoped_ptr<MediaSetAccess::ReleaseFileGuard> releaseFileGuard; // will take care provided files get released
592 Pathname candidate;
593
594 // Try to get cached file (by checksum) or provide it from media.
595 ManagedFile cachedFile = locateInCache( resource, destDir_r, inCachePath );
596 if ( (*cachedFile).empty() ) {
597 pMIL( "file", inCachePath, "not found in cache, retrieving..." );
599 releaseFileGuard.reset( new MediaSetAccess::ReleaseFileGuard( media_r, resource ) ); // release it when we leave the block
600 } else {
601 candidate = cachedFile;
602 }
603
604 if ( candidate == finalDestination ) {
605 // If we have a match at destFullPath, take care
606 // it gets deleted, in case the validation fails.
607 cachedFile.setDispose( filesystem::unlink );
608 }
609
610 // Validate the file (throws if not valid)
611 validate( candidate, jobp_r->checkers );
612
613 // move it to the final destination
614 if ( candidate == finalDestination )
615 cachedFile.resetDispose(); // keep it!
616 else
617 {
618 if ( assert_dir( finalDestination.dirname() ) != 0 )
619 ZYPP_THROW( Exception( str::sprint( "Can't create", finalDestination.dirname() ) ) );
620
621 if ( filesystem::hardlinkCopy( candidate, finalDestination ) != 0 )
622 ZYPP_THROW( Exception( str::sprint( "Can't hardlink/copy", candidate, "to", finalDestination ) ) );
623 }
624 }
625 catch ( Exception & excpt )
626 {
627 if ( resource.optional() )
628 {
629 ZYPP_CAUGHT( excpt );
630 WAR << "Optional resource " << resource << " could not be transferred." << endl;
631 return;
632 }
633 else
634 {
635 excpt.remember( str::sprint("Can't provide", resource.filename() ) );
636 ZYPP_RETHROW( excpt );
637 }
638 }
639 }
640
641 // helper class to consume a content file
643 {
648
649 void consumeIndex( const parser::susetags::RepoIndex_Ptr & data_r )
650 { _repoindex = data_r; }
651
652 parser::susetags::RepoIndex_Ptr _repoindex;
653 };
654
655 // generic function for reading indexes
656 void Fetcher::Impl::readIndex( const Pathname &index, const Pathname &basedir )
657 {
658 if ( index.basename() == "CHECKSUMS" || index.basename() == "SHA1SUMS" )
659 readChecksumsIndex(index, basedir);
660 else if ( index.basename() == "content" )
661 readContentFileIndex(index, basedir);
662 else
663 WAR << index << ": index file format not known" << endl;
664 }
665
666 // reads a content file index
667 void Fetcher::Impl::readContentFileIndex( const Pathname &index, const Pathname &basedir )
668 {
669 ContentReaderHelper reader;
670 reader.parse(index);
671 MIL << index << " contains " << reader._repoindex->mediaFileChecksums.size() << " checksums." << endl;
672 for_( it, reader._repoindex->mediaFileChecksums.begin(), reader._repoindex->mediaFileChecksums.end() )
673 {
674 // content file entries don't start with /
675 _checksums[(basedir + it->first).asString()] = it->second;
676 }
677 }
678
679 // reads a CHECKSUMS (old SHA1SUMS) file index
680 void Fetcher::Impl::readChecksumsIndex( const Pathname &index, const Pathname &basedir )
681 {
682 std::ifstream in( index.c_str() );
683 if ( ! in.fail() )
684 {
685 std::string buffer;
686 while ( getline( in, buffer ) )
687 {
688
689 if ( buffer[0] == '#' )
690 continue; // simple comment
691
692 CheckSum checksum( str::stripFirstWord( buffer, /*ltrim before strip*/true ) );
693 if ( checksum.empty() )
694 continue; // empty line | unknown cheksum format
695
696 if ( buffer.empty() )
697 {
698 WAR << "Missing filename in CHECKSUMS file: " << index.asString() << " (" << checksum << ")" << endl;
699 continue;
700 }
701
702 _checksums[(basedir/buffer).asString()] = checksum;
703 }
704 }
705 else
706 ZYPP_THROW(Exception("Can't open CHECKSUMS file: " + index.asString()));
707 }
708
710 {
711 MIL << "downloading index " << resource << endl;
712 // create a new fetcher with a different state to transfer the
713 // file containing checksums and its signature
714 Fetcher fetcher;
715 // signature checker for index. We havent got the signature from
716 // the nextwork yet.
717 SignatureFileChecker sigchecker;
718
719 // build the name of the index and the signature
720 const OnMediaLocation& idxloc(resource);
721 OnMediaLocation sigloc(resource);
722 OnMediaLocation keyloc(resource);
723
724 // we should not fail the download if those don't exists
725 // the checking will warn later
726 sigloc.setOptional(true);
727 keyloc.setOptional(true);
728
729 // calculate signature and key name
730 sigloc.changeFilename( sigloc.filename().extend(".asc") );
731 keyloc.changeFilename( keyloc.filename().extend(".key") );
732
733 //assert_dir(dest_dir + idxloc.filename().dirname());
734
735 // transfer the signature
736 fetcher.enqueue(sigloc);
737 fetcher.start( dest_dir, media );
738 // if we get the signature, update the checker
739 if ( PathInfo(dest_dir + sigloc.filename()).isExist() )
740 sigchecker = SignatureFileChecker(dest_dir + sigloc.filename());
741
742 fetcher.reset();
743
744 // now the key
745 fetcher.enqueue(keyloc);
746 fetcher.start( dest_dir, media );
747 fetcher.reset();
748
749 // try to import the key
750 if ( PathInfo(dest_dir + keyloc.filename()).isExist() )
751 getZYpp()->keyRing()->importKey(PublicKey(dest_dir + keyloc.filename()), false);
752 else
753 WAR << "No public key specified by user for index '" << keyloc.filename() << "'"<< endl;
754
755 // now the index itself
756 fetcher.enqueue( idxloc, FileChecker(sigchecker) );
757 fetcher.start( dest_dir, media );
758 fetcher.reset();
759 }
760
761 // this method takes all the user pointed indexes, gets them and also tries to
762 // download their signature, and verify them. After that, it parses each one
763 // to fill the checksum cache.
765 {
766 // if there is no indexes, then just return to avoid
767 // the directory listing
768 if ( _indexes.empty() )
769 {
770 MIL << "No indexes to read." << endl;
771 return;
772 }
773
774 for_( it_idx, _indexes.begin(), _indexes.end() )
775 {
776 if ( (*it_idx)->read )
777 {
778 DBG << "Already read index " << PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
779 }
780 else
781 {
782 // base::LogControl::TmpLineWriter shutUp;
783 downloadIndex( media, (*it_idx)->location, dest_dir );
784 // now we have the indexes in dest_dir
785 readIndex( dest_dir + (*it_idx)->location.filename(), (*it_idx)->location.filename().dirname() );
786 // Take care we don't process it again
787 MIL << "Remember read index " << PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
788 (*it_idx)->read = true;
789 }
790 }
791 MIL << "done reading indexes" << endl;
792 }
793
794 void Fetcher::Impl::start( const Pathname &dest_dir,
795 const ProgressData::ReceiverFnc & progress )
796 {
797 if ( !_mediaSetAccess )
798 ZYPP_THROW( zypp::Exception("Called Fetcher::start without setting MediaSetAccess before.") );
799 start( dest_dir, *_mediaSetAccess, progress );
800 }
801
802 // start processing all fetcher jobs.
803 // it processes any user pointed index first
804 void Fetcher::Impl::start( const Pathname &dest_dir,
806 const ProgressData::ReceiverFnc & progress_receiver )
807 {
808 _mediaSetAccess = nullptr; //reset the internally stored MediaSetAccess
809
810 ProgressData progress(_resources.size());
811 progress.sendTo(progress_receiver);
812
814
815 for ( const FetcherJob_Ptr & jobp : _resources )
816 {
817 if ( jobp->flags & FetcherJob::Directory )
818 {
819 const OnMediaLocation location(jobp->location);
820 addDirJobs(media, location, dest_dir, jobp->flags);
821 continue;
822 }
823
824 // may be this code can be factored out
825 // together with the autodiscovery of indexes
826 // of addDirJobs
829 {
830 // if auto indexing is enabled, then we need to read the
831 // index for each file. We look only in the directory
832 // where the file is. this is expensive of course.
834 getDirectoryContent(media, jobp->location.filename().dirname(), content);
835 // this method test for the option flags so indexes are added
836 // only if the options are enabled
837 MIL << "Autodiscovering signed indexes on '"
838 << jobp->location.filename().dirname() << "' for '"
839 << jobp->location.filename() << "'" << endl;
840
841 autoaddIndexes(content, media, jobp->location.filename().dirname(), dest_dir);
842
843 // also look in the root of the media
844 content.clear();
845 getDirectoryContent(media, Pathname("/"), content);
846 // this method test for the option flags so indexes are added
847 // only if the options are enabled
848 MIL << "Autodiscovering signed indexes on '"
849 << "/" << "' for '"
850 << jobp->location.filename() << "'" << endl;
851
852 autoaddIndexes(content, media, Pathname("/"), dest_dir);
853 }
854
855 // if the checksum is empty, but the checksum is in one of the
856 // indexes checksum, then add a checker
857 if ( jobp->location.checksum().empty() )
858 {
859 if ( _checksums.find(jobp->location.filename().asString())
860 != _checksums.end() )
861 {
862 CheckSum chksm = _checksums[jobp->location.filename().asString()];
863 ChecksumFileChecker digest_check(chksm);
864 jobp->checkers.push_back(digest_check);
865 }
866 else
867 {
868 // if the index checksum is empty too, we only add the checker
869 // if the AlwaysVerifyChecksum option is set on
870 if ( jobp->flags & FetcherJob::AlwaysVerifyChecksum )
871 {
872 // add the checker with the empty checksum
873 ChecksumFileChecker digest_check(jobp->location.checksum());
874 jobp->checkers.push_back(digest_check);
875 }
876 }
877 }
878 else
879 {
880 // checksum is not empty, so add a checksum checker
881 ChecksumFileChecker digest_check(jobp->location.checksum());
882 jobp->checkers.push_back(digest_check);
883 }
884
885 // Provide and validate the file. If the file was not transferred
886 // and no exception was thrown, it was an optional file.
887 provideToDest( media, dest_dir, jobp );
888
889 if ( ! progress.incr() )
890 ZYPP_THROW(AbortRequestException());
891 } // for each job
892 }
893
895 inline std::ostream & operator<<( std::ostream & str, const Fetcher::Impl & obj )
896 {
897 for ( std::list<FetcherJob_Ptr>::const_iterator it_res = obj._resources.begin(); it_res != obj._resources.end(); ++it_res )
898 {
899 str << *it_res;
900 }
901 return str;
902 }
903
905 : _pimpl( new Impl() )
906 {}
907
910
911 void Fetcher::setOptions( Fetcher::Options options )
912 {
913 _pimpl->setOptions(options);
914 }
915
916 Fetcher::Options Fetcher::options() const
917 {
918 return _pimpl->options();
919 }
920
921 void Fetcher::enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker, const Pathname &deltafile )
922 {
923 enqueueDigested( OnMediaLocation(resource).setDeltafile(deltafile), checker );
924 }
925
926 void Fetcher::enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker )
927 {
928 _pimpl->enqueueDigested( resource, checker );
929 }
930
932 bool recursive,
933 const FileChecker &checker )
934 {
935 _pimpl->enqueueDir(resource, recursive, checker);
936 }
937
939 bool recursive,
940 const FileChecker &checker )
941 {
942 _pimpl->enqueueDigestedDir(resource, recursive, checker);
943 }
944
945
946 void Fetcher::addIndex( const OnMediaLocation &resource )
947 {
948 _pimpl->addIndex(resource);
949 }
950
951
952 void Fetcher::enqueue( const OnMediaLocation &resource, const FileChecker &checker )
953 {
954 _pimpl->enqueue(resource, checker);
955 }
956
957
958 void Fetcher::addCachePath( const Pathname &cache_dir )
959 {
960 _pimpl->addCachePath(cache_dir, Fetcher::Default);
961 }
962
964 {
965 _pimpl->addCachePath(cache_dir, options);
966 }
967
969 {
970 _pimpl->reset();
971 }
972
974 {
975 _pimpl->setMediaSetAccess( media );
976 }
977
979 {
980 _pimpl->start( dest_dir, progress );
981 }
982
983 void Fetcher::start( const Pathname &dest_dir,
985 const ProgressData::ReceiverFnc & progress_receiver )
986 {
987 _pimpl->start(dest_dir, media, progress_receiver);
988 }
989
991 {
992 fixup( remotePath_r );
993 return remotePath_r;
994 }
995
996 std::ostream & operator<<( std::ostream & str, const Fetcher & obj )
997 {
998 return str << *obj._pimpl;
999 }
1000
1002} // namespace zypp
1004
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:479
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name)
Definition Flags.h:177
#define pMIL
Definition LogTools.h:305
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101
void resetDispose()
Set no dispose function.
void setDispose(const Dispose &dispose_r)
Set a new dispose function.
bool empty() const
Definition CheckSum.cc:173
Built in file checkers.
Definition FileChecker.h:48
Integral type with defined initial value when default constructed.
Base class for Exception.
Definition Exception.h:153
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
Fetcher implementation.
Definition Fetcher.cc:176
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:303
void autoaddIndexes(const filesystem::DirContent &content, MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
auto discovery and reading of indexes
Definition Fetcher.cc:468
void downloadIndex(MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
download the indexes and reads them
Definition Fetcher.cc:709
Impl & operator=(const Impl &)=delete
void readContentFileIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for content file
Definition Fetcher.cc:667
void readIndex(const Pathname &index, const Pathname &basedir)
reads a downloaded index file and updates internal attributes table
Definition Fetcher.cc:656
std::set< FetcherIndex_Ptr, SameFetcherIndex > _indexes
Definition Fetcher.cc:290
friend std::ostream & operator<<(std::ostream &str, const Fetcher::Impl &obj)
std::map< std::string, CheckSum > _checksums
Definition Fetcher.cc:293
void downloadAndReadIndexList(MediaSetAccess &media, const Pathname &dest_dir)
download the indexes and reads them
Definition Fetcher.cc:764
void addDirJobs(MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir, FetcherJob::Flags flags)
scan the directory and adds the individual jobs
Definition Fetcher.cc:519
Impl * clone() const
clone for RWCOW_pointer
Definition Fetcher.cc:286
std::list< FetcherJob_Ptr > _resources
Definition Fetcher.cc:289
friend Impl * rwcowClone(const Impl *rhs)
void readChecksumsIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for CHECKSUMS file
Definition Fetcher.cc:680
Impl(Impl &&)=delete
void enqueueDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:325
Impl & operator=(Impl &&)=delete
void addIndex(const OnMediaLocation &resource)
Definition Fetcher.cc:369
std::map< std::string, filesystem::DirContent > _dircontent
Definition Fetcher.cc:295
void provideToDest(MediaSetAccess &media_r, const Pathname &destDir_r, const FetcherJob_Ptr &jobp_r)
Provide the resource to dest_dir.
Definition Fetcher.cc:583
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:357
MediaSetAccess * _mediaSetAccess
Definition Fetcher.cc:297
Impl(const Impl &)=default
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:340
void validate(const Pathname &localfile_r, const std::list< FileChecker > &checkers_r)
Validates the provided file against its checkers.
Definition Fetcher.cc:439
Fetcher::Options options() const
Definition Fetcher.cc:322
std::set< CacheInfo > _caches
Definition Fetcher.cc:291
void getDirectoryContent(MediaSetAccess &media, const OnMediaLocation &resource, filesystem::DirContent &content)
reads the content of a directory but keeps a cache
Definition Fetcher.cc:496
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition Fetcher.cc:218
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...
Definition Fetcher.cc:412
void addCachePath(const Pathname &cache_dir, Fetcher::CacheOptions options)
Definition Fetcher.cc:389
void start(const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress)
Definition Fetcher.cc:794
void setOptions(Fetcher::Options options)
Definition Fetcher.cc:319
Fetcher::Options _options
Definition Fetcher.cc:299
void setMediaSetAccess(MediaSetAccess &media)
Definition Fetcher.cc:384
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...
Definition Fetcher.cc:978
static Pathname mapToCachePath(Pathname remotePath_r)
Map a resource filename to a local path below a destDir.
Definition Fetcher.cc:990
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition Fetcher.h:377
void addIndex(const OnMediaLocation &resource)
Adds an index containing metadata (for example checksums ) that will be retrieved and read before the...
Definition Fetcher.cc:946
Options options() const
Get current options.
Definition Fetcher.cc:916
void reset()
Reset the transfer (jobs) list.
Definition Fetcher.cc:968
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Enqueue a object for transferal, they will not be transferred until start() is called.
Definition Fetcher.cc:952
void enqueueDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory.
Definition Fetcher.cc:931
void setOptions(Options options)
Set the Fetcher options.
Definition Fetcher.cc:911
@ AutoAddChecksumsIndexes
If a CHECKSUMS file is found, it is downloaded and read.
Definition Fetcher.h:134
@ AutoAddContentFileIndexes
If a content file is found, it is downloaded and read.
Definition Fetcher.h:129
Fetcher()
Default ctor.
Definition Fetcher.cc:904
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory and always check for checksums.
Definition Fetcher.cc:938
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Enqueue a object for transferal, they will not be transferred until start() is called.
Definition Fetcher.cc:926
void addCachePath(const Pathname &cache_dir)
adds a directory to the list of directories where to look for cached files
Definition Fetcher.cc:958
void setMediaSetAccess(MediaSetAccess &media)
Sets the media set access that will be used to precache and to download the files when start is calle...
Definition Fetcher.cc:973
virtual ~Fetcher()
Dtor.
Definition Fetcher.cc:908
Media access layer responsible for handling files distributed on a set of media with media change and...
@ PROVIDE_DEFAULT
The user is not asked anything, and the error exception is just propagated.
Pathname provideFile(const OnMediaLocation &resource, ProvideFileOptions options=PROVIDE_DEFAULT)
Provides a file from a media location.
Describes a resource file located on a medium.
bool optional() const
Whether this is an optional resource.
const Pathname & filename() const
The path to the resource on the medium.
OnMediaLocation & setChecksum(CheckSum val_r)
Set the checksum.
unsigned medianr() const
The media number the resource is located on.
OnMediaLocation & changeFilename(Pathname filename_r)
Individual manipulation of filename (prefer setLocation).
const CheckSum & checksum() const
The checksum of the resource on the server.
OnMediaLocation & setOptional(bool val)
Set whether the resource is optional.
Maintain [min,max] and counter (value) for progress counting.
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
bool incr(value_type val_r=1)
Increment counter value (default by 1).
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Definition PublicKey.h:358
Checks for the validity of a signature.
Definition FileChecker.h:71
ZYpp::Ptr getZYpp()
Convenience to get the Pointer to the ZYpp instance.
Definition ZYppFactory.h:77
Wrapper class for stat/lstat.
Definition PathInfo.h:226
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Definition Pathname.h:182
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:133
const char * c_str() const
String representation.
Definition Pathname.h:113
const std::string & asString() const
String representation.
Definition Pathname.h:94
std::string basename() const
Return the last component of this path.
Definition Pathname.h:137
Parse repoindex part from a content file.
virtual void parse(const InputStream &imput_r, const ProgressData::ReceiverFnc &fnc_r=ProgressData::ReceiverFnc())
Parse the stream.
void setRepoIndexConsumer(const RepoIndexConsumer &fnc_r)
Consumer to call when repo index was parsed.
unsigned short a
unsigned short b
String related utilities and Regular expression matching.
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:534
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition PathInfo.cc:902
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:719
std::string sprint(Args &&... args)
Print words as string.
Definition LogTools.h:266
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition String.cc:266
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1097
Easy-to use interface to the ZYPP dependency resolver.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
shared_ptr< FetcherIndex > FetcherIndex_Ptr
Definition Fetcher.cc:103
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
function< void(const Pathname &file)> FileChecker
Functor signature used to check files.
Definition FileChecker.h:38
shared_ptr< FetcherJob > FetcherJob_Ptr
Definition Fetcher.cc:163
parser::susetags::RepoIndex_Ptr _repoindex
Definition Fetcher.cc:652
void consumeIndex(const parser::susetags::RepoIndex_Ptr &data_r)
Definition Fetcher.cc:649
class that represents indexes which add metadata to fetcher jobs and therefore need to be retrieved i...
Definition Fetcher.cc:93
OnMediaLocation location
Index localtion.
Definition Fetcher.cc:98
FetcherIndex(const OnMediaLocation &loc)
Definition Fetcher.cc:94
DefaultIntegral< bool, false > read
Whether we read this index.
Definition Fetcher.cc:100
Class to encapsulate the OnMediaLocation object and the FileChecker together.
Definition Fetcher.cc:129
std::list< FileChecker > checkers
Definition Fetcher.cc:158
FetcherJob(const FetcherJob &)=default
FetcherJob(FetcherJob &&)=default
OnMediaLocation location
Definition Fetcher.cc:156
FetcherJob & operator=(const FetcherJob &)=default
ZYPP_DECLARE_FLAGS(Flags, Flag)
FetcherJob & operator=(FetcherJob &&)=default
FetcherJob(const OnMediaLocation &loc)
Definition Fetcher.cc:147
Fetcher::CacheOptions _options
Definition Fetcher.cc:191
friend bool operator<(const CacheInfo &a, const CacheInfo &b)
Definition Fetcher.cc:193
std::set ordering (less semantic)
Definition Fetcher.cc:107
bool operator()(const FetcherIndex_Ptr &lhs, const FetcherIndex_Ptr &rhs) const
Definition Fetcher.cc:108
Listentry returned by readdir.
Definition PathInfo.h:517