00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <fstream>
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Gettext.h"
00016 #include "zypp/Digest.h"
00017 #include "zypp/SourceFactory.h"
00018 #include "zypp/source/SourceImpl.h"
00019 #include "zypp/ZYppCallbacks.h"
00020 #include "zypp/SourceManager.h"
00021 #include "zypp/ZYppFactory.h"
00022 #include <fstream>
00023
00024 using std::endl;
00025
00027 namespace zypp
00028 {
00029
00030 namespace source
00031 {
00032
00033 IMPL_PTR_TYPE(SourceImpl);
00034
00035
00036 static int random()
00037 {
00038 static bool init = false;
00039 if (!init)
00040 {
00041 unsigned int seed;
00042 init = true;
00043 int fd = open("/dev/urandom", O_RDONLY);
00044 if (fd < 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed))
00045 {
00046
00047 srand(getpid());
00048 seed = rand()+time(0);
00049 }
00050 if (fd >= 0) close(fd);
00051 srand(seed);
00052 }
00053 return rand();
00054 }
00055
00056
00057 static std::string randomString(int length)
00058 {
00059 if (length <=0 ) return std::string();
00060
00061 std::string str;
00062 str.resize( length );
00063 int i = 0;
00064 while (length--)
00065 {
00066 int r=random() % 62;
00067 r+=48;
00068 if (r>57) r+=7;
00069 if (r>90) r+=6;
00070 str[i++] = char(r);
00071
00072 }
00073 return str;
00074 }
00075
00076
00077 class DownloadProgressPackageReceiver : public callback::ReceiveReport<media::DownloadProgressReport>
00078 {
00079 callback::SendReport <DownloadResolvableReport> & _report;
00080 Resolvable::constPtr _resolvable;
00081
00082 public:
00083
00084 DownloadProgressPackageReceiver ( callback::SendReport <DownloadResolvableReport> & report_r, Resolvable::constPtr resolvable_r )
00085 : _report (report_r), _resolvable (resolvable_r)
00086 {}
00087
00088 virtual ~DownloadProgressPackageReceiver ()
00089 {}
00090 virtual void reportbegin()
00091 {}
00092 virtual void reportend()
00093 {}
00094
00099 virtual bool progress( int percent, const Url& )
00100 {
00101 return _report->progress( percent, _resolvable );
00102 }
00103 };
00104
00105
00106 class DownloadProgressFileReceiver : public callback::ReceiveReport<media::DownloadProgressReport>
00107 {
00108 callback::SendReport<SourceReport> & _report;
00109
00110 public:
00111
00112 DownloadProgressFileReceiver ( callback::SendReport<SourceReport> & report_r )
00113 : _report (report_r)
00114 {}
00115
00116 virtual ~DownloadProgressFileReceiver ()
00117 {}
00118 virtual void reportbegin()
00119 {}
00120 virtual void reportend()
00121 {}
00122
00127 virtual bool progress( int percent, const Url& url )
00128 {
00129 return _report->progress( percent);
00130 }
00131 };
00132
00136 SourceImpl::SourceImpl( const null & )
00137 : base::ProvideNumericId<SourceImpl,Source_Ref::NumericId>( NULL )
00138 , _res_store_initialized(true)
00139 {}
00140
00142
00143
00144
00145
00146 SourceImpl::SourceImpl()
00147 : _enabled(true)
00148 , _autorefresh(true)
00149 , _priority (0)
00150 , _priority_unsubscribed (0)
00151 , _subscribed(false)
00152 , _base_source(false)
00153 , _res_store_initialized(false)
00154 {}
00155
00157
00158
00159
00160
00161 void SourceImpl::factoryCtor( const media::MediaId & media_r,
00162 const Pathname & path_r,
00163 const std::string & alias_r,
00164 const Pathname cache_dir_r,
00165 bool base_source,
00166 bool auto_refresh )
00167 {
00168 _media_set = new MediaSet( selfSourceRef() );
00169 _url = media_mgr.url( media_r );
00170 _media_set->redirect( 1, media_r );
00171 _path = path_r;
00172 _alias = alias_r;
00173 _cache_dir = cache_dir_r;
00174 _subscribed = true;
00175 _base_source = base_source;
00176
00177 MIL << "Setting autorefresh: " << auto_refresh << endl;
00178 _autorefresh = auto_refresh;
00179
00180 try
00181 {
00182 factoryInit();
00183 }
00184 catch ( Exception & excpt )
00185 {
00186 _store.clear();
00187 ZYPP_RETHROW( excpt );
00188 }
00189 }
00190
00192
00193
00194
00195
00196 void SourceImpl::factoryInit()
00197 {
00198 ZYPP_THROW( Exception( "FactoryInit not implemented!" ) );
00199 }
00200
00202
00203
00204
00205
00206 SourceImpl::~SourceImpl()
00207 {
00208 if (_media_set)
00209 {
00210 media::MediaAccessId _media = _media_set->getMediaAccessId( 1 );
00211 media_mgr.release (_media, false);
00212 }
00213 }
00214
00215 bool SourceImpl::enabled() const
00216 {
00217 return _enabled;
00218 }
00219
00220 void SourceImpl::disable()
00221 {
00222 _enabled = false;
00223 }
00224
00225 bool SourceImpl::autorefresh() const
00226 {
00227 return _autorefresh;
00228 }
00229
00230 void SourceImpl::setAutorefresh( bool enable )
00231 {
00232 MIL << "Changing source [" << alias() << "] [" << url() << "] to autorefresh: " << enable << endl;
00233 _autorefresh = enable;
00234 }
00235
00236 const ResStore & SourceImpl::resolvables() const
00237 {
00238 if ( !_res_store_initialized )
00239 {
00240
00241 Source_Ref self( const_cast<SourceImpl*>(this)->selfSourceRef() );
00242 const_cast<SourceImpl*>(this)->createResolvables(self);
00243 const_cast<SourceImpl*>(this)->_res_store_initialized = true;
00244 }
00245 return _store;
00246 }
00247
00248 std::set<zypp::Resolvable::Kind> SourceImpl::resolvableKinds() const
00249 {
00250 return std::set<zypp::Resolvable::Kind>();
00251 }
00252
00253 const ResStore SourceImpl::resolvables(zypp::Resolvable::Kind kind) const
00254 {
00255 Source_Ref self( const_cast<SourceImpl*>(this)->selfSourceRef() );
00256 return const_cast<SourceImpl*>(this)->provideResolvablesByKind(self, kind);
00257 }
00258
00259 Pathname SourceImpl::tmpMetadataDir() const
00260 {
00261 if ( !_tmp_metadata_dir_ptr )
00262 _tmp_metadata_dir_ptr.reset(new filesystem::TmpDir(getZYpp()->tmpPath()));
00263 return _tmp_metadata_dir_ptr->path();
00264 }
00265
00266 Date SourceImpl::timestamp() const
00267 {
00268 return Date::now();
00269 }
00270
00271 std::string SourceImpl::checksum() const
00272 {
00273 return randomString(48);
00274 }
00275
00276 void SourceImpl::dirInfo(const unsigned media_nr,
00277 std::list<std::string> &retlist,
00278 const Pathname &path_r,
00279 bool dots ) const
00280 {
00281 DBG << "reading " << path_r << " file list" << endl;
00282 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00283 media_mgr.dirInfo( _media, retlist, path_r, dots );
00284 }
00285
00286 const Pathname SourceImpl::providePackage( Package::constPtr package )
00287 {
00288 bool retry = true;
00289 bool digest_ok = false;
00290 Pathname file;
00291 callback::SendReport<source::DownloadResolvableReport> report;
00292 DownloadProgressPackageReceiver download_report( report, package );
00293
00294 while (retry)
00295 {
00296 report->start( package, package->source().url() );
00297
00298 callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
00299
00300 try
00301 {
00302 file = provideJustFile( package->location(), package->sourceMediaNr());
00303 }
00304 catch (const Exception &e)
00305 {
00306 ERR << "Failed to provide " << package << " from " << url() << " in source " << alias() << std::endl;
00307 ZYPP_RETHROW (e);
00308 }
00309
00310 report->finish( package, source::DownloadResolvableReport::NO_ERROR, "" );
00311
00312 CheckSum checksum = package->checksum();
00313 std::string calculated_digest;
00314
00315
00316 try
00317 {
00318 std::ifstream is(file.asString().c_str(), std::ifstream::binary);
00319 calculated_digest = Digest::digest(checksum.type(), is);
00320 is.close();
00321 }
00322 catch (std::exception &e)
00323 {
00324 ERR << "Can't open " << file << " for integrity check." << std::endl;
00325 }
00326
00327 if ( checksum.checksum() == calculated_digest )
00328 {
00329 MIL << package->location() << " ok. [" << calculated_digest << "]" << std::endl;
00330 digest_ok = true;
00331 retry = false;
00332 }
00333
00334 if (!digest_ok)
00335 {
00336 std::string package_str = package->name() + "-" + package->edition().asString();
00337
00338
00339 source::DownloadResolvableReport::Action useraction = report->problem(package, source::DownloadResolvableReport::INVALID, str::form(_("Package %s fails integrity check. Do you want to retry downloading it, or abort installation?"), package_str.c_str() ));
00340
00341 if ( useraction == source::DownloadResolvableReport::ABORT )
00342 {
00343 ZYPP_THROW(Exception("Package " + package->location().asString() + " fails integrity check. Expected: [" + checksum.checksum() + "] Read: [" + calculated_digest + "] (" + checksum.type() + ")"));
00344 }
00345 else if ( useraction == source::DownloadResolvableReport::RETRY )
00346 {
00347 retry = true;
00348 }
00349 }
00350 }
00351 return file;
00352 }
00353
00354 void SourceImpl::getPossiblyCachedMetadataFile( const Pathname &file_to_download, const Pathname &destination, const Pathname &cached_file, const CheckSum &checksum )
00355 {
00356 Pathname downloaded_file;
00357 Url file_url( url().asString() + file_to_download.asString() );
00358
00359 if ( PathInfo(cached_file).isExist() && (! checksum.empty()) && is_checksum( cached_file, checksum ) )
00360 {
00361 MIL << "file " << file_url << " found in previous cache. Using cached copy." << std::endl;
00362
00363
00364 if ( filesystem::copy(cached_file, destination) != 0 )
00365 ZYPP_THROW(SourceIOException("Can't copy " + cached_file.asString() + " to " + destination.asString()));
00366 }
00367 else
00368 {
00369 try
00370 {
00371
00372 downloaded_file = provideFile( file_to_download);
00373 }
00374 catch (const Exception & excpt_r)
00375 {
00376 ZYPP_CAUGHT(excpt_r);
00377 ZYPP_THROW(SourceIOException("Can't provide " + downloaded_file.asString() + " : " + excpt_r.msg() ));
00378 }
00379
00380 if ( filesystem::copy(downloaded_file, destination) != 0 )
00381 ZYPP_THROW(SourceIOException("Can't copy " + downloaded_file.asString() + " to " + destination.asString()));
00382
00383 callback::SendReport<DigestReport> report;
00384 if ( checksum.empty() )
00385 {
00386 MIL << "File " << file_url << " has no checksum available." << std::endl;
00387 if ( report->askUserToAcceptNoDigest(file_to_download) )
00388 {
00389 MIL << "User accepted " << file_url << " with no checksum." << std::endl;
00390 return;
00391 }
00392 else
00393 {
00394 ZYPP_THROW(SourceMetadataException( file_url.asString() + " " + N_(" miss checksum.") ));
00395 }
00396 }
00397 else
00398 {
00399 if (! is_checksum( destination, checksum))
00400 ZYPP_THROW(SourceMetadataException( file_url.asString() + " " + N_(" fails checksum verification.") ));
00401 }
00402
00403 }
00404 }
00405
00406 void SourceImpl::resetMediaVerifier()
00407 {
00408 try
00409 {
00410 media::MediaManager media_mgr;
00411 MIL << "Reseting media verifier" << std::endl;
00412
00413
00414 media::MediaAccessId _media = _media_set->getMediaAccessId(1, true);
00415 media_mgr.delVerifier(_media);
00416 media_mgr.addVerifier(_media, media::MediaVerifierRef(new media::NoVerifier()));
00417 }
00418 catch (const Exception & excpt_r)
00419 {
00420 ZYPP_CAUGHT(excpt_r);
00421 WAR << "Media Verifier not found." << endl;
00422 }
00423 }
00424
00425 const Pathname SourceImpl::provideFile(const Pathname & file_r,
00426 const unsigned media_nr,
00427 bool cached,
00428 bool checkonly )
00429 {
00430 bool retry = true;
00431 Pathname downloaded_file;
00432 callback::SendReport<source::SourceReport> report;
00433 DownloadProgressFileReceiver download_report( report );
00434 Url file_url( url().asString() + file_r.asString() );
00435
00436 callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
00437
00438 while (retry)
00439 {
00440
00441 report->start( selfSourceRef(), str::form( _("Downloading %s"), file_url.asString().c_str() ) );
00442 try
00443 {
00444 downloaded_file = provideJustFile(file_r, media_nr, cached, checkonly);
00445 report->finish( selfSourceRef(), str::form( _("Downloading %s"), file_url.asString().c_str() ), SourceReport::NO_ERROR, str::form(_("Downloaded %s from %s"), file_r.asString().c_str(), url().asString().c_str()) );
00446 retry = false;
00447 }
00448 catch ( const SkipRequestedException &e )
00449 {
00450
00451 report->finish( selfSourceRef(), str::form( _("Downloading %s"), file_url.asString().c_str() ), SourceReport::IO, str::form(_("Can't provide %s from %s"), file_r.asString().c_str(), url().asString().c_str()) );
00452 ZYPP_RETHROW(e);
00453 }
00454 catch (const Exception &e)
00455 {
00456
00457 if ( report->problem(selfSourceRef(), SourceReport::IO, str::form(_("Can't provide %s from %s"), file_r.asString().c_str(), url().asString().c_str())) != SourceReport::RETRY )
00458 {
00459 report->finish( selfSourceRef(), str::form( _("Downloading %s"), file_url.asString().c_str() ), SourceReport::IO, str::form(_("Can't provide %s from %s"), file_r.asString().c_str(), url().asString().c_str()) );
00460 ZYPP_THROW(Exception("Can't provide " + file_r.asString() + " from " + url().asString() ));
00461 }
00462 }
00463
00464 }
00465 return downloaded_file;
00466 }
00467
00468 const Pathname SourceImpl::tryToProvideFile( const Pathname & file, const unsigned media_nr )
00469 {
00470 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr);
00471 media_mgr.provideFile (_media, file, false, false);
00472 return media_mgr.localPath( _media, file );
00473 }
00474
00475 void SourceImpl::copyLocalMetadata(const Pathname &src, const Pathname &dst) const
00476 {
00477
00478 if (dst == Pathname("/") )
00479 ZYPP_THROW(Exception("I refuse to use / as local dir"));
00480
00481 if (0 != assert_dir(dst, 0755))
00482 ZYPP_THROW(Exception("Cannot create local directory" + dst.asString()));
00483
00484 MIL << "Cleaning up local dir" << std::endl;
00485 filesystem::clean_dir(dst);
00486 MIL << "Copying " << src << " content to local : " << dst << std::endl;
00487
00488 if ( copy_dir_content( src, dst) != 0)
00489 {
00490 filesystem::clean_dir(dst);
00491 ZYPP_THROW(Exception( "Can't copy downloaded data to local dir. local dir cleaned."));
00492 }
00493 }
00494
00495 const Pathname SourceImpl::provideJustFile(const Pathname & file_r,
00496 const unsigned media_nr,
00497 bool cached,
00498 bool checkonly )
00499 {
00500 callback::SendReport<media::MediaChangeReport> report;
00501
00502 SourceFactory source_factory;
00503
00504
00505 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr, true );
00506 do
00507 {
00508 try
00509 {
00510 DBG << "Going to try provide file " << file_r << " from " << media_nr << endl;
00511
00512
00513 _media = _media_set->getMediaAccessId( media_nr );
00514 media_mgr.provideFile (_media, file_r, cached, checkonly);
00515 break;
00516 }
00517 catch ( Exception & excp )
00518 {
00519 ZYPP_CAUGHT(excp);
00520 media::MediaChangeReport::Action user;
00521
00522 do
00523 {
00524
00525 DBG << "Media couldn't provide file " << file_r << " , releasing." << endl;
00526 try
00527 {
00528 media_mgr.release (_media, false);
00529 }
00530 catch (const Exception & excpt_r)
00531 {
00532 ZYPP_CAUGHT(excpt_r);
00533 MIL << "Failed to release media " << _media << endl;
00534 }
00535 MIL << "Releasing all medias of all sources" << endl;
00536 try
00537 {
00538 zypp::SourceManager::sourceManager()->releaseAllSources();
00539 }
00540 catch (const zypp::Exception& excpt_r)
00541 {
00542 ZYPP_CAUGHT(excpt_r);
00543 ERR << "Failed to release all sources" << endl;
00544 }
00545
00546
00547 media::MediaChangeReport::Error reason
00548 = media::MediaChangeReport::INVALID;
00549
00550 if ( typeid(excp) == typeid( media::MediaFileNotFoundException ) ||
00551 typeid(excp) == typeid( media::MediaNotAFileException ) )
00552 {
00553 reason = media::MediaChangeReport::NOT_FOUND;
00554 }
00555 else if ( typeid(excp) == typeid( media::MediaNotDesiredException) ||
00556 typeid(excp) == typeid( media::MediaNotAttachedException) )
00557 {
00558 reason = media::MediaChangeReport::WRONG;
00559 }
00560
00561 user = checkonly ? media::MediaChangeReport::ABORT :
00562 report->requestMedia (
00563 source_factory.createFrom( this ),
00564 media_nr,
00565 reason,
00566 excp.asUserString()
00567 );
00568
00569 DBG << "ProvideFile exception caught, callback answer: " << user << endl;
00570
00571 if ( user == media::MediaChangeReport::ABORT )
00572 {
00573 DBG << "Aborting" << endl;
00574 ZYPP_RETHROW ( excp );
00575 }
00576 else if ( user == media::MediaChangeReport::IGNORE )
00577 {
00578 DBG << "Skipping" << endl;
00579 ZYPP_THROW ( SkipRequestedException("User-requested skipping of a file") );
00580 }
00581 else if ( user == media::MediaChangeReport::EJECT )
00582 {
00583 DBG << "Eject: try to release" << endl;
00584 try
00585 {
00586 zypp::SourceManager::sourceManager()->releaseAllSources();
00587 }
00588 catch (const zypp::Exception& excpt_r)
00589 {
00590 ZYPP_CAUGHT(excpt_r);
00591 ERR << "Failed to release all sources" << endl;
00592 }
00593
00594 try
00595 {
00596 media_mgr.release (_media, true);
00597 }
00598 catch (const zypp::media::MediaNotEjectedException & excpt_r)
00599 {
00600 ZYPP_CAUGHT(excpt_r);
00601 ERR << "Failed to eject" << endl;
00602 break;
00603 }
00604
00605 }
00606 else if ( user == media::MediaChangeReport::RETRY ||
00607 user == media::MediaChangeReport::CHANGE_URL )
00608 {
00609
00610 DBG << "Going to try again" << endl;
00611
00612
00613
00614
00615 break;
00616 }
00617 else
00618 {
00619 DBG << "Don't know, let's ABORT" << endl;
00620
00621 ZYPP_RETHROW ( excp );
00622 }
00623 }
00624 while ( user == media::MediaChangeReport::EJECT );
00625 }
00626
00627
00628 }
00629 while ( true );
00630
00631 return media_mgr.localPath( _media, file_r );
00632 }
00633
00634 const Pathname SourceImpl::provideDirTree(const Pathname & path_r, const unsigned media_nr)
00635 {
00636 callback::SendReport<media::MediaChangeReport> report;
00637 SourceFactory source_factory;
00638
00639 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr, true );
00640 do
00641 {
00642 try
00643 {
00644 DBG << "Going to try provide tree " << path_r << " from " << media_nr << endl;
00645
00646 _media = _media_set->getMediaAccessId( media_nr );
00647 media_mgr.provideDirTree (_media, path_r);
00648 break;
00649 }
00650 catch ( Exception & excp )
00651 {
00652 ZYPP_CAUGHT(excp);
00653 media::MediaChangeReport::Action user;
00654
00655 do
00656 {
00657 DBG << "Media couldn't provide tree " << path_r << " , releasing." << endl;
00658 try
00659 {
00660 media_mgr.release (_media, false);
00661 }
00662 catch (const Exception & excpt_r)
00663 {
00664 ZYPP_CAUGHT(excpt_r);
00665 MIL << "Failed to release media " << _media << endl;
00666 }
00667 MIL << "Releasing all medias of all sources" << endl;
00668 try
00669 {
00670 zypp::SourceManager::sourceManager()->releaseAllSources();
00671 }
00672 catch (const zypp::Exception& excpt_r)
00673 {
00674 ZYPP_CAUGHT(excpt_r);
00675 ERR << "Failed to release all sources" << endl;
00676 }
00677
00678 media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
00679
00680 if ( typeid(excp) == typeid( media::MediaFileNotFoundException ) || typeid(excp) == typeid( media::MediaNotAFileException ) )
00681 {
00682 reason = media::MediaChangeReport::NOT_FOUND;
00683 }
00684 else if ( typeid(excp) == typeid( media::MediaNotDesiredException) || typeid(excp) == typeid( media::MediaNotAttachedException) )
00685 {
00686 reason = media::MediaChangeReport::WRONG;
00687 }
00688 user = report->requestMedia ( source_factory.createFrom( this ), media_nr, reason, excp.asUserString() );
00689
00690 DBG << "ProvideFile exception caught, callback answer: " << user << endl;
00691
00692 if ( user == media::MediaChangeReport::ABORT )
00693 {
00694 DBG << "Aborting" << endl;
00695 ZYPP_RETHROW ( excp );
00696 }
00697 else if ( user == media::MediaChangeReport::EJECT )
00698 {
00699 DBG << "Eject: try to release" << endl;
00700 try
00701 {
00702 zypp::SourceManager::sourceManager()->releaseAllSources();
00703 }
00704 catch (const zypp::Exception& excpt_r)
00705 {
00706 ZYPP_CAUGHT(excpt_r);
00707 ERR << "Failed to release all sources" << endl;
00708 }
00709 media_mgr.release (_media, true);
00710
00711 }
00712 else if ( user == media::MediaChangeReport::RETRY ||
00713 user == media::MediaChangeReport::CHANGE_URL )
00714 {
00715
00716 DBG << "Going to try again" << endl;
00717
00718
00719
00720
00721 break;
00722 }
00723 else
00724 {
00725 DBG << "Don't know, let's ABORT" << endl;
00726
00727 ZYPP_RETHROW ( excp );
00728 }
00729 }
00730 while ( user == media::MediaChangeReport::EJECT );
00731 }
00732
00733 }
00734 while ( true );
00735 return media_mgr.localPath( _media, path_r );
00736 }
00737
00738 const void SourceImpl::releaseFile(const Pathname & file_r,
00739 const unsigned media_nr)
00740 {
00741 DBG << "releaseFile(" << file_r << ", " << media_nr << ")" << endl;
00742 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00743 media_mgr.releaseFile(_media, file_r);
00744 }
00745
00746 const void SourceImpl::releaseDir(const Pathname & path_r,
00747 const unsigned media_nr,
00748 const bool recursive)
00749 {
00750 DBG << "releaseDir(" << path_r << ", " << media_nr << (recursive?", recursive":"") << ")" << endl;
00751 media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00752 if (recursive)
00753 media_mgr.releasePath(_media, path_r);
00754 else
00755 media_mgr.releaseDir(_media, path_r);
00756 }
00757
00758 void SourceImpl::changeMedia( const media::MediaId & media_r, const Pathname & path_r )
00759 {
00760 DBG << "changeMedia(" << path_r << ")" << endl;
00761 _url = media_mgr.url( media_r );
00762 _media_set->reset();
00763 _media_set->redirect( 1, media_r );
00764 _path = path_r;
00765 }
00766
00767 void SourceImpl::enable()
00768 {
00769
00770
00771 _enabled = true;
00772 }
00773
00774 void SourceImpl::createResolvables(Source_Ref source_r)
00775 {
00776 WAR << "createResolvables not implemented by the source" << endl;
00777 }
00778
00779 ResStore SourceImpl::provideResolvablesByKind(Source_Ref source_r, zypp::Resolvable::Kind kind)
00780 {
00781 WAR << "provideResolvablesByKind not implemented by the source" << endl;
00782 return ResStore();
00783 }
00784
00785 void SourceImpl::storeMetadata(const Pathname & cache_dir_r)
00786 {}
00787
00788 void SourceImpl::refresh()
00789 {
00790 MIL << "Refreshing" << endl;
00791
00792
00793 try
00794 {
00795 storeMetadata( _cache_dir );
00796 }
00797 catch ( const zypp::Exception & excpt )
00798 {
00799 ERR << "Unable to refresh the source cache" << endl;
00800 if ( ! _cache_dir.empty() && _cache_dir != "/" )
00801 filesystem::clean_dir( _cache_dir );
00802
00803 ZYPP_RETHROW( excpt );
00804 }
00805 }
00806
00807 void SourceImpl::redirect(unsigned media_nr, const Url & new_url)
00808 {
00809 DBG << "redirect(" << new_url << ")" << endl;
00810 media::MediaAccessId id = media_mgr.open( new_url );
00811 _media_set->redirect( media_nr, id );
00812 }
00813 void SourceImpl::reattach(const Pathname &attach_point)
00814 {
00815 DBG << "reattach(" << attach_point << ")" << endl;
00816 _media_set->reattach( attach_point );
00817 }
00818
00819 void SourceImpl::release()
00820 {
00821 if (_media_set)
00822 _media_set->release();
00823 }
00824
00825 media::MediaVerifierRef SourceImpl::verifier(unsigned media_nr)
00826 {
00827 return media::MediaVerifierRef(new media::NoVerifier());
00828 }
00829
00831
00832
00833 std::string SourceImpl::type (void) const
00834 {
00835 return "undefined";
00836 }
00837
00838 std::string SourceImpl::id (void) const
00839 {
00840 return _id;
00841 }
00842
00843 void SourceImpl::setId (const std::string id_r)
00844 {
00845 _id = id_r;
00846 }
00847
00848 unsigned SourceImpl::priority (void) const
00849 {
00850 return _priority;
00851 }
00852
00853 void SourceImpl::setPriority (unsigned p)
00854 {
00855 _priority = p;
00856 }
00857
00858 unsigned SourceImpl::priorityUnsubscribed (void) const
00859 {
00860 return _priority_unsubscribed;
00861 }
00862
00863 void SourceImpl::setPriorityUnsubscribed (unsigned p)
00864 {
00865 _priority_unsubscribed = p;
00866 }
00867
00868 bool SourceImpl::subscribed (void) const
00869 {
00870 return _subscribed;
00871 }
00872
00873 void SourceImpl::setSubscribed (bool s)
00874 {
00875 _subscribed = s;
00876 }
00877
00878 const Pathname & SourceImpl::cacheDir (void)
00879 {
00880 return _cache_dir;
00881 }
00882
00883 Url SourceImpl::url (void) const
00884 {
00885 return _url;
00886 }
00887
00888 void SourceImpl::setUrl( const Url & url )
00889 {
00890 _url = url;
00891 }
00892
00893 bool SourceImpl::remote() const
00894 {
00895 bool downloads = false;
00896 try
00897 {
00898 downloads = media::MediaManager::downloads(_url);
00899 }
00900 catch (const zypp::Exception &e)
00901 {
00902
00903 ZYPP_CAUGHT(e);
00904 }
00905 return downloads;
00906 }
00907
00908 const Pathname & SourceImpl::path (void) const
00909 {
00910 return _path;
00911 }
00912
00913 unsigned SourceImpl::numberOfMedia(void) const
00914 {
00915 return 1;
00916 }
00917
00918 std::string SourceImpl::vendor (void) const
00919 {
00920 return "";
00921 }
00922
00923 const std::list<Pathname> SourceImpl::publicKeys()
00924 {
00925 return std::list<Pathname>();
00926 }
00927
00928 std::string SourceImpl::unique_id (void) const
00929 {
00930 return "";
00931 }
00932
00934
00938 std::string SourceImpl::zmdName (void) const
00939 {
00940 return "zmdname";
00941 }
00942
00943 void SourceImpl::setZmdName (const std::string name_r)
00944 {
00945 return;
00946 }
00947
00948 std::string SourceImpl::zmdDescription (void) const
00949 {
00950 return "zmddescription";
00951 }
00952
00953 void SourceImpl::setZmdDescription (const std::string desc_r)
00954 {
00955 return;
00956 }
00957
00959
00960 std::ostream & SourceImpl::dumpOn( std::ostream & str ) const
00961 {
00962 str << "Source[" << numericId() << "|" << type();
00963 if ( !_alias.empty() )
00964 str << "|" << _alias;
00965 str << "]";
00966
00967 str << "{"
00968 << _url << "(" << _path << ")";
00969 if ( ! _cache_dir.empty() )
00970 str << "; cache " << _cache_dir;
00971
00972 str << "; autorefresh: " << _autorefresh;
00973 str << "; enabled: " << _enabled;
00974 str << "}";
00975
00976 return str;
00977 }
00978
00979 SourceImpl::Verifier::Verifier(const std::string & vendor_r, const std::string & id_r, const media::MediaNr media_nr)
00980 : _media_vendor(vendor_r)
00981 , _media_id(id_r)
00982 , _media_nr(media_nr)
00983 {}
00984
00985 bool SourceImpl::Verifier::isDesiredMedia(const media::MediaAccessRef &ref)
00986 {
00987 if (_media_vendor.empty() || _media_id.empty())
00988 return true;
00989 #warning TODO define what does missing media_id/media_vendor mean
00990
00991 Pathname media_file = "/media." + str::numstring(_media_nr) + "/media";
00992 ref->provideFile (media_file);
00993 media_file = ref->localPath(media_file);
00994 std::ifstream str(media_file.asString().c_str());
00995 std::string vendor;
00996 std::string id;
00997
00998 #warning check the stream status
00999 getline(str, vendor);
01000 getline(str, id);
01001
01002 return (vendor == _media_vendor && id == _media_id );
01003 }
01004
01006 }
01009 }