#include <apt-pkg/version.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/sptr.h>
+#include <apt-pkg/md5.h>
#include <apt-pkg/versionmatch.h>
#include <config.h>
#include "acqprogress.h"
+#include <set>
#include <locale.h>
#include <langinfo.h>
#include <fstream>
ostream c1out(0);
ostream c2out(0);
ofstream devnull("/dev/null");
-unsigned int ScreenWidth = 80;
+unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
// class CacheFile - Cover class for some dependency cache functions /*{{{*/
// ---------------------------------------------------------------------
string VerTag;
string TmpSrc = Name;
string::size_type Slash = TmpSrc.rfind('=');
+
+ // honor default release
+ string DefRel = _config->Find("APT::Default-Release");
+ pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
+
if (Slash != string::npos)
{
VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
+ }
+ else if(!Pkg.end() && DefRel.empty() == false)
+ {
+ // we have a default release, try to locate the pkg. we do it like
+ // this because GetCandidateVer() will not "downgrade", that means
+ // "apt-get source -t stable apt" won't work on a unstable system
+ for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false;
+ Ver++)
+ {
+ for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false;
+ VF++)
+ {
+ /* If this is the status file, and the current version is not the
+ version in the status file (ie it is not installed, or somesuch)
+ then it is not a candidate for installation, ever. This weeds
+ out bogus entries that may be due to config-file states, or
+ other. */
+ if ((VF.File()->Flags & pkgCache::Flag::NotSource) ==
+ pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver)
+ continue;
+
+ //std::cout << VF.File().Archive() << std::endl;
+ if(VF.File().Archive() && (VF.File().Archive() == DefRel))
+ {
+ VerTag = Ver.VerStr();
+ break;
+ }
+ }
+ }
}
-
+
/* Lookup the version of the package we would install if we were to
install a version and determine the source package name, then look
- in the archive for a source package of the same name. In theory
- we could stash the version string as well and match that too but
- today there aren't multi source versions in the archive. */
- if (_config->FindB("APT::Get::Only-Source") == false &&
- VerTag.empty() == true)
+ in the archive for a source package of the same name. */
+ if (_config->FindB("APT::Get::Only-Source") == false)
{
- pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
if (Pkg.end() == false)
{
- pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
+ pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
if (Ver.end() == false)
{
pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
}
}
- if (Last == 0)
- return 0;
-
- if (Last->Jump(Offset) == false)
+ if (Last == 0 || Last->Jump(Offset) == false)
return 0;
return Last;
return _error->Error(_("Unable to lock the list directory"));
}
- // Create the download object
+ // Create the progress
AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
- pkgAcquire Fetcher(&Stat);
-
-
+
// Just print out the uris an exit if the --print-uris flag was used
if (_config->FindB("APT::Get::Print-URIs") == true)
{
+ // get a fetcher
+ pkgAcquire Fetcher(&Stat);
+
// Populate it with the source selection and get all Indexes
// (GetAll=true)
if (List.GetIndexes(&Fetcher,true) == false)
return true;
}
- // Populate it with the source selection
- if (List.GetIndexes(&Fetcher) == false)
- return false;
-
- // Run it
- if (Fetcher.Run() == pkgAcquire::Failed)
- return false;
-
- bool Failed = false;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone)
- continue;
-
- (*I)->Finished();
-
- fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
- (*I)->ErrorText.c_str());
- Failed = true;
- }
-
- // Clean out any old list files
- if (_config->FindB("APT::Get::List-Cleanup",true) == true)
- {
- if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
- Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
- return false;
- }
-
- // Prepare the cache.
+ // do the work
CacheFile Cache;
+ bool res = Cache.ListUpdate(Stat, List);
+
+ // Rebuild the cache.
if (Cache.BuildCaches() == false)
return false;
- if (Failed == true)
+ if (res == false)
return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
return true;
/* Install named packages */
bool DoInstall(CommandLine &CmdL)
{
- // Lock the list directory
- FileFd Lock;
- if (_config->FindB("Debug::NoLocking",false) == false)
- {
- Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
- if (_error->PendingError() == true)
- return _error->Error(_("Unable to lock the list directory"));
- }
-
CacheFile Cache;
if (Cache.OpenForInstall() == false ||
Cache.CheckDeps(CmdL.FileSize() != 1) == false)
// See if we need to prompt
if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
return InstallPackages(Cache,false,false);
-
+
return InstallPackages(Cache,false);
}
/*}}}*/
DscFile *Dsc = new DscFile[CmdL.FileSize()];
+ // insert all downloaded uris into this set to avoid downloading them
+ // twice
+ set<string> queued;
// Load the requestd sources into the fetcher
unsigned J = 0;
for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
if (_config->FindB("APT::Get::Tar-Only",false) == true &&
I->Type != "tar")
continue;
-
+
+ // don't download the same uri twice (should this be moved to
+ // the fetcher interface itself?)
+ if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end())
+ continue;
+ queued.insert(Last->Index().ArchiveURI(I->Path));
+
+ // check if we have a file with that md5 sum already localy
+ if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))
+ {
+ FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly);
+ MD5Summation sum;
+ sum.AddFD(Fd.Fd(), Fd.Size());
+ Fd.Close();
+ if((string)sum.Result() == I->MD5Hash)
+ {
+ ioprintf(c1out,_("Skipping already downloaded file '%s'\n"),
+ flNotDir(I->Path).c_str());
+ continue;
+ }
+ }
+
new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
I->MD5Hash,I->Size,
Last->Index().SourceInfo(*Last,*I),Src);
if (system(S) != 0)
{
fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
+ fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n"));
_exit(1);
}
}