1
/*---------------------------------------------------------------------\
3
| |__ / \ / / . \ . \ |
8
\---------------------------------------------------------------------*/
11
#include "zypp/base/String.h"
12
#include "zypp/base/Logger.h"
13
#include "zypp/base/Function.h"
15
#include "zypp/Date.h"
17
#include "zypp/parser/yum/RepomdFileReader.h"
18
#include "zypp/parser/yum/PatchesFileReader.h"
19
#include "Downloader.h"
20
#include "zypp/repo/MediaInfoDownloader.h"
21
#include "zypp/base/UserRequestException.h"
22
#include "zypp/parser/xml/Reader.h"
23
#include "zypp/KeyContext.h"
26
using namespace zypp::xml;
27
using namespace zypp::parser::yum;
36
Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
37
: repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
42
RepoStatus Downloader::status( MediaSetAccess &media )
44
Pathname repomd = media.provideFile( repoInfo().path() + "/repodata/repomd.xml");
45
return RepoStatus(repomd);
48
static OnMediaLocation
49
loc_with_path_prefix(const OnMediaLocation & loc,
50
const Pathname & prefix)
52
if (prefix.empty() || prefix == "/")
55
OnMediaLocation loc_with_path(loc);
56
loc_with_path.changeFilename(prefix / loc.filename());
60
// search old repository file file to run the delta algorithm on
61
static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
64
if (!PathInfo(dir).isDir())
66
string base = file.basename();
67
size_t hypoff = base.find("-");
68
if (hypoff != string::npos)
69
base.replace(0, hypoff + 1, "");
70
size_t basesize = base.size();
71
std::list<Pathname> retlist;
72
if (!filesystem::readdir(retlist, dir, false))
74
for_( it, retlist.begin(), retlist.end() )
76
string fn = it->asString();
77
if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
84
bool Downloader::patches_Callback( const OnMediaLocation &loc,
87
OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
88
MIL << id << " : " << loc_with_path << endl;
89
this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
93
bool Downloader::repomd_Callback( const OnMediaLocation &loc,
94
const ResourceType &dtype )
96
OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
97
MIL << dtype << " : " << loc_with_path << endl;
99
//! \todo do this through a ZConfig call so that it is always in sync with parser
101
if ( dtype == ResourceType::OTHER )
103
MIL << "Skipping other.xml" << endl;
107
if ( dtype == ResourceType::FILELISTS )
109
MIL << "Skipping filelists.xml.gz" << endl;
113
this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
115
// We got a patches file we need to read, to add patches listed
116
// there, so we transfer what we have in the queue, and
117
// queue the patches in the patches callback
118
if ( dtype == ResourceType::PATCHES )
120
this->start( _dest_dir, *_media_ptr );
121
// now the patches.xml file must exists
122
PatchesFileReader( _dest_dir + repoInfo().path() + loc.filename(),
123
bind( &Downloader::patches_Callback, this, _1, _2));
129
void Downloader::download( MediaSetAccess &media,
130
const Pathname &dest_dir,
131
const ProgressData::ReceiverFnc & progressrcv )
133
Pathname repomdpath = repoInfo().path() + "/repodata/repomd.xml";
134
Pathname keypath = repoInfo().path() + "/repodata/repomd.xml.key";
135
Pathname sigpath = repoInfo().path() + "/repodata/repomd.xml.asc";
137
_media_ptr = (&media);
139
ProgressData progress;
140
progress.sendTo(progressrcv);
143
//downloadMediaInfo( dest_dir, _media );
145
_dest_dir = dest_dir;
147
#warning Do we need SignatureFileChecker(string descr)?
148
SignatureFileChecker sigchecker/*(repoInfo().name())*/;
150
this->enqueue( OnMediaLocation(sigpath,1).setOptional(true) );
151
this->start( dest_dir, *_media_ptr);
152
// only add the signature if it exists
153
if ( PathInfo(dest_dir / sigpath).isExist() )
154
sigchecker = SignatureFileChecker(dest_dir / sigpath);
157
this->enqueue( OnMediaLocation(keypath,1).setOptional(true) );
158
this->start( dest_dir, *_media_ptr);
161
context.setRepoInfo(repoInfo());
162
// only add the key if it exists
163
if ( PathInfo(dest_dir / keypath).isExist() )
164
sigchecker.addPublicKey(dest_dir + keypath, context);
165
// set the checker context even if the key is not known (unsigned repo, key
166
// file missing; bnc #495977)
168
sigchecker.setKeyContext(context);
172
if ( ! progress.tick() )
173
ZYPP_THROW(AbortRequestException());
175
if ( ! repoInfo().gpgCheck() )
176
WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
178
this->enqueue( OnMediaLocation(repomdpath,1),
179
repoInfo().gpgCheck() ? FileChecker(sigchecker) : FileChecker(NullFileChecker()) );
180
this->start( dest_dir, *_media_ptr);
182
if ( ! progress.tick() )
183
ZYPP_THROW(AbortRequestException());
187
Reader reader( dest_dir + repoInfo().path() + "/repodata/repomd.xml" );
188
RepomdFileReader( dest_dir + repoInfo().path() + "/repodata/repomd.xml", bind( &Downloader::repomd_Callback, this, _1, _2));
191
this->start( dest_dir, *_media_ptr);