#include "zypp/base/Logger.h"
#include "zypp/base/Function.h"
-#include "zypp/Date.h"
-
#include "zypp/parser/yum/RepomdFileReader.h"
#include "zypp/parser/yum/PatchesFileReader.h"
#include "Downloader.h"
+#include "zypp/repo/MediaInfoDownloader.h"
#include "zypp/base/UserRequestException.h"
+#include "zypp/parser/xml/Reader.h"
using namespace std;
using namespace zypp::xml;
namespace yum
{
-Downloader::Downloader( const Url &url, const Pathname &path )
- : _url(url), _path(path), _media(url, path)
+Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
+ : repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
{
}
-RepoStatus Downloader::status()
+
+RepoStatus Downloader::status( MediaSetAccess &media )
{
- Pathname repomd = _media.provideFile("/repodata/repomd.xml");
+ Pathname repomd = media.provideFile( repoInfo().path() + "/repodata/repomd.xml");
return RepoStatus(repomd);
}
-bool Downloader::patches_Callback( const OnMediaLocation &loc, const string &id )
+static OnMediaLocation
+loc_with_path_prefix(const OnMediaLocation & loc,
+ const Pathname & prefix)
{
- MIL << id << " : " << loc << endl;
- _fetcher.enqueueDigested(loc);
- return true;
+ if (prefix.empty() || prefix == "/")
+ return loc;
+
+ OnMediaLocation loc_with_path(loc);
+ loc_with_path.changeFilename(prefix / loc.filename());
+ return loc_with_path;
}
+// search old repository file file to run the delta algorithm on
+static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
+{
+ Pathname deltafile;
+ if (!PathInfo(dir).isDir())
+ return deltafile;
+ string base = file.basename();
+ size_t hypoff = base.find("-");
+ if (hypoff != string::npos)
+ base.replace(0, hypoff + 1, "");
+ size_t basesize = base.size();
+ std::list<Pathname> retlist;
+ if (!filesystem::readdir(retlist, dir, false))
+ {
+ for_( it, retlist.begin(), retlist.end() )
+ {
+ string fn = it->asString();
+ if (fn.size() >= basesize && fn.substr(fn.size() - basesize, basesize) == base)
+ deltafile = *it;
+ }
+ }
+ return deltafile;
+}
-bool Downloader::repomd_Callback( const OnMediaLocation &loc, const ResourceType &dtype )
+bool Downloader::patches_Callback( const OnMediaLocation &loc,
+ const string &id )
{
- MIL << dtype << " : " << loc << endl;
-
+ OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
+ MIL << id << " : " << loc_with_path << endl;
+ this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
+ return true;
+}
+
+bool Downloader::repomd_Callback( const OnMediaLocation &loc,
+ const ResourceType &dtype )
+{
+ OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
+ MIL << dtype << " : " << loc_with_path << endl;
+
+ //! \todo do this through a ZConfig call so that it is always in sync with parser
// skip other
if ( dtype == ResourceType::OTHER )
{
MIL << "Skipping other.xml" << endl;
return true;
}
-
- _fetcher.enqueueDigested(loc);
-
+ // skip filelists
+ if ( dtype == ResourceType::FILELISTS )
+ {
+ MIL << "Skipping filelists.xml.gz" << endl;
+ return true;
+ }
+
+ this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
+
// We got a patches file we need to read, to add patches listed
- // there, so we transfer what we have in the queue, and
+ // there, so we transfer what we have in the queue, and
// queue the patches in the patches callback
if ( dtype == ResourceType::PATCHES )
{
- _fetcher.start( _dest_dir, _media);
+ this->start( _dest_dir, *_media_ptr );
// now the patches.xml file must exists
- PatchesFileReader( _dest_dir + loc.filename(), bind( &Downloader::patches_Callback, this, _1, _2));
+ PatchesFileReader( _dest_dir + repoInfo().path() + loc.filename(),
+ bind( &Downloader::patches_Callback, this, _1, _2));
}
-
+
return true;
}
-void Downloader::download( const Pathname &dest_dir,
+/** \todo: Downloading/sigcheck of master index shoudl be common in base class */
+void Downloader::download( MediaSetAccess &media,
+ const Pathname &dest_dir,
const ProgressData::ReceiverFnc & progressrcv )
{
- Pathname repomdpath = "/repodata/repomd.xml";
- Pathname keypath = "/repodata/repomd.xml.key";
- Pathname sigpath = "/repodata/repomd.xml.asc";
-
- ProgressData progress;
- progress.sendTo(progressrcv);
- progress.toMin();
+ Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
+ defaultDownloadMasterIndex( media, dest_dir, masterIndex );
+ _media_ptr = (&media);
_dest_dir = dest_dir;
- if ( _media.doesFileExist(keypath) )
- _fetcher.enqueue( OnMediaLocation().setFilename(keypath) );
-
- if ( _media.doesFileExist(sigpath) )
- _fetcher.enqueue( OnMediaLocation().setFilename(sigpath) );
-
- _fetcher.start( dest_dir, _media );
-
- if ( ! progress.tick() )
- ZYPP_THROW(AbortRequestException());
-
- SignatureFileChecker sigchecker;
-
- if ( PathInfo( dest_dir + sigpath ).isExist() )
- sigchecker = SignatureFileChecker(dest_dir + sigpath);
-
- if ( PathInfo( dest_dir + keypath ).isExist() )
- sigchecker.addPublicKey(dest_dir + keypath );
-
- _fetcher.enqueue( OnMediaLocation().setFilename(repomdpath), sigchecker );
- _fetcher.start( dest_dir, _media);
-
- if ( ! progress.tick() )
- ZYPP_THROW(AbortRequestException());
-
- _fetcher.reset();
-
- Reader reader( dest_dir + "/repodata/repomd.xml" );
- RepomdFileReader( dest_dir + "/repodata/repomd.xml", bind( &Downloader::repomd_Callback, this, _1, _2));
+ RepomdFileReader( dest_dir / masterIndex, bind( &Downloader::repomd_Callback, this, _1, _2));
// ready, go!
- _fetcher.start( dest_dir, _media);
- progress.toMax();
+ start( dest_dir, media );
}
}// ns yum
-}// ns source
+}// ns source
} // ns zypp