Browse Source

Merge remote-tracking branch 'upstream/debian/experimental' into feature/srv-records

debian/1.8.y
Michael Vogt 7 years ago
parent
commit
b53c9cea29
  1. 6
      .travis.yml
  2. 15
      Makefile
  3. 4
      apt-inst/contrib/arfile.h
  4. 5
      apt-inst/contrib/extracttar.cc
  5. 8
      apt-inst/contrib/extracttar.h
  6. 8
      apt-inst/deb/debfile.cc
  7. 14
      apt-inst/deb/debfile.h
  8. 12
      apt-inst/dirstream.h
  9. 6
      apt-inst/extract.h
  10. 2
      apt-inst/makefile
  11. 4162
      apt-pkg/acquire-item.cc
  12. 873
      apt-pkg/acquire-item.h
  13. 27
      apt-pkg/acquire-method.cc
  14. 14
      apt-pkg/acquire-method.h
  15. 409
      apt-pkg/acquire-worker.cc
  16. 8
      apt-pkg/acquire-worker.h
  17. 163
      apt-pkg/acquire.cc
  18. 60
      apt-pkg/acquire.h
  19. 42
      apt-pkg/algorithms.cc
  20. 32
      apt-pkg/algorithms.h
  21. 3
      apt-pkg/aptconfiguration.cc
  22. 23
      apt-pkg/aptconfiguration.h
  23. 41
      apt-pkg/cachefile.cc
  24. 30
      apt-pkg/cachefile.h
  25. 60
      apt-pkg/cachefilter.h
  26. 201
      apt-pkg/cacheiterators.h
  27. 135
      apt-pkg/cacheset.cc
  28. 527
      apt-pkg/cacheset.h
  29. 13
      apt-pkg/cdrom.cc
  30. 11
      apt-pkg/cdrom.h
  31. 3
      apt-pkg/clean.cc
  32. 4
      apt-pkg/clean.h
  33. 2
      apt-pkg/contrib/cdromutl.cc
  34. 8
      apt-pkg/contrib/cmndline.cc
  35. 10
      apt-pkg/contrib/configuration.cc
  36. 11
      apt-pkg/contrib/configuration.h
  37. 81
      apt-pkg/contrib/fileutl.cc
  38. 32
      apt-pkg/contrib/fileutl.h
  39. 19
      apt-pkg/contrib/gpgv.cc
  40. 5
      apt-pkg/contrib/gpgv.h
  41. 52
      apt-pkg/contrib/hashes.cc
  42. 18
      apt-pkg/contrib/hashes.h
  43. 2
      apt-pkg/contrib/hashsum_template.h
  44. 10
      apt-pkg/contrib/macros.h
  45. 2
      apt-pkg/contrib/md5.h
  46. 5
      apt-pkg/contrib/progress.h
  47. 2
      apt-pkg/contrib/sha1.h
  48. 6
      apt-pkg/contrib/sha2.h
  49. 12
      apt-pkg/contrib/sptr.h
  50. 19
      apt-pkg/contrib/strutl.cc
  51. 1
      apt-pkg/contrib/strutl.h
  52. 779
      apt-pkg/deb/debindexfile.cc
  53. 205
      apt-pkg/deb/debindexfile.h
  54. 162
      apt-pkg/deb/deblistparser.cc
  55. 56
      apt-pkg/deb/deblistparser.h
  56. 1008
      apt-pkg/deb/debmetaindex.cc
  57. 98
      apt-pkg/deb/debmetaindex.h
  58. 13
      apt-pkg/deb/debrecords.cc
  59. 41
      apt-pkg/deb/debrecords.h
  60. 4
      apt-pkg/deb/debsrcrecords.cc
  61. 30
      apt-pkg/deb/debsrcrecords.h
  62. 5
      apt-pkg/deb/debsystem.cc
  63. 18
      apt-pkg/deb/debsystem.h
  64. 48
      apt-pkg/deb/debversion.cc
  65. 9
      apt-pkg/deb/debversion.h
  66. 27
      apt-pkg/deb/dpkgpm.cc
  67. 14
      apt-pkg/deb/dpkgpm.h
  68. 276
      apt-pkg/depcache.cc
  69. 41
      apt-pkg/depcache.h
  70. 154
      apt-pkg/edsp.cc
  71. 44
      apt-pkg/edsp.h
  72. 83
      apt-pkg/edsp/edspindexfile.cc
  73. 27
      apt-pkg/edsp/edspindexfile.h
  74. 9
      apt-pkg/edsp/edsplistparser.cc
  75. 16
      apt-pkg/edsp/edsplistparser.h
  76. 21
      apt-pkg/edsp/edspsystem.cc
  77. 22
      apt-pkg/edsp/edspsystem.h
  78. 31
      apt-pkg/indexcopy.cc
  79. 49
      apt-pkg/indexcopy.h
  80. 288
      apt-pkg/indexfile.cc
  81. 145
      apt-pkg/indexfile.h
  82. 296
      apt-pkg/indexrecords.cc
  83. 96
      apt-pkg/indexrecords.h
  84. 28
      apt-pkg/init.cc
  85. 23
      apt-pkg/install-progress.cc
  86. 45
      apt-pkg/install-progress.h
  87. 85
      apt-pkg/metaindex.cc
  88. 83
      apt-pkg/metaindex.h
  89. 26
      apt-pkg/orderlist.cc
  90. 6
      apt-pkg/orderlist.h
  91. 51
      apt-pkg/packagemanager.cc
  92. 14
      apt-pkg/packagemanager.h
  93. 304
      apt-pkg/pkgcache.cc
  94. 264
      apt-pkg/pkgcache.h
  95. 1007
      apt-pkg/pkgcachegen.cc
  96. 71
      apt-pkg/pkgcachegen.h
  97. 3
      apt-pkg/pkgrecords.cc
  98. 19
      apt-pkg/pkgrecords.h
  99. 5
      apt-pkg/pkgsystem.cc
  100. 18
      apt-pkg/pkgsystem.h

6
.travis.yml

@ -1,5 +1,11 @@
language: cpp
before_install:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -q
install:
- sudo ./prepare-release travis-ci
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get -qq update
- sudo apt-get -qq install g++-4.8
- export CXX=g++-4.8
script: make && make test && test/integration/run-tests

15
Makefile

@ -9,7 +9,7 @@ endif
.PHONY: default
default: startup all
.PHONY: headers library clean veryclean all binary program doc test update-po
.PHONY: fast headers library clean veryclean all binary program doc test update-po
all headers library clean veryclean binary program doc manpages docbook test update-po startup dirs:
$(MAKE) -C vendor $@
$(MAKE) -C apt-pkg $@
@ -21,7 +21,18 @@ all headers library clean veryclean binary program doc manpages docbook test upd
$(MAKE) -C dselect $@
$(MAKE) -C doc $@
$(MAKE) -C po $@
$(MAKE) -C test $@
# FIXME: -C test has issue swith parallel builds, investigate!
-$(MAKE) -C test $@
fast:
$(MAKE) -C vendor all
$(MAKE) -C apt-pkg all
$(MAKE) -C apt-inst all
$(MAKE) -C apt-private all
$(MAKE) -C methods all
$(MAKE) -C cmdline all
$(MAKE) -C ftparchive all
$(MAKE) -C test all
all headers library clean veryclean binary program doc manpages docbook test update-po: startup dirs

4
apt-inst/contrib/arfile.h

@ -62,11 +62,7 @@ struct ARArchive::Member
unsigned long long Size;
// Location of the data.
#if APT_PKG_ABI >= 413
unsigned long long Start;
#else
unsigned long Start;
#endif
Member *Next;
Member() : Start(0), Next(0) {};

5
apt-inst/contrib/extracttar.cc

@ -60,13 +60,8 @@ struct ExtractTar::TarHeader
// ExtractTar::ExtractTar - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
#if APT_PKG_ABI >= 413
ExtractTar::ExtractTar(FileFd &Fd,unsigned long long Max,string DecompressionProgram)
: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
#else
ExtractTar::ExtractTar(FileFd &Fd,unsigned long Max,string DecompressionProgram)
: File(Fd), MaxInSize(Max), DecompressProg(DecompressionProgram)
#endif
{
GZPid = -1;
Eof = false;

8
apt-inst/contrib/extracttar.h

@ -40,11 +40,7 @@ class ExtractTar
GNU_LongLink = 'K',GNU_LongName = 'L'};
FileFd &File;
#if APT_PKG_ABI >= 413
unsigned long long MaxInSize;
#else
unsigned long MaxInSize;
#endif
int GZPid;
FileFd InFd;
bool Eof;
@ -58,11 +54,7 @@ class ExtractTar
bool Go(pkgDirStream &Stream);
#if APT_PKG_ABI >= 413
ExtractTar(FileFd &Fd,unsigned long long Max,std::string DecompressionProgram);
#else
ExtractTar(FileFd &Fd,unsigned long Max,std::string DecompressionProgram);
#endif
virtual ~ExtractTar();
};

8
apt-inst/deb/debfile.cc

@ -203,11 +203,7 @@ bool debDebFile::MemControlExtract::DoItem(Item &Itm,int &Fd)
/* Just memcopy the block from the tar extractor and put it in the right
place in the pre-allocated memory block. */
bool debDebFile::MemControlExtract::Process(Item &/*Itm*/,const unsigned char *Data,
#if APT_PKG_ABI >= 413
unsigned long long Size,unsigned long long Pos)
#else
unsigned long Size,unsigned long Pos)
#endif
{
memcpy(Control + Pos, Data,Size);
return true;
@ -236,11 +232,7 @@ bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
// ---------------------------------------------------------------------
/* The given memory block is loaded into the parser and parsed as a control
record. */
#if APT_PKG_ABI >= 413
bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long long Size)
#else
bool debDebFile::MemControlExtract::TakeControl(const void *Data,unsigned long Size)
#endif
{
delete [] Control;
Control = new char[Size+2];

14
apt-inst/deb/debfile.h

@ -65,7 +65,7 @@ class debDebFile::ControlExtract : public pkgDirStream
{
public:
virtual bool DoItem(Item &Itm,int &Fd);
virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
};
class debDebFile::MemControlExtract : public pkgDirStream
@ -80,21 +80,13 @@ class debDebFile::MemControlExtract : public pkgDirStream
std::string Member;
// Members from DirStream
virtual bool DoItem(Item &Itm,int &Fd);
virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
virtual bool Process(Item &Itm,const unsigned char *Data,
#if APT_PKG_ABI >= 413
unsigned long long Size,unsigned long long Pos);
#else
unsigned long Size,unsigned long Pos);
#endif
unsigned long long Size,unsigned long long Pos) APT_OVERRIDE;
// Helpers
bool Read(debDebFile &Deb);
#if APT_PKG_ABI >= 413
bool TakeControl(const void *Data,unsigned long long Size);
#else
bool TakeControl(const void *Data,unsigned long Size);
#endif
MemControlExtract() : IsControl(false), Control(0), Length(0), Member("control") {};
MemControlExtract(std::string Member) : IsControl(false), Control(0), Length(0), Member(Member) {};

12
apt-inst/dirstream.h

@ -38,15 +38,10 @@ class pkgDirStream
Directory, FIFO} Type;
char *Name;
char *LinkTarget;
#if APT_PKG_ABI >= 413
unsigned long long Size;
#endif
unsigned long Mode;
unsigned long UID;
unsigned long GID;
#if APT_PKG_ABI < 413
unsigned long Size;
#endif
unsigned long long Size;
unsigned long MTime;
unsigned long Major;
unsigned long Minor;
@ -55,13 +50,8 @@ class pkgDirStream
virtual bool DoItem(Item &Itm,int &Fd);
virtual bool Fail(Item &Itm,int Fd);
virtual bool FinishedFile(Item &Itm,int Fd);
#if APT_PKG_ABI >= 413
virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
unsigned long long /*Size*/,unsigned long long /*Pos*/) {return true;};
#else
virtual bool Process(Item &/*Itm*/,const unsigned char * /*Data*/,
unsigned long /*Size*/,unsigned long /*Pos*/) {return true;};
#endif
virtual ~pkgDirStream() {};
};

6
apt-inst/extract.h

@ -38,9 +38,9 @@ class pkgExtract : public pkgDirStream
public:
virtual bool DoItem(Item &Itm,int &Fd);
virtual bool Fail(Item &Itm,int Fd);
virtual bool FinishedFile(Item &Itm,int Fd);
virtual bool DoItem(Item &Itm,int &Fd) APT_OVERRIDE;
virtual bool Fail(Item &Itm,int Fd) APT_OVERRIDE;
virtual bool FinishedFile(Item &Itm,int Fd) APT_OVERRIDE;
bool Finished();
bool Aborted();

2
apt-inst/makefile

@ -14,7 +14,7 @@ include ../buildlib/libversion.mak
# The library name
LIBRARY=apt-inst
MAJOR=1.6
MAJOR=2.0
MINOR=0
SLIBS=$(PTHREADLIB) -lapt-pkg
APT_DOMAIN:=libapt-inst$(MAJOR)

4162
apt-pkg/acquire-item.cc

File diff suppressed because it is too large

873
apt-pkg/acquire-item.h

File diff suppressed because it is too large

27
apt-pkg/acquire-method.cc

@ -376,7 +376,10 @@ int pkgAcqMethod::Run(bool Single)
Tmp->ExpectedHashes.push_back(HashString(*t, hash));
}
char *End;
Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
if (Tmp->ExpectedHashes.FileSize() > 0)
Tmp->MaximumSize = Tmp->ExpectedHashes.FileSize();
else
Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
Tmp->Next = 0;
// Append it to the list
@ -385,14 +388,14 @@ int pkgAcqMethod::Run(bool Single)
*I = Tmp;
if (QueueBack == 0)
QueueBack = Tmp;
// Notify that this item is to be fetched.
if (Fetch(Tmp) == false)
if (URIAcquire(Message, Tmp) == false)
Fail();
break;
}
}
break;
}
}
}
Exit();
@ -400,8 +403,6 @@ int pkgAcqMethod::Run(bool Single)
}
/*}}}*/
// AcqMethod::PrintStatus - privately really send a log/status message /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
va_list &args) const
{
@ -456,7 +457,7 @@ void pkgAcqMethod::Redirect(const string &NewURI)
// ---------------------------------------------------------------------
/* */
pkgAcqMethod::FetchResult::FetchResult() : LastModified(0),
IMSHit(false), Size(0), ResumePoint(0)
IMSHit(false), Size(0), ResumePoint(0), d(NULL)
{
}
/*}}}*/
@ -477,5 +478,9 @@ void pkgAcqMethod::Dequeue() { /*{{{*/
delete Tmp;
}
/*}}}*/
pkgAcqMethod::~pkgAcqMethod() {}
pkgAcqMethod::FetchItem::FetchItem() : d(NULL) {}
pkgAcqMethod::FetchItem::~FetchItem() {}
pkgAcqMethod::FetchResult::~FetchResult() {}

14
apt-pkg/acquire-method.h

@ -1,6 +1,5 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-method.h,v 1.15.2.1 2003/12/24 23:09:17 mdz Exp $
/* ######################################################################
Acquire Method - Method helper class + functions
@ -53,6 +52,11 @@ class pkgAcqMethod
// for when we know it or a arbitrary limit when we don't know the
// filesize (like a InRelease file)
unsigned long long MaximumSize;
FetchItem();
virtual ~FetchItem();
private:
void * const d;
};
struct FetchResult
@ -67,6 +71,9 @@ class pkgAcqMethod
void TakeHashes(class Hashes &Hash);
FetchResult();
virtual ~FetchResult();
private:
void * const d;
};
// State
@ -76,11 +83,12 @@ class pkgAcqMethod
std::string FailReason;
std::string UsedMirror;
std::string IP;
// Handlers for messages
virtual bool Configuration(std::string Message);
virtual bool Fetch(FetchItem * /*Item*/) {return true;};
virtual bool URIAcquire(std::string const &/*Message*/, FetchItem *Itm) { return Fetch(Itm); };
// Outgoing messages
void Fail(bool Transient = false);
inline void Fail(const char *Why, bool Transient = false) {Fail(std::string(Why),Transient);};

409
apt-pkg/acquire-worker.cc

@ -26,7 +26,6 @@
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <sys/stat.h>
#include <stdlib.h>
@ -34,9 +33,7 @@
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <sstream>
#include <apti18n.h>
/*}}}*/
@ -47,7 +44,7 @@ using namespace std;
// ---------------------------------------------------------------------
/* */
pkgAcquire::Worker::Worker(Queue *Q,MethodConfig *Cnf,
pkgAcquireStatus *Log) : Log(Log)
pkgAcquireStatus *log) : d(NULL), Log(log)
{
OwnerQ = Q;
Config = Cnf;
@ -55,23 +52,18 @@ pkgAcquire::Worker::Worker(Queue *Q,MethodConfig *Cnf,
CurrentItem = 0;
TotalSize = 0;
CurrentSize = 0;
Construct();
Construct();
}
/*}}}*/
// Worker::Worker - Constructor for method config startup /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquire::Worker::Worker(MethodConfig *Cnf)
pkgAcquire::Worker::Worker(MethodConfig *Cnf) : d(NULL), OwnerQ(NULL), Config(Cnf),
Access(Cnf->Access), CurrentItem(NULL),
CurrentSize(0), TotalSize(0)
{
OwnerQ = 0;
Config = Cnf;
Access = Cnf->Access;
CurrentItem = 0;
TotalSize = 0;
CurrentSize = 0;
Construct();
Construct();
}
/*}}}*/
// Worker::Construct - Constructor helper /*{{{*/
@ -136,7 +128,7 @@ bool pkgAcquire::Worker::Start()
}
for (int I = 0; I != 4; I++)
SetCloseExec(Pipes[I],true);
// Fork off the process
Process = ExecFork();
if (Process == 0)
@ -145,9 +137,9 @@ bool pkgAcquire::Worker::Start()
dup2(Pipes[1],STDOUT_FILENO);
dup2(Pipes[2],STDIN_FILENO);
SetCloseExec(STDOUT_FILENO,false);
SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
const char *Args[2];
Args[0] = Method.c_str();
Args[1] = 0;
@ -165,7 +157,7 @@ bool pkgAcquire::Worker::Start()
close(Pipes[2]);
OutReady = false;
InReady = true;
// Read the configuration data
if (WaitFd(InFd) == false ||
ReadMessages() == false)
@ -174,7 +166,7 @@ bool pkgAcquire::Worker::Start()
RunMessages();
if (OwnerQ != 0)
SendConfiguration();
return true;
}
/*}}}*/
@ -201,7 +193,7 @@ bool pkgAcquire::Worker::RunMessages()
if (Debug == true)
clog << " <- " << Access << ':' << QuoteString(Message,"\n") << endl;
// Fetch the message number
char *End;
int Number = strtol(Message.c_str(),&End,10);
@ -209,21 +201,24 @@ bool pkgAcquire::Worker::RunMessages()
return _error->Error("Invalid message from method %s: %s",Access.c_str(),Message.c_str());
string URI = LookupTag(Message,"URI");
pkgAcquire::Queue::QItem *Itm = 0;
pkgAcquire::Queue::QItem *Itm = NULL;
if (URI.empty() == false)
Itm = OwnerQ->FindItem(URI,this);
// update used mirror
string UsedMirror = LookupTag(Message,"UsedMirror", "");
if (!UsedMirror.empty() &&
Itm &&
Itm->Description.find(" ") != string::npos)
if (Itm != NULL)
{
Itm->Description.replace(0, Itm->Description.find(" "), UsedMirror);
// FIXME: will we need this as well?
//Itm->ShortDesc = UsedMirror;
// update used mirror
string UsedMirror = LookupTag(Message,"UsedMirror", "");
if (UsedMirror.empty() == false)
{
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
(*O)->UsedMirror = UsedMirror;
if (Itm->Description.find(" ") != string::npos)
Itm->Description.replace(0, Itm->Description.find(" "), UsedMirror);
}
}
// Determine the message number and dispatch
switch (Number)
{
@ -232,18 +227,18 @@ bool pkgAcquire::Worker::RunMessages()
if (Capabilities(Message) == false)
return _error->Error("Unable to process Capabilities message from %s",Access.c_str());
break;
// 101 Log
case 101:
if (Debug == true)
clog << " <- (log) " << LookupTag(Message,"Message") << endl;
break;
// 102 Status
case 102:
Status = LookupTag(Message,"Message");
break;
// 103 Redirect
case 103:
{
@ -252,27 +247,49 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 103 Redirect message");
break;
}
string NewURI = LookupTag(Message,"New-URI",URI.c_str());
std::string const NewURI = LookupTag(Message,"New-URI",URI.c_str());
Itm->URI = NewURI;
ItemDone();
pkgAcquire::Item *Owner = Itm->Owner;
pkgAcquire::ItemDesc Desc = *Itm;
// Change the status so that it can be dequeued
Owner->Status = pkgAcquire::Item::StatIdle;
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
(*O)->Status = pkgAcquire::Item::StatIdle;
// Mark the item as done (taking care of all queues)
// and then put it in the main queue again
std::vector<Item*> const ItmOwners = Itm->Owners;
OwnerQ->ItemDone(Itm);
OwnerQ->Owner->Enqueue(Desc);
if (Log != 0)
Log->Done(Desc);
Itm = NULL;
for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
{
pkgAcquire::Item *Owner = *O;
pkgAcquire::ItemDesc &desc = Owner->GetItemDesc();
// if we change site, treat it as a mirror change
if (URI::SiteOnly(NewURI) != URI::SiteOnly(desc.URI))
{
std::string const OldSite = desc.Description.substr(0, desc.Description.find(" "));
if (likely(APT::String::Startswith(desc.URI, OldSite)))
{
std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
if (likely(APT::String::Endswith(NewURI, OldExtra)))
{
std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
Owner->UsedMirror = URI::ArchiveOnly(NewSite);
if (desc.Description.find(" ") != string::npos)
desc.Description.replace(0, desc.Description.find(" "), Owner->UsedMirror);
}
}
}
desc.URI = NewURI;
OwnerQ->Owner->Enqueue(desc);
if (Log != 0)
Log->Done(desc);
}
break;
}
// 200 URI Start
case 200:
{
@ -281,23 +298,27 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 200 URI Start message");
break;
}
CurrentItem = Itm;
CurrentSize = 0;
TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
ResumePoint = strtoull(LookupTag(Message,"Resume-Point","0").c_str(), NULL, 10);
Itm->Owner->Start(Message,strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10));
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
{
(*O)->Start(Message, TotalSize);
// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Itm->Owner->GetOwner());
if (Log != 0)
Log->Fetch(*Itm);
// Display update before completion
if (Log != 0)
{
if (Log->MorePulses == true)
Log->Pulse((*O)->GetOwner());
Log->Fetch((*O)->GetItemDesc());
}
}
break;
}
// 201 URI Done
case 201:
{
@ -306,72 +327,114 @@ bool pkgAcquire::Worker::RunMessages()
_error->Error("Method gave invalid 201 URI Done message");
break;
}
pkgAcquire::Item *Owner = Itm->Owner;
pkgAcquire::ItemDesc Desc = *Itm;
if (RealFileExists(Owner->DestFile))
ChangeOwnerAndPermissionOfFile("201::URIDone", Owner->DestFile.c_str(), "root", "root", 0644);
PrepareFiles("201::URIDone", Itm);
// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Owner->GetOwner());
OwnerQ->ItemDone(Itm);
unsigned long long const ServerSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
bool isHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
// Using the https method the server might return 200, but the
// If-Modified-Since condition is not satsified, libcurl will
// discard the download. In this case, however, TotalSize will be
// set to the actual size of the file, while ServerSize will be set
// to 0. Therefore, if the item is marked as a hit and the
// downloaded size (ServerSize) is 0, we ignore TotalSize.
if (TotalSize != 0 && (!isHit || ServerSize != 0) && ServerSize != TotalSize)
_error->Warning("Size of file %s is not what the server reported %s %llu",
Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
// see if there is a hash to verify
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
Log->Pulse((*O)->GetOwner());
std::string const filename = LookupTag(Message, "Filename", Itm->Owner->DestFile.c_str());
HashStringList ReceivedHashes;
for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
{
std::string const tagname = std::string(*type) + "-Hash";
std::string const hashsum = LookupTag(Message, tagname.c_str());
if (hashsum.empty() == false)
ReceivedHashes.push_back(HashString(*type, hashsum));
// see if we got hashes to verify
for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
{
std::string const tagname = std::string(*type) + "-Hash";
std::string const hashsum = LookupTag(Message, tagname.c_str());
if (hashsum.empty() == false)
ReceivedHashes.push_back(HashString(*type, hashsum));
}
// not all methods always sent Hashes our way
if (ReceivedHashes.usable() == false)
{
HashStringList const ExpectedHashes = Itm->GetExpectedHashes();
if (ExpectedHashes.usable() == true && RealFileExists(filename))
{
Hashes calc(ExpectedHashes);
FileFd file(filename, FileFd::ReadOnly, FileFd::None);
calc.AddFD(file);
ReceivedHashes = calc.GetHashStringList();
}
}
}
if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
{
std::clog << "201 URI Done: " << Owner->DescURI() << endl
<< "ReceivedHash:" << endl;
for (HashStringList::const_iterator hs = ReceivedHashes.begin(); hs != ReceivedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << "ExpectedHash:" << endl;
HashStringList expectedHashes = Owner->HashSums();
for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << endl;
}
Owner->Done(Message, ServerSize, ReceivedHashes, Config);
ItemDone();
// only local files can refer other filenames and counting them as fetched would be unfair
if (Log != NULL && filename != Itm->Owner->DestFile)
Log->Fetched(ReceivedHashes.FileSize(),atoi(LookupTag(Message,"Resume-Point","0").c_str()));
std::vector<Item*> const ItmOwners = Itm->Owners;
OwnerQ->ItemDone(Itm);
Itm = NULL;
// Log that we are done
if (Log != 0)
bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
{
if (isHit)
pkgAcquire::Item * const Owner = *O;
HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
{
std::clog << "201 URI Done: " << Owner->DescURI() << endl
<< "ReceivedHash:" << endl;
for (HashStringList::const_iterator hs = ReceivedHashes.begin(); hs != ReceivedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << "ExpectedHash:" << endl;
for (HashStringList::const_iterator hs = ExpectedHashes.begin(); hs != ExpectedHashes.end(); ++hs)
std::clog << "\t- " << hs->toStr() << std::endl;
std::clog << endl;
}
// decide if what we got is what we expected
bool consideredOkay = false;
if (ExpectedHashes.usable())
{
/* Hide 'hits' for local only sources - we also manage to
hide gets */
if (Config->LocalOnly == false)
Log->IMSHit(Desc);
}
if (ReceivedHashes.usable() == false)
{
/* IMS-Hits can't be checked here as we will have uncompressed file,
but the hashes for the compressed file. What we have was good through
so all we have to ensure later is that we are not stalled. */
consideredOkay = isIMSHit;
}
else if (ReceivedHashes == ExpectedHashes)
consideredOkay = true;
else
consideredOkay = false;
}
else if (Owner->HashesRequired() == true)
consideredOkay = false;
else
Log->Done(Desc);
consideredOkay = true;
if (consideredOkay == true)
consideredOkay = Owner->VerifyDone(Message, Config);
else // hashsum mismatch
Owner->Status = pkgAcquire::Item::StatAuthError;
if (consideredOkay == true)
{
Owner->Done(Message, ReceivedHashes, Config);
if (Log != 0)
{
if (isIMSHit)
Log->IMSHit(Owner->GetItemDesc());
else
Log->Done(Owner->GetItemDesc());
}
}
else
{
Owner->Failed(Message,Config);
if (Log != 0)
Log->Fail(Owner->GetItemDesc());
}
}
ItemDone();
break;
}
}
// 400 URI Failure
case 400:
{
@ -382,44 +445,46 @@ bool pkgAcquire::Worker::RunMessages()
break;
}
PrepareFiles("400::URIFailure", Itm);
// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Itm->Owner->GetOwner());
pkgAcquire::Item *Owner = Itm->Owner;
pkgAcquire::ItemDesc Desc = *Itm;
if (RealFileExists(Owner->DestFile))
ChangeOwnerAndPermissionOfFile("400::URIFailure", Owner->DestFile.c_str(), "root", "root", 0644);
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
Log->Pulse((*O)->GetOwner());
std::vector<Item*> const ItmOwners = Itm->Owners;
OwnerQ->ItemDone(Itm);
Itm = NULL;
// set some status
if(LookupTag(Message,"FailReason") == "Timeout" ||
LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
LookupTag(Message,"FailReason") == "ResolveFailure" ||
LookupTag(Message,"FailReason") == "ConnectionRefused")
Owner->Status = pkgAcquire::Item::StatTransientNetworkError;
for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
{
// set some status
if(LookupTag(Message,"FailReason") == "Timeout" ||
LookupTag(Message,"FailReason") == "TmpResolveFailure" ||
LookupTag(Message,"FailReason") == "ResolveFailure" ||
LookupTag(Message,"FailReason") == "ConnectionRefused")
(*O)->Status = pkgAcquire::Item::StatTransientNetworkError;
Owner->Failed(Message,Config);
ItemDone();
(*O)->Failed(Message,Config);
if (Log != 0)
Log->Fail(Desc);
if (Log != 0)
Log->Fail((*O)->GetItemDesc());
}
ItemDone();
break;
}
}
// 401 General Failure
case 401:
_error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str());
break;
// 403 Media Change
case 403:
MediaChange(Message);
MediaChange(Message);
break;
}
}
}
return true;
}
@ -432,7 +497,7 @@ bool pkgAcquire::Worker::Capabilities(string Message)
{
if (Config == 0)
return true;
Config->Version = LookupTag(Message,"Version");
Config->SingleInstance = StringToBool(LookupTag(Message,"Single-Instance"),false);
Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false);
@ -447,13 +512,13 @@ bool pkgAcquire::Worker::Capabilities(string Message)
clog << "Configured access method " << Config->Access << endl;
clog << "Version:" << Config->Version <<
" SingleInstance:" << Config->SingleInstance <<
" Pipeline:" << Config->Pipeline <<
" SendConfig:" << Config->SendConfig <<
" LocalOnly: " << Config->LocalOnly <<
" NeedsCleanup: " << Config->NeedsCleanup <<
" Pipeline:" << Config->Pipeline <<
" SendConfig:" << Config->SendConfig <<
" LocalOnly: " << Config->LocalOnly <<
" NeedsCleanup: " << Config->NeedsCleanup <<
" Removable: " << Config->Removable << endl;
}
return true;
}
/*}}}*/
@ -463,14 +528,14 @@ bool pkgAcquire::Worker::Capabilities(string Message)
bool pkgAcquire::Worker::MediaChange(string Message)
{
int status_fd = _config->FindI("APT::Status-Fd",-1);
if(status_fd > 0)
if(status_fd > 0)
{
string Media = LookupTag(Message,"Media");
string Drive = LookupTag(Message,"Drive");
string Drive = LookupTag(Message,"Drive");
ostringstream msg,status;
ioprintf(msg,_("Please insert the disc labeled: "
"'%s' "
"in the drive '%s' and press enter."),
"in the drive '%s' and press [Enter]."),
Media.c_str(),Drive.c_str());
status << "media-change: " // message
<< Media << ":" // media
@ -536,21 +601,29 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
{
if (OutFd == -1)
return false;
string Message = "600 URI Acquire\n";
Message.reserve(300);
Message += "URI: " + Item->URI;
Message += "\nFilename: " + Item->Owner->DestFile;
HashStringList const hsl = Item->Owner->HashSums();
HashStringList const hsl = Item->GetExpectedHashes();
for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
if(Item->Owner->FileSize > 0)
if (hsl.FileSize() == 0)
{
string MaximumSize;
strprintf(MaximumSize, "%llu", Item->Owner->FileSize);
Message += "\nMaximum-Size: " + MaximumSize;
unsigned long long FileSize = Item->GetMaximumSize();
if(FileSize > 0)
{
string MaximumSize;
strprintf(MaximumSize, "%llu", FileSize);
Message += "\nMaximum-Size: " + MaximumSize;
}
}
Message += Item->Owner->Custom600Headers();
Item->SyncDestinationFiles();
Message += Item->Custom600Headers();
Message += "\n\n";
if (RealFileExists(Item->Owner->DestFile))
@ -564,7 +637,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
OutQueue += Message;
OutReady = true;
return true;
}
/*}}}*/
@ -586,7 +659,7 @@ bool pkgAcquire::Worker::OutFdReady()
OutQueue.erase(0,Res);
if (OutQueue.empty() == true)
OutReady = false;
return true;
}
/*}}}*/
@ -608,7 +681,7 @@ bool pkgAcquire::Worker::InFdReady()
bool pkgAcquire::Worker::MethodFailure()
{
_error->Error("Method %s has died unexpectedly!",Access.c_str());
// do not reap the child here to show meaningfull error to the user
ExecWait(Process,Access.c_str(),false);
Process = -1;
@ -620,26 +693,22 @@ bool pkgAcquire::Worker::MethodFailure()
InReady = false;
OutQueue = string();
MessageQueue.erase(MessageQueue.begin(),MessageQueue.end());
return false;
}
/*}}}*/
// Worker::Pulse - Called periodically /*{{{*/
// Worker::Pulse - Called periodically /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcquire::Worker::Pulse()
{
if (CurrentItem == 0)
return;
struct stat Buf;
if (stat(CurrentItem->Owner->DestFile.c_str(),&Buf) != 0)
return;
CurrentSize = Buf.st_size;
// Hmm? Should not happen...
if (CurrentSize > TotalSize && TotalSize != 0)
TotalSize = CurrentSize;
}
/*}}}*/
// Worker::ItemDone - Called when the current item is finished /*{{{*/
@ -653,3 +722,33 @@ void pkgAcquire::Worker::ItemDone()
Status = string();
}
/*}}}*/
void pkgAcquire::Worker::PrepareFiles(char const * const caller, pkgAcquire::Queue::QItem const * const Itm)/*{{{*/
{
if (RealFileExists(Itm->Owner->DestFile))
{
ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", "root", 0644);
std::string const filename = Itm->Owner->DestFile;
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
{
pkgAcquire::Item const * const Owner = *O;
if (Owner->DestFile == filename)
continue;
unlink(Owner->DestFile.c_str());
if (link(filename.c_str(), Owner->DestFile.c_str()) != 0)
{
// different mounts can't happen for us as we download to lists/ by default,
// but if the system is reused by others the locations can potentially be on
// different disks, so use symlink as poor-men replacement.
// FIXME: Real copying as last fallback, but that is costly, so offload to a method preferable
if (symlink(filename.c_str(), Owner->DestFile.c_str()) != 0)
_error->Error("Can't create (sym)link of file %s to %s", filename.c_str(), Owner->DestFile.c_str());
}
}
}
else
{
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
unlink((*O)->DestFile.c_str());
}
}
/*}}}*/

8
apt-pkg/acquire-worker.h

@ -1,6 +1,5 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-worker.h,v 1.12 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Acquire Worker - Worker process manager
@ -48,7 +47,7 @@
class pkgAcquire::Worker : public WeakPointable
{
/** \brief dpointer placeholder (for later in case we need it) */
void *d;
void * const d;
friend class pkgAcquire;
@ -318,7 +317,7 @@ class pkgAcquire::Worker : public WeakPointable
* \param Config A location in which to store information about
* the fetch method.
*/
Worker(MethodConfig *Config);
explicit Worker(MethodConfig *Config);
/** \brief Clean up this worker.
*
@ -326,6 +325,9 @@ class pkgAcquire::Worker : public WeakPointable
* \b false, also rudely interrupts the worker with a SIGINT.
*/
virtual ~Worker();
private:
APT_HIDDEN void PrepareFiles(char const * const caller, pkgAcquire::Queue::QItem const * const Itm);
};
/** @} */

163
apt-pkg/acquire.cc

@ -23,6 +23,7 @@
#include <apt-pkg/strutl.h>
#include <apt-pkg/fileutl.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
@ -40,7 +41,6 @@
#include <sys/select.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <apti18n.h>
/*}}}*/
@ -50,13 +50,13 @@ using namespace std;
// Acquire::pkgAcquire - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* We grab some runtime state from the configuration space */
pkgAcquire::pkgAcquire() : LockFD(-1), Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0),
pkgAcquire::pkgAcquire() : LockFD(-1), d(NULL), Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0),
Debug(_config->FindB("Debug::pkgAcquire",false)),
Running(false)
{
Initialize();
}
pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Workers(0),
pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), d(NULL), Queues(0), Workers(0),
Configs(0), Log(NULL), ToFetch(0),
Debug(_config->FindB("Debug::pkgAcquire",false)),
Running(false)
@ -652,8 +652,8 @@ pkgAcquire::MethodConfig::MethodConfig() : d(NULL), Next(0), SingleInstance(fals
// Queue::Queue - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquire::Queue::Queue(string Name,pkgAcquire *Owner) : d(NULL), Next(0),
Name(Name), Items(0), Workers(0), Owner(Owner), PipeDepth(0), MaxPipeDepth(1)
pkgAcquire::Queue::Queue(string const &name,pkgAcquire * const owner) : d(NULL), Next(0),
Name(name), Items(0), Workers(0), Owner(owner), PipeDepth(0), MaxPipeDepth(1)
{
}
/*}}}*/
@ -679,10 +679,14 @@ bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
{
QItem **I = &Items;
// move to the end of the queue and check for duplicates here
HashStringList const hsl = Item.Owner->GetExpectedHashes();
for (; *I != 0; I = &(*I)->Next)
if (Item.URI == (*I)->URI)
if (Item.URI == (*I)->URI || hsl == (*I)->Owner->GetExpectedHashes())
{
Item.Owner->Status = Item::StatDone;
if (_config->FindB("Debug::pkgAcquire::Worker",false) == true)
std::cerr << " @ Queue: Action combined for " << Item.URI << " and " << (*I)->URI << std::endl;
(*I)->Owners.push_back(Item.Owner);
Item.Owner->Status = (*I)->Owner->Status;
return false;
}
@ -705,13 +709,13 @@ bool pkgAcquire::Queue::Dequeue(Item *Owner)
{
if (Owner->Status == pkgAcquire::Item::StatFetching)
return _error->Error("Tried to dequeue a fetching object");
bool Res = false;
QItem **I = &Items;
for (; *I != 0;)
{
if ((*I)->Owner == Owner)
if (Owner == (*I)->Owner)
{
QItem *Jnk= *I;
*I = (*I)->Next;
@ -722,7 +726,7 @@ bool pkgAcquire::Queue::Dequeue(Item *Owner)
else
I = &(*I)->Next;
}
return Res;
}
/*}}}*/
@ -799,9 +803,12 @@ pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Wor
bool pkgAcquire::Queue::ItemDone(QItem *Itm)
{
PipeDepth--;
if (Itm->Owner->Status == pkgAcquire::Item::StatFetching)
Itm->Owner->Status = pkgAcquire::Item::StatDone;
for (QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
{
if ((*O)->Status == pkgAcquire::Item::StatFetching)
(*O)->Status = pkgAcquire::Item::StatDone;
}
if (Itm->Owner->QueueCounter <= 1)
Owner->Dequeue(Itm->Owner);
else
@ -809,7 +816,7 @@ bool pkgAcquire::Queue::ItemDone(QItem *Itm)
Dequeue(Itm->Owner);
Owner->Bump();
}
return Cycle();
}
/*}}}*/
@ -824,7 +831,7 @@ bool pkgAcquire::Queue::Cycle()
if (PipeDepth < 0)
return _error->Error("Pipedepth failure");
// Look for a queable item
QItem *I = Items;
while (PipeDepth < (signed)MaxPipeDepth)
@ -832,18 +839,19 @@ bool pkgAcquire::Queue::Cycle()
for (; I != 0; I = I->Next)
if (I->Owner->Status == pkgAcquire::Item::StatIdle)
break;
// Nothing to do, queue is idle.
if (I == 0)
return true;
I->Worker = Workers;
I->Owner->Status = pkgAcquire::Item::StatFetching;
for (QItem::owner_iterator O = I->Owners.begin(); O != I->Owners.end(); ++O)
(*O)->Status = pkgAcquire::Item::StatFetching;
PipeDepth++;
if (Workers->QueueItem(I) == false)
return false;
}
return true;
}
/*}}}*/
@ -855,10 +863,98 @@ void pkgAcquire::Queue::Bump()
Cycle();
}
/*}}}*/
HashStringList pkgAcquire::Queue::QItem::GetExpectedHashes() const /*{{{*/
{
/* each Item can have multiple owners and each owner might have different
hashes, even if that is unlikely in practice and if so at least some
owners will later fail. There is one situation through which is not a
failure and still needs this handling: Two owners who expect the same
file, but one owner only knows the SHA1 while the other only knows SHA256. */
HashStringList superhsl;
for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
{
HashStringList const hsl = (*O)->GetExpectedHashes();
if (hsl.usable() == false)
continue;
if (superhsl.usable() == false)
superhsl = hsl;
else
{
// we merge both lists - if we find disagreement send no hashes
HashStringList::const_iterator hs = hsl.begin();
for (; hs != hsl.end(); ++hs)
if (superhsl.push_back(*hs) == false)
break;
if (hs != hsl.end())
{
superhsl.clear();
break;
}
}
}
return superhsl;
}
/*}}}*/
APT_PURE unsigned long long pkgAcquire::Queue::QItem::GetMaximumSize() const /*{{{*/
{
unsigned long long Maximum = std::numeric_limits<unsigned long long>::max();
for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
{
if ((*O)->FileSize == 0)
continue;
Maximum = std::min(Maximum, (*O)->FileSize);
}
if (Maximum == std::numeric_limits<unsigned long long>::max())
return 0;
return Maximum;
}
/*}}}*/
void pkgAcquire::Queue::QItem::SyncDestinationFiles() const /*{{{*/
{
/* ensure that the first owner has the best partial file of all and
the rest have (potentially dangling) symlinks to it so that
everything (like progress reporting) finds it easily */
std::string superfile = Owner->DestFile;
off_t supersize = 0;
for (pkgAcquire::Queue::QItem::owner_iterator O = Owners.begin(); O != Owners.end(); ++O)
{
if ((*O)->DestFile == superfile)
continue;
struct stat file;
if (lstat((*O)->DestFile.c_str(),&file) == 0)
{
if ((file.st_mode & S_IFREG) == 0)
unlink((*O)->DestFile.c_str());
else if (supersize < file.st_size)
{
supersize = file.st_size;
unlink(superfile.c_str());
rename((*O)->DestFile.c_str(), superfile.c_str());
}
else
unlink((*O)->DestFile.c_str());
if (symlink(superfile.c_str(), (*O)->DestFile.c_str()) != 0)
{
; // not a problem per-se and no real alternative
}
}
}
}
/*}}}*/
std::string pkgAcquire::Queue::QItem::Custom600Headers() const /*{{{*/
{
/* The others are relatively easy to merge, but this one?
Lets not merge and see how far we can run with it
Likely, nobody will ever notice as all the items will
be of the same class and hence generate the same headers. */
return Owner->Custom600Headers();
}
/*}}}*/
// AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(0), Update(true), MorePulses(false)
pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(-1), Update(true), MorePulses(false)
{
Start();
}
@ -914,9 +1010,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
{
CurrentBytes += I->CurrentSize;
ResumeSize += I->ResumePoint;
// Files with unknown size always have 100% completion
if (I->CurrentItem->Owner->FileSize == 0 &&
if (I->CurrentItem->Owner->FileSize