libzypp 17.35.14
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/base/Easy.h>
19#include <zypp/base/LogTools.h>
20#include <zypp/base/PtrTypes.h>
21#include <zypp-core/base/DefaultIntegral>
22#include <zypp/base/String.h>
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
53
54 using FetcherIndex_Ptr = shared_ptr<FetcherIndex>;
55
58 {
59 bool operator()( const FetcherIndex_Ptr & lhs, const FetcherIndex_Ptr & rhs ) const
60 {
61 if ( lhs == rhs )
62 return false; // incl. NULL == NULL
63 if ( ! lhs )
64 return true; // NULL < nonNULL
65 if ( ! rhs )
66 return false; // nonNULL > NULL
67 // both nonNULL ==> compare medianr and path
68 if ( lhs->location.medianr() == rhs->location.medianr() )
69 return lhs->location.filename() < rhs->location.filename();
70 //else
71 return lhs->location.medianr() < rhs->location.medianr();
72 }
73 };
74
80 {
81 enum Flag
82 {
83 None = 0x0000,
84 Directory = 0x0001,
85 Recursive = 0x0002,
87 // check checksums even if there is no such
88 // checksum (warns of no checksum)
90 };
92
93 FetcherJob(const FetcherJob &) = default;
94 FetcherJob(FetcherJob &&) = default;
95 FetcherJob &operator=(const FetcherJob &) = default;
97
99 //MIL << location << endl;
100 }
101
103 {
104 //MIL << location << " | * " << checkers.size() << endl;
105 }
106
108 //CompositeFileChecker checkers;
109 std::list<FileChecker> checkers;
110 Flags flags;
111 };
112
114 using FetcherJob_Ptr = shared_ptr<FetcherJob>;
115
116 std::ostream & operator<<( std::ostream & str, const FetcherJob_Ptr & obj )
117 {
118 return str << obj->location;
119 }
120
122 //
123 // CLASS NAME : Fetcher::Impl
124 //
127 {
128 friend std::ostream & operator<<( std::ostream & str, const Fetcher::Impl & obj );
129
130 public:
131 Impl();
132
133 Impl(const Impl &) = default;
134 Impl(Impl &&) = delete;
135 Impl &operator=(const Impl &) = delete;
136 Impl &operator=(Impl &&) = delete;
137
138 ~Impl() {}
139
140 void setOptions( Fetcher::Options options );
141 Fetcher::Options options() const;
142
143 void addIndex( const OnMediaLocation &resource );
144
145 void enqueueDir( const OnMediaLocation &resource, bool recursive, const FileChecker &checker = FileChecker() );
146 void enqueueDigestedDir( const OnMediaLocation &resource, bool recursive, const FileChecker &checker = FileChecker() );
147
148 void enqueue( const OnMediaLocation &resource, const FileChecker &checker = FileChecker() );
149 void enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker = FileChecker() );
150 void addCachePath( const Pathname &cache_dir );
151 void reset();
152 void setMediaSetAccess ( MediaSetAccess &media );
153 void start( const Pathname &dest_dir,
154 const ProgressData::ReceiverFnc &progress );
155 void start( const Pathname &dest_dir,
156 MediaSetAccess &media,
157 const ProgressData::ReceiverFnc & progress_receiver );
158
160 static shared_ptr<Impl> nullimpl()
161 {
162 static shared_ptr<Impl> _nullimpl( new Impl );
163 return _nullimpl;
164 }
165 private:
169 void downloadAndReadIndexList( MediaSetAccess &media, const Pathname &dest_dir);
170
174 void downloadIndex( MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir);
175
183 void readIndex( const Pathname &index, const Pathname &basedir );
184
186 void readChecksumsIndex( const Pathname &index, const Pathname &basedir );
187
189 void readContentFileIndex( const Pathname &index, const Pathname &basedir );
190
192 void getDirectoryContent( MediaSetAccess &media, const OnMediaLocation &resource, filesystem::DirContent &content );
193
199 Pathname locateInCache( const OnMediaLocation & resource_r, const Pathname & destDir_r, const std::string & suffix_in_cache = "" );
204 void validate( const Pathname & localfile_r, const std::list<FileChecker> & checkers_r );
205
209 void addDirJobs( MediaSetAccess &media, const OnMediaLocation &resource,
210 const Pathname &dest_dir, FetcherJob::Flags flags );
211
215 void autoaddIndexes( const filesystem::DirContent &content,
216 MediaSetAccess &media,
217 const OnMediaLocation &resource,
218 const Pathname &dest_dir );
222 void provideToDest( MediaSetAccess & media_r, const Pathname & destDir_r , const FetcherJob_Ptr & jobp_r );
223
224 private:
225 friend Impl * rwcowClone<Impl>( const Impl * rhs );
227 Impl * clone() const
228 { return new Impl( *this ); }
229
230 std::list<FetcherJob_Ptr> _resources;
231 std::set<FetcherIndex_Ptr,SameFetcherIndex> _indexes;
232 std::set<Pathname> _caches;
233 // checksums read from the indexes
234 std::map<std::string, CheckSum> _checksums;
235 // cache of dir contents
236 std::map<std::string, filesystem::DirContent> _dircontent;
237
239
240 Fetcher::Options _options;
241 };
243
245 {
246 if ( _mediaSetAccess )
247 _mediaSetAccess->precacheFiles( {resource} );
248
249 FetcherJob_Ptr job;
250 job.reset(new FetcherJob(resource));
252 _resources.push_back(job);
253 }
254
256 : _options(0)
257 {
258 }
259
260 void Fetcher::Impl::setOptions( Fetcher::Options options )
261 { _options = options; }
262
263 Fetcher::Options Fetcher::Impl::options() const
264 { return _options; }
265
267 bool recursive,
268 const FileChecker &checker )
269 {
270 FetcherJob_Ptr job;
271 job.reset(new FetcherJob(resource));
272 if ( checker )
273 job->checkers.push_back(checker);
274 if ( recursive )
275 job->flags |= FetcherJob::Recursive;
276 job->flags |= FetcherJob::Directory;
277
278 _resources.push_back(job);
279 }
280
282 bool recursive,
283 const FileChecker &checker )
284 {
285 FetcherJob_Ptr job;
286 job.reset(new FetcherJob(resource));
287 if ( checker )
288 job->checkers.push_back(checker);
289 if ( recursive )
290 job->flags |= FetcherJob::Recursive;
291 job->flags |= FetcherJob::Directory;
293
294 _resources.push_back(job);
295
296 }
297
298 void Fetcher::Impl::enqueue( const OnMediaLocation &resource, const FileChecker &checker )
299 {
300 if ( _mediaSetAccess )
301 _mediaSetAccess->precacheFiles( {resource} );
302
303 FetcherJob_Ptr job;
304 job.reset(new FetcherJob(resource));
305 if ( checker )
306 job->checkers.push_back(checker);
307 _resources.push_back(job);
308 }
309
311 {
312 MIL << "adding index " << resource << endl;
313 _indexes.insert(FetcherIndex_Ptr(new FetcherIndex(resource)));
314 }
315
316
318 {
319 _resources.clear();
320 _indexes.clear();
321 _checksums.clear();
322 _dircontent.clear();
323 }
324
326 {
327 _mediaSetAccess = &media;
328 }
329
330 void Fetcher::Impl::addCachePath( const Pathname &cache_dir )
331 {
332 PathInfo info(cache_dir);
333 if ( info.isExist() )
334 {
335 if ( info.isDir() )
336 {
337 DBG << "Adding fetcher cache: '" << cache_dir << "'." << endl;
338 _caches.insert(cache_dir);
339 }
340 else
341 {
342 // don't add bad cache directory, just log the error
343 ERR << "Not adding cache: '" << cache_dir << "'. Not a directory." << endl;
344 }
345 }
346 else
347 {
348 ERR << "Not adding cache '" << cache_dir << "'. Path does not exists." << endl;
349 }
350
351 }
352
353 Pathname Fetcher::Impl::locateInCache( const OnMediaLocation & resource_r, const Pathname & destDir_r, const std::string & suffix_in_cache )
354 {
355 Pathname ret;
356 // No checksum - no match
357 if ( resource_r.checksum().empty() )
358 return ret;
359
360 // first check in the destination directory
361 Pathname cacheLocation = destDir_r / resource_r.filename();
362
363 if ( !suffix_in_cache.empty() )
364 cacheLocation = cacheLocation.extend( suffix_in_cache.c_str() );
365
366 if ( PathInfo(cacheLocation).isExist() && is_checksum( cacheLocation, resource_r.checksum() ) )
367 {
368 swap( ret, cacheLocation );
369 return ret;
370 }
371
372 MIL << "start fetcher with " << _caches.size() << " cache directories." << endl;
373 for( const Pathname & cacheDir : _caches )
374 {
375 cacheLocation = cacheDir / resource_r.filename();
376 std::string detail = cacheDir.asString();
377 if ( !suffix_in_cache.empty() )
378 detail += "with suffix " + suffix_in_cache;
379
380 if ( PathInfo(cacheLocation).isExist() )
381 {
382 MIL << "file " << resource_r.filename() << " found in cache " << detail << endl;
383 if (!is_checksum( cacheLocation, resource_r.checksum() ) )
384 MIL << "file " << resource_r.filename() << " failed checksum verification in cache " << detail << endl;
385 else {
386 swap( ret, cacheLocation );
387 return ret;
388 }
389 }
390 }
391
392 return ret;
393 }
394
395 void Fetcher::Impl::validate( const Pathname & localfile_r, const std::list<FileChecker> & checkers_r )
396 {
397 try
398 {
399 MIL << "Checking job [" << localfile_r << "] (" << checkers_r.size() << " checkers )" << endl;
400
401 for ( const FileChecker & chkfnc : checkers_r )
402 {
403 if ( chkfnc )
404 chkfnc( localfile_r );
405 else
406 ERR << "Invalid checker for '" << localfile_r << "'" << endl;
407 }
408
409 }
410 catch ( const FileCheckException &e )
411 {
412 throw; // let known exceptions bypass silently
413 }
414 catch ( const Exception &e )
415 {
416 throw; // slet known exceptions bypass silently
417 }
418 catch (...)
419 {
420 ZYPP_THROW(Exception("Unknown error while validating " + localfile_r.asString()));
421 }
422 }
423
425 MediaSetAccess &media,
426 const OnMediaLocation &resource,
427 const Pathname &dest_dir )
428 {
429 auto fnc_addIfInContent( [&]( const std::string & index_r ) -> bool
430 {
431 if ( find( content.begin(), content.end(), filesystem::DirEntry(index_r,filesystem::FT_FILE) ) == content.end() )
432 return false;
433 // add the index of this directory
434 OnMediaLocation indexloc( resource );
435 indexloc.changeFilename( resource.filename() + index_r );
436 addIndex( indexloc );
437 // we need to read it now
438 downloadAndReadIndexList( media, dest_dir );
439 return true;
440 } );
441
443 {
444 fnc_addIfInContent( "CHECKSUMS" ) || fnc_addIfInContent( "SHA1SUMS" );
445 }
447 {
448 fnc_addIfInContent( "content" );
449 }
450 }
451
453 const OnMediaLocation &resource,
454 filesystem::DirContent &content )
455 {
456 if ( _dircontent.find(resource.filename().asString())
457 != _dircontent.end() )
458 {
459 filesystem::DirContent filled(_dircontent[resource.filename().asString()]);
460
461 std::copy(filled.begin(), filled.end(), std::back_inserter(content));
462 }
463 else
464 {
466 media.dirInfo( tofill,
467 resource.filename(),
468 false /* dots */,
469 resource.medianr());
470 std::copy(tofill.begin(), tofill.end(), std::back_inserter(content));
471 _dircontent[resource.filename().asString()] = tofill;
472 }
473 }
474
476 const OnMediaLocation &resource,
477 const Pathname &dest_dir, FetcherJob::Flags flags )
478 {
479 // first get the content of the directory so we can add
480 // individual transfer jobs
481 MIL << "Adding directory " << resource.filename() << endl;
483 try {
484 getDirectoryContent(media, resource, content);
485 }
486 catch ( media::MediaFileNotFoundException & exception )
487 {
488 ZYPP_CAUGHT( exception );
489 WAR << "Skipping subtree hidden at " << resource.filename() << endl;
490 return;
491 }
492
493 // this method test for the option flags so indexes are added
494 // only if the options are enabled
495 autoaddIndexes(content, media, resource, dest_dir);
496
497 for ( filesystem::DirContent::const_iterator it = content.begin();
498 it != content.end();
499 ++it )
500 {
501 // skip CHECKSUMS* as they were already retrieved
502 if ( str::hasPrefix(it->name, "CHECKSUMS") || str::hasPrefix(it->name, "SHA1SUMS") )
503 continue;
504
505 Pathname filename = resource.filename() + it->name;
506
507 switch ( it->type )
508 {
509 case filesystem::FT_NOT_AVAIL: // old directory.yast contains no typeinfo at all
511 {
512 CheckSum chksm(resource.checksum());
513 if ( _checksums.find(filename.asString()) != _checksums.end() )
514 {
515 // the checksum can be replaced with the one in the index.
516 chksm = _checksums[filename.asString()];
517 //MIL << "resource " << filename << " has checksum in the index file." << endl;
518 }
519 else
520 WAR << "Resource " << filename << " has no checksum in the index either." << endl;
521
523 enqueueDigested(OnMediaLocation(filename, resource.medianr()).setChecksum(chksm));
524 else
525 enqueue(OnMediaLocation(filename, resource.medianr()).setChecksum(chksm));
526 break;
527 }
528 case filesystem::FT_DIR: // newer directory.yast contain at least directory info
529 if ( flags & FetcherJob::Recursive )
530 addDirJobs(media, filename, dest_dir, flags);
531 break;
532 default:
533 // don't provide devices, sockets, etc.
534 break;
535 }
536 }
537 }
538
539 void Fetcher::Impl::provideToDest( MediaSetAccess & media_r, const Pathname & destDir_r , const FetcherJob_Ptr & jobp_r )
540 {
541 const OnMediaLocation & resource( jobp_r->location );
542
543 try
544 {
545 scoped_ptr<MediaSetAccess::ReleaseFileGuard> releaseFileGuard; // will take care provided files get released
546
547 // get cached file (by checksum) or provide from media
548 Pathname tmpFile = locateInCache( resource, destDir_r );
549 if ( tmpFile.empty() ) {
550 const std::string suffix(".unverified");
551 Pathname tmpFileUnverified = locateInCache( resource, destDir_r, suffix );
552 if (!tmpFileUnverified.empty()) {
553 try {
554 validate( tmpFileUnverified, jobp_r->checkers );
555 if (tmpFileUnverified.extension() == suffix ) {
556 std::string_view dest = tmpFileUnverified.asString().c_str();
557 dest.remove_suffix( suffix.length() );
558
559 rename( tmpFileUnverified.asString().c_str(), std::string(dest).c_str() );
560 tmpFile = locateInCache( resource, destDir_r );
561 }
562 } catch (...) {
563 // ignore all exceptions and proceed normally
564 };
565 }
566 }
567
568 if ( !tmpFile.empty() ) {
569 MIL << "Found in cache, verifying..." << endl;
570 } else {
571 MIL << "Not found in cache, retrieving..." << endl;
573 releaseFileGuard.reset( new MediaSetAccess::ReleaseFileGuard( media_r, resource ) ); // release it when we leave the block
574 }
575
576 // The final destination: locateInCache also checks destFullPath!
577 // If we find a cache match (by checksum) at destFullPath, take
578 // care it gets deleted, in case the validation fails.
579 ManagedFile destFullPath( destDir_r / resource.filename() );
580 if ( tmpFile == destFullPath )
581 destFullPath.setDispose( filesystem::unlink );
582
583 // validate the file (throws if not valid)
584 validate( tmpFile, jobp_r->checkers );
585
586 // move it to the final destination
587 if ( tmpFile == destFullPath )
588 destFullPath.resetDispose(); // keep it!
589 else
590 {
591 if ( assert_dir( destFullPath->dirname() ) != 0 )
592 ZYPP_THROW( Exception( "Can't create " + destFullPath->dirname().asString() ) );
593
594 if ( filesystem::hardlinkCopy( tmpFile, destFullPath ) != 0 )
595 ZYPP_THROW( Exception( "Can't hardlink/copy " + tmpFile.asString() + " to " + destDir_r.asString() ) );
596 }
597 }
598 catch ( Exception & excpt )
599 {
600 if ( resource.optional() )
601 {
602 ZYPP_CAUGHT( excpt );
603 WAR << "optional resource " << resource << " could not be transferred." << endl;
604 return;
605 }
606 else
607 {
608 excpt.remember( "Can't provide " + resource.filename().asString() );
609 ZYPP_RETHROW( excpt );
610 }
611 }
612 }
613
614 // helper class to consume a content file
616 {
618 {
619 setRepoIndexConsumer( bind( &ContentReaderHelper::consumeIndex, this, _1 ) );
620 }
621
622 void consumeIndex( const parser::susetags::RepoIndex_Ptr & data_r )
623 { _repoindex = data_r; }
624
625 parser::susetags::RepoIndex_Ptr _repoindex;
626 };
627
628 // generic function for reading indexes
629 void Fetcher::Impl::readIndex( const Pathname &index, const Pathname &basedir )
630 {
631 if ( index.basename() == "CHECKSUMS" || index.basename() == "SHA1SUMS" )
632 readChecksumsIndex(index, basedir);
633 else if ( index.basename() == "content" )
634 readContentFileIndex(index, basedir);
635 else
636 WAR << index << ": index file format not known" << endl;
637 }
638
639 // reads a content file index
640 void Fetcher::Impl::readContentFileIndex( const Pathname &index, const Pathname &basedir )
641 {
642 ContentReaderHelper reader;
643 reader.parse(index);
644 MIL << index << " contains " << reader._repoindex->mediaFileChecksums.size() << " checksums." << endl;
645 for_( it, reader._repoindex->mediaFileChecksums.begin(), reader._repoindex->mediaFileChecksums.end() )
646 {
647 // content file entries don't start with /
648 _checksums[(basedir + it->first).asString()] = it->second;
649 }
650 }
651
652 // reads a CHECKSUMS (old SHA1SUMS) file index
653 void Fetcher::Impl::readChecksumsIndex( const Pathname &index, const Pathname &basedir )
654 {
655 std::ifstream in( index.c_str() );
656 if ( ! in.fail() )
657 {
658 std::string buffer;
659 while ( getline( in, buffer ) )
660 {
661
662 if ( buffer[0] == '#' )
663 continue; // simple comment
664
665 CheckSum checksum( str::stripFirstWord( buffer, /*ltrim before strip*/true ) );
666 if ( checksum.empty() )
667 continue; // empty line | unknown cheksum format
668
669 if ( buffer.empty() )
670 {
671 WAR << "Missing filename in CHECKSUMS file: " << index.asString() << " (" << checksum << ")" << endl;
672 continue;
673 }
674
675 _checksums[(basedir/buffer).asString()] = checksum;
676 }
677 }
678 else
679 ZYPP_THROW(Exception("Can't open CHECKSUMS file: " + index.asString()));
680 }
681
682 void Fetcher::Impl::downloadIndex( MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
683 {
684 MIL << "downloading index " << resource << endl;
685 // create a new fetcher with a different state to transfer the
686 // file containing checksums and its signature
687 Fetcher fetcher;
688 // signature checker for index. We havent got the signature from
689 // the nextwork yet.
690 SignatureFileChecker sigchecker;
691
692 // build the name of the index and the signature
693 const OnMediaLocation& idxloc(resource);
694 OnMediaLocation sigloc(resource);
695 OnMediaLocation keyloc(resource);
696
697 // we should not fail the download if those don't exists
698 // the checking will warn later
699 sigloc.setOptional(true);
700 keyloc.setOptional(true);
701
702 // calculate signature and key name
703 sigloc.changeFilename( sigloc.filename().extend(".asc") );
704 keyloc.changeFilename( keyloc.filename().extend(".key") );
705
706 //assert_dir(dest_dir + idxloc.filename().dirname());
707
708 // transfer the signature
709 fetcher.enqueue(sigloc);
710 fetcher.start( dest_dir, media );
711 // if we get the signature, update the checker
712 if ( PathInfo(dest_dir + sigloc.filename()).isExist() )
713 sigchecker = SignatureFileChecker(dest_dir + sigloc.filename());
714
715 fetcher.reset();
716
717 // now the key
718 fetcher.enqueue(keyloc);
719 fetcher.start( dest_dir, media );
720 fetcher.reset();
721
722 // try to import the key
723 if ( PathInfo(dest_dir + keyloc.filename()).isExist() )
724 getZYpp()->keyRing()->importKey(PublicKey(dest_dir + keyloc.filename()), false);
725 else
726 WAR << "No public key specified by user for index '" << keyloc.filename() << "'"<< endl;
727
728 // now the index itself
729 fetcher.enqueue( idxloc, FileChecker(sigchecker) );
730 fetcher.start( dest_dir, media );
731 fetcher.reset();
732 }
733
734 // this method takes all the user pointed indexes, gets them and also tries to
735 // download their signature, and verify them. After that, it parses each one
736 // to fill the checksum cache.
738 {
739 // if there is no indexes, then just return to avoid
740 // the directory listing
741 if ( _indexes.empty() )
742 {
743 MIL << "No indexes to read." << endl;
744 return;
745 }
746
747 for_( it_idx, _indexes.begin(), _indexes.end() )
748 {
749 if ( (*it_idx)->read )
750 {
751 DBG << "Already read index " << PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
752 }
753 else
754 {
755 // base::LogControl::TmpLineWriter shutUp;
756 downloadIndex( media, (*it_idx)->location, dest_dir );
757 // now we have the indexes in dest_dir
758 readIndex( dest_dir + (*it_idx)->location.filename(), (*it_idx)->location.filename().dirname() );
759 // Take care we don't process it again
760 MIL << "Remember read index " << PathInfo(dest_dir + (*it_idx)->location.filename()) << endl;
761 (*it_idx)->read = true;
762 }
763 }
764 MIL << "done reading indexes" << endl;
765 }
766
767 void Fetcher::Impl::start( const Pathname &dest_dir,
768 const ProgressData::ReceiverFnc & progress )
769 {
770 if ( !_mediaSetAccess )
771 ZYPP_THROW( zypp::Exception("Called Fetcher::start without setting MediaSetAccess before.") );
772 start( dest_dir, *_mediaSetAccess, progress );
773 }
774
775 // start processing all fetcher jobs.
776 // it processes any user pointed index first
777 void Fetcher::Impl::start( const Pathname &dest_dir,
778 MediaSetAccess &media,
779 const ProgressData::ReceiverFnc & progress_receiver )
780 {
781 _mediaSetAccess = nullptr; //reset the internally stored MediaSetAccess
782
783 ProgressData progress(_resources.size());
784 progress.sendTo(progress_receiver);
785
786 downloadAndReadIndexList(media, dest_dir);
787
788 for ( const FetcherJob_Ptr & jobp : _resources )
789 {
790 if ( jobp->flags & FetcherJob::Directory )
791 {
792 const OnMediaLocation location(jobp->location);
793 addDirJobs(media, location, dest_dir, jobp->flags);
794 continue;
795 }
796
797 // may be this code can be factored out
798 // together with the autodiscovery of indexes
799 // of addDirJobs
802 {
803 // if auto indexing is enabled, then we need to read the
804 // index for each file. We look only in the directory
805 // where the file is. this is expensive of course.
807 getDirectoryContent(media, jobp->location.filename().dirname(), content);
808 // this method test for the option flags so indexes are added
809 // only if the options are enabled
810 MIL << "Autodiscovering signed indexes on '"
811 << jobp->location.filename().dirname() << "' for '"
812 << jobp->location.filename() << "'" << endl;
813
814 autoaddIndexes(content, media, jobp->location.filename().dirname(), dest_dir);
815
816 // also look in the root of the media
817 content.clear();
818 getDirectoryContent(media, Pathname("/"), content);
819 // this method test for the option flags so indexes are added
820 // only if the options are enabled
821 MIL << "Autodiscovering signed indexes on '"
822 << "/" << "' for '"
823 << jobp->location.filename() << "'" << endl;
824
825 autoaddIndexes(content, media, Pathname("/"), dest_dir);
826 }
827
828 // if the checksum is empty, but the checksum is in one of the
829 // indexes checksum, then add a checker
830 if ( jobp->location.checksum().empty() )
831 {
832 if ( _checksums.find(jobp->location.filename().asString())
833 != _checksums.end() )
834 {
835 CheckSum chksm = _checksums[jobp->location.filename().asString()];
836 ChecksumFileChecker digest_check(chksm);
837 jobp->checkers.push_back(digest_check);
838 }
839 else
840 {
841 // if the index checksum is empty too, we only add the checker
842 // if the AlwaysVerifyChecksum option is set on
843 if ( jobp->flags & FetcherJob::AlwaysVerifyChecksum )
844 {
845 // add the checker with the empty checksum
846 ChecksumFileChecker digest_check(jobp->location.checksum());
847 jobp->checkers.push_back(digest_check);
848 }
849 }
850 }
851 else
852 {
853 // checksum is not empty, so add a checksum checker
854 ChecksumFileChecker digest_check(jobp->location.checksum());
855 jobp->checkers.push_back(digest_check);
856 }
857
858 // Provide and validate the file. If the file was not transferred
859 // and no exception was thrown, it was an optional file.
860 provideToDest( media, dest_dir, jobp );
861
862 if ( ! progress.incr() )
863 ZYPP_THROW(AbortRequestException());
864 } // for each job
865 }
866
868 inline std::ostream & operator<<( std::ostream & str, const Fetcher::Impl & obj )
869 {
870 for ( std::list<FetcherJob_Ptr>::const_iterator it_res = obj._resources.begin(); it_res != obj._resources.end(); ++it_res )
871 {
872 str << *it_res;
873 }
874 return str;
875 }
876
878 : _pimpl( new Impl() )
879 {}
880
883
884 void Fetcher::setOptions( Fetcher::Options options )
885 {
887 }
888
889 Fetcher::Options Fetcher::options() const
890 {
891 return _pimpl->options();
892 }
893
894 void Fetcher::enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker, const Pathname &deltafile )
895 {
896 enqueueDigested( OnMediaLocation(resource).setDeltafile(deltafile), checker );
897 }
898
899 void Fetcher::enqueueDigested( const OnMediaLocation &resource, const FileChecker &checker )
900 {
901 _pimpl->enqueueDigested( resource, checker );
902 }
903
905 bool recursive,
906 const FileChecker &checker )
907 {
908 _pimpl->enqueueDir(resource, recursive, checker);
909 }
910
912 bool recursive,
913 const FileChecker &checker )
914 {
915 _pimpl->enqueueDigestedDir(resource, recursive, checker);
916 }
917
918
919 void Fetcher::addIndex( const OnMediaLocation &resource )
920 {
921 _pimpl->addIndex(resource);
922 }
923
924
925 void Fetcher::enqueue( const OnMediaLocation &resource, const FileChecker &checker )
926 {
927 _pimpl->enqueue(resource, checker);
928 }
929
930
931 void Fetcher::addCachePath( const Pathname &cache_dir )
932 {
933 _pimpl->addCachePath(cache_dir);
934 }
935
937 {
938 _pimpl->reset();
939 }
940
942 {
943 _pimpl->setMediaSetAccess( media );
944 }
945
947 {
948 _pimpl->start( dest_dir, progress );
949 }
950
951 void Fetcher::start( const Pathname &dest_dir,
952 MediaSetAccess &media,
953 const ProgressData::ReceiverFnc & progress_receiver )
954 {
955 _pimpl->start(dest_dir, media, progress_receiver);
956 }
957
958 std::ostream & operator<<( std::ostream & str, const Fetcher & obj )
959 {
960 return str << *obj._pimpl;
961 }
962
964} // namespace zypp
966
Pathname deltafile
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:147
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:141
Fetcher implementation.
Definition Fetcher.cc:127
void enqueueDigested(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:244
void autoaddIndexes(const filesystem::DirContent &content, MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
auto discovery and reading of indexes
Definition Fetcher.cc:424
void downloadIndex(MediaSetAccess &media, const OnMediaLocation &resource, const Pathname &dest_dir)
download the indexes and reads them
Definition Fetcher.cc:682
Impl & operator=(const Impl &)=delete
void readContentFileIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for content file
Definition Fetcher.cc:640
void readIndex(const Pathname &index, const Pathname &basedir)
reads a downloaded index file and updates internal attributes table
Definition Fetcher.cc:629
std::set< FetcherIndex_Ptr, SameFetcherIndex > _indexes
Definition Fetcher.cc:231
friend std::ostream & operator<<(std::ostream &str, const Fetcher::Impl &obj)
std::map< std::string, CheckSum > _checksums
Definition Fetcher.cc:234
void downloadAndReadIndexList(MediaSetAccess &media, const Pathname &dest_dir)
download the indexes and reads them
Definition Fetcher.cc:737
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:475
Impl * clone() const
clone for RWCOW_pointer
Definition Fetcher.cc:227
void addCachePath(const Pathname &cache_dir)
Definition Fetcher.cc:330
std::list< FetcherJob_Ptr > _resources
Definition Fetcher.cc:230
friend Impl * rwcowClone(const Impl *rhs)
void readChecksumsIndex(const Pathname &index, const Pathname &basedir)
specific version of readIndex for CHECKSUMS file
Definition Fetcher.cc:653
Impl(Impl &&)=delete
void enqueueDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:266
Impl & operator=(Impl &&)=delete
void addIndex(const OnMediaLocation &resource)
Definition Fetcher.cc:310
std::map< std::string, filesystem::DirContent > _dircontent
Definition Fetcher.cc:236
void provideToDest(MediaSetAccess &media_r, const Pathname &destDir_r, const FetcherJob_Ptr &jobp_r)
Provide the resource to dest_dir.
Definition Fetcher.cc:539
void enqueue(const OnMediaLocation &resource, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:298
MediaSetAccess * _mediaSetAccess
Definition Fetcher.cc:238
std::set< Pathname > _caches
Definition Fetcher.cc:232
Impl(const Impl &)=default
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive, const FileChecker &checker=FileChecker())
Definition Fetcher.cc:281
void validate(const Pathname &localfile_r, const std::list< FileChecker > &checkers_r)
Validates the provided file against its checkers.
Definition Fetcher.cc:395
Fetcher::Options options() const
Definition Fetcher.cc:263
void getDirectoryContent(MediaSetAccess &media, const OnMediaLocation &resource, filesystem::DirContent &content)
reads the content of a directory but keeps a cache
Definition Fetcher.cc:452
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition Fetcher.cc:160
Pathname locateInCache(const OnMediaLocation &resource_r, const Pathname &destDir_r, const std::string &suffix_in_cache="")
Tries to locate the file represented by job by looking at the cache (matching checksum is mandatory).
Definition Fetcher.cc:353
void start(const Pathname &dest_dir, const ProgressData::ReceiverFnc &progress)
Definition Fetcher.cc:767
void setOptions(Fetcher::Options options)
Definition Fetcher.cc:260
Fetcher::Options _options
Definition Fetcher.cc:240
void setMediaSetAccess(MediaSetAccess &media)
Definition Fetcher.cc:325
This class allows to retrieve a group of files in a confortable way, providing some smartness that do...
Definition Fetcher.h:104
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:946
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Definition Fetcher.h:344
void addIndex(const OnMediaLocation &resource)
Adds an index containing metadata (for example checksums ) that will be retrieved and read before the...
Definition Fetcher.cc:919
Options options() const
Get current options.
Definition Fetcher.cc:889
void reset()
Reset the transfer (jobs) list.
Definition Fetcher.cc:936
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:925
void enqueueDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory.
Definition Fetcher.cc:904
void setOptions(Options options)
Set the Fetcher options.
Definition Fetcher.cc:884
@ AutoAddChecksumsIndexes
If a CHECKSUMS file is found, it is downloaded and read.
Definition Fetcher.h:126
@ AutoAddContentFileIndexes
If a content file is found, it is downloaded and read.
Definition Fetcher.h:121
Fetcher()
Default ctor.
Definition Fetcher.cc:877
void enqueueDigestedDir(const OnMediaLocation &resource, bool recursive=false, const FileChecker &checker=FileChecker())
Enqueue a directory and always check for checksums.
Definition Fetcher.cc:911
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:899
void addCachePath(const Pathname &cache_dir)
adds a directory to the list of directories where to look for cached files
Definition Fetcher.cc:931
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:941
virtual ~Fetcher()
Dtor.
Definition Fetcher.cc:881
Media access layer responsible for handling files distributed on a set of media with media change and...
void precacheFiles(const std::vector< OnMediaLocation > &files)
Tries to fetch the given files and precaches them.
@ 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.
void dirInfo(filesystem::DirContent &retlist, const Pathname &dirname, bool dots=true, unsigned media_nr=1)
Fills retlist with directory information.
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:365
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:222
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:282
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Definition Pathname.h:175
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:126
const char * c_str() const
String representation.
Definition Pathname.h:112
const std::string & asString() const
String representation.
Definition Pathname.h:93
std::string basename() const
Return the last component of this path.
Definition Pathname.h:130
bool empty() const
Test for an empty path.
Definition Pathname.h:116
std::string extension() const
Return all of the characters in name after and including the last dot in the last element of name.
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.
String related utilities and Regular expression matching.
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:519
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition PathInfo.cc:888
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition String.cc:264
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1026
Easy-to use interface to the ZYPP dependency resolver.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
shared_ptr< FetcherIndex > FetcherIndex_Ptr
Definition Fetcher.cc:54
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:114
zypp::RepoManager::RefreshServiceOptions _options
parser::susetags::RepoIndex_Ptr _repoindex
Definition Fetcher.cc:625
void consumeIndex(const parser::susetags::RepoIndex_Ptr &data_r)
Definition Fetcher.cc:622
class that represents indexes which add metadata to fetcher jobs and therefore need to be retrieved i...
Definition Fetcher.cc:44
OnMediaLocation location
Index localtion.
Definition Fetcher.cc:49
FetcherIndex(const OnMediaLocation &loc)
Definition Fetcher.cc:45
DefaultIntegral< bool, false > read
Whether we read this index.
Definition Fetcher.cc:51
Class to encapsulate the OnMediaLocation object and the FileChecker together.
Definition Fetcher.cc:80
std::list< FileChecker > checkers
Definition Fetcher.cc:109
FetcherJob(const FetcherJob &)=default
FetcherJob(FetcherJob &&)=default
OnMediaLocation location
Definition Fetcher.cc:107
FetcherJob & operator=(const FetcherJob &)=default
ZYPP_DECLARE_FLAGS(Flags, Flag)
FetcherJob & operator=(FetcherJob &&)=default
FetcherJob(const OnMediaLocation &loc)
Definition Fetcher.cc:98
std::set ordering (less semantic)
Definition Fetcher.cc:58
bool operator()(const FetcherIndex_Ptr &lhs, const FetcherIndex_Ptr &rhs) const
Definition Fetcher.cc:59
Listentry returned by readdir.
Definition PathInfo.h:502
zypp::parser::susetags::RepoIndex_Ptr _repoindex
Definition susetags.cc:324
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:28
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:444
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:440
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
#define ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name)
Definition Flags.h:177
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101