]> git.saurik.com Git - apt.git/commitdiff
* apt-pkg/deb/dpkgpm.cc:
authorMichael Vogt <mvo@debian.org>
Fri, 9 Jul 2010 17:14:44 +0000 (19:14 +0200)
committerMichael Vogt <mvo@debian.org>
Fri, 9 Jul 2010 17:14:44 +0000 (19:14 +0200)
  - make the apt/term.log output unbuffered (thanks to Matt Zimmerman)

1  2 
apt-pkg/deb/dpkgpm.cc
debian/changelog

diff --combined apt-pkg/deb/dpkgpm.cc
index 9af7a0792d1b5c79439b2003af229cf5d3c4c46f,2bbc7a4bac1afd832c3d39ab39d63abb284e1845..67291063c52d565d199eba2556f30247f0f0c084
@@@ -12,7 -12,6 +12,7 @@@
  #include <apt-pkg/error.h>
  #include <apt-pkg/configuration.h>
  #include <apt-pkg/depcache.h>
 +#include <apt-pkg/pkgrecords.h>
  #include <apt-pkg/strutl.h>
  #include <apti18n.h>
  #include <apt-pkg/fileutl.h>
@@@ -26,7 -25,6 +26,7 @@@
  #include <sys/wait.h>
  #include <signal.h>
  #include <errno.h>
 +#include <string.h>
  #include <stdio.h>
  #include <string.h>
  #include <algorithm>
@@@ -53,7 -51,6 +53,7 @@@ namespac
      std::make_pair("configure", N_("Configuring %s")),
      std::make_pair("remove",    N_("Removing %s")),
      std::make_pair("purge",    N_("Completely removing %s")),
 +    std::make_pair("disappear", N_("Noting disappearance of %s")),
      std::make_pair("trigproc",  N_("Running post-installation trigger %s"))
    };
  
@@@ -109,7 -106,7 +109,7 @@@ ionice(int PID
  /* */
  pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) 
     : pkgPackageManager(Cache), dpkgbuf_pos(0),
 -     term_out(NULL), PackagesDone(0), PackagesTotal(0)
 +     term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0)
  {
  }
                                                                        /*}}}*/
@@@ -128,19 -125,7 +128,19 @@@ bool pkgDPkgPM::Install(PkgIterator Pkg
     if (File.empty() == true || Pkg.end() == true)
        return _error->Error("Internal Error, No file name for %s",Pkg.Name());
  
 -   List.push_back(Item(Item::Install,Pkg,File));
 +   // If the filename string begins with DPkg::Chroot-Directory, return the
 +   // substr that is within the chroot so dpkg can access it.
 +   string const chrootdir = _config->FindDir("DPkg::Chroot-Directory","/");
 +   if (chrootdir != "/" && File.find(chrootdir) == 0)
 +   {
 +      size_t len = chrootdir.length();
 +      if (chrootdir.at(len - 1) == '/')
 +        len--;
 +      List.push_back(Item(Item::Install,Pkg,File.substr(len)));
 +   }
 +   else
 +      List.push_back(Item(Item::Install,Pkg,File));
 +
     return true;
  }
                                                                        /*}}}*/
@@@ -357,6 -342,7 +357,6 @@@ bool pkgDPkgPM::RunScriptsWithPkgs(cons
  
     return true;
  }
 -
                                                                        /*}}}*/
  // DPkgPM::DoStdin - Read stdin and pass to slave pty                 /*{{{*/
  // ---------------------------------------------------------------------
@@@ -422,12 -408,11 +422,12 @@@ void pkgDPkgPM::ProcessDpkgStatusLine(i
        'processing: install: pkg'
        'processing: configure: pkg'
        'processing: remove: pkg'
 -      'processing: purge: pkg' - but for apt is it a ignored "unknown" action
 +      'processing: purge: pkg'
 +      'processing: disappear: pkg'
        'processing: trigproc: trigger'
            
     */
 -   char* list[5];
 +   char* list[6];
     //        dpkg sends multiline error messages sometimes (see
     //        #374195 for a example. we should support this by
     //        either patching dpkg to not send multiline over the
         write(OutStatusFd, status.str().c_str(), status.str().size());
        if (Debug == true)
         std::clog << "send: '" << status.str() << "'" << endl;
 +
 +      if (strncmp(action, "disappear", strlen("disappear")) == 0)
 +       handleDisappearAction(pkg_or_trigger);
        return;
     }
  
     if(strncmp(action,"error",strlen("error")) == 0)
     {
 +      // urgs, sometime has ":" in its error string so that we
 +      // end up with the error message split between list[3]
 +      // and list[4], e.g. the message: 
 +      // "failed in buffer_write(fd) (10, ret=-1): backend dpkg-deb ..."
 +      // concat them again
 +      if( list[4] != NULL )
 +       list[3][strlen(list[3])] = ':';
 +
        status << "pmerror:" << list[1]
             << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
             << ":" << list[3]
         write(OutStatusFd, status.str().c_str(), status.str().size());
        if (Debug == true)
         std::clog << "send: '" << status.str() << "'" << endl;
 +      pkgFailures++;
 +      WriteApportReport(list[1], list[3]);
        return;
     }
     else if(strncmp(action,"conffile",strlen("conffile")) == 0)
                << " action: " << action << endl;
  }
                                                                        /*}}}*/
 +// DPkgPM::handleDisappearAction                                      /*{{{*/
 +void pkgDPkgPM::handleDisappearAction(string const &pkgname)
 +{
 +   // record the package name for display and stuff later
 +   disappearedPkgs.insert(pkgname);
 +
 +   pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname);
 +   if (unlikely(Pkg.end() == true))
 +      return;
 +   // the disappeared package was auto-installed - nothing to do
 +   if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
 +      return;
 +   pkgCache::VerIterator PkgVer = Pkg.CurrentVer();
 +   if (unlikely(PkgVer.end() == true))
 +      return;
 +   /* search in the list of dependencies for (Pre)Depends,
 +      check if this dependency has a Replaces on our package
 +      and if so transfer the manual installed flag to it */
 +   for (pkgCache::DepIterator Dep = PkgVer.DependsList(); Dep.end() != true; ++Dep)
 +   {
 +      if (Dep->Type != pkgCache::Dep::Depends &&
 +        Dep->Type != pkgCache::Dep::PreDepends)
 +       continue;
 +      pkgCache::PkgIterator Tar = Dep.TargetPkg();
 +      if (unlikely(Tar.end() == true))
 +       continue;
 +      // the package is already marked as manual
 +      if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto)
 +       continue;
 +      pkgCache::VerIterator TarVer = Tar.CurrentVer();
 +      for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep)
 +      {
 +       if (Rep->Type != pkgCache::Dep::Replaces)
 +          continue;
 +       if (Pkg != Rep.TargetPkg())
 +          continue;
 +       // okay, they are strongly connected - transfer manual-bit
 +       if (Debug == true)
 +          std::clog << "transfer manual-bit from disappeared »" << pkgname << "« to »" << Tar.FullName() << "«" << std::endl;
 +       Cache[Tar].Flags &= ~Flag::Auto;
 +       break;
 +      }
 +   }
 +}
 +                                                                      /*}}}*/
  // DPkgPM::DoDpkgStatusFd                                             /*{{{*/
  // ---------------------------------------------------------------------
  /*
@@@ -625,50 -552,48 +625,50 @@@ void pkgDPkgPM::DoDpkgStatusFd(int stat
  }
                                                                        /*}}}*/
  // DPkgPM::WriteHistoryTag                                            /*{{{*/
 -void pkgDPkgPM::WriteHistoryTag(string tag, string value)
 +void pkgDPkgPM::WriteHistoryTag(string const &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());
 -   }
 +   size_t const length = value.length();
 +   if (length == 0)
 +      return;
 +   // poor mans rstrip(", ")
 +   if (value[length-2] == ',' && value[length-1] == ' ')
 +      value.erase(length - 2, 2);
 +   fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
  }                                                                     /*}}}*/
  // DPkgPM::OpenLog                                                    /*{{{*/
  bool pkgDPkgPM::OpenLog()
  {
 -   string logdir = _config->FindDir("Dir::Log");
 +   string const logdir = _config->FindDir("Dir::Log");
     if(not FileExists(logdir))
        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);
 +   time_t const t = time(NULL);
 +   struct tm const * const tmp = localtime(&t);
     strftime(timestr, sizeof(timestr), "%F  %T", tmp);
  
     // open terminal log
 -   string logfile_name = flCombine(logdir,
 +   string const logfile_name = flCombine(logdir,
                                   _config->Find("Dir::Log::Terminal"));
     if (!logfile_name.empty())
     {
        term_out = fopen(logfile_name.c_str(),"a");
        if (term_out == NULL)
 -       return _error->WarningE(_("Could not open file '%s'"), logfile_name.c_str());
 +       return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
+       setvbuf(term_out, NULL, _IONBF, 0);
        chmod(logfile_name.c_str(), 0600);
        fprintf(term_out, "\nLog started: %s\n", timestr);
     }
  
 -   // write 
 -   string history_name = flCombine(logdir,
 +   // write your history
 +   string const history_name = flCombine(logdir,
                                   _config->Find("Dir::Log::History"));
     if (!history_name.empty())
     {
        history_out = fopen(history_name.c_str(),"a");
 +      if (history_out == NULL)
 +       return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
        chmod(history_name.c_str(), 0644);
        fprintf(history_out, "\nStart-Date: %s\n", timestr);
        string remove, purge, install, upgrade, downgrade;
               remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");     
         }
        }
 +      if (_config->Exists("Commandline::AsString") == true)
 +       WriteHistoryTag("Commandline", _config->Find("Commandline::AsString"));
        WriteHistoryTag("Install", install);
        WriteHistoryTag("Upgrade", upgrade);
        WriteHistoryTag("Downgrade",downgrade);
@@@ -720,27 -643,11 +720,27 @@@ bool pkgDPkgPM::CloseLog(
  
     if(history_out)
     {
 -      if (dpkg_error.size() > 0)
 +      if (disappearedPkgs.empty() == false)
 +      {
 +       string disappear;
 +       for (std::set<std::string>::const_iterator d = disappearedPkgs.begin();
 +            d != disappearedPkgs.end(); ++d)
 +       {
 +          pkgCache::PkgIterator P = Cache.FindPkg(*d);
 +          disappear.append(*d);
 +          if (P.end() == true)
 +             disappear.append(", ");
 +          else
 +             disappear.append(" (").append(Cache[P].CurVersion).append("), ");
 +       }
 +       WriteHistoryTag("Disappeared", disappear);
 +      }
 +      if (dpkg_error.empty() == false)
         fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
        fprintf(history_out, "End-Date: %s\n", timestr);
        fclose(history_out);
     }
 +   history_out = NULL;
  
     return true;
  }
@@@ -988,8 -895,6 +988,8 @@@ bool pkgDPkgPM::Go(int OutStatusFd
         {
            if((*I).Pkg.end() == true)
               continue;
 +          if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
 +             continue;
            Args[n++] = I->Pkg.Name();
            Size += strlen(Args[n-1]);
         }       
  
         // wait for input or output here
         FD_ZERO(&rfds);
 -       if (!stdin_is_dev_null)
 +       if (master >= 0 && !stdin_is_dev_null)
            FD_SET(0, &rfds); 
         FD_SET(_dpkgin, &rfds);
         if(master >= 0)
@@@ -1247,186 -1152,3 +1247,186 @@@ void pkgDPkgPM::Reset(
     List.erase(List.begin(),List.end());
  }
                                                                        /*}}}*/
 +// pkgDpkgPM::WriteApportReport - write out error report pkg failure  /*{{{*/
 +// ---------------------------------------------------------------------
 +/* */
 +void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) 
 +{
 +   string pkgname, reportfile, srcpkgname, pkgver, arch;
 +   string::size_type pos;
 +   FILE *report;
 +
 +   if (_config->FindB("Dpkg::ApportFailureReport", false) == false)
 +   {
 +      std::clog << "configured to not write apport reports" << std::endl;
 +      return;
 +   }
 +
 +   // only report the first errors
 +   if(pkgFailures > _config->FindI("APT::Apport::MaxReports", 3))
 +   {
 +      std::clog << _("No apport report written because MaxReports is reached already") << std::endl;
 +      return;
 +   }
 +
 +   // check if its not a follow up error 
 +   const char *needle = dgettext("dpkg", "dependency problems - leaving unconfigured");
 +   if(strstr(errormsg, needle) != NULL) {
 +      std::clog << _("No apport report written because the error message indicates its a followup error from a previous failure.") << std::endl;
 +      return;
 +   }
 +
 +   // do not report disk-full failures 
 +   if(strstr(errormsg, strerror(ENOSPC)) != NULL) {
 +      std::clog << _("No apport report written because the error message indicates a disk full error") << std::endl;
 +      return;
 +   }
 +
 +   // do not report out-of-memory failures 
 +   if(strstr(errormsg, strerror(ENOMEM)) != NULL) {
 +      std::clog << _("No apport report written because the error message indicates a out of memory error") << std::endl;
 +      return;
 +   }
 +
 +   // do not report dpkg I/O errors
 +   // XXX - this message is localized, but this only matches the English version.  This is better than nothing.
 +   if(strstr(errormsg, "short read in buffer_copy (")) {
 +      std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl;
 +      return;
 +   }
 +
 +   // get the pkgname and reportfile
 +   pkgname = flNotDir(pkgpath);
 +   pos = pkgname.find('_');
 +   if(pos != string::npos)
 +      pkgname = pkgname.substr(0, pos);
 +
 +   // find the package versin and source package name
 +   pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname);
 +   if (Pkg.end() == true)
 +      return;
 +   pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
 +   if (Ver.end() == true)
 +      return;
 +   pkgver = Ver.VerStr() == NULL ? "unknown" : Ver.VerStr();
 +   pkgRecords Recs(Cache);
 +   pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
 +   srcpkgname = Parse.SourcePkg();
 +   if(srcpkgname.empty())
 +      srcpkgname = pkgname;
 +
 +   // if the file exists already, we check:
 +   // - if it was reported already (touched by apport). 
 +   //   If not, we do nothing, otherwise
 +   //    we overwrite it. This is the same behaviour as apport
 +   // - if we have a report with the same pkgversion already
 +   //   then we skip it
 +   reportfile = flCombine("/var/crash",pkgname+".0.crash");
 +   if(FileExists(reportfile))
 +   {
 +      struct stat buf;
 +      char strbuf[255];
 +
 +      // check atime/mtime
 +      stat(reportfile.c_str(), &buf);
 +      if(buf.st_mtime > buf.st_atime)
 +       return;
 +
 +      // check if the existing report is the same version
 +      report = fopen(reportfile.c_str(),"r");
 +      while(fgets(strbuf, sizeof(strbuf), report) != NULL)
 +      {
 +       if(strstr(strbuf,"Package:") == strbuf)
 +       {
 +          char pkgname[255], version[255];
 +          if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2)
 +             if(strcmp(pkgver.c_str(), version) == 0)
 +             {
 +                fclose(report);
 +                return;
 +             }
 +       }
 +      }
 +      fclose(report);
 +   }
 +
 +   // now write the report
 +   arch = _config->Find("APT::Architecture");
 +   report = fopen(reportfile.c_str(),"w");
 +   if(report == NULL)
 +      return;
 +   if(_config->FindB("DPkgPM::InitialReportOnly",false) == true)
 +      chmod(reportfile.c_str(), 0);
 +   else
 +      chmod(reportfile.c_str(), 0600);
 +   fprintf(report, "ProblemType: Package\n");
 +   fprintf(report, "Architecture: %s\n", arch.c_str());
 +   time_t now = time(NULL);
 +   fprintf(report, "Date: %s" , ctime(&now));
 +   fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str());
 +   fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str());
 +   fprintf(report, "ErrorMessage:\n %s\n", errormsg);
 +
 +   // ensure that the log is flushed
 +   if(term_out)
 +      fflush(term_out);
 +
 +   // attach terminal log it if we have it
 +   string logfile_name = _config->FindFile("Dir::Log::Terminal");
 +   if (!logfile_name.empty())
 +   {
 +      FILE *log = NULL;
 +      char buf[1024];
 +
 +      fprintf(report, "DpkgTerminalLog:\n");
 +      log = fopen(logfile_name.c_str(),"r");
 +      if(log != NULL)
 +      {
 +       while( fgets(buf, sizeof(buf), log) != NULL)
 +          fprintf(report, " %s", buf);
 +       fclose(log);
 +      }
 +   }
 +
 +   // log the ordering 
 +   const char *ops_str[] = {"Install", "Configure","Remove","Purge"};
 +   fprintf(report, "AptOrdering:\n");
 +   for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
 +      fprintf(report, " %s: %s\n", (*I).Pkg.Name(), ops_str[(*I).Op]);
 +
 +   // attach dmesg log (to learn about segfaults)
 +   if (FileExists("/bin/dmesg"))
 +   {
 +      FILE *log = NULL;
 +      char buf[1024];
 +
 +      fprintf(report, "Dmesg:\n");
 +      log = popen("/bin/dmesg","r");
 +      if(log != NULL)
 +      {
 +       while( fgets(buf, sizeof(buf), log) != NULL)
 +          fprintf(report, " %s", buf);
 +       fclose(log);
 +      }
 +   }
 +
 +   // attach df -l log (to learn about filesystem status)
 +   if (FileExists("/bin/df"))
 +   {
 +      FILE *log = NULL;
 +      char buf[1024];
 +
 +      fprintf(report, "Df:\n");
 +      log = popen("/bin/df -l","r");
 +      if(log != NULL)
 +      {
 +       while( fgets(buf, sizeof(buf), log) != NULL)
 +          fprintf(report, " %s", buf);
 +       fclose(log);
 +      }
 +   }
 +
 +   fclose(report);
 +
 +}
 +                                                                      /*}}}*/
diff --combined debian/changelog
index dab703c6b81f30791118d0663b4d752ceb791600,27acd33c599b87398ca8303f8d5da10f6118a616..c4d18d70b06f66b9ff61d6045d05889653d4ba8b
 -apt (0.7.25.4) UNRELEASED; urgency=low
 +apt (0.7.26~exp8) UNRELEASED; urgency=low
  
 -  [ Evan Dandrea ]
 -  * Remember hosts with general failures for
 -    https://wiki.ubuntu.com/NetworklessInstallationFixes (LP: #556831).
 +  [ David Kalnischkies ]
 +  * cmdline/cacheset.cc:
 +    - doesn't include it in the library for now as it is too volatile
 +    - get the candidate either from an already built depcache
 +      or use the policy which is a bit faster than depcache generation
 +    - get packages by task^ with FromTask()
 +    - only print errors if all tries to get a package by string failed
 +    - factor out code to get a single package FromName()
 +    - check in Grouped* first without modifier interpretation
 +  * cmdline/apt-get.cc:
 +    - use the cachsets in the install commands
 +    - make the specify order of packages irrelevant (Closes: #196021)
 +  * apt-pkg/orderlist.cc:
 +    - untouched packages are never missing
 +  * apt-pkg/packagemanager.cc:
 +    - packages that are not touched doesn't need to be unpacked
 +  * debian/control:
 +    - remove intltool's dependency as it is an ubuntu artefact
 +  * apt-pkg/depcache.cc:
 +    - SetCandidateVer for all pseudo packages
 +    - SetReInstall for the "all" package of a pseudo package
 +    - use the new MatchAgainstConfig for the DefaultRootSetFunc
 +    - always mark the all package if a pseudo package is marked for install
 +  * apt-pkg/contrib/error.{cc,h}:
 +    - complete rewrite but use the same API
 +    - add NOTICE and DEBUG as new types of a message
 +    - add a simple stack handling to be able to delay error handling
 +  * apt-pkg/aptconfiguration.cc:
 +    - show a deprecation notice for APT::Acquire::Translation
 +  * apt-pkg/contrib/configuration.{cc,h}:
 +    - add a wrapper to match strings against configurable regex patterns
 +  * apt-pkg/contrib/fileutl.cc:
 +    - show notice about ignored file instead of being always silent
 +    - add a Dir::Ignore-Files-Silently list option to control the notice
 +  * apt-pkg/policy.h:
 +    - add another round of const& madness as the previous round accidentally
 +      NOT overrides the virtual GetCandidateVer() method (Closes: #587725)
 +  * apt-pkg/pkgcachegen.{cc,h}:
 +    - make the used MMap moveable (and therefore dynamic resizeable) by
 +      applying (some) mad pointer magic (Closes: #195018)
 +
++  [ Michael Vogt ]
++  * apt-pkg/deb/dpkgpm.cc:
++    - make the apt/term.log output unbuffered (thanks to Matt Zimmerman)
++
 +  [ Julian Andres Klode ]
 +  * methods/ftp.h:
 +    - Handle different logins on the same server (Closes: #586904).
 +  * apt-pkg/deb/deblistparser.cc:
 +    - Handle architecture wildcards (Closes: #547724).
 +  * apt-pkg/versionmatch.cc:
 +    - Support matching pins by regular expressions or glob() like patterns,
 +      regular expressions have to be put between to slashes; for example,
 +      /.*/.
 +  * apt-pkg/contrib/fileutl.cc:
 +    - Make FileFd replace files atomically in WriteTemp mode (for cache, etc).
 +  * debian/control:
 +    - Set Standards-Version to 3.9.0
 +
 + -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 05 Jul 2010 12:05:30 +0200
 +
 +apt (0.7.26~exp7) experimental; urgency=low
 +
 +  * apt-pkg/cachefile.h:
 +    - make pkgPolicy public again, libapt-pkg-perl (and probably
 +      others) get unhappy without that
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 10 Jun 2010 15:33:24 +0200
 +
 +apt (0.7.26~exp6) experimental; urgency=low
 +
 +  [ Michael Vogt ]
 +  * merge the remaining Ubuntu change:
 +    - on gpg verification failure warn and restore the last known
 +      good state
 +    - on failure display the IP of the server (useful for servers
 +      that use round robin DNS)
 +    - support Original-Maintainer in RewritePackageOrder
 +    - enable cdrom autodetection via libudev by default
 +    - show message about Vcs in use when apt-get source is run for
 +      packages maintained in a Vcs
 +    - better support transitional packages with mark auto-installed. 
 +      when the transitional package is in "oldlibs" the new package
 +      is not marked auto installed (same is true for section
 +      metapackages)
 +    - provide new "deb mirror://archive.foo/mirrors.list sid main"
 +      method expects a list of mirrors (generated on the server e.g.
 +      via geoip) and will use that, including cycle on failure
 +    - write apport crash file on package failure (disabled by default
 +      on debian until apport is available)
 +    - support mirror failure reporting (disabled by default on debian)
 +  
 +  [ David Kalnischkies ]
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - write Disappeared also to the history.log
 +    - forward manual-installed bit on package disappearance
 +  * apt-pkg/deb/debsystem.cc:
 +    - add better config item for extended_states file
 +  * apt-pkg/pkgcache.h:
 +    - switch {,Install-}Size to unsigned long long
 +  * apt-pkg/depcache.cc:
 +    - do the autoremove mark process also for required packages to handle
 +      these illegally depending on lower priority packages (Closes: #583517)
 +    - try harder to find the other pseudo versions for autoremove multiarch
 +    - correct "Dangerous iterator usage" pointed out by cppcheck
 +    - deal with long long, not with int to remove 2GB Limit (LP: #250909)
 +    - deprecate AddSize with Multiplier as it is unused and switch to
 +      boolean instead to handle the sizes more gracefully.
 +    - switch i{Download,Usr}Size from double to (un)signed long long
 +  * apt-pkg/aptconfiguration.cc:
 +    - remove duplicate architectures in getArchitectures()
 +  * apt-pkg/indexrecords.{cc,h}:
 +    - backport forgotten Valid-Until patch from the obsolete experimental
 +      branch to prevent replay attacks better, thanks to Thomas Viehmann
 +      for the initial patch! (Closes: #499897)
 +    - add a constant Exists check for MetaKeys
 +  * apt-pkg/acquire-item.cc:
 +    - do not try PDiff if it is not listed in the Meta file
 +    - sent Last-Modified header also for Translation files
 +  * apt-pkg/cacheiterator.h:
 +    - let pkgCache::Iterator inherent std::iterator
 +  * ftparchive/writer.h:
 +    - add a virtual destructor to FTWScanner class (for cppcheck)
 +  * apt-pkg/cacheset.{cc,h}:
 +    - add simple wrapper around std::set for cache structures
 +    - move regex magic from apt-get to new FromRegEx method
 +    - move cmdline parsing from apt-cache to new FromCommandLine method
 +    - support special release-modifier 'installed' and 'candidate'
 +  * apt-pkg/contrib/cmdline.cc:
 +    - fix segfault in SaveInConfig caused by writing over char[] sizes
 +  * apt-pkg/pkgcache.cc:
 +    - get the best matching arch package from a group with FindPreferredPkg
 +  * cmdline/apt-cache.cc:
 +    - make the search multiarch compatible by using GrpIterator instead
 +    - use pkgCacheFile and the new CacheSets all over the place
 +    - add --target-release option (Closes: #115520)
 +    - accept pkg/release and pkg=version in show and co. (Closes: #236270)
 +    - accept package versions in the unmet command
 +  * cmdline/apt-get.cc:
 +    - use unsigned long long instead of double to store values it gets
 +  * apt-pkg/cachefile.{cc,h}:
 +    - split Open() into submethods to be able to build only parts
 +    - make the OpProgress optional in the Cache buildprocess
 +    - store also the SourceList we use internally for export
 +  * doc/apt.conf.5.xml:
 +    - document the new Valid-Until related options
 +  * apt-pkg/contrib/strutl.cc:
 +    - split StrToTime() into HTTP1.1 and FTP date parser methods and
 +      use strptime() instead of some self-made scanf mangling
 +    - use the portable timegm shown in his manpage instead of a strange
 +      looking code copycat from wget
 +  * ftparchive/writer.cc:
 +    - add ValidTime option to generate a Valid-Until header in Release file
 +  * apt-pkg/policy.cc:
 +    - get the candidate right for a not-installed pseudo package if
 +      his non-pseudo friend is installed
 +  * apt-pkg/indexcopy.cc:
 +    - move the gpg codecopy to a new method and use it also in methods/gpgv.cc
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 10 Jun 2010 14:02:22 +0200
 +
 +apt (0.7.26~exp5) experimental; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * cmdline/apt-get.cc:
 +    - rerun dpkg-source in source if --fix-broken is given (Closes: #576752)
 +    - don't suggest held packages as they are installed (Closes: #578135)
 +    - handle multiple --{tar,diff,dsc}-only options correctly
 +    - show at the end of the install process a list of disappeared packages
 +  * cmdline/apt-cache.cc:
 +    - use GroupCount for package names in stats and add a package struct line
 +  * methods/rred.cc:
 +    - use the patchfile modification time instead of the one from the
 +      "old" file - thanks to Philipp Weis for noticing! (Closes: #571541)
 +  * debian/rules:
 +    - remove targets referring to CVS or arch as they are useless
 +    - use $(CURDIR) instead of $(pwd)
 +    - use dpkg-buildflags if available for CXXFLAGS
 +  * README.arch:
 +    - remove the file completely as it has no use nowadays
 +  * apt-pkg/depcache.cc:
 +    - be doublesure that the killer query is empty before starting reinstall
 +  * methods/gpgv.cc:
 +    - remove the keyrings count limit by using vector magic
 +  * contrib/mmap.cc:
 +    - clarify "MMap reached size limit" error message, thanks Ivan Masár!
 +  * doc/apt.ent
 +    - add entities for the current oldstable/stable/testing codenames
 +  * doc/sources.list.5.xml:
 +    - use stable-codename instead of stable in the examples (Closes: #531492)
 +  * doc/apt_preferences.5.xml:
 +    - adapt some examples here to use current codenames as well
 +    - add "NotAutomatic: yes" handling, thanks Osamu Aoki (Closes: #490347)
 +  * debian/libapt-pkg-doc.doc-base.cache:
 +    - remove yet another reference to the removed cache.sgml
 +  * doc/apt-get.8.xml:
 +    - do not say explicit target_release_{name,version,codename}, it should
 +      be clear by itself and 'man' can break lines again (Closes: #566166)
 +    - remove the gnome-apt reference as it is removed from unstable
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - add 'disappear' to the known processing states, thanks Jonathan Nieder
 +  * apt-pkg/packagemanager.h:
 +    - export info about disappeared packages with GetDisappearedPackages()
 +
 +  [ Michael Vogt ]
 +  * methods/http.{cc,h}:
 +    - code cleanup, use enums instead of magic ints
    
 +  [ Jari Aalto ]
 +  * debian/rules:
 +    - spell out some less known options to reduce manpage consultation-rate
 +    - Use POSIX command substitution: $(<command sequence>)
 +    - Remove EOL whitespace (Closes: #577804)
 +
 +  [ Julian Andres Klode ]
 +  * apt-pkg/acquire-item.cc:
 +    - Fix pkgAcqFile::Custom600Headers() to always return something.
 +  
 +
 +  [ Christian Perrier ]
 +  * Slovak translation update. Closes: #581159
 +  * Italian translation update. Closes: #581742
 +
 + -- Michael Vogt <mvo@debian.org>  Tue, 25 May 2010 16:01:42 +0200
 +
 +apt (0.7.26~exp4) experimental; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * apt-pkg/depcache.cc:
 +    - rewrite the pseudo package reinstaller to be more intelligent
 +      in his package choices
 +  * apt-pkg/packagemanager.cc:
 +    - don't try to "unpack" pseudo packages twice
 +  * apt-pkg/contrib/fileutl.cc:
 +    - add a parent-guarded "mkdir -p" as CreateDirectory()
 +  * apt-pkg/acquire.{cc,h}:
 +    - add a delayed constructor with Setup() for success reporting
 +    - check for and create directories in Setup if needed instead of
 +      error out unfriendly in the Constructor (Closes: #523920, #525783)
 +    - optional handle a lock file in Setup()
 +  * apt-pkg/acquire-item.cc:
 +    - Acquire::ForceHash to force method for expected hash
 +  * cmdline/apt-get.cc:
 +    - remove the lock file handling and let Acquire take care of it instead
 +    - display MD5Sum in --print-uris if not forced to use another method
 +      instead of displaying the strongest available (Closes: #576420)
 +    - regex for package names executed on Grp- not PkgIterator
 +    - show non-candidates as fallback for virtual packages (Closes: #578385)
 +    - set also "all" to this version for pseudo packages in TryToChangeVer
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - remove Chroot-Directory from files passed to install commands.
 +      Thanks to Kel Modderman for report & patch! (Closes: #577226)
 +  * ftparchive/writer.cc:
 +    - remove 999 chars Files and Checksums rewrite limit (Closes: #577759)
 +  * cmdline/apt-cache.cc:
 +    - align Installed and Candidate Version in policy so they can be compared
 +      easier, thanks Ralf Gesellensetter for the pointer! (Closes: #578657)
 +  * doc/apt.ent:
 +    - Add a note about APT_CONFIG in the -c description (Closes: #578267)
 +  * doc/po/de.po:
 +    - correct typos in german apt_preferences manpage, thanks Chris Leick!
 +  * apt-pkg/sourcelist.cc:
 +    - be less strict and accept [option=value] as well
 +  * apt-pkg/contrib/configuration.cc:
 +    - error out if #clear directive has no argument
 +  * doc/files.sgml:
 +    - sync documentation with status quo, regarding files/directories in
 +      use, extended_states and uri schemes.
 +  * doc/cache.sgml:
 +    - drop the file in favor of inplace documentation with doxygen
 +  * apt-pkg/pkgcache.h:
 +    - enhance the Groups ABI by providing a ID as the other structs does
 +    - check also the size of the Group struct then checking for the others
 +
 +  [ Jari Aalto ]
 +  * cmdline/apt-get.cc:
 +    - replace backticks with single quotes around fix-broken command
 +      in the broken packages message. (Closes: #577168)
 +  * dselect/install:
 +    - modernize if-statements not to use 'x' (Closes: #577117)
 +    - replace backticks with POSIX $() (Closes: #577116)
 +
 +  [ Michael Vogt ]
 +  * [ Abi break ] apt-pkg/acquire-item.{cc,h}:
 +    - add "IsIndexFile" to constructor of pkgAcqFile so that it sends
 +      the right cache control headers
 +  * cmdline/apt-get.cc:
 +    - fix crash when pkg.VersionList() is empty
 +  * apt-pkg/depcache.cc:
 +    - fix incorrect std::cout usage for debug output
 +  * test/libapt/getlanguages_test.cc:
 +    - Add test for Esperanto that has nocounty associated with them
 +      (LP: #560956)
 +  * apt-pkg/deb/debrecords.cc:
 +    - fix max tag buffer size (LP: #545336, closes: #578959)
 +  * debian/rules:
 +    - install html doxygen in libapt-pkg-doc 
 +  * debian/control:
 +    - build-depend on doxygen
 +
 +  [ Julian Andres Klode ]
 +  * apt-pkg/contrib/weakptr.h:
 +    - add a class WeakPointable which allows one to register weak pointers to
 +      an object which will be set to NULL when the object is deallocated.
 +  * [ABI break] apt-pkg/acquire{-worker,-item,}.h:
 +    - subclass pkgAcquire::{Worker,Item,ItemDesc} from WeakPointable.
 +  * apt-pkg/pkgcache.cc:
 +    - Merge fix from David to correct handling in single-arch environments.
 +  * cmdline/apt-cache.cc:
 +    - Add a showauto command to apt-cache.
 +  * cmdline/apt-get.cc:
 +    - Add apt-get markauto and unmarkauto commands.
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 06 May 2010 09:32:54 +0200
 +
 +apt (0.7.26~exp3) experimental; urgency=low
 +
 +  [ Christian Perrier ]
 +  * German translation update. Closes: #571037
 +  * Spanish manpages translation update. Closes: #573293
 +  * Dutch translation update. Closes: #573946
 +  * Polish manpages translation update. Closes: #574558
 +  * Add "manpages-pl (<< 20060617-3~)" to avoid file conflicts with
 +    that package that was providing some manpages for APT utilities.
 +
 +  [ David Kalnischkies ]
 +  * [BREAK] merge MultiArch-ABI. We don't support MultiArch,
 +    but we support the usage of the new ABI so libapt users
 +    can start to prepare for MultiArch (Closes: #536029)
 +  * Ignore :qualifiers after package name in build dependencies
 +    in the library by default, but try to honour them in apt-get
 +    as we have some sort of MultiArch support ready (Closes: #558103)
 +  * add translation of the manpages to PT (portuguese)
 +    Thanks to Américo Monteiro!
 +  * Switch to dpkg-source 3.0 (native) format
 +  * apt-pkg/depcache.cc:
 +    - remove Auto-Installed information from extended_states
 +      together with the package itself (Closes: #572364)
 +  * cmdline/apt-mark:
 +    - don't crash if no arguments are given (Closes: #570962)
 +  * debian/control:
 +    - remove some years old and obsolete Replaces
 +    - add automake/conf build-depends/conflicts as recommend by
 +      the autotools-dev README (Closes: #572615)
 +  * apt-pkg/contrib/mmap.{h,cc}:
 +    - add char[] fallback for filesystems without shared writable
 +      mmap() like JFFS2. Thanks to Marius Vollmer for writing
 +      and to Loïc Minier for pointing to the patch! (Closes: #314334)
 +  * doc/apt_preferences.5.xml:
 +    - fix two typos and be more verbose in the novice warning.
 +      Thanks to Osamu Aoki for pointing it out! (Closes: #567669)
 +    - fix a=sid vs. n=sid typo, thanks Ansgar Burchardt!
 +    - origin can be used to match a hostname (Closes: #352667)
 +    - remove wrong pin-priority is optional remark (Closes: #574944)
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - fix error message construction in OpenLog()
 +    - if available store the Commandline in the history
 +  * cmdline/apt-get.cc:
 +    - add a --only-upgrade flag to install command (Closes: #572259)
 +    - fix memory leaks in error conditions in DoSource()
 +    - try version match in FindSrc first exact than fuzzy (LP: #551178)
 +  * apt-pkg/contrib/cmndline.cc:
 +    - save Commandline in Commandline::AsString for logging
 +  * apt-pkg/deb/debversion.cc:
 +    - consider absent of debian revision equivalent to 0 (Closes: #573592)
 +  * doc/makefile, doc/*:
 +    - generate subdirectories for building the manpages in on the fly
 +      depending on the po files we have.
 +  * apt-pkg/pkgcachegen.cc:
 +    - merge versions correctly even if multiple different versions
 +      with the same version number are available.
 +      Thanks to Magnus Holmgren for the patch! (Closes: #351056)
 +  * ftparchive/writer.cc:
 +    - write LongDescriptions if they shouldn't be included in Packages
 +      file into i18n/Translation-en by default.
 +  * doc/po/de.po:
 +    - correct a few typos in the german manpage translation.
 +      Thanks to Chris Leick and Georg Koppen! (Closes: #574962)
 +  * apt-pkg/contrib/strutl.cc:
 +    - convert all toupper calls to tolower_ascii for a little speedup
 +
 +  [ Jean-Baptiste Lallement ]
 +  * apt-pkg/contrib/strutl.cc:
 +    - always escape '%' (LP: #130289) (Closes: #500560)
 +    - unescape '%' sequence only if followed by 2 hex digit
 +    - username/password are urlencoded in proxy string (RFC 3986)
 +
 +  [ Julian Andres Klode ]
 +  * cmdline/apt-cache.cc:
 +    - Change behavior of showsrc to match the one of show (Closes: #512046).
 +  * cmdline/apt-key:
 +    - Honor Apt::GPGV::TrustedKeyring (Closes: #316390)
 +  * cmdline/apt-mark:
 +    - Use the new python-apt API (and conflict with python-apt << 0.7.93.2).
 +  * apt-inst/contrib/arfile.h:
 +    - Add public ARArchive::Members() which returns the list of members.
 +  * apt-pkg/policy.cc:
 +    - Always return a candidate if there is at least one version pinned > 0
 +      (Closes: #512318)
 +  * ftparchive/apt-ftparchive.cc:
 +    - Read default configuration (Closes: #383257)
 +  * debian/rules:
 +    - Fix the libraries name to be e.g. libapt-pkg4.9 instead of
 +      libapt-pkg-4.9.
 +
 +  [ Michael Vogt ]
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - fix backgrounding when dpkg runs (closes: #486222)
 +  * cmdline/apt-mark:
 +    - show error on incorrect aguments (LP: #517917), thanks to
 +      Torsten Spindler
 +  * cmdline/apt-get.cc:
 +    - if apt-get source foo=version or foo/distro can not be found,
 +      error out (LP: #502641)
 +  * apt-pkg/packagemanager.cc:
 +    - better debug output 
 +  * doc/examples/configure-index:
 +    - add missing Debug::pkgPackageManager option
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 01 Apr 2010 17:30:43 +0200
 +
 +apt (0.7.26~exp2) experimental; urgency=low
 +
 +  * fix crash when LANGUAGE is not set
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 18 Feb 2010 22:07:23 +0100
 +
 +apt (0.7.26~exp1) experimental; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * [BREAK] add possibility to download and use multiply
 +    Translation files, configurable with Acquire::Translation
 +    (Closes: #444222, #448216, #550564)
 +  * Ignore :qualifiers after package name in build dependencies
 +    for now as long we don't understand them (Closes: #558103)
 +  * apt-pkg/contrib/mmap.{cc,h}:
 +    - extend it to have a growable flag - unused now but maybe...
 +  * apt-pkg/pkgcache.h:
 +    - use long instead of short for {Ver,Desc}File size,
 +      patch from Víctor Manuel Jáquez Leal, thanks! (Closes: #538917)
 +  * apt-pkg/acquire-item.cc:
 +    - allow also to skip the last patch if target is reached,
 +      thanks Bernhard R. Link! (Closes: #545699)
 +  * ftparchive/writer.{cc,h}:
 +    - add --arch option for packages and contents commands
 +    - if an arch is given accept only *_all.deb and *_arch.deb instead
 +      of *.deb. Thanks Stephan Bosch for the patch! (Closes: #319710)
 +    - add APT::FTPArchive::AlwaysStat to disable the too aggressive
 +      caching if versions are build multiply times (not recommend)
 +      Patch by Christoph Goehre, thanks! (Closes: #463260)
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - stdin redirected to /dev/null takes all CPU (Closes: #569488)
 +      Thanks to Aurelien Jarno for providing (again) a patch!
 +  * buildlib/apti18n.h.in, po/makefile:
 +    - add ngettext support with P_()
 +  * aptconfiguration.cc:
 +    - include all existing Translation files in the Cache (Closes: 564137)
 +  * debian/control:
 +    - update with no changes to debian policy 3.8.4
 +  * doc/apt_preferences.5.xml:
 +    - explicitly warn against careless use (Closes: #567669)
 +  * debian/rules:
 +    - remove creation of empty dir /usr/share/apt
 +  * doc/apt-cdrom.8.xml:
 +    - fix typo spotted by lintian: proc(c)eed
 +
    [ Ivan Masár ]
    * Slovak translation update. Closes: #568294
    
    [ Michael Vogt ]
 -  * merged lp:~mvo/apt/history
 +  * [BREAK] merged lp:~mvo/apt/history
      - this writes a /var/log/apt/history tagfile that contains details
        from the transaction (complements term.log)
    * methods/http.cc:
    * abicheck/
      - add new abitest tester using the ABI Compliance Checker from
        http://ispras.linuxfoundation.org/index.php/ABI_compliance_checker
 -  * apt-pkg/deb/dpkgpm.cc:
 -    - fix backgrounding when dpkg runs (closes: #486222)
 -  * cmdline/apt-mark:
 -    - show error on incorrect aguments (LP: #517917), thanks to
 -      Torsten Spindler
 -  * cmdline/apt-get.cc:
 -    - if apt-get source foo=version or foo/distro can not be found,
 -      error out (LP: #502641)
 -  * apt-pkg/indexfile.cc:
 -    - deal correctly with three letter langcodes (LP: #391409)
 -  * [ Abi break ] apt-pkg/acquire-item.{cc,h}:
 -    - add "IsIndexFile" to constructor of pkgAcqFile so that it sends
 -      the right cache control headers
 -  * apt-pkg/depcache.cc:
 -    - fix incorrect std::cout usage for debug output
 -  * apt-pkg/indexfile.cc:
 -    - If no "_" is found in the language code, try to find a "."
 -      This is required for languages like Esperanto that have no
 -      county associated with them (LP: #560956)
 -      Thanks to "Aisano" for the fix
 -  * apt-pkg/deb/debrecords.cc:
 -    - fix max tag buffer size (LP: #545336, closes: #578959)
 -  * debian/rules:
 -    - install html doxygen in libapt-pkg-doc as well
 -  * methods/http.cc: 
 -    - code cleanup, add (some) doxygen strings
 -  * apt-pkg/deb/dpkgpm.cc:
 -    - make the apt/term.log output unbuffered (thanks to Matt Zimmerman)
  
    [ Robert Collins ]
    * Change the package index Info methods to allow apt-cache policy to be
      useful when using several different archives on the same host.
      (Closes: #329814, LP: #22354)
  
 - -- Michael Vogt <michael.vogt@ubuntu.com>  Fri, 18 Dec 2009 16:54:18 +0100
 + -- Michael Vogt <mvo@debian.org>  Thu, 18 Feb 2010 16:11:39 +0100
  
  apt (0.7.25.3) unstable; urgency=low
  
@@@ -1815,6 -1385,13 +1819,6 @@@ apt (0.7.6) unstable; urgency=lo
  
   -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
  
 -apt (0.7.6) unstable; urgency=low
 -
 -  * Applied patch from Aurelien Jarno <aurel32@debian.org> to fix wrong
 -    directory downloading on non-linux architectures (closes: #435597)
 -
 - -- Otavio Salvador <otavio@debian.org>  Wed, 01 Aug 2007 19:49:51 -0300
 -
  apt (0.7.5) unstable; urgency=low
  
    [ Otavio Salvador ]