Browse Source

Merge branch 'debian/experimental' into feature/srv-records

Conflicts:
	cmdline/apt-helper.cc
	cmdline/makefile
debian/1.8.y
Michael Vogt 7 years ago
parent
commit
21248c0f00
  1. 1
      .travis.yml
  2. 2
      COMPILING
  3. 4
      Makefile
  4. 74
      README.ddtp
  5. 181
      README.md
  6. 5
      apt-inst/contrib/arfile.h
  7. 18
      apt-inst/contrib/extracttar.cc
  8. 11
      apt-inst/contrib/extracttar.h
  9. 8
      apt-inst/deb/debfile.cc
  10. 12
      apt-inst/deb/debfile.h
  11. 1
      apt-inst/dirstream.cc
  12. 12
      apt-inst/dirstream.h
  13. 2
      apt-inst/extract.cc
  14. 2
      apt-inst/makefile
  15. 2669
      apt-pkg/acquire-item.cc
  16. 933
      apt-pkg/acquire-item.h
  17. 69
      apt-pkg/acquire-method.cc
  18. 19
      apt-pkg/acquire-method.h
  19. 72
      apt-pkg/acquire-worker.cc
  20. 5
      apt-pkg/acquire-worker.h
  21. 174
      apt-pkg/acquire.cc
  22. 32
      apt-pkg/acquire.h
  23. 26
      apt-pkg/algorithms.cc
  24. 34
      apt-pkg/algorithms.h
  25. 60
      apt-pkg/aptconfiguration.cc
  26. 3
      apt-pkg/aptconfiguration.h
  27. 3
      apt-pkg/cachefile.cc
  28. 144
      apt-pkg/cachefilter.cc
  29. 157
      apt-pkg/cachefilter.h
  30. 20
      apt-pkg/cacheiterators.h
  31. 350
      apt-pkg/cacheset.cc
  32. 522
      apt-pkg/cacheset.h
  33. 40
      apt-pkg/cdrom.cc
  34. 7
      apt-pkg/clean.cc
  35. 8
      apt-pkg/clean.h
  36. 31
      apt-pkg/contrib/cdromutl.cc
  37. 22
      apt-pkg/contrib/cmndline.cc
  38. 1
      apt-pkg/contrib/cmndline.h
  39. 17
      apt-pkg/contrib/configuration.cc
  40. 16
      apt-pkg/contrib/configuration.h
  41. 269
      apt-pkg/contrib/fileutl.cc
  42. 48
      apt-pkg/contrib/fileutl.h
  43. 63
      apt-pkg/contrib/gpgv.cc
  44. 264
      apt-pkg/contrib/hashes.cc
  45. 179
      apt-pkg/contrib/hashes.h
  46. 21
      apt-pkg/contrib/macros.h
  47. 12
      apt-pkg/contrib/netrc.cc
  48. 4
      apt-pkg/contrib/netrc.h
  49. 86
      apt-pkg/contrib/proxy.cc
  50. 16
      apt-pkg/contrib/proxy.h
  51. 9
      apt-pkg/contrib/sha2_internal.cc
  52. 342
      apt-pkg/contrib/strutl.cc
  53. 8
      apt-pkg/contrib/strutl.h
  54. 309
      apt-pkg/deb/debindexfile.cc
  55. 121
      apt-pkg/deb/debindexfile.h
  56. 305
      apt-pkg/deb/deblistparser.cc
  57. 55
      apt-pkg/deb/deblistparser.h
  58. 95
      apt-pkg/deb/debmetaindex.cc
  59. 36
      apt-pkg/deb/debmetaindex.h
  60. 201
      apt-pkg/deb/debrecords.cc
  61. 65
      apt-pkg/deb/debrecords.h
  62. 176
      apt-pkg/deb/debsrcrecords.cc
  63. 10
      apt-pkg/deb/debsrcrecords.h
  64. 2
      apt-pkg/deb/debsystem.cc
  65. 2
      apt-pkg/deb/debsystem.h
  66. 368
      apt-pkg/deb/dpkgpm.cc
  67. 16
      apt-pkg/deb/dpkgpm.h
  68. 94
      apt-pkg/depcache.cc
  69. 21
      apt-pkg/depcache.h
  70. 79
      apt-pkg/edsp.cc
  71. 6
      apt-pkg/edsp.h
  72. 6
      apt-pkg/edsp/edspindexfile.cc
  73. 2
      apt-pkg/edsp/edspindexfile.h
  74. 2
      apt-pkg/edsp/edsplistparser.h
  75. 4
      apt-pkg/edsp/edspsystem.cc
  76. 4
      apt-pkg/edsp/edspsystem.h
  77. 140
      apt-pkg/indexcopy.cc
  78. 13
      apt-pkg/indexcopy.h
  79. 1
      apt-pkg/indexfile.h
  80. 100
      apt-pkg/indexrecords.cc
  81. 45
      apt-pkg/indexrecords.h
  82. 10
      apt-pkg/init.cc
  83. 2
      apt-pkg/install-progress.cc
  84. 7
      apt-pkg/install-progress.h
  85. 40
      apt-pkg/metaindex.cc
  86. 29
      apt-pkg/metaindex.h
  87. 444
      apt-pkg/packagemanager.cc
  88. 35
      apt-pkg/packagemanager.h
  89. 104
      apt-pkg/pkgcache.cc
  90. 285
      apt-pkg/pkgcache.h
  91. 329
      apt-pkg/pkgcachegen.cc
  92. 71
      apt-pkg/pkgcachegen.h
  93. 2
      apt-pkg/pkgrecords.cc
  94. 51
      apt-pkg/pkgrecords.h
  95. 6
      apt-pkg/pkgsystem.h
  96. 66
      apt-pkg/policy.cc
  97. 10
      apt-pkg/sourcelist.cc
  98. 8
      apt-pkg/sourcelist.h
  99. 68
      apt-pkg/srcrecords.cc
  100. 24
      apt-pkg/srcrecords.h

1
.travis.yml

@ -2,5 +2,4 @@ language: cpp
before_install:
- sudo apt-get update -q
- sudo ./prepare-release travis-ci
- sudo apt-get install -q --no-install-recommends stunnel4
script: make && make test && test/integration/run-tests

2
COMPILING

@ -53,7 +53,7 @@ Debian GNU Linux 'potato'
Debian GNU Linux 'woody'
* All Archs
- Works flawlessly
- You will want to have debiandoc-sgml and docbook2man installed to get
- You will want to have docbook-xml and docbook2man installed to get
best results.
- No IPv6 Support in glibc's < 2.1.

4
Makefile

@ -10,7 +10,7 @@ endif
default: startup all
.PHONY: headers library clean veryclean all binary program doc test update-po
all headers library clean veryclean binary program doc manpages debiandoc test update-po startup dirs:
all headers library clean veryclean binary program doc manpages docbook test update-po startup dirs:
$(MAKE) -C vendor $@
$(MAKE) -C apt-pkg $@
$(MAKE) -C apt-inst $@
@ -23,7 +23,7 @@ all headers library clean veryclean binary program doc manpages debiandoc test u
$(MAKE) -C po $@
$(MAKE) -C test $@
all headers library clean veryclean binary program doc manpages debiandoc test update-po: startup dirs
all headers library clean veryclean binary program doc manpages docbook test update-po: startup dirs
dirs: startup

74
README.ddtp

@ -1,74 +0,0 @@
TODO:
- URL-Remap for the translation files (to hack around the problem that
they are not on any ftp server yet but only on http://ddtp.debian.org/)
Here is the original announcement of the ddtp support:
* To: debian-devel-announce@lists.debian.org
* Subject: Translate files
* From: Michael Bramer <grisu@debian.org>
* Date: Sun, 6 Oct 2002 21:56:06 +0200
* Mail-followup-to: debian-devel@lists.debian.org
* Message-id: <20021006195605.GA30516@home.debsupport.de>
* Old-return-path: <michael@home.debsupport.de>
* User-agent: Mutt/1.3.28i
Hello all
After some discussion between Anthony Towns (a ftpmaster), Jason
Gunthorpe (APT Developer) and some DDTP Coordinators we find a way to
transfer the translated package descriptions from the archive to the
user.
The translated descriptions need to be downloadable befor any
installation process, like the other package meta information. We
choose a new file per languages with all translated package
descriptions. The package system can download one or more of this
files at 'apt-get update' time and know the translations.
The new files are names 'Translate-$lang' and the file have this
rfc822-format:
Package: &lt;package-name&gt;
Description-md5: &lt;the md5 checksum of the english description&gt;
Description-$lang.$encoding: &lt;translated headline&gt;
&lt;translated section&gt;
The encoding of the Description is 'UTF-8' in all languages normal.
The files will be located at 'debian/dists/sid/main/i18n/' on the ftp
server (for all architecture). In addition of the plain
'Translate-$lang' file, there will be a 'gz' and a 'bz2' version and
in future also the new incremental format version.
The &lt;the md5 checksum of the english description&gt; is the md5 checksum
of the full english description, without the 'Description: '-tag and
with all spaces and newlines. Look at this example:
Description: XXX
YYY
.
ZZZ
is md5(&quot;XXX\n YYY\n .\n ZZZ\n&quot;) (perl-syntax).
A future APT version will download one or some 'Translate-$lang'
file(s) at 'update'-time. After this download it show a translated
description instead of the english form, if it found a translated
description of the package with the right md5 chechsum. The environment
of the user will controlled this process (LANG, LANGUAGE, LC_MESSAGES,
etc). With this the package system will never show a outdated
translation.
The translations come all from the DDTP. A daily process on
ddtp.debian.org make new 'Translated-$lang' files and a script on
ftp-master request this files and move this to the debian archive.
Now the first files are accessible at
<a href="http://ddtp.debian.org/pdesc/translatefiles/">http://ddtp.debian.org/pdesc/translatefiles/</a>
If you found wrong translations, please read the guides on
ddtp.debian.org, make a better translation and send this per mail to
the DDTP server. Don't bug the package maintainer!
Thanks
Grisu
--
Michael Bramer - a Debian Linux Developer <a href="http://www.debsupport.de">http://www.debsupport.de</a>
PGP: finger grisu@db.debian.org -- Linux Sysadmin -- Use Debian Linux

181
README.md

@ -0,0 +1,181 @@
APT
===
apt is the main commandline package manager for Debian and its derivatives.
It provides commandline tools for searching and managing as well as querying
information about packages as well as low-level access to all features
provided by the libapt-pkg and libapt-inst libraries which higher-level
package managers can depend upon.
Included tools are:
* apt-get for retrieval of packages and information about them
from authenticated sources and for installation, upgrade and
removal of packages together with their dependencies
* apt-cache for querying available information about installed
as well as installable packages
* apt-cdrom to use removable media as a source for packages
* apt-config as an interface to the configuration settings
* apt-key as an interface to manage authentication keys
* apt-extracttemplates to be used by debconf to prompt for configuration
questions before installation.
* apt-ftparchive creates Packages and other index files
needed to publish an archive of debian packages
* apt-sortpkgs is a Packages/Sources file normalizer.
The libraries libapt-pkg and libapt-inst are also maintained as part of this project,
alongside various additional binaries like the acquire-methods used by them.
Bindings for Python ([python-apt](https://tracker.debian.org/pkg/python-apt)) and
Perl ([libapt-pkg-perl](https://tracker.debian.org/pkg/libapt-pkg-perl)) are available as separated projects.
Discussion happens mostly on [the mailinglist](mailto:deity@lists.debian.org) ([archive](https://lists.debian.org/deity/)) and on [IRC](irc://irc.oftc.net/debian-apt).
Our bugtracker as well as a general overview can be found at the [Debian Tracker page](https://tracker.debian.org/pkg/apt).
Contributing
------------
APT is maintained in git, the official repository being located at
`git://anonscm.debian.org/apt/apt.git` ([webgit](http://anonscm.debian.org/gitweb/?p=apt/apt.git)),
but also available at other locations like [GitHub](https://github.com/Debian/apt).
The default branch is `debian/sid`, other branches targeted at different
derivatives and releases being used as needed. Various topic branches in
different stages of completion might be branched of from those, which you
are encouraged to do as well.
### Coding
APT uses its own autoconf based build system, see [README.make](http://anonscm.debian.org/gitweb/?p=apt/apt.git;a=blob;f=README.make)
for the glory details, but to get started, just run:
$ make
from a fresh git checkout.
The source code uses in most parts a relatively uncommon indent convention,
namely 3 spaces with 8 space tab (see [doc/style.txt](http://anonscm.debian.org/gitweb/?p=apt/apt.git;a=blob;f=doc/style.txt) for more on this).
Adhering to it avoids unnecessary code-churn destroying history (aka: `git blame`)
and you are therefore encouraged to write patches in this style.
Your editor can surely help you with this, for vim the settings would be
`setlocal shiftwidth=3 noexpandtab tabstop=8`
(the later two are the default configuration and could therefore be omitted).
### Translations
While we welcome contributions here, we highly encourage you to contact the [Debian Internationalization (i18n) team](https://wiki.debian.org/Teams/I18n).
Various language teams have formed which can help you creating, maintaining
and improving a translation, while we could only do a basic syntax check of the
file format…
Further more, Translating APT is split into two independent parts:
The program translation, meaning the messages printed by the tools,
as well as the manpages and other documentation shipped with APT.
### Bug triage
Software tools like APT which are used by thousands of users every
day have a steady flow of incoming bugreports. Not all of them are really
bugs in APT: It can be packaging bugs like failing maintainer scripts a
user reports against apt, because apt was the command he executed leading
to this failure or various wishlist items for new features. Given enough time
also the occasional duplicate enters the system.
Our bugtracker is therefore full with open bugreports which are waiting for you! ;)
Testing
-------
### Manual execution
When you make changes and want to run them manually, make sure your
`$LD_LIBRARY_PATH` points to the libraries you have built, e.g. via:
$ export LD_LIBRARY_PATH=$(pwd)/build/bin
$ ./build/bin/apt-get moo
### Integration tests
There is a extensive integration testsuite available which can be run via:
$ ./test/integration/run-tests
While these tests are not executed at package build-time as they require additional
dependencies, the repository contains the configuration needed to run them on [Travis CI](https://travis-ci.org/)
as well as via autopkgtests e.g. on [Debian Continuous Integration](http://ci.debian.net/?q=apt#package/apt).
A testcase here is a shellscript embedded in a framework creating an environment in which
apt tools can be used naturally without root-rights to test every aspect of its behavior
itself as well as in conjunction with dpkg and other tools while working with packages.
### Unit tests
These tests are gtest-dev based, reside in `./test/libapt` and can be run with `make test`.
They are executed at package build-time, but not by `make`.
Debugging
---------
APT does many things, so there is no central debug mode which could be
activated. It uses instead various config-options to activate debug output
in certain areas. The following describes some common scenarios and generally
useful options, but is in no way exhaustive.
Note that you should *NEVER* use these settings as root to avoid accidents.
Similation mode (`-s`) is usually sufficient to help you run apt as a non-root user.
### Using different state files
If a dependency solver bug is reported, but can't be reproduced by the
triager easily, it is beneficial to ask the reporter for the
`/var/lib/dpkg/status` file, which includes the packages installed on the
system and in which version. Such a file can then be used via the option
`dir::state::status`. Beware of different architecture settings!
Bugreports usually include this information in the template. Assuming you
already have the `Packages` files for the architecture (see `sources.list`
manpage for the `arch=` option) you can change to a different architecture
with a config file like:
APT::Architecture "arch1";
#clear APT::Architectures;
APT:: Architectures { "arch1"; "arch2"; }
If a certain mirror state is needed, see if you can reproduce it with [snapshot.debian.org](http://snapshot.debian.org/).
Your sources.list file (`dir::etc::sourcelist`) has to be correctly mention the repository,
but if it does, you can use different downloaded archive state files via `dir::state::lists`.
In case manually vs. automatically installed matters, you can ask the reporter for
the `/var/lib/apt/extended_states` file and use it with `dir::state::extended_states`.
### Dependency resolution
APT works in its internal resolver in two stages: First all packages are visited
and marked for installation, keep back or removal. Option `Debug::pkgDepCache::Marker`
shows this. This also decides which packages are to be installed to satisfy dependencies,
which can be seen by `Debug::pkgDepCache::AutoInstall`. After this is done, we might
be in a situation in which two packages want to be installed, but only on of them can be.
It is the job of the pkgProblemResolver to decide which of two packages 'wins' and can
therefore decide what has to happen. You can see the contenders as well as their fight and
the resulting resolution with `Debug::pkgProblemResolver`.
### Downloading files
Various binaries (called 'methods') are tasked with downloading files. The Acquire system
talks to them via simple text protocol. Depending on which side you want to see, either
`Debug::pkgAcquire::Worker` or `Debug::Acquire::http` (or similar) will show the messages.
The integration tests use a simple self-built webserver which also logs. If you find that
the http(s) methods do not behave like they should be try to implement this behavior in the
webserver for simpler and more controlled testing.
### Installation order
Dependencies are solved, packages downloaded: Everything read for the installation!
The last step in the chain is often forgotten, but still very important:
Packages have to be installed in a particular order so that their dependencies are
satisfied, but at the same time you don't want to install very important and optional
packages at the same time if possible, so that a broken optional package does not
block the correct installation of very important packages. Which option to use depends on
if you are interested in the topology sorting (`Debug::pkgOrderList`), the dependency-aware
cycle and unconfigured prevention (`Debug::pkgPackageManager`) or the actual calls
to dpkg (`Debug::pkgDpkgPm`).

5
apt-inst/contrib/arfile.h

@ -17,6 +17,7 @@
#include <string>
#include <apt-pkg/macros.h>
#ifndef APT_8_CLEANER_HEADERS
#include <apt-pkg/fileutl.h>
#endif
@ -61,7 +62,11 @@ 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) {};

18
apt-inst/contrib/extracttar.cc

@ -60,9 +60,13 @@ struct ExtractTar::TarHeader
// ExtractTar::ExtractTar - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
ExtractTar::ExtractTar(FileFd &Fd,unsigned long Max,string DecompressionProgram) : File(Fd),
MaxInSize(Max), DecompressProg(DecompressionProgram)
#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;
@ -267,7 +271,7 @@ bool ExtractTar::Go(pkgDirStream &Stream)
case GNU_LongLink:
{
unsigned long Length = Itm.Size;
unsigned long long Length = Itm.Size;
unsigned char Block[512];
while (Length > 0)
{
@ -286,7 +290,7 @@ bool ExtractTar::Go(pkgDirStream &Stream)
case GNU_LongName:
{
unsigned long Length = Itm.Size;
unsigned long long Length = Itm.Size;
unsigned char Block[512];
while (Length > 0)
{
@ -315,11 +319,11 @@ bool ExtractTar::Go(pkgDirStream &Stream)
return false;
// Copy the file over the FD
unsigned long Size = Itm.Size;
unsigned long long Size = Itm.Size;
while (Size != 0)
{
unsigned char Junk[32*1024];
unsigned long Read = min(Size,(unsigned long)sizeof(Junk));
unsigned long Read = min(Size, (unsigned long long)sizeof(Junk));
if (InFd.Read(Junk,((Read+511)/512)*512) == false)
return false;

11
apt-inst/contrib/extracttar.h

@ -15,6 +15,7 @@
#define PKGLIB_EXTRACTTAR_H
#include <apt-pkg/fileutl.h>
#include <apt-pkg/macros.h>
#include <string>
@ -39,7 +40,11 @@ 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;
@ -52,8 +57,12 @@ class ExtractTar
public:
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,7 +203,11 @@ 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;
@ -232,7 +236,11 @@ 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];

12
apt-inst/deb/debfile.h

@ -27,6 +27,7 @@
#include <apt-pkg/arfile.h>
#include <apt-pkg/dirstream.h>
#include <apt-pkg/tagfile.h>
#include <apt-pkg/macros.h>
#include <string>
@ -81,13 +82,20 @@ class debDebFile::MemControlExtract : public pkgDirStream
// Members from DirStream
virtual bool DoItem(Item &Itm,int &Fd);
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
// 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) {};
~MemControlExtract() {delete [] Control;};

1
apt-inst/dirstream.cc

@ -76,7 +76,6 @@ bool pkgDirStream::DoItem(Item &Itm,int &Fd)
if(mkdir(Itm.Name,Itm.Mode) < 0)
return false;
return true;
break;
}
case Item::FIFO:
break;

12
apt-inst/dirstream.h

@ -25,6 +25,7 @@
#ifndef PKGLIB_DIRSTREAM_H
#define PKGLIB_DIRSTREAM_H
#include <apt-pkg/macros.h>
class pkgDirStream
{
@ -37,10 +38,15 @@ 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 MTime;
unsigned long Major;
unsigned long Minor;
@ -49,9 +55,13 @@ 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() {};
};

2
apt-inst/extract.cc

@ -404,7 +404,7 @@ bool pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator Nde,
// Now see if this package matches one in a replace depends
pkgCache::DepIterator Dep = Ver.DependsList();
bool Ok = false;
for (; Dep.end() == false; Dep++)
for (; Dep.end() == false; ++Dep)
{
if (Dep->Type != pkgCache::Dep::Replaces)
continue;

2
apt-inst/makefile

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

2669
apt-pkg/acquire-item.cc

File diff suppressed because it is too large

933
apt-pkg/acquire-item.h

File diff suppressed because it is too large

69
apt-pkg/acquire-method.cc

@ -102,7 +102,10 @@ void pkgAcqMethod::Fail(string Err,bool Transient)
if (Queue != 0)
{
std::cout << "400 URI Failure\nURI: " << Queue->Uri << "\n"
<< "Message: " << Err << " " << IP << "\n";
<< "Message: " << Err;
if (IP.empty() == false && _config->FindB("Acquire::Failure::ShowIP", true) == true)
std::cout << " " << IP;
std::cout << "\n";
Dequeue();
}
else
@ -118,6 +121,18 @@ void pkgAcqMethod::Fail(string Err,bool Transient)
std::cout << "\n" << std::flush;
}
/*}}}*/
// AcqMethod::DropPrivsOrDie - Drop privileges or die /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::DropPrivsOrDie()
{
if (!DropPrivileges()) {
Fail(false);
exit(112); /* call the european emergency number */
}
}
/*}}}*/
// AcqMethod::URIStart - Indicate a download is starting /*{{{*/
// ---------------------------------------------------------------------
@ -147,6 +162,16 @@ void pkgAcqMethod::URIStart(FetchResult &Res)
// AcqMethod::URIDone - A URI is finished /*{{{*/
// ---------------------------------------------------------------------
/* */
static void printHashStringList(HashStringList const * const list)
{
for (HashStringList::const_iterator hash = list->begin(); hash != list->end(); ++hash)
{
// very old compatibility name for MD5Sum
if (hash->HashType() == "MD5Sum")
std::cout << "MD5-Hash: " << hash->HashValue() << "\n";
std::cout << hash->HashType() << "-Hash: " << hash->HashValue() << "\n";
}
}
void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
{
if (Queue == 0)
@ -164,15 +189,8 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
if (Res.LastModified != 0)
std::cout << "Last-Modified: " << TimeRFC1123(Res.LastModified) << "\n";
if (Res.MD5Sum.empty() == false)
std::cout << "MD5-Hash: " << Res.MD5Sum << "\n"
<< "MD5Sum-Hash: " << Res.MD5Sum << "\n";
if (Res.SHA1Sum.empty() == false)
std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
if (Res.SHA256Sum.empty() == false)
std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
if (Res.SHA512Sum.empty() == false)
std::cout << "SHA512-Hash: " << Res.SHA512Sum << "\n";
printHashStringList(&Res.Hashes);
if (UsedMirror.empty() == false)
std::cout << "UsedMirror: " << UsedMirror << "\n";
if (Res.GPGVOutput.empty() == false)
@ -200,15 +218,8 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
if (Alt->LastModified != 0)
std::cout << "Alt-Last-Modified: " << TimeRFC1123(Alt->LastModified) << "\n";
if (Alt->MD5Sum.empty() == false)
std::cout << "Alt-MD5-Hash: " << Alt->MD5Sum << "\n";
if (Alt->SHA1Sum.empty() == false)
std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
if (Alt->SHA256Sum.empty() == false)
std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
if (Alt->SHA512Sum.empty() == false)
std::cout << "Alt-SHA512-Hash: " << Alt->SHA512Sum << "\n";
printHashStringList(&Alt->Hashes);
if (Alt->IMSHit == true)
std::cout << "Alt-IMS-Hit: true\n";
}
@ -355,6 +366,17 @@ int pkgAcqMethod::Run(bool Single)
Tmp->LastModified = 0;
Tmp->IndexFile = StringToBool(LookupTag(Message,"Index-File"),false);
Tmp->FailIgnore = StringToBool(LookupTag(Message,"Fail-Ignore"),false);
Tmp->ExpectedHashes = HashStringList();
for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t)
{
std::string tag = "Expected-";
tag.append(*t);
std::string const hash = LookupTag(Message, tag.c_str());
if (hash.empty() == false)
Tmp->ExpectedHashes.push_back(HashString(*t, hash));
}
char *End;
Tmp->MaximumSize = strtoll(LookupTag(Message, "Maximum-Size", "0").c_str(), &End, 10);
Tmp->Next = 0;
// Append it to the list
@ -442,12 +464,9 @@ pkgAcqMethod::FetchResult::FetchResult() : LastModified(0),
// ---------------------------------------------------------------------
/* This hides the number of hashes we are supporting from the caller.
It just deals with the hash class. */
void pkgAcqMethod::FetchResult::TakeHashes(Hashes &Hash)
void pkgAcqMethod::FetchResult::TakeHashes(class Hashes &Hash)
{
MD5Sum = Hash.MD5.Result();
SHA1Sum = Hash.SHA1.Result();
SHA256Sum = Hash.SHA256.Result();
SHA512Sum = Hash.SHA512.Result();
Hashes = Hash.GetHashStringList();
}
/*}}}*/
void pkgAcqMethod::Dequeue() { /*{{{*/
@ -458,3 +477,5 @@ void pkgAcqMethod::Dequeue() { /*{{{*/
delete Tmp;
}
/*}}}*/
pkgAcqMethod::~pkgAcqMethod() {}

19
apt-pkg/acquire-method.h

@ -20,6 +20,7 @@
#ifndef PKGLIB_ACQUIRE_METHOD_H
#define PKGLIB_ACQUIRE_METHOD_H
#include <apt-pkg/hashes.h>
#include <apt-pkg/macros.h>
#include <stdarg.h>
@ -33,7 +34,6 @@
#include <apt-pkg/strutl.h>
#endif
class Hashes;
class pkgAcqMethod
{
protected:
@ -44,17 +44,20 @@ class pkgAcqMethod
std::string Uri;
std::string DestFile;
int DestFileFd;
time_t LastModified;
bool IndexFile;
bool FailIgnore;
HashStringList ExpectedHashes;
// a maximum size we will download, this can be the exact filesize
// for when we know it or a arbitrary limit when we don't know the
// filesize (like a InRelease file)
unsigned long long MaximumSize;
};
struct FetchResult
{
std::string MD5Sum;
std::string SHA1Sum;
std::string SHA256Sum;
std::string SHA512Sum;
HashStringList Hashes;
std::vector<std::string> GPGVOutput;
time_t LastModified;
bool IMSHit;
@ -62,7 +65,7 @@ class pkgAcqMethod
unsigned long long Size;
unsigned long long ResumePoint;
void TakeHashes(Hashes &Hash);
void TakeHashes(class Hashes &Hash);
FetchResult();
};
@ -106,8 +109,8 @@ class pkgAcqMethod
inline void SetIP(std::string aIP) {IP = aIP;};
pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
virtual ~pkgAcqMethod() {};
virtual ~pkgAcqMethod();
void DropPrivsOrDie();
private:
APT_HIDDEN void Dequeue();
};

72
apt-pkg/acquire-worker.cc

@ -34,6 +34,9 @@
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <apti18n.h>
/*}}}*/
@ -306,7 +309,10 @@ bool pkgAcquire::Worker::RunMessages()
pkgAcquire::Item *Owner = Itm->Owner;
pkgAcquire::ItemDesc Desc = *Itm;
if (RealFileExists(Owner->DestFile))
ChangeOwnerAndPermissionOfFile("201::URIDone", Owner->DestFile.c_str(), "root", "root", 0644);
// Display update before completion
if (Log != 0 && Log->MorePulses == true)
Log->Pulse(Owner->GetOwner());
@ -326,25 +332,30 @@ bool pkgAcquire::Worker::RunMessages()
Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
// see if there is a hash to verify
string RecivedHash;
HashString expectedHash(Owner->HashSum());
if(!expectedHash.empty())
HashStringList ReceivedHashes;
for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
{
string hashTag = expectedHash.HashType()+"-Hash";
string hashSum = LookupTag(Message, hashTag.c_str());
if(!hashSum.empty())
RecivedHash = expectedHash.HashType() + ":" + hashSum;
if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
{
clog << "201 URI Done: " << Owner->DescURI() << endl
<< "RecivedHash: " << RecivedHash << endl
<< "ExpectedHash: " << expectedHash.toStr()
<< endl << endl;
}
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));
}
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, RecivedHash.c_str(), Config);
Owner->Done(Message, ServerSize, ReceivedHashes, Config);
ItemDone();
// Log that we are done
if (Log != 0)
{
@ -366,16 +377,21 @@ bool pkgAcquire::Worker::RunMessages()
{
if (Itm == 0)
{
_error->Error("Method gave invalid 400 URI Failure message");
std::string const msg = LookupTag(Message,"Message");
_error->Error("Method gave invalid 400 URI Failure message: %s", msg.c_str());
break;
}
// 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);
OwnerQ->ItemDone(Itm);
// set some status
@ -525,9 +541,25 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
Message.reserve(300);
Message += "URI: " + Item->URI;
Message += "\nFilename: " + Item->Owner->DestFile;
HashStringList const hsl = Item->Owner->HashSums();
for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();
if(Item->Owner->FileSize > 0)
{
string MaximumSize;
strprintf(MaximumSize, "%llu", Item->Owner->FileSize);
Message += "\nMaximum-Size: " + MaximumSize;
}
Message += Item->Owner->Custom600Headers();
Message += "\n\n";
if (RealFileExists(Item->Owner->DestFile))
{
std::string SandboxUser = _config->Find("APT::Sandbox::User");
ChangeOwnerAndPermissionOfFile("Item::QueueURI", Item->Owner->DestFile.c_str(),
SandboxUser.c_str(), "root", 0600);
}
if (Debug == true)
clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
OutQueue += Message;

5
apt-pkg/acquire-worker.h

@ -101,6 +101,11 @@ class pkgAcquire::Worker : public WeakPointable
*/
int OutFd;
/** \brief The socket to send SCM_RIGHTS message through
*/
int PrivSepSocketFd;
int PrivSepSocketFdChild;
/** \brief Set to \b true if the worker is in a state in which it
* might generate data or command responses.
*

174
apt-pkg/acquire.cc

@ -27,15 +27,20 @@
#include <vector>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/select.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <apti18n.h>
/*}}}*/
@ -49,52 +54,110 @@ pkgAcquire::pkgAcquire() : LockFD(-1), Queues(0), Workers(0), Configs(0), Log(NU
Debug(_config->FindB("Debug::pkgAcquire",false)),
Running(false)
{
string const Mode = _config->Find("Acquire::Queue-Mode","host");
if (strcasecmp(Mode.c_str(),"host") == 0)
QueueMode = QueueHost;
if (strcasecmp(Mode.c_str(),"access") == 0)
QueueMode = QueueAccess;
Initialize();
}
pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Workers(0),
Configs(0), Log(Progress), ToFetch(0),
pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Workers(0),
Configs(0), Log(NULL), ToFetch(0),
Debug(_config->FindB("Debug::pkgAcquire",false)),
Running(false)
{
Initialize();
SetLog(Progress);
}
void pkgAcquire::Initialize()
{
string const Mode = _config->Find("Acquire::Queue-Mode","host");
if (strcasecmp(Mode.c_str(),"host") == 0)
QueueMode = QueueHost;
if (strcasecmp(Mode.c_str(),"access") == 0)
QueueMode = QueueAccess;
Setup(Progress, "");
// chown the auth.conf file as it will be accessed by our methods
std::string const SandboxUser = _config->Find("APT::Sandbox::User");
if (getuid() == 0 && SandboxUser.empty() == false) // if we aren't root, we can't chown, so don't try it
{
struct passwd const * const pw = getpwnam(SandboxUser.c_str());
struct group const * const gr = getgrnam("root");
if (pw != NULL && gr != NULL)
{
std::string const AuthConf = _config->FindFile("Dir::Etc::netrc");
if(AuthConf.empty() == false && RealFileExists(AuthConf) &&
chown(AuthConf.c_str(), pw->pw_uid, gr->gr_gid) != 0)
_error->WarningE("SetupAPTPartialDirectory", "chown to %s:root of file %s failed", SandboxUser.c_str(), AuthConf.c_str());
}
}
}
/*}}}*/
// Acquire::Setup - Delayed Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Do everything needed to be a complete Acquire object and report the
success (or failure) back so the user knows that something is wrong */
// Acquire::GetLock - lock directory and prepare for action /*{{{*/
static bool SetupAPTPartialDirectory(std::string const &grand, std::string const &parent)
{
std::string const partial = parent + "partial";
mode_t const mode = umask(S_IWGRP | S_IWOTH);
bool const creation_fail = (CreateAPTDirectoryIfNeeded(grand, partial) == false &&
CreateAPTDirectoryIfNeeded(parent, partial) == false);
umask(mode);
if (creation_fail == true)
return false;
std::string const SandboxUser = _config->Find("APT::Sandbox::User");
if (getuid() == 0 && SandboxUser.empty() == false) // if we aren't root, we can't chown, so don't try it
{
struct passwd const * const pw = getpwnam(SandboxUser.c_str());
struct group const * const gr = getgrnam("root");
if (pw != NULL && gr != NULL)
{
// chown the partial dir
if(chown(partial.c_str(), pw->pw_uid, gr->gr_gid) != 0)
_error->WarningE("SetupAPTPartialDirectory", "chown to %s:root of directory %s failed", SandboxUser.c_str(), partial.c_str());
}
}
if (chmod(partial.c_str(), 0700) != 0)
_error->WarningE("SetupAPTPartialDirectory", "chmod 0700 of directory %s failed", partial.c_str());
return true;
}
bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock)
{
Log = Progress;
if (Lock.empty())
{
string const listDir = _config->FindDir("Dir::State::lists");
if (SetupAPTPartialDirectory(_config->FindDir("Dir::State"), listDir) == false)
return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str());
string const archivesDir = _config->FindDir("Dir::Cache::Archives");
if (SetupAPTPartialDirectory(_config->FindDir("Dir::Cache"), archivesDir) == false)
return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str());
return true;
}
return GetLock(Lock);
}
bool pkgAcquire::GetLock(std::string const &Lock)
{
if (Lock.empty() == true)
return false;
// check for existence and possibly create auxiliary directories
string const listDir = _config->FindDir("Dir::State::lists");
string const partialListDir = listDir + "partial/";
string const archivesDir = _config->FindDir("Dir::Cache::Archives");
string const partialArchivesDir = archivesDir + "partial/";
if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false)
return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str());
if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::Cache"), partialArchivesDir) == false &&
CreateAPTDirectoryIfNeeded(archivesDir, partialArchivesDir) == false)
return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str());
if (Lock == listDir)
{
if (SetupAPTPartialDirectory(_config->FindDir("Dir::State"), listDir) == false)
return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str());
}
if (Lock == archivesDir)
{
if (SetupAPTPartialDirectory(_config->FindDir("Dir::Cache"), archivesDir) == false)
return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str());
}
if (Lock.empty() == true || _config->FindB("Debug::NoLocking", false) == true)
if (_config->FindB("Debug::NoLocking", false) == true)
return true;
// Lock the directory this acquire object will work in
LockFD = GetLock(flCombine(Lock, "lock"));
if (LockFD != -1)
close(LockFD);
LockFD = ::GetLock(flCombine(Lock, "lock"));
if (LockFD == -1)
return _error->Error(_("Unable to lock directory %s"), Lock.c_str());
@ -486,6 +549,9 @@ bool pkgAcquire::Clean(string Dir)
if (DirectoryExists(Dir) == false)
return true;
if(Dir == "/")
return _error->Error(_("Clean of %s is not supported"), Dir.c_str());
DIR *D = opendir(Dir.c_str());
if (D == 0)
return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
@ -577,27 +643,18 @@ pkgAcquire::UriIterator pkgAcquire::UriEnd()
// Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquire::MethodConfig::MethodConfig()
pkgAcquire::MethodConfig::MethodConfig() : d(NULL), Next(0), SingleInstance(false),
Pipeline(false), SendConfig(false), LocalOnly(false), NeedsCleanup(false),
Removable(false)
{
SingleInstance = false;
Pipeline = false;
SendConfig = false;
LocalOnly = false;
Removable = false;
Next = 0;
}
/*}}}*/
// Queue::Queue - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquire::Queue::Queue(string Name,pkgAcquire *Owner) : Name(Name),
Owner(Owner)
pkgAcquire::Queue::Queue(string Name,pkgAcquire *Owner) : d(NULL), Next(0),
Name(Name), Items(0), Workers(0), Owner(Owner), PipeDepth(0), MaxPipeDepth(1)
{
Items = 0;
Next = 0;
Workers = 0;
MaxPipeDepth = 1;
PipeDepth = 0;
}
/*}}}*/
// Queue::~Queue - Destructor /*{{{*/
@ -801,7 +858,7 @@ void pkgAcquire::Queue::Bump()
// AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Update(true), MorePulses(false)
pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(0), Update(true), MorePulses(false)
{
Start();
}
@ -821,7 +878,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
// Compute the total number of bytes to fetch
unsigned int Unknown = 0;
unsigned int Count = 0;
for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin(); I != Owner->ItemsEnd();
bool UnfetchedReleaseFiles = false;
for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin();
I != Owner->ItemsEnd();
++I, ++Count)
{
TotalItems++;
@ -832,6 +891,13 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
if ((*I)->Local == true)
continue;
// see if the method tells us to expect more
TotalItems += (*I)->ExpectedAdditionalItems;
// check if there are unfetched Release files
if ((*I)->Complete == false && (*I)->ExpectedAdditionalItems > 0)
UnfetchedReleaseFiles = true;
TotalBytes += (*I)->FileSize;
if ((*I)->Complete == true)
CurrentBytes += (*I)->FileSize;
@ -843,6 +909,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
unsigned long long ResumeSize = 0;
for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
I = Owner->WorkerStep(I))
{
if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false)
{
CurrentBytes += I->CurrentSize;
@ -853,6 +920,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
I->CurrentItem->Owner->Complete == false)
TotalBytes += I->CurrentSize;
}
}
// Normalize the figures and account for unknown size downloads
if (TotalBytes <= 0)
@ -863,6 +931,12 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
// Wha?! Is not supposed to happen.
if (CurrentBytes > TotalBytes)
CurrentBytes = TotalBytes;
// debug
if (_config->FindB("Debug::acquire::progress", false) == true)
std::clog << " Bytes: "
<< SizeToStr(CurrentBytes) << " / " << SizeToStr(TotalBytes)
<< std::endl;
// Compute the CPS
struct timeval NewTime;
@ -883,6 +957,14 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
Time = NewTime;
}
// calculate the percentage, if we have too little data assume 1%
if (TotalBytes > 0 && UnfetchedReleaseFiles)
Percent = 0;
else
// use both files and bytes because bytes can be unreliable
Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) +
0.2 * (CurrentItems/float(TotalItems)*100.0));
int fd = _config->FindI("APT::Status-Fd",-1);
if(fd > 0)
{
@ -900,13 +982,11 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
else
snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
// build the status str
status << "dlstatus:" << i
<< ":" << (CurrentBytes/float(TotalBytes)*100.0)
<< ":" << msg
<< endl;
<< ":" << std::setprecision(3) << Percent
<< ":" << msg
<< endl;
std::string const dlstatus = status.str();
FileFd::Write(fd, dlstatus.c_str(), dlstatus.size());
@ -961,3 +1041,7 @@ void pkgAcquireStatus::Fetched(unsigned long long Size,unsigned long long Resume
FetchedBytes += Size - Resume;
}
/*}}}*/
APT_CONST pkgAcquire::UriIterator::~UriIterator() {}
APT_CONST pkgAcquire::MethodConfig::~MethodConfig() {}
APT_CONST pkgAcquireStatus::~pkgAcquireStatus() {}

32
apt-pkg/acquire.h

@ -111,6 +111,7 @@ class pkgAcquire
struct MethodConfig;
struct ItemDesc;
friend class Item;
friend class pkgAcqMetaBase;
friend class Queue;
typedef std::vector<Item *>::iterator ItemIterator;
@ -351,14 +352,24 @@ class pkgAcquire
* long as the pkgAcquire object does.
* \param Lock defines a lock file that should be acquired to ensure
* only one Acquire class is in action at the time or an empty string
* if no lock file should be used.
* if no lock file should be used. If set also all needed directories
* will be created.
*/
bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "");
APT_DEPRECATED bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "");
void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
/** \brief acquire lock and perform directory setup
*
* \param Lock defines a lock file that should be acquired to ensure
* only one Acquire class is in action at the time or an empty string
* if no lock file should be used. If set also all needed directories
* will be created and setup.
*/
bool GetLock(std::string const &Lock);
/** \brief Construct a new pkgAcquire. */
pkgAcquire(pkgAcquireStatus *Log) APT_DEPRECATED;
pkgAcquire(pkgAcquireStatus *Log);
pkgAcquire();
/** \brief Destroy this pkgAcquire object.
@ -368,6 +379,8 @@ class pkgAcquire
*/
virtual ~pkgAcquire();
private:
APT_HIDDEN void Initialize();
};
/** \brief Represents a single download source from which an item
@ -585,7 +598,7 @@ class pkgAcquire::UriIterator
*
* \param Q The queue over which this UriIterator should iterate.
*/
UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0)
UriIterator(pkgAcquire::Queue *Q) : d(NULL), CurQ(Q), CurItem(0)
{
while (CurItem == 0 && CurQ != 0)
{
@ -593,7 +606,7 @@ class pkgAcquire::UriIterator
CurQ = CurQ->Next;
}
}
virtual ~UriIterator() {};
virtual ~UriIterator();
};
/*}}}*/
/** \brief Information about the properties of a single acquire method. {{{*/
@ -651,8 +664,7 @@ struct pkgAcquire::MethodConfig
*/
MethodConfig();
/* \brief Destructor, empty currently */
virtual ~MethodConfig() {};
virtual ~MethodConfig();
};
/*}}}*/
/** \brief A monitor object for downloads controlled by the pkgAcquire class. {{{
@ -714,6 +726,10 @@ class pkgAcquireStatus
/** \brief The number of items that have been successfully downloaded. */
unsigned long CurrentItems;
/** \brief The estimated percentage of the download (0-100)
*/
double Percent;
public:
/** \brief If \b true, the download scheduler should call Pulse()
@ -794,7 +810,7 @@ class pkgAcquireStatus
/** \brief Initialize all counters to 0 and the time to the current time. */
pkgAcquireStatus();
virtual ~pkgAcquireStatus() {};
virtual ~pkgAcquireStatus();
};
/*}}}*/
/** @} */

26
apt-pkg/algorithms.cc

@ -468,7 +468,7 @@ void pkgProblemResolver::MakeScores()
if (D->Version != 0)
{
pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
if (IV.end() == true || D.IsSatisfied(IV) != D.IsNegative())
if (IV.end() == true || D.IsSatisfied(IV) == false)
continue;
}
Scores[T->ID] += DepMap[D->Type];
@ -640,13 +640,17 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
// ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/
// ---------------------------------------------------------------------
/* */
#if APT_PKG_ABI < 413
bool pkgProblemResolver::Resolve(bool BrokenFix)
{
return Resolve(BrokenFix, NULL);
}
#endif
bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal") {
OpTextProgress Prog(*_config);
return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog);
}
if (solver != "internal")
return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, Progress);
return ResolveInternal(BrokenFix);
}
/*}}}*/
@ -1140,13 +1144,17 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
/* This is the work horse of the soft upgrade routine. It is very gental
in that it does not install or remove any packages. It is assumed that the
system was non-broken previously. */
#if APT_PKG_ABI < 413
bool pkgProblemResolver::ResolveByKeep()
{
return ResolveByKeep(NULL);
}
#endif
bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal") {
OpTextProgress Prog(*_config);
return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
}
if (solver != "internal")
return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress);
return ResolveByKeepInternal();
}
/*}}}*/