~thopiekar/zypper/libzypp-manual-import

« back to all changes in this revision

Viewing changes to zypp/repo/yum/Downloader.cc

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-01-29 22:44:28 UTC
  • Revision ID: thopiekar@googlemail.com-20140129224428-gpcqnsdakby362n8
firstĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*---------------------------------------------------------------------\
 
2
|                          ____ _   __ __ ___                          |
 
3
|                         |__  / \ / / . \ . \                         |
 
4
|                           / / \ V /|  _/  _/                         |
 
5
|                          / /__ | | | | | |                           |
 
6
|                         /_____||_| |_| |_|                           |
 
7
|                                                                      |
 
8
\---------------------------------------------------------------------*/
 
9
 
 
10
#include <fstream>
 
11
#include "zypp/base/String.h"
 
12
#include "zypp/base/Logger.h"
 
13
#include "zypp/base/Function.h"
 
14
 
 
15
#include "zypp/Date.h"
 
16
 
 
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"
 
24
 
 
25
using namespace std;
 
26
using namespace zypp::xml;
 
27
using namespace zypp::parser::yum;
 
28
 
 
29
namespace zypp
 
30
{
 
31
namespace repo
 
32
{
 
33
namespace yum
 
34
{
 
35
 
 
36
Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
 
37
  : repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
 
38
{
 
39
}
 
40
 
 
41
 
 
42
RepoStatus Downloader::status( MediaSetAccess &media )
 
43
{
 
44
  Pathname repomd = media.provideFile( repoInfo().path() + "/repodata/repomd.xml");
 
45
  return RepoStatus(repomd);
 
46
}
 
47
 
 
48
static OnMediaLocation
 
49
loc_with_path_prefix(const OnMediaLocation & loc,
 
50
                     const Pathname & prefix)
 
51
{
 
52
  if (prefix.empty() || prefix == "/")
 
53
    return loc;
 
54
 
 
55
  OnMediaLocation loc_with_path(loc);
 
56
  loc_with_path.changeFilename(prefix / loc.filename());
 
57
  return loc_with_path;
 
58
}
 
59
 
 
60
// search old repository file file to run the delta algorithm on
 
61
static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
 
62
{
 
63
  Pathname deltafile;
 
64
  if (!PathInfo(dir).isDir())
 
65
    return deltafile;
 
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))
 
73
  {
 
74
    for_( it, retlist.begin(), retlist.end() )
 
75
    {
 
76
      string fn = it->asString();
 
77
      if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
 
78
        deltafile = *it;
 
79
    }
 
80
  }
 
81
  return deltafile;
 
82
}
 
83
 
 
84
bool Downloader::patches_Callback( const OnMediaLocation &loc,
 
85
                                   const string &id )
 
86
{
 
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()));
 
90
  return true;
 
91
}
 
92
 
 
93
bool Downloader::repomd_Callback( const OnMediaLocation &loc,
 
94
                                  const ResourceType &dtype )
 
95
{
 
96
  OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
 
97
  MIL << dtype << " : " << loc_with_path << endl;
 
98
 
 
99
  //! \todo do this through a ZConfig call so that it is always in sync with parser
 
100
  // skip other
 
101
  if ( dtype == ResourceType::OTHER )
 
102
  {
 
103
    MIL << "Skipping other.xml" << endl;
 
104
    return true;
 
105
  }
 
106
  // skip filelists
 
107
  if ( dtype == ResourceType::FILELISTS )
 
108
  {
 
109
    MIL << "Skipping filelists.xml.gz" << endl;
 
110
    return true;
 
111
  }
 
112
 
 
113
  this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
 
114
 
 
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 )
 
119
  {
 
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));
 
124
  }
 
125
 
 
126
  return true;
 
127
}
 
128
 
 
129
void Downloader::download( MediaSetAccess &media,
 
130
                           const Pathname &dest_dir,
 
131
                           const ProgressData::ReceiverFnc & progressrcv )
 
132
{
 
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";
 
136
 
 
137
  _media_ptr = (&media);
 
138
 
 
139
  ProgressData progress;
 
140
  progress.sendTo(progressrcv);
 
141
  progress.toMin();
 
142
 
 
143
  //downloadMediaInfo( dest_dir, _media );
 
144
 
 
145
  _dest_dir = dest_dir;
 
146
 
 
147
#warning Do we need SignatureFileChecker(string descr)?
 
148
  SignatureFileChecker sigchecker/*(repoInfo().name())*/;
 
149
 
 
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);
 
155
  this->reset();
 
156
 
 
157
  this->enqueue( OnMediaLocation(keypath,1).setOptional(true) );
 
158
  this->start( dest_dir, *_media_ptr);
 
159
 
 
160
  KeyContext context;
 
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)
 
167
  else
 
168
    sigchecker.setKeyContext(context);
 
169
 
 
170
  this->reset();
 
171
 
 
172
  if ( ! progress.tick() )
 
173
    ZYPP_THROW(AbortRequestException());
 
174
 
 
175
  if ( ! repoInfo().gpgCheck() )
 
176
    WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
 
177
 
 
178
  this->enqueue( OnMediaLocation(repomdpath,1),
 
179
                 repoInfo().gpgCheck() ? FileChecker(sigchecker) : FileChecker(NullFileChecker()) );
 
180
  this->start( dest_dir, *_media_ptr);
 
181
 
 
182
  if ( ! progress.tick() )
 
183
        ZYPP_THROW(AbortRequestException());
 
184
 
 
185
  this->reset();
 
186
 
 
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));
 
189
 
 
190
  // ready, go!
 
191
  this->start( dest_dir, *_media_ptr);
 
192
  progress.toMax();
 
193
}
 
194
 
 
195
}// ns yum
 
196
}// ns source
 
197
} // ns zypp
 
198
 
 
199
 
 
200