Michael Vogt лет назад: 16
Родитель
Сommit
51f9f4d78d
100 измененных файлов с 2410 добавлено и 4650 удалено
  1. 0 2
      .bzr-builddeb/default.conf.orig
  2. 22 0
      .bzrignore
  3. 0 4
      .cvsignore
  4. 16 135
      COPYING
  5. 3 3
      apt-inst/contrib/arfile.cc
  6. 3 1
      apt-inst/makefile
  7. 75 92
      apt-pkg/acquire-item.cc
  8. 25 29
      apt-pkg/acquire-item.h
  9. 0 2
      apt-pkg/acquire-method.cc
  10. 2 5
      apt-pkg/acquire.cc
  11. 13 13
      apt-pkg/acquire.h
  12. 73 37
      apt-pkg/algorithms.cc
  13. 4 4
      apt-pkg/algorithms.h
  14. 90 0
      apt-pkg/aptconfiguration.cc
  15. 46 0
      apt-pkg/aptconfiguration.h
  16. 4 5
      apt-pkg/cachefile.cc
  17. 30 20
      apt-pkg/cacheiterators.h
  18. 15 19
      apt-pkg/cdrom.cc
  19. 8 8
      apt-pkg/cdrom.h
  20. 0 1
      apt-pkg/clean.cc
  21. 30 21
      apt-pkg/contrib/cdromutl.cc
  22. 27 5
      apt-pkg/contrib/configuration.cc
  23. 3 0
      apt-pkg/contrib/configuration.h
  24. 7 6
      apt-pkg/contrib/error.cc
  25. 2 0
      apt-pkg/contrib/fileutl.cc
  26. 13 11
      apt-pkg/contrib/hashes.cc
  27. 9 4
      apt-pkg/contrib/md5.cc
  28. 86 34
      apt-pkg/contrib/mmap.cc
  29. 2 0
      apt-pkg/contrib/mmap.h
  30. 211 0
      apt-pkg/contrib/netrc.cc
  31. 29 0
      apt-pkg/contrib/netrc.h
  32. 13 19
      apt-pkg/contrib/sha256.cc
  33. 26 4
      apt-pkg/contrib/strutl.cc
  34. 8 6
      apt-pkg/contrib/strutl.h
  35. 4 0
      apt-pkg/deb/deblistparser.cc
  36. 7 0
      apt-pkg/deb/debmetaindex.cc
  37. 1 0
      apt-pkg/deb/debmetaindex.h
  38. 15 1
      apt-pkg/deb/debsrcrecords.cc
  39. 1 0
      apt-pkg/deb/debsrcrecords.h
  40. 2 2
      apt-pkg/deb/debsystem.cc
  41. 220 88
      apt-pkg/deb/dpkgpm.cc
  42. 5 2
      apt-pkg/deb/dpkgpm.h
  43. 118 61
      apt-pkg/depcache.cc
  44. 47 4
      apt-pkg/depcache.h
  45. 14 11
      apt-pkg/indexcopy.cc
  46. 10 12
      apt-pkg/indexcopy.h
  47. 0 1
      apt-pkg/indexfile.cc
  48. 7 7
      apt-pkg/indexrecords.cc
  49. 16 6
      apt-pkg/init.cc
  50. 6 2
      apt-pkg/init.h
  51. 11 11
      apt-pkg/makefile
  52. 7 1
      apt-pkg/metaindex.h
  53. 44 29
      apt-pkg/orderlist.cc
  54. 46 22
      apt-pkg/packagemanager.cc
  55. 1 1
      apt-pkg/packagemanager.h
  56. 61 8
      apt-pkg/pkgcache.cc
  57. 26 25
      apt-pkg/pkgcache.h
  58. 23 19
      apt-pkg/pkgcachegen.cc
  59. 4 4
      apt-pkg/pkgcachegen.h
  60. 4 4
      apt-pkg/pkgrecords.h
  61. 82 2
      apt-pkg/policy.cc
  62. 1 0
      apt-pkg/policy.h
  63. 10 3
      apt-pkg/sourcelist.cc
  64. 16 5
      apt-pkg/tagfile.cc
  65. 4 1
      apt-pkg/tagfile.h
  66. 10 9
      apt-pkg/vendorlist.cc
  67. 24 13
      apt-pkg/versionmatch.cc
  68. 13 8
      apt-pkg/versionmatch.h
  69. 0 1526
      buildlib/config.guess
  70. 1 0
      buildlib/config.h.in
  71. 0 1658
      buildlib/config.sub
  72. 7 1
      buildlib/configure.mak
  73. 12 14
      buildlib/defaults.mak
  74. 4 9
      buildlib/environment.mak.in
  75. 1 1
      buildlib/library.mak
  76. 21 0
      buildlib/libversion.mak
  77. 1 1
      buildlib/manpage.mak
  78. 61 0
      buildlib/po4a_manpage.mak
  79. 0 45
      buildlib/sgml_manpage.mak
  80. 2 1
      buildlib/sizetable
  81. 0 50
      buildlib/tools.m4
  82. 0 45
      buildlib/xml_manpage.mak
  83. 0 42
      buildlib/yodl_manpage.mak
  84. 14 15
      cmdline/apt-cache.cc
  85. 4 8
      cmdline/apt-cdrom.cc
  86. 2 2
      cmdline/apt-config.cc
  87. 2 2
      cmdline/apt-extracttemplates.cc
  88. 244 139
      cmdline/apt-get.cc
  89. 11 7
      cmdline/apt-key
  90. 10 5
      cmdline/apt-mark
  91. 4 4
      cmdline/apt-sortpkgs.cc
  92. 9 10
      configure.in
  93. 0 13
      debian/.cvsignore
  94. 43 0
      debian/NEWS
  95. 0 18
      debian/NEWS.Debian
  96. 0 6
      debian/apt-utils.manpages
  97. 1 0
      debian/apt.conf.autoremove
  98. 200 176
      debian/apt.cron.daily
  99. 1 0
      debian/apt.dirs
  100. 0 0
      debian/apt.logrotate

+ 0 - 2
.bzr-builddeb/default.conf.orig

@@ -1,2 +0,0 @@
-[BUILDDEB]
-native = true

+ 22 - 0
.bzrignore

@@ -0,0 +1,22 @@
+# temporary and backup files
+*~
+*.bak
+*.rej
+
+# buildrelated files/dirs
+aclocal.m4
+autom4te.cache/
+build/
+configure
+
+# generated files in the progress to build all
+# apt man pages and other documentation
+doc/*.1
+doc/*.5
+doc/*.8
+doc/*/*.1
+doc/*/*.5
+doc/*/*.8
+doc/*/apt.ent
+doc/*/*.xml
+doc/*/*.sgml

+ 0 - 4
.cvsignore

@@ -1,4 +0,0 @@
-autom4te.cache
-aclocal.m4
-configure
-build

+ 16 - 135
COPYING

@@ -1,142 +1,23 @@
 Apt is copyright 1997, 1998, 1999 Jason Gunthorpe and others.
 Apt is copyright 1997, 1998, 1999 Jason Gunthorpe and others.
+Apt is currently developed by APT Development Team <deity@lists.debian.org>.
 
 
-Apt is licensed under the terms of the GNU General Public License (GPL),
-version 2.0 or later, as published by the Free Software Foundation.  See
-the file COPYING.GPL [included], /usr/share/common-licenses/GPL, or
-<http://www.gnu.org/copyleft/gpl.txt> for the terms of the latest version
-of the GNU General Public License.
-
-In addition, prior to November 15th, 2000, apt may be distributed under
-terms identical to the above with the following addition:
-
-Works using apt may link against the GUI library "libqt", copyright by
-Troll Tech AS, Norway, provided that:
-
-1. The version of "libqt" is licensed under the terms of the "Qt Free Edition
-   License" published by Troll Tech AS.  The license terms identified as
-   the Qt Free Edition License below are the only such terms under which
-   distribution of works derived from both apt and "libqt" are permitted;
-
-and
-
-2. The source code of the version of "libqt" used is
-
-   a) Distributed with the binary version;
-
-   or
-
-   b) Downloadable by anyone, without fee, using a publicly-announced
-      URL on the Internet, for a duration of at least three years
-      starting with distribution of the binary version.
-
-On and after November 15th, 2000, the above additional terms lose all
-force, and apt will be licensed only under the terms of the GNU General
-Public License, version 2.0 or later.
-
-      _______________________________________________________________
-
-The following text, up to the text of the Qt Free Edition License, is
-informational and not part of the license terms on apt.
-
-Modifications to apt in either source or compiled form must be licensed
-under the terms of the GNU General Public License, version 2.0 (or later),
-but need not include the above clause permitting usage of the "libqt"
-library under the Qt Free Edition License.  Note that removal of this
-clause will result in software which is not licensed for binary
-redistribution linked against software governed by the Qt Free Edition
-License.  In the event that a version of "libqt" is released that is
-licensed under terms that do not conflict with the GPL, the additional
-clause above is not required to grant permission for distribution of works
-that are derived from both apt and "libqt".
-
-No part of apt is licensed under the Qt Free Edition License.  The terms
-below are provided to help identify the circumstances under which the
-"libqt" library may be used with apt (or a work derived from both).  The
-terms below are copied from the LICENSE file of the qt-1.44 distribution,
-as of November 10th, 1999.
-
-      _______________________________________________________________
-
-                        QT FREE EDITION LICENSE
+License: GPLv2+
 
 
-Copyright (C) 1992-1999 Troll Tech AS. All rights reserved. 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
 
 
-This is the license for Qt Free Edition version 1.44; it covers private use,
-use of third-party application programs based on Qt, and development of
-free software for the free software community. 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
 
 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 
 
-                      COPYRIGHT AND RESTRICTIONS
-
-The Qt toolkit is a product of Troll Tech AS. The Qt Free Edition is limited
-to use with the X Window System. 
-
-You may copy this version of the Qt Free Edition provided that the entire
-archive is distributed unchanged and as a whole, including this notice. 
-
-You may use this version of the Qt Free Edition to compile, link and run
-application programs legally developed by third parties. 
-
-You may use the Qt Free Edition to create application programs
-provided that: 
-
-      You accept this license. 
-      Your software does not require modifications to Qt Free Edition.
-      You satisfy ONE of the following three requirements 
-      EITHER 
-            Users of your software can freely obtain source code for the
-            software, freely modify the source code (possibly with
-            restrictions on copyright notices, attributions and legal
-            responsibility), and freely redistribute original or modified
-            versions of the software. 
-      OR 
-            Your software is distributed under the GNU GENERAL
-            PUBLIC LICENSE, version 2 or later, as defined by the
-            Free Software Foundation. 
-      OR 
-            Your software is distributed under the GNU LIBRARY
-            GENERAL PUBLIC LICENSE, version 2 or later, as
-            defined by the Free Software Foundation. 
-
-If you are paid to develop something with Qt Free Edition or it is a part of
-your job the following conditions also apply: 
-
-      Your software must not require libraries, programs, data or
-      documentation that are not available outside your organization in
-      order to compile or use. 
-      If and when your organization starts using the software, you must
-      notify Troll Tech AS of the following: 
-            Your organization's name and purpose. 
-            The software's name and purpose. 
-            The software's license. 
-            That your organization considers the software to be free
-            software. 
-
-You may also use the Qt Free Edition to create reusable components
-(such as libraries) provided that you accept the terms above, and in
-addition that: 
-
-      Your components' license includes the following text: 
-
-            [Your package] requires the Qt library, which is
-            copyright Troll Tech AS. Freely distributable
-            programs may generally use Qt Free Edition free of
-            charge, see [README.QT] for details. 
-
-      README.QT is distributed along with your components. 
-      Qt Free Edition is not distributed as an integral part of your
-      components. 
-
-                       LIMITATIONS OF LIABILITY
-
-Troll Tech AS makes no obligation under this license to support or
-upgrade Qt Free Edition, or assist in the use of Qt Free Edition. 
-
-In no event shall Troll Tech AS be liable for any lost revenue or profits or
-other direct, indirect, special, incidental or consequential damages, even
-if Troll Tech has been advised of the possibility of such damages. 
+See /usr/share/common-licenses/GPL-2, or
+<http://www.gnu.org/copyleft/gpl.txt> for the terms of the latest version
+of the GNU General Public License.
 
 
-QT FREE EDITION IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND,
-INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE.
-      _______________________________________________________________

+ 3 - 3
apt-inst/contrib/arfile.cc

@@ -87,7 +87,7 @@ bool ARArchive::LoadHeaders()
 	  StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
 	  StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
       {
       {
 	 delete Memb;
 	 delete Memb;
-	 return _error->Error(_("Invalid archive member header"));
+	 return _error->Error(_("Invalid archive member header %s"), Head.Name);
       }
       }
 	 
 	 
       // Check for an extra long name string
       // Check for an extra long name string
@@ -96,7 +96,7 @@ bool ARArchive::LoadHeaders()
 	 char S[300];
 	 char S[300];
 	 unsigned long Len;
 	 unsigned long Len;
 	 if (StrToNum(Head.Name+3,Len,sizeof(Head.Size)-3) == false ||
 	 if (StrToNum(Head.Name+3,Len,sizeof(Head.Size)-3) == false ||
-	     Len >= strlen(S))
+	     Len >= sizeof(S))
 	 {
 	 {
 	    delete Memb;
 	    delete Memb;
 	    return _error->Error(_("Invalid archive member header"));
 	    return _error->Error(_("Invalid archive member header"));
@@ -111,7 +111,7 @@ bool ARArchive::LoadHeaders()
       else
       else
       {
       {
 	 unsigned int I = sizeof(Head.Name) - 1;
 	 unsigned int I = sizeof(Head.Name) - 1;
-	 for (; Head.Name[I] == ' '; I--);
+	 for (; Head.Name[I] == ' ' || Head.Name[I] == '/'; I--);
 	 Memb->Name = string(Head.Name,I+1);
 	 Memb->Name = string(Head.Name,I+1);
       }
       }
 
 

+ 3 - 1
apt-inst/makefile

@@ -9,9 +9,11 @@ HEADER_TARGETDIRS = apt-pkg
 # Bring in the default rules
 # Bring in the default rules
 include ../buildlib/defaults.mak
 include ../buildlib/defaults.mak
 
 
+# The library name and version (indirectly used from init.h)
+include ../buildlib/libversion.mak
+
 # The library name
 # The library name
 LIBRARY=apt-inst
 LIBRARY=apt-inst
-LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
 MAJOR=1.1
 MAJOR=1.1
 MINOR=0
 MINOR=0
 SLIBS=$(PTHREADLIB) -lapt-pkg
 SLIBS=$(PTHREADLIB) -lapt-pkg

+ 75 - 92
apt-pkg/acquire-item.cc

@@ -15,6 +15,7 @@
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/acquire-item.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/vendorlist.h>
 #include <apt-pkg/vendorlist.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
@@ -131,9 +132,7 @@ void pkgAcquire::Item::Rename(string From,string To)
    }   
    }   
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-
-// AcqDiffIndex::AcqDiffIndex - Constructor			
+// AcqDiffIndex::AcqDiffIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Get the DiffIndex file first and see if there are patches availabe 
 /* Get the DiffIndex file first and see if there are patches availabe 
  * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
  * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
@@ -184,7 +183,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
    QueueURI(Desc);
    QueueURI(Desc);
 
 
 }
 }
-
+									/*}}}*/
 // AcqIndex::Custom600Headers - Insert custom request headers		/*{{{*/
 // AcqIndex::Custom600Headers - Insert custom request headers		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The only header we use is the last-modified header. */
 /* The only header we use is the last-modified header. */
@@ -202,9 +201,8 @@ string pkgAcqDiffIndex::Custom600Headers()
    
    
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
-
-
-bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
+									/*}}}*/
+bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)		/*{{{*/
 {
 {
    if(Debug)
    if(Debug)
       std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
       std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
@@ -291,8 +289,8 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
       std::clog << "Can't find a patch in the index file" << std::endl;
       std::clog << "Can't find a patch in the index file" << std::endl;
    return false;
    return false;
 }
 }
-
-void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+									/*}}}*/
+void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 {
 {
    if(Debug)
    if(Debug)
       std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
       std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
@@ -305,8 +303,8 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    Status = StatDone;
    Status = StatDone;
    Dequeue();
    Dequeue();
 }
 }
-
-void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
+									/*}}}*/
+void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,	/*{{{*/
 			   pkgAcquire::MethodConfig *Cnf)
 			   pkgAcquire::MethodConfig *Cnf)
 {
 {
    if(Debug)
    if(Debug)
@@ -335,10 +333,8 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
    Dequeue();
    Dequeue();
    return;
    return;
 }
 }
-
-
-
-// AcqIndexDiffs::AcqIndexDiffs - Constructor			
+									/*}}}*/
+// AcqIndexDiffs::AcqIndexDiffs - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The package diff is added to the queue. one object is constructed
 /* The package diff is added to the queue. one object is constructed
  * for each diff and the index
  * for each diff and the index
@@ -372,9 +368,8 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
       QueueNextDiff();
       QueueNextDiff();
    }
    }
 }
 }
-
-
-void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+									/*}}}*/
+void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 {
 {
    if(Debug)
    if(Debug)
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
@@ -383,9 +378,8 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 		   ExpectedHash);
 		   ExpectedHash);
    Finish();
    Finish();
 }
 }
-
-
-// helper that cleans the item out of the fetcher queue
+									/*}}}*/
+// Finish - helper that cleans the item out of the fetcher queue	/*{{{*/
 void pkgAcqIndexDiffs::Finish(bool allDone)
 void pkgAcqIndexDiffs::Finish(bool allDone)
 {
 {
    // we restore the original name, this is required, otherwise
    // we restore the original name, this is required, otherwise
@@ -420,10 +414,8 @@ void pkgAcqIndexDiffs::Finish(bool allDone)
    Dequeue();
    Dequeue();
    return;
    return;
 }
 }
-
-
-
-bool pkgAcqIndexDiffs::QueueNextDiff()
+									/*}}}*/
+bool pkgAcqIndexDiffs::QueueNextDiff()					/*{{{*/
 {
 {
 
 
    // calc sha1 of the just patched file
    // calc sha1 of the just patched file
@@ -469,10 +461,8 @@ bool pkgAcqIndexDiffs::QueueNextDiff()
 
 
    return true;
    return true;
 }
 }
-
-
-
-void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
+									/*}}}*/
+void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,	/*{{{*/
 			    pkgAcquire::MethodConfig *Cnf)
 			    pkgAcquire::MethodConfig *Cnf)
 {
 {
    if(Debug)
    if(Debug)
@@ -543,8 +533,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
 	 return Finish(true);
 	 return Finish(true);
    }
    }
 }
 }
-
-
+									/*}}}*/
 // AcqIndex::AcqIndex - Constructor					/*{{{*/
 // AcqIndex::AcqIndex - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The package file is added to the queue and a second class is 
 /* The package file is added to the queue and a second class is 
@@ -563,13 +552,14 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
    if(comprExt.empty()) 
    if(comprExt.empty()) 
    {
    {
       // autoselect the compression method
       // autoselect the compression method
-      if(FileExists("/bin/bzip2")) 
-	 CompressionExtension = ".bz2";
-      else 
-	 CompressionExtension = ".gz";
-   } else {
-      CompressionExtension = (comprExt == "plain" ? "" : comprExt);
+      std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+      if (types.empty() == true)
+	 comprExt = "plain";
+      else
+	 comprExt = "." + types[0];
    }
    }
+   CompressionExtension = ((comprExt == "plain" || comprExt == ".") ? "" : comprExt);
+
    Desc.URI = URI + CompressionExtension;
    Desc.URI = URI + CompressionExtension;
 
 
    Desc.Description = URIDesc;
    Desc.Description = URIDesc;
@@ -594,27 +584,29 @@ string pkgAcqIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)	/*{{{*/
 {
 {
-   bool descChanged = false;
-   // no .bz2 found, retry with .gz
-   if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") {
-      Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz";
-
-      new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
-		      ExpectedHash, string(".gz"));
-	  descChanged = true;
-   }
-   // no .gz found, retry with uncompressed
-   else if(Desc.URI.substr(Desc.URI.size()-2) == "gz") {
-      Desc.URI = Desc.URI.substr(0,Desc.URI.size()-2);
+   std::vector<std::string> types = APT::Configuration::getCompressionTypes();
 
 
-      new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
-		      ExpectedHash, string("plain"));
-	  descChanged = true;
-   }
-   if (descChanged) {
+   for (std::vector<std::string>::const_iterator t = types.begin();
+	t != types.end(); t++)
+   {
+      // jump over all already tried compression types
+      const unsigned int nameLen = Desc.URI.size() - (*t).size();
+      if(Desc.URI.substr(nameLen) != *t)
+	 continue;
+
+      // we want to try it with the next extension (and make sure to 
+      // not skip over the end)
+      t++;
+      if (t == types.end())
+	 break;
+
+      // queue new download
+      Desc.URI = Desc.URI.substr(0, nameLen) + *t;
+      new pkgAcqIndex(Owner, RealURI, Desc.Description, Desc.ShortDesc,
+      ExpectedHash, string(".").append(*t));
+      
       Status = StatDone;
       Status = StatDone;
       Complete = false;
       Complete = false;
       Dequeue();
       Dequeue();
@@ -630,8 +622,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 
 
    Item::Failed(Message,Cnf);
    Item::Failed(Message,Cnf);
 }
 }
-
-
+									/*}}}*/
 // AcqIndex::Done - Finished a fetch					/*{{{*/
 // AcqIndex::Done - Finished a fetch					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This goes through a number of states.. On the initial fetch the
 /* This goes through a number of states.. On the initial fetch the
@@ -712,11 +703,11 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
       Local = true;
       Local = true;
    
    
    string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
    string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
-   const char *decompProg;
-   if(compExt == "bz2") 
-      decompProg = "bzip2";
-   else if(compExt == "gz") 
-      decompProg = "gzip";
+   string decompProg;
+
+   // get the binary name for your used compression type
+   decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),"");
+   if(decompProg.empty() == false);
    // flExtensions returns the full name if no extension is found
    // flExtensions returns the full name if no extension is found
    // this is why we have this complicated compare operation here
    // this is why we have this complicated compare operation here
    // FIMXE: add a new flJustExtension() that return "" if no
    // FIMXE: add a new flJustExtension() that return "" if no
@@ -731,11 +722,11 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
 
 
    Decompression = true;
    Decompression = true;
    DestFile += ".decomp";
    DestFile += ".decomp";
-   Desc.URI = string(decompProg) + ":" + FileName;
+   Desc.URI = decompProg + ":" + FileName;
    QueueURI(Desc);
    QueueURI(Desc);
-   Mode = decompProg;
+   Mode = decompProg.c_str();
 }
 }
-
+									/*}}}*/
 // AcqIndexTrans::pkgAcqIndexTrans - Constructor			/*{{{*/
 // AcqIndexTrans::pkgAcqIndexTrans - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The Translation file is added to the queue */
 /* The Translation file is added to the queue */
@@ -744,7 +735,6 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
   : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
   : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
 {
 {
 }
 }
-
 									/*}}}*/
 									/*}}}*/
 // AcqIndexTrans::Failed - Silence failure messages for missing files	/*{{{*/
 // AcqIndexTrans::Failed - Silence failure messages for missing files	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -764,8 +754,7 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    Item::Failed(Message,Cnf);
    Item::Failed(Message,Cnf);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
+pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,				/*{{{*/
 			     string URI,string URIDesc,string ShortDesc,
 			     string URI,string URIDesc,string ShortDesc,
 			     string MetaIndexURI, string MetaIndexURIDesc,
 			     string MetaIndexURI, string MetaIndexURIDesc,
 			     string MetaIndexShortDesc,
 			     string MetaIndexShortDesc,
@@ -854,7 +843,7 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
 
 
 }
 }
 									/*}}}*/
 									/*}}}*/
-void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
 {
 {
    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
 
 
@@ -890,8 +879,8 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    
    
    Item::Failed(Message,Cnf);
    Item::Failed(Message,Cnf);
 }
 }
-
-pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
+									/*}}}*/
+pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,			/*{{{*/
 				 string URI,string URIDesc,string ShortDesc,
 				 string URI,string URIDesc,string ShortDesc,
 				 string SigFile,
 				 string SigFile,
 				 const vector<struct IndexTarget*>* IndexTargets,
 				 const vector<struct IndexTarget*>* IndexTargets,
@@ -910,7 +899,6 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
 
 
    QueueURI(Desc);
    QueueURI(Desc);
 }
 }
-
 									/*}}}*/
 									/*}}}*/
 // pkgAcqMetaIndex::Custom600Headers - Insert custom request headers	/*{{{*/
 // pkgAcqMetaIndex::Custom600Headers - Insert custom request headers	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -926,8 +914,8 @@ string pkgAcqMetaIndex::Custom600Headers()
    
    
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 }
-
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
+									/*}}}*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,	/*{{{*/
 			   pkgAcquire::MethodConfig *Cfg)
 			   pkgAcquire::MethodConfig *Cfg)
 {
 {
    Item::Done(Message,Size,Hash,Cfg);
    Item::Done(Message,Size,Hash,Cfg);
@@ -968,8 +956,8 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
       }
       }
    }
    }
 }
 }
-
-void pkgAcqMetaIndex::RetrievalDone(string Message)
+									/*}}}*/
+void pkgAcqMetaIndex::RetrievalDone(string Message)			/*{{{*/
 {
 {
    // We have just finished downloading a Release file (it is not
    // We have just finished downloading a Release file (it is not
    // verified yet)
    // verified yet)
@@ -1007,8 +995,8 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)
    chmod(FinalFile.c_str(),0644);
    chmod(FinalFile.c_str(),0644);
    DestFile = FinalFile;
    DestFile = FinalFile;
 }
 }
-
-void pkgAcqMetaIndex::AuthDone(string Message)
+									/*}}}*/
+void pkgAcqMetaIndex::AuthDone(string Message)				/*{{{*/
 {
 {
    // At this point, the gpgv method has succeeded, so there is a
    // At this point, the gpgv method has succeeded, so there is a
    // valid signature from a key in the trusted keyring.  We
    // valid signature from a key in the trusted keyring.  We
@@ -1041,8 +1029,8 @@ void pkgAcqMetaIndex::AuthDone(string Message)
    Rename(SigFile,VerifiedSigFile);
    Rename(SigFile,VerifiedSigFile);
    chmod(VerifiedSigFile.c_str(),0644);
    chmod(VerifiedSigFile.c_str(),0644);
 }
 }
-
-void pkgAcqMetaIndex::QueueIndexes(bool verify)
+									/*}}}*/
+void pkgAcqMetaIndex::QueueIndexes(bool verify)				/*{{{*/
 {
 {
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         Target != IndexTargets->end();
@@ -1084,8 +1072,8 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
 			    (*Target)->ShortDesc, ExpectedIndexHash);
 			    (*Target)->ShortDesc, ExpectedIndexHash);
    }
    }
 }
 }
-
-bool pkgAcqMetaIndex::VerifyVendor(string Message)
+									/*}}}*/
+bool pkgAcqMetaIndex::VerifyVendor(string Message)			/*{{{*/
 {
 {
 //    // Maybe this should be made available from above so we don't have
 //    // Maybe this should be made available from above so we don't have
 //    // to read and parse it every time?
 //    // to read and parse it every time?
@@ -1171,9 +1159,8 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)
 
 
    return true;
    return true;
 }
 }
-       								/*}}}*/
-// pkgAcqMetaIndex::Failed - no Release file present or no signature
-//      file present	                                        /*{{{*/
+									/*}}}*/
+// pkgAcqMetaIndex::Failed - no Release file present or no signature file present	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
@@ -1210,9 +1197,7 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    // back to queueing Packages files without verification
    // back to queueing Packages files without verification
    QueueIndexes(false);
    QueueIndexes(false);
 }
 }
-
 									/*}}}*/
 									/*}}}*/
-
 // AcqArchive::AcqArchive - Constructor					/*{{{*/
 // AcqArchive::AcqArchive - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This just sets up the initial fetch environment and queues the first
 /* This just sets up the initial fetch environment and queues the first
@@ -1495,14 +1480,13 @@ void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
-// AcqArchive::IsTrusted - Determine whether this archive comes from a
-// trusted source							/*{{{*/
+// AcqArchive::IsTrusted - Determine whether this archive comes from a trusted source /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 bool pkgAcqArchive::IsTrusted()
 bool pkgAcqArchive::IsTrusted()
 {
 {
    return Trusted;
    return Trusted;
 }
 }
-
+									/*}}}*/
 // AcqArchive::Finished - Fetching has finished, tidy up		/*{{{*/
 // AcqArchive::Finished - Fetching has finished, tidy up		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -1514,7 +1498,6 @@ void pkgAcqArchive::Finished()
    StoreFilename = string();
    StoreFilename = string();
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // AcqFile::pkgAcqFile - Constructor					/*{{{*/
 // AcqFile::pkgAcqFile - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The file is added to the queue */
 /* The file is added to the queue */

+ 25 - 29
apt-pkg/acquire-item.h

@@ -34,7 +34,7 @@
  *  \file acquire-item.h
  *  \file acquire-item.h
  */
  */
 
 
-/** \brief Represents the process by which a pkgAcquire object should
+/** \brief Represents the process by which a pkgAcquire object should	{{{
  *  retrieve a file or a collection of files.
  *  retrieve a file or a collection of files.
  *
  *
  *  By convention, Item subclasses should insert themselves into the
  *  By convention, Item subclasses should insert themselves into the
@@ -261,8 +261,8 @@ class pkgAcquire::Item
     */
     */
    virtual ~Item();
    virtual ~Item();
 };
 };
-
-/** \brief Information about an index patch (aka diff). */
+									/*}}}*/
+/** \brief Information about an index patch (aka diff). */		/*{{{*/
 struct DiffInfo {
 struct DiffInfo {
    /** The filename of the diff. */
    /** The filename of the diff. */
    string file;
    string file;
@@ -273,8 +273,8 @@ struct DiffInfo {
    /** The size of the diff. */
    /** The size of the diff. */
    unsigned long size;
    unsigned long size;
 };
 };
-
-/** \brief An item that is responsible for fetching an index file of
+									/*}}}*/
+/** \brief An item that is responsible for fetching an index file of	{{{
  *  package list diffs and starting the package list's download.
  *  package list diffs and starting the package list's download.
  *
  *
  *  This item downloads the Index file and parses it, then enqueues
  *  This item downloads the Index file and parses it, then enqueues
@@ -348,8 +348,8 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
    pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
 		   string ShortDesc, HashString ExpectedHash);
 		   string ShortDesc, HashString ExpectedHash);
 };
 };
-
-/** \brief An item that is responsible for fetching all the patches
+									/*}}}*/
+/** \brief An item that is responsible for fetching all the patches	{{{
  *  that need to be applied to a given package index file.
  *  that need to be applied to a given package index file.
  *
  *
  *  After downloading and applying a single patch, this item will
  *  After downloading and applying a single patch, this item will
@@ -477,8 +477,8 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
 		    string ShortDesc, HashString ExpectedHash,
 		    string ShortDesc, HashString ExpectedHash,
 		    vector<DiffInfo> diffs=vector<DiffInfo>());
 		    vector<DiffInfo> diffs=vector<DiffInfo>());
 };
 };
-
-/** \brief An acquire item that is responsible for fetching an index
+									/*}}}*/
+/** \brief An acquire item that is responsible for fetching an index	{{{
  *  file (e.g., Packages or Sources).
  *  file (e.g., Packages or Sources).
  *
  *
  *  \sa pkgAcqDiffIndex, pkgAcqIndexDiffs, pkgAcqIndexTrans
  *  \sa pkgAcqDiffIndex, pkgAcqIndexDiffs, pkgAcqIndexTrans
@@ -540,13 +540,15 @@ class pkgAcqIndex : public pkgAcquire::Item
     *
     *
     *  \param compressExt The compression-related extension with which
     *  \param compressExt The compression-related extension with which
     *  this index file should be downloaded, or "" to autodetect
     *  this index file should be downloaded, or "" to autodetect
-    *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
+    *  Compression types can be set with config Acquire::CompressionTypes,
+    *  default is ".lzma" or ".bz2" (if the needed binaries are present)
+    *  fallback is ".gz" or none.
     */
     */
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
 	       string ShortDesc, HashString ExpectedHash, string compressExt="");
 	       string ShortDesc, HashString ExpectedHash, string compressExt="");
 };
 };
-
-/** \brief An acquire item that is responsible for fetching a
+									/*}}}*/
+/** \brief An acquire item that is responsible for fetching a		{{{
  *  translated index file.
  *  translated index file.
  *
  *
  *  The only difference from pkgAcqIndex is that transient failures
  *  The only difference from pkgAcqIndex is that transient failures
@@ -569,18 +571,12 @@ class pkgAcqIndexTrans : public pkgAcqIndex
     *  \param URIDesc A "URI-style" description of this index file.
     *  \param URIDesc A "URI-style" description of this index file.
     *
     *
     *  \param ShortDesc A brief description of this index file.
     *  \param ShortDesc A brief description of this index file.
-    *
-    *  \param ExpectedHash The expected hashsum of this index file.
-    *
-    *  \param compressExt The compression-related extension with which
-    *  this index file should be downloaded, or "" to autodetect
-    *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
     */
     */
    pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
    pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
 		    string ShortDesc);
 		    string ShortDesc);
 };
 };
-
-/** \brief Information about an index file. */
+									/*}}}*/
+/** \brief Information about an index file. */				/*{{{*/
 struct IndexTarget
 struct IndexTarget
 {
 {
    /** \brief A URI from which the index file can be downloaded. */
    /** \brief A URI from which the index file can be downloaded. */
@@ -597,8 +593,8 @@ struct IndexTarget
     */
     */
    string MetaKey;
    string MetaKey;
 };
 };
-
-/** \brief An acquire item that downloads the detached signature
+									/*}}}*/
+/** \brief An acquire item that downloads the detached signature	{{{
  *  of a meta-index (Release) file, then queues up the release
  *  of a meta-index (Release) file, then queues up the release
  *  file itself.
  *  file itself.
  *
  *
@@ -660,8 +656,8 @@ class pkgAcqMetaSig : public pkgAcquire::Item
 		 const vector<struct IndexTarget*>* IndexTargets,
 		 const vector<struct IndexTarget*>* IndexTargets,
 		 indexRecords* MetaIndexParser);
 		 indexRecords* MetaIndexParser);
 };
 };
-
-/** \brief An item that is responsible for downloading the meta-index
+									/*}}}*/
+/** \brief An item that is responsible for downloading the meta-index	{{{
  *  file (i.e., Release) itself and verifying its signature.
  *  file (i.e., Release) itself and verifying its signature.
  *
  *
  *  Once the download and verification are complete, the downloads of
  *  Once the download and verification are complete, the downloads of
@@ -756,8 +752,8 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
 		   const vector<struct IndexTarget*>* IndexTargets,
 		   const vector<struct IndexTarget*>* IndexTargets,
 		   indexRecords* MetaIndexParser);
 		   indexRecords* MetaIndexParser);
 };
 };
-
-/** \brief An item that is responsible for fetching a package file.
+									/*}}}*/
+/** \brief An item that is responsible for fetching a package file.	{{{
  *
  *
  *  If the package file already exists in the cache, nothing will be
  *  If the package file already exists in the cache, nothing will be
  *  done.
  *  done.
@@ -840,8 +836,8 @@ class pkgAcqArchive : public pkgAcquire::Item
 		 pkgRecords *Recs,pkgCache::VerIterator const &Version,
 		 pkgRecords *Recs,pkgCache::VerIterator const &Version,
 		 string &StoreFilename);
 		 string &StoreFilename);
 };
 };
-
-/** \brief Retrieve an arbitrary file to the current directory.
+									/*}}}*/
+/** \brief Retrieve an arbitrary file to the current directory.		{{{
  *
  *
  *  The file is retrieved even if it is accessed via a URL type that
  *  The file is retrieved even if it is accessed via a URL type that
  *  normally is a NOP, such as "file".  If the download fails, the
  *  normally is a NOP, such as "file".  If the download fails, the
@@ -902,7 +898,7 @@ class pkgAcqFile : public pkgAcquire::Item
 	      string Desc, string ShortDesc,
 	      string Desc, string ShortDesc,
 	      const string &DestDir="", const string &DestFilename="");
 	      const string &DestDir="", const string &DestFilename="");
 };
 };
-
+									/*}}}*/
 /** @} */
 /** @} */
 
 
 #endif
 #endif

+ 0 - 2
apt-pkg/acquire-method.cc

@@ -446,7 +446,6 @@ void pkgAcqMethod::Status(const char *Format,...)
       exit(100);
       exit(100);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // AcqMethod::Redirect - Send a redirect message                       /*{{{*/
 // AcqMethod::Redirect - Send a redirect message                       /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This method sends the redirect message and also manipulates the queue
 /* This method sends the redirect message and also manipulates the queue
@@ -478,7 +477,6 @@ void pkgAcqMethod::Redirect(const string &NewURI)
       QueueBack = I->Next;
       QueueBack = I->Next;
 }
 }
                                                                         /*}}}*/
                                                                         /*}}}*/
-
 // AcqMethod::FetchResult::FetchResult - Constructor			/*{{{*/
 // AcqMethod::FetchResult::FetchResult - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 2 - 5
apt-pkg/acquire.cc

@@ -266,7 +266,7 @@ pkgAcquire::MethodConfig *pkgAcquire::GetConfig(string Access)
       return 0;
       return 0;
 
 
    /* if a method uses DownloadLimit, we switch to SingleInstance mode */
    /* if a method uses DownloadLimit, we switch to SingleInstance mode */
-   if(_config->FindI("Acquire::"+Access+"::DlLimit",0) > 0)
+   if(_config->FindI("Acquire::"+Access+"::Dl-Limit",0) > 0)
       Conf->SingleInstance = true;
       Conf->SingleInstance = true;
     
     
    return Conf;
    return Conf;
@@ -485,7 +485,7 @@ double pkgAcquire::PartialPresent()
 	 Total += (*I)->PartialSize;
 	 Total += (*I)->PartialSize;
    return Total;
    return Total;
 }
 }
-
+									/*}}}*/
 // Acquire::UriBegin - Start iterator for the uri list			/*{{{*/
 // Acquire::UriBegin - Start iterator for the uri list			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -502,7 +502,6 @@ pkgAcquire::UriIterator pkgAcquire::UriEnd()
    return UriIterator(0);
    return UriIterator(0);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // Acquire::MethodConfig::MethodConfig - Constructor			/*{{{*/
 // Acquire::MethodConfig::MethodConfig - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -516,7 +515,6 @@ pkgAcquire::MethodConfig::MethodConfig()
    Next = 0;
    Next = 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // Queue::Queue - Constructor						/*{{{*/
 // Queue::Queue - Constructor						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -728,7 +726,6 @@ void pkgAcquire::Queue::Bump()
    Cycle();
    Cycle();
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // AcquireStatus::pkgAcquireStatus - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 13 - 13
apt-pkg/acquire.h

@@ -30,7 +30,7 @@
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 
 
-/** \defgroup acquire Acquire system
+/** \defgroup acquire Acquire system					{{{
  *
  *
  *  \brief The Acquire system is responsible for retrieving files from
  *  \brief The Acquire system is responsible for retrieving files from
  *  local or remote URIs and postprocessing them (for instance,
  *  local or remote URIs and postprocessing them (for instance,
@@ -54,7 +54,7 @@
  *  once, but it is not clear what its behavior in this case is, and
  *  once, but it is not clear what its behavior in this case is, and
  *  no subclass of pkgAcquire::Item seems to actually use this
  *  no subclass of pkgAcquire::Item seems to actually use this
  *  capability.
  *  capability.
- */
+ */									/*}}}*/
 
 
 /** \addtogroup acquire
 /** \addtogroup acquire
  *
  *
@@ -78,7 +78,7 @@ using std::string;
 
 
 class pkgAcquireStatus;
 class pkgAcquireStatus;
 
 
-/** \brief The core download scheduler.
+/** \brief The core download scheduler.					{{{
  *
  *
  *  This class represents an ongoing download.  It manages the lists
  *  This class represents an ongoing download.  It manages the lists
  *  of active and pending downloads and handles setting up and tearing
  *  of active and pending downloads and handles setting up and tearing
@@ -366,8 +366,8 @@ struct pkgAcquire::ItemDesc
    /** brief The underlying item which is to be downloaded. */
    /** brief The underlying item which is to be downloaded. */
    Item *Owner;
    Item *Owner;
 };
 };
-
-/** \brief A single download queue in a pkgAcquire object.
+									/*}}}*/
+/** \brief A single download queue in a pkgAcquire object.		{{{
  *
  *
  *  \todo Why so many protected values?
  *  \todo Why so many protected values?
  */
  */
@@ -528,8 +528,8 @@ class pkgAcquire::Queue
     */
     */
    ~Queue();
    ~Queue();
 };
 };
-
-/** \brief Iterates over all the URIs being fetched by a pkgAcquire object. */
+									/*}}}*/
+/** \brief Iterates over all the URIs being fetched by a pkgAcquire object.	{{{*/
 class pkgAcquire::UriIterator
 class pkgAcquire::UriIterator
 {
 {
    /** The next queue to iterate over. */
    /** The next queue to iterate over. */
@@ -539,7 +539,7 @@ class pkgAcquire::UriIterator
    
    
    public:
    public:
    
    
-   inline void operator ++() {operator ++();};
+   inline void operator ++() {operator ++(0);};
 
 
    void operator ++(int)
    void operator ++(int)
    {
    {
@@ -568,8 +568,8 @@ class pkgAcquire::UriIterator
       }
       }
    }   
    }   
 };
 };
-
-/** \brief Information about the properties of a single acquire method. */
+									/*}}}*/
+/** \brief Information about the properties of a single acquire method.	{{{*/
 struct pkgAcquire::MethodConfig
 struct pkgAcquire::MethodConfig
 {
 {
    /** \brief The next link on the acquire method list.
    /** \brief The next link on the acquire method list.
@@ -621,8 +621,8 @@ struct pkgAcquire::MethodConfig
     */
     */
    MethodConfig();
    MethodConfig();
 };
 };
-
-/** \brief A monitor object for downloads controlled by the pkgAcquire class.
+									/*}}}*/
+/** \brief A monitor object for downloads controlled by the pkgAcquire class.	{{{
  *
  *
  *  \todo Why protected members?
  *  \todo Why protected members?
  *
  *
@@ -762,7 +762,7 @@ class pkgAcquireStatus
    pkgAcquireStatus();
    pkgAcquireStatus();
    virtual ~pkgAcquireStatus() {};
    virtual ~pkgAcquireStatus() {};
 };
 };
-
+									/*}}}*/
 /** @} */
 /** @} */
 
 
 #endif
 #endif

+ 73 - 37
apt-pkg/algorithms.cc

@@ -442,7 +442,6 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // ProblemResolver::pkgProblemResolver - Constructor			/*{{{*/
 // ProblemResolver::pkgProblemResolver - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -489,6 +488,36 @@ void pkgProblemResolver::MakeScores()
    unsigned long Size = Cache.Head().PackageCount;
    unsigned long Size = Cache.Head().PackageCount;
    memset(Scores,0,sizeof(*Scores)*Size);
    memset(Scores,0,sizeof(*Scores)*Size);
 
 
+   // Important Required Standard Optional Extra
+   signed short PrioMap[] = {
+      0,
+      _config->FindI("pkgProblemResolver::Scores::Important",3),
+      _config->FindI("pkgProblemResolver::Scores::Required",2),
+      _config->FindI("pkgProblemResolver::Scores::Standard",1),
+      _config->FindI("pkgProblemResolver::Scores::Optional",-1),
+      _config->FindI("pkgProblemResolver::Scores::Extra",-2)
+   };
+   signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
+   signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
+   signed short PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
+   signed short PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
+   signed short AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
+   signed short AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
+
+   if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+      clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl
+         << "  Important => " << PrioMap[1] << endl
+         << "  Required => " << PrioMap[2] << endl
+         << "  Standard => " << PrioMap[3] << endl
+         << "  Optional => " << PrioMap[4] << endl
+         << "  Extra => " << PrioMap[5] << endl
+         << "  Essentials => " << PrioEssentials << endl
+         << "  InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl
+         << "  Depends => " << PrioDepends << endl
+         << "  Recommends => " << PrioRecommends << endl
+         << "  AddProtected => " << AddProtected << endl
+         << "  AddEssential => " << AddEssential << endl;
+
    // Generate the base scores for a package based on its properties
    // Generate the base scores for a package based on its properties
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
    {
@@ -502,11 +531,9 @@ void pkgProblemResolver::MakeScores()
 	 to allow an obsolete essential packages to be removed by
 	 to allow an obsolete essential packages to be removed by
 	 a conflicts on a powerfull normal package (ie libc6) */
 	 a conflicts on a powerfull normal package (ie libc6) */
       if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
       if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
-	 Score += 100;
+	 Score += PrioEssentials;
 
 
       // We transform the priority
       // We transform the priority
-      // Important Required Standard Optional Extra
-      signed short PrioMap[] = {0,3,2,1,-1,-2};
       if (Cache[I].InstVerIter(Cache)->Priority <= 5)
       if (Cache[I].InstVerIter(Cache)->Priority <= 5)
 	 Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority];
 	 Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority];
       
       
@@ -515,7 +542,7 @@ void pkgProblemResolver::MakeScores()
 	 if those are not obsolete
 	 if those are not obsolete
       */
       */
       if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable())
       if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable())
-	 Score += 1;
+	 Score += PrioInstalledAndNotObsolete;
    }
    }
 
 
    // Now that we have the base scores we go and propogate dependencies
    // Now that we have the base scores we go and propogate dependencies
@@ -527,9 +554,10 @@ void pkgProblemResolver::MakeScores()
       for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; D++)
       for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; D++)
       {
       {
 	 if (D->Type == pkgCache::Dep::Depends || 
 	 if (D->Type == pkgCache::Dep::Depends || 
-	     D->Type == pkgCache::Dep::PreDepends || 
-	     D->Type == pkgCache::Dep::Recommends) 
-	    Scores[D.TargetPkg()->ID]++;
+	     D->Type == pkgCache::Dep::PreDepends)
+	    Scores[D.TargetPkg()->ID] += PrioDepends;
+	 else if (D->Type == pkgCache::Dep::Recommends)
+	    Scores[D.TargetPkg()->ID] += PrioRecommends;
       }
       }
    }   
    }   
    
    
@@ -576,10 +604,10 @@ void pkgProblemResolver::MakeScores()
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
    {
       if ((Flags[I->ID] & Protected) != 0)
       if ((Flags[I->ID] & Protected) != 0)
-	 Scores[I->ID] += 10000;
+	 Scores[I->ID] += AddProtected;
       if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
       if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
-	 Scores[I->ID] += 5000;
-   }   
+	 Scores[I->ID] += AddEssential;
+   }
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ProblemResolver::DoUpgrade - Attempt to upgrade this package		/*{{{*/
 // ProblemResolver::DoUpgrade - Attempt to upgrade this package		/*{{{*/
@@ -755,19 +783,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
       *PEnd++ = I;
       *PEnd++ = I;
    This = this;
    This = this;
    qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
    qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
-   
-/* for (pkgCache::Package **K = PList; K != PEnd; K++)
-      if (Scores[(*K)->ID] != 0)
-      {
-	 pkgCache::PkgIterator Pkg(Cache,*K);
-	 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
-	    ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' << 
-	    Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
-      } */
+
+   if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+   {
+      clog << "Show Scores" << endl;
+      for (pkgCache::Package **K = PList; K != PEnd; K++)
+         if (Scores[(*K)->ID] != 0)
+         {
+           pkgCache::PkgIterator Pkg(Cache,*K);
+           clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+         }
+   }
 
 
    if (Debug == true)
    if (Debug == true)
       clog << "Starting 2" << endl;
       clog << "Starting 2" << endl;
-   
+
    /* Now consider all broken packages. For each broken package we either
    /* Now consider all broken packages. For each broken package we either
       remove the package or fix it's problem. We do this once, it should
       remove the package or fix it's problem. We do this once, it should
       not be possible for a loop to form (that is a < b < c and fixing b by
       not be possible for a loop to form (that is a < b < c and fixing b by
@@ -882,7 +912,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    }
 	    }
 	    
 	    
 	    if (Debug == true)
 	    if (Debug == true)
-	       clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
+	       clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl;
 
 
 	    /* Look across the version list. If there are no possible
 	    /* Look across the version list. If there are no possible
 	       targets then we keep the package and bail. This is necessary
 	       targets then we keep the package and bail. This is necessary
@@ -964,12 +994,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 			   if (Debug == true)
 			   if (Debug == true)
 			      clog << "  Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
 			      clog << "  Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
 			   Cache.MarkDelete(I);
 			   Cache.MarkDelete(I);
-			   if (Counter > 1)
-			   {
-			      if (Scores[Pkg->ID] > Scores[I->ID])
-				 Scores[I->ID] = Scores[Pkg->ID];
-			   }			   
-			}			
+			   if (Counter > 1 && Scores[Pkg->ID] > Scores[I->ID])
+			      Scores[I->ID] = Scores[Pkg->ID];
+			}
 		     }
 		     }
 		  }
 		  }
 		  		  
 		  		  
@@ -1141,9 +1168,6 @@ bool pkgProblemResolver::ResolveByKeep()
 
 
    unsigned long Size = Cache.Head().PackageCount;
    unsigned long Size = Cache.Head().PackageCount;
 
 
-   if (Debug == true)      
-      clog << "Entering ResolveByKeep" << endl;
-   
    MakeScores();
    MakeScores();
    
    
    /* We have to order the packages so that the broken fixing pass 
    /* We have to order the packages so that the broken fixing pass 
@@ -1156,7 +1180,21 @@ bool pkgProblemResolver::ResolveByKeep()
       *PEnd++ = I;
       *PEnd++ = I;
    This = this;
    This = this;
    qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
    qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
-   
+
+   if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+   {
+      clog << "Show Scores" << endl;
+      for (pkgCache::Package **K = PList; K != PEnd; K++)
+         if (Scores[(*K)->ID] != 0)
+         {
+           pkgCache::PkgIterator Pkg(Cache,*K);
+           clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+         }
+   }
+
+   if (Debug == true)
+      clog << "Entering ResolveByKeep" << endl;
+
    // Consider each broken package 
    // Consider each broken package 
    pkgCache::Package **LastStop = 0;
    pkgCache::Package **LastStop = 0;
    for (pkgCache::Package **K = PList; K != PEnd; K++)
    for (pkgCache::Package **K = PList; K != PEnd; K++)
@@ -1202,8 +1240,8 @@ bool pkgProblemResolver::ResolveByKeep()
 	 while (true)
 	 while (true)
 	 {
 	 {
 	    if (Debug == true)
 	    if (Debug == true)
-	       clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
-	    
+	       clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl;
+
 	    // Look at all the possible provides on this package
 	    // Look at all the possible provides on this package
 	    SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
 	    SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
 	    for (pkgCache::Version **V = VList; *V != 0; V++)
 	    for (pkgCache::Version **V = VList; *V != 0; V++)
@@ -1219,7 +1257,7 @@ bool pkgProblemResolver::ResolveByKeep()
 	       if ((Flags[I->ID] & Protected) == 0)
 	       if ((Flags[I->ID] & Protected) == 0)
 	       {
 	       {
 		  if (Debug == true)
 		  if (Debug == true)
-		     clog << "  Keeping Package " << Pkg.Name() << " due to dep" << endl;
+		     clog << "  Keeping Package " << Pkg.Name() << " due to " << Start.DepType() << endl;
 		  Cache.MarkKeep(Pkg, false, false);
 		  Cache.MarkKeep(Pkg, false, false);
 	       }
 	       }
 	       
 	       
@@ -1276,7 +1314,6 @@ void pkgProblemResolver::InstallProtect()
    }   
    }   
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // PrioSortList - Sort a list of versions by priority			/*{{{*/
 // PrioSortList - Sort a list of versions by priority			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is ment to be used in conjunction with AllTargets to get a list 
 /* This is ment to be used in conjunction with AllTargets to get a list 
@@ -1307,7 +1344,6 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
    qsort(List,Count,sizeof(*List),PrioComp);
    qsort(List,Count,sizeof(*List),PrioComp);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // CacheFile::ListUpdate - update the cache files                    	/*{{{*/
 // CacheFile::ListUpdate - update the cache files                    	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is a simple wrapper to update the cache. it will fetch stuff
 /* This is a simple wrapper to update the cache. it will fetch stuff

+ 4 - 4
apt-pkg/algorithms.h

@@ -39,7 +39,7 @@
 
 
 using std::ostream;
 using std::ostream;
 
 
-class pkgSimulate : public pkgPackageManager
+class pkgSimulate : public pkgPackageManager				/*{{{*/
 {
 {
    protected:
    protected:
 
 
@@ -75,8 +75,8 @@ private:
 
 
    pkgSimulate(pkgDepCache *Cache);
    pkgSimulate(pkgDepCache *Cache);
 };
 };
-
-class pkgProblemResolver
+									/*}}}*/
+class pkgProblemResolver						/*{{{*/
 {
 {
    pkgDepCache &Cache;
    pkgDepCache &Cache;
    typedef pkgCache::PkgIterator PkgIterator;
    typedef pkgCache::PkgIterator PkgIterator;
@@ -124,7 +124,7 @@ class pkgProblemResolver
    pkgProblemResolver(pkgDepCache *Cache);
    pkgProblemResolver(pkgDepCache *Cache);
    ~pkgProblemResolver();
    ~pkgProblemResolver();
 };
 };
-
+									/*}}}*/
 bool pkgDistUpgrade(pkgDepCache &Cache);
 bool pkgDistUpgrade(pkgDepCache &Cache);
 bool pkgApplyStatus(pkgDepCache &Cache);
 bool pkgApplyStatus(pkgDepCache &Cache);
 bool pkgFixBroken(pkgDepCache &Cache);
 bool pkgFixBroken(pkgDepCache &Cache);

+ 90 - 0
apt-pkg/aptconfiguration.cc

@@ -0,0 +1,90 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Provide access methods to various configuration settings,
+   setup defaults and returns validate settings.
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/configuration.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+									/*}}}*/
+namespace APT {
+// getCompressionTypes - Return Vector of usbale compressiontypes	/*{{{*/
+// ---------------------------------------------------------------------
+/* return a vector of compression types in the prefered order. */
+std::vector<std::string>
+const Configuration::getCompressionTypes(bool const &Cached) {
+	static std::vector<std::string> types;
+	if (types.empty() == false) {
+		if (Cached == true)
+			return types;
+		else
+			types.clear();
+	}
+
+	// setup the defaults for the compressiontypes => method mapping
+	_config->CndSet("Acquire::CompressionTypes::bz2","bzip2");
+	_config->CndSet("Acquire::CompressionTypes::lzma","lzma");
+	_config->CndSet("Acquire::CompressionTypes::gz","gzip");
+
+	// Set default application paths to check for optional compression types
+	_config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
+	_config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
+
+	// accept non-list order as override setting for config settings on commandline
+	std::string const overrideOrder = _config->Find("Acquire::CompressionTypes::Order","");
+	if (overrideOrder.empty() == false)
+		types.push_back(overrideOrder);
+
+	// load the order setting into our vector
+	std::vector<std::string> const order = _config->FindVector("Acquire::CompressionTypes::Order");
+	for (std::vector<std::string>::const_iterator o = order.begin();
+	     o != order.end(); o++) {
+		if ((*o).empty() == true)
+			continue;
+		// ignore types we have no method ready to use
+		if (_config->Exists(string("Acquire::CompressionTypes::").append(*o)) == false)
+			continue;
+		// ignore types we have no app ready to use
+		string const appsetting = string("Dir::Bin::").append(*o);
+		if (_config->Exists(appsetting) == true) {
+			std::string const app = _config->FindFile(appsetting.c_str(), "");
+			if (app.empty() == false && FileExists(app) == false)
+				continue;
+		}
+		types.push_back(*o);
+	}
+
+	// move again over the option tree to add all missing compression types
+	::Configuration::Item const *Types = _config->Tree("Acquire::CompressionTypes");
+	if (Types != 0)
+		Types = Types->Child;
+
+	for (; Types != 0; Types = Types->Next) {
+		if (Types->Tag == "Order" || Types->Tag.empty() == true)
+			continue;
+		// ignore types we already have in the vector
+		if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
+			continue;
+		// ignore types we have no app ready to use
+		string const appsetting = string("Dir::Bin::").append(Types->Value);
+		if (appsetting.empty() == false && _config->Exists(appsetting) == true) {
+			std::string const app = _config->FindFile(appsetting.c_str(), "");
+			if (app.empty() == false && FileExists(app) == false)
+				continue;
+		}
+		types.push_back(Types->Tag);
+	}
+
+	return types;
+}
+									/*}}}*/
+}

+ 46 - 0
apt-pkg/aptconfiguration.h

@@ -0,0 +1,46 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/** \class APT::Configuration
+ *  \brief Provide access methods to various configuration settings
+ *
+ *  This class and their methods providing a layer around the usual access
+ *  methods with _config to ensure that settings are correct and to be able
+ *  to set defaults without the need to recheck it in every method again.
+ */
+									/*}}}*/
+#ifndef APT_CONFIGURATION_H
+#define APT_CONFIGURATION_H
+// Include Files							/*{{{*/
+#include <string>
+#include <vector>
+									/*}}}*/
+namespace APT {
+class Configuration {							/*{{{*/
+public:									/*{{{*/
+	/** \brief Returns a vector of usable Compression Types
+	 *
+	 *  Files can be compressed in various ways to decrease the size of the
+	 *  download. Therefore the Acquiremethods support a few compression types
+	 *  and some archives provide also a few different types. This option
+	 *  group exists to give the user the choice to prefer one type over the
+	 *  other (some compression types are very resource intensive - great if you
+	 *  have a limited download, bad if you have a really lowpowered hardware.)
+	 *
+	 *  This method ensures that the defaults are set and checks at runtime
+	 *  if the type can be used. E.g. the current default is to prefer bzip2
+	 *  over lzma and gz - if the bzip2 binary is not available it has not much
+	 *  sense in downloading the bz2 file, therefore we will not return bz2 as
+	 *  a usable compression type. The availability is checked with the settings
+	 *  in the Dir::Bin group.
+	 *
+	 *  \param Cached saves the result so we need to calculated it only once
+	 *                this parameter should ony be used for testing purposes.
+	 *
+	 *  \return a vector of (all) Language Codes in the prefered usage order
+	 */
+	std::vector<std::string> static const getCompressionTypes(bool const &Cached = true);
+									/*}}}*/
+};
+									/*}}}*/
+}
+#endif

+ 4 - 5
apt-pkg/cachefile.cc

@@ -24,7 +24,6 @@
     
     
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
-
 // CacheFile::CacheFile - Constructor					/*{{{*/
 // CacheFile::CacheFile - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -49,6 +48,7 @@ pkgCacheFile::~pkgCacheFile()
 /* */
 /* */
 bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock)
 bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock)
 {
 {
+   const bool ErrorWasEmpty = _error->empty();
    if (WithLock == true)
    if (WithLock == true)
       if (_system->Lock() == false)
       if (_system->Lock() == false)
 	 return false;
 	 return false;
@@ -71,7 +71,7 @@ bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock)
       return _error->Error(_("The package lists or status file could not be parsed or opened."));
       return _error->Error(_("The package lists or status file could not be parsed or opened."));
 
 
    /* This sux, remove it someday */
    /* This sux, remove it someday */
-   if (_error->empty() == false)
+   if (ErrorWasEmpty == true && _error->empty() == false)
       _error->Warning(_("You may want to run apt-get update to correct these problems"));
       _error->Warning(_("You may want to run apt-get update to correct these problems"));
 
 
    Cache = new pkgCache(Map);
    Cache = new pkgCache(Map);
@@ -92,7 +92,8 @@ bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
    Policy = new pkgPolicy(Cache);
    Policy = new pkgPolicy(Cache);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
-   if (ReadPinFile(*Policy) == false)
+
+   if (ReadPinFile(*Policy) == false || ReadPinDir(*Policy) == false)
       return false;
       return false;
    
    
    // Create the dependency cache
    // Create the dependency cache
@@ -108,8 +109,6 @@ bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-
 // CacheFile::Close - close the cache files				/*{{{*/
 // CacheFile::Close - close the cache files				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 30 - 20
apt-pkg/cacheiterators.h

@@ -32,7 +32,7 @@
 #define PKGLIB_CACHEITERATORS_H
 #define PKGLIB_CACHEITERATORS_H
 
 
 
 
-// Package Iterator
+// Package Iterator							/*{{{*/
 class pkgCache::PkgIterator
 class pkgCache::PkgIterator
 {
 {
    friend class pkgCache;
    friend class pkgCache;
@@ -80,7 +80,13 @@ class pkgCache::PkgIterator
    inline PrvIterator ProvidesList() const;
    inline PrvIterator ProvidesList() const;
    inline unsigned long Index() const {return Pkg - Owner->PkgP;};
    inline unsigned long Index() const {return Pkg - Owner->PkgP;};
    OkState State() const;
    OkState State() const;
-   
+
+   //Nice printable representation
+   friend std::ostream& operator<<(std::ostream& out, pkgCache::PkgIterator Pkg);
+
+   const char *CandVersion() const;
+   const char *CurVersion() const;
+
    // Constructors
    // Constructors
    inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner),
    inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner),
           HashIndex(0) 
           HashIndex(0) 
@@ -90,8 +96,8 @@ class pkgCache::PkgIterator
    };
    };
    inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {};
    inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {};
 };
 };
-
-// Version Iterator
+									/*}}}*/
+// Version Iterator							/*{{{*/
 class pkgCache::VerIterator
 class pkgCache::VerIterator
 {
 {
    Version *Ver;
    Version *Ver;
@@ -111,7 +117,10 @@ class pkgCache::VerIterator
    inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;};
    inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;};
    inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;};
    inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;};
    int CompareVer(const VerIterator &B) const;
    int CompareVer(const VerIterator &B) const;
-   
+
+   // Testing
+   inline bool IsGood() const { return Ver && Owner && ! end();};
+
    // Accessors
    // Accessors
    inline Version *operator ->() {return Ver;};
    inline Version *operator ->() {return Ver;};
    inline Version const *operator ->() const {return Ver;};
    inline Version const *operator ->() const {return Ver;};
@@ -146,8 +155,8 @@ class pkgCache::VerIterator
 	 Ver = Owner.VerP;
 	 Ver = Owner.VerP;
    };
    };
 };
 };
-
-// Description Iterator
+									/*}}}*/
+// Description Iterator							/*{{{*/
 class pkgCache::DescIterator
 class pkgCache::DescIterator
 {
 {
    Description *Desc;
    Description *Desc;
@@ -190,8 +199,8 @@ class pkgCache::DescIterator
 	 Desc = Owner.DescP;
 	 Desc = Owner.DescP;
    };
    };
 };
 };
-
-// Dependency iterator
+									/*}}}*/
+// Dependency iterator							/*{{{*/
 class pkgCache::DepIterator
 class pkgCache::DepIterator
 {
 {
    Dependency *Dep;
    Dependency *Dep;
@@ -249,8 +258,8 @@ class pkgCache::DepIterator
    };
    };
    inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {};
    inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {};
 };
 };
-
-// Provides iterator
+									/*}}}*/
+// Provides iterator							/*{{{*/
 class pkgCache::PrvIterator
 class pkgCache::PrvIterator
 {
 {
    Provides *Prv;
    Provides *Prv;
@@ -302,8 +311,8 @@ class pkgCache::PrvIterator
 	 Prv = Owner.ProvideP;
 	 Prv = Owner.ProvideP;
    };
    };
 };
 };
-
-// Package file 
+									/*}}}*/
+// Package file								/*{{{*/
 class pkgCache::PkgFileIterator
 class pkgCache::PkgFileIterator
 {
 {
    pkgCache *Owner;
    pkgCache *Owner;
@@ -333,6 +342,7 @@ class pkgCache::PkgFileIterator
    inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;};
    inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;};
    inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;};
    inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;};
    inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;};
    inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;};
+   inline const char *Codename() const {return File->Codename ==0?0:Owner->StrP + File->Codename;};
    inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;};
    inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;};
    inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;};
    inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;};
    inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;};
    inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;};
@@ -348,8 +358,8 @@ class pkgCache::PkgFileIterator
    inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {};
    inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {};
    inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {};
    inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {};
 };
 };
-
-// Version File 
+									/*}}}*/
+// Version File								/*{{{*/
 class pkgCache::VerFileIterator
 class pkgCache::VerFileIterator
 {
 {
    pkgCache *Owner;
    pkgCache *Owner;
@@ -380,8 +390,8 @@ class pkgCache::VerFileIterator
    inline VerFileIterator() : Owner(0), FileP(0) {};
    inline VerFileIterator() : Owner(0), FileP(0) {};
    inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {};
    inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {};
 };
 };
-
-// Description File 
+									/*}}}*/
+// Description File							/*{{{*/
 class pkgCache::DescFileIterator
 class pkgCache::DescFileIterator
 {
 {
    pkgCache *Owner;
    pkgCache *Owner;
@@ -412,8 +422,8 @@ class pkgCache::DescFileIterator
    inline DescFileIterator() : Owner(0), FileP(0) {};
    inline DescFileIterator() : Owner(0), FileP(0) {};
    inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {};
    inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {};
 };
 };
-
-// Inlined Begin functions cant be in the class because of order problems
+									/*}}}*/
+// Inlined Begin functions cant be in the class because of order problems /*{{{*/
 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
        {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);};
        {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);};
 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
 inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
@@ -432,5 +442,5 @@ inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
        {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);};
        {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);};
 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
 inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
        {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);};
        {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);};
-
+									/*}}}*/
 #endif
 #endif

+ 15 - 19
apt-pkg/cdrom.cc

@@ -160,7 +160,7 @@ bool pkgCdrom::FindPackages(string CD,
    
    
    return !_error->PendingError();
    return !_error->PendingError();
 }
 }
-
+									/*}}}*/
 // Score - We compute a 'score' for a path				/*{{{*/
 // Score - We compute a 'score' for a path				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Paths are scored based on how close they come to what I consider
 /* Paths are scored based on how close they come to what I consider
@@ -210,7 +210,6 @@ int pkgCdrom::Score(string Path)
 
 
    return Res;
    return Res;
 }
 }
-
 									/*}}}*/
 									/*}}}*/
 // DropBinaryArch - Dump dirs with a string like /binary-<foo>/		/*{{{*/
 // DropBinaryArch - Dump dirs with a string like /binary-<foo>/		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -248,8 +247,7 @@ bool pkgCdrom::DropBinaryArch(vector<string> &List)
    
    
    return true;
    return true;
 }
 }
-
-
+									/*}}}*/
 // DropRepeats - Drop repeated files resulting from symlinks		/*{{{*/
 // DropRepeats - Drop repeated files resulting from symlinks		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Here we go and stat every file that we found and strip dup inodes. */
 /* Here we go and stat every file that we found and strip dup inodes. */
@@ -304,7 +302,6 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // ReduceSourceList - Takes the path list and reduces it		/*{{{*/
 // ReduceSourceList - Takes the path list and reduces it		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This takes the list of source list expressed entires and collects
 /* This takes the list of source list expressed entires and collects
@@ -513,9 +510,8 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
    
    
    return true;
    return true;
 }
 }
-
-
-bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
+									/*}}}*/
+bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
 {
 {
    stringstream msg;
    stringstream msg;
 
 
@@ -573,9 +569,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
 
 
    return true;
    return true;
 }
 }
-
-
-bool pkgCdrom::Add(pkgCdromStatus *log)
+									/*}}}*/
+bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 {
 {
    stringstream msg;
    stringstream msg;
 
 
@@ -844,16 +839,16 @@ bool pkgCdrom::Add(pkgCdromStatus *log)
 
 
    return true;
    return true;
 }
 }
-
-
-pkgUdevCdromDevices::pkgUdevCdromDevices() 
+									/*}}}*/
+pkgUdevCdromDevices::pkgUdevCdromDevices()                     		/*{{{*/
    : libudev_handle(NULL)
    : libudev_handle(NULL)
 {
 {
 
 
 }
 }
+									/*}}}*/
 
 
 bool
 bool
-pkgUdevCdromDevices::Dlopen()
+pkgUdevCdromDevices::Dlopen()                     		        /*{{{*/
 {
 {
    // alread open
    // alread open
    if(libudev_handle != NULL)
    if(libudev_handle != NULL)
@@ -880,9 +875,9 @@ pkgUdevCdromDevices::Dlopen()
 
 
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 vector<CdromDevice>
 vector<CdromDevice>
-pkgUdevCdromDevices::Scan()
+pkgUdevCdromDevices::Scan()                                             /*{{{*/
 {
 {
    vector<CdromDevice> cdrom_devices;
    vector<CdromDevice> cdrom_devices;
    struct udev_enumerate *enumerate;
    struct udev_enumerate *enumerate;
@@ -922,9 +917,10 @@ pkgUdevCdromDevices::Scan()
    } 
    } 
    return cdrom_devices;
    return cdrom_devices;
 }
 }
+									/*}}}*/
 
 
-
-pkgUdevCdromDevices::~pkgUdevCdromDevices()
+pkgUdevCdromDevices::~pkgUdevCdromDevices()                             /*{{{*/
 { 
 { 
    dlclose(libudev_handle);
    dlclose(libudev_handle);
 }
 }
+									/*}}}*/

+ 8 - 8
apt-pkg/cdrom.h

@@ -8,7 +8,7 @@
 
 
 using namespace std;
 using namespace std;
 
 
-class pkgCdromStatus
+class pkgCdromStatus							/*{{{*/
 {
 {
  protected:
  protected:
    int totalSteps;
    int totalSteps;
@@ -29,8 +29,8 @@ class pkgCdromStatus
    // Progress indicator for the Index rewriter
    // Progress indicator for the Index rewriter
    virtual OpProgress* GetOpProgress() {return NULL; };
    virtual OpProgress* GetOpProgress() {return NULL; };
 };
 };
-
-class pkgCdrom 
+									/*}}}*/
+class pkgCdrom								/*{{{*/
 {
 {
  protected:
  protected:
    enum {
    enum {
@@ -65,17 +65,18 @@ class pkgCdrom
    bool Ident(string &ident, pkgCdromStatus *log);
    bool Ident(string &ident, pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
    bool Add(pkgCdromStatus *log);
 };
 };
+									/*}}}*/
 
 
 
 
 // class that uses libudev to find cdrom devices dynamically
 // class that uses libudev to find cdrom devices dynamically
-struct CdromDevice
+struct CdromDevice							/*{{{*/
 {
 {
    string DeviceName;
    string DeviceName;
    bool Mounted;
    bool Mounted;
    string MountPath;
    string MountPath;
 };
 };
-
-class pkgUdevCdromDevices
+									/*}}}*/
+class pkgUdevCdromDevices						/*{{{*/
 {
 {
  protected:
  protected:
    // libudev dlopen stucture
    // libudev dlopen stucture
@@ -101,7 +102,6 @@ class pkgUdevCdromDevices
    bool Dlopen();
    bool Dlopen();
    vector<CdromDevice> Scan();
    vector<CdromDevice> Scan();
 };
 };
-
-
+									/*}}}*/
 
 
 #endif
 #endif

+ 0 - 1
apt-pkg/clean.cc

@@ -19,7 +19,6 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
 									/*}}}*/
 									/*}}}*/
-
 // ArchiveCleaner::Go - Perform smart cleanup of the archive		/*{{{*/
 // ArchiveCleaner::Go - Perform smart cleanup of the archive		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Scan the directory for files to erase, we check the version information
 /* Scan the directory for files to erase, we check the version information

+ 30 - 21
apt-pkg/contrib/cdromutl.cc

@@ -64,35 +64,44 @@ bool UnmountCdrom(string Path)
 {
 {
    if (IsMounted(Path) == false)
    if (IsMounted(Path) == false)
       return true;
       return true;
-   
-   int Child = ExecFork();
 
 
-   // The child
-   if (Child == 0)
+   for (int i=0;i<3;i++)
    {
    {
-      // Make all the fds /dev/null
-      for (int I = 0; I != 3; I++)
-	 dup2(open("/dev/null",O_RDWR),I);
+   
+      int Child = ExecFork();
 
 
-      if (_config->Exists("Acquire::cdrom::"+Path+"::UMount") == true)
+      // The child
+      if (Child == 0)
       {
       {
-	 if (system(_config->Find("Acquire::cdrom::"+Path+"::UMount").c_str()) != 0)
+	 // Make all the fds /dev/null
+	 for (int I = 0; I != 3; I++)
+	    dup2(open("/dev/null",O_RDWR),I);
+
+	 if (_config->Exists("Acquire::cdrom::"+Path+"::UMount") == true)
+	 {
+	    if (system(_config->Find("Acquire::cdrom::"+Path+"::UMount").c_str()) != 0)
+	       _exit(100);
+	    _exit(0);	 	 
+	 }
+	 else
+	 {
+	    const char *Args[10];
+	    Args[0] = "umount";
+	    Args[1] = Path.c_str();
+	    Args[2] = 0;
+	    execvp(Args[0],(char **)Args);      
 	    _exit(100);
 	    _exit(100);
-	 _exit(0);	 	 
+	 }      
       }
       }
-      else
-      {
-	 const char *Args[10];
-	 Args[0] = "umount";
-	 Args[1] = Path.c_str();
-	 Args[2] = 0;
-	 execvp(Args[0],(char **)Args);      
-	 _exit(100);
-      }      
+
+      // if it can not be umounted, give it a bit more time
+      // this can happen when auto-mount magic or fs/cdrom prober attack
+      if (ExecWait(Child,"umount",true) == true)
+	 return true;
+      sleep(1);
    }
    }
 
 
-   // Wait for mount
-   return ExecWait(Child,"umount",true);
+   return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // MountCdrom - Mount a cdrom						/*{{{*/
 // MountCdrom - Mount a cdrom						/*{{{*/

+ 27 - 5
apt-pkg/contrib/configuration.cc

@@ -182,9 +182,9 @@ string Configuration::FindFile(const char *Name,const char *Default) const
    if (Itm == 0 || Itm->Value.empty() == true)
    if (Itm == 0 || Itm->Value.empty() == true)
    {
    {
       if (Default == 0)
       if (Default == 0)
-	 return "";
+	 return rootDir;
       else
       else
-	 return Default;
+	 return rootDir + Default;
    }
    }
    
    
    string val = Itm->Value;
    string val = Itm->Value;
@@ -223,6 +223,25 @@ string Configuration::FindDir(const char *Name,const char *Default) const
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// Configuration::FindVector - Find a vector of values			/*{{{*/
+// ---------------------------------------------------------------------
+/* Returns a vector of config values under the given item */
+vector<string> Configuration::FindVector(const char *Name) const
+{
+   vector<string> Vec;
+   const Item *Top = Lookup(Name);
+   if (Top == NULL)
+      return Vec;
+
+   Item *I = Top->Child;
+   while(I != NULL)
+   {
+      Vec.push_back(I->Value);
+      I = I->Next;
+   }
+   return Vec;
+}
+									/*}}}*/
 // Configuration::FindI - Find an integer value				/*{{{*/
 // Configuration::FindI - Find an integer value				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -521,6 +540,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
 	  F.getline(Buffer,sizeof(Buffer) / 2);
 	  F.getline(Buffer,sizeof(Buffer) / 2);
 
 
 	  Input += Buffer;
 	  Input += Buffer;
+	  delete[] Buffer;
 	}
 	}
       while (F.fail() && !F.eof());
       while (F.fail() && !F.eof());
 
 
@@ -581,9 +601,11 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
 	    InQuote = !InQuote;
 	    InQuote = !InQuote;
 	 if (InQuote == true)
 	 if (InQuote == true)
 	    continue;
 	    continue;
-	 
-	 if (*I == '/' && I + 1 != End && I[1] == '/')
-         {
+
+	 if ((*I == '/' && I + 1 != End && I[1] == '/') ||
+	     (*I == '#' && strcmp(string(I,I+6).c_str(),"#clear") != 0 &&
+	      strcmp(string(I,I+8).c_str(),"#include") != 0))
+	 {
 	    End = I;
 	    End = I;
 	    break;
 	    break;
 	 }
 	 }

+ 3 - 0
apt-pkg/contrib/configuration.h

@@ -31,6 +31,7 @@
 
 
 
 
 #include <string>
 #include <string>
+#include <vector>
 #include <iostream>
 #include <iostream>
 
 
 using std::string;
 using std::string;
@@ -70,6 +71,8 @@ class Configuration
    string Find(const string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
    string Find(const string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
    string FindFile(const char *Name,const char *Default = 0) const;
    string FindFile(const char *Name,const char *Default = 0) const;
    string FindDir(const char *Name,const char *Default = 0) const;
    string FindDir(const char *Name,const char *Default = 0) const;
+   std::vector<string> FindVector(const string &Name) const;
+   std::vector<string> FindVector(const char *Name) const;
    int FindI(const char *Name,int Default = 0) const;
    int FindI(const char *Name,int Default = 0) const;
    int FindI(const string Name,int Default = 0) const {return FindI(Name.c_str(),Default);};
    int FindI(const string Name,int Default = 0) const {return FindI(Name.c_str(),Default);};
    bool FindB(const char *Name,bool Default = false) const;
    bool FindB(const char *Name,bool Default = false) const;

+ 7 - 6
apt-pkg/contrib/error.cc

@@ -84,17 +84,17 @@ bool GlobalError::Errno(const char *Function,const char *Description,...)
    char S[400];
    char S[400];
    vsnprintf(S,sizeof(S),Description,args);
    vsnprintf(S,sizeof(S),Description,args);
    snprintf(S + strlen(S),sizeof(S) - strlen(S),
    snprintf(S + strlen(S),sizeof(S) - strlen(S),
-	    " - %s (%i %s)",Function,errno,strerror(errno));
+	    " - %s (%i: %s)",Function,errno,strerror(errno));
 
 
    // Put it on the list
    // Put it on the list
    Item *Itm = new Item;
    Item *Itm = new Item;
    Itm->Text = S;
    Itm->Text = S;
    Itm->Error = true;
    Itm->Error = true;
    Insert(Itm);
    Insert(Itm);
-   
+
    PendingFlag = true;
    PendingFlag = true;
 
 
-   return false;   
+   return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // GlobalError::WarningE - Get part of the warn string from errno	/*{{{*/
 // GlobalError::WarningE - Get part of the warn string from errno	/*{{{*/
@@ -112,15 +112,16 @@ bool GlobalError::WarningE(const char *Function,const char *Description,...)
    // sprintf the description
    // sprintf the description
    char S[400];
    char S[400];
    vsnprintf(S,sizeof(S),Description,args);
    vsnprintf(S,sizeof(S),Description,args);
-   snprintf(S + strlen(S),sizeof(S) - strlen(S)," - %s (%i %s)",Function,errno,strerror(errno));
+   snprintf(S + strlen(S),sizeof(S) - strlen(S),
+	    " - %s (%i: %s)",Function,errno,strerror(errno));
 
 
    // Put it on the list
    // Put it on the list
    Item *Itm = new Item;
    Item *Itm = new Item;
    Itm->Text = S;
    Itm->Text = S;
    Itm->Error = false;
    Itm->Error = false;
    Insert(Itm);
    Insert(Itm);
-   
-   return false;   
+
+   return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // GlobalError::Error - Add an error to the list			/*{{{*/
 // GlobalError::Error - Add an error to the list			/*{{{*/

+ 2 - 0
apt-pkg/contrib/fileutl.cc

@@ -451,10 +451,12 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap)
       if (Reap == true)
       if (Reap == true)
 	 return false;
 	 return false;
       if (WIFSIGNALED(Status) != 0)
       if (WIFSIGNALED(Status) != 0)
+      {
 	 if( WTERMSIG(Status) == SIGSEGV)
 	 if( WTERMSIG(Status) == SIGSEGV)
 	    return _error->Error(_("Sub-process %s received a segmentation fault."),Name);
 	    return _error->Error(_("Sub-process %s received a segmentation fault."),Name);
 	 else 
 	 else 
 	    return _error->Error(_("Sub-process %s received signal %u."),Name, WTERMSIG(Status));
 	    return _error->Error(_("Sub-process %s received signal %u."),Name, WTERMSIG(Status));
+      }
 
 
       if (WIFEXITED(Status) != 0)
       if (WIFEXITED(Status) != 0)
 	 return _error->Error(_("Sub-process %s returned an error code (%u)"),Name,WEXITSTATUS(Status));
 	 return _error->Error(_("Sub-process %s returned an error code (%u)"),Name,WEXITSTATUS(Status));

+ 13 - 11
apt-pkg/contrib/hashes.cc

@@ -34,7 +34,7 @@ HashString::HashString(string Type, string Hash) : Type(Type), Hash(Hash)
 {
 {
 }
 }
 
 
-HashString::HashString(string StringedHash)
+HashString::HashString(string StringedHash)				/*{{{*/
 {
 {
    // legacy: md5sum without "MD5Sum:" prefix
    // legacy: md5sum without "MD5Sum:" prefix
    if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
    if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
@@ -50,9 +50,8 @@ HashString::HashString(string StringedHash)
    if(_config->FindB("Debug::Hashes",false) == true)
    if(_config->FindB("Debug::Hashes",false) == true)
       std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
       std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
 }
 }
-
-
-bool HashString::VerifyFile(string filename) const
+									/*}}}*/
+bool HashString::VerifyFile(string filename) const			/*{{{*/
 {
 {
    FileFd fd;
    FileFd fd;
    MD5Summation MD5;
    MD5Summation MD5;
@@ -83,7 +82,7 @@ bool HashString::VerifyFile(string filename) const
 
 
    return (fileHash == Hash);
    return (fileHash == Hash);
 }
 }
-
+									/*}}}*/
 const char** HashString::SupportedHashes()
 const char** HashString::SupportedHashes()
 {
 {
    return _SupportedHashes;
    return _SupportedHashes;
@@ -94,13 +93,11 @@ bool HashString::empty() const
    return (Type.empty() || Hash.empty());
    return (Type.empty() || Hash.empty());
 }
 }
 
 
-
 string HashString::toStr() const
 string HashString::toStr() const
 {
 {
    return Type+string(":")+Hash;
    return Type+string(":")+Hash;
 }
 }
 
 
-
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -108,11 +105,16 @@ bool Hashes::AddFD(int Fd,unsigned long Size)
 {
 {
    unsigned char Buf[64*64];
    unsigned char Buf[64*64];
    int Res = 0;
    int Res = 0;
-   while (Size != 0)
+   int ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
    {
    {
-      Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf)));
-      if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf)))
-	 return false;
+      unsigned n = sizeof(Buf);
+      if (!ToEOF) n = min(Size,(unsigned long)n);
+      Res = read(Fd,Buf,n);
+      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
+         return false;
+      if (ToEOF && Res == 0) // EOF
+         break;
       Size -= Res;
       Size -= Res;
       MD5.Add(Buf,Res);
       MD5.Add(Buf,Res);
       SHA1.Add(Buf,Res);
       SHA1.Add(Buf,Res);

+ 9 - 4
apt-pkg/contrib/md5.cc

@@ -294,11 +294,16 @@ bool MD5Summation::AddFD(int Fd,unsigned long Size)
 {
 {
    unsigned char Buf[64*64];
    unsigned char Buf[64*64];
    int Res = 0;
    int Res = 0;
-   while (Size != 0)
+   int ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
    {
    {
-      Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf)));
-      if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf)))
-	 return false;
+      unsigned n = sizeof(Buf);
+      if (!ToEOF) n = min(Size,(unsigned long)n);
+      Res = read(Fd,Buf,n);
+      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
+         return false;
+      if (ToEOF && Res == 0) // EOF
+         break;
       Size -= Res;
       Size -= Res;
       Add(Buf,Res);
       Add(Buf,Res);
    }
    }

+ 86 - 34
apt-pkg/contrib/mmap.cc

@@ -13,11 +13,6 @@
    libc6 generates warnings -- which should be errors, g++ isn't properly
    libc6 generates warnings -- which should be errors, g++ isn't properly
    strict.
    strict.
    
    
-   The configure test notes that some OS's have broken private mmap's
-   so on those OS's we can't use mmap. This means we have to use
-   configure to test mmap and can't rely on the POSIX
-   _POSIX_MAPPED_FILES test.
-   
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
@@ -31,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <fcntl.h>
+#include <stdlib.h>
 
 
 #include <cstring>
 #include <cstring>
    									/*}}}*/
    									/*}}}*/
@@ -144,7 +140,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
 // DynamicMMap::DynamicMMap - Constructor				/*{{{*/
 // DynamicMMap::DynamicMMap - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : 
+DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
              MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
              MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
 {
 {
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
@@ -166,15 +162,34 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace)
 									/*}}}*/
 									/*}}}*/
 // DynamicMMap::DynamicMMap - Constructor for a non-file backed map	/*{{{*/
 // DynamicMMap::DynamicMMap - Constructor for a non-file backed map	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* This is just a fancy malloc really.. */
+/* We try here to use mmap to reserve some space - this is much more
+   cooler than the fallback solution to simply allocate a char array
+   and could come in handy later than we are able to grow such an mmap */
 DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
 DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
              MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
              MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
 {
 {
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return;
       return;
-   
+
+#ifdef _POSIX_MAPPED_FILES
+   // Set the permissions.
+   int Prot = PROT_READ;
+   int Map = MAP_PRIVATE | MAP_ANONYMOUS;
+   if ((Flags & ReadOnly) != ReadOnly)
+      Prot |= PROT_WRITE;
+   if ((Flags & Public) == Public)
+      Map = MAP_SHARED | MAP_ANONYMOUS;
+
+   // use anonymous mmap() to get the memory
+   Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0);
+
+   if(Base == MAP_FAILED)
+      _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace);
+#else
+   // fallback to a static allocated space
    Base = new unsigned char[WorkSpace];
    Base = new unsigned char[WorkSpace];
    memset(Base,0,WorkSpace);
    memset(Base,0,WorkSpace);
+#endif
    iSize = 0;
    iSize = 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -185,7 +200,11 @@ DynamicMMap::~DynamicMMap()
 {
 {
    if (Fd == 0)
    if (Fd == 0)
    {
    {
+#ifdef _POSIX_MAPPED_FILES
+      munmap(Base, WorkSpace);
+#else
       delete [] (unsigned char *)Base;
       delete [] (unsigned char *)Base;
+#endif
       return;
       return;
    }
    }
    
    
@@ -204,17 +223,19 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
    unsigned long Result = iSize;
    unsigned long Result = iSize;
    if (Aln != 0)
    if (Aln != 0)
       Result += Aln - (iSize%Aln);
       Result += Aln - (iSize%Aln);
-   
+
    iSize = Result + Size;
    iSize = Result + Size;
-   
-   // Just in case error check
-   if (Result + Size > WorkSpace)
+
+   // try to grow the buffer
+   while(Result + Size > WorkSpace)
    {
    {
-	  _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
-				  "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
-      return 0;
+      if(!Grow())
+      {
+	 _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
+			 "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
+	 return 0;
+      }
    }
    }
-
    return Result;
    return Result;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -223,7 +244,7 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
 /* This allocates an Item of size ItemSize so that it is aligned to its
 /* This allocates an Item of size ItemSize so that it is aligned to its
    size in the file. */
    size in the file. */
 unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
-{   
+{
    // Look for a matching pool entry
    // Look for a matching pool entry
    Pool *I;
    Pool *I;
    Pool *Empty = 0;
    Pool *Empty = 0;
@@ -234,7 +255,6 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
       if (I->ItemSize == ItemSize)
       if (I->ItemSize == ItemSize)
 	 break;
 	 break;
    }
    }
-
    // No pool is allocated, use an unallocated one
    // No pool is allocated, use an unallocated one
    if (I == Pools + PoolCount)
    if (I == Pools + PoolCount)
    {
    {
@@ -249,17 +269,24 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
       I->ItemSize = ItemSize;
       I->ItemSize = ItemSize;
       I->Count = 0;
       I->Count = 0;
    }
    }
-   
+
+   unsigned long Result = 0;
    // Out of space, allocate some more
    // Out of space, allocate some more
    if (I->Count == 0)
    if (I->Count == 0)
    {
    {
-      I->Count = 20*1024/ItemSize;
-      I->Start = RawAllocate(I->Count*ItemSize,ItemSize);
-   }   
+      const unsigned long size = 20*1024;
+      I->Count = size/ItemSize;
+      Result = RawAllocate(size,ItemSize);
+      // Does the allocation failed ?
+      if (Result == 0 && _error->PendingError())
+	 return 0;
+      I->Start = Result;
+   }
+   else
+      Result = I->Start;
 
 
    I->Count--;
    I->Count--;
-   unsigned long Result = I->Start;
-   I->Start += ItemSize;  
+   I->Start += ItemSize;
    return Result/ItemSize;
    return Result/ItemSize;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -269,20 +296,45 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 unsigned long DynamicMMap::WriteString(const char *String,
 unsigned long DynamicMMap::WriteString(const char *String,
 				       unsigned long Len)
 				       unsigned long Len)
 {
 {
-   unsigned long Result = iSize;
-   // Just in case error check
-   if (Result + Len > WorkSpace)
-   {
-	  _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
-				  "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
-      return 0;
-   }   
-   
    if (Len == (unsigned long)-1)
    if (Len == (unsigned long)-1)
       Len = strlen(String);
       Len = strlen(String);
-   iSize += Len + 1;
+
+   unsigned long Result = RawAllocate(Len+1,0);
+
+   if (Result == 0 && _error->PendingError())
+      return 0;
+
    memcpy((char *)Base + Result,String,Len);
    memcpy((char *)Base + Result,String,Len);
    ((char *)Base)[Result + Len] = 0;
    ((char *)Base)[Result + Len] = 0;
    return Result;
    return Result;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// DynamicMMap::Grow - Grow the mmap					/*{{{*/
+// ---------------------------------------------------------------------
+/* This method will try to grow the mmap we currently use. This doesn't
+   work most of the time because we can't move the mmap around in the
+   memory for now as this would require to adjust quite a lot of pointers
+   but why we should not at least try to grow it before we give up? */
+bool DynamicMMap::Grow()
+{
+#if defined(_POSIX_MAPPED_FILES) && defined(__linux__)
+   unsigned long newSize = WorkSpace + 1024*1024;
+
+   if(Fd != 0)
+   {
+      Fd->Seek(newSize - 1);
+      char C = 0;
+      Fd->Write(&C,sizeof(C));
+   }
+
+   Base = mremap(Base, WorkSpace, newSize, 0);
+   if(Base == MAP_FAILED)
+      return false;
+
+   WorkSpace = newSize;
+   return true;
+#else
+   return false;
+#endif
+}
+									/*}}}*/

+ 2 - 0
apt-pkg/contrib/mmap.h

@@ -84,6 +84,8 @@ class DynamicMMap : public MMap
    unsigned long WorkSpace;
    unsigned long WorkSpace;
    Pool *Pools;
    Pool *Pools;
    unsigned int PoolCount;
    unsigned int PoolCount;
+
+   bool Grow();
    
    
    public:
    public:
 
 

+ 211 - 0
apt-pkg/contrib/netrc.cc

@@ -0,0 +1,211 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: netrc.c,v 1.38 2007-11-07 09:21:35 bagder Exp $
+/* ######################################################################
+
+   netrc file parser - returns the login and password of a give host in
+                       a specified netrc-type file
+
+   Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+   placed into the Public Domain, do with it what you will.
+
+   ##################################################################### */
+									/*}}}*/
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/fileutl.h>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "netrc.h"
+
+
+/* Get user and password from .netrc when given a machine name */
+
+enum {
+  NOTHING,
+  HOSTFOUND,    /* the 'machine' keyword was found */
+  HOSTCOMPLETE, /* the machine name following the keyword was found too */
+  HOSTVALID,    /* this is "our" machine! */
+  HOSTEND /* LAST enum */
+};
+
+/* make sure we have room for at least this size: */
+#define LOGINSIZE 64
+#define PASSWORDSIZE 64
+#define NETRC DOT_CHAR "netrc"
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
+{
+  FILE *file;
+  int retcode = 1;
+  int specific_login = (login[0] != 0);
+  char *home = NULL;
+  bool netrc_alloc = false;
+  int state = NOTHING;
+
+  char state_login = 0;        /* Found a login keyword */
+  char state_password = 0;     /* Found a password keyword */
+  int state_our_login = false;  /* With specific_login,
+                                   found *our* login name */
+
+  if (!netrcfile) {
+    home = getenv ("HOME"); /* portable environment reader */
+
+    if (!home) {
+      struct passwd *pw;
+      pw = getpwuid (geteuid ());
+      if(pw)
+        home = pw->pw_dir;
+    }
+
+    if (!home)
+      return -1;
+
+    asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
+    if(!netrcfile)
+      return -1;
+    else
+      netrc_alloc = true;
+  }
+
+  file = fopen (netrcfile, "r");
+  if(file) {
+    char *tok;
+    char *tok_buf;
+    bool done = false;
+    char netrcbuffer[256];
+
+    while (!done && fgets(netrcbuffer, sizeof (netrcbuffer), file)) {
+      tok = strtok_r (netrcbuffer, " \t\n", &tok_buf);
+      while (!done && tok) {
+        if(login[0] && password[0]) {
+          done = true;
+          break;
+        }
+
+        switch(state) {
+        case NOTHING:
+          if (!strcasecmp ("machine", tok)) {
+            /* the next tok is the machine name, this is in itself the
+               delimiter that starts the stuff entered for this machine,
+               after this we need to search for 'login' and
+               'password'. */
+            state = HOSTFOUND;
+          }
+          break;
+        case HOSTFOUND:
+	   /* extended definition of a "machine" if we have a "/"
+	      we match the start of the string (host.startswith(token) */
+	  if ((strchr(host, '/') && strstr(host, tok) == host) ||
+	      (!strcasecmp (host, tok))) {
+            /* and yes, this is our host! */
+            state = HOSTVALID;
+            retcode = 0; /* we did find our host */
+          }
+          else
+            /* not our host */
+            state = NOTHING;
+          break;
+        case HOSTVALID:
+          /* we are now parsing sub-keywords concerning "our" host */
+          if (state_login) {
+            if (specific_login)
+              state_our_login = !strcasecmp (login, tok);
+            else
+              strncpy (login, tok, LOGINSIZE - 1);
+            state_login = 0;
+          } else if (state_password) {
+            if (state_our_login || !specific_login)
+              strncpy (password, tok, PASSWORDSIZE - 1);
+            state_password = 0;
+          } else if (!strcasecmp ("login", tok))
+            state_login = 1;
+          else if (!strcasecmp ("password", tok))
+            state_password = 1;
+          else if(!strcasecmp ("machine", tok)) {
+            /* ok, there's machine here go => */
+            state = HOSTFOUND;
+            state_our_login = false;
+          }
+          break;
+        } /* switch (state) */
+
+        tok = strtok_r (NULL, " \t\n", &tok_buf);
+      } /* while(tok) */
+    } /* while fgets() */
+
+    fclose(file);
+  }
+
+  if (netrc_alloc)
+    free(netrcfile);
+
+  return retcode;
+}
+
+void maybe_add_auth (URI &Uri, string NetRCFile)
+{
+  if (_config->FindB("Debug::Acquire::netrc", false) == true)
+     std::clog << "maybe_add_auth: " << (string)Uri 
+	       << " " << NetRCFile << std::endl;
+  if (Uri.Password.empty () == true || Uri.User.empty () == true)
+  {
+    if (NetRCFile.empty () == false)
+    {
+      char login[64] = "";
+      char password[64] = "";
+      char *netrcfile = strdupa (NetRCFile.c_str ());
+
+      // first check for a generic host based netrc entry
+      char *host = strdupa (Uri.Host.c_str ());
+      if (host && parsenetrc (host, login, password, netrcfile) == 0)
+      {
+	 if (_config->FindB("Debug::Acquire::netrc", false) == true)
+	    std::clog << "host: " << host 
+		      << " user: " << login
+		      << " pass-size: " << strlen(password)
+		      << std::endl;
+        Uri.User = string (login);
+        Uri.Password = string (password);
+	return;
+      }
+
+      // if host did not work, try Host+Path next, this will trigger
+      // a lookup uri.startswith(host) in the netrc file parser (because
+      // of the "/"
+      char *hostpath = strdupa (string(Uri.Host+Uri.Path).c_str ());
+      if (hostpath && parsenetrc (hostpath, login, password, netrcfile) == 0)
+      {
+	 if (_config->FindB("Debug::Acquire::netrc", false) == true)
+	    std::clog << "hostpath: " << hostpath
+		      << " user: " << login
+		      << " pass-size: " << strlen(password)
+		      << std::endl;
+	 Uri.User = string (login);
+	 Uri.Password = string (password);
+	 return;
+      }
+    }
+  }
+}
+
+#ifdef DEBUG
+int main(int argc, char* argv[])
+{
+  char login[64] = "";
+  char password[64] = "";
+
+  if(argc < 2)
+    return -1;
+
+  if(0 == parsenetrc (argv[1], login, password, argv[2])) {
+    printf("HOST: %s LOGIN: %s PASSWORD: %s\n", argv[1], login, password);
+  }
+}
+#endif

+ 29 - 0
apt-pkg/contrib/netrc.h

@@ -0,0 +1,29 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+// $Id: netrc.h,v 1.11 2004/01/07 09:19:35 bagder Exp $
+/* ######################################################################
+
+   netrc file parser - returns the login and password of a give host in
+                       a specified netrc-type file
+
+   Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+   placed into the Public Domain, do with it what you will.
+
+   ##################################################################### */
+									/*}}}*/
+#ifndef NETRC_H
+#define NETRC_H
+
+#include <apt-pkg/strutl.h>
+
+#define DOT_CHAR "."
+#define DIR_CHAR "/"
+
+// Assume: password[0]=0, host[0] != 0.
+// If login[0] = 0, search for login and password within a machine section
+// in the netrc.
+// If login[0] != 0, search for password within machine and login.
+int parsenetrc (char *host, char *login, char *password, char *filename);
+
+void maybe_add_auth (URI &Uri, string NetRCFile);
+#endif

+ 13 - 19
apt-pkg/contrib/sha256.cc

@@ -1,5 +1,5 @@
 /*
 /*
- * Cryptographic API.
+ * Cryptographic API.							{{{
  *
  *
  * SHA-256, as specified in
  * SHA-256, as specified in
  * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
  * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
@@ -17,7 +17,7 @@
  * Software Foundation; either version 2 of the License, or (at your option) 
  * Software Foundation; either version 2 of the License, or (at your option) 
  * any later version.
  * any later version.
  *
  *
- */
+ */									/*}}}*/
 
 
 #ifdef __GNUG__
 #ifdef __GNUG__
 #pragma implementation "apt-pkg/sha256.h"
 #pragma implementation "apt-pkg/sha256.h"
@@ -65,20 +65,20 @@ static inline u32 Maj(u32 x, u32 y, u32 z)
 #define H6         0x1f83d9ab
 #define H6         0x1f83d9ab
 #define H7         0x5be0cd19
 #define H7         0x5be0cd19
 
 
-static inline void LOAD_OP(int I, u32 *W, const u8 *input)
+static inline void LOAD_OP(int I, u32 *W, const u8 *input)		/*{{{*/
 {
 {
 	W[I] = (  ((u32) input[I * 4 + 0] << 24)
 	W[I] = (  ((u32) input[I * 4 + 0] << 24)
 		| ((u32) input[I * 4 + 1] << 16)
 		| ((u32) input[I * 4 + 1] << 16)
 		| ((u32) input[I * 4 + 2] << 8)
 		| ((u32) input[I * 4 + 2] << 8)
 		| ((u32) input[I * 4 + 3]));
 		| ((u32) input[I * 4 + 3]));
 }
 }
-
+									/*}}}*/
 static inline void BLEND_OP(int I, u32 *W)
 static inline void BLEND_OP(int I, u32 *W)
 {
 {
         W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
         W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
 }
 }
 
 
-static void sha256_transform(u32 *state, const u8 *input)
+static void sha256_transform(u32 *state, const u8 *input)		/*{{{*/
 {
 {
         u32 a, b, c, d, e, f, g, h, t1, t2;
         u32 a, b, c, d, e, f, g, h, t1, t2;
         u32 W[64];
         u32 W[64];
@@ -240,8 +240,8 @@ static void sha256_transform(u32 *state, const u8 *input)
         a = b = c = d = e = f = g = h = t1 = t2 = 0;
         a = b = c = d = e = f = g = h = t1 = t2 = 0;
         memset(W, 0, 64 * sizeof(u32));
         memset(W, 0, 64 * sizeof(u32));
 }
 }
-
-SHA256Summation::SHA256Summation()
+									/*}}}*/
+SHA256Summation::SHA256Summation()					/*{{{*/
 {
 {
         Sum.state[0] = H0;
         Sum.state[0] = H0;
         Sum.state[1] = H1;
         Sum.state[1] = H1;
@@ -255,8 +255,8 @@ SHA256Summation::SHA256Summation()
         memset(Sum.buf, 0, sizeof(Sum.buf));
         memset(Sum.buf, 0, sizeof(Sum.buf));
         Done = false;
         Done = false;
 }
 }
-
-bool SHA256Summation::Add(const u8 *data, unsigned long len)
+									/*}}}*/
+bool SHA256Summation::Add(const u8 *data, unsigned long len)		/*{{{*/
 {
 {
         struct sha256_ctx *sctx = &Sum;
         struct sha256_ctx *sctx = &Sum;
         unsigned int i, index, part_len;
         unsigned int i, index, part_len;
@@ -291,8 +291,8 @@ bool SHA256Summation::Add(const u8 *data, unsigned long len)
 
 
         return true;
         return true;
 }
 }
-
-SHA256SumValue SHA256Summation::Result()
+									/*}}}*/
+SHA256SumValue SHA256Summation::Result()				/*{{{*/
 {
 {
    struct sha256_ctx *sctx = &Sum;
    struct sha256_ctx *sctx = &Sum;
    if (!Done) {
    if (!Done) {
@@ -340,7 +340,7 @@ SHA256SumValue SHA256Summation::Result()
 
 
    return res;
    return res;
 }
 }
-
+									/*}}}*/
 // SHA256SumValue::SHA256SumValue - Constructs the sum from a string   /*{{{*/
 // SHA256SumValue::SHA256SumValue - Constructs the sum from a string   /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The string form of a SHA256 is a 64 character hex number */
 /* The string form of a SHA256 is a 64 character hex number */
@@ -349,7 +349,6 @@ SHA256SumValue::SHA256SumValue(string Str)
    memset(Sum,0,sizeof(Sum));
    memset(Sum,0,sizeof(Sum));
    Set(Str);
    Set(Str);
 }
 }
-
                                                                        /*}}}*/
                                                                        /*}}}*/
 // SHA256SumValue::SHA256SumValue - Default constructor                /*{{{*/
 // SHA256SumValue::SHA256SumValue - Default constructor                /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -358,7 +357,6 @@ SHA256SumValue::SHA256SumValue()
 {
 {
    memset(Sum,0,sizeof(Sum));
    memset(Sum,0,sizeof(Sum));
 }
 }
-
                                                                        /*}}}*/
                                                                        /*}}}*/
 // SHA256SumValue::Set - Set the sum from a string                     /*{{{*/
 // SHA256SumValue::Set - Set the sum from a string                     /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -391,9 +389,7 @@ string SHA256SumValue::Value() const
 
 
    return string(Result);
    return string(Result);
 }
 }
-
-
-
+									/*}}}*/
 // SHA256SumValue::operator == - Comparator                            /*{{{*/
 // SHA256SumValue::operator == - Comparator                            /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Call memcmp on the buffer */
 /* Call memcmp on the buffer */
@@ -402,8 +398,6 @@ bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const
    return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
    return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
 }
 }
                                                                        /*}}}*/
                                                                        /*}}}*/
-
-
 // SHA256Summation::AddFD - Add content of file into the checksum      /*{{{*/
 // SHA256Summation::AddFD - Add content of file into the checksum      /*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 26 - 4
apt-pkg/contrib/strutl.cc

@@ -67,9 +67,20 @@ bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest)
   outbuf = new char[insize+1];
   outbuf = new char[insize+1];
   outptr = outbuf;
   outptr = outbuf;
 
 
-  iconv(cd, &inptr, &insize, &outptr, &outsize);
-  *outptr = '\0';
+  while (insize != 0)
+  {
+     size_t const err = iconv(cd, &inptr, &insize, &outptr, &outsize);
+     if (err == (size_t)(-1))
+     {
+	insize--;
+	outsize++;
+	inptr++;
+	*outptr = '?';
+	outptr++;
+     }
+  }
 
 
+  *outptr = '\0';
   *dest = outbuf;
   *dest = outbuf;
   delete[] outbuf;
   delete[] outbuf;
   
   
@@ -304,13 +315,13 @@ string SizeToStr(double Size)
    {
    {
       if (ASize < 100 && I != 0)
       if (ASize < 100 && I != 0)
       {
       {
-         sprintf(S,"%.1f%c",ASize,Ext[I]);
+         sprintf(S,"%'.1f%c",ASize,Ext[I]);
 	 break;
 	 break;
       }
       }
       
       
       if (ASize < 10000)
       if (ASize < 10000)
       {
       {
-         sprintf(S,"%.0f%c",ASize,Ext[I]);
+         sprintf(S,"%'.0f%c",ASize,Ext[I]);
 	 break;
 	 break;
       }
       }
       ASize /= 1000.0;
       ASize /= 1000.0;
@@ -387,6 +398,17 @@ string SubstVar(string Str,const struct SubstVar *Vars)
    return Str;
    return Str;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// OutputInDepth - return a string with separator multiplied with depth /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns a string with the supplied separator depth + 1 times in it */
+std::string OutputInDepth(const unsigned long Depth, const char* Separator)
+{
+   std::string output = "";
+   for(unsigned long d=Depth+1; d > 0; d--)
+      output.append(Separator);
+   return output;
+}
+									/*}}}*/
 // URItoFileName - Convert the uri into a unique file name		/*{{{*/
 // URItoFileName - Convert the uri into a unique file name		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This converts a URI into a safe filename. It quotes all unsafe characters
 /* This converts a URI into a safe filename. It quotes all unsafe characters

+ 8 - 6
apt-pkg/contrib/strutl.h

@@ -48,6 +48,7 @@ string DeQuoteString(const string &Str);
 string SizeToStr(double Bytes);
 string SizeToStr(double Bytes);
 string TimeToStr(unsigned long Sec);
 string TimeToStr(unsigned long Sec);
 string Base64Encode(const string &Str);
 string Base64Encode(const string &Str);
+string OutputInDepth(const unsigned long Depth, const char* Separator="  ");
 string URItoFileName(const string &URI);
 string URItoFileName(const string &URI);
 string TimeRFC1123(time_t Date);
 string TimeRFC1123(time_t Date);
 bool StrToTime(const string &Val,time_t &Result);
 bool StrToTime(const string &Val,time_t &Result);
@@ -65,16 +66,17 @@ bool CheckDomainList(const string &Host, const string &List);
 int tolower_ascii(int c);
 int tolower_ascii(int c);
 
 
 #define APT_MKSTRCMP(name,func) \
 #define APT_MKSTRCMP(name,func) \
+inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(string A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
-inline int name(string A,string B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
-inline int name(string A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);}; 
+inline int name(const string& A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
+inline int name(const string& A,const string& B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
+inline int name(const string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);};
 
 
 #define APT_MKSTRCMP2(name,func) \
 #define APT_MKSTRCMP2(name,func) \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
 inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(string A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
-inline int name(string A,string B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
-inline int name(string A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);}; 
+inline int name(const string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
+inline int name(const string& A,const string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
+inline int name(const string& A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);};
 
 
 int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
 int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);

+ 4 - 0
apt-pkg/deb/deblistparser.cc

@@ -109,6 +109,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
       return false;
       return false;
    if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
    if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
       return false;
       return false;
+   if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
+      return false;
 
 
    // Obsolete.
    // Obsolete.
    if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
    if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
@@ -637,6 +639,8 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
       FileI->Version = WriteUniqString(Start,Stop - Start);
       FileI->Version = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Origin",Start,Stop) == true)
    if (Section.Find("Origin",Start,Stop) == true)
       FileI->Origin = WriteUniqString(Start,Stop - Start);
       FileI->Origin = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Codename",Start,Stop) == true)
+      FileI->Codename = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Label",Start,Stop) == true)
    if (Section.Find("Label",Start,Stop) == true)
       FileI->Label = WriteUniqString(Start,Stop - Start);
       FileI->Label = WriteUniqString(Start,Stop - Start);
    if (Section.Find("Architecture",Start,Stop) == true)
    if (Section.Find("Architecture",Start,Stop) == true)

+ 7 - 0
apt-pkg/deb/debmetaindex.cc

@@ -115,6 +115,13 @@ debReleaseIndex::debReleaseIndex(string URI,string Dist)
    this->Type = "deb";
    this->Type = "deb";
 }
 }
 
 
+debReleaseIndex::~debReleaseIndex()
+{
+   for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin();
+	I != SectionEntries.end(); I++)
+      delete *I;
+}
+
 vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
 vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
 {
 {
    vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
    vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;

+ 1 - 0
apt-pkg/deb/debmetaindex.h

@@ -22,6 +22,7 @@ class debReleaseIndex : public metaIndex {
    public:
    public:
 
 
    debReleaseIndex(string URI, string Dist);
    debReleaseIndex(string URI, string Dist);
+   ~debReleaseIndex();
 
 
    virtual string ArchiveURI(string File) const {return URI + File;};
    virtual string ArchiveURI(string File) const {return URI + File;};
    virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const;
    virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const;

+ 15 - 1
apt-pkg/deb/debsrcrecords.cc

@@ -135,9 +135,15 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
 	 string::size_type Tmp = F.Path.rfind('.',Pos);
 	 string::size_type Tmp = F.Path.rfind('.',Pos);
 	 if (Tmp == string::npos)
 	 if (Tmp == string::npos)
 	    break;
 	    break;
+	 if (F.Type == "tar") {
+	    // source v3 has extension 'debian.tar.*' instead of 'diff.*'
+	    if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
+	       F.Type = "diff";
+	    break;
+	 }
 	 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 	 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 	 
 	 
-	 if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma")
+	 if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar")
 	 {
 	 {
 	    Pos = Tmp-1;
 	    Pos = Tmp-1;
 	    continue;
 	    continue;
@@ -152,3 +158,11 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// SrcRecordParser::~SrcRecordParser - Destructor			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+debSrcRecordParser::~debSrcRecordParser()
+{
+   delete[] Buffer;
+}
+									/*}}}*/

+ 1 - 0
apt-pkg/deb/debsrcrecords.h

@@ -50,6 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
    debSrcRecordParser(string File,pkgIndexFile const *Index) 
    debSrcRecordParser(string File,pkgIndexFile const *Index) 
       : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), 
       : Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400), 
         Buffer(0), BufSize(0) {}
         Buffer(0), BufSize(0) {}
+   ~debSrcRecordParser();
 };
 };
 
 
 #endif
 #endif

+ 2 - 2
apt-pkg/deb/debsystem.cc

@@ -17,8 +17,8 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
-#include <apti18n.h>    
-
+#include <apti18n.h>
+    
 #include <sys/types.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <dirent.h>

+ 220 - 88
apt-pkg/deb/dpkgpm.cc

@@ -49,6 +49,7 @@ namespace
     std::make_pair("install",   N_("Installing %s")),
     std::make_pair("install",   N_("Installing %s")),
     std::make_pair("configure", N_("Configuring %s")),
     std::make_pair("configure", N_("Configuring %s")),
     std::make_pair("remove",    N_("Removing %s")),
     std::make_pair("remove",    N_("Removing %s")),
+    std::make_pair("purge",    N_("Completely removing %s")),
     std::make_pair("trigproc",  N_("Running post-installation trigger %s"))
     std::make_pair("trigproc",  N_("Running post-installation trigger %s"))
   };
   };
 
 
@@ -134,8 +135,14 @@ bool pkgDPkgPM::Configure(PkgIterator Pkg)
 {
 {
    if (Pkg.end() == true)
    if (Pkg.end() == true)
       return false;
       return false;
-   
-   List.push_back(Item(Item::Configure,Pkg));
+
+   List.push_back(Item(Item::Configure, Pkg));
+
+   // Use triggers for config calls if we configure "smart"
+   // as otherwise Pre-Depends will not be satisfied, see #526774
+   if (_config->FindB("DPkg::TriggersPending", false) == true)
+      List.push_back(Item(Item::TriggersPending, PkgIterator()));
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -190,6 +197,9 @@ bool pkgDPkgPM::SendV2Pkgs(FILE *F)
    // Write out the package actions in order.
    // Write out the package actions in order.
    for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
    for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
    {
    {
+      if(I->Pkg.end() == true)
+	 continue;
+
       pkgDepCache::StateCache &S = Cache[I->Pkg];
       pkgDepCache::StateCache &S = Cache[I->Pkg];
       
       
       fprintf(F,"%s ",I->Pkg.Name());
       fprintf(F,"%s ",I->Pkg.Name());
@@ -378,10 +388,11 @@ void pkgDPkgPM::DoTerminalPty(int master)
  */
  */
 void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 {
 {
+   bool const Debug = _config->FindB("Debug::pkgDPkgProgressReporting",false);
    // the status we output
    // the status we output
    ostringstream status;
    ostringstream status;
 
 
-   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+   if (Debug == true)
       std::clog << "got from dpkg '" << line << "'" << std::endl;
       std::clog << "got from dpkg '" << line << "'" << std::endl;
 
 
 
 
@@ -396,6 +407,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
       'processing: install: pkg'
       'processing: install: pkg'
       'processing: configure: pkg'
       'processing: configure: pkg'
       'processing: remove: pkg'
       'processing: remove: pkg'
+      'processing: purge: pkg' - but for apt is it a ignored "unknown" action
       'processing: trigproc: trigger'
       'processing: trigproc: trigger'
 	    
 	    
    */
    */
@@ -408,28 +420,28 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
    TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
    TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
    if( list[0] == NULL || list[1] == NULL || list[2] == NULL) 
    if( list[0] == NULL || list[1] == NULL || list[2] == NULL) 
    {
    {
-      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      if (Debug == true)
 	 std::clog << "ignoring line: not enough ':'" << std::endl;
 	 std::clog << "ignoring line: not enough ':'" << std::endl;
       return;
       return;
    }
    }
-   char *pkg = list[1];
-   char *action = _strstrip(list[2]);
+   const char* const pkg = list[1];
+   const char* action = _strstrip(list[2]);
 
 
    // 'processing' from dpkg looks like
    // 'processing' from dpkg looks like
    // 'processing: action: pkg'
    // 'processing: action: pkg'
    if(strncmp(list[0], "processing", strlen("processing")) == 0)
    if(strncmp(list[0], "processing", strlen("processing")) == 0)
    {
    {
       char s[200];
       char s[200];
-      char *pkg_or_trigger = _strstrip(list[2]);
-      action =_strstrip( list[1]);
+      const char* const pkg_or_trigger = _strstrip(list[2]);
+      action = _strstrip( list[1]);
       const std::pair<const char *, const char *> * const iter =
       const std::pair<const char *, const char *> * const iter =
 	std::find_if(PackageProcessingOpsBegin,
 	std::find_if(PackageProcessingOpsBegin,
 		     PackageProcessingOpsEnd,
 		     PackageProcessingOpsEnd,
 		     MatchProcessingOp(action));
 		     MatchProcessingOp(action));
       if(iter == PackageProcessingOpsEnd)
       if(iter == PackageProcessingOpsEnd)
       {
       {
-	 if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
-	    std::clog << "ignoring unknwon action: " << action << std::endl;
+	 if (Debug == true)
+	    std::clog << "ignoring unknown action: " << action << std::endl;
 	 return;
 	 return;
       }
       }
       snprintf(s, sizeof(s), _(iter->second), pkg_or_trigger);
       snprintf(s, sizeof(s), _(iter->second), pkg_or_trigger);
@@ -440,7 +452,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
-      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
       return;
       return;
    }
    }
@@ -453,11 +465,11 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
-      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
       return;
       return;
    }
    }
-   if(strncmp(action,"conffile",strlen("conffile")) == 0)
+   else if(strncmp(action,"conffile",strlen("conffile")) == 0)
    {
    {
       status << "pmconffile:" << list[1]
       status << "pmconffile:" << list[1]
 	     << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
 	     << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
@@ -465,12 +477,12 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
-      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
       return;
       return;
    }
    }
 
 
-   vector<struct DpkgState> &states = PackageOps[pkg];
+   vector<struct DpkgState> const &states = PackageOps[pkg];
    const char *next_action = NULL;
    const char *next_action = NULL;
    if(PackageOpsDone[pkg] < states.size())
    if(PackageOpsDone[pkg] < states.size())
       next_action = states[PackageOpsDone[pkg]].state;
       next_action = states[PackageOpsDone[pkg]].state;
@@ -493,15 +505,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	     << endl;
 	     << endl;
       if(OutStatusFd > 0)
       if(OutStatusFd > 0)
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
 	 write(OutStatusFd, status.str().c_str(), status.str().size());
-      if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+      if (Debug == true)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 	 std::clog << "send: '" << status.str() << "'" << endl;
    }
    }
-   if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true) 
+   if (Debug == true) 
       std::clog << "(parsed from dpkg) pkg: " << pkg 
       std::clog << "(parsed from dpkg) pkg: " << pkg 
 		<< " action: " << action << endl;
 		<< " action: " << action << endl;
 }
 }
-
-// DPkgPM::DoDpkgStatusFd                                           	/*{{{*/
+									/*}}}*/
+// DPkgPM::DoDpkgStatusFd						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /*
 /*
  */
  */
@@ -538,47 +550,106 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
    dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
    dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
+// DPkgPM::WriteHistoryTag						/*{{{*/
+void pkgDPkgPM::WriteHistoryTag(string tag, string value)
+{
+   if (value.size() > 0)
+   {
+      // poor mans rstrip(", ")
+      if (value[value.size()-2] == ',' && value[value.size()-1] == ' ')
+	 value.erase(value.size() - 2, 2);
+      fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
+   }
+}									/*}}}*/
+// DPkgPM::OpenLog							/*{{{*/
 bool pkgDPkgPM::OpenLog()
 bool pkgDPkgPM::OpenLog()
 {
 {
    string logdir = _config->FindDir("Dir::Log");
    string logdir = _config->FindDir("Dir::Log");
    if(not FileExists(logdir))
    if(not FileExists(logdir))
       return _error->Error(_("Directory '%s' missing"), logdir.c_str());
       return _error->Error(_("Directory '%s' missing"), logdir.c_str());
+
+   // get current time
+   char timestr[200];
+   time_t t = time(NULL);
+   struct tm *tmp = localtime(&t);
+   strftime(timestr, sizeof(timestr), "%F  %T", tmp);
+
+   // open terminal log
    string logfile_name = flCombine(logdir,
    string logfile_name = flCombine(logdir,
 				   _config->Find("Dir::Log::Terminal"));
 				   _config->Find("Dir::Log::Terminal"));
    if (!logfile_name.empty())
    if (!logfile_name.empty())
    {
    {
       term_out = fopen(logfile_name.c_str(),"a");
       term_out = fopen(logfile_name.c_str(),"a");
       chmod(logfile_name.c_str(), 0600);
       chmod(logfile_name.c_str(), 0600);
-      // output current time
-      char outstr[200];
-      time_t t = time(NULL);
-      struct tm *tmp = localtime(&t);
-      strftime(outstr, sizeof(outstr), "%F  %T", tmp);
-      fprintf(term_out, "\nLog started: ");
-      fprintf(term_out, "%s", outstr);
+      fprintf(term_out, "\n\nLog started: ");
+      fprintf(term_out, "%s", timestr);
       fprintf(term_out, "\n");
       fprintf(term_out, "\n");
    }
    }
+
+   // write 
+   string history_name = flCombine(logdir,
+				   _config->Find("Dir::Log::History"));
+   if (!history_name.empty())
+   {
+      history_out = fopen(history_name.c_str(),"a");
+      chmod(history_name.c_str(), 0644);
+      fprintf(history_out, "\nStart-Date: %s\n", timestr);
+      string remove, purge, install, upgrade, downgrade;
+      for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+      {
+	 if (Cache[I].NewInstall())
+	    install += I.Name() + string(" (") + Cache[I].CandVersion + string("), ");
+	 else if (Cache[I].Upgrade())
+	    upgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+	 else if (Cache[I].Downgrade())
+	    downgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+	 else if (Cache[I].Delete())
+	 {
+	    if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+	       purge += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");	    
+	    else
+	       remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");	    
+	 }
+      }
+      WriteHistoryTag("Install", install);
+      WriteHistoryTag("Upgrade", upgrade);
+      WriteHistoryTag("Downgrade",downgrade);
+      WriteHistoryTag("Remove",remove);
+      WriteHistoryTag("Purge",purge);
+      fflush(history_out);
+   }
+   
    return true;
    return true;
 }
 }
-
+									/*}}}*/
+// DPkg::CloseLog							/*{{{*/
 bool pkgDPkgPM::CloseLog()
 bool pkgDPkgPM::CloseLog()
 {
 {
+   char timestr[200];
+   time_t t = time(NULL);
+   struct tm *tmp = localtime(&t);
+   strftime(timestr, sizeof(timestr), "%F  %T", tmp);
+
    if(term_out)
    if(term_out)
    {
    {
-      char outstr[200];
-      time_t t = time(NULL);
-      struct tm *tmp = localtime(&t);
-      strftime(outstr, sizeof(outstr), "%F  %T", tmp);
       fprintf(term_out, "Log ended: ");
       fprintf(term_out, "Log ended: ");
-      fprintf(term_out, "%s", outstr);
+      fprintf(term_out, "%s", timestr);
       fprintf(term_out, "\n");
       fprintf(term_out, "\n");
       fclose(term_out);
       fclose(term_out);
    }
    }
    term_out = NULL;
    term_out = NULL;
+
+   if(history_out)
+   {
+      if (dpkg_error.size() > 0)
+	 fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
+      fprintf(history_out, "End-Date: %s\n", timestr);
+      fclose(history_out);
+   }
+
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 /*{{{*/
 /*{{{*/
 // This implements a racy version of pselect for those architectures
 // This implements a racy version of pselect for those architectures
 // that don't have a working implementation.
 // that don't have a working implementation.
@@ -600,7 +671,6 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
    return retval;
    return retval;
 }
 }
 /*}}}*/
 /*}}}*/
-
 // DPkgPM::Go - Run the sequence					/*{{{*/
 // DPkgPM::Go - Run the sequence					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This globs the operations and calls dpkg 
 /* This globs the operations and calls dpkg 
@@ -617,9 +687,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    sigset_t sigmask;
    sigset_t sigmask;
    sigset_t original_sigmask;
    sigset_t original_sigmask;
 
 
-   unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024);   
-   unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024);
-   bool NoTriggers = _config->FindB("DPkg::NoTriggers",false);
+   unsigned int const MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024);
+   unsigned int const MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024);
+   bool const NoTriggers = _config->FindB("DPkg::NoTriggers", false);
 
 
    if (RunScripts("DPkg::Pre-Invoke") == false)
    if (RunScripts("DPkg::Pre-Invoke") == false)
       return false;
       return false;
@@ -627,6 +697,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
    if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
       return false;
       return false;
 
 
+   // support subpressing of triggers processing for special
+   // cases like d-i that runs the triggers handling manually
+   bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all");
+   bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
+   if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true)
+      List.push_back(Item(Item::ConfigurePending, PkgIterator()));
+
    // map the dpkg states to the operations that are performed
    // map the dpkg states to the operations that are performed
    // (this is sorted in the same way as Item::Ops)
    // (this is sorted in the same way as Item::Ops)
    static const struct DpkgState DpkgStatesOpMap[][7] = {
    static const struct DpkgState DpkgStatesOpMap[][7] = {
@@ -640,20 +717,12 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       { 
       { 
 	 {"unpacked",N_("Preparing to configure %s") },
 	 {"unpacked",N_("Preparing to configure %s") },
 	 {"half-configured", N_("Configuring %s") },
 	 {"half-configured", N_("Configuring %s") },
-#if 0
-	 {"triggers-awaited", N_("Processing triggers for %s") },
-	 {"triggers-pending", N_("Processing triggers for %s") },
-#endif
 	 { "installed", N_("Installed %s")},
 	 { "installed", N_("Installed %s")},
 	 {NULL, NULL}
 	 {NULL, NULL}
       },
       },
       // Remove operation
       // Remove operation
       { 
       { 
 	 {"half-configured", N_("Preparing for removal of %s")},
 	 {"half-configured", N_("Preparing for removal of %s")},
-#if 0
-	 {"triggers-awaited", N_("Preparing for removal of %s")},
-	 {"triggers-pending", N_("Preparing for removal of %s")},
-#endif
 	 {"half-installed", N_("Removing %s")},
 	 {"half-installed", N_("Removing %s")},
 	 {"config-files",  N_("Removed %s")},
 	 {"config-files",  N_("Removed %s")},
 	 {NULL, NULL}
 	 {NULL, NULL}
@@ -670,16 +739,19 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    // that will be [installed|configured|removed|purged] and add
    // that will be [installed|configured|removed|purged] and add
    // them to the PackageOps map (the dpkg states it goes through)
    // them to the PackageOps map (the dpkg states it goes through)
    // and the PackageOpsTranslations (human readable strings)
    // and the PackageOpsTranslations (human readable strings)
-   for (vector<Item>::iterator I = List.begin(); I != List.end();I++)
+   for (vector<Item>::const_iterator I = List.begin(); I != List.end();I++)
    {
    {
-      string name = (*I).Pkg.Name();
+      if((*I).Pkg.end() == true)
+	 continue;
+
+      string const name = (*I).Pkg.Name();
       PackageOpsDone[name] = 0;
       PackageOpsDone[name] = 0;
       for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL;  i++) 
       for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL;  i++) 
       {
       {
 	 PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
 	 PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
 	 PackagesTotal++;
 	 PackagesTotal++;
       }
       }
-   }   
+   }
 
 
    stdin_is_dev_null = false;
    stdin_is_dev_null = false;
 
 
@@ -687,19 +759,42 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    OpenLog();
    OpenLog();
 
 
    // this loop is runs once per operation
    // this loop is runs once per operation
-   for (vector<Item>::iterator I = List.begin(); I != List.end();)
+   for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
    {
    {
-      vector<Item>::iterator J = I;
-      for (; J != List.end() && J->Op == I->Op; J++);
+      // Do all actions with the same Op in one run
+      vector<Item>::const_iterator J = I;
+      if (TriggersPending == true)
+	 for (; J != List.end(); J++)
+	 {
+	    if (J->Op == I->Op)
+	       continue;
+	    if (J->Op != Item::TriggersPending)
+	       break;
+	    vector<Item>::const_iterator T = J + 1;
+	    if (T != List.end() && T->Op == I->Op)
+	       continue;
+	    break;
+	 }
+      else
+	 for (; J != List.end() && J->Op == I->Op; J++)
+	    /* nothing */;
 
 
       // Generate the argument list
       // Generate the argument list
       const char *Args[MaxArgs + 50];
       const char *Args[MaxArgs + 50];
+      
+      // Now check if we are within the MaxArgs limit
+      //
+      // this code below is problematic, because it may happen that
+      // the argument list is split in a way that A depends on B
+      // and they are in the same "--configure A B" run
+      // - with the split they may now be configured in different
+      //   runs 
       if (J - I > (signed)MaxArgs)
       if (J - I > (signed)MaxArgs)
 	 J = I + MaxArgs;
 	 J = I + MaxArgs;
       
       
       unsigned int n = 0;
       unsigned int n = 0;
       unsigned long Size = 0;
       unsigned long Size = 0;
-      string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+      string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
       Args[n++] = Tmp.c_str();
       Args[n++] = Tmp.c_str();
       Size += strlen(Args[n-1]);
       Size += strlen(Args[n-1]);
       
       
@@ -749,11 +844,23 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 
 	 
 	 case Item::Configure:
 	 case Item::Configure:
 	 Args[n++] = "--configure";
 	 Args[n++] = "--configure";
-	 if (NoTriggers)
-	    Args[n++] = "--no-triggers";
 	 Size += strlen(Args[n-1]);
 	 Size += strlen(Args[n-1]);
 	 break;
 	 break;
-	 
+
+	 case Item::ConfigurePending:
+	 Args[n++] = "--configure";
+	 Size += strlen(Args[n-1]);
+	 Args[n++] = "--pending";
+	 Size += strlen(Args[n-1]);
+	 break;
+
+	 case Item::TriggersPending:
+	 Args[n++] = "--triggers-only";
+	 Size += strlen(Args[n-1]);
+	 Args[n++] = "--pending";
+	 Size += strlen(Args[n-1]);
+	 break;
+
 	 case Item::Install:
 	 case Item::Install:
 	 Args[n++] = "--unpack";
 	 Args[n++] = "--unpack";
 	 Size += strlen(Args[n-1]);
 	 Size += strlen(Args[n-1]);
@@ -761,7 +868,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 Size += strlen(Args[n-1]);
 	 Size += strlen(Args[n-1]);
 	 break;
 	 break;
       }
       }
-      
+
+      if (NoTriggers == true && I->Op != Item::TriggersPending &&
+	  I->Op != Item::ConfigurePending)
+      {
+	 Args[n++] = "--no-triggers";
+	 Size += strlen(Args[n-1]);
+      }
+
       // Write in the file or package names
       // Write in the file or package names
       if (I->Op == Item::Install)
       if (I->Op == Item::Install)
       {
       {
@@ -777,6 +891,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       {
       {
 	 for (;I != J && Size < MaxArgBytes; I++)
 	 for (;I != J && Size < MaxArgBytes; I++)
 	 {
 	 {
+	    if((*I).Pkg.end() == true)
+	       continue;
 	    Args[n++] = I->Pkg.Name();
 	    Args[n++] = I->Pkg.Name();
 	    Size += strlen(Args[n-1]);
 	    Size += strlen(Args[n-1]);
 	 }	 
 	 }	 
@@ -808,32 +924,36 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 
 
       struct	termios tt;
       struct	termios tt;
       struct	winsize win;
       struct	winsize win;
-      int	master;
-      int	slave;
+      int	master = -1;
+      int	slave = -1;
 
 
-      // FIXME: setup sensible signal handling (*ick*)
-      tcgetattr(0, &tt);
-      ioctl(0, TIOCGWINSZ, (char *)&win);
-      if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
+      // if tcgetattr does not return zero there was a error
+      // and we do not do any pty magic
+      if (tcgetattr(0, &tt) == 0)
       {
       {
-	 const char *s = _("Can not write log, openpty() "
-			   "failed (/dev/pts not mounted?)\n");
-	 fprintf(stderr, "%s",s);
-	 fprintf(term_out, "%s",s);
-	 master = slave = -1;
-      }  else {
-	 struct termios rtt;
-	 rtt = tt;
-	 cfmakeraw(&rtt);
-	 rtt.c_lflag &= ~ECHO;
-	 // block SIGTTOU during tcsetattr to prevent a hang if
-	 // the process is a member of the background process group
-	 // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
-	 sigemptyset(&sigmask);
-	 sigaddset(&sigmask, SIGTTOU);
-	 sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask);
-	 tcsetattr(0, TCSAFLUSH, &rtt);
-	 sigprocmask(SIG_SETMASK, &original_sigmask, 0);
+	 ioctl(0, TIOCGWINSZ, (char *)&win);
+	 if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
+	 {
+	    const char *s = _("Can not write log, openpty() "
+	                      "failed (/dev/pts not mounted?)\n");
+	    fprintf(stderr, "%s",s);
+            if(term_out)
+              fprintf(term_out, "%s",s);
+	    master = slave = -1;
+	 }  else {
+	    struct termios rtt;
+	    rtt = tt;
+	    cfmakeraw(&rtt);
+	    rtt.c_lflag &= ~ECHO;
+	    // block SIGTTOU during tcsetattr to prevent a hang if
+	    // the process is a member of the background process group
+	    // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
+	    sigemptyset(&sigmask);
+	    sigaddset(&sigmask, SIGTTOU);
+	    sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask);
+	    tcsetattr(0, TCSAFLUSH, &rtt);
+	    sigprocmask(SIG_SETMASK, &original_sigmask, 0);
+	 }
       }
       }
 
 
        // Fork dpkg
        // Fork dpkg
@@ -865,6 +985,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 }
 	 }
 	 close(fd[0]); // close the read end of the pipe
 	 close(fd[0]); // close the read end of the pipe
 
 
+	 if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") 
+	 {
+	    std::cerr << "Chrooting into " 
+		      << _config->FindDir("DPkg::Chroot-Directory") 
+		      << std::endl;
+	    if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
+	       _exit(100);
+	 }
+
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	 if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
 	    _exit(100);
 	    _exit(100);
 	 
 	 
@@ -903,11 +1032,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       int Status = 0;
       int Status = 0;
 
 
       // we read from dpkg here
       // we read from dpkg here
-      int _dpkgin = fd[0];
+      int const _dpkgin = fd[0];
       close(fd[1]);                        // close the write end of the pipe
       close(fd[1]);                        // close the write end of the pipe
 
 
-      // the result of the waitpid call
-      int res;
       if(slave > 0)
       if(slave > 0)
 	 close(slave);
 	 close(slave);
 
 
@@ -915,6 +1042,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       sigemptyset(&sigmask);
       sigemptyset(&sigmask);
       sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
       sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
 
 
+      // the result of the waitpid call
+      int res;
       int select_ret;
       int select_ret;
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
 	 if(res < 0) {
 	 if(res < 0) {
@@ -981,17 +1110,20 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 // if it was set to "keep-dpkg-runing" then we won't return
 	 // if it was set to "keep-dpkg-runing" then we won't return
 	 // here but keep the loop going and just report it as a error
 	 // here but keep the loop going and just report it as a error
 	 // for later
 	 // for later
-	 bool stopOnError = _config->FindB("Dpkg::StopOnError",true);
+	 bool const stopOnError = _config->FindB("Dpkg::StopOnError",true);
 	 
 	 
 	 if(stopOnError)
 	 if(stopOnError)
 	    RunScripts("DPkg::Post-Invoke");
 	    RunScripts("DPkg::Post-Invoke");
 
 
 	 if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
 	 if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) 
-	    _error->Error("Sub-process %s received a segmentation fault.",Args[0]);
+	    strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
 	 else if (WIFEXITED(Status) != 0)
 	 else if (WIFEXITED(Status) != 0)
-	    _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
+	    strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
 	 else 
 	 else 
-	    _error->Error("Sub-process %s exited unexpectedly",Args[0]);
+	    strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
+
+	 if(dpkg_error.size() > 0)
+	    _error->Error(dpkg_error.c_str());
 
 
 	 if(stopOnError) 
 	 if(stopOnError) 
 	 {
 	 {

+ 5 - 2
apt-pkg/deb/dpkgpm.h

@@ -29,7 +29,9 @@ class pkgDPkgPM : public pkgPackageManager
    char dpkgbuf[1024];
    char dpkgbuf[1024];
    int dpkgbuf_pos;
    int dpkgbuf_pos;
    FILE *term_out;
    FILE *term_out;
-   
+   FILE *history_out;
+   string dpkg_error;
+
    protected:
    protected:
 
 
    // progress reporting
    // progress reporting
@@ -53,7 +55,7 @@ class pkgDPkgPM : public pkgPackageManager
   
   
    struct Item
    struct Item
    {
    {
-      enum Ops {Install, Configure, Remove, Purge} Op;
+      enum Ops {Install, Configure, Remove, Purge, ConfigurePending, TriggersPending} Op;
       string File;
       string File;
       PkgIterator Pkg;
       PkgIterator Pkg;
       Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op),
       Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op),
@@ -66,6 +68,7 @@ class pkgDPkgPM : public pkgPackageManager
    // Helpers
    // Helpers
    bool RunScriptsWithPkgs(const char *Cnf);
    bool RunScriptsWithPkgs(const char *Cnf);
    bool SendV2Pkgs(FILE *F);
    bool SendV2Pkgs(FILE *F);
+   void WriteHistoryTag(string tag, string value);
 
 
    // dpkg log
    // dpkg log
    bool OpenLog();
    bool OpenLog();

+ 118 - 61
apt-pkg/depcache.cc

@@ -15,6 +15,7 @@
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/algorithms.h>
 
 
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
@@ -26,8 +27,8 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
 #include <apti18n.h>    
 #include <apti18n.h>    
-
-// helper for Install-Recommends-Sections and Never-MarkAuto-Sections
+									/*}}}*/
+// helper for Install-Recommends-Sections and Never-MarkAuto-Sections	/*{{{*/
 static bool 
 static bool 
 ConfigValueInSubTree(const char* SubTree, const char *needle)
 ConfigValueInSubTree(const char* SubTree, const char *needle)
 {
 {
@@ -46,9 +47,8 @@ ConfigValueInSubTree(const char* SubTree, const char *needle)
    }
    }
    return false;
    return false;
 }
 }
-
-
-pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
+									/*}}}*/
+pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :		/*{{{*/
   cache(cache), released(false)
   cache(cache), released(false)
 {
 {
   ++cache.group_level;
   ++cache.group_level;
@@ -76,13 +76,15 @@ pkgDepCache::ActionGroup::~ActionGroup()
 {
 {
   release();
   release();
 }
 }
-
+									/*}}}*/
 // DepCache::pkgDepCache - Constructors					/*{{{*/
 // DepCache::pkgDepCache - Constructors					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
   group_level(0), Cache(pCache), PkgState(0), DepState(0)
   group_level(0), Cache(pCache), PkgState(0), DepState(0)
 {
 {
+   DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
+   DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
    delLocalPolicy = 0;
    delLocalPolicy = 0;
    LocalPolicy = Plcy;
    LocalPolicy = Plcy;
    if (LocalPolicy == 0)
    if (LocalPolicy == 0)
@@ -127,7 +129,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
    int Done = 0;
    int Done = 0;
    for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
    for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
    {
    {
-      if (Prog != 0)
+      if (Prog != 0 && Done%20 == 0)
 	 Prog->Progress(Done);
 	 Prog->Progress(Done);
       
       
       // Find the proper cache slot
       // Find the proper cache slot
@@ -159,8 +161,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
    return true;
    return true;
 } 
 } 
 									/*}}}*/
 									/*}}}*/
-
-bool pkgDepCache::readStateFile(OpProgress *Prog)
+bool pkgDepCache::readStateFile(OpProgress *Prog)			/*{{{*/
 {
 {
    FileFd state_file;
    FileFd state_file;
    string state = _config->FindDir("Dir::State") + "extended_states";
    string state = _config->FindDir("Dir::State") + "extended_states";
@@ -174,6 +175,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
       pkgTagFile tagfile(&state_file);
       pkgTagFile tagfile(&state_file);
       pkgTagSection section;
       pkgTagSection section;
       int amt=0;
       int amt=0;
+      bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false);
       while(tagfile.Step(section)) {
       while(tagfile.Step(section)) {
 	 string pkgname = section.FindS("Package");
 	 string pkgname = section.FindS("Package");
 	 pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
 	 pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
@@ -183,7 +185,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
 	    short reason = section.FindI("Auto-Installed", 0);
 	    short reason = section.FindI("Auto-Installed", 0);
 	    if(reason > 0)
 	    if(reason > 0)
 	       PkgState[pkg->ID].Flags  |= Flag::Auto;
 	       PkgState[pkg->ID].Flags  |= Flag::Auto;
-	    if(_config->FindB("Debug::pkgAutoRemove",false))
+	    if(debug_autoremove)
 	       std::cout << "Auto-Installed : " << pkgname << std::endl;
 	       std::cout << "Auto-Installed : " << pkgname << std::endl;
 	    amt+=section.size();
 	    amt+=section.size();
 	    if(Prog != NULL)
 	    if(Prog != NULL)
@@ -198,10 +200,12 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
 
 
    return true;
    return true;
 }
 }
-
-bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
+									/*}}}*/
+bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)	/*{{{*/
 {
 {
-   if(_config->FindB("Debug::pkgAutoRemove",false))
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+   
+   if(debug_autoremove)
       std::clog << "pkgDepCache::writeStateFile()" << std::endl;
       std::clog << "pkgDepCache::writeStateFile()" << std::endl;
 
 
    FileFd StateFile;
    FileFd StateFile;
@@ -239,7 +243,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
 	    continue;
 	    continue;
 	 bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
 	 bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
 	 if(_config->FindB("Debug::pkgAutoRemove",false))
 	 if(_config->FindB("Debug::pkgAutoRemove",false))
-	    std::clog << "Update exisiting AutoInstall info: " 
+	    std::clog << "Update existing AutoInstall info: " 
 		      << pkg.Name() << std::endl;
 		      << pkg.Name() << std::endl;
 	 TFRewriteData rewrite[2];
 	 TFRewriteData rewrite[2];
 	 rewrite[0].Tag = "Auto-Installed";
 	 rewrite[0].Tag = "Auto-Installed";
@@ -256,14 +260,14 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
       if(PkgState[pkg->ID].Flags & Flag::Auto) {
       if(PkgState[pkg->ID].Flags & Flag::Auto) {
 	 if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
 	 if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
-	    if(_config->FindB("Debug::pkgAutoRemove",false))
+	    if(debug_autoremove)
 	       std::clog << "Skipping already written " << pkg.Name() << std::endl;
 	       std::clog << "Skipping already written " << pkg.Name() << std::endl;
 	    continue;
 	    continue;
 	 }
 	 }
          // skip not installed ones if requested
          // skip not installed ones if requested
          if(InstalledOnly && pkg->CurrentVer == 0)
          if(InstalledOnly && pkg->CurrentVer == 0)
             continue;
             continue;
-	 if(_config->FindB("Debug::pkgAutoRemove",false))
+	 if(debug_autoremove)
 	    std::clog << "Writing new AutoInstall: " 
 	    std::clog << "Writing new AutoInstall: " 
 		      << pkg.Name() << std::endl;
 		      << pkg.Name() << std::endl;
 	 ostr.str(string(""));
 	 ostr.str(string(""));
@@ -281,7 +285,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
 
 
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 // DepCache::CheckDep - Checks a single dependency			/*{{{*/
 // DepCache::CheckDep - Checks a single dependency			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This first checks the dependency against the main target package and
 /* This first checks the dependency against the main target package and
@@ -699,13 +703,12 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
 	   P.end() != true; P++)
 	   P.end() != true; P++)
 	 Update(P.ParentPkg().RevDependsList());
 	 Update(P.ParentPkg().RevDependsList());
 }
 }
-
 									/*}}}*/
 									/*}}}*/
-
 // DepCache::MarkKeep - Put the package in the keep state		/*{{{*/
 // DepCache::MarkKeep - Put the package in the keep state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
+void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
+                           unsigned long Depth)
 {
 {
    // Simplifies other routines.
    // Simplifies other routines.
    if (Pkg.end() == true)
    if (Pkg.end() == true)
@@ -746,6 +749,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
      P.Flags &= ~Flag::Auto;
      P.Flags &= ~Flag::Auto;
 #endif
 #endif
 
 
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << " FU=" << FromUser << std::endl;
+
    RemoveSizes(Pkg);
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
    RemoveStates(Pkg);
 
 
@@ -765,7 +771,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
 // DepCache::MarkDelete - Put the package in the delete state		/*{{{*/
 // DepCache::MarkDelete - Put the package in the delete state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
+void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
+                             unsigned long Depth, bool FromUser)
 {
 {
    // Simplifies other routines.
    // Simplifies other routines.
    if (Pkg.end() == true)
    if (Pkg.end() == true)
@@ -787,6 +794,13 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
    if (Pkg->VersionList == 0)
    if (Pkg->VersionList == 0)
       return;
       return;
 
 
+   // check if we are allowed to install the package
+   if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
+      return;
+
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << " FU=" << FromUser << std::endl;
+
    RemoveSizes(Pkg);
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
    RemoveStates(Pkg);
    
    
@@ -801,6 +815,23 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
    AddSizes(Pkg);
    AddSizes(Pkg);
 }
 }
 									/*}}}*/
 									/*}}}*/
+// DepCache::IsDeleteOk - check if it is ok to remove this package	/*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation just honors dpkg hold
+   But an application using this library can override this method
+   to control the MarkDelete behaviour */
+bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
+			      unsigned long Depth, bool FromUser)
+{
+   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
+   {
+      if (DebugMarker == true)
+	 std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << " FU=" << FromUser << std::endl;
+      return false;
+   }
+   return true;
+}
+									/*}}}*/
 // DepCache::MarkInstall - Put the package in the install state		/*{{{*/
 // DepCache::MarkInstall - Put the package in the install state		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -826,7 +857,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
    {
    {
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
-	 MarkKeep(Pkg, false, FromUser);
+	 MarkKeep(Pkg, false, FromUser, Depth+1);
       return;
       return;
    }
    }
 
 
@@ -836,6 +867,11 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    // We dont even try to install virtual packages..
    // We dont even try to install virtual packages..
    if (Pkg->VersionList == 0)
    if (Pkg->VersionList == 0)
       return;
       return;
+
+   // check if we are allowed to install the package
+   if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
+      return;
+
    /* Target the candidate version and remove the autoflag. We reset the
    /* Target the candidate version and remove the autoflag. We reset the
       autoflag below if this was called recursively. Otherwise the user
       autoflag below if this was called recursively. Otherwise the user
       should have the ability to de-auto a package by changing its state */
       should have the ability to de-auto a package by changing its state */
@@ -864,10 +900,13 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    AddStates(Pkg);
    AddStates(Pkg);
    Update(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
    AddSizes(Pkg);
-   
+
    if (AutoInst == false)
    if (AutoInst == false)
       return;
       return;
 
 
+   if (DebugMarker == true)
+      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
+
    DepIterator Dep = P.InstVerIter(*this).DependsList();
    DepIterator Dep = P.InstVerIter(*this).DependsList();
    for (; Dep.end() != true;)
    for (; Dep.end() != true;)
    {
    {
@@ -937,12 +976,12 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 }
 	 }
       }
       }
       if(isNewImportantDep)
       if(isNewImportantDep)
-	 if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
-	    std::clog << "new important dependency: " 
+	 if(DebugAutoInstall == true)
+	    std::clog << OutputInDepth(Depth) << "new important dependency: "
 		      << Start.TargetPkg().Name() << std::endl;
 		      << Start.TargetPkg().Name() << std::endl;
       if(isPreviouslySatisfiedImportantDep)
       if(isPreviouslySatisfiedImportantDep)
-	if(_config->FindB("Debug::pkgDepCache::AutoInstall", false) == true)
-	  std::clog << "previously satisfied important dependency on "
+	if(DebugAutoInstall == true)
+	  std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
 		    << Start.TargetPkg().Name() << std::endl;
 		    << Start.TargetPkg().Name() << std::endl;
 
 
       // skip important deps if the package is already installed
       // skip important deps if the package is already installed
@@ -991,17 +1030,18 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    }
 	    }
 	 }
 	 }
 	 
 	 
-	 if (InstPkg.end() == false) 
+	 if (InstPkg.end() == false)
 	 {
 	 {
-	    if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
-	       std::clog << "Installing " << InstPkg.Name() 
-			 << " as dep of " << Pkg.Name() 
+	    if(DebugAutoInstall == true)
+	       std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
+			 << " as " << Start.DepType() << " of " << Pkg.Name()
 			 << std::endl;
 			 << std::endl;
  	    // now check if we should consider it a automatic dependency or not
  	    // now check if we should consider it a automatic dependency or not
  	    if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section()))
  	    if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section()))
  	    {
  	    {
- 	       if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
- 		  std::clog << "Setting NOT as auto-installed (direct dep of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
+	       if(DebugAutoInstall == true)
+		  std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct "
+                            << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
  	       MarkInstall(InstPkg,true,Depth + 1, true);
  	       MarkInstall(InstPkg,true,Depth + 1, true);
  	    }
  	    }
  	    else 
  	    else 
@@ -1028,16 +1068,32 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    PkgIterator Pkg = Ver.ParentPkg();
 	    PkgIterator Pkg = Ver.ParentPkg();
 
 
 	    if (Start->Type != Dep::DpkgBreaks)
 	    if (Start->Type != Dep::DpkgBreaks)
-	       MarkDelete(Pkg);
-	    else
-	       if (PkgState[Pkg->ID].CandidateVer != *I)
-		  MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
+	       MarkDelete(Pkg,false,Depth + 1, false);
+	    else if (PkgState[Pkg->ID].CandidateVer != *I)
+	       MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
 	 }
 	 }
 	 continue;
 	 continue;
       }      
       }      
    }
    }
 }
 }
 									/*}}}*/
 									/*}}}*/
+// DepCache::IsInstallOk - check if it is ok to install this package	/*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation just honors dpkg hold
+   But an application using this library can override this method
+   to control the MarkInstall behaviour */
+bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
+			      unsigned long Depth, bool FromUser)
+{
+   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
+   {
+      if (DebugMarker == true)
+	 std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << " FU=" << FromUser << std::endl;
+      return false;
+   }
+   return true;
+}
+									/*}}}*/
 // DepCache::SetReInstall - Set the reinstallation flag			/*{{{*/
 // DepCache::SetReInstall - Set the reinstallation flag			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -1137,7 +1193,6 @@ const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
    return Ver;
    return Ver;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // Policy::GetCandidateVer - Returns the Candidate install version	/*{{{*/
 // Policy::GetCandidateVer - Returns the Candidate install version	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The default just returns the highest available version that is not
 /* The default just returns the highest available version that is not
@@ -1174,7 +1229,6 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
    return Last;
    return Last;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // Policy::IsImportantDep - True if the dependency is important		/*{{{*/
 // Policy::IsImportantDep - True if the dependency is important		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -1200,8 +1254,7 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
+pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()			/*{{{*/
   : constructedSuccessfully(false)
   : constructedSuccessfully(false)
 {
 {
   Configuration::Item const *Opts;
   Configuration::Item const *Opts;
@@ -1230,8 +1283,8 @@ pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
 
 
   constructedSuccessfully = true;
   constructedSuccessfully = true;
 }
 }
-
-pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
+									/*}}}*/
+pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()			/*{{{*/
 {
 {
   for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
   for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
     {
     {
@@ -1239,9 +1292,8 @@ pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
       delete rootSetRegexp[i];
       delete rootSetRegexp[i];
     }
     }
 }
 }
-
-
-bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg)
+									/*}}}*/
+bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) /*{{{*/
 {
 {
    for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
    for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
       if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
       if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
@@ -1249,8 +1301,8 @@ bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg
 
 
    return false;
    return false;
 }
 }
-
-pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
+									/*}}}*/
+pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()		/*{{{*/
 {
 {
   DefaultRootSetFunc *f = new DefaultRootSetFunc;
   DefaultRootSetFunc *f = new DefaultRootSetFunc;
   if(f->wasConstructedSuccessfully())
   if(f->wasConstructedSuccessfully())
@@ -1261,7 +1313,7 @@ pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
       return NULL;
       return NULL;
     }
     }
 }
 }
-
+									/*}}}*/
 bool pkgDepCache::MarkFollowsRecommends()
 bool pkgDepCache::MarkFollowsRecommends()
 {
 {
   return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
   return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
@@ -1272,11 +1324,12 @@ bool pkgDepCache::MarkFollowsSuggests()
   return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
   return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
 }
 }
 
 
-// the main mark algorithm
+// pkgDepCache::MarkRequired - the main mark algorithm			/*{{{*/
 bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 {
 {
    bool follow_recommends;
    bool follow_recommends;
    bool follow_suggests;
    bool follow_suggests;
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
 
 
    // init the states
    // init the states
    for(PkgIterator p = PkgBegin(); !p.end(); ++p)
    for(PkgIterator p = PkgBegin(); !p.end(); ++p)
@@ -1285,8 +1338,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
       PkgState[p->ID].Garbage = false;
       PkgState[p->ID].Garbage = false;
 
 
       // debug output
       // debug output
-      if(_config->FindB("Debug::pkgAutoRemove",false) 
-	 && PkgState[p->ID].Flags & Flag::Auto)
+      if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto)
   	 std::clog << "AutoDep: " << p.Name() << std::endl;
   	 std::clog << "AutoDep: " << p.Name() << std::endl;
    }
    }
 
 
@@ -1317,8 +1369,8 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
 
 
    return true;
    return true;
 }
 }
-
-// mark a single package in Mark-and-Sweep
+									/*}}}*/
+// MarkPackage - mark a single package in Mark-and-Sweep		/*{{{*/
 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
 			      const pkgCache::VerIterator &ver,
 			      const pkgCache::VerIterator &ver,
 			      bool follow_recommends,
 			      bool follow_recommends,
@@ -1357,7 +1409,9 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
    if(state.Marked)
    if(state.Marked)
       return;
       return;
 
 
-   if(_config->FindB("Debug::pkgAutoRemove",false))
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
+   
+   if(debug_autoremove)
      {
      {
        std::clog << "Marking: " << pkg.Name();
        std::clog << "Marking: " << pkg.Name();
        if(!ver.end())
        if(!ver.end())
@@ -1388,7 +1442,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
 	   {
 	   {
 	      if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
 	      if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
 	      {
 	      {
-		if(_config->FindB("Debug::pkgAutoRemove",false))
+		if(debug_autoremove)
 		  {
 		  {
 		    std::clog << "Following dep: " << d.ParentPkg().Name()
 		    std::clog << "Following dep: " << d.ParentPkg().Name()
 			      << " " << d.ParentVer().VerStr() << " "
 			      << " " << d.ParentVer().VerStr() << " "
@@ -1412,7 +1466,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
 	      if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
 	      if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
 				       d.TargetVer()))
 				       d.TargetVer()))
 	      {
 	      {
-		if(_config->FindB("Debug::pkgAutoRemove",false))
+		if(debug_autoremove)
 		  {
 		  {
 		    std::clog << "Following dep: " << d.ParentPkg().Name()
 		    std::clog << "Following dep: " << d.ParentPkg().Name()
 			      << " " << d.ParentVer().VerStr() << " "
 			      << " " << d.ParentVer().VerStr() << " "
@@ -1437,12 +1491,14 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
      }
      }
    }
    }
 }
 }
-
-bool pkgDepCache::Sweep()
+									/*}}}*/
+bool pkgDepCache::Sweep()						/*{{{*/
 {
 {
+   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+
    // do the sweep
    // do the sweep
    for(PkgIterator p=PkgBegin(); !p.end(); ++p)
    for(PkgIterator p=PkgBegin(); !p.end(); ++p)
-  {
+   {
      StateCache &state=PkgState[p->ID];
      StateCache &state=PkgState[p->ID];
 
 
      // skip required packages
      // skip required packages
@@ -1454,10 +1510,11 @@ bool pkgDepCache::Sweep()
      if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
      if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
      {
      {
 	state.Garbage=true;
 	state.Garbage=true;
-	if(_config->FindB("Debug::pkgAutoRemove",false))
+	if(debug_autoremove)
 	   std::cout << "Garbage: " << p.Name() << std::endl;
 	   std::cout << "Garbage: " << p.Name() << std::endl;
      }
      }
   }   
   }   
 
 
    return true;
    return true;
 }
 }
+									/*}}}*/

+ 47 - 4
apt-pkg/depcache.h

@@ -294,7 +294,10 @@ class pkgDepCache : protected pkgCache::Namespace
    unsigned long iBrokenCount;
    unsigned long iBrokenCount;
    unsigned long iPolicyBrokenCount;
    unsigned long iPolicyBrokenCount;
    unsigned long iBadCount;
    unsigned long iBadCount;
-   
+
+   bool DebugMarker;
+   bool DebugAutoInstall;
+
    Policy *delLocalPolicy;           // For memory clean up..
    Policy *delLocalPolicy;           // For memory clean up..
    Policy *LocalPolicy;
    Policy *LocalPolicy;
    
    
@@ -387,18 +390,58 @@ class pkgDepCache : protected pkgCache::Namespace
     */
     */
    // @{
    // @{
    void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
    void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
-		 bool FromUser = true);
-   void MarkDelete(PkgIterator const &Pkg,bool Purge = false);
+		 bool FromUser = true, unsigned long Depth = 0);
+   void MarkDelete(PkgIterator const &Pkg, bool Purge = false,
+                   unsigned long Depth = 0, bool FromUser = true);
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    bool ForceImportantDeps = false);
 		    bool ForceImportantDeps = false);
+
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetCandidateVersion(VerIterator TargetVer);
    void SetCandidateVersion(VerIterator TargetVer);
 
 
    /** Set the "is automatically installed" flag of Pkg. */
    /** Set the "is automatically installed" flag of Pkg. */
    void MarkAuto(const PkgIterator &Pkg, bool Auto);
    void MarkAuto(const PkgIterator &Pkg, bool Auto);
    // @}
    // @}
-   
+
+   /** \return \b true if it's OK for MarkInstall to install
+    *  the given package.
+    *
+    *  See the default implementation for a simple example how this
+    *  method can be used.
+    *  Overriding implementations should use the hold-state-flag to cache
+    *  results from previous checks of this package - also it should
+    *  be used if the default resolver implementation is also used to
+    *  ensure that these packages are handled like "normal" dpkg holds.
+    *
+    *  The parameters are the same as in the calling MarkInstall:
+    *  \param Pkg       the package that MarkInstall wants to install.
+    *  \param AutoInst  needs a previous MarkInstall this package?
+    *  \param Depth     recursive deep of this Marker call
+    *  \param FromUser  was the install requested by the user?
+    */
+   virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
+			    unsigned long Depth = 0, bool FromUser = true);
+
+   /** \return \b true if it's OK for MarkDelete to remove
+    *  the given package.
+    *
+    *  See the default implementation for a simple example how this
+    *  method can be used.
+    *  Overriding implementations should use the hold-state-flag to cache
+    *  results from previous checks of this package - also it should
+    *  be used if the default resolver implementation is also used to
+    *  ensure that these packages are handled like "normal" dpkg holds.
+    *
+    *  The parameters are the same as in the calling MarkDelete:
+    *  \param Pkg       the package that MarkDelete wants to remove.
+    *  \param Purge     should we purge instead of "only" remove?
+    *  \param Depth     recursive deep of this Marker call
+    *  \param FromUser  was the remove requested by the user?
+    */
+   virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false,
+			    unsigned long Depth = 0, bool FromUser = true);
+
    // This is for debuging
    // This is for debuging
    void Update(OpProgress *Prog = 0);
    void Update(OpProgress *Prog = 0);
 
 

+ 14 - 11
apt-pkg/indexcopy.cc

@@ -527,19 +527,19 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
    // (non-existing files are not considered a error)
    // (non-existing files are not considered a error)
    if(!FileExists(prefix+file))
    if(!FileExists(prefix+file))
    {
    {
-      _error->Warning("Skipping non-exisiting file %s", string(prefix+file).c_str());
+      _error->Warning(_("Skipping nonexistent file %s"), string(prefix+file).c_str());
       return true;
       return true;
    }
    }
 
 
    if (!Record) 
    if (!Record) 
    {
    {
-      _error->Warning("Can't find authentication record for: %s",file.c_str());
+      _error->Warning(_("Can't find authentication record for: %s"), file.c_str());
       return false;
       return false;
    }
    }
 
 
    if (!Record->Hash.VerifyFile(prefix+file))
    if (!Record->Hash.VerifyFile(prefix+file))
    {
    {
-      _error->Warning("Hash mismatch for: %s",file.c_str());
+      _error->Warning(_("Hash mismatch for: %s"),file.c_str());
       return false;
       return false;
    }
    }
 
 
@@ -551,8 +551,8 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
 
 
    return true;
    return true;
 }
 }
-
-bool SigVerify::CopyMetaIndex(string CDROM, string CDName, 
+									/*}}}*/
+bool SigVerify::CopyMetaIndex(string CDROM, string CDName,		/*{{{*/
 			      string prefix, string file)
 			      string prefix, string file)
 {
 {
       char S[400];
       char S[400];
@@ -572,8 +572,8 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName,
    
    
       return true;
       return true;
 }
 }
-
-bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
+									/*}}}*/
+bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,	/*{{{*/
 			      vector<string> PkgList,vector<string> SrcList)
 			      vector<string> PkgList,vector<string> SrcList)
 {
 {
    if (SigList.size() == 0)
    if (SigList.size() == 0)
@@ -592,7 +592,10 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 
 
       // a Release.gpg without a Release should never happen
       // a Release.gpg without a Release should never happen
       if(!FileExists(*I+"Release"))
       if(!FileExists(*I+"Release"))
+      {
+	 delete MetaIndex;
 	 continue;
 	 continue;
+      }
 
 
 
 
       // verify the gpg signature of "Release"
       // verify the gpg signature of "Release"
@@ -675,10 +678,9 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 
 
    return true;
    return true;
 }
 }
-
-
-bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string> &List,
-			     pkgCdromStatus *log)
+									/*}}}*/
+bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
+				vector<string> &List, pkgCdromStatus *log)
 {
 {
    OpProgress *Progress = NULL;
    OpProgress *Progress = NULL;
    if (List.size() == 0)
    if (List.size() == 0)
@@ -850,3 +852,4 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string>
 
 
    return true;
    return true;
 }
 }
+									/*}}}*/

+ 10 - 12
apt-pkg/indexcopy.h

@@ -22,7 +22,7 @@ class FileFd;
 class indexRecords;
 class indexRecords;
 class pkgCdromStatus;
 class pkgCdromStatus;
 
 
-class IndexCopy
+class IndexCopy								/*{{{*/
 {
 {
    protected:
    protected:
    
    
@@ -45,8 +45,8 @@ class IndexCopy
 		     pkgCdromStatus *log);
 		     pkgCdromStatus *log);
    virtual ~IndexCopy() {};
    virtual ~IndexCopy() {};
 };
 };
-
-class PackageCopy : public IndexCopy
+									/*}}}*/
+class PackageCopy : public IndexCopy					/*{{{*/
 {
 {
    protected:
    protected:
    
    
@@ -57,8 +57,8 @@ class PackageCopy : public IndexCopy
    
    
    public:
    public:
 };
 };
-
-class SourceCopy : public IndexCopy
+									/*}}}*/
+class SourceCopy : public IndexCopy					/*{{{*/
 {
 {
    protected:
    protected:
    
    
@@ -69,8 +69,8 @@ class SourceCopy : public IndexCopy
    
    
    public:
    public:
 };
 };
-
-class TranslationsCopy
+									/*}}}*/
+class TranslationsCopy							/*{{{*/
 {
 {
    protected:
    protected:
    pkgTagSection *Section;
    pkgTagSection *Section;
@@ -79,9 +79,8 @@ class TranslationsCopy
    bool CopyTranslations(string CDROM,string Name,vector<string> &List,
    bool CopyTranslations(string CDROM,string Name,vector<string> &List,
 			 pkgCdromStatus *log);
 			 pkgCdromStatus *log);
 };
 };
-
-
-class SigVerify 
+									/*}}}*/
+class SigVerify								/*{{{*/
 {
 {
    bool Verify(string prefix,string file, indexRecords *records);
    bool Verify(string prefix,string file, indexRecords *records);
    bool CopyMetaIndex(string CDROM, string CDName, 
    bool CopyMetaIndex(string CDROM, string CDName, 
@@ -91,7 +90,6 @@ class SigVerify
    bool CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
    bool CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 		      vector<string> PkgList,vector<string> SrcList);
 		      vector<string> PkgList,vector<string> SrcList);
 };
 };
-
-
+									/*}}}*/
 
 
 #endif
 #endif

+ 0 - 1
apt-pkg/indexfile.cc

@@ -41,7 +41,6 @@ pkgIndexFile::Type *pkgIndexFile::Type::GetType(const char *Type)
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
-    
 // IndexFile::ArchiveInfo - Stub					/*{{{*/
 // IndexFile::ArchiveInfo - Stub					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 7 - 7
apt-pkg/indexrecords.cc

@@ -9,7 +9,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apti18n.h>
 #include <apti18n.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
-
+									/*}}}*/
 string indexRecords::GetDist() const
 string indexRecords::GetDist() const
 {
 {
    return this->Dist;
    return this->Dist;
@@ -31,7 +31,7 @@ const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
    return Entries[MetaKey];
    return Entries[MetaKey];
 }
 }
 
 
-bool indexRecords::Load(const string Filename)
+bool indexRecords::Load(const string Filename)				/*{{{*/
 {
 {
    FileFd Fd(Filename, FileFd::ReadOnly);
    FileFd Fd(Filename, FileFd::ReadOnly);
    pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
    pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
@@ -85,8 +85,8 @@ bool indexRecords::Load(const string Filename)
    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
    return true;
    return true;
 }
 }
-
-vector<string> indexRecords::MetaKeys()
+									/*}}}*/
+vector<string> indexRecords::MetaKeys()					/*{{{*/
 {
 {
    std::vector<std::string> keys;
    std::vector<std::string> keys;
    std::map<string,checkSum *>::iterator I = Entries.begin();
    std::map<string,checkSum *>::iterator I = Entries.begin();
@@ -96,8 +96,8 @@ vector<string> indexRecords::MetaKeys()
    }
    }
    return keys;
    return keys;
 }
 }
-
-bool indexRecords::parseSumData(const char *&Start, const char *End,
+									/*}}}*/
+bool indexRecords::parseSumData(const char *&Start, const char *End,	/*{{{*/
 				   string &Name, string &Hash, size_t &Size)
 				   string &Name, string &Hash, size_t &Size)
 {
 {
    Name = "";
    Name = "";
@@ -154,7 +154,7 @@ bool indexRecords::parseSumData(const char *&Start, const char *End,
    Start = EntryEnd; //prepare for the next round
    Start = EntryEnd; //prepare for the next round
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 indexRecords::indexRecords()
 indexRecords::indexRecords()
 {
 {
 }
 }

+ 16 - 6
apt-pkg/init.cc

@@ -65,13 +65,16 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.Set("Dir::Etc::vendorlist","vendors.list");
    Cnf.Set("Dir::Etc::vendorlist","vendors.list");
    Cnf.Set("Dir::Etc::vendorparts","vendors.list.d");
    Cnf.Set("Dir::Etc::vendorparts","vendors.list.d");
    Cnf.Set("Dir::Etc::main","apt.conf");
    Cnf.Set("Dir::Etc::main","apt.conf");
+   Cnf.Set("Dir::ETc::netrc", "auth.conf");
    Cnf.Set("Dir::Etc::parts","apt.conf.d");
    Cnf.Set("Dir::Etc::parts","apt.conf.d");
    Cnf.Set("Dir::Etc::preferences","preferences");
    Cnf.Set("Dir::Etc::preferences","preferences");
+   Cnf.Set("Dir::Etc::preferencesparts","preferences.d");
    Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods");
    Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods");
 
 
    // State   
    // State   
    Cnf.Set("Dir::Log","var/log/apt");
    Cnf.Set("Dir::Log","var/log/apt");
    Cnf.Set("Dir::Log::Terminal","term.log");
    Cnf.Set("Dir::Log::Terminal","term.log");
+   Cnf.Set("Dir::Log::History","history.log");
 
 
    // Translation
    // Translation
    Cnf.Set("APT::Acquire::Translation", "environment");
    Cnf.Set("APT::Acquire::Translation", "environment");
@@ -80,22 +83,29 @@ bool pkgInitConfig(Configuration &Cnf)
    
    
    // Read an alternate config file
    // Read an alternate config file
    const char *Cfg = getenv("APT_CONFIG");
    const char *Cfg = getenv("APT_CONFIG");
-   if (Cfg != 0 && FileExists(Cfg) == true)
-      Res &= ReadConfigFile(Cnf,Cfg);
-   
+   if (Cfg != 0)
+   {
+      if (FileExists(Cfg) == true)
+	 Res &= ReadConfigFile(Cnf,Cfg);
+      else
+	 _error->WarningE("FileExists",_("Unable to read %s"),Cfg);
+   }
+
    // Read the configuration parts dir
    // Read the configuration parts dir
    string Parts = Cnf.FindDir("Dir::Etc::parts");
    string Parts = Cnf.FindDir("Dir::Etc::parts");
    if (FileExists(Parts) == true)
    if (FileExists(Parts) == true)
       Res &= ReadConfigDir(Cnf,Parts);
       Res &= ReadConfigDir(Cnf,Parts);
-      
+   else
+      _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str());
+
    // Read the main config file
    // Read the main config file
    string FName = Cnf.FindFile("Dir::Etc::main");
    string FName = Cnf.FindFile("Dir::Etc::main");
    if (FileExists(FName) == true)
    if (FileExists(FName) == true)
       Res &= ReadConfigFile(Cnf,FName);
       Res &= ReadConfigFile(Cnf,FName);
-   
+
    if (Res == false)
    if (Res == false)
       return false;
       return false;
-   
+
    if (Cnf.FindB("Debug::pkgInitConfig",false) == true)
    if (Cnf.FindB("Debug::pkgInitConfig",false) == true)
       Cnf.Dump();
       Cnf.Dump();
    
    

+ 6 - 2
apt-pkg/init.h

@@ -16,9 +16,13 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
 
 
-// See the makefile
+// These lines are extracted by the makefiles and the buildsystem
+// Increasing MAJOR or MINOR results in the need of recompiling all
+// reverse-dependencies of libapt-pkg against the new SONAME.
+// Non-ABI-Breaks should only increase RELEASE number.
+// See also buildlib/libversion.mak
 #define APT_PKG_MAJOR 4
 #define APT_PKG_MAJOR 4
-#define APT_PKG_MINOR 6
+#define APT_PKG_MINOR 8
 #define APT_PKG_RELEASE 0
 #define APT_PKG_RELEASE 0
     
     
 extern const char *pkgVersion;
 extern const char *pkgVersion;

+ 11 - 11
apt-pkg/makefile

@@ -9,23 +9,22 @@ HEADER_TARGETDIRS = apt-pkg
 # Bring in the default rules
 # Bring in the default rules
 include ../buildlib/defaults.mak
 include ../buildlib/defaults.mak
 
 
-# The library name, don't forget to update init.h and the copy in 
-# methods/makefile - FIXME
+# The library name and version (indirectly used from init.h)
+include ../buildlib/libversion.mak
 LIBRARY=apt-pkg
 LIBRARY=apt-pkg
-LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=4.7
-MINOR=0
+MAJOR=$(LIBAPTPKG_MAJOR)
+MINOR=$(LIBAPTPKG_RELEASE)
 SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil -ldl
 SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil -ldl
-APT_DOMAIN:=libapt-pkg$(MAJOR)
+APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR)
 
 
 # Source code for the contributed non-core things
 # Source code for the contributed non-core things
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
          contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
          contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
 	 contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
 	 contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
-	 contrib/cdromutl.cc contrib/crc-16.cc \
+	 contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \
 	 contrib/fileutl.cc 
 	 contrib/fileutl.cc 
-HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h \
-	  md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h
+HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h netrc.h\
+	  md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h 
 
 
 # Source code for the core main library
 # Source code for the core main library
 SOURCE+= pkgcache.cc version.cc depcache.cc \
 SOURCE+= pkgcache.cc version.cc depcache.cc \
@@ -34,14 +33,15 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
 	 acquire-worker.cc acquire-method.cc init.cc clean.cc \
 	 acquire-worker.cc acquire-method.cc init.cc clean.cc \
 	 srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
 	 srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
 	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
 	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
-	 indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc
+	 indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
+	 aptconfiguration.cc
 HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
 HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
 	  orderlist.h sourcelist.h packagemanager.h tagfile.h \
 	  orderlist.h sourcelist.h packagemanager.h tagfile.h \
 	  init.h pkgcache.h version.h progress.h pkgrecords.h \
 	  init.h pkgcache.h version.h progress.h pkgrecords.h \
 	  acquire.h acquire-worker.h acquire-item.h acquire-method.h \
 	  acquire.h acquire-worker.h acquire-item.h acquire-method.h \
 	  clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
 	  clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
 	  pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
 	  pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
-          vendorlist.h cdrom.h indexcopy.h
+          vendorlist.h cdrom.h indexcopy.h aptconfiguration.h
 
 
 # Source code for the debian specific components
 # Source code for the debian specific components
 # In theory the deb headers do not need to be exported..
 # In theory the deb headers do not need to be exported..

+ 7 - 1
apt-pkg/metaindex.h

@@ -39,7 +39,13 @@ class metaIndex
    virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; 
    virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; 
    virtual bool IsTrusted() const = 0;
    virtual bool IsTrusted() const = 0;
 
 
-   virtual ~metaIndex() {};
+   virtual ~metaIndex() {
+      if (Indexes == 0)
+	 return;
+      for (vector<pkgIndexFile *>::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I)
+	 delete *I;
+      delete Indexes;
+   }
 };
 };
 
 
 #endif
 #endif

+ 44 - 29
apt-pkg/orderlist.cc

@@ -129,7 +129,6 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // OrderList::DoRun - Does an order run					/*{{{*/
 // OrderList::DoRun - Does an order run					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* The caller is expeted to have setup the desired probe state */
 /* The caller is expeted to have setup the desired probe state */
@@ -175,22 +174,35 @@ bool pkgOrderList::DoRun()
 bool pkgOrderList::OrderCritical()
 bool pkgOrderList::OrderCritical()
 {
 {
    FileList = 0;
    FileList = 0;
-   
-   Primary = &pkgOrderList::DepUnPackPre;
+
+   Primary = &pkgOrderList::DepUnPackPreD;
    Secondary = 0;
    Secondary = 0;
    RevDepends = 0;
    RevDepends = 0;
    Remove = 0;
    Remove = 0;
    LoopCount = 0;
    LoopCount = 0;
-   
+
    // Sort
    // Sort
    Me = this;
    Me = this;
-   qsort(List,End - List,sizeof(*List),&OrderCompareB);   
-   
+   qsort(List,End - List,sizeof(*List),&OrderCompareB);
+
    if (DoRun() == false)
    if (DoRun() == false)
       return false;
       return false;
-   
+
    if (LoopCount != 0)
    if (LoopCount != 0)
       return _error->Error("Fatal, predepends looping detected");
       return _error->Error("Fatal, predepends looping detected");
+
+   if (Debug == true)
+   {
+      clog << "** Critical Unpack ordering done" << endl;
+
+      for (iterator I = List; I != End; I++)
+      {
+	 PkgIterator P(Cache,*I);
+	 if (IsNow(P) == true)
+	    clog << "  " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+      }
+   }
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -206,7 +218,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
    if (FileList != 0)
    if (FileList != 0)
    {
    {
       WipeFlags(After);
       WipeFlags(After);
-      
+
       // Set the inlist flag
       // Set the inlist flag
       for (iterator I = List; I != End; I++)
       for (iterator I = List; I != End; I++)
       {
       {
@@ -215,7 +227,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
 	     Flag(*I,After);
 	     Flag(*I,After);
       }
       }
    }
    }
-   
+
    Primary = &pkgOrderList::DepUnPackCrit;
    Primary = &pkgOrderList::DepUnPackCrit;
    Secondary = &pkgOrderList::DepConfigure;
    Secondary = &pkgOrderList::DepConfigure;
    RevDepends = &pkgOrderList::DepUnPackDep;
    RevDepends = &pkgOrderList::DepUnPackDep;
@@ -230,7 +242,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
       clog << "** Pass A" << endl;
       clog << "** Pass A" << endl;
    if (DoRun() == false)
    if (DoRun() == false)
       return false;
       return false;
-   
+
    if (Debug == true)
    if (Debug == true)
       clog << "** Pass B" << endl;
       clog << "** Pass B" << endl;
    Secondary = 0;
    Secondary = 0;
@@ -244,7 +256,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
    Remove = 0;             // Otherwise the libreadline remove problem occures
    Remove = 0;             // Otherwise the libreadline remove problem occures
    if (DoRun() == false)
    if (DoRun() == false)
       return false;
       return false;
-      
+
    if (Debug == true)
    if (Debug == true)
       clog << "** Pass D" << endl;
       clog << "** Pass D" << endl;
    LoopCount = 0;
    LoopCount = 0;
@@ -260,9 +272,9 @@ bool pkgOrderList::OrderUnpack(string *FileList)
       {
       {
 	 PkgIterator P(Cache,*I);
 	 PkgIterator P(Cache,*I);
 	 if (IsNow(P) == true)
 	 if (IsNow(P) == true)
-	    clog << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+	    clog << "  " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
       }
       }
-   }   
+   }
 
 
    return true;
    return true;
 }
 }
@@ -282,35 +294,40 @@ bool pkgOrderList::OrderConfigure()
    return DoRun();
    return DoRun();
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // OrderList::Score - Score the package for sorting			/*{{{*/
 // OrderList::Score - Score the package for sorting			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Higher scores order earlier */
 /* Higher scores order earlier */
 int pkgOrderList::Score(PkgIterator Pkg)
 int pkgOrderList::Score(PkgIterator Pkg)
 {
 {
+   static int const ScoreDelete = _config->FindI("OrderList::Score::Delete", 500);
+
    // Removal is always done first
    // Removal is always done first
    if (Cache[Pkg].Delete() == true)
    if (Cache[Pkg].Delete() == true)
-      return 200;
-   
+      return ScoreDelete;
+
    // This should never happen..
    // This should never happen..
    if (Cache[Pkg].InstVerIter(Cache).end() == true)
    if (Cache[Pkg].InstVerIter(Cache).end() == true)
       return -1;
       return -1;
-   
+
+   static int const ScoreEssential = _config->FindI("OrderList::Score::Essential", 200);
+   static int const ScoreImmediate = _config->FindI("OrderList::Score::Immediate", 10);
+   static int const ScorePreDepends = _config->FindI("OrderList::Score::PreDepends", 50);
+
    int Score = 0;
    int Score = 0;
    if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
    if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
-      Score += 100;
+      Score += ScoreEssential;
 
 
    if (IsFlag(Pkg,Immediate) == true)
    if (IsFlag(Pkg,Immediate) == true)
-      Score += 10;
-   
-   for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); 
+      Score += ScoreImmediate;
+
+   for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
 	D.end() == false; D++)
 	D.end() == false; D++)
       if (D->Type == pkgCache::Dep::PreDepends)
       if (D->Type == pkgCache::Dep::PreDepends)
       {
       {
-	 Score += 50;
+	 Score += ScorePreDepends;
 	 break;
 	 break;
       }
       }
-      
+
    // Important Required Standard Optional Extra
    // Important Required Standard Optional Extra
    signed short PrioMap[] = {0,5,4,3,1,0};
    signed short PrioMap[] = {0,5,4,3,1,0};
    if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5)
    if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5)
@@ -388,6 +405,7 @@ int pkgOrderList::OrderCompareA(const void *a, const void *b)
    
    
    int ScoreA = Me->Score(A);
    int ScoreA = Me->Score(A);
    int ScoreB = Me->Score(B);
    int ScoreB = Me->Score(B);
+
    if (ScoreA > ScoreB)
    if (ScoreA > ScoreB)
       return -1;
       return -1;
    
    
@@ -424,6 +442,7 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b)
    
    
    int ScoreA = Me->Score(A);
    int ScoreA = Me->Score(A);
    int ScoreB = Me->Score(B);
    int ScoreB = Me->Score(B);
+
    if (ScoreA > ScoreB)
    if (ScoreA > ScoreB)
       return -1;
       return -1;
    
    
@@ -433,7 +452,6 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b)
    return strcmp(A.Name(),B.Name());
    return strcmp(A.Name(),B.Name());
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // OrderList::VisitDeps - Visit forward install dependencies		/*{{{*/
 // OrderList::VisitDeps - Visit forward install dependencies		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This calls the dependency function for the normal forwards dependencies
 /* This calls the dependency function for the normal forwards dependencies
@@ -590,7 +608,6 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // OrderList::DepUnPackCrit - Critical UnPacking ordering		/*{{{*/
 // OrderList::DepUnPackCrit - Critical UnPacking ordering		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Critical unpacking ordering strives to satisfy Conflicts: and 
 /* Critical unpacking ordering strives to satisfy Conflicts: and 
@@ -668,13 +685,12 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
    }   
    }   
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends	/*{{{*/
 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Critical PreDepends (also configure immediate and essential) strives to
 /* Critical PreDepends (also configure immediate and essential) strives to
    ensure not only that all conflicts+predepends are met but that this
    ensure not only that all conflicts+predepends are met but that this
-   package will be immediately configurable when it is unpacked. 
-
+   package will be immediately configurable when it is unpacked.
    Loops are preprocessed and logged. */
    Loops are preprocessed and logged. */
 bool pkgOrderList::DepUnPackPreD(DepIterator D)
 bool pkgOrderList::DepUnPackPreD(DepIterator D)
 {
 {
@@ -892,7 +908,6 @@ bool pkgOrderList::DepRemove(DepIterator D)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // OrderList::AddLoop - Add a loop to the loop list			/*{{{*/
 // OrderList::AddLoop - Add a loop to the loop list			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* We record the loops. This is a relic since loop breaking is done 
 /* We record the loops. This is a relic since loop breaking is done 

+ 46 - 22
apt-pkg/packagemanager.cc

@@ -26,7 +26,7 @@
 #include <apti18n.h>    
 #include <apti18n.h>    
 #include <iostream>
 #include <iostream>
 #include <fcntl.h> 
 #include <fcntl.h> 
-
+									/*}}}*/
 using namespace std;
 using namespace std;
 
 
 // PM::PackageManager - Constructor					/*{{{*/
 // PM::PackageManager - Constructor					/*{{{*/
@@ -57,7 +57,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
    if (CreateOrderList() == false)
    if (CreateOrderList() == false)
       return false;
       return false;
    
    
-   if (List->OrderUnpack() == false)
+   bool const ordering =
+	_config->FindB("PackageManager::UnpackAll",true) ?
+		List->OrderUnpack() : List->OrderCritical();
+   if (ordering == false)
       return _error->Error("Internal ordering error");
       return _error->Error("Internal ordering error");
 
 
    for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
    for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
@@ -117,13 +120,12 @@ bool pkgPackageManager::FixMissing()
    return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;   
    return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;   
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // PM::ImmediateAdd - Add the immediate flag recursivly			/*{{{*/
 // PM::ImmediateAdd - Add the immediate flag recursivly			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This adds the immediate flag to the pkg and recursively to the
 /* This adds the immediate flag to the pkg and recursively to the
    dependendies 
    dependendies 
  */
  */
-void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer)
+void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned const int &Depth)
 {
 {
    DepIterator D;
    DepIterator D;
    
    
@@ -144,15 +146,14 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer)
 	 if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
 	 if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
 	 {
 	 {
 	    if(Debug)
 	    if(Debug)
-	       clog << "ImmediateAdd(): Adding Immediate flag to " << I.Name() << endl;
+	       clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl;
 	    List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
 	    List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
-	    ImmediateAdd(D.TargetPkg(), UseInstallVer);
+	    ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
 	 }
 	 }
       }
       }
    return;
    return;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // PM::CreateOrderList - Create the ordering class			/*{{{*/
 // PM::CreateOrderList - Create the ordering class			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This populates the ordering list with all the packages that are
 /* This populates the ordering list with all the packages that are
@@ -165,7 +166,7 @@ bool pkgPackageManager::CreateOrderList()
    delete List;
    delete List;
    List = new pkgOrderList(&Cache);
    List = new pkgOrderList(&Cache);
    
    
-   bool NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
+   static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
    
    
    // Generate the list of affected packages and sort it
    // Generate the list of affected packages and sort it
    for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
@@ -268,13 +269,16 @@ bool pkgPackageManager::ConfigureAll()
    
    
    if (OList.OrderConfigure() == false)
    if (OList.OrderConfigure() == false)
       return false;
       return false;
-   
+
+   std::string const conf = _config->Find("PackageManager::Configure","all");
+   bool const ConfigurePkgs = (conf == "all");
+
    // Perform the configuring
    // Perform the configuring
    for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
    for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
    {
    {
       PkgIterator Pkg(Cache,*I);
       PkgIterator Pkg(Cache,*I);
       
       
-      if (Configure(Pkg) == false)
+      if (ConfigurePkgs == true && Configure(Pkg) == false)
 	 return false;
 	 return false;
       
       
       List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
       List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -289,20 +293,27 @@ bool pkgPackageManager::ConfigureAll()
    of it's dependents. */
    of it's dependents. */
 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
 {
 {
+   if (Debug == true)
+      clog << "SmartConfigure " << Pkg.Name() << endl;
+
    pkgOrderList OList(&Cache);
    pkgOrderList OList(&Cache);
 
 
    if (DepAdd(OList,Pkg) == false)
    if (DepAdd(OList,Pkg) == false)
       return false;
       return false;
-   
-   if (OList.OrderConfigure() == false)
-      return false;
-   
+
+   static std::string const conf = _config->Find("PackageManager::Configure","all");
+   static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
+
+   if (ConfigurePkgs == true)
+      if (OList.OrderConfigure() == false)
+	 return false;
+
    // Perform the configuring
    // Perform the configuring
    for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
    for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
    {
    {
       PkgIterator Pkg(Cache,*I);
       PkgIterator Pkg(Cache,*I);
       
       
-      if (Configure(Pkg) == false)
+      if (ConfigurePkgs == true && Configure(Pkg) == false)
 	 return false;
 	 return false;
       
       
       List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
       List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -310,8 +321,9 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
 
 
    // Sanity Check
    // Sanity Check
    if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
    if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
-      return _error->Error("Internal error, could not immediate configure %s",Pkg.Name());
-   
+      return _error->Error(_("Could not perform immediate configuration on '%s'."
+			"Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -463,7 +475,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
       List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
       List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
       if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
       if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
 	 if (SmartConfigure(Pkg) == false)
 	 if (SmartConfigure(Pkg) == false)
-	    return _error->Error("Internal Error, Could not perform immediate configuration (1) on %s",Pkg.Name());
+	    return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'."
+			"Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
       return true;
       return true;
    }
    }
 
 
@@ -479,6 +492,9 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
       
       
       while (End->Type == pkgCache::Dep::PreDepends)
       while (End->Type == pkgCache::Dep::PreDepends)
       {
       {
+	 if (Debug == true)
+	    clog << "PreDepends order for " << Pkg.Name() << std::endl;
+
 	 // Look for possible ok targets.
 	 // Look for possible ok targets.
 	 SPtrArray<Version *> VList = Start.AllTargets();
 	 SPtrArray<Version *> VList = Start.AllTargets();
 	 bool Bad = true;
 	 bool Bad = true;
@@ -492,6 +508,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
 		Pkg.State() == PkgIterator::NeedsNothing)
 		Pkg.State() == PkgIterator::NeedsNothing)
 	    {
 	    {
 	       Bad = false;
 	       Bad = false;
+	       if (Debug == true)
+		  clog << "Found ok package " << Pkg.Name() << endl;
 	       continue;
 	       continue;
 	    }
 	    }
 	 }
 	 }
@@ -507,6 +525,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
 		(Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
 		(Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
 	       continue;
 	       continue;
 
 
+	    if (Debug == true)
+	       clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
 	    Bad = !SmartConfigure(Pkg);
 	    Bad = !SmartConfigure(Pkg);
 	 }
 	 }
 
 
@@ -563,7 +583,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
    // Perform immedate configuration of the package.
    // Perform immedate configuration of the package.
    if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
    if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
       if (SmartConfigure(Pkg) == false)
       if (SmartConfigure(Pkg) == false)
-	 return _error->Error("Internal Error, Could not perform immediate configuration (2) on %s",Pkg.Name());
+	 return _error->Error(_("Could not perform immediate configuration on '%s'."
+			"Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
    
    
    return true;
    return true;
 }
 }
@@ -579,9 +600,12 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
    Reset();
    Reset();
    
    
    if (Debug == true)
    if (Debug == true)
-      clog << "Begining to order" << endl;
+      clog << "Beginning to order" << endl;
 
 
-   if (List->OrderUnpack(FileNames) == false)
+   bool const ordering =
+	_config->FindB("PackageManager::UnpackAll",true) ?
+		List->OrderUnpack(FileNames) : List->OrderCritical();
+   if (ordering == false)
    {
    {
       _error->Error("Internal ordering error");
       _error->Error("Internal ordering error");
       return Failed;
       return Failed;
@@ -634,7 +658,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
 	    return Failed;
 	    return Failed;
       DoneSomething = true;
       DoneSomething = true;
    }
    }
-   
+
    // Final run through the configure phase
    // Final run through the configure phase
    if (ConfigureAll() == false)
    if (ConfigureAll() == false)
       return Failed;
       return Failed;

+ 1 - 1
apt-pkg/packagemanager.h

@@ -49,7 +49,7 @@ class pkgPackageManager : protected pkgCache::Namespace
    bool Debug;
    bool Debug;
          
          
    bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0);
    bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0);
-   void ImmediateAdd(PkgIterator P, bool UseInstallVer);
+   void ImmediateAdd(PkgIterator P, bool UseInstallVer, unsigned const int &Depth = 0);
    virtual OrderResult OrderInstall();
    virtual OrderResult OrderInstall();
    bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver);
    bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver);
    bool CreateOrderList();
    bool CreateOrderList();

+ 61 - 8
apt-pkg/pkgcache.cc

@@ -21,6 +21,7 @@
 									/*}}}*/
 									/*}}}*/
 // Include Files							/*{{{*/
 // Include Files							/*{{{*/
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
+#include <apt-pkg/policy.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
@@ -49,7 +50,7 @@ pkgCache::Header::Header()
    
    
    /* Whenever the structures change the major version should be bumped,
    /* Whenever the structures change the major version should be bumped,
       whenever the generator changes the minor version should be bumped. */
       whenever the generator changes the minor version should be bumped. */
-   MajorVersion = 7;
+   MajorVersion = 8;
    MinorVersion = 0;
    MinorVersion = 0;
    Dirty = false;
    Dirty = false;
    
    
@@ -223,7 +224,7 @@ const char *pkgCache::DepType(unsigned char Type)
 {
 {
    const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
    const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
                           _("Recommends"),_("Conflicts"),_("Replaces"),
                           _("Recommends"),_("Conflicts"),_("Replaces"),
-                          _("Obsoletes"),_("Breaks")};
+                          _("Obsoletes"),_("Breaks"), _("Enhances")};
    if (Type < sizeof(Types)/sizeof(*Types))
    if (Type < sizeof(Types)/sizeof(*Types))
       return Types[Type];
       return Types[Type];
    return "";
    return "";
@@ -274,13 +275,13 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
       return NeedsUnpack;
       return NeedsUnpack;
    
    
    if (Pkg->CurrentState == pkgCache::State::UnPacked ||
    if (Pkg->CurrentState == pkgCache::State::UnPacked ||
-       Pkg->CurrentState == pkgCache::State::HalfConfigured ||
-      //we don't need to care for triggers awaiting packages
-      //dpkg will deal with them automatically when the 
-      //trigger pending action is run (those packages are usually
-      //in half-configured or triggers-pending state)
+       Pkg->CurrentState == pkgCache::State::HalfConfigured)
+      // we leave triggers alone complettely. dpkg deals with
+      // them in a hard-to-predict manner and if they get 
+      // resolved by dpkg before apt run dpkg --configure on 
+      // the TriggersPending package dpkg returns a error
       //Pkg->CurrentState == pkgCache::State::TriggersAwaited
       //Pkg->CurrentState == pkgCache::State::TriggersAwaited
-       Pkg->CurrentState == pkgCache::State::TriggersPending)
+      //Pkg->CurrentState == pkgCache::State::TriggersPending)
       return NeedsConfigure;
       return NeedsConfigure;
    
    
    if (Pkg->CurrentState == pkgCache::State::HalfInstalled ||
    if (Pkg->CurrentState == pkgCache::State::HalfInstalled ||
@@ -290,6 +291,56 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
    return NeedsNothing;
    return NeedsNothing;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// PkgIterator::CandVersion - Returns the candidate version string	/*{{{*/
+// ---------------------------------------------------------------------
+/* Return string representing of the candidate version. */
+const char *
+pkgCache::PkgIterator::CandVersion() const 
+{
+  //TargetVer is empty, so don't use it.
+  VerIterator version = pkgPolicy::pkgPolicy(Owner).GetCandidateVer(*this);
+  if (version.IsGood())
+    return version.VerStr();
+  return 0;
+};
+									/*}}}*/
+// PkgIterator::CurVersion - Returns the current version string		/*{{{*/
+// ---------------------------------------------------------------------
+/* Return string representing of the current version. */
+const char *
+pkgCache::PkgIterator::CurVersion() const 
+{
+  VerIterator version = CurrentVer();
+  if (version.IsGood())
+    return CurrentVer().VerStr();
+  return 0;
+};
+									/*}}}*/
+// ostream operator to handle string representation of a package	/*{{{*/
+// ---------------------------------------------------------------------
+/* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section)
+   Note that the characters <|>() are all literal above. Versions will be ommited
+   if they provide no new information (e.g. there is no newer version than candidate)
+   If no version and/or section can be found "none" is used. */
+std::ostream& 
+operator<<(ostream& out, pkgCache::PkgIterator Pkg) 
+{
+   if (Pkg.end() == true)
+      return out << "invalid package";
+
+   string current = string(Pkg.CurVersion() == 0 ? "none" : Pkg.CurVersion());
+   string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
+   string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
+
+   out << Pkg.Name() << " < " << current;
+   if (current != candidate)
+      out << " -> " << candidate;
+   if ( newest != "none" && candidate != newest)
+      out << " | " << newest;
+   out << " > ( " << string(Pkg.Section()==0?"none":Pkg.Section()) << " )";
+   return out;
+}
+									/*}}}*/
 // DepIterator::IsCritical - Returns true if the dep is important	/*{{{*/
 // DepIterator::IsCritical - Returns true if the dep is important	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Currently critical deps are defined as depends, predepends and
 /* Currently critical deps are defined as depends, predepends and
@@ -607,6 +658,8 @@ string pkgCache::PkgFileIterator::RelStr()
       Res = Res + (Res.empty() == true?"o=":",o=")  + Origin();
       Res = Res + (Res.empty() == true?"o=":",o=")  + Origin();
    if (Archive() != 0)
    if (Archive() != 0)
       Res = Res + (Res.empty() == true?"a=":",a=")  + Archive();
       Res = Res + (Res.empty() == true?"a=":",a=")  + Archive();
+   if (Codename() != 0)
+      Res = Res + (Res.empty() == true?"n=":",n=")  + Codename();
    if (Label() != 0)
    if (Label() != 0)
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
    if (Component() != 0)
    if (Component() != 0)

+ 26 - 25
apt-pkg/pkgcache.h

@@ -27,7 +27,7 @@
 using std::string;
 using std::string;
     
     
 class pkgVersioningSystem;
 class pkgVersioningSystem;
-class pkgCache
+class pkgCache								/*{{{*/
 {
 {
    public:
    public:
    // Cache element predeclarations
    // Cache element predeclarations
@@ -70,7 +70,7 @@ class pkgCache
    struct Dep
    struct Dep
    {
    {
       enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4,
       enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4,
-	 Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8};
+	 Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8,Enhances=9};
       enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
       enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
 	 Greater=0x4,Equals=0x5,NotEquals=0x6};
 	 Greater=0x4,Equals=0x5,NotEquals=0x6};
    };
    };
@@ -146,8 +146,8 @@ class pkgCache
    pkgCache(MMap *Map,bool DoMap = true);
    pkgCache(MMap *Map,bool DoMap = true);
    virtual ~pkgCache() {};
    virtual ~pkgCache() {};
 };
 };
-
-// Header structure
+									/*}}}*/
+// Header structure							/*{{{*/
 struct pkgCache::Header
 struct pkgCache::Header
 {
 {
    // Signature information
    // Signature information
@@ -195,8 +195,8 @@ struct pkgCache::Header
    bool CheckSizes(Header &Against) const;
    bool CheckSizes(Header &Against) const;
    Header();
    Header();
 };
 };
-
-struct pkgCache::Package
+									/*}}}*/
+struct pkgCache::Package						/*{{{*/
 {
 {
    // Pointers
    // Pointers
    map_ptrloc Name;              // Stringtable
    map_ptrloc Name;              // Stringtable
@@ -217,12 +217,13 @@ struct pkgCache::Package
    unsigned int ID;
    unsigned int ID;
    unsigned long Flags;
    unsigned long Flags;
 };
 };
-
-struct pkgCache::PackageFile
+									/*}}}*/
+struct pkgCache::PackageFile						/*{{{*/
 {
 {
    // Names
    // Names
    map_ptrloc FileName;        // Stringtable
    map_ptrloc FileName;        // Stringtable
    map_ptrloc Archive;         // Stringtable
    map_ptrloc Archive;         // Stringtable
+   map_ptrloc Codename;        // Stringtable
    map_ptrloc Component;       // Stringtable
    map_ptrloc Component;       // Stringtable
    map_ptrloc Version;         // Stringtable
    map_ptrloc Version;         // Stringtable
    map_ptrloc Origin;          // Stringtable
    map_ptrloc Origin;          // Stringtable
@@ -238,24 +239,24 @@ struct pkgCache::PackageFile
    unsigned int ID;
    unsigned int ID;
    time_t mtime;                  // Modification time for the file
    time_t mtime;                  // Modification time for the file
 };
 };
-
-struct pkgCache::VerFile
+									/*}}}*/
+struct pkgCache::VerFile						/*{{{*/
 {
 {
    map_ptrloc File;           // PackageFile
    map_ptrloc File;           // PackageFile
    map_ptrloc NextFile;       // PkgVerFile
    map_ptrloc NextFile;       // PkgVerFile
    map_ptrloc Offset;         // File offset
    map_ptrloc Offset;         // File offset
    unsigned short Size;
    unsigned short Size;
 };
 };
-
-struct pkgCache::DescFile
+									/*}}}*/
+struct pkgCache::DescFile						/*{{{*/
 {
 {
    map_ptrloc File;           // PackageFile
    map_ptrloc File;           // PackageFile
    map_ptrloc NextFile;       // PkgVerFile
    map_ptrloc NextFile;       // PkgVerFile
    map_ptrloc Offset;         // File offset
    map_ptrloc Offset;         // File offset
    unsigned short Size;
    unsigned short Size;
 };
 };
-
-struct pkgCache::Version
+									/*}}}*/
+struct pkgCache::Version						/*{{{*/
 {
 {
    map_ptrloc VerStr;            // Stringtable
    map_ptrloc VerStr;            // Stringtable
    map_ptrloc Section;           // StringTable (StringItem)
    map_ptrloc Section;           // StringTable (StringItem)
@@ -275,8 +276,8 @@ struct pkgCache::Version
    unsigned int ID;
    unsigned int ID;
    unsigned char Priority;
    unsigned char Priority;
 };
 };
-
-struct pkgCache::Description
+									/*}}}*/
+struct pkgCache::Description						/*{{{*/
 {
 {
    // Language Code store the description translation language code. If
    // Language Code store the description translation language code. If
    // the value has a 0 lenght then this is readed using the Package
    // the value has a 0 lenght then this is readed using the Package
@@ -291,8 +292,8 @@ struct pkgCache::Description
 
 
    unsigned int ID;
    unsigned int ID;
 };
 };
-
-struct pkgCache::Dependency
+									/*}}}*/
+struct pkgCache::Dependency						/*{{{*/
 {
 {
    map_ptrloc Version;         // Stringtable
    map_ptrloc Version;         // Stringtable
    map_ptrloc Package;         // Package
    map_ptrloc Package;         // Package
@@ -305,8 +306,8 @@ struct pkgCache::Dependency
    unsigned char Type;
    unsigned char Type;
    unsigned char CompareOp;
    unsigned char CompareOp;
 };
 };
-
-struct pkgCache::Provides
+									/*}}}*/
+struct pkgCache::Provides						/*{{{*/
 {
 {
    map_ptrloc ParentPkg;        // Pacakge
    map_ptrloc ParentPkg;        // Pacakge
    map_ptrloc Version;          // Version
    map_ptrloc Version;          // Version
@@ -314,13 +315,13 @@ struct pkgCache::Provides
    map_ptrloc NextProvides;     // Provides
    map_ptrloc NextProvides;     // Provides
    map_ptrloc NextPkgProv;      // Provides
    map_ptrloc NextPkgProv;      // Provides
 };
 };
-
-struct pkgCache::StringItem
+									/*}}}*/
+struct pkgCache::StringItem						/*{{{*/
 {
 {
    map_ptrloc String;        // Stringtable
    map_ptrloc String;        // Stringtable
    map_ptrloc NextItem;      // StringItem
    map_ptrloc NextItem;      // StringItem
 };
 };
-
+									/*}}}*/
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 
 
 inline pkgCache::PkgIterator pkgCache::PkgBegin() 
 inline pkgCache::PkgIterator pkgCache::PkgBegin() 
@@ -333,7 +334,7 @@ inline pkgCache::PkgFileIterator pkgCache::FileEnd()
        {return PkgFileIterator(*this,PkgFileP);};
        {return PkgFileIterator(*this,PkgFileP);};
 
 
 // Oh I wish for Real Name Space Support
 // Oh I wish for Real Name Space Support
-class pkgCache::Namespace
+class pkgCache::Namespace						/*{{{*/
 {   
 {   
    public:
    public:
 
 
@@ -351,5 +352,5 @@ class pkgCache::Namespace
    typedef pkgCache::Dep Dep;
    typedef pkgCache::Dep Dep;
    typedef pkgCache::Flag Flag;
    typedef pkgCache::Flag Flag;
 };
 };
-
+									/*}}}*/
 #endif
 #endif

+ 23 - 19
apt-pkg/pkgcachegen.cc

@@ -53,14 +53,16 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
    {
    {
       // Setup the map interface..
       // Setup the map interface..
       Cache.HeaderP = (pkgCache::Header *)Map.Data();
       Cache.HeaderP = (pkgCache::Header *)Map.Data();
-      Map.RawAllocate(sizeof(pkgCache::Header));
+      if (Map.RawAllocate(sizeof(pkgCache::Header)) == 0 && _error->PendingError() == true)
+	 return;
+
       Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
       Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
-      
+
       // Starting header
       // Starting header
       *Cache.HeaderP = pkgCache::Header();
       *Cache.HeaderP = pkgCache::Header();
       Cache.HeaderP->VerSysName = Map.WriteString(_system->VS->Label);
       Cache.HeaderP->VerSysName = Map.WriteString(_system->VS->Label);
       Cache.HeaderP->Architecture = Map.WriteString(_config->Find("APT::Architecture"));
       Cache.HeaderP->Architecture = Map.WriteString(_config->Find("APT::Architecture"));
-      Cache.ReMap(); 
+      Cache.ReMap();
    }
    }
    else
    else
    {
    {
@@ -135,7 +137,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
  	 pkgCache::VerIterator Ver = Pkg.VersionList();
  	 pkgCache::VerIterator Ver = Pkg.VersionList();
  	 map_ptrloc *LastVer = &Pkg->VersionList;
  	 map_ptrloc *LastVer = &Pkg->VersionList;
 
 
-  	 for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) 
+	 for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
  	 {
  	 {
  	    pkgCache::DescIterator Desc = Ver.DescriptionList();
  	    pkgCache::DescIterator Desc = Ver.DescriptionList();
  	    map_ptrloc *LastDesc = &Ver->DescriptionList;
  	    map_ptrloc *LastDesc = &Ver->DescriptionList;
@@ -143,7 +145,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
 
 
 	    // don't add a new description if we have one for the given
 	    // don't add a new description if we have one for the given
 	    // md5 && language
 	    // md5 && language
- 	    for ( ; Desc.end() == false; Desc++)
+	    for ( ; Desc.end() == false; Desc++)
 	       if (MD5SumValue(Desc.md5()) == CurMd5 && 
 	       if (MD5SumValue(Desc.md5()) == CurMd5 && 
 	           Desc.LanguageCode() == List.DescriptionLanguage())
 	           Desc.LanguageCode() == List.DescriptionLanguage())
 		  duplicate=true;
 		  duplicate=true;
@@ -151,7 +153,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
 	       continue;
 	       continue;
 	    
 	    
  	    for (Desc = Ver.DescriptionList();
  	    for (Desc = Ver.DescriptionList();
-		 Desc.end() == false; 
+		 Desc.end() == false;
 		 LastDesc = &Desc->NextDesc, Desc++)
 		 LastDesc = &Desc->NextDesc, Desc++)
 	    {
 	    {
  	       if (MD5SumValue(Desc.md5()) == CurMd5) 
  	       if (MD5SumValue(Desc.md5()) == CurMd5) 
@@ -160,7 +162,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
  		  *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
  		  *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
  		  Desc->ParentPkg = Pkg.Index();
  		  Desc->ParentPkg = Pkg.Index();
 		  
 		  
- 		  if (NewFileDesc(Desc,List) == false)
+		  if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
  		     return _error->Error(_("Error occurred while processing %s (NewFileDesc1)"),PackageName.c_str());
  		     return _error->Error(_("Error occurred while processing %s (NewFileDesc1)"),PackageName.c_str());
  		  break;
  		  break;
  	       }
  	       }
@@ -220,7 +222,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
       Ver->ParentPkg = Pkg.Index();
       Ver->ParentPkg = Pkg.Index();
       Ver->Hash = Hash;
       Ver->Hash = Hash;
 
 
-      if (List.NewVersion(Ver) == false)
+      if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false)
 	 return _error->Error(_("Error occurred while processing %s (NewVersion1)"),
 	 return _error->Error(_("Error occurred while processing %s (NewVersion1)"),
 			      PackageName.c_str());
 			      PackageName.c_str());
 
 
@@ -252,7 +254,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
       *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
       *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
       Desc->ParentPkg = Pkg.Index();
       Desc->ParentPkg = Pkg.Index();
 
 
-      if (NewFileDesc(Desc,List) == false)
+      if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
 	 return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str());
 	 return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str());
    }
    }
 
 
@@ -419,7 +421,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
    // Get a structure
    // Get a structure
    unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
    unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
    if (DescFile == 0)
    if (DescFile == 0)
-      return 0;
+      return false;
 
 
    pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile);
    pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile);
    DF->File = CurrentFile - Cache.PkgFileP;
    DF->File = CurrentFile - Cache.PkgFileP;
@@ -460,6 +462,8 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
    Desc->ID = Cache.HeaderP->DescriptionCount++;
    Desc->ID = Cache.HeaderP->DescriptionCount++;
    Desc->language_code = Map.WriteString(Lang);
    Desc->language_code = Map.WriteString(Lang);
    Desc->md5sum = Map.WriteString(md5sum.Value());
    Desc->md5sum = Map.WriteString(md5sum.Value());
+   if (Desc->language_code == 0 || Desc->md5sum == 0)
+      return 0;
 
 
    return Description;
    return Description;
 }
 }
@@ -652,7 +656,6 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S,
    return ItemP->String;
    return ItemP->String;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // CheckValidity - Check that a cache is up-to-date			/*{{{*/
 // CheckValidity - Check that a cache is up-to-date			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This just verifies that each file in the list of index files exists,
 /* This just verifies that each file in the list of index files exists,
@@ -667,7 +670,7 @@ static bool CheckValidity(const string &CacheFile, FileIterator Start,
    
    
    // Map it
    // Map it
    FileFd CacheF(CacheFile,FileFd::ReadOnly);
    FileFd CacheF(CacheFile,FileFd::ReadOnly);
-   SPtr<MMap> Map = new MMap(CacheF,MMap::Public | MMap::ReadOnly);
+   SPtr<MMap> Map = new MMap(CacheF,0);
    pkgCache Cache(Map);
    pkgCache Cache(Map);
    if (_error->PendingError() == true || Map->Size() == 0)
    if (_error->PendingError() == true || Map->Size() == 0)
    {
    {
@@ -810,7 +813,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
    unsigned long EndOfSource = Files.size();
    unsigned long EndOfSource = Files.size();
    if (_system->AddStatusFiles(Files) == false)
    if (_system->AddStatusFiles(Files) == false)
       return false;
       return false;
-   
+
    // Decide if we can write to the files..
    // Decide if we can write to the files..
    string CacheFile = _config->FindFile("Dir::Cache::pkgcache");
    string CacheFile = _config->FindFile("Dir::Cache::pkgcache");
    string SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
    string SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
@@ -851,7 +854,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
    else
    else
    {
    {
       // Just build it in memory..
       // Just build it in memory..
-      Map = new DynamicMMap(MMap::Public,MapSize);
+      Map = new DynamicMMap(0,MapSize);
    }
    }
    
    
    // Lets try the source cache.
    // Lets try the source cache.
@@ -862,8 +865,10 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
    {
    {
       // Preload the map with the source cache
       // Preload the map with the source cache
       FileFd SCacheF(SrcCacheFile,FileFd::ReadOnly);
       FileFd SCacheF(SrcCacheFile,FileFd::ReadOnly);
-      if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()),
-		       SCacheF.Size()) == false)
+      unsigned long alloc = Map->RawAllocate(SCacheF.Size());
+      if ((alloc == 0 && _error->PendingError())
+		|| SCacheF.Read((unsigned char *)Map->Data() + alloc,
+				SCacheF.Size()) == false)
 	 return false;
 	 return false;
 
 
       TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end());
       TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end());
@@ -924,7 +929,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
       if (CacheF != 0)
       if (CacheF != 0)
       {
       {
 	 delete Map.UnGuard();
 	 delete Map.UnGuard();
-	 *OutMap = new MMap(*CacheF,MMap::Public | MMap::ReadOnly);
+	 *OutMap = new MMap(*CacheF,0);
       }
       }
       else
       else
       {
       {
@@ -946,8 +951,7 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap)
    if (_system->AddStatusFiles(Files) == false)
    if (_system->AddStatusFiles(Files) == false)
       return false;
       return false;
    
    
-   SPtr<DynamicMMap> Map;   
-   Map = new DynamicMMap(MMap::Public,MapSize);
+   SPtr<DynamicMMap> Map = new DynamicMMap(0,MapSize);
    unsigned long CurrentSize = 0;
    unsigned long CurrentSize = 0;
    unsigned long TotalSize = 0;
    unsigned long TotalSize = 0;
    
    

+ 4 - 4
apt-pkg/pkgcachegen.h

@@ -28,7 +28,7 @@ class OpProgress;
 class MMap;
 class MMap;
 class pkgIndexFile;
 class pkgIndexFile;
 
 
-class pkgCacheGenerator
+class pkgCacheGenerator							/*{{{*/
 {
 {
    private:
    private:
    
    
@@ -76,8 +76,8 @@ class pkgCacheGenerator
    pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
    pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
    ~pkgCacheGenerator();
    ~pkgCacheGenerator();
 };
 };
-
-// This is the abstract package list parser class.
+									/*}}}*/
+// This is the abstract package list parser class.			/*{{{*/
 class pkgCacheGenerator::ListParser
 class pkgCacheGenerator::ListParser
 {
 {
    pkgCacheGenerator *Owner;
    pkgCacheGenerator *Owner;
@@ -126,7 +126,7 @@ class pkgCacheGenerator::ListParser
    ListParser() : FoundFileDeps(false) {};
    ListParser() : FoundFileDeps(false) {};
    virtual ~ListParser() {};
    virtual ~ListParser() {};
 };
 };
-
+									/*}}}*/
 bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
 bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
 			MMap **OutMap = 0,bool AllowMem = false);
 			MMap **OutMap = 0,bool AllowMem = false);
 bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap);
 bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap);

+ 4 - 4
apt-pkg/pkgrecords.h

@@ -22,7 +22,7 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <vector>
 #include <vector>
 
 
-class pkgRecords
+class pkgRecords							/*{{{*/
 {
 {
    public:
    public:
    class Parser;
    class Parser;
@@ -42,8 +42,8 @@ class pkgRecords
    pkgRecords(pkgCache &Cache);
    pkgRecords(pkgCache &Cache);
    ~pkgRecords();
    ~pkgRecords();
 };
 };
-
-class pkgRecords::Parser
+									/*}}}*/
+class pkgRecords::Parser						/*{{{*/
 {
 {
    protected:
    protected:
    
    
@@ -73,5 +73,5 @@ class pkgRecords::Parser
    
    
    virtual ~Parser() {};
    virtual ~Parser() {};
 };
 };
-
+									/*}}}*/
 #endif
 #endif

+ 82 - 2
apt-pkg/policy.cc

@@ -32,6 +32,9 @@
     
     
 #include <apti18n.h>
 #include <apti18n.h>
 
 
+#include <dirent.h>
+#include <sys/stat.h>
+#include <algorithm>
 #include <iostream>
 #include <iostream>
 #include <sstream>
 #include <sstream>
 									/*}}}*/
 									/*}}}*/
@@ -120,6 +123,14 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg)
    signed Max = GetPriority(Pkg);
    signed Max = GetPriority(Pkg);
    pkgCache::VerIterator Pref = GetMatch(Pkg);
    pkgCache::VerIterator Pref = GetMatch(Pkg);
 
 
+   // no package = no candidate version
+   if (Pkg.end() == true)
+      return Pref;
+
+   // packages with a pin lower than 0 have no newer candidate than the current version
+   if (Max < 0)
+      return Pkg.CurrentVer();
+
    /* Falling through to the default version.. Setting Max to zero
    /* Falling through to the default version.. Setting Max to zero
       effectively excludes everything <= 0 which are the non-automatic
       effectively excludes everything <= 0 which are the non-automatic
       priorities.. The status file is given a prio of 100 which will exclude
       priorities.. The status file is given a prio of 100 which will exclude
@@ -239,7 +250,76 @@ signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// PreferenceSection class - Overriding the default TrimRecord method	/*{{{*/
+// ---------------------------------------------------------------------
+/* The preference file is a user generated file so the parser should
+   therefore be a bit more friendly by allowing comments and new lines
+   all over the place rather than forcing a special format */
+class PreferenceSection : public pkgTagSection
+{
+   void TrimRecord(bool BeforeRecord, const char* &End)
+   {
+      for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
+	 if (Stop[0] == '#')
+	    Stop = (const char*) memchr(Stop,'\n',End-Stop);
+   }
+};
+									/*}}}*/
+// ReadPinDir - Load the pin files from this dir into a Policy		/*{{{*/
+// ---------------------------------------------------------------------
+/* This will load each pin file in the given dir into a Policy. If the
+   given dir is empty the dir set in Dir::Etc::PreferencesParts is used.
+   Note also that this method will issue a warning if the dir does not
+   exists but it will return true in this case! */
+bool ReadPinDir(pkgPolicy &Plcy,string Dir)
+{
+   if (Dir.empty() == true)
+      Dir = _config->FindDir("Dir::Etc::PreferencesParts");
+
+   if (FileExists(Dir) == false)
+   {
+      _error->WarningE("FileExists",_("Unable to read %s"),Dir.c_str());
+      return true;
+   }
+
+   DIR *D = opendir(Dir.c_str());
+   if (D == 0)
+      return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
+
+   vector<string> List;
 
 
+   for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
+   {
+      if (Ent->d_name[0] == '.')
+	 continue;
+
+      // Skip bad file names ala run-parts
+      const char *C = Ent->d_name;
+      for (; *C != 0; C++)
+	 if (isalpha(*C) == 0 && isdigit(*C) == 0 && *C != '_' && *C != '-')
+	    break;
+      if (*C != 0)
+	 continue;
+
+      // Make sure it is a file and not something else
+      string File = flCombine(Dir,Ent->d_name);
+      struct stat St;
+      if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0)
+	 continue;
+
+      List.push_back(File);
+   }
+   closedir(D);
+
+   sort(List.begin(),List.end());
+
+   // Read the files
+   for (vector<string>::const_iterator I = List.begin(); I != List.end(); I++)
+      if (ReadPinFile(Plcy, *I) == false)
+	 return false;
+   return true;
+}
+									/*}}}*/
 // ReadPinFile - Load the pin file into a Policy			/*{{{*/
 // ReadPinFile - Load the pin file into a Policy			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* I'd like to see the preferences file store more than just pin information
 /* I'd like to see the preferences file store more than just pin information
@@ -259,12 +339,12 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return false;
       return false;
    
    
-   pkgTagSection Tags;
+   PreferenceSection Tags;
    while (TF.Step(Tags) == true)
    while (TF.Step(Tags) == true)
    {
    {
       string Name = Tags.FindS("Package");
       string Name = Tags.FindS("Package");
       if (Name.empty() == true)
       if (Name.empty() == true)
-	 return _error->Error(_("Invalid record in the preferences file, no Package header"));
+	 return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str());
       if (Name == "*")
       if (Name == "*")
 	 Name = string();
 	 Name = string();
       
       

+ 1 - 0
apt-pkg/policy.h

@@ -84,5 +84,6 @@ class pkgPolicy : public pkgDepCache::Policy
 };
 };
 
 
 bool ReadPinFile(pkgPolicy &Plcy,string File = "");
 bool ReadPinFile(pkgPolicy &Plcy,string File = "");
+bool ReadPinDir(pkgPolicy &Plcy,string Dir = "");
 
 
 #endif
 #endif

+ 10 - 3
apt-pkg/sourcelist.cc

@@ -157,13 +157,20 @@ bool pkgSourceList::ReadMainList()
    // CNC:2003-11-28 - Entries in sources.list have priority over
    // CNC:2003-11-28 - Entries in sources.list have priority over
    //                  entries in sources.list.d.
    //                  entries in sources.list.d.
    string Main = _config->FindFile("Dir::Etc::sourcelist");
    string Main = _config->FindFile("Dir::Etc::sourcelist");
+   string Parts = _config->FindDir("Dir::Etc::sourceparts");
+   
    if (FileExists(Main) == true)
    if (FileExists(Main) == true)
-      Res &= ReadAppend(Main);   
+      Res &= ReadAppend(Main);
+   else if (FileExists(Parts) == false)
+      // Only warn if there are no sources.list.d.
+      _error->WarningE("FileExists",_("Unable to read %s"),Main.c_str());
 
 
-   string Parts = _config->FindDir("Dir::Etc::sourceparts");
    if (FileExists(Parts) == true)
    if (FileExists(Parts) == true)
       Res &= ReadSourceDir(Parts);
       Res &= ReadSourceDir(Parts);
-   
+   else if (FileExists(Main) == false)
+      // Only warn if there is no sources.list file.
+      _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str());
+
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 16 - 5
apt-pkg/tagfile.cc

@@ -81,7 +81,7 @@ bool pkgTagFile::Resize()
    End = Start + EndSize;
    End = Start + EndSize;
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 // TagFile::Step - Advance to the next section				/*{{{*/
 // TagFile::Step - Advance to the next section				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* If the Section Scanner fails we refill the buffer and try again. 
 /* If the Section Scanner fails we refill the buffer and try again. 
@@ -212,10 +212,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
 
 
    if (Stop == 0)
    if (Stop == 0)
       return false;
       return false;
-   
+
    TagCount = 0;
    TagCount = 0;
    while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End)
    while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End)
    {
    {
+       TrimRecord(true,End);
+
       // Start a new index and add it to the hash
       // Start a new index and add it to the hash
       if (isspace(Stop[0]) == 0)
       if (isspace(Stop[0]) == 0)
       {
       {
@@ -227,14 +229,14 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
       
       
       if (Stop == 0)
       if (Stop == 0)
 	 return false;
 	 return false;
-      
+
       for (; Stop+1 < End && Stop[1] == '\r'; Stop++);
       for (; Stop+1 < End && Stop[1] == '\r'; Stop++);
 
 
       // Double newline marks the end of the record
       // Double newline marks the end of the record
       if (Stop+1 < End && Stop[1] == '\n')
       if (Stop+1 < End && Stop[1] == '\n')
       {
       {
 	 Indexes[TagCount] = Stop - Section;
 	 Indexes[TagCount] = Stop - Section;
-	 for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
+	 TrimRecord(false,End);
 	 return true;
 	 return true;
       }
       }
       
       
@@ -244,6 +246,16 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// TagSection::TrimRecord - Trim off any garbage before/after a record	/*{{{*/
+// ---------------------------------------------------------------------
+/* There should be exactly 2 newline at the end of the record, no more. */
+void pkgTagSection::TrimRecord(bool BeforeRecord, const char*& End)
+{
+   if (BeforeRecord == true)
+      return;
+   for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
+}
+									/*}}}*/
 // TagSection::Trim - Trim off any trailing garbage			/*{{{*/
 // TagSection::Trim - Trim off any trailing garbage			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* There should be exactly 1 newline at the end of the buffer, no more. */
 /* There should be exactly 1 newline at the end of the buffer, no more. */
@@ -390,7 +402,6 @@ bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags,
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // TFRewrite - Rewrite a control record					/*{{{*/
 // TFRewrite - Rewrite a control record					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This writes the control record to stdout rewriting it as necessary. The
 /* This writes the control record to stdout rewriting it as necessary. The

+ 4 - 1
apt-pkg/tagfile.h

@@ -27,7 +27,6 @@
 class pkgTagSection
 class pkgTagSection
 {
 {
    const char *Section;
    const char *Section;
-   const char *Stop;
    
    
    // We have a limit of 256 tags per section.
    // We have a limit of 256 tags per section.
    unsigned int Indexes[256];
    unsigned int Indexes[256];
@@ -35,6 +34,9 @@ class pkgTagSection
    
    
    unsigned int TagCount;
    unsigned int TagCount;
      
      
+   protected:
+   const char *Stop;
+
    public:
    public:
    
    
    inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
    inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
@@ -49,6 +51,7 @@ class pkgTagSection
    bool Scan(const char *Start,unsigned long MaxLength);
    bool Scan(const char *Start,unsigned long MaxLength);
    inline unsigned long size() const {return Stop - Section;};
    inline unsigned long size() const {return Stop - Section;};
    void Trim();
    void Trim();
+   virtual void TrimRecord(bool BeforeRecord, const char* &End);
    
    
    inline unsigned int Count() const {return TagCount;};
    inline unsigned int Count() const {return TagCount;};
    inline void Get(const char *&Start,const char *&Stop,unsigned int I) const
    inline void Get(const char *&Start,const char *&Stop,unsigned int I) const

+ 10 - 9
apt-pkg/vendorlist.cc

@@ -10,7 +10,7 @@ pkgVendorList::~pkgVendorList()
       delete *I;
       delete *I;
 }
 }
 
 
-// pkgVendorList::ReadMainList - Read list of known package vendors		/*{{{*/
+// pkgVendorList::ReadMainList - Read list of known package vendors	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This also scans a directory of vendor files similar to apt.conf.d 
 /* This also scans a directory of vendor files similar to apt.conf.d 
    which can contain the usual suspects of distribution provided data.
    which can contain the usual suspects of distribution provided data.
@@ -31,8 +31,8 @@ bool pkgVendorList::ReadMainList()
 
 
    return CreateList(Cnf);
    return CreateList(Cnf);
 }
 }
-
-bool pkgVendorList::Read(string File)
+									/*}}}*/
+bool pkgVendorList::Read(string File)					/*{{{*/
 {
 {
    Configuration Cnf;
    Configuration Cnf;
    if (ReadConfigFile(Cnf,File,true) == false)
    if (ReadConfigFile(Cnf,File,true) == false)
@@ -40,8 +40,8 @@ bool pkgVendorList::Read(string File)
 
 
    return CreateList(Cnf);
    return CreateList(Cnf);
 }
 }
-
-bool pkgVendorList::CreateList(Configuration& Cnf)
+									/*}}}*/
+bool pkgVendorList::CreateList(Configuration& Cnf)			/*{{{*/
 {
 {
    for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
    for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
 	I != VendorList.end(); I++)
 	I != VendorList.end(); I++)
@@ -110,8 +110,8 @@ bool pkgVendorList::CreateList(Configuration& Cnf)
    
    
    return !_error->PendingError();
    return !_error->PendingError();
 }
 }
-
-const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint)
+									/*}}}*/
+const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint)	/*{{{*/
 {
 {
    for (const_iterator I = VendorList.begin(); I != VendorList.end(); ++I)
    for (const_iterator I = VendorList.begin(); I != VendorList.end(); ++I)
    {
    {
@@ -121,8 +121,8 @@ const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint)
 
 
    return NULL;
    return NULL;
 }
 }
-
-const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)
+									/*}}}*/
+const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)	/*{{{*/
 {
 {
    for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
    for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
    {
    {
@@ -142,3 +142,4 @@ const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)
 
 
    return NULL;
    return NULL;
 }
 }
+									/*}}}*/

+ 24 - 13
apt-pkg/versionmatch.cc

@@ -63,8 +63,8 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
 	 if (isdigit(Data[0]))
 	 if (isdigit(Data[0]))
 	    RelVerStr = Data;
 	    RelVerStr = Data;
 	 else
 	 else
-	    RelArchive = Data;
-	 
+	    RelRelease = Data;
+
 	 if (RelVerStr.length() > 0 && RelVerStr.end()[-1] == '*')
 	 if (RelVerStr.length() > 0 && RelVerStr.end()[-1] == '*')
 	 {
 	 {
 	    RelVerPrefixMatch = true;
 	    RelVerPrefixMatch = true;
@@ -87,19 +87,21 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
       {
       {
 	 if (strlen(Fragments[J]) < 3)
 	 if (strlen(Fragments[J]) < 3)
 	    continue;
 	    continue;
-	    
+
 	 if (stringcasecmp(Fragments[J],Fragments[J]+2,"v=") == 0)
 	 if (stringcasecmp(Fragments[J],Fragments[J]+2,"v=") == 0)
 	    RelVerStr = Fragments[J]+2;
 	    RelVerStr = Fragments[J]+2;
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"o=") == 0)
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"o=") == 0)
 	    RelOrigin = Fragments[J]+2;
 	    RelOrigin = Fragments[J]+2;
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"a=") == 0)
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"a=") == 0)
 	    RelArchive = Fragments[J]+2;
 	    RelArchive = Fragments[J]+2;
+	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"n=") == 0)
+	    RelCodename = Fragments[J]+2;
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"l=") == 0)
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"l=") == 0)
 	    RelLabel = Fragments[J]+2;
 	    RelLabel = Fragments[J]+2;
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
 	    RelComponent = Fragments[J]+2;
 	    RelComponent = Fragments[J]+2;
       }
       }
-      
+
       if (RelVerStr.end()[-1] == '*')
       if (RelVerStr.end()[-1] == '*')
       {
       {
 	 RelVerPrefixMatch = true;
 	 RelVerPrefixMatch = true;
@@ -169,15 +171,16 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
    {
    {
       if (MatchAll == true)
       if (MatchAll == true)
 	 return true;
 	 return true;
-      
+
 /*      cout << RelVerStr << ',' << RelOrigin << ',' << RelArchive << ',' << RelLabel << endl;
 /*      cout << RelVerStr << ',' << RelOrigin << ',' << RelArchive << ',' << RelLabel << endl;
       cout << File.Version() << ',' << File.Origin() << ',' << File.Archive() << ',' << File.Label() << endl;*/
       cout << File.Version() << ',' << File.Origin() << ',' << File.Archive() << ',' << File.Label() << endl;*/
-      
+
       if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
       if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
 	  RelArchive.empty() == true && RelLabel.empty() == true &&
 	  RelArchive.empty() == true && RelLabel.empty() == true &&
+	  RelRelease.empty() == true && RelCodename.empty() == true &&
 	  RelComponent.empty() == true)
 	  RelComponent.empty() == true)
 	 return false;
 	 return false;
-      
+
       if (RelVerStr.empty() == false)
       if (RelVerStr.empty() == false)
 	 if (File->Version == 0 ||
 	 if (File->Version == 0 ||
 	     MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false)
 	     MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false)
@@ -187,11 +190,19 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
 	     stringcasecmp(RelOrigin,File.Origin()) != 0)
 	     stringcasecmp(RelOrigin,File.Origin()) != 0)
 	    return false;
 	    return false;
       if (RelArchive.empty() == false)
       if (RelArchive.empty() == false)
-      {
-	 if (File->Archive == 0 || 
+	 if (File->Archive == 0 ||
 	     stringcasecmp(RelArchive,File.Archive()) != 0)
 	     stringcasecmp(RelArchive,File.Archive()) != 0)
-	    return false;
-      }      
+            return false;
+      if (RelCodename.empty() == false)
+	 if (File->Codename == 0 ||
+	     stringcasecmp(RelCodename,File.Codename()) != 0)
+            return false;
+      if (RelRelease.empty() == false)
+	 if ((File->Archive == 0 ||
+	     stringcasecmp(RelRelease,File.Archive()) != 0) &&
+             (File->Codename == 0 ||
+	      stringcasecmp(RelRelease,File.Codename()) != 0))
+	       return false;
       if (RelLabel.empty() == false)
       if (RelLabel.empty() == false)
 	 if (File->Label == 0 ||
 	 if (File->Label == 0 ||
 	     stringcasecmp(RelLabel,File.Label()) != 0)
 	     stringcasecmp(RelLabel,File.Label()) != 0)
@@ -202,7 +213,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
 	    return false;
 	    return false;
       return true;
       return true;
    }
    }
-   
+
    if (Type == Origin)
    if (Type == Origin)
    {
    {
       if (OrSite.empty() == false) {
       if (OrSite.empty() == false) {
@@ -213,7 +224,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
 	    return false;
 	    return false;
       return (OrSite == File.Site());		/* both strings match */
       return (OrSite == File.Site());		/* both strings match */
    }
    }
-   
+
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 13 - 8
apt-pkg/versionmatch.h

@@ -3,29 +3,32 @@
 // $Id: versionmatch.h,v 1.4 2001/05/29 03:07:12 jgg Exp $
 // $Id: versionmatch.h,v 1.4 2001/05/29 03:07:12 jgg Exp $
 /* ######################################################################
 /* ######################################################################
 
 
-   Version Matching 
-   
+   Version Matching
+
    This module takes a matching string and a type and locates the version
    This module takes a matching string and a type and locates the version
    record that satisfies the constraint described by the matching string.
    record that satisfies the constraint described by the matching string.
 
 
      Version: 1.2*
      Version: 1.2*
      Release: o=Debian,v=2.1*,c=main
      Release: o=Debian,v=2.1*,c=main
      Release: v=2.1*
      Release: v=2.1*
+     Release: a=testing
+     Release: n=squeeze
      Release: *
      Release: *
      Origin: ftp.debian.org
      Origin: ftp.debian.org
-   
+
    Release may be a complex type that can specify matches for any of:
    Release may be a complex type that can specify matches for any of:
       Version (v= with prefix)
       Version (v= with prefix)
       Origin (o=)
       Origin (o=)
-      Archive (a=)
+      Archive (a=) eg, unstable, testing, stable
+      Codename (n=) e.g. etch, lenny, squeeze, sid
       Label (l=)
       Label (l=)
       Component (c=)
       Component (c=)
    If there are no equals signs in the string then it is scanned in short
    If there are no equals signs in the string then it is scanned in short
-   form - if it starts with a number it is Version otherwise it is an 
-   Archive.
-   
+   form - if it starts with a number it is Version otherwise it is an
+   Archive or a Codename.
+
    Release may be a '*' to match all releases.
    Release may be a '*' to match all releases.
-   
+
    ##################################################################### */
    ##################################################################### */
 									/*}}}*/
 									/*}}}*/
 #ifndef PKGLIB_VERSIONMATCH_H
 #ifndef PKGLIB_VERSIONMATCH_H
@@ -47,6 +50,8 @@ class pkgVersionMatch
    string RelVerStr;
    string RelVerStr;
    bool RelVerPrefixMatch;
    bool RelVerPrefixMatch;
    string RelOrigin;
    string RelOrigin;
+   string RelRelease;
+   string RelCodename;
    string RelArchive;
    string RelArchive;
    string RelLabel;
    string RelLabel;
    string RelComponent;
    string RelComponent;

Разница между файлами не показана из-за своего большого размера
+ 0 - 1526
buildlib/config.guess


+ 1 - 0
buildlib/config.h.in

@@ -22,6 +22,7 @@
 /* These two are used by the statvfs shim for glibc2.0 and bsd */
 /* These two are used by the statvfs shim for glibc2.0 and bsd */
 /* Define if we have sys/vfs.h */
 /* Define if we have sys/vfs.h */
 #undef HAVE_VFS_H
 #undef HAVE_VFS_H
+#undef HAVE_STRUCT_STATFS_F_TYPE
 
 
 /* Define if we have sys/mount.h */
 /* Define if we have sys/mount.h */
 #undef HAVE_MOUNT_H
 #undef HAVE_MOUNT_H

Разница между файлами не показана из-за своего большого размера
+ 0 - 1658
buildlib/config.sub


+ 7 - 1
buildlib/configure.mak

@@ -15,7 +15,13 @@ BUILDDIR=build
 .PHONY: startup
 .PHONY: startup
 startup: configure $(BUILDDIR)/config.status $(addprefix $(BUILDDIR)/,$(CONVERTED))
 startup: configure $(BUILDDIR)/config.status $(addprefix $(BUILDDIR)/,$(CONVERTED))
 
 
-configure: aclocal.m4 configure.in
+# use the files provided from the system instead of carry around
+# and use (most of the time outdated) copycats
+buildlib/config.sub:
+	ln -sf /usr/share/misc/config.sub buildlib/config.sub
+buildlib/config.guess:
+	ln -sf /usr/share/misc/config.guess buildlib/config.guess	
+configure: aclocal.m4 configure.in buildlib/config.guess buildlib/config.sub
 	autoconf
 	autoconf
 
 
 aclocal.m4: $(wildcard buildlib/*.m4)
 aclocal.m4: $(wildcard buildlib/*.m4)

+ 12 - 14
buildlib/defaults.mak

@@ -6,26 +6,26 @@
 # for it to operate as expected. When included the module generates
 # for it to operate as expected. When included the module generates
 # the requested rules based on the contents of its control variables.
 # the requested rules based on the contents of its control variables.
 
 
-# This works out very well and allows a good degree of flexability.
-# To accomidate some of the features we introduce the concept of 
+# This works out very well and allows a good degree of flexibility.
+# To accommodate some of the features we introduce the concept of 
 # local variables. To do this we use the 'Computed Names' feature of
 # local variables. To do this we use the 'Computed Names' feature of
 # gmake. Each module declares a LOCAL scope and access it with,
 # gmake. Each module declares a LOCAL scope and access it with,
 #   $($(LOCAL)-VAR)
 #   $($(LOCAL)-VAR)
-# This works very well but it is important to rembember that within
-# a rule the LOCAL var is unavailble, it will have to be constructed
-# from the information in the rule invokation. For stock rules like 
+# This works very well but it is important to remember that within
+# a rule the LOCAL var is unavailable, it will have to be constructed
+# from the information in the rule invocation. For stock rules like 
 # clean this is simple, we use a local clean rule called clean/$(LOCAL)
 # clean this is simple, we use a local clean rule called clean/$(LOCAL)
 # and then within the rule $(@F) gets back $(LOCAL)! Other rules will
 # and then within the rule $(@F) gets back $(LOCAL)! Other rules will
 # have to use some other mechanism (filter perhaps?) The reason such
 # have to use some other mechanism (filter perhaps?) The reason such
 # lengths are used is so that each directory can contain several 'instances'
 # lengths are used is so that each directory can contain several 'instances'
 # of any given module. I notice that the very latest gmake has the concept
 # of any given module. I notice that the very latest gmake has the concept
 # of local variables for rules. It is possible this feature in conjunction
 # of local variables for rules. It is possible this feature in conjunction
-# with the generated names will provide a very powerfull solution indeed!
+# with the generated names will provide a very powerful solution indeed!
 
 
 # A build directory is used by default, all generated items get put into
 # A build directory is used by default, all generated items get put into
 # there. However unlike automake this is not done with a VPATH build
 # there. However unlike automake this is not done with a VPATH build
 # (vpath builds break the distinction between #include "" and #include <>)
 # (vpath builds break the distinction between #include "" and #include <>)
-# but by explicly setting the BUILD variable. Make is invoked from
+# but by explicitly setting the BUILD variable. Make is invoked from
 # within the source itself which is much more compatible with compilation
 # within the source itself which is much more compatible with compilation
 # environments.
 # environments.
 ifndef NOISY
 ifndef NOISY
@@ -81,9 +81,7 @@ MANPAGE_H = $(BASE)/buildlib/manpage.mak
 PROGRAM_H = $(BASE)/buildlib/program.mak
 PROGRAM_H = $(BASE)/buildlib/program.mak
 PYTHON_H = $(BASE)/buildlib/python.mak
 PYTHON_H = $(BASE)/buildlib/python.mak
 COPY_H = $(BASE)/buildlib/copy.mak
 COPY_H = $(BASE)/buildlib/copy.mak
-YODL_MANPAGE_H = $(BASE)/buildlib/yodl_manpage.mak
-SGML_MANPAGE_H = $(BASE)/buildlib/sgml_manpage.mak
-XML_MANPAGE_H = $(BASE)/buildlib/xml_manpage.mak
+PO4A_MANPAGE_H = $(BASE)/buildlib/po4a_manpage.mak
 FAIL_H = $(BASE)/buildlib/fail.mak
 FAIL_H = $(BASE)/buildlib/fail.mak
 PODOMAIN_H = $(BASE)/buildlib/podomain.mak
 PODOMAIN_H = $(BASE)/buildlib/podomain.mak
 
 
@@ -99,12 +97,12 @@ endif
 
 
 # Source location control
 # Source location control
 # SUBDIRS specifies sub components of the module that
 # SUBDIRS specifies sub components of the module that
-# may be located in subdrictories of the source dir. 
+# may be located in subdirectories of the source dir. 
 # This should be declared before including this file
 # This should be declared before including this file
 SUBDIRS+=
 SUBDIRS+=
 
 
 # Header file control. 
 # Header file control. 
-# TARGETDIRS indicitates all of the locations that public headers 
+# TARGETDIRS indicates all of the locations that public headers 
 # will be published to.
 # will be published to.
 # This should be declared before including this file
 # This should be declared before including this file
 HEADER_TARGETDIRS+=
 HEADER_TARGETDIRS+=
@@ -133,7 +131,7 @@ dirs:
 	mkdir -p $(patsubst %/,%,$(sort $(MKDIRS)))
 	mkdir -p $(patsubst %/,%,$(sort $(MKDIRS)))
 
 
 # Header file control. We want all published interface headers to go
 # Header file control. We want all published interface headers to go
-# into the build directory from thier source dirs. We setup some
+# into the build directory from their source dirs. We setup some
 # search paths here
 # search paths here
 vpath %.h $(SUBDIRS)
 vpath %.h $(SUBDIRS)
 $(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) : %.h
 $(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) : %.h
@@ -142,7 +140,7 @@ $(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) :
 # Dependency generation. We want to generate a .d file using gnu cpp.
 # Dependency generation. We want to generate a .d file using gnu cpp.
 # For GNU systems the compiler can spit out a .d file while it is compiling,
 # For GNU systems the compiler can spit out a .d file while it is compiling,
 # this is specified with the INLINEDEPFLAG. Other systems might have a 
 # this is specified with the INLINEDEPFLAG. Other systems might have a 
-# makedep program that can be called after compiling, that's illistrated
+# makedep program that can be called after compiling, that's illustrated
 # by the DEPFLAG case.
 # by the DEPFLAG case.
 # Compile rules are expected to call this macro after calling the compiler
 # Compile rules are expected to call this macro after calling the compiler
 ifdef GCC3DEP
 ifdef GCC3DEP

+ 4 - 9
buildlib/environment.mak.in

@@ -9,8 +9,6 @@ CPPFLAGS+= @CPPFLAGS@ @DEFS@ -D_REENTRANT -Wall
 CXX = @CXX@
 CXX = @CXX@
 CXXFLAGS+= @CXXFLAGS@
 CXXFLAGS+= @CXXFLAGS@
 NUM_PROCS = @NUM_PROCS@
 NUM_PROCS = @NUM_PROCS@
-GLIBC_VER = @GLIBC_VER@
-LIBSTDCPP_VER = @LIBSTDCPP_VER@
 
 
 # Linker stuff
 # Linker stuff
 PICFLAGS+= -fPIC -DPIC
 PICFLAGS+= -fPIC -DPIC
@@ -30,14 +28,11 @@ DEBIANDOC_TEXT = @DEBIANDOC_TEXT@
 
 
 DOXYGEN = @DOXYGEN@
 DOXYGEN = @DOXYGEN@
 
 
-# SGML for the man pages
-DOCBOOK2MAN := @DOCBOOK2MAN@
+# xsltproc for the man pages
+XSLTPROC := @XSLTPROC@
 
 
-# XML for the man pages
-XMLTO := @XMLTO@
-
-# XML for the man pages
-XMLTO := @XMLTO@
+# po4a for the man pages
+PO4A := @PO4A@
 
 
 # Gettext settings
 # Gettext settings
 GMSGFMT = @GMSGFMT@
 GMSGFMT = @GMSGFMT@

+ 1 - 1
buildlib/library.mak

@@ -5,7 +5,7 @@
 # Input
 # Input
 # $(SOURCE) - The source code to use
 # $(SOURCE) - The source code to use
 # $(HEADERS) - Exported header files and private header files
 # $(HEADERS) - Exported header files and private header files
-# $(LIBRARY) - The name of the library without lib or .so 
+# $(LIBRARY) - The name of the library without lib or .so
 # $(MAJOR) - The major version number of this library
 # $(MAJOR) - The major version number of this library
 # $(MINOR) - The minor version number of this library
 # $(MINOR) - The minor version number of this library
 # $(APT_DOMAIN) - The text domain for this library
 # $(APT_DOMAIN) - The text domain for this library

+ 21 - 0
buildlib/libversion.mak

@@ -0,0 +1,21 @@
+# -*- make -*-
+# Version number of libapt-pkg.
+# Please increase MAJOR with each ABI break,
+# with each non-ABI break to the lib, please increase RELEASE.
+# The versionnumber is extracted from apt-pkg/init.h - see also there.
+LIBAPTPKG_MAJOR=$(shell awk -v ORS='.' '/^\#define APT_PKG_M/ {print $$3}' $(BASE)/apt-pkg/init.h | sed 's/\.$$//')
+LIBAPTPKG_RELEASE=$(shell grep -E '^\#define APT_PKG_RELEASE' $(BASE)/apt-pkg/init.h | cut -d ' ' -f 3)
+
+# Version number of libapt-inst
+# Please increase MAJOR with each ABI break,
+# with each non-ABI break to the lib, please increase MINOR.
+# The versionnumber is extracted from apt-inst/makefile - see also there.
+LIBAPTINST_MAJOR=$(shell egrep '^MAJOR=' $(BASE)/apt-inst/makefile |cut -d '=' -f 2)
+LIBAPTINST_MINOR=$(shell egrep '^MINOR=' $(BASE)/apt-inst/makefile |cut -d '=' -f 2)
+
+# FIXME: In previous releases this lovely variable includes
+# the detected libc and libdc++ version. As this is bogus we
+# want to drop this, but this a ABI break.
+# And we don't want to do this now. So we hardcode a value here,
+# and drop it later on (hopefully as fast as possible).
+LIBEXT=-libc6.9-6

+ 1 - 1
buildlib/manpage.mak

@@ -5,7 +5,7 @@
 # Input
 # Input
 # $(SOURCE) - The documents to use
 # $(SOURCE) - The documents to use
 
 
-# All output is writtin to files in the build doc directory
+# All output is written to files in the build doc directory
 
 
 # See defaults.mak for information about LOCAL
 # See defaults.mak for information about LOCAL
 
 

+ 61 - 0
buildlib/po4a_manpage.mak

@@ -0,0 +1,61 @@
+# -*- make -*-
+
+# This handles man pages with po4a. We convert to the respective
+# output in the source directory then copy over to the final dest. This
+# means po4a is only needed if compiling from bzr
+
+# Input
+# $(LC)     - The language code of the translation
+
+# See defaults.mak for information about LOCAL
+
+# generate a list of accepted man page translations
+SOURCE = $(patsubst %.xml,%,$(wildcard *.$(LC).?.xml))
+INCLUDES = apt.ent
+
+# Do not use XMLTO, build the manpages directly with XSLTPROC
+ifdef XSLTPROC
+
+STYLESHEET=../manpage-style.xsl
+
+LOCAL := po4a-manpage-$(firstword $(SOURCE))
+$(LOCAL)-LIST := $(SOURCE)
+
+# Install generation hooks
+doc: $($(LOCAL)-LIST)
+veryclean: veryclean/$(LOCAL)
+
+$($(LOCAL)-LIST) :: % : %.xml $(INCLUDES)
+	echo Creating man page $@
+	$(XSLTPROC) -o $@ $(STYLESHEET) $< # why xsltproc doesn't respect the -o flag here???
+	test -f $(subst .$(LC),,$@) || echo FIXME: xsltproc respect the -o flag now, workaround can be removed
+	mv -f $(subst .$(LC),,$@) $@
+
+# Clean rule
+.PHONY: veryclean/$(LOCAL)
+veryclean/$(LOCAL):
+	-rm -rf $($(@F)-LIST) apt.ent apt.$(LC).8 \
+		$(addsuffix .xml,$($(@F)-LIST)) \
+		offline.$(LC).sgml guide.$(LC).sgml
+
+HAVE_PO4A=yes
+endif
+
+# take care of the rest
+SOURCE := $(SOURCE) $(wildcard apt.$(LC).8)
+INCLUDES :=
+
+ifndef HAVE_PO4A
+# Strip from the source list any man pages we dont have compiled already
+SOURCE := $(wildcard $(SOURCE))
+endif
+
+# Chain to the manpage rule
+ifneq ($(words $(SOURCE)),0)
+include $(MANPAGE_H)
+endif
+
+# Debian Doc SGML Documents
+SOURCE := $(wildcard *.$(LC).sgml)
+DEBIANDOC_HTML_OPTIONS=-l $(LC)
+include $(DEBIANDOC_H)

+ 0 - 45
buildlib/sgml_manpage.mak

@@ -1,45 +0,0 @@
-# -*- make -*-
-
-# This handles man pages in DocBook SGMLL format. We convert to the respective
-# output in the source directory then copy over to the final dest. This
-# means yodl is only needed if compiling from CVS
-
-# Input
-# $(SOURCE) - The documents to use, in the form foo.sect, ie apt-cache.8
-#             the sgml files are called apt-cache.8.sgml
-
-# See defaults.mak for information about LOCAL
-
-# Some local definitions
-ifdef DOCBOOK2MAN
-
-LOCAL := sgml-manpage-$(firstword $(SOURCE))
-$(LOCAL)-LIST := $(SOURCE)
-
-# Install generation hooks
-doc: $($(LOCAL)-LIST)
-veryclean: veryclean/$(LOCAL)
-
-$($(LOCAL)-LIST) :: % : %.sgml $(INCLUDES)
-	echo Creating man page $@
-	$(DOCBOOK2MAN) $<
-
-# Clean rule
-.PHONY: veryclean/$(LOCAL)
-veryclean/$(LOCAL):
-	-rm -rf $($(@F)-LIST)
-
-HAVE_SGML=yes
-endif
-
-INCLUDES :=
-
-ifndef HAVE_SGML
-# Strip from the source list any man pages we dont have compiled already
-SOURCE := $(wildcard $(SOURCE))
-endif
-
-# Chain to the manpage rule
-ifneq ($(words $(SOURCE)),0)
-include $(MANPAGE_H)
-endif

+ 2 - 1
buildlib/sizetable

@@ -11,6 +11,7 @@
 # The format is:-
 # The format is:-
 # CPU endian sizeof: char, int, short, long
 # CPU endian sizeof: char, int, short, long
 i386    little  1 4 2 4
 i386    little  1 4 2 4
+amd64   little  1 4 2 8
 armeb   big     1 4 2 4
 armeb   big     1 4 2 4
 arm     little  1 4 2 4
 arm     little  1 4 2 4
 alpha   little  1 4 2 8
 alpha   little  1 4 2 8
@@ -21,4 +22,4 @@ m68k    big     1 4 2 4
 powerpc big     1 4 2 4
 powerpc big     1 4 2 4
 mips    big     1 4 2 4
 mips    big     1 4 2 4
 hppa    big     1 4 2 4
 hppa    big     1 4 2 4
-m32r	big	1 4 2 4
+m32r	big	1 4 2 4

+ 0 - 50
buildlib/tools.m4

@@ -89,56 +89,6 @@ AC_DEFUN(ah_NUM_PROCS,
 	AC_SUBST(NUM_PROCS)
 	AC_SUBST(NUM_PROCS)
 ])
 ])
 
 
-AC_DEFUN(rc_GLIBC_VER,
-	[AC_MSG_CHECKING([glibc version])
-	AC_CACHE_VAL(ac_cv_glibc_ver,
-	dummy=if$$
-	cat <<_GLIBC_>$dummy.c
-#include <features.h>
-#include <stdio.h>
-#include <stdlib.h>
-int main(int argc, char **argv) { printf("libc6.%d",__GLIBC_MINOR__); exit(0); }
-_GLIBC_
-	${CC-cc} $dummy.c -o $dummy > /dev/null 2>&1
-	if test "$?" = 0; then
-		GLIBC_VER=`./$dummy`
-		AC_MSG_RESULT([$GLIBC_VER])
-		ac_cv_glibc_ver=$GLIBC_VER
-	else
-		AC_MSG_WARN([cannot determine GNU C library minor version number])
-	fi
-	rm -f $dummy $dummy.c
-	)
-	GLIBC_VER="-$ac_cv_glibc_ver"
-	AC_SUBST(GLIBC_VER)
-])
-
-AC_DEFUN(rc_LIBSTDCPP_VER,
-	[AC_MSG_CHECKING([libstdc++ version])
-	dummy=if$$
-	cat <<_LIBSTDCPP_>$dummy.cc
-#include <features.h>
-#include <stdio.h>
-#include <stdlib.h>
-int main(int argc, char **argv) { exit(0); }
-_LIBSTDCPP_
-	${CXX-c++} $dummy.cc -o $dummy > /dev/null 2>&1
-
-	if test "$?" = 0; then
-		soname=`objdump -p ./$dummy |grep NEEDED|grep libstd`
-                LIBSTDCPP_VER=`echo $soname | sed -e 's/.*NEEDED.*libstdc++\(-libc.*\(-.*\)\)\?.so.\(.*\)/\3\2/'`
-	fi
-	rm -f $dummy $dummy.cc
-
-	if test -z "$LIBSTDCPP_VER"; then
-		AC_MSG_WARN([cannot determine standard C++ library version number])
-	else
-		AC_MSG_RESULT([$LIBSTDCPP_VER])
-		LIBSTDCPP_VER="-$LIBSTDCPP_VER"
-	fi
-	AC_SUBST(LIBSTDCPP_VER)
-])
-
 AC_DEFUN(ah_GCC3DEP,[
 AC_DEFUN(ah_GCC3DEP,[
 	AC_MSG_CHECKING(if $CXX -MD works)
 	AC_MSG_CHECKING(if $CXX -MD works)
 	touch gcc3dep.cc
 	touch gcc3dep.cc

+ 0 - 45
buildlib/xml_manpage.mak

@@ -1,45 +0,0 @@
-# -*- make -*-
-
-# This handles man pages in DocBook XML format. We convert to the respective
-# output in the source directory then copy over to the final dest. This
-# means xmlto is only needed if compiling from Arch
-
-# Input
-# $(SOURCE) - The documents to use, in the form foo.sect, ie apt-cache.8
-#             the XML files are called apt-cache.8.xml
-
-# See defaults.mak for information about LOCAL
-
-# Some local definitions
-ifdef XMLTO
-
-LOCAL := xml-manpage-$(firstword $(SOURCE))
-$(LOCAL)-LIST := $(SOURCE)
-
-# Install generation hooks
-doc: $($(LOCAL)-LIST)
-veryclean: veryclean/$(LOCAL)
-
-$($(LOCAL)-LIST) :: % : %.xml $(INCLUDES)
-	echo Creating man page $@
-	$(XMLTO) man $<
-
-# Clean rule
-.PHONY: veryclean/$(LOCAL)
-veryclean/$(LOCAL):
-	-rm -rf $($(@F)-LIST)
-
-HAVE_XMLTO=yes
-endif
-
-INCLUDES :=
-
-ifndef HAVE_XMLTO
-# Strip from the source list any man pages we dont have compiled already
-SOURCE := $(wildcard $(SOURCE))
-endif
-
-# Chain to the manpage rule
-ifneq ($(words $(SOURCE)),0)
-include $(MANPAGE_H)
-endif

+ 0 - 42
buildlib/yodl_manpage.mak

@@ -1,42 +0,0 @@
-# -*- make -*-
-
-# This handles man pages in YODL format. We convert to the respective
-# output in the source directory then copy over to the final dest. This
-# means yodl is only needed if compiling from CVS
-
-# Input
-# $(SOURCE) - The documents to use, in the form foo.sect, ie apt-cache.8
-#             the yodl files are called apt-cache.8.yo
-
-# See defaults.mak for information about LOCAL
-
-# Some local definitions
-ifdef YODL_MAN
-
-LOCAL := yodl-manpage-$(firstword $(SOURCE))
-$(LOCAL)-LIST := $(SOURCE)
-
-# Install generation hooks
-doc: $($(LOCAL)-LIST)
-veryclean: veryclean/$(LOCAL)
-
-$($(LOCAL)-LIST) :: % : %.yo
-	echo Creating man page $@
-	yodl2man -o $@ $<
-
-# Clean rule
-.PHONY: veryclean/$(LOCAL)
-veryclean/$(LOCAL):
-	-rm -rf $($(@F)-LIST)
-
-else
-
-# Strip from the source list any man pages we dont have compiled already
-SOURCE := $(wildcard $(SOURCE))
-
-endif
-
-# Chain to the manpage rule
-ifneq ($(words $(SOURCE)),0)
-include $(MANPAGE_H)
-endif

+ 14 - 15
cmdline/apt-cache.cc

@@ -399,7 +399,7 @@ bool DumpAvail(CommandLine &Cmd)
    pkgCache &Cache = *GCache;
    pkgCache &Cache = *GCache;
 
 
    pkgPolicy Plcy(&Cache);
    pkgPolicy Plcy(&Cache);
-   if (ReadPinFile(Plcy) == false)
+   if (ReadPinFile(Plcy) == false || ReadPinDir(Plcy) == false)
       return false;
       return false;
    
    
    unsigned long Count = Cache.HeaderP->PackageCount+1;
    unsigned long Count = Cache.HeaderP->PackageCount+1;
@@ -626,7 +626,7 @@ bool Depends(CommandLine &CmdL)
    
    
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 // RDepends - Print out a reverse dependency tree - mbc			/*{{{*/
 // RDepends - Print out a reverse dependency tree - mbc			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -714,10 +714,7 @@ bool RDepends(CommandLine &CmdL)
    
    
    return true;
    return true;
 }
 }
-
 									/*}}}*/
 									/*}}}*/
-
-
 // xvcg - Generate a graph for xvcg					/*{{{*/
 // xvcg - Generate a graph for xvcg					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
@@ -932,13 +929,15 @@ bool XVcg(CommandLine &CmdL)
 		Shapes[ShapeMap[Pkg->ID]]);
 		Shapes[ShapeMap[Pkg->ID]]);
       
       
    }
    }
-   
+
+   delete[] Show;
+   delete[] Flags;
+   delete[] ShapeMap;
+
    printf("}\n");
    printf("}\n");
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-
 // Dotty - Generate a graph for Dotty					/*{{{*/
 // Dotty - Generate a graph for Dotty					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Dotty is the graphvis program for generating graphs. It is a fairly
 /* Dotty is the graphvis program for generating graphs. It is a fairly
@@ -1274,15 +1273,16 @@ bool DisplayRecord(pkgCache::VerIterator V)
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// Search - Perform a search						/*{{{*/
-// ---------------------------------------------------------------------
-/* This searches the package names and package descriptions for a pattern */
+
 struct ExDescFile
 struct ExDescFile
 {
 {
    pkgCache::DescFile *Df;
    pkgCache::DescFile *Df;
    bool NameMatch;
    bool NameMatch;
 };
 };
 
 
+// Search - Perform a search						/*{{{*/
+// ---------------------------------------------------------------------
+/* This searches the package names and package descriptions for a pattern */
 bool Search(CommandLine &CmdL)
 bool Search(CommandLine &CmdL)
 {
 {
    pkgCache &Cache = *GCache;
    pkgCache &Cache = *GCache;
@@ -1519,7 +1519,7 @@ bool Policy(CommandLine &CmdL)
    
    
    pkgCache &Cache = *GCache;
    pkgCache &Cache = *GCache;
    pkgPolicy Plcy(&Cache);
    pkgPolicy Plcy(&Cache);
-   if (ReadPinFile(Plcy) == false)
+   if (ReadPinFile(Plcy) == false || ReadPinDir(Plcy) == false)
       return false;
       return false;
    
    
    // Print out all of the package files
    // Print out all of the package files
@@ -1696,7 +1696,6 @@ bool Madison(CommandLine &CmdL)
 
 
    return true;
    return true;
 }
 }
-
 									/*}}}*/
 									/*}}}*/
 // GenCaches - Call the main cache generator				/*{{{*/
 // GenCaches - Call the main cache generator				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
@@ -1770,8 +1769,7 @@ void CacheInitialize()
    _config->Set("help",false);
    _config->Set("help",false);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc,const char *argv[])
+int main(int argc,const char *argv[])					/*{{{*/
 {
 {
    CommandLine::Args Args[] = {
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'h',"help","help",0},
@@ -1878,3 +1876,4 @@ int main(int argc,const char *argv[])
           
           
    return 0;
    return 0;
 }
 }
+									/*}}}*/

+ 4 - 8
cmdline/apt-cdrom.cc

@@ -40,8 +40,7 @@
 
 
 using namespace std;
 using namespace std;
 
 
-                                                                        /*{{{*/
-class pkgCdromTextStatus : public pkgCdromStatus
+class pkgCdromTextStatus : public pkgCdromStatus			/*{{{*/
 {
 {
 protected:
 protected:
    OpTextProgress Progress;
    OpTextProgress Progress;
@@ -75,7 +74,7 @@ string pkgCdromTextStatus::PromptLine(const char *Text)
 
 
 bool pkgCdromTextStatus::AskCdromName(string &name) 
 bool pkgCdromTextStatus::AskCdromName(string &name) 
 {
 {
-   cout << _("Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'") << flush;
+   cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush;
    name = PromptLine("");
    name = PromptLine("");
 	 
 	 
    return true;
    return true;
@@ -98,9 +97,7 @@ OpProgress* pkgCdromTextStatus::GetOpProgress()
 { 
 { 
    return &Progress; 
    return &Progress; 
 };
 };
-
 									/*}}}*/
 									/*}}}*/
-
 // DoAdd - Add a new CDROM						/*{{{*/
 // DoAdd - Add a new CDROM						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This does the main add bit.. We show some status and things. The
 /* This does the main add bit.. We show some status and things. The
@@ -129,7 +126,6 @@ bool DoIdent(CommandLine &)
    return cdrom.Ident(ident, &log);
    return cdrom.Ident(ident, &log);
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // ShowHelp - Show the help screen					/*{{{*/
 // ShowHelp - Show the help screen					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -164,8 +160,7 @@ int ShowHelp()
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc,const char *argv[])
+int main(int argc,const char *argv[])					/*{{{*/
 {
 {
    CommandLine::Args Args[] = {
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'h',"help","help",0},
@@ -222,3 +217,4 @@ int main(int argc,const char *argv[])
    
    
    return 0;
    return 0;
 }
 }
+									/*}}}*/

+ 2 - 2
cmdline/apt-config.cc

@@ -88,8 +88,7 @@ int ShowHelp()
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc,const char *argv[])
+int main(int argc,const char *argv[])					/*{{{*/
 {
 {
    CommandLine::Args Args[] = {
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'h',"help","help",0},
@@ -133,3 +132,4 @@ int main(int argc,const char *argv[])
    
    
    return 0;
    return 0;
 }
 }
+									/*}}}*/

+ 2 - 2
cmdline/apt-extracttemplates.cc

@@ -348,8 +348,7 @@ bool Go(CommandLine &CmdL)
 	return !_error->PendingError();
 	return !_error->PendingError();
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc, const char **argv)
+int main(int argc, const char **argv)					/*{{{*/
 {
 {
 	CommandLine::Args Args[] = {
 	CommandLine::Args Args[] = {
 		{'h',"help","help",0},
 		{'h',"help","help",0},
@@ -391,3 +390,4 @@ int main(int argc, const char **argv)
 	
 	
 	return 0;
 	return 0;
 }
 }
+									/*}}}*/

+ 244 - 139
cmdline/apt-get.cc

@@ -111,6 +111,9 @@ class CacheFile : public pkgCacheFile
 	 return Open(true);
 	 return Open(true);
    }
    }
    CacheFile() : List(0) {};
    CacheFile() : List(0) {};
+   ~CacheFile() {
+      delete[] List;
+   }
 };
 };
 									/*}}}*/
 									/*}}}*/
 
 
@@ -594,7 +597,6 @@ void Stats(ostream &out,pkgDepCache &Dep)
 	       Dep.BadCount());
 	       Dep.BadCount());
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // CacheFile::NameComp - QSort compare by name				/*{{{*/
 // CacheFile::NameComp - QSort compare by name				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -687,7 +689,10 @@ bool CacheFile::CheckDeps(bool AllowBroken)
       
       
    return true;
    return true;
 }
 }
-
+									/*}}}*/
+// CheckAuth - check if each download comes form a trusted source	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
 static bool CheckAuth(pkgAcquire& Fetcher)
 static bool CheckAuth(pkgAcquire& Fetcher)
 {
 {
    string UntrustedList;
    string UntrustedList;
@@ -728,10 +733,7 @@ static bool CheckAuth(pkgAcquire& Fetcher)
 
 
    return _error->Error(_("There are problems and -y was used without --force-yes"));
    return _error->Error(_("There are problems and -y was used without --force-yes"));
 }
 }
-
-
 									/*}}}*/
 									/*}}}*/
-
 // InstallPackages - Actually download and install the packages		/*{{{*/
 // InstallPackages - Actually download and install the packages		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This displays the informative messages describing what is going to 
 /* This displays the informative messages describing what is going to 
@@ -860,14 +862,21 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
    {
    {
       struct statvfs Buf;
       struct statvfs Buf;
       string OutputDir = _config->FindDir("Dir::Cache::Archives");
       string OutputDir = _config->FindDir("Dir::Cache::Archives");
-      if (statvfs(OutputDir.c_str(),&Buf) != 0)
-	 return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
-			      OutputDir.c_str());
-      if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+      if (statvfs(OutputDir.c_str(),&Buf) != 0) {
+	 if (errno == EOVERFLOW)
+	    return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
+				 OutputDir.c_str());
+	 else
+	    return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+				 OutputDir.c_str());
+      } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
       {
       {
          struct statfs Stat;
          struct statfs Stat;
-         if (statfs(OutputDir.c_str(),&Stat) != 0 ||
-			 unsigned(Stat.f_type) != RAMFS_MAGIC)
+         if (statfs(OutputDir.c_str(),&Stat) != 0
+#if HAVE_STRUCT_STATFS_F_TYPE
+             || unsigned(Stat.f_type) != RAMFS_MAGIC
+#endif
+             )
             return _error->Error(_("You don't have enough free space in %s."),
             return _error->Error(_("You don't have enough free space in %s."),
                 OutputDir.c_str());
                 OutputDir.c_str());
       }
       }
@@ -1044,17 +1053,42 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
 		  pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
 		  pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
 		  unsigned int &ExpectedInst,bool AllowFail = true)
 		  unsigned int &ExpectedInst,bool AllowFail = true)
 {
 {
-   /* This is a pure virtual package and there is a single available 
-      provides */
-   if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
-       Pkg.ProvidesList()->NextProvides == 0)
+   /* This is a pure virtual package and there is a single available
+      candidate providing it. */
+   if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
    {
    {
-      pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
-      ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
-	       Tmp.Name(),Pkg.Name());
-      Pkg = Tmp;
+      pkgCache::PkgIterator Prov;
+      bool found_one = false;
+
+      for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
+      {
+	 pkgCache::VerIterator const PVer = P.OwnerVer();
+	 pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+	 /* Ignore versions that are not a candidate. */
+	 if (Cache[PPkg].CandidateVer != PVer)
+	     continue;
+
+	 if (found_one == false)
+	 {
+	    Prov = PPkg;
+	    found_one = true;
+	 }
+	 else if (PPkg != Prov)
+	 {
+	    found_one = false; // we found at least two
+	    break;
+	 }
+      }
+
+      if (found_one == true)
+      {
+	 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
+		  Prov.Name(),Pkg.Name());
+	 Pkg = Prov;
+      }
    }
    }
-   
+
    // Handle the no-upgrade case
    // Handle the no-upgrade case
    if (_config->FindB("APT::Get::upgrade",true) == false &&
    if (_config->FindB("APT::Get::upgrade",true) == false &&
        Pkg->CurrentVer != 0)
        Pkg->CurrentVer != 0)
@@ -1213,129 +1247,155 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
 			       pkgSrcRecords &SrcRecs,string &Src,
 			       pkgSrcRecords &SrcRecs,string &Src,
 			       pkgDepCache &Cache)
 			       pkgDepCache &Cache)
 {
 {
-   // We want to pull the version off the package specification..
    string VerTag;
    string VerTag;
+   string DefRel = _config->Find("APT::Default-Release");
    string TmpSrc = Name;
    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);
+   // extract the version/release from the pkgname
+   const size_t found = TmpSrc.find_last_of("/=");
+   if (found != string::npos) {
+      if (TmpSrc[found] == '/')
+	 DefRel = TmpSrc.substr(found+1);
+      else
+	 VerTag = TmpSrc.substr(found+1);
+      TmpSrc = TmpSrc.substr(0,found);
+   }
 
 
-   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)
+   /* 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. */
+   bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source");
+   const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
+   if (MatchSrcOnly == false && Pkg.end() == 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++)
+      if(VerTag.empty() == false || DefRel.empty() == false) 
       {
       {
-	 for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false;
-	      VF++)
+	 // 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++) 
 	 {
 	 {
-	    /* 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)) 
+	    for (pkgCache::VerFileIterator VF = Ver.FileList();
+		 VF.end() == false; VF++) 
 	    {
 	    {
-	       VerTag = Ver.VerStr();
-	       break;
+	       /* 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;
+
+	       // We match against a concrete version (or a part of this version)
+	       if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)
+		  continue;
+
+	       // or we match against a release
+	       if(VerTag.empty() == false ||
+		  (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) ||
+		  (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) 
+	       {
+		  pkgRecords::Parser &Parse = Recs.Lookup(VF);
+		  Src = Parse.SourcePkg();
+		  // no SourcePkg name, so it is the "binary" name
+		  if (Src.empty() == true)
+		     Src = TmpSrc;
+		  // no Version, so we try the Version of the SourcePkg -
+		  // and after that the version of the binary package
+		  if (VerTag.empty() == true)
+		     VerTag = Parse.SourceVer();
+		  if (VerTag.empty() == true)
+		     VerTag = Ver.VerStr();
+		  break;
+	       }
 	    }
 	    }
+	    if (Src.empty() == false)
+	       break;
+	 }
+	 if (Src.empty() == true) 
+	 {
+	    // Sources files have no codename information
+	    if (VerTag.empty() == true && DefRel.empty() == false)
+	       _error->Warning(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str());
+	    DefRel.clear();
 	 }
 	 }
       }
       }
-   }
-
-   /* 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. */
-   if (_config->FindB("APT::Get::Only-Source") == false)
-   {
-      if (Pkg.end() == false)
+      if (Src.empty() == true)
       {
       {
+	 // if we don't have found a fitting package yet so we will
+	 // choose a good candidate and proceed with that.
+	 // Maybe we will find a source later on with the right VerTag
 	 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
 	 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
-	 if (Ver.end() == false)
+	 if (Ver.end() == false) 
 	 {
 	 {
 	    pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
 	    pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
 	    Src = Parse.SourcePkg();
 	    Src = Parse.SourcePkg();
+	    if (VerTag.empty() == true)
+	       VerTag = Parse.SourceVer();
 	 }
 	 }
-      }   
+      }
+   }
+
+   if (Src.empty() == true)
+      Src = TmpSrc;
+   else 
+   {
+      /* if we have a source pkg name, make sure to only search
+	 for srcpkg names, otherwise apt gets confused if there
+	 is a binary package "pkg1" and a source package "pkg1"
+	 with the same name but that comes from different packages */
+      MatchSrcOnly = true;
+      if (Src != TmpSrc) 
+      {
+	 ioprintf(c1out, _("Picking '%s' as source package instead of '%s'\n"), Src.c_str(), TmpSrc.c_str());
+      }
    }
    }
 
 
    // The best hit
    // The best hit
    pkgSrcRecords::Parser *Last = 0;
    pkgSrcRecords::Parser *Last = 0;
    unsigned long Offset = 0;
    unsigned long Offset = 0;
    string Version;
    string Version;
-   bool IsMatch = false;
-   bool MatchSrcOnly = false;
 
 
-   // No source package name..
-   if (Src.empty() == true)
-      Src = TmpSrc;
-   else 
-      // if we have a source pkg name, make sure to only search
-      // for srcpkg names, otherwise apt gets confused if there
-      // is a binary package "pkg1" and a source package "pkg1"
-      // with the same name but that comes from different packages
-      MatchSrcOnly = true;
-   
-   // If we are matching by version then we need exact matches to be happy
-   if (VerTag.empty() == false)
-      IsMatch = true;
-   
    /* Iterate over all of the hits, which includes the resulting
    /* Iterate over all of the hits, which includes the resulting
       binary packages in the search */
       binary packages in the search */
    pkgSrcRecords::Parser *Parse;
    pkgSrcRecords::Parser *Parse;
-   SrcRecs.Restart();
-   while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0)
+   while (true) 
    {
    {
-      string Ver = Parse->Version();
-      
-      // show name mismatches
-      if (IsMatch == true && Parse->Package() != Src) 
-	 ioprintf(c1out,  _("No source package '%s' picking '%s' instead\n"), Parse->Package().c_str(), Src.c_str());
-      
-      if (VerTag.empty() == false)
+      SrcRecs.Restart();
+      while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0) 
       {
       {
-	 /* Don't want to fall through because we are doing exact version 
-	    matching. */
-	 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
+	 const string Ver = Parse->Version();
+
+	 // Ignore all versions which doesn't fit
+	 if (VerTag.empty() == false && strncmp(VerTag.c_str(), Ver.c_str(), VerTag.size()) != 0)
 	    continue;
 	    continue;
-	 
-	 Last = Parse;
-	 Offset = Parse->Offset();
-	 break;
+
+	 // Newer version or an exact match? Save the hit
+	 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) {
+	    Last = Parse;
+	    Offset = Parse->Offset();
+	    Version = Ver;
+	 }
+
+	 // was the version check above an exact match? If so, we don't need to look further
+	 if (VerTag.empty() == false && VerTag.size() == Ver.size())
+	    break;
       }
       }
-				  
-      // Newer version or an exact match
-      if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 || 
-	  (Parse->Package() == Src && IsMatch == false))
-      {
-	 IsMatch = Parse->Package() == Src;
-	 Last = Parse;
-	 Offset = Parse->Offset();
-	 Version = Ver;
-      }      
+      if (Last != 0 || VerTag.empty() == true)
+	 break;
+      //if (VerTag.empty() == false && Last == 0)
+      _error->Warning(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str());
+      VerTag.clear();
    }
    }
-   
+
    if (Last == 0 || Last->Jump(Offset) == false)
    if (Last == 0 || Last->Jump(Offset) == false)
       return 0;
       return 0;
-   
+
    return Last;
    return Last;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
 // DoUpdate - Update the package lists					/*{{{*/
 // DoUpdate - Update the package lists					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -1399,20 +1459,29 @@ bool DoAutomaticRemove(CacheFile &Cache)
    bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
    bool Debug = _config->FindI("Debug::pkgAutoRemove",false);
    bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
    bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false);
    bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
    bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove");
-   pkgDepCache::ActionGroup group(*Cache);
 
 
+   pkgDepCache::ActionGroup group(*Cache);
    if(Debug)
    if(Debug)
       std::cout << "DoAutomaticRemove()" << std::endl;
       std::cout << "DoAutomaticRemove()" << std::endl;
 
 
-   if (_config->FindB("APT::Get::Remove",true) == false &&
-       doAutoRemove == true)
+   // we don't want to autoremove and we don't want to see it, so why calculating?
+   if (doAutoRemove == false && hideAutoRemove == true)
+      return true;
+
+   if (doAutoRemove == true &&
+	_config->FindB("APT::Get::Remove",true) == false)
    {
    {
       c1out << _("We are not supposed to delete stuff, can't start "
       c1out << _("We are not supposed to delete stuff, can't start "
 		 "AutoRemover") << std::endl;
 		 "AutoRemover") << std::endl;
-      doAutoRemove = false;
+      return false;
    }
    }
 
 
+   bool purgePkgs = _config->FindB("APT::Get::Purge", false);
+   bool smallList = (hideAutoRemove == false &&
+	strcasecmp(_config->Find("APT::Get::HideAutoRemove","").c_str(),"small") == 0);
+
    string autoremovelist, autoremoveversions;
    string autoremovelist, autoremoveversions;
+   unsigned long autoRemoveCount = 0;
    // look over the cache to see what can be removed
    // look over the cache to see what can be removed
    for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
    for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
    {
    {
@@ -1421,30 +1490,43 @@ bool DoAutomaticRemove(CacheFile &Cache)
 	 if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
 	 if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
 	    if(Debug)
 	    if(Debug)
 	       std::cout << "We could delete %s" <<  Pkg.Name() << std::endl;
 	       std::cout << "We could delete %s" <<  Pkg.Name() << std::endl;
-	  
-	 // only show stuff in the list that is not yet marked for removal
-	 if(Cache[Pkg].Delete() == false) 
-	 {
-	    autoremovelist += string(Pkg.Name()) + " ";
-	    autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
-	 }
+
 	 if (doAutoRemove)
 	 if (doAutoRemove)
 	 {
 	 {
 	    if(Pkg.CurrentVer() != 0 && 
 	    if(Pkg.CurrentVer() != 0 && 
 	       Pkg->CurrentState != pkgCache::State::ConfigFiles)
 	       Pkg->CurrentState != pkgCache::State::ConfigFiles)
-	       Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false));
+	       Cache->MarkDelete(Pkg, purgePkgs);
 	    else
 	    else
 	       Cache->MarkKeep(Pkg, false, false);
 	       Cache->MarkKeep(Pkg, false, false);
 	 }
 	 }
+	 else
+	 {
+	    // only show stuff in the list that is not yet marked for removal
+	    if(Cache[Pkg].Delete() == false) 
+	    {
+	       // we don't need to fill the strings if we don't need them
+	       if (smallList == true)
+		  ++autoRemoveCount;
+	       else
+	       {
+		 autoremovelist += string(Pkg.Name()) + " ";
+		 autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
+	       }
+	    }
+	 }
       }
       }
    }
    }
-   if (!hideAutoRemove) 
-      ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
-   if (!doAutoRemove && !hideAutoRemove && autoremovelist.size() > 0)
+   // if we don't remove them, we should show them!
+   if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
+   {
+      if (smallList == false)
+	 ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions);
+      else
+	 ioprintf(c1out, _("%lu packages were automatically installed and are no longer required.\n"), autoRemoveCount);
       c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
       c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl;
-
-   // Now see if we destroyed anything
-   if (Cache->BrokenCount() != 0)
+   }
+   // Now see if we had destroyed anything (if we had done anything)
+   else if (Cache->BrokenCount() != 0)
    {
    {
       c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
       c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n"
 	         "shouldn't happen. Please file a bug report against apt.") << endl;
 	         "shouldn't happen. Please file a bug report against apt.") << endl;
@@ -1457,7 +1539,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
    }
    }
    return true;
    return true;
 }
 }
-
+									/*}}}*/
 // DoUpgrade - Upgrade all packages					/*{{{*/
 // DoUpgrade - Upgrade all packages					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Upgrade all packages without installing new packages or erasing old
 /* Upgrade all packages without installing new packages or erasing old
@@ -1532,7 +1614,7 @@ bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix,
    regfree(&Pattern);
    regfree(&Pattern);
    return res;
    return res;
 }
 }
-
+									/*}}}*/
 // DoInstall - Install packages from the command line			/*{{{*/
 // DoInstall - Install packages from the command line			/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Install named packages */
 /* Install named packages */
@@ -1870,7 +1952,8 @@ bool DoInstall(CommandLine &CmdL)
    // cache.commit()
    // cache.commit()
    if (AutoMarkChanged > 0 &&
    if (AutoMarkChanged > 0 &&
        Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
        Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
-       Cache->BadCount() == 0)
+       Cache->BadCount() == 0 &&
+       _config->FindB("APT::Get::Simulate",false) == false)
       Cache->writeStateFile(NULL);
       Cache->writeStateFile(NULL);
 
 
    // See if we need to prompt
    // See if we need to prompt
@@ -2171,14 +2254,21 @@ bool DoSource(CommandLine &CmdL)
    // Check for enough free space
    // Check for enough free space
    struct statvfs Buf;
    struct statvfs Buf;
    string OutputDir = ".";
    string OutputDir = ".";
-   if (statvfs(OutputDir.c_str(),&Buf) != 0)
-      return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
-			   OutputDir.c_str());
-   if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
+   if (statvfs(OutputDir.c_str(),&Buf) != 0) {
+      if (errno == EOVERFLOW)
+	 return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
+				OutputDir.c_str());
+      else
+	 return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
+				OutputDir.c_str());
+   } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
      {
      {
        struct statfs Stat;
        struct statfs Stat;
-       if (statfs(OutputDir.c_str(),&Stat) != 0 || 
-           unsigned(Stat.f_type) != RAMFS_MAGIC) 
+       if (statfs(OutputDir.c_str(),&Stat) != 0
+#if HAVE_STRUCT_STATFS_F_TYPE
+           || unsigned(Stat.f_type) != RAMFS_MAGIC
+#endif
+           ) 
           return _error->Error(_("You don't have enough free space in %s"),
           return _error->Error(_("You don't have enough free space in %s"),
               OutputDir.c_str());
               OutputDir.c_str());
       }
       }
@@ -2522,7 +2612,7 @@ bool DoBuildDep(CommandLine &CmdL)
             {
             {
                // We successfully installed something; skip remaining alternatives
                // We successfully installed something; skip remaining alternatives
                skipAlternatives = hasAlternatives;
                skipAlternatives = hasAlternatives;
-	       if(_config->FindB("APT::Get::Build-Dep-Automatic", true) == true)
+	       if(_config->FindB("APT::Get::Build-Dep-Automatic", false) == true)
 		  Cache->MarkAuto(Pkg, true);
 		  Cache->MarkAuto(Pkg, true);
                continue;
                continue;
             }
             }
@@ -2548,7 +2638,10 @@ bool DoBuildDep(CommandLine &CmdL)
       
       
       // Now we check the state of the packages,
       // Now we check the state of the packages,
       if (Cache->BrokenCount() != 0)
       if (Cache->BrokenCount() != 0)
-         return _error->Error(_("Build-dependencies for %s could not be satisfied."),*I);
+      {
+	 ShowBroken(cout, Cache, false);
+	 return _error->Error(_("Build-dependencies for %s could not be satisfied."),*I);
+      }
    }
    }
   
   
    if (InstallPackages(Cache, false, true) == false)
    if (InstallPackages(Cache, false, true) == false)
@@ -2698,8 +2791,7 @@ void SigWinch(int)
 #endif
 #endif
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc,const char *argv[])
+int main(int argc,const char *argv[])					/*{{{*/
 {
 {
    CommandLine::Args Args[] = {
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'h',"help","help",0},
@@ -2729,6 +2821,7 @@ int main(int argc,const char *argv[])
       {0,"force-yes","APT::Get::force-yes",0},
       {0,"force-yes","APT::Get::force-yes",0},
       {0,"print-uris","APT::Get::Print-URIs",0},
       {0,"print-uris","APT::Get::Print-URIs",0},
       {0,"diff-only","APT::Get::Diff-Only",0},
       {0,"diff-only","APT::Get::Diff-Only",0},
+      {0,"debian-only","APT::Get::Diff-Only",0},
       {0,"tar-only","APT::Get::Tar-Only",0},
       {0,"tar-only","APT::Get::Tar-Only",0},
       {0,"dsc-only","APT::Get::Dsc-Only",0},
       {0,"dsc-only","APT::Get::Dsc-Only",0},
       {0,"purge","APT::Get::Purge",0},
       {0,"purge","APT::Get::Purge",0},
@@ -2739,7 +2832,6 @@ int main(int argc,const char *argv[])
       {0,"only-source","APT::Get::Only-Source",0},
       {0,"only-source","APT::Get::Only-Source",0},
       {0,"arch-only","APT::Get::Arch-Only",0},
       {0,"arch-only","APT::Get::Arch-Only",0},
       {0,"auto-remove","APT::Get::AutomaticRemove",0},
       {0,"auto-remove","APT::Get::AutomaticRemove",0},
-      {0,"build-dep-automatic","APT::Get::Build-Dep-Automatic",0},
       {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
       {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
       {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
       {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
       {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
       {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
@@ -2789,7 +2881,19 @@ int main(int argc,const char *argv[])
       ShowHelp(CmdL);
       ShowHelp(CmdL);
       return 0;
       return 0;
    }
    }
-   
+
+   // simulate user-friendly if apt-get has no root privileges
+   if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true)
+   {
+      if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
+	 cout << _("NOTE: This is only a simulation!\n"
+	    "      apt-get needs root privileges for real execution.\n"
+	    "      Keep also in mind that locking is deactivated,\n"
+	    "      so don't depend on the relevance to the real current situation!"
+	 ) << std::endl;
+      _config->Set("Debug::NoLocking",true);
+   }
+
    // Deal with stdout not being a tty
    // Deal with stdout not being a tty
    if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
    if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
       _config->Set("quiet","1");
       _config->Set("quiet","1");
@@ -2821,3 +2925,4 @@ int main(int argc,const char *argv[])
    
    
    return 0;   
    return 0;   
 }
 }
+									/*}}}*/

+ 11 - 7
cmdline/apt-key

@@ -93,13 +93,17 @@ update() {
     # add any security. we *need* this check on net-update though
     # add any security. we *need* this check on net-update though
     $GPG_CMD --quiet --batch --keyring $ARCHIVE_KEYRING --export | $GPG --import
     $GPG_CMD --quiet --batch --keyring $ARCHIVE_KEYRING --export | $GPG --import
 
 
-    # remove no-longer supported/used keys
-    keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5`
-    for key in $keys; do
-	if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then
-	    $GPG --quiet --batch --delete-key --yes ${key}
-	fi
-    done
+    if [ -r "$REMOVED_KEYS" ]; then
+	# remove no-longer supported/used keys
+	keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5`
+	for key in $keys; do
+	    if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then
+		$GPG --quiet --batch --delete-key --yes ${key}
+	    fi
+	done
+    else
+	echo "Warning: removed keys keyring  $REMOVED_KEYS missing or not readable" >&2
+    fi
 }
 }
 
 
 
 

+ 10 - 5
cmdline/apt-mark

@@ -2,13 +2,14 @@
 
 
 from optparse import OptionParser
 from optparse import OptionParser
 
 
+import sys
+import os.path
+    
 try:
 try:
     import apt_pkg
     import apt_pkg
 except ImportError:
 except ImportError:
     print "Error importing apt_pkg, is python-apt installed?"
     print "Error importing apt_pkg, is python-apt installed?"
-    
-import sys
-import os.path
+    sys.exit(1)
     
     
 actions = { "markauto" : 1,
 actions = { "markauto" : 1,
             "unmarkauto": 0
             "unmarkauto": 0
@@ -31,8 +32,12 @@ def mark_unmark_automatic(filename, action, pkgs):
     " mark or unmark automatic flag"
     " mark or unmark automatic flag"
     # open the statefile
     # open the statefile
     if os.path.exists(STATE_FILE):
     if os.path.exists(STATE_FILE):
-        tagfile = apt_pkg.ParseTagFile(open(STATE_FILE))
-        outfile = open(STATE_FILE+".tmp","w")
+        try:
+            tagfile = apt_pkg.ParseTagFile(open(STATE_FILE))
+            outfile = open(STATE_FILE+".tmp","w")
+        except IOError, msg:
+            print "%s, are you root?" % (msg)
+            sys.exit(1)
         while tagfile.Step():
         while tagfile.Step():
             pkgname = tagfile.Section.get("Package")
             pkgname = tagfile.Section.get("Package")
             autoInst = tagfile.Section.get("Auto-Installed")
             autoInst = tagfile.Section.get("Auto-Installed")

+ 4 - 4
cmdline/apt-sortpkgs.cc

@@ -31,7 +31,7 @@
 
 
 using namespace std;
 using namespace std;
 
 
-struct PkgName
+struct PkgName								/*{{{*/
 {
 {
    string Name;
    string Name;
    string Ver;
    string Ver;
@@ -55,7 +55,7 @@ struct PkgName
    bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
    bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
    bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
    bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
 };
 };
-
+									/*}}}*/
 // DoIt - Sort a single file						/*{{{*/
 // DoIt - Sort a single file						/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
@@ -161,8 +161,7 @@ int ShowHelp()
    return 0;
    return 0;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-int main(int argc,const char *argv[])
+int main(int argc,const char *argv[])					/*{{{*/
 {
 {
    CommandLine::Args Args[] = {
    CommandLine::Args Args[] = {
       {'h',"help","help",0},
       {'h',"help","help",0},
@@ -206,3 +205,4 @@ int main(int argc,const char *argv[])
    
    
    return 0;   
    return 0;   
 }
 }
+									/*}}}*/

+ 9 - 10
configure.in

@@ -18,7 +18,7 @@ AC_CONFIG_AUX_DIR(buildlib)
 AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
 AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
 
 
 dnl -- SET THIS TO THE RELEASE VERSION --
 dnl -- SET THIS TO THE RELEASE VERSION --
-AC_DEFINE_UNQUOTED(VERSION,"0.7.20~exp3")
+AC_DEFINE_UNQUOTED(VERSION,"0.7.25")
 PACKAGE="apt"
 PACKAGE="apt"
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_SUBST(PACKAGE)
 AC_SUBST(PACKAGE)
@@ -112,6 +112,10 @@ if test x"$HAVE_STATVFS" != x"yes"; then
    ])
    ])
 fi
 fi
 
 
+AC_CHECK_MEMBERS([struct statfs.f_type],,,
+    [$ac_includes_default
+     #include <sys/vfs.h>])
+
 dnl We should use the real timegm function if we have it.
 dnl We should use the real timegm function if we have it.
 AC_CHECK_FUNC(timegm,AC_DEFINE(HAVE_TIMEGM))
 AC_CHECK_FUNC(timegm,AC_DEFINE(HAVE_TIMEGM))
 AC_SUBST(HAVE_TIMEGM)
 AC_SUBST(HAVE_TIMEGM)
@@ -180,11 +184,11 @@ AC_PATH_PROG(DEBIANDOC_TEXT,debiandoc2text)
 dnl Check for doxygen
 dnl Check for doxygen
 AC_PATH_PROG(DOXYGEN, doxygen)
 AC_PATH_PROG(DOXYGEN, doxygen)
 
 
-dnl Check for the SGML tools needed to build man pages
-AC_PATH_PROG(DOCBOOK2MAN,docbook2man)
+dnl Check for the XSLTProc tool needed to build man pages together with po4a
+AC_PATH_PROG(XSLTPROC,xsltproc)
 
 
-dnl Check for the XML tools needed to build man pages
-AC_PATH_PROG(XMLTO,xmlto)
+dnl Check for the po4a tool needed to build man pages
+AC_PATH_PROG(PO4A,po4a)
 
 
 dnl Check for graphviz
 dnl Check for graphviz
 AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO])
 AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO])
@@ -192,12 +196,7 @@ AC_PATH_PROG([DOT], [dot], [])
 DOTDIR=$(dirname $DOT)
 DOTDIR=$(dirname $DOT)
 AC_SUBST(DOTDIR)
 AC_SUBST(DOTDIR)
 
 
-dnl Check for YODL
-dnl AC_CHECK_PROG(YODL_MAN,yodl2man,"yes","")
-
 ah_NUM_PROCS
 ah_NUM_PROCS
-rc_GLIBC_VER
-rc_LIBSTDCPP_VER
 ah_GCC3DEP
 ah_GCC3DEP
 
 
 dnl It used to be that the user could select translations and that could get
 dnl It used to be that the user could select translations and that could get

+ 0 - 13
debian/.cvsignore

@@ -1,13 +0,0 @@
-copyright
-apt
-apt-doc
-apt-utils
-apt-utils.substvars
-apt.substvars
-files
-libapt-pkg-dev
-libapt-pkg-doc
-shlibs.local
-shlibs.local.apt
-shlibs.local.apt-utils
-*.debhelper

+ 43 - 0
debian/NEWS

@@ -0,0 +1,43 @@
+apt (0.7.24) unstable; urgency=low
+
+  * Already included in the last version but now with better documentation
+    is the possibility to add/prefer different compression types while
+    downloading archive informations, which can decrease the time needed for
+    update on slow machines. See apt.conf (5) manpage for details.
+  * APT manages his manpage translations now with po4a, thanks to Nicolas
+    François and Kurasawa Nozomu, who also provide the ja translation.
+    Thanks to Christian Perrier we have already a fr translation and
+    a few more are hopefully added in the near future.
+  * This version also introduces some _experimental_ configuration options
+    to make more aggressive use of dpkg's triggers. If you want to help
+    testing these _experimental_ options see apt.conf (5) manpage.
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Thu, 24 Sep 2009 15:13:16 +0200
+
+apt (0.7.23) unstable; urgency=low
+
+  * Code that determines which proxy to use was changed. Now
+    'Acquire::{http,ftp}::Proxy[::<host>]' options have the highest priority,
+    and '{http,ftp}_proxy' environment variables are used only if options
+    mentioned above are not specified.
+
+ -- Eugene V. Lyubimkin <jackyf.devel@gmail.com>  Thu, 19 Aug 2009 11:26:16 +0200
+
+apt (0.6.44) unstable; urgency=low
+
+  * apt-ftparchive --db now uses Berkeley DB_BTREE instead of DB_HASH. 
+    If you use a database created by an older version of apt, delete 
+    it and allow it to be recreated the next time.
+
+ -- Michael Vogt <mvo@debian.org>  Wed, 26 Apr 2006 12:57:53 +0200
+
+apt (0.5.25) unstable; urgency=low
+
+  * apt-ftparchive --db now uses Berkeley DB version 4.2.  If used with a
+    database created by an older version of apt, an attempt will be made
+    to upgrade the database, but this may not work in all cases.  If your
+    database is not automatically upgraded, delete it and allow it to be
+    recreated the next time.
+
+ -- Matt Zimmerman <mdz@debian.org>  Sat,  8 May 2004 12:38:07 -0700
+

+ 0 - 18
debian/NEWS.Debian

@@ -1,18 +0,0 @@
-apt (0.6.44) unstable; urgency=low
-
-  * apt-ftparchive --db now uses Berkeley DB_BTREE instead of DB_HASH. 
-    If you use a database created by an older version of apt, delete 
-    it and allow it to be recreated the next time.
-
- -- Michael Vogt <mvo@debian.org>  Wed, 26 Apr 2006 12:57:53 +0200
-
-apt (0.5.25) unstable; urgency=low
-
-  * apt-ftparchive --db now uses Berkeley DB version 4.2.  If used with a
-    database created by an older version of apt, an attempt will be made
-    to upgrade the database, but this may not work in all cases.  If your
-    database is not automatically upgraded, delete it and allow it to be
-    recreated the next time.
-
- -- Matt Zimmerman <mdz@debian.org>  Sat,  8 May 2004 12:38:07 -0700
-

+ 0 - 6
debian/apt-utils.manpages

@@ -1,6 +0,0 @@
-doc/apt-extracttemplates.1
-doc/apt-ftparchive.1
-doc/apt-sortpkgs.1
-doc/fr/apt-extracttemplates.fr.1
-doc/fr/apt-ftparchive.fr.1
-doc/fr/apt-sortpkgs.fr.1

+ 1 - 0
debian/apt.conf.autoremove

@@ -4,5 +4,6 @@ APT
   { 
   { 
 	"^linux-image.*";  
 	"^linux-image.*";  
 	"^linux-restricted-modules.*";
 	"^linux-restricted-modules.*";
+	"^kfreebsd-image.*";  
   };
   };
 };
 };

+ 200 - 176
debian/apt.cron.daily

@@ -14,6 +14,9 @@
 #  Dir::Cache::Archive "archives/";
 #  Dir::Cache::Archive "archives/";
 #  - Set package archive directory
 #  - Set package archive directory
 #
 #
+#  APT::Periodic::Enable "1";
+#  - Enable the update/upgrade script (0=disable)
+#
 #  APT::Periodic::BackupArchiveInterval "0";
 #  APT::Periodic::BackupArchiveInterval "0";
 #  - Backup after n-days if archive contents changed.(0=disable)
 #  - Backup after n-days if archive contents changed.(0=disable)
 #
 #
@@ -46,7 +49,10 @@
 #    
 #    
 #  APT::Periodic::Download-Upgradeable-Packages "0";
 #  APT::Periodic::Download-Upgradeable-Packages "0";
 #  - Do "apt-get upgrade --download-only" every n-days (0=disable)
 #  - Do "apt-get upgrade --download-only" every n-days (0=disable)
-# 
+#
+#  APT::Periodic::Download-Upgradeable-Packages-Debdelta "1";
+#  - Use debdelta-upgrade to download updates if available (0=disable)
+#
 #  APT::Periodic::Unattended-Upgrade "0";
 #  APT::Periodic::Unattended-Upgrade "0";
 #  - Run the "unattended-upgrade" security upgrade script 
 #  - Run the "unattended-upgrade" security upgrade script 
 #    every n-days (0=disabled)
 #    every n-days (0=disabled)
@@ -69,26 +75,50 @@ check_stamp()
     interval="$2"
     interval="$2"
 
 
     if [ $interval -eq 0 ]; then
     if [ $interval -eq 0 ]; then
-	debug_echo "check_stamp: interval=0."
+	debug_echo "check_stamp: interval=0"
 	# treat as no time has passed
 	# treat as no time has passed
         return 1
         return 1
     fi
     fi
 
 
     if [ ! -f $stamp ]; then
     if [ ! -f $stamp ]; then
-    	update_stamp $stamp
 	debug_echo "check_stamp: missing time stamp file: $stamp."
 	debug_echo "check_stamp: missing time stamp file: $stamp."
 	# treat as enough time has passed
 	# treat as enough time has passed
         return 0
         return 0
     fi
     fi
 
 
     # compare midnight today to midnight the day the stamp was updated
     # compare midnight today to midnight the day the stamp was updated
-    stamp=$(date -r $stamp '+%s')
+    stamp_file="$stamp"
+    stamp=$(date --date=$(date -r $stamp_file --iso-8601) +%s 2>/dev/null)
+    if [ "$?" != "0" ]; then
+        # Due to some timezones returning 'invalid date' for midnight on
+        # certain dates (eg America/Sao_Paulo), if date returns with error
+        # remove the stamp file and return 0. See coreutils bug:
+        # http://lists.gnu.org/archive/html/bug-coreutils/2007-09/msg00176.html
+        rm -f "$stamp_file"
+        return 0
+    fi
+
+    now=$(date --date=$(date --iso-8601) +%s 2>/dev/null)
+    if [ "$?" != "0" ]; then
+        # As above, due to some timezones returning 'invalid date' for midnight
+        # on certain dates (eg America/Sao_Paulo), if date returns with error
+        # return 0.
+        return 0
+    fi
+
     delta=$(($now-$stamp))
     delta=$(($now-$stamp))
 
 
     # intervall is in days, convert to sec.
     # intervall is in days, convert to sec.
     interval=$(($interval*60*60*24))
     interval=$(($interval*60*60*24))
     debug_echo "check_stamp: interval=$interval, now=$now, stamp=$stamp, delta=$delta (sec)"
     debug_echo "check_stamp: interval=$interval, now=$now, stamp=$stamp, delta=$delta (sec)"
 
 
+    # remove timestamps a day (or more) in the future and force re-check
+    if [ $stamp -gt $(($now+86400)) ]; then
+         echo "WARNING: file $stamp_file has a timestamp in the future: $stamp"
+         rm -f "$stamp_file"
+         return 0
+    fi
+
     if [ $delta -ge $interval ]; then
     if [ $delta -ge $interval ]; then
         return 0
         return 0
     fi
     fi
@@ -105,18 +135,25 @@ update_stamp()
 # we check here if autoclean was enough sizewise
 # we check here if autoclean was enough sizewise
 check_size_constraints()
 check_size_constraints()
 {
 {
-    # min-age in days
     MaxAge=0
     MaxAge=0
-    MinAge=2
-    MaxSize=0
-    CacheDir="var/cache/apt"
-    CacheArchive="archives/"
     eval $(apt-config shell MaxAge APT::Archives::MaxAge)
     eval $(apt-config shell MaxAge APT::Archives::MaxAge)
+    eval $(apt-config shell MaxAge APT::Periodic::MaxAge)
+
+    MinAge=2
     eval $(apt-config shell MinAge APT::Archives::MinAge)
     eval $(apt-config shell MinAge APT::Archives::MinAge)
+    eval $(apt-config shell MinAge APT::Periodic::MinAge)
+
+    MaxSize=0
     eval $(apt-config shell MaxSize APT::Archives::MaxSize)
     eval $(apt-config shell MaxSize APT::Archives::MaxSize)
-    eval $(apt-config shell Dir Dir)
+    eval $(apt-config shell MaxSize APT::Periodic::MaxSize)
+
+    CacheDir="var/cache/apt/"
     eval $(apt-config shell CacheDir Dir::Cache)
     eval $(apt-config shell CacheDir Dir::Cache)
+    CacheDir=${CacheDir%/}
+
+    CacheArchive="archives/"
     eval $(apt-config shell CacheArchive Dir::Cache::archives)
     eval $(apt-config shell CacheArchive Dir::Cache::archives)
+    CacheArchive=${CacheArchive%/}
 
 
     # sanity check
     # sanity check
     if [ -z "$CacheDir" -o -z "$CacheArchive" ]; then
     if [ -z "$CacheDir" -o -z "$CacheArchive" ]; then
@@ -128,9 +165,13 @@ check_size_constraints()
 
 
     # check age
     # check age
     if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
     if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
+	debug_echo "aged: ctime <$MaxAge and mtime <$MaxAge and ctime>$MinAge and mtime>$MinAge"
 	find $Cache -name "*.deb"  \( -mtime +$MaxAge -and -ctime +$MaxAge \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) -print0 | xargs -r -0 rm -f
 	find $Cache -name "*.deb"  \( -mtime +$MaxAge -and -ctime +$MaxAge \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) -print0 | xargs -r -0 rm -f
     elif [ ! $MaxAge -eq 0 ]; then
     elif [ ! $MaxAge -eq 0 ]; then
+	debug_echo "aged: ctime <$MaxAge and mtime <$MaxAge only"
 	find $Cache -name "*.deb"  -ctime +$MaxAge -and -mtime +$MaxAge -print0 | xargs -r -0 rm -f
 	find $Cache -name "*.deb"  -ctime +$MaxAge -and -mtime +$MaxAge -print0 | xargs -r -0 rm -f
+    else
+	debug_echo "skip aging since MaxAge is 0"
     fi
     fi
     
     
     # check size
     # check size
@@ -148,11 +189,12 @@ check_size_constraints()
 	    size=${du%%/*}
 	    size=${du%%/*}
 	    # check if the cache is small enough
 	    # check if the cache is small enough
 	    if [ $size -lt $MaxSize ]; then
 	    if [ $size -lt $MaxSize ]; then
+		debug_echo "end remove by archive size:  size=$size < $MaxSize"
 		break
 		break
 	    fi
 	    fi
 
 
 	    # check for MinAge of the file
 	    # check for MinAge of the file
-	    if [ ! $MinAge -eq 0 ]; then 
+	    if [ $MinAge -ne 0 ]; then 
 		# check both ctime and mtime 
 		# check both ctime and mtime 
 		mtime=$(stat -c %Y $file)
 		mtime=$(stat -c %Y $file)
 		ctime=$(stat -c %Z $file)
 		ctime=$(stat -c %Z $file)
@@ -161,19 +203,94 @@ check_size_constraints()
 		else
 		else
 		    delta=$(($now-$ctime))
 		    delta=$(($now-$ctime))
 		fi
 		fi
-		#echo "$file ($delta), $MinAge"
 		if [ $delta -le $MinAge ]; then
 		if [ $delta -le $MinAge ]; then
-		    #echo "Skiping $file (delta=$delta)"
+		    debug_echo "skip remove by archive size:  $file, delta=$delta < $MinAgeSec"
 		    break
 		    break
+		else
+		    # delete oldest file
+		    debug_echo "remove by archive size: $file, delta=$delta >= $MinAgeSec (sec), size=$size >= $MaxSize"
+		    rm -f $file
 		fi
 		fi
 	    fi
 	    fi
-
-	    # delete oldest file
-	    rm -f $file
 	done
 	done
     fi
     fi
 }
 }
 
 
+# deal with the Apt::Periodic::BackupArchiveInterval
+do_cache_backup()
+{
+    BackupArchiveInterval="$1"
+    if [ $BackupArchiveInterval -eq 0 ]; then
+	return
+    fi
+
+    # Set default values and normalize
+    Dir="/"
+    eval $(apt-config shell Dir Dir)
+    Dir=${Dir%/}
+
+    CacheDir="var/cache/apt/"
+    eval $(apt-config shell CacheDir Dir::Cache)
+    CacheDir=${CacheDir%/}
+    if [ -z "$CacheDir" ]; then
+	debug_echo "practically empty Dir::Cache, exiting"
+	return 0
+    fi
+
+    CacheArchive="archives/"
+    eval $(apt-config shell CacheArchive Dir::Cache::Archives)
+    CacheArchive=${CacheArchive%/}
+    if [ -z "$CacheArchive" ]; then
+	debug_echo "practically empty Dir::Cache::archives, exiting"
+	return 0
+    fi
+
+    BackupLevel=3
+    eval $(apt-config shell BackupLevel APT::Periodic::BackupLevel)
+    if [ $BackupLevel -le 1 ]; then 
+	BackupLevel=2 ; 
+    fi
+    
+    CacheBackup="backup/"
+    eval $(apt-config shell CacheBackup Dir::Cache::Backup)
+    CacheBackup=${CacheBackup%/}
+    if [ -z "$CacheBackup" ]; then
+	echo "practically empty Dir::Cache::Backup, exiting" 1>&2
+	return
+    fi
+
+    Cache="${Dir}/${CacheDir}/${CacheArchive}/"
+    Back="${Dir}/${CacheDir}/${CacheBackup}/"
+    BackX="${Back}${CacheArchive}/"
+    for x in $(seq 0 1 $((${BackupLevel}-1))); do 
+	eval "Back${x}=${Back}${x}/"
+    done
+    
+    # backup after n-days if archive contents changed.
+    # (This uses hardlink to save disk space)
+    BACKUP_ARCHIVE_STAMP=/var/lib/apt/periodic/backup-archive-stamp
+    if check_stamp $BACKUP_ARCHIVE_STAMP $BackupArchiveInterval; then
+	if [ $({(cd $Cache 2>/dev/null; find . -name "*.deb"); (cd $Back0 2>/dev/null;find . -name "*.deb") ;}| sort|uniq -u|wc -l) -ne 0 ]; then
+	    mkdir -p $Back
+	    rm -rf $Back$((${BackupLevel}-1))
+	    for y in $(seq $((${BackupLevel}-1)) -1 1); do 
+		eval BackY=${Back}$y
+		eval BackZ=${Back}$(($y-1))
+		if [ -e $BackZ ]; then 
+		    mv -f $BackZ $BackY ; 
+		fi
+	    done
+	    cp -la $Cache $Back ; mv -f $BackX $Back0
+	    update_stamp $BACKUP_ARCHIVE_STAMP
+	    debug_echo "backup with hardlinks. (success)"
+	else
+	    debug_echo "skip backup since same content."
+	fi
+    else
+	debug_echo "skip backup since too new."
+    fi
+}
+
 # sleep for a random interval of time (default 30min)
 # sleep for a random interval of time (default 30min)
 # (some code taken from cron-apt, thanks)
 # (some code taken from cron-apt, thanks)
 random_sleep()
 random_sleep()
@@ -188,6 +305,7 @@ random_sleep()
 	RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5")
 	RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5")
     fi
     fi
     TIME=$(($RANDOM % $RandomSleep))
     TIME=$(($RANDOM % $RandomSleep))
+    debug_echo "sleeping for $TIME seconds"
     sleep $TIME
     sleep $TIME
 }
 }
 
 
@@ -200,18 +318,25 @@ debug_echo()
     fi
     fi
 }
 }
 
 
-# main
+# ------------------------ main ----------------------------
 
 
 # check apt-config exstance
 # check apt-config exstance
 if ! which apt-config >/dev/null ; then
 if ! which apt-config >/dev/null ; then
 	exit 0
 	exit 0
 fi
 fi
 
 
+# check if the user really wants to do something
+AutoAptEnable=1  # default is yes
+eval $(apt-config shell AutoAptEnable APT::Periodic::Enable)
+
+if [ $AutoAptEnable -eq 0 ]; then
+    exit 0
+fi
+
 # Set VERBOSE mode from  apt-config (or inherit from environment)
 # Set VERBOSE mode from  apt-config (or inherit from environment)
+VERBOSE=0
 eval $(apt-config shell VERBOSE APT::Periodic::Verbose)
 eval $(apt-config shell VERBOSE APT::Periodic::Verbose)
-if [ -z "$VERBOSE" ]; then
-    VERBOSE="0"
-fi
+debug_echo "verbose level $VERBOSE"
 if [ "$VERBOSE" -le 2 ]; then
 if [ "$VERBOSE" -le 2 ]; then
     # quiet for 0,1,2
     # quiet for 0,1,2
     XSTDOUT=">/dev/null"
     XSTDOUT=">/dev/null"
@@ -238,74 +363,25 @@ if which on_ac_power >/dev/null; then
     on_ac_power
     on_ac_power
     POWER=$?
     POWER=$?
     if [ $POWER -eq 1 ]; then
     if [ $POWER -eq 1 ]; then
-	debug_echo "exit: system on main power."
+	debug_echo "exit: system NOT on main power"
 	exit 0
 	exit 0
     elif [ $POWER -ne 0 ]; then
     elif [ $POWER -ne 0 ]; then
-	debug_echo "exit: power status ($POWER) undetermined."
-	exit 0
+	debug_echo "power status ($POWER) undetermined, continuing"
     fi
     fi
     debug_echo "system is on main power."
     debug_echo "system is on main power."
 fi
 fi
 
 
 # check if we can lock the cache and if the cache is clean
 # check if we can lock the cache and if the cache is clean
-if which apt-get >/dev/null && ! eval apt-get check $XAPTOPT $XSTDERR ; then
+if which apt-get >/dev/null && ! eval apt-get check -f $XAPTOPT $XSTDERR ; then
     debug_echo "error encountered in cron job with \"apt-get check\"."
     debug_echo "error encountered in cron job with \"apt-get check\"."
     exit 0
     exit 0
 fi
 fi
-# No need to check for apt-get below
 
 
 # Global current time in seconds since 1970-01-01 00:00:00 UTC
 # Global current time in seconds since 1970-01-01 00:00:00 UTC
 now=$(date +%s)
 now=$(date +%s)
 
 
-# Set default values and normalize
-Dir="/"
-eval $(apt-config shell Dir Dir)
-Dir=${Dir%/}
-
-CacheDir="var/cache/apt/"
-eval $(apt-config shell CacheDir Dir::Cache)
-CacheDir=${CacheDir%/}
-if [ -z "$CacheDir" ]; then
-    debug_echo "practically empty Dir::Cache, exiting"
-    exit 0
-fi
-
-CacheArchive="archives/"
-eval $(apt-config shell CacheArchive Dir::Cache::Archives)
-CacheArchive=${CacheArchive%/}
-if [ -z "$CacheArchive" ]; then
-    debug_echo "practically empty Dir::Cache::archives, exiting"
-    exit 0
-fi
-
-BackupArchiveInterval=0
-eval $(apt-config shell BackupArchiveInterval APT::Periodic::BackupArchiveInterval)
-
-BackupLevel=3
-eval $(apt-config shell BackupLevel APT::Periodic::BackupLevel)
-if [ $BackupLevel -le 1 ]; then BackupLevel=2 ; fi
-
-CacheBackup="backup/"
-eval $(apt-config shell CacheBackup Dir::Cache::Backup)
-CacheBackup=${CacheBackup%/}
-if [ -z "$CacheBackup" ]; then
-    echo "practically empty Dir::Cache::Backup, exiting" 1>&2
-    exit 0
-fi
-
 # Support old Archive for compatibility.
 # Support old Archive for compatibility.
 # Document only Periodic for all controling parameters of this script.
 # Document only Periodic for all controling parameters of this script.
-MaxAge=0
-eval $(apt-config shell MaxAge APT::Archives::MaxAge)
-eval $(apt-config shell MaxAge APT::Periodic::MaxAge)
-
-MinAge=2
-eval $(apt-config shell MinAge APT::Archives::MinAge)
-eval $(apt-config shell MinAge APT::Periodic::MinAge)
-
-MaxSize=0
-eval $(apt-config shell MaxSize APT::Archives::MaxSize)
-eval $(apt-config shell MaxSize APT::Periodic::MaxSize)
 
 
 UpdateInterval=0
 UpdateInterval=0
 eval $(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists)
 eval $(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists)
@@ -319,95 +395,34 @@ eval $(apt-config shell UnattendedUpgradeInterval APT::Periodic::Unattended-Upgr
 AutocleanInterval=0
 AutocleanInterval=0
 eval $(apt-config shell AutocleanInterval APT::Periodic::AutocleanInterval)
 eval $(apt-config shell AutocleanInterval APT::Periodic::AutocleanInterval)
 
 
-Cache="${Dir}/${CacheDir}/${CacheArchive}/"
-Back="${Dir}/${CacheDir}/${CacheBackup}/"
-BackX="${Back}${CacheArchive}/"
-for x in $(seq 0 1 $((${BackupLevel}-1))); do 
-    eval "Back${x}=${Back}${x}/"
-done
+BackupArchiveInterval=0
+eval $(apt-config shell BackupArchiveInterval APT::Periodic::BackupArchiveInterval)
 
 
-# check if we actually have to do anything
+Debdelta=1
+eval $(apt-config shell Debdelta APT::Periodic::Download-Upgradeable-Packages-Debdelta)
+
+# check if we actually have to do anything that requires locking the cache
 if [ $UpdateInterval -eq 0 ] &&
 if [ $UpdateInterval -eq 0 ] &&
    [ $DownloadUpgradeableInterval -eq 0 ] &&
    [ $DownloadUpgradeableInterval -eq 0 ] &&
    [ $UnattendedUpgradeInterval -eq 0 ] &&
    [ $UnattendedUpgradeInterval -eq 0 ] &&
    [ $BackupArchiveInterval -eq 0 ] &&
    [ $BackupArchiveInterval -eq 0 ] &&
    [ $AutocleanInterval -eq 0 ]; then
    [ $AutocleanInterval -eq 0 ]; then
-    exit 0
-fi
 
 
+    # check cache size
+    check_size_constraints
 
 
-# backup after n-days if archive contents changed.
-# (This uses hardlink to save disk space)
-BACKUP_ARCHIVE_STAMP=/var/lib/apt/periodic/backup-archive-stamp
-if check_stamp $BACKUP_ARCHIVE_STAMP $BackupArchiveInterval; then
-    if [ $({(cd $Cache 2>/dev/null; find . -name "*.deb"); (cd $Back0 2>/dev/null;find . -name "*.deb") ;}| sort|uniq -u|wc -l) -ne 0 ]; then
-	mkdir -p $Back
-	rm -rf $Back$((${BackupLevel}-1))
-	for y in $(seq $((${BackupLevel}-1)) -1 1); do 
-	    eval BackY=${Back}$y
-	    eval BackZ=${Back}$(($y-1))
-	    if [ -e $BackZ ]; then mv -f $BackZ $BackY ; fi
-	done
-	cp -la $Cache $Back ; mv -f $BackX $Back0
-	update_stamp $BACKUP_ARCHIVE_STAMP
-	debug_echo "backup with hardlinks. (success)"
-    else
-
-	debug_echo "skip backup since same content."
-    fi
-else
-	debug_echo "skip backup since too new."
-fi
-
-# package archive contnts removal by package age
-if [ $MaxAge -ne 0 ] && [ $MinAge -ne 0 ]; then
-    find $Cache -name "*.deb"  \( -mtime +$MaxAge -and -ctime +$MaxAge \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) -print0 | xargs -r -0 rm -f
-    debug_echo "aged: ctime <$MaxAge and mtime <$MaxAge and ctime>$MinAge and mtime>$MinAge"
-elif [ $MaxAge -ne 0 ]; then
-    find $Cache -name "*.deb"  -ctime +$MaxAge -and -mtime +$MaxAge -print0 | xargs -r -0 rm -f
-    debug_echo "aged: ctime <$MaxAge and mtime <$MaxAge only"
-else
-    debug_echo "skip aging since MaxAge is 0"
+    exit 0
 fi
 fi
-    
-# package archive contnts removal down to $MaxSize
-if [ $MaxSize -ne 0 ]; then
-
-    MinAgeSec=$(($MinAge*24*60*60))
-
-    # reverse-sort by mtime
-    for file in $(ls -rt $Cache/*.deb 2>/dev/null); do 
-	du=$(du -m -s $Cache)
-	size=${du%%/*}
-	# check if the cache is small enough
-	if [ $size -lt $MaxSize ]; then
-	    debug_echo "end remove by archive size:  size=$size < $MaxSize"
-	    break
-	fi
 
 
-	# check for MinAge in second of the file
-	if [ $MinAgeSec -ne 0 ]; then 
-	    # check both ctime and mtime 
-	    mtime=$(stat -c %Y $file)
-	    ctime=$(stat -c %Z $file)
-	    if [ $mtime -gt $ctime ]; then
-		delta=$(($now-$mtime))
-	    else
-		delta=$(($now-$ctime))
-	    fi
-	    if [ $delta -le $MinAgeSec ]; then
-		debug_echo "skip remove by archive size:  $file, delta=$delta < $MinAgeSec"
-	    else
-		# delete oldest file
-		debug_echo "remove by archive size: $file, delta=$delta >= $MinAgeSec (sec), size=$size >= $MaxSize"
-		rm -f $file
-	    fi
-	fi
+# deal with BackupArchiveInterval
+do_cache_backup $BackupArchiveInterval
 
 
-    done
-fi
+# sleep random amount of time to avoid hitting the 
+# mirrors at the same time
+random_sleep
 
 
 # update package lists
 # update package lists
+UPDATED=0
 UPDATE_STAMP=/var/lib/apt/periodic/update-stamp
 UPDATE_STAMP=/var/lib/apt/periodic/update-stamp
 if check_stamp $UPDATE_STAMP $UpdateInterval; then
 if check_stamp $UPDATE_STAMP $UpdateInterval; then
     if eval apt-get $XAPTOPT -y update $XSTDERR; then
     if eval apt-get $XAPTOPT -y update $XSTDERR; then
@@ -422,50 +437,59 @@ if check_stamp $UPDATE_STAMP $UpdateInterval; then
 	    debug_echo "dbus signal not send (command not available)"
 	    debug_echo "dbus signal not send (command not available)"
 	fi
 	fi
 	update_stamp $UPDATE_STAMP
 	update_stamp $UPDATE_STAMP
-	# download all upgradeable packages if it is requested
-	DOWNLOAD_UPGRADEABLE_STAMP=/var/lib/apt/periodic/download-upgradeable-stamp
-	if check_stamp $DOWNLOAD_UPGRADEABLE_STAMP $DownloadUpgradeableInterval; then
-	    if eval apt-get $XAPTOPT -y -d dist-upgrade $XSTDERR; then
-		update_stamp $DOWNLOAD_UPGRADEABLE_STAMP
-		debug_echo "download upgradable (success)."
-		# auto upgrade all upgradeable packages
-		UPGRADE_STAMP=/var/lib/apt/periodic/upgrade-stamp
-		if which unattended-upgrade >/dev/null && check_stamp $UPGRADE_STAMP $UnattendedUpgradeInterval; then
-		    if unattended-upgrade $XUUPOPT; then
-			update_stamp $UPGRADE_STAMP
-			debug_echo "unattended-upgrade (success)."
-		    else
-			debug_echo "unattended-upgrade (error)."
-		    fi
-		else
-		    debug_echo "unattended-upgrade (not run)."
-		fi
-	    else
-		debug_echo "download upgradable (error)."
-	    fi
-	else
-	    debug_echo "download upgradable (not run)."
-	fi
+	UPDATED=1
     else
     else
-	debug_echo "download updated metadata (error)."
+	debug_echo "download updated metadata (error)"
     fi
     fi
 else
 else
     debug_echo "download updated metadata (not run)."
     debug_echo "download updated metadata (not run)."
 fi
 fi
+	
+# download all upgradeable packages (if it is requested)
+DOWNLOAD_UPGRADEABLE_STAMP=/var/lib/apt/periodic/download-upgradeable-stamp
+if [ $UPDATED -eq 1 ] && check_stamp $DOWNLOAD_UPGRADEABLE_STAMP $DownloadUpgradeableInterval; then
+    if [ $Debdelta -eq 1 ]; then
+        debdelta-upgrade >/dev/null 2>&1 || true
+    fi
+    if  eval apt-get $XAPTOPT -y -d dist-upgrade $XSTDERR; then
+	update_stamp $DOWNLOAD_UPGRADEABLE_STAMP
+	debug_echo "download upgradable (success)"
+    else
+	debug_echo "download upgradable (error)"
+    fi
+else
+    debug_echo "download upgradable (not run)"
+fi
+
+# auto upgrade all upgradeable packages
+UPGRADE_STAMP=/var/lib/apt/periodic/upgrade-stamp
+if [ $UPDATED -eq 1 ] && which unattended-upgrade >/dev/null && check_stamp $UPGRADE_STAMP $UnattendedUpgradeInterval; then
+    if unattended-upgrade $XUUPOPT; then
+	update_stamp $UPGRADE_STAMP
+	debug_echo "unattended-upgrade (success)"
+    else
+	debug_echo "unattended-upgrade (error)"
+    fi
+else
+    debug_echo "unattended-upgrade (not run)"
+fi
 
 
 # autoclean package archive
 # autoclean package archive
 AUTOCLEAN_STAMP=/var/lib/apt/periodic/autoclean-stamp
 AUTOCLEAN_STAMP=/var/lib/apt/periodic/autoclean-stamp
 if check_stamp $AUTOCLEAN_STAMP $AutocleanInterval; then
 if check_stamp $AUTOCLEAN_STAMP $AutocleanInterval; then
-    if apt-get $XAPTOPT -y autoclean $XSTDERR; then
+    if  eval apt-get $XAPTOPT -y autoclean $XSTDERR; then
 	debug_echo "autoclean (success)."
 	debug_echo "autoclean (success)."
 	update_stamp $AUTOCLEAN_STAMP
 	update_stamp $AUTOCLEAN_STAMP
     else
     else
-	debug_echo "autoclean (error)."
+	debug_echo "autoclean (error)"
     fi
     fi
 else
 else
-    debug_echo "autoclean (not run)."
+    debug_echo "autoclean (not run)"
 fi
 fi
 
 
+# check cache size 
+check_size_constraints
+
 #
 #
 #     vim: set sts=4 ai :
 #     vim: set sts=4 ai :
 #
 #

+ 1 - 0
debian/apt.dirs

@@ -3,6 +3,7 @@ usr/lib/apt/methods
 usr/lib/dpkg/methods/apt
 usr/lib/dpkg/methods/apt
 etc/apt
 etc/apt
 etc/apt/apt.conf.d
 etc/apt/apt.conf.d
+etc/apt/preferences.d
 etc/apt/sources.list.d
 etc/apt/sources.list.d
 etc/logrotate.d
 etc/logrotate.d
 var/cache/apt/archives/partial
 var/cache/apt/archives/partial

+ 0 - 0
debian/apt.logrotate


Некоторые файлы не были показаны из-за большого количества измененных файлов