1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
11 #include "zypp/base/String.h"
12 #include "zypp/base/Logger.h"
13 #include "zypp/base/Function.h"
15 #include "zypp/parser/yum/RepomdFileReader.h"
16 #include "zypp/parser/yum/PatchesFileReader.h"
17 #include "Downloader.h"
18 #include "zypp/repo/MediaInfoDownloader.h"
19 #include "zypp/base/UserRequestException.h"
20 #include "zypp/parser/xml/Reader.h"
23 using namespace zypp::xml;
24 using namespace zypp::parser::yum;
33 Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
34 : repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
39 RepoStatus Downloader::status( MediaSetAccess &media )
41 Pathname repomd = media.provideFile( repoInfo().path() + "/repodata/repomd.xml");
42 return RepoStatus(repomd);
45 static OnMediaLocation
46 loc_with_path_prefix(const OnMediaLocation & loc,
47 const Pathname & prefix)
49 if (prefix.empty() || prefix == "/")
52 OnMediaLocation loc_with_path(loc);
53 loc_with_path.changeFilename(prefix / loc.filename());
57 // search old repository file file to run the delta algorithm on
58 static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
61 if (!PathInfo(dir).isDir())
63 string base = file.basename();
64 size_t hypoff = base.find("-");
65 if (hypoff != string::npos)
66 base.replace(0, hypoff + 1, "");
67 size_t basesize = base.size();
68 std::list<Pathname> retlist;
69 if (!filesystem::readdir(retlist, dir, false))
71 for_( it, retlist.begin(), retlist.end() )
73 string fn = it->asString();
74 if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
81 bool Downloader::patches_Callback( const OnMediaLocation &loc,
84 OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
85 MIL << id << " : " << loc_with_path << endl;
86 this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
90 bool Downloader::repomd_Callback( const OnMediaLocation &loc,
91 const ResourceType &dtype )
93 OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
94 MIL << dtype << " : " << loc_with_path << endl;
96 //! \todo do this through a ZConfig call so that it is always in sync with parser
98 if ( dtype == ResourceType::OTHER )
100 MIL << "Skipping other.xml" << endl;
104 if ( dtype == ResourceType::FILELISTS )
106 MIL << "Skipping filelists.xml.gz" << endl;
110 this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
112 // We got a patches file we need to read, to add patches listed
113 // there, so we transfer what we have in the queue, and
114 // queue the patches in the patches callback
115 if ( dtype == ResourceType::PATCHES )
117 this->start( _dest_dir, *_media_ptr );
118 // now the patches.xml file must exists
119 PatchesFileReader( _dest_dir + repoInfo().path() + loc.filename(),
120 bind( &Downloader::patches_Callback, this, _1, _2));
126 /** \todo: Downloading/sigcheck of master index shoudl be common in base class */
127 void Downloader::download( MediaSetAccess &media,
128 const Pathname &dest_dir,
129 const ProgressData::ReceiverFnc & progressrcv )
131 Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
132 defaultDownloadMasterIndex( media, dest_dir, masterIndex );
134 _media_ptr = (&media);
135 _dest_dir = dest_dir;
136 RepomdFileReader( dest_dir / masterIndex, bind( &Downloader::repomd_Callback, this, _1, _2));
139 start( dest_dir, media );