Michael Vogt лет назад: 15
Родитель
Сommit
3b310a644d
95 измененных файлов с 2775 добавлено и 1610 удалено
  1. 10 4
      apt-inst/dirstream.cc
  2. 66 1
      apt-pkg/acquire-item.cc
  3. 100 147
      apt-pkg/acquire-method.cc
  4. 3 0
      apt-pkg/acquire-method.h
  5. 5 6
      apt-pkg/acquire-worker.cc
  6. 9 26
      apt-pkg/algorithms.cc
  7. 1 0
      apt-pkg/cacheiterators.h
  8. 13 13
      apt-pkg/cacheset.h
  9. 54 34
      apt-pkg/cdrom.cc
  10. 10 6
      apt-pkg/contrib/cdromutl.cc
  11. 2 0
      apt-pkg/contrib/error.cc
  12. 8 0
      apt-pkg/contrib/mmap.cc
  13. 8 4
      apt-pkg/contrib/netrc.cc
  14. 1 1
      apt-pkg/deb/deblistparser.cc
  15. 4 1
      apt-pkg/deb/debmetaindex.cc
  16. 3 2
      apt-pkg/deb/dpkgpm.cc
  17. 65 69
      apt-pkg/depcache.cc
  18. 5 5
      apt-pkg/indexcopy.cc
  19. 5 13
      apt-pkg/orderlist.cc
  20. 37 7
      apt-pkg/packagemanager.cc
  21. 2 0
      apt-pkg/packagemanager.h
  22. 29 17
      apt-pkg/pkgcache.cc
  23. 6 0
      apt-pkg/pkgcache.h
  24. 3 2
      apt-pkg/pkgcachegen.cc
  25. 13 1
      apt-pkg/policy.cc
  26. 10 14
      cmdline/apt-cache.cc
  27. 26 9
      cmdline/apt-get.cc
  28. 0 101
      cmdline/apt-mark
  29. 373 0
      cmdline/apt-mark.cc
  30. 5 4
      cmdline/makefile
  31. 4 2
      debian/apt-utils.symbols
  32. 22 16
      debian/apt.cron.daily
  33. 0 3
      debian/apt.lintian-overrides
  34. 50 33
      debian/apt.symbols
  35. 108 5
      debian/changelog
  36. 3 2
      debian/control
  37. 3 0
      debian/rules
  38. 16 0
      doc/apt-key.8.xml
  39. 43 24
      doc/apt-mark.8.xml
  40. 43 0
      doc/apt_preferences.5.xml
  41. 1 1
      doc/po/de.po
  42. 28 5
      methods/http.cc
  43. 2 2
      po/apt-all.pot
  44. 2 2
      po/ar.po
  45. 2 2
      po/ast.po
  46. 2 2
      po/bg.po
  47. 2 2
      po/bs.po
  48. 2 2
      po/ca.po
  49. 2 2
      po/cs.po
  50. 2 2
      po/cy.po
  51. 2 2
      po/da.po
  52. 2 2
      po/de.po
  53. 2 2
      po/dz.po
  54. 2 2
      po/el.po
  55. 2 2
      po/es.po
  56. 2 2
      po/eu.po
  57. 2 2
      po/fi.po
  58. 2 2
      po/fr.po
  59. 1031 902
      po/gl.po
  60. 2 2
      po/he.po
  61. 2 2
      po/hu.po
  62. 16 7
      po/it.po
  63. 2 2
      po/ja.po
  64. 2 2
      po/km.po
  65. 2 2
      po/ko.po
  66. 2 2
      po/ku.po
  67. 2 2
      po/lt.po
  68. 2 2
      po/mr.po
  69. 2 2
      po/nb.po
  70. 2 2
      po/ne.po
  71. 2 2
      po/nl.po
  72. 2 2
      po/nn.po
  73. 2 2
      po/pl.po
  74. 2 2
      po/pt.po
  75. 2 2
      po/pt_BR.po
  76. 2 2
      po/ro.po
  77. 2 2
      po/ru.po
  78. 2 2
      po/sk.po
  79. 2 2
      po/sl.po
  80. 2 2
      po/sv.po
  81. 2 2
      po/th.po
  82. 2 2
      po/tl.po
  83. 2 2
      po/uk.po
  84. 2 2
      po/vi.po
  85. 2 2
      po/zh_CN.po
  86. 2 2
      po/zh_TW.po
  87. 47 28
      test/integration/framework
  88. 36 0
      test/integration/skip-bug-602412-dequote-redirect
  89. 172 0
      test/integration/test-bug-470115-new-and-tighten-recommends
  90. 3 3
      test/integration/test-bug-612557-garbage-upgrade
  91. 32 0
      test/integration/test-bug-618288-multiarch-same-lockstep
  92. 108 0
      test/integration/test-handling-broken-orgroups
  93. 38 0
      test/integration/test-ubuntu-bug-761175-remove-purge
  94. 5 2
      test/testextract.cc
  95. 6 6
      test/versions.lst

+ 10 - 4
apt-inst/dirstream.cc

@@ -43,11 +43,17 @@ bool pkgDirStream::DoItem(Item &Itm,int &Fd)
 	 
 	 // fchmod deals with umask and fchown sets the ownership
 	 if (fchmod(iFd,Itm.Mode) != 0)
-	    return _error->Errno("fchmod",_("Failed to write file %s"),
-				 Itm.Name);
+	 {
+	    _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
+	    close(iFd);
+	    return false;
+	 }
 	 if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
-	    return _error->Errno("fchown",_("Failed to write file %s"),
-				 Itm.Name);
+	 {
+	    return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
+	    close(iFd);
+	    return false;
+	 }
 	 Fd = iFd;
 	 return true;
       }

+ 66 - 1
apt-pkg/acquire-item.cc

@@ -271,6 +271,14 @@ void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash,	/*{{
 
    string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
 
+   /* Downloaded invalid transindex => Error (LP: #346386) (Closes: #627642) */
+   indexRecords SubIndexParser;
+   if (FileExists(DestFile) == true && !SubIndexParser.Load(DestFile)) {
+      Status = StatError;
+      ErrorText = SubIndexParser.ErrorText;
+      return;
+   }
+
    // sucess in downloading the index
    // rename the index
    if(Debug)
@@ -894,6 +902,27 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
 	 ReportMirrorFailure("HashChecksumFailure");
          return;
       }
+
+      /* Verify the index file for correctness (all indexes must
+       * have a Package field) (LP: #346386) (Closes: #627642) */
+      {
+	 FileFd fd(DestFile, FileFd::ReadOnly);
+	 pkgTagSection sec;
+	 pkgTagFile tag(&fd);
+
+	 if (_error->PendingError() || !tag.Step(sec)) {
+	    Status = StatError;
+	    _error->DumpErrors();
+	    Rename(DestFile,DestFile + ".FAILED");
+	    return;
+	 } else if (!sec.Exists("Package")) {
+	    Status = StatError;
+	    ErrorText = ("Encountered a section with no Package: header");
+	    Rename(DestFile,DestFile + ".FAILED");
+	    return;
+	 }
+      }
+       
       // Done, move it into position
       string FinalFile = _config->FindDir("Dir::State::lists");
       FinalFile += URItoFileName(RealURI);
@@ -1330,6 +1359,16 @@ void pkgAcqMetaIndex::AuthDone(string Message)				/*{{{*/
 									/*}}}*/
 void pkgAcqMetaIndex::QueueIndexes(bool verify)				/*{{{*/
 {
+#if 0
+   /* Reject invalid, existing Release files (LP: #346386) (Closes: #627642)
+    * FIXME: Disabled; it breaks unsigned repositories without hashes */
+   if (!verify && FileExists(DestFile) && !MetaIndexParser->Load(DestFile))
+   {
+      Status = StatError;
+      ErrorText = MetaIndexParser->ErrorText;
+      return;
+   }
+#endif
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         Target++)
@@ -1493,6 +1532,12 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 			 LookupTag(Message,"Message").c_str());
 	 RunScripts("APT::Update::Auth-Failure");
 	 return;
+      } else if (LookupTag(Message,"Message").find("NODATA") != string::npos) {
+	 /* Invalid signature file, reject (LP: #346386) (Closes: #627642) */
+	 _error->Error(_("GPG error: %s: %s"),
+			 Desc.Description.c_str(),
+			 LookupTag(Message,"Message").c_str());
+	 return;
       } else {
 	 _error->Warning(_("GPG error: %s: %s"),
 			 Desc.Description.c_str(),
@@ -1502,6 +1547,26 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
       ReportMirrorFailure("GPGFailure");
    }
 
+   /* Always move the meta index, even if gpgv failed. This ensures
+    * that PackageFile objects are correctly filled in */
+   if (FileExists(DestFile)) {
+      string FinalFile = _config->FindDir("Dir::State::lists");
+      FinalFile += URItoFileName(RealURI);
+      /* InRelease files become Release files, otherwise
+       * they would be considered as trusted later on */
+      if (SigFile == DestFile) {
+	 RealURI = RealURI.replace(RealURI.rfind("InRelease"), 9,
+	                               "Release");
+	 FinalFile = FinalFile.replace(FinalFile.rfind("InRelease"), 9,
+	                               "Release");
+	 SigFile = FinalFile;
+      }
+      Rename(DestFile,FinalFile);
+      chmod(FinalFile.c_str(),0644);
+
+      DestFile = FinalFile;
+   }
+
    // No Release file was present, or verification failed, so fall
    // back to queueing Packages files without verification
    QueueIndexes(false);
@@ -1625,7 +1690,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
 
    // Select a source
    if (QueueNext() == false && _error->PendingError() == false)
-      _error->Error(_("I wasn't able to locate file for the %s package. "
+      _error->Error(_("I wasn't able to locate a file for the %s package. "
 		    "This might mean you need to manually fix this package."),
 		    Version.ParentPkg().Name());
 }

+ 100 - 147
apt-pkg/acquire-method.cc

@@ -23,9 +23,7 @@
 #include <apt-pkg/hashes.h>
 
 #include <iostream>
-#include <stdarg.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <sys/signal.h>
 									/*}}}*/
 
@@ -36,32 +34,28 @@ using namespace std;
 /* This constructs the initialization text */
 pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags)
 {
-   char S[300] = "";
-   char *End = S;
-   strcat(End,"100 Capabilities\n");
-   sprintf(End+strlen(End),"Version: %s\n",Ver);
+   std::cout << "100 Capabilities\n"
+	     << "Version: " << Ver << "\n";
 
    if ((Flags & SingleInstance) == SingleInstance)
-      strcat(End,"Single-Instance: true\n");
-   
+      std::cout << "Single-Instance: true\n";
+
    if ((Flags & Pipeline) == Pipeline)
-      strcat(End,"Pipeline: true\n");
-   
+      std::cout << "Pipeline: true\n";
+
    if ((Flags & SendConfig) == SendConfig)
-      strcat(End,"Send-Config: true\n");
+      std::cout << "Send-Config: true\n";
 
    if ((Flags & LocalOnly) == LocalOnly)
-      strcat(End,"Local-Only: true\n");
+      std::cout <<"Local-Only: true\n";
 
    if ((Flags & NeedsCleanup) == NeedsCleanup)
-      strcat(End,"Needs-Cleanup: true\n");
+      std::cout << "Needs-Cleanup: true\n";
 
    if ((Flags & Removable) == Removable)
-      strcat(End,"Removable: true\n");
-   strcat(End,"\n");
+      std::cout << "Removable: true\n";
 
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+   std::cout << "\n" << std::flush;
 
    SetNonBlock(STDIN_FILENO,true);
 
@@ -94,13 +88,11 @@ void pkgAcqMethod::Fail(string Err,bool Transient)
       if (*I == '\n') 
 	 *I = ' ';
    }
-   
-   char S[1024];
-   char *End = S;
+
    if (Queue != 0)
    {
-      End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n"
-		      "Message: %s %s\n",Queue->Uri.c_str(), Err.c_str(), IP.c_str());
+      std::cout << "400 URI Failure\nURI: " << Queue->Uri << "\n"
+		<< "Message: " << Err << " " << IP << "\n";
       // Dequeue
       FetchItem *Tmp = Queue;
       Queue = Queue->Next;
@@ -109,22 +101,17 @@ void pkgAcqMethod::Fail(string Err,bool Transient)
 	 QueueBack = Queue;
    }
    else
-   {
-      End += snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: <UNKNOWN>\n"
-		      "Message: %s\n",Err.c_str());
-   }
+      std::cout << "400 URI Failure\nURI: <UNKNOWN>\nMessage: " << Err << "\n";
+
    if(FailReason.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"FailReason: %s\n",FailReason.c_str());
+      std::cout << "FailReason: " << FailReason << "\n";
    if (UsedMirror.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
-   // Set the transient flag 
+      std::cout << "UsedMirror: " << UsedMirror << "\n";
+   // Set the transient flag
    if (Transient == true)
-      strcat(S,"Transient-Failure: true\n\n");
-   else
-      strcat(S,"\n");
-   
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+      std::cout << "Transient-Failure: true\n";
+
+   std::cout << "\n" << std::flush;
 }
 									/*}}}*/
 // AcqMethod::URIStart - Indicate a download is starting		/*{{{*/
@@ -134,27 +121,22 @@ void pkgAcqMethod::URIStart(FetchResult &Res)
 {
    if (Queue == 0)
       abort();
-   
-   char S[1024] = "";
-   char *End = S;
-   
-   End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",Queue->Uri.c_str());
+
+   std::cout << "200 URI Start\n"
+	     << "URI: " << Queue->Uri << "\n";
    if (Res.Size != 0)
-      End += snprintf(End,sizeof(S)-4 - (End - S),"Size: %lu\n",Res.Size);
-   
+      std::cout << "Size: " << Res.Size << "\n";
+
    if (Res.LastModified != 0)
-      End += snprintf(End,sizeof(S)-4 - (End - S),"Last-Modified: %s\n",
-		      TimeRFC1123(Res.LastModified).c_str());
-   
+      std::cout << "Last-Modified: " << TimeRFC1123(Res.LastModified) << "\n";
+
    if (Res.ResumePoint != 0)
-      End += snprintf(End,sizeof(S)-4 - (End - S),"Resume-Point: %lu\n",
-		      Res.ResumePoint);
+      std::cout << "Resume-Point: " << Res.ResumePoint << "\n";
+
    if (UsedMirror.empty() == false)
-      End += snprintf(End,sizeof(S)-4 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
-      
-   strcat(End,"\n");
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+      std::cout << "UsedMirror: " << UsedMirror << "\n";
+
+   std::cout << "\n" << std::flush;
 }
 									/*}}}*/
 // AcqMethod::URIDone - A URI is finished				/*{{{*/
@@ -164,76 +146,65 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
 {
    if (Queue == 0)
       abort();
-   
-   char S[1024] = "";
-   char *End = S;
-   
-   End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",Queue->Uri.c_str());
+
+   std::cout << "201 URI Done\n"
+	     << "URI: " << Queue->Uri << "\n";
 
    if (Res.Filename.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"Filename: %s\n",Res.Filename.c_str());
-   
+      std::cout << "Filename: " << Res.Filename << "\n";
+
    if (Res.Size != 0)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"Size: %lu\n",Res.Size);
-   
+      std::cout << "Size: " << Res.Size << "\n";
+
    if (Res.LastModified != 0)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"Last-Modified: %s\n",
-		      TimeRFC1123(Res.LastModified).c_str());
+      std::cout << "Last-Modified: " << TimeRFC1123(Res.LastModified) << "\n";
 
    if (Res.MD5Sum.empty() == false)
-   {
-      End += snprintf(End,sizeof(S)-50 - (End - S),"MD5-Hash: %s\n",Res.MD5Sum.c_str());
-      End += snprintf(End,sizeof(S)-50 - (End - S),"MD5Sum-Hash: %s\n",Res.MD5Sum.c_str());
-   }
+      std::cout << "MD5-Hash: " << Res.MD5Sum << "\n"
+		<< "MD5Sum-Hash: " << Res.MD5Sum << "\n";
    if (Res.SHA1Sum.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA1-Hash: %s\n",Res.SHA1Sum.c_str());
+      std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
    if (Res.SHA256Sum.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"SHA256-Hash: %s\n",Res.SHA256Sum.c_str());
+      std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
    if (UsedMirror.empty() == false)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"UsedMirror: %s\n",UsedMirror.c_str());
-   if (Res.GPGVOutput.size() > 0)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"GPGVOutput:\n");     
-   for (vector<string>::iterator I = Res.GPGVOutput.begin();
-      I != Res.GPGVOutput.end(); I++)
-      End += snprintf(End,sizeof(S)-50 - (End - S), " %s\n", (*I).c_str());
+      std::cout << "UsedMirror: " << UsedMirror << "\n";
+   if (Res.GPGVOutput.empty() == false)
+   {
+      std::cout << "GPGVOutput:\n";
+      for (vector<string>::const_iterator I = Res.GPGVOutput.begin();
+	   I != Res.GPGVOutput.end(); ++I)
+	 std::cout << " " << *I << "\n";
+   }
 
    if (Res.ResumePoint != 0)
-      End += snprintf(End,sizeof(S)-50 - (End - S),"Resume-Point: %lu\n",
-		      Res.ResumePoint);
+      std::cout << "Resume-Point: " << Res.ResumePoint << "\n";
 
    if (Res.IMSHit == true)
-      strcat(End,"IMS-Hit: true\n");
-   End = S + strlen(S);
-   
+      std::cout << "IMS-Hit: true\n";
+
    if (Alt != 0)
    {
       if (Alt->Filename.empty() == false)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str());
-      
+	 std::cout << "Alt-Filename: " << Alt->Filename << "\n";
+
       if (Alt->Size != 0)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Size: %lu\n",Alt->Size);
-      
+	 std::cout << "Alt-Size: " << Alt->Size << "\n";
+
       if (Alt->LastModified != 0)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Last-Modified: %s\n",
-			 TimeRFC1123(Alt->LastModified).c_str());
-      
+	 std::cout << "Alt-Last-Modified: " << TimeRFC1123(Alt->LastModified) << "\n";
+
       if (Alt->MD5Sum.empty() == false)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-MD5-Hash: %s\n",
-			 Alt->MD5Sum.c_str());
+	 std::cout << "Alt-MD5-Hash: " << Alt->MD5Sum << "\n";
       if (Alt->SHA1Sum.empty() == false)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA1-Hash: %s\n",
-			 Alt->SHA1Sum.c_str());
+	 std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
       if (Alt->SHA256Sum.empty() == false)
-	 End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-SHA256-Hash: %s\n",
-			 Alt->SHA256Sum.c_str());
-      
+	 std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
+
       if (Alt->IMSHit == true)
-	 strcat(End,"Alt-IMS-Hit: true\n");
+	 std::cout << "Alt-IMS-Hit: true\n";
    }
-   
-   strcat(End,"\n");
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+
+   std::cout << "\n" << std::flush;
 
    // Dequeue
    FetchItem *Tmp = Queue;
@@ -249,13 +220,10 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
    to be ackd */
 bool pkgAcqMethod::MediaFail(string Required,string Drive)
 {
-   char S[1024];
-   snprintf(S,sizeof(S),"403 Media Failure\nMedia: %s\nDrive: %s\n\n",
+   fprintf(stdout, "403 Media Failure\nMedia: %s\nDrive: %s\n",
 	    Required.c_str(),Drive.c_str());
+   std::cout << "\n" << std::flush;
 
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
-   
    vector<string> MyMessages;
    
    /* Here we read messages until we find a 603, each non 603 message is
@@ -406,30 +374,34 @@ int pkgAcqMethod::Run(bool Single)
    return 0;
 }
 									/*}}}*/
-// AcqMethod::Log - Send a log message					/*{{{*/
+// AcqMethod::PrintStatus - privately really send a log/status message	/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqMethod::Log(const char *Format,...)
+void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
+			       va_list &args) const
 {
    string CurrentURI = "<UNKNOWN>";
    if (Queue != 0)
       CurrentURI = Queue->Uri;
-   
+   if (UsedMirror.empty() == true)
+      fprintf(stdout, "%s\nURI: %s\nMessage: ",
+	      header, CurrentURI.c_str());
+   else
+      fprintf(stdout, "%s\nURI: %s\nUsedMirror: %s\nMessage: ",
+	      header, CurrentURI.c_str(), UsedMirror.c_str());
+   vfprintf(stdout,Format,args);
+   std::cout << "\n\n" << std::flush;
+}
+									/*}}}*/
+// AcqMethod::Log - Send a log message					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqMethod::Log(const char *Format,...)
+{
    va_list args;
    va_start(args,Format);
-
-   // sprintf the description
-   char S[1024];
-   unsigned int Len = snprintf(S,sizeof(S)-4,"101 Log\n"
-                               "URI: %s\n"
-                               "UsedMirror: %s\n"
-			       "Message: ", UsedMirror.c_str(),
-                               CurrentURI.c_str());
-   vsnprintf(S+Len,sizeof(S)-4-Len,Format,args);
-   strcat(S,"\n\n");
-   
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+   PrintStatus("101 Log", Format, args);
+   va_end(args);
 }
 									/*}}}*/
 // AcqMethod::Status - Send a status message				/*{{{*/
@@ -437,26 +409,10 @@ void pkgAcqMethod::Log(const char *Format,...)
 /* */
 void pkgAcqMethod::Status(const char *Format,...)
 {
-   string CurrentURI = "<UNKNOWN>";
-   if (Queue != 0)
-      CurrentURI = Queue->Uri;
-   
    va_list args;
    va_start(args,Format);
-
-   // sprintf the description
-   char S[1024];
-   unsigned int Len = snprintf(S,sizeof(S)-4,"102 Status\n"
-                               "URI: %s\n"
-                               "UsedMirror: %s\n"
-			       "Message: ",UsedMirror.c_str(),
-                               CurrentURI.c_str());
-
-   vsnprintf(S+Len,sizeof(S)-4-Len,Format,args);
-   strcat(S,"\n\n");
-   
-   if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
-      exit(100);
+   PrintStatus("102 Status", Format, args);
+   va_end(args);
 }
 									/*}}}*/
 // AcqMethod::Redirect - Send a redirect message                       /*{{{*/
@@ -465,16 +421,13 @@ void pkgAcqMethod::Status(const char *Format,...)
    to keep the pipeline synchronized. */
 void pkgAcqMethod::Redirect(const string &NewURI)
 {
-   string CurrentURI = "<UNKNOWN>";
+   std::cout << "103 Redirect\nURI: ";
    if (Queue != 0)
-      CurrentURI = Queue->Uri;
- 
-   char S[1024];
-   snprintf(S, sizeof(S)-50, "103 Redirect\nURI: %s\nNew-URI: %s\n\n",
-         CurrentURI.c_str(), NewURI.c_str());
-
-   if (write(STDOUT_FILENO,S,strlen(S)) != (ssize_t)strlen(S))
-      exit(100);
+      std::cout << Queue->Uri << "\n";
+   else
+      std::cout << "<UNKNOWN>\n";
+   std::cout << "New-URI: " << NewURI << "\n"
+	     << "\n" << std::flush;
 
    // Change the URI for the request.
    Queue->Uri = NewURI;

+ 3 - 0
apt-pkg/acquire-method.h

@@ -23,6 +23,7 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/strutl.h>
 
+#include <stdarg.h>
 
 class Hashes;
 class pkgAcqMethod
@@ -78,6 +79,8 @@ class pkgAcqMethod
    bool MediaFail(string Required,string Drive);
    virtual void Exit() {};
 
+   void PrintStatus(char const * const header, const char* Format, va_list &args) const;
+
    public:
    enum CnfFlags {SingleInstance = (1<<0),
                   Pipeline = (1<<1), SendConfig = (1<<2),

+ 5 - 6
apt-pkg/acquire-worker.cc

@@ -287,10 +287,10 @@ bool pkgAcquire::Worker::RunMessages()
 	       Log->Pulse(Owner->GetOwner());
 	    
 	    OwnerQ->ItemDone(Itm);
-	    if (TotalSize != 0 &&
-		(unsigned)atoi(LookupTag(Message,"Size","0").c_str()) != TotalSize)
-	       _error->Warning("Bizarre Error - File size is not what the server reported %s %lu",
-			       LookupTag(Message,"Size","0").c_str(),TotalSize);
+	    unsigned long const ServerSize = atol(LookupTag(Message,"Size","0").c_str());
+	    if (TotalSize != 0 && ServerSize != TotalSize)
+	       _error->Warning("Size of file %s is not what the server reported %s %lu",
+			       Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize);
 
 	    // see if there is a hash to verify
 	    string RecivedHash;
@@ -309,8 +309,7 @@ bool pkgAcquire::Worker::RunMessages()
 		       << endl << endl;
 	       }
 	    }
-	    Owner->Done(Message,atoi(LookupTag(Message,"Size","0").c_str()),
-			RecivedHash.c_str(), Config);
+	    Owner->Done(Message, ServerSize, RecivedHash.c_str(), Config);
 	    ItemDone();
 	    
 	    // Log that we are done

+ 9 - 26
apt-pkg/algorithms.cc

@@ -101,9 +101,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
 	 DepIterator Start;
 	 DepIterator End;
 	 D.GlobOr(Start,End);
-	 if (Start->Type == pkgCache::Dep::Conflicts ||
-	     Start->Type == pkgCache::Dep::DpkgBreaks ||
-	     Start->Type == pkgCache::Dep::Obsoletes ||
+	 if (Start.IsNegative() == true ||
 	     End->Type == pkgCache::Dep::PreDepends)
          {
 	    if ((Sim[End] & pkgDepCache::DepGInstall) == 0)
@@ -647,12 +645,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
       // Compute a single dependency element (glob or)
       pkgCache::DepIterator Start = D;
       pkgCache::DepIterator End = D;
-      unsigned char State = 0;
       for (bool LastOR = true; D.end() == false && LastOR == true;)
       {
-	 State |= Cache[D];
 	 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
-	 D++;
+	 ++D;
 	 if (LastOR == true)
 	    End = D;
       }
@@ -697,9 +693,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 	    {
 	       /* We let the algorithm deal with conflicts on its next iteration,
 		it is much smarter than us */
-	       if (Start->Type == pkgCache::Dep::Conflicts || 
-		   Start->Type == pkgCache::Dep::DpkgBreaks || 
-		   Start->Type == pkgCache::Dep::Obsoletes)
+	       if (Start.IsNegative() == true)
 		   break;
 	       
 	       if (Debug == true)
@@ -928,9 +922,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	       if a package has a dep on another package that cant be found */
 	    SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
 	    if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
-		Start->Type != pkgCache::Dep::Conflicts &&
-		Start->Type != pkgCache::Dep::DpkgBreaks &&
-		Start->Type != pkgCache::Dep::Obsoletes &&
+		Start.IsNegative() == false &&
 		Cache[I].NowBroken() == false)
 	    {	       
 	       if (InOr == true)
@@ -955,10 +947,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                   at is not the currently selected version of the 
                   package, which means it is not necessary to 
                   remove/keep */
-               if (Cache[Pkg].InstallVer != Ver &&
-                   (Start->Type == pkgCache::Dep::Conflicts ||
-                    Start->Type == pkgCache::Dep::DpkgBreaks ||
-                    Start->Type == pkgCache::Dep::Obsoletes)) 
+               if (Cache[Pkg].InstallVer != Ver && Start.IsNegative() == true)
                {
                   if (Debug) 
                      clog << "  Conflicts//Breaks against version " 
@@ -976,9 +965,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	          fiddle with the VList package */
 	       if (Scores[I->ID] <= Scores[Pkg->ID] ||
 		   ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
-		    End->Type != pkgCache::Dep::Conflicts &&
-		    End->Type != pkgCache::Dep::DpkgBreaks &&
-		    End->Type != pkgCache::Dep::Obsoletes))
+		    End.IsNegative() == false))
 	       {
 		  // Try a little harder to fix protected packages..
 		  if ((Flags[I->ID] & Protected) == Protected)
@@ -1085,10 +1072,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    }
 
 	    // Hm, nothing can possibly satisify this dep. Nuke it.
-	    if (VList[0] == 0 && 
-		Start->Type != pkgCache::Dep::Conflicts &&
-		Start->Type != pkgCache::Dep::DpkgBreaks &&
-		Start->Type != pkgCache::Dep::Obsoletes &&
+	    if (VList[0] == 0 &&
+		Start.IsNegative() == false &&
 		(Flags[I->ID] & Protected) != Protected)
 	    {
 	       bool Installed = Cache[I].Install();
@@ -1134,9 +1119,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	       Change = true;
 	       if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
 	       {
-		  if (J->Dep->Type == pkgCache::Dep::Conflicts || 
-		      J->Dep->Type == pkgCache::Dep::DpkgBreaks ||
-		      J->Dep->Type == pkgCache::Dep::Obsoletes)
+		  if (J->Dep.IsNegative() == true)
 		  {
 		     if (Debug == true)
 			clog << "  Fixing " << I.FullName(false) << " via remove of " << J->Pkg.FullName(false) << endl;

+ 1 - 0
apt-pkg/cacheiterators.h

@@ -287,6 +287,7 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
 	inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
 	inline bool Reverse() const {return Type == DepRev;};
 	bool IsCritical() const;
+	bool IsNegative() const;
 	void GlobOr(DepIterator &Start,DepIterator &End);
 	Version **AllTargets() const;
 	bool SmartTargetPkg(PkgIterator &Result) const;

+ 13 - 13
apt-pkg/cacheset.h

@@ -135,7 +135,7 @@ public:									/*{{{*/
 	static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
 	static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
-		return APT::PackageSet::FromTask(Cache, pattern, helper);
+		return FromTask(Cache, pattern, helper);
 	}
 
 	/** \brief returns all packages in the cache whose name matchs a given pattern
@@ -149,7 +149,7 @@ public:									/*{{{*/
 	static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
 	static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
 		CacheSetHelper helper;
-		return APT::PackageSet::FromRegEx(Cache, pattern, helper);
+		return FromRegEx(Cache, pattern, helper);
 	}
 
 	/** \brief returns all packages specified by a string
@@ -160,7 +160,7 @@ public:									/*{{{*/
 	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
 	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) {
 		CacheSetHelper helper;
-		return APT::PackageSet::FromString(Cache, string, helper);
+		return FromString(Cache, string, helper);
 	}
 
 	/** \brief returns a package specified by a string
@@ -171,7 +171,7 @@ public:									/*{{{*/
 	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
 	static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) {
 		CacheSetHelper helper;
-		return APT::PackageSet::FromName(Cache, string, helper);
+		return FromName(Cache, string, helper);
 	}
 
 	/** \brief returns all packages specified on the commandline
@@ -184,7 +184,7 @@ public:									/*{{{*/
 	static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
 	static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
 		CacheSetHelper helper;
-		return APT::PackageSet::FromCommandLine(Cache, cmdline, helper);
+		return FromCommandLine(Cache, cmdline, helper);
 	}
 
 	struct Modifier {
@@ -215,7 +215,7 @@ public:									/*{{{*/
 		std::list<PackageSet::Modifier> const &mods,
 		unsigned short const &fallback) {
 		CacheSetHelper helper;
-		return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline,
+		return GroupedFromCommandLine(Cache, cmdline,
 				mods, fallback, helper);
 	}
 
@@ -309,10 +309,10 @@ public:									/*{{{*/
 	static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
 			APT::VersionSet::Version const &fallback) {
 		CacheSetHelper helper;
-		return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, helper);
+		return FromCommandLine(Cache, cmdline, fallback, helper);
 	}
 	static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
-		return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST);
+		return FromCommandLine(Cache, cmdline, CANDINST);
 	}
 
 	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
@@ -321,10 +321,10 @@ public:									/*{{{*/
 	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
 			APT::VersionSet::Version const &fallback) {
 		CacheSetHelper helper;
-		return APT::VersionSet::FromString(Cache, pkg, fallback, helper);
+		return FromString(Cache, pkg, fallback, helper);
 	}
 	static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) {
-		return APT::VersionSet::FromString(Cache, pkg, CANDINST);
+		return FromString(Cache, pkg, CANDINST);
 	}
 
 	/** \brief returns all versions specified for the package
@@ -338,10 +338,10 @@ public:									/*{{{*/
 	static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
 			APT::VersionSet::Version const &fallback) {
 		CacheSetHelper helper;
-		return APT::VersionSet::FromPackage(Cache, P, fallback, helper);
+		return FromPackage(Cache, P, fallback, helper);
 	}
 	static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
-		return APT::VersionSet::FromPackage(Cache, P, CANDINST);
+		return FromPackage(Cache, P, CANDINST);
 	}
 
 	struct Modifier {
@@ -364,7 +364,7 @@ public:									/*{{{*/
 		std::list<VersionSet::Modifier> const &mods,
 		unsigned short const &fallback) {
 		CacheSetHelper helper;
-		return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline,
+		return GroupedFromCommandLine(Cache, cmdline,
 				mods, fallback, helper);
 	}
 									/*}}}*/

+ 54 - 34
apt-pkg/cdrom.cc

@@ -155,7 +155,11 @@ bool pkgCdrom::FindPackages(string CD,
 	 break;
 
       if (chdir(CD.c_str()) != 0)
-	 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
+      {
+	 _error->Errno("chdir","Unable to change to %s", CD.c_str());
+	 closedir(D);
+	 return false;
+      }
    };
 
    closedir(D);
@@ -257,8 +261,10 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
       Inodes[I] = Buf.st_ino;
    }
    
-   if (_error->PendingError() == true)
+   if (_error->PendingError() == true) {
+      delete[] Inodes;
       return false;
+   }
    
    // Look for dups
    for (unsigned int I = 0; I != List.size(); I++)
@@ -513,7 +519,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
 
-   if(log) {
+   if (log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
 		      CDROM.c_str());
@@ -523,7 +530,7 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
       return _error->Error("Failed to mount the cdrom.");
 
    // Hash the CD to get an ID
-   if(log) 
+   if (log != NULL)
       log->Update(_("Identifying.. "));
    
 
@@ -533,10 +540,12 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
       return false;
    }
 
-   msg.str("");
-   ioprintf(msg, "[%s]\n",ident.c_str());
-   log->Update(msg.str());
-
+   if (log != NULL)
+   {
+      msg.str("");
+      ioprintf(msg, "[%s]\n",ident.c_str());
+      log->Update(msg.str());
+   }
 
    // Read the database
    Configuration Database;
@@ -547,7 +556,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
 	 return _error->Error("Unable to read the cdrom database %s",
 			      DFile.c_str());
    }
-   if(log) {
+   if (log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("Stored label: %s\n"),
       Database.Find("CD::"+ident).c_str());
@@ -555,8 +565,10 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)		/*{{{*/
    }
 
    // Unmount and finish
-   if (_config->FindB("APT::CDROM::NoMount",false) == false) {
-      log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
+   if (_config->FindB("APT::CDROM::NoMount",false) == false)
+   {
+      if (log != NULL)
+	 log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
       UnmountCdrom(CDROM);
    }
 
@@ -572,7 +584,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
    
-   if(log) {
+   if(log != NULL)
+   {
       log->SetTotal(STEP_LAST);
       msg.str("");
       ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
@@ -592,11 +605,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    // Unmount the CD and get the user to put in the one they want
    if (_config->FindB("APT::CDROM::NoMount",false) == false)
    {
-      if(log)
+      if(log != NULL)
 	 log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
       UnmountCdrom(CDROM);
 
-      if(log) {
+      if(log != NULL)
+      {
 	 log->Update(_("Waiting for disc...\n"), STEP_WAIT);
 	 if(!log->ChangeCdrom()) {
 	    // user aborted
@@ -605,26 +619,29 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       }
 
       // Mount the new CDROM
-      log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+      if(log != NULL)
+	 log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+
       if (MountCdrom(CDROM) == false)
 	 return _error->Error("Failed to mount the cdrom.");
    }
    
    // Hash the CD to get an ID
-   if(log)
+   if(log != NULL)
       log->Update(_("Identifying.. "), STEP_IDENT);
    string ID;
    if (IdentCdrom(CDROM,ID) == false)
    {
-      log->Update("\n");
+      if (log != NULL)
+	 log->Update("\n");
       return false;
    }
-   if(log) 
+   if(log != NULL)
+   {
       log->Update("["+ID+"]\n");
-
-   if(log) 
       log->Update(_("Scanning disc for index files..\n"),STEP_SCAN);
-   
+   }
+
    // Get the CD structure
    vector<string> List;
    vector<string> SourceList;
@@ -634,7 +651,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    string InfoDir;
    if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false)
    {
-      log->Update("\n");
+      if (log != NULL)
+	 log->Update("\n");
       return false;
    }
 
@@ -661,7 +679,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
    DropRepeats(SourceList,"Sources");
    DropRepeats(SigList,"Release.gpg");
    DropRepeats(TransList,"");
-   if(log) {
+   if(log != NULL) {
       msg.str("");
       ioprintf(msg, _("Found %zu package indexes, %zu source indexes, "
 		      "%zu translation indexes and %zu signatures\n"), 
@@ -698,7 +716,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	       if (*J == '"' || *J == ']' || *J == '[')
 		  *J = '_';
 	    
-	    if(log) {
+	    if(log != NULL)
+	    {
 	       msg.str("");
 	       ioprintf(msg, _("Found label '%s'\n"), Name.c_str());
 	       log->Update(msg.str());
@@ -710,7 +729,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       if (_config->FindB("APT::CDROM::Rename",false) == true ||
 	  Name.empty() == true)
       {
-	 if(!log) 
+	 if(log == NULL) 
          {
 	    if (_config->FindB("APT::CDROM::NoMount",false) == false) 
 	       UnmountCdrom(CDROM);
@@ -743,13 +762,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	 *J = '_';
    
    Database.Set("CD::" + ID,Name);
-   if(log) {
+   if(log != NULL)
+   {
       msg.str("");
       ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
       log->Update(msg.str());
+      log->Update(_("Copying package lists..."), STEP_COPY);
    }
-
-   log->Update(_("Copying package lists..."), STEP_COPY);
    // take care of the signatures and copy them if they are ok
    // (we do this before PackageCopy as it modifies "List" and "SourceList")
    SigVerify SignVerify;
@@ -774,16 +793,15 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
       if (WriteDatabase(Database) == false)
 	 return false;
       
-      if(log) {
+      if(log != NULL)
 	 log->Update(_("Writing new source list\n"), STEP_WRITE);
-      }
       if (WriteSourceList(Name,List,false) == false ||
 	  WriteSourceList(Name,SourceList,true) == false)
 	 return false;
    }
 
    // Print the sourcelist entries
-   if(log) 
+   if(log != NULL)
       log->Update(_("Source list entries for this disc are:\n"));
 
    for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
@@ -796,7 +814,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	 return _error->Error("Internal error");
       }
 
-      if(log) {
+      if(log != NULL)
+      {
 	 msg.str("");
 	 msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
 	    " " << string(*I,Space+1) << endl;
@@ -814,7 +833,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 	 return _error->Error("Internal error");
       }
 
-      if(log) {
+      if(log != NULL) {
 	 msg.str("");
 	 msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
 	    " " << string(*I,Space+1) << endl;
@@ -824,7 +843,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log)					/*{{{*/
 
    // Unmount and finish
    if (_config->FindB("APT::CDROM::NoMount",false) == false) {
-      log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
+      if (log != NULL)
+	 log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST);
       UnmountCdrom(CDROM);
    }
 

+ 10 - 6
apt-pkg/contrib/cdromutl.cc

@@ -20,7 +20,6 @@
 #include <apti18n.h>
     
 #include <sys/wait.h>
-#include <sys/errno.h>
 #include <sys/statvfs.h>
 #include <dirent.h>
 #include <fcntl.h>
@@ -206,8 +205,11 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
       Hash.Add(Dir->d_name);
    };
    
-   if (chdir(StartDir.c_str()) != 0)
-      return _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
+   if (chdir(StartDir.c_str()) != 0) {
+      _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str());
+      closedir(D);
+      return false;
+   }
    closedir(D);
    
    // Some stats from the fsys
@@ -236,7 +238,7 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
 }
 									/*}}}*/
 
-// FindMountPointForDevice - Find mountpoint for the given device      /*{{{*/
+// FindMountPointForDevice - Find mountpoint for the given device	/*{{{*/
 string FindMountPointForDevice(const char *devnode)
 {
    char buf[255];
@@ -254,7 +256,10 @@ string FindMountPointForDevice(const char *devnode)
          while ( fgets(buf, sizeof(buf), f) != NULL) {
             if (strncmp(buf, devnode, strlen(devnode)) == 0) {
                if(TokSplitString(' ', buf, out, 10))
+               {
+                  fclose(f);
                   return string(out[1]);
+               }
             }
          }
          fclose(f);
@@ -263,5 +268,4 @@ string FindMountPointForDevice(const char *devnode)
    
    return string();
 }
-
-
+									/*}}}*/

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

@@ -107,6 +107,7 @@ bool GlobalError::InsertErrno(MsgType type, const char* Function,
 			msgSize = n + 1;
 		else
 			msgSize *= 2;
+		free(S);
 		return true;
 	}
 
@@ -160,6 +161,7 @@ bool GlobalError::Insert(MsgType type, const char* Description,
 			msgSize = n + 1;
 		else
 			msgSize *= 2;
+ 		free(S);
 		return true;
 	}
 

+ 8 - 0
apt-pkg/contrib/mmap.cc

@@ -237,11 +237,19 @@ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
 	if ((this->Flags & Fallback) != Fallback) {
 		// Set the permissions.
 		int Prot = PROT_READ;
+#ifdef MAP_ANONYMOUS
 		int Map = MAP_PRIVATE | MAP_ANONYMOUS;
+#else
+		int Map = MAP_PRIVATE | MAP_ANON;
+#endif
 		if ((this->Flags & ReadOnly) != ReadOnly)
 			Prot |= PROT_WRITE;
 		if ((this->Flags & Public) == Public)
+#ifdef MAP_ANONYMOUS
 			Map = MAP_SHARED | MAP_ANONYMOUS;
+#else
+			Map = MAP_SHARED | MAP_ANON;
+#endif
 
 		// use anonymous mmap() to get the memory
 		Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0);

+ 8 - 4
apt-pkg/contrib/netrc.cc

@@ -160,10 +160,10 @@ void maybe_add_auth (URI &Uri, string NetRCFile)
     {
       char login[64] = "";
       char password[64] = "";
-      char *netrcfile = strdupa (NetRCFile.c_str ());
+      char *netrcfile = strdup(NetRCFile.c_str());
 
       // first check for a generic host based netrc entry
-      char *host = strdupa (Uri.Host.c_str ());
+      char *host = strdup(Uri.Host.c_str());
       if (host && parsenetrc (host, login, password, netrcfile) == 0)
       {
 	 if (_config->FindB("Debug::Acquire::netrc", false) == true)
@@ -173,13 +173,16 @@ void maybe_add_auth (URI &Uri, string NetRCFile)
 		      << std::endl;
         Uri.User = string (login);
         Uri.Password = string (password);
+	free(netrcfile);
+	free(host);
 	return;
       }
+      free(host);
 
       // 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 ());
+      char *hostpath = strdup(string(Uri.Host+Uri.Path).c_str());
       if (hostpath && parsenetrc (hostpath, login, password, netrcfile) == 0)
       {
 	 if (_config->FindB("Debug::Acquire::netrc", false) == true)
@@ -189,8 +192,9 @@ void maybe_add_auth (URI &Uri, string NetRCFile)
 		      << std::endl;
 	 Uri.User = string (login);
 	 Uri.Password = string (password);
-	 return;
       }
+      free(netrcfile);
+      free(hostpath);
     }
   }
 }

+ 1 - 1
apt-pkg/deb/deblistparser.cc

@@ -487,7 +487,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
    // Parse off the package name
    const char *I = Start;
    for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
-	*I != ',' && *I != '|'; I++);
+	*I != ',' && *I != '|' && *I != '[' && *I != ']'; I++);
    
    // Malformed, no '('
    if (I != Stop && *I == ')')

+ 4 - 1
apt-pkg/deb/debmetaindex.cc

@@ -195,11 +195,14 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
 		}
 	}
 
+	std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+	if (lang.empty() == true)
+		return IndexTargets;
+
 	// get the Translations:
 	// - if its a dists-style repository get the i18n/Index first
 	// - if its flat try to acquire files by guessing
 	if (Dist[Dist.size() - 1] == '/') {
-		std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
 		for (std::set<std::string>::const_iterator s = sections.begin();
 		     s != sections.end(); ++s) {
 			for (std::vector<std::string>::const_iterator l = lang.begin();

+ 3 - 2
apt-pkg/deb/dpkgpm.cc

@@ -391,8 +391,9 @@ void pkgDPkgPM::DoTerminalPty(int master)
    {
       // this happens when the child is about to exit, we
       // give it time to actually exit, otherwise we run
-      // into a race
-      usleep(500000);
+      // into a race so we sleep for half a second.
+      struct timespec sleepfor = { 0, 500000000 };
+      nanosleep(&sleepfor, NULL);
       return;
    }  
    if(len <= 0) 

+ 65 - 69
apt-pkg/depcache.cc

@@ -70,7 +70,7 @@ void pkgDepCache::ActionGroup::release()
 	    cache.MarkAndSweep();
 	}
 
-      released = false;
+      released = true;
     }
 }
 
@@ -339,8 +339,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
    /* Check simple depends. A depends -should- never self match but 
       we allow it anyhow because dpkg does. Technically it is a packaging
       bug. Conflicts may never self match */
-   if (Dep.TargetPkg() != Dep.ParentPkg() ||
-       (Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes))
+   if (Dep.TargetPkg() != Dep.ParentPkg() || Dep.IsNegative() == false)
    {
       PkgIterator Pkg = Dep.TargetPkg();
       // Check the base package
@@ -370,8 +369,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
    {
       /* Provides may never be applied against the same package (or group)
          if it is a conflicts. See the comment above. */
-      if (P.OwnerPkg()->Group == Pkg->Group &&
-	  (Dep->Type == Dep::Conflicts || Dep->Type == Dep::DpkgBreaks))
+      if (P.OwnerPkg()->Group == Pkg->Group && Dep.IsNegative() == true)
 	 continue;
       
       // Check if the provides is a hit
@@ -549,8 +547,8 @@ void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
    // Not installed
    if (Pkg->CurrentVer == 0)
    {
-      if (State.Mode == ModeDelete && 
-	  (State.iFlags | Purge) == Purge && Pkg.Purge() == false)
+      if (State.Mode == ModeDelete &&
+	  (State.iFlags & Purge) == Purge && Pkg.Purge() == false)
 	 iDelCount += Add;
       
       if (State.Mode == ModeInstall)
@@ -594,9 +592,7 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V)
 
       /* Invert for Conflicts. We have to do this twice to get the
          right sense for a conflicts group */
-      if (D->Type == Dep::Conflicts ||
-	  D->Type == Dep::DpkgBreaks ||
-	  D->Type == Dep::Obsoletes)
+      if (D.IsNegative() == true)
 	 State = ~State;
       
       // Add to the group if we are within an or..
@@ -607,9 +603,7 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V)
 	 Group = 0;
       
       // Invert for Conflicts
-      if (D->Type == Dep::Conflicts ||
-	  D->Type == Dep::DpkgBreaks ||
-	  D->Type == Dep::Obsoletes)
+      if (D.IsNegative() == true)
 	 State = ~State;
    }	 
 }
@@ -742,9 +736,7 @@ void pkgDepCache::Update(OpProgress *Prog)
 	       Group = 0;
 
 	    // Invert for Conflicts
-	    if (D->Type == Dep::Conflicts ||
-		D->Type == Dep::DpkgBreaks ||
-		D->Type == Dep::Obsoletes)
+	    if (D.IsNegative() == true)
 	       State = ~State;
 	 }
       }
@@ -774,9 +766,7 @@ void pkgDepCache::Update(DepIterator D)
       State = DependencyState(D);
     
       // Invert for Conflicts
-      if (D->Type == Dep::Conflicts ||
-	  D->Type == Dep::DpkgBreaks ||
-	  D->Type == Dep::Obsoletes)
+      if (D.IsNegative() == true)
 	 State = ~State;
 
       RemoveStates(D.ParentPkg());
@@ -1088,7 +1078,22 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       */
       if (IsImportantDep(Start) == false)
 	 continue;
-      
+
+      /* If we are in an or group locate the first or that can 
+         succeed. We have already cached this.. */
+      for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; --Ors)
+	 ++Start;
+      if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer && Start.IsNegative() == false)
+      {
+	 if(DebugAutoInstall == true)
+	    std::clog << OutputInDepth(Depth) << Start << " can't be satisfied!" << std::endl;
+	 if (Start.IsCritical() == false)
+	    continue;
+	 // if the dependency was critical, we can't install it, so remove it again
+	 MarkDelete(Pkg,false,Depth + 1, false);
+	 return;
+      }
+
       /* Check if any ImportantDep() (but not Critical) were added
        * since we installed the package.  Also check for deps that
        * were satisfied in the past: for instance, if a version
@@ -1096,57 +1101,49 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
        * package should follow that Recommends rather than causing the
        * dependency to be removed. (bug #470115)
        */
-      bool isNewImportantDep = false;
-      bool isPreviouslySatisfiedImportantDep = false;
-      if(!ForceImportantDeps && !Start.IsCritical())
+      if (Pkg->CurrentVer != 0 && ForceImportantDeps == false && Start.IsCritical() == false)
       {
-	 bool found=false;
-	 VerIterator instVer = Pkg.CurrentVer();
-	 if(!instVer.end())
+	 bool isNewImportantDep = true;
+	 bool isPreviouslySatisfiedImportantDep = false;
+	 for (DepIterator D = Pkg.CurrentVer().DependsList(); D.end() != true; ++D)
+	 {
+	    //FIXME: Should we handle or-group better here?
+	    // We do not check if the package we look for is part of the same or-group
+	    // we might find while searching, but could that really be a problem?
+	    if (D.IsCritical() == true || IsImportantDep(D) == false ||
+		Start.TargetPkg() != D.TargetPkg())
+	       continue;
+
+	    isNewImportantDep = false;
+
+	    while ((D->CompareOp & Dep::Or) != 0)
+	       ++D;
+
+	    isPreviouslySatisfiedImportantDep = (((*this)[D] & DepGNow) != 0);
+	    if (isPreviouslySatisfiedImportantDep == true)
+	       break;
+	 }
+
+	 if(isNewImportantDep == true)
+	 {
+	    if (DebugAutoInstall == true)
+	       std::clog << OutputInDepth(Depth) << "new important dependency: "
+			 << Start.TargetPkg().FullName() << std::endl;
+	 }
+	 else if(isPreviouslySatisfiedImportantDep == true)
+	 {
+	    if (DebugAutoInstall == true)
+	       std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
+			 << Start.TargetPkg().FullName() << std::endl;
+	 }
+	 else
 	 {
-	   for (DepIterator D = instVer.DependsList(); D.end() != true; D++)
-	     {
-	       //FIXME: deal better with or-groups(?)
-	       if(IsImportantDep(D) && !D.IsCritical() &&
-		  Start.TargetPkg() == D.TargetPkg())
-		 {
-		   if(!isPreviouslySatisfiedImportantDep)
-		     {
-		       DepIterator D2 = D;
-		       while((D2->CompareOp & Dep::Or) != 0)
-			 ++D2;
-
-		       isPreviouslySatisfiedImportantDep =
-			 (((*this)[D2] & DepGNow) != 0);
-		     }
-
-		   found=true;
-		 }
-	     }
-	    // this is a new dep if it was not found to be already
-	    // a important dep of the installed pacakge
-	    isNewImportantDep = !found;
+	    if (DebugAutoInstall == true)
+	       std::clog << OutputInDepth(Depth) << "ignore old unsatisfied important dependency on "
+			 << Start.TargetPkg().FullName() << std::endl;
+	    continue;
 	 }
       }
-      if(isNewImportantDep)
-	 if(DebugAutoInstall == true)
-	    std::clog << OutputInDepth(Depth) << "new important dependency: "
-		      << Start.TargetPkg().Name() << std::endl;
-      if(isPreviouslySatisfiedImportantDep)
-	if(DebugAutoInstall == true)
-	  std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
-		    << Start.TargetPkg().Name() << std::endl;
-
-      // skip important deps if the package is already installed
-      if (Pkg->CurrentVer != 0 && Start.IsCritical() == false 
-	  && !isNewImportantDep && !isPreviouslySatisfiedImportantDep
-	  && !ForceImportantDeps)
-	 continue;
-      
-      /* If we are in an or group locate the first or that can 
-         succeed. We have already cached this.. */
-      for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; Ors--)
-	 Start++;
 
       /* This bit is for processing the possibilty of an install/upgrade
          fixing the problem */
@@ -1212,8 +1209,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       /* For conflicts we just de-install the package and mark as auto,
          Conflicts may not have or groups.  For dpkg's Breaks we try to
          upgrade the package. */
-      if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes ||
-	  Start->Type == Dep::DpkgBreaks)
+      if (Start.IsNegative() == true)
       {
 	 for (Version **I = List; *I != 0; I++)
 	 {

+ 5 - 5
apt-pkg/indexcopy.cc

@@ -75,7 +75,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
       
       // Open the package file
       FileFd Pkg;
-      if (FileExists(*I + GetFileName()) == true)
+      if (RealFileExists(*I + GetFileName()) == true)
       {
 	 Pkg.Open(*I + GetFileName(),FileFd::ReadOnly);
 	 FileSize = Pkg.Size();
@@ -532,7 +532,7 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
    // we skip non-existing files in the verifcation to support a cdrom
    // with no Packages file (just a Package.gz), see LP: #255545
    // (non-existing files are not considered a error)
-   if(!FileExists(prefix+file))
+   if(!RealFileExists(prefix+file))
    {
       _error->Warning(_("Skipping nonexistent file %s"), string(prefix+file).c_str());
       return true;
@@ -601,7 +601,7 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
       string const release = *I+"Release";
 
       // a Release.gpg without a Release should never happen
-      if(FileExists(release) == false)
+      if(RealFileExists(release) == false)
       {
 	 delete MetaIndex;
 	 continue;
@@ -681,7 +681,7 @@ bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG,
    std::vector<string> keyrings;
    if (DirectoryExists(trustedPath))
      keyrings = GetListOfFilesInDir(trustedPath, "gpg", false, true);
-   if (FileExists(trustedFile) == true)
+   if (RealFileExists(trustedFile) == true)
      keyrings.push_back(trustedFile);
 
    std::vector<const char *> Args;
@@ -788,7 +788,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
       
       // Open the package file
       FileFd Pkg;
-      if (FileExists(*I) == true)
+      if (RealFileExists(*I) == true)
       {
 	 Pkg.Open(*I,FileFd::ReadOnly);
 	 FileSize = Pkg.Size();

+ 5 - 13
apt-pkg/orderlist.cc

@@ -490,7 +490,7 @@ bool pkgOrderList::VisitRProvides(DepFunc F,VerIterator Ver)
    bool Res = true;
    for (PrvIterator P = Ver.ProvidesList(); P.end() == false; P++)
       Res &= (this->*F)(P.ParentPkg().RevDependsList());
-   return true;
+   return Res;
 }
 									/*}}}*/
 // OrderList::VisitProvides - Visit all of the providing packages	/*{{{*/
@@ -507,15 +507,11 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical)
       if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)
 	 continue;
       
-      if (D->Type != pkgCache::Dep::Conflicts &&
-	  D->Type != pkgCache::Dep::DpkgBreaks &&
-	  D->Type != pkgCache::Dep::Obsoletes &&
+      if (D.IsNegative() == false &&
 	  Cache[Pkg].InstallVer != *I)
 	 continue;
       
-      if ((D->Type == pkgCache::Dep::Conflicts ||
-	   D->Type == pkgCache::Dep::DpkgBreaks ||
-	   D->Type == pkgCache::Dep::Obsoletes) &&
+      if (D.IsNegative() == true &&
 	  (Version *)Pkg.CurrentVer() != *I)
 	 continue;
       
@@ -647,9 +643,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
       {
 	 /* Forward critical dependencies MUST be correct before the 
 	    package can be unpacked. */
-	 if (D->Type != pkgCache::Dep::Conflicts &&
-	     D->Type != pkgCache::Dep::DpkgBreaks &&
-	     D->Type != pkgCache::Dep::Obsoletes &&
+	 if (D.IsNegative() == false &&
 	     D->Type != pkgCache::Dep::PreDepends)
 	    continue;
 	 	 	 	 
@@ -1077,9 +1071,7 @@ bool pkgOrderList::CheckDep(DepIterator D)
       
       /* Conflicts requires that all versions are not present, depends
          just needs one */
-      if (D->Type != pkgCache::Dep::Conflicts && 
-	  D->Type != pkgCache::Dep::DpkgBreaks && 
-	  D->Type != pkgCache::Dep::Obsoletes)
+      if (D.IsNegative() == false)
       {
 	 /* Try to find something that does not have the after flag set
 	    if at all possible */

+ 37 - 7
apt-pkg/packagemanager.cc

@@ -319,6 +319,17 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
       List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
    }
 
+   if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same)
+      for (PkgIterator P = Pkg.Group().PackageList();
+	   P.end() == false; P = Pkg.Group().NextPkg(P))
+      {
+	 if (Pkg == P || List->IsFlag(P,pkgOrderList::Configured) == true ||
+	     Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
+	      (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
+	    continue;
+	 SmartConfigure(P);
+      }
+
    // Sanity Check
    if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
       return _error->Error(_("Could not perform immediate configuration on '%s'. "
@@ -474,22 +485,29 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
 // ---------------------------------------------------------------------
 /* This performs the task of handling pre-depends. */
 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
+{
+   return SmartUnPack(Pkg, true);
+}
+bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate)
 {
    // Check if it is already unpacked
    if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
        Cache[Pkg].Keep() == true)
    {
       List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
-      if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
+      if (Immediate == true &&
+	  List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
 	 if (SmartConfigure(Pkg) == false)
 	    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;
    }
 
+   VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
+
    /* See if this packages install version has any predependencies
       that are not met by 'now' packages. */
-   for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); 
+   for (DepIterator D = instVer.DependsList();
 	D.end() == false; )
    {
       // Compute a single dependency element (glob or)
@@ -575,20 +593,32 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
 
    // Check for reverse conflicts.
    if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
-		   Cache[Pkg].InstVerIter(Cache).VerStr()) == false)
+		   instVer.VerStr()) == false)
       return false;
    
-   for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList(); 
+   for (PrvIterator P = instVer.ProvidesList();
 	P.end() == false; P++)
       CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
 
+   List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
+
+   if (instVer->MultiArch == pkgCache::Version::Same)
+      for (PkgIterator P = Pkg.Group().PackageList();
+	   P.end() == false; P = Pkg.Group().NextPkg(P))
+      {
+	 if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true ||
+	     Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer &&
+	      (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall))
+	    continue;
+	 SmartUnPack(P, false);
+      }
+
    if(Install(Pkg,FileNames[Pkg->ID]) == false)
       return false;
 
-   List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
-   
    // Perform immedate configuration of the package.
-   if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
+   if (Immediate == true &&
+       List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
       if (SmartConfigure(Pkg) == false)
 	 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);

+ 2 - 0
apt-pkg/packagemanager.h

@@ -69,7 +69,9 @@ class pkgPackageManager : protected pkgCache::Namespace
    // Install helpers
    bool ConfigureAll();
    bool SmartConfigure(PkgIterator Pkg);
+   //FIXME: merge on abi break
    bool SmartUnPack(PkgIterator Pkg);
+   bool SmartUnPack(PkgIterator Pkg, bool const Immediate);
    bool SmartRemove(PkgIterator Pkg);
    bool EarlyRemove(PkgIterator Pkg);   
    

+ 29 - 17
apt-pkg/pkgcache.cc

@@ -211,12 +211,18 @@ pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
 // ---------------------------------------------------------------------
 /* Returns 0 on error, pointer to the package otherwise */
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
-	if (MultiArchCache() == false)
-		return SingleArchFindPkg(Name);
 	size_t const found = Name.find(':');
 	if (found == string::npos)
-		return FindPkg(Name, "native");
+	{
+		if (MultiArchCache() == false)
+			return SingleArchFindPkg(Name);
+		else
+			return FindPkg(Name, "native");
+	}
 	string const Arch = Name.substr(found+1);
+	/* Beware: This is specialcased to handle pkg:any in dependencies as
+	   these are linked to virtual pkg:any named packages with all archs.
+	   If you want any arch from a given pkg, use FindPkg(pkg,arch) */
 	if (Arch == "any")
 		return FindPkg(Name, "any");
 	return FindPkg(Name.substr(0, found), Arch);
@@ -228,7 +234,7 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
 	if (MultiArchCache() == false) {
 		if (Arch == "native" || Arch == "all" || Arch == "any" ||
-		    Arch == _config->Find("APT::Architecture"))
+		    Arch == NativeArch())
 			return SingleArchFindPkg(Name);
 		else
 			return PkgIterator(*this,0);
@@ -322,15 +328,15 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
 	if (Arch == "any")
 		return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage);
 
-	static string const myArch = _config->Find("APT::Architecture");
+	char const* const myArch = Owner->NativeArch();
 	/* Most of the time the package for our native architecture is
 	   the one we add at first to the cache, but this would be the
 	   last one we check, so we do it now. */
 	if (Arch == "native" || Arch == myArch || Arch == "all") {
-		Arch = myArch;
 		pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
-		if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0)
+		if (strcasecmp(myArch, Owner->StrP + Pkg->Arch) == 0)
 			return PkgIterator(*Owner, Pkg);
+		Arch = myArch;
 	}
 
 	/* Iterate over the list to find the matching arch
@@ -503,7 +509,8 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
 {
    string fullname = Name();
    if (Pretty == false ||
-       (strcmp(Arch(), "all") != 0 && _config->Find("APT::Architecture") != Arch()))
+       (strcmp(Arch(), "all") != 0 &&
+	strcmp(Owner->NativeArch(), Arch()) != 0))
       return fullname.append(":").append(Arch());
    return fullname;
 }
@@ -514,15 +521,24 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
    conflicts (including dpkg's Breaks fields). */
 bool pkgCache::DepIterator::IsCritical() const
 {
-   if (S->Type == pkgCache::Dep::Conflicts ||
-       S->Type == pkgCache::Dep::DpkgBreaks ||
-       S->Type == pkgCache::Dep::Obsoletes ||
+   if (IsNegative() == true ||
        S->Type == pkgCache::Dep::Depends ||
        S->Type == pkgCache::Dep::PreDepends)
       return true;
    return false;
 }
 									/*}}}*/
+// DepIterator::IsNegative - Returns true if the dep is a negative one	/*{{{*/
+// ---------------------------------------------------------------------
+/* Some dependencies are positive like Depends and Recommends, others
+   are negative like Conflicts which can and should be handled differently */
+bool pkgCache::DepIterator::IsNegative() const
+{
+   return S->Type == Dep::DpkgBreaks ||
+	  S->Type == Dep::Conflicts ||
+	  S->Type == Dep::Obsoletes;
+}
+									/*}}}*/
 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides	/*{{{*/
 // ---------------------------------------------------------------------
 /* This intellegently looks at dep target packages and tries to figure
@@ -600,9 +616,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() const
 	 if (Owner->VS->CheckDep(I.VerStr(),S->CompareOp,TargetVer()) == false)
 	    continue;
 
-	 if ((S->Type == pkgCache::Dep::Conflicts ||
-	      S->Type == pkgCache::Dep::DpkgBreaks ||
-	      S->Type == pkgCache::Dep::Obsoletes) &&
+	 if (IsNegative() == true &&
 	     ParentPkg() == I.ParentPkg())
 	    continue;
 	 
@@ -617,9 +631,7 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() const
 	 if (Owner->VS->CheckDep(I.ProvideVersion(),S->CompareOp,TargetVer()) == false)
 	    continue;
 	 
-	 if ((S->Type == pkgCache::Dep::Conflicts ||
-	      S->Type == pkgCache::Dep::DpkgBreaks ||
-	      S->Type == pkgCache::Dep::Obsoletes) &&
+	 if (IsNegative() == true &&
 	     ParentPkg() == I.OwnerPkg())
 	    continue;
 	 

+ 6 - 0
apt-pkg/pkgcache.h

@@ -215,6 +215,7 @@ class pkgCache								/*{{{*/
 private:
    bool MultiArchEnabled;
    PkgIterator SingleArchFindPkg(const string &Name);
+   inline char const * const NativeArch() const;
 };
 									/*}}}*/
 // Header structure							/*{{{*/
@@ -649,6 +650,11 @@ struct pkgCache::StringItem
    map_ptrloc NextItem;      // StringItem
 };
 									/*}}}*/
+
+
+inline char const * const pkgCache::NativeArch() const
+	{ return StrP + HeaderP->Architecture; };
+
 #include <apt-pkg/cacheiterators.h>
 
 inline pkgCache::GrpIterator pkgCache::GrpBegin() 

+ 3 - 2
apt-pkg/pkgcachegen.cc

@@ -479,7 +479,8 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
    // Set the name, arch and the ID
    Pkg->Name = Grp->Name;
    Pkg->Group = Grp.Index();
-   map_ptrloc const idxArch = WriteUniqString((Arch == "all") ? _config->Find("APT::Architecture") : Arch.c_str());
+   // all is mapped to the native architecture
+   map_ptrloc const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : WriteUniqString(Arch.c_str());
    if (unlikely(idxArch == 0))
       return false;
    Pkg->Arch = idxArch;
@@ -783,7 +784,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
 
    // We do not add self referencing provides
    if (Ver.ParentPkg().Name() == PkgName && (PkgArch == Ver.ParentPkg().Arch() ||
-	(PkgArch == "all" && _config->Find("APT::Architecture") == Ver.ParentPkg().Arch())))
+	(PkgArch == "all" && strcmp((Cache.StrP + Cache.HeaderP->Architecture), Ver.ParentPkg().Arch()) == 0)))
       return true;
    
    // Get a structure

+ 13 - 1
apt-pkg/policy.cc

@@ -216,10 +216,22 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
       P->Data = Data;
       return;
    }
+   
+   // Allow pinning by wildcards
+   // TODO: Maybe we should always prefer specific pins over non-
+   // specific ones.
+   if (Name[0] == '/' || Name.find_first_of("*[?") != string::npos)
+   {
+      pkgVersionMatch match(Data, Type);
+      for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G)
+	 if (match.ExpressionMatches(Name, G.Name()))
+	    CreatePin(Type, G.Name(), Data, Priority);
+      return;
+   }
 
    // Get a spot to put the pin
    pkgCache::GrpIterator Grp = Cache->FindGrp(Name);
-   for (pkgCache::PkgIterator Pkg = Grp.FindPkg("any");
+   for (pkgCache::PkgIterator Pkg = Grp.PackageList();
 	Pkg.end() != true; Pkg = Grp.NextPkg(Pkg))
    {
       Pin *P = 0;

+ 10 - 14
cmdline/apt-cache.cc

@@ -121,9 +121,7 @@ bool ShowUnMet(pkgCache::VerIterator const &V, bool const &Important)
 		  continue;
 
 	    // Skip conflicts and replaces
-	    if (End->Type == pkgCache::Dep::DpkgBreaks ||
-		End->Type == pkgCache::Dep::Replaces ||
-		End->Type == pkgCache::Dep::Conflicts)
+	    if (End.IsNegative() == true)
 	       continue;
 
 	    // Verify the or group
@@ -848,10 +846,7 @@ bool XVcg(CommandLine &CmdL)
 	       {
 		  /* If a conflicts does not meet anything in the database
 		     then show the relation but do not recurse */
-		  if (Hit == false && 
-		      (D->Type == pkgCache::Dep::Conflicts ||
-		       D->Type == pkgCache::Dep::DpkgBreaks ||
-		       D->Type == pkgCache::Dep::Obsoletes))
+		  if (Hit == false && D.IsNegative() == true)
 		  {
 		     if (Show[D.TargetPkg()->ID] == None && 
 			 Show[D.TargetPkg()->ID] != ToShow)
@@ -1060,9 +1055,7 @@ bool Dotty(CommandLine &CmdL)
 	       {
 		  /* If a conflicts does not meet anything in the database
 		     then show the relation but do not recurse */
-		  if (Hit == false && 
-		      (D->Type == pkgCache::Dep::Conflicts ||
-		       D->Type == pkgCache::Dep::Obsoletes))
+		  if (Hit == false && D.IsNegative() == true)
 		  {
 		     if (Show[D.TargetPkg()->ID] == None && 
 			 Show[D.TargetPkg()->ID] != ToShow)
@@ -1082,6 +1075,7 @@ bool Dotty(CommandLine &CmdL)
 	       {
 		  case pkgCache::Dep::Conflicts:
 		  case pkgCache::Dep::Obsoletes:
+		  case pkgCache::Dep::DpkgBreaks:
 		  printf("[color=springgreen];\n");
 		  break;
 		  
@@ -1115,6 +1109,9 @@ bool Dotty(CommandLine &CmdL)
    }
    
    printf("}\n");
+   delete[] Show;
+   delete[] Flags;
+   delete[] ShapeMap;
    return true;
 }
 									/*}}}*/
@@ -1331,9 +1328,8 @@ bool Search(CommandLine &CmdL)
        return _error->Error("Write to stdout failed");
    return true;
 }
-
-
-/* show automatically installed packages (sorted) */
+									/*}}}*/
+/* ShowAuto - show automatically installed packages (sorted)		{{{*/
 bool ShowAuto(CommandLine &CmdL)
 {
    pkgCacheFile CacheFile;
@@ -1354,6 +1350,7 @@ bool ShowAuto(CommandLine &CmdL)
     for (vector<string>::iterator I = packages.begin(); I != packages.end(); I++)
             cout << *I << "\n";
 
+   _error->Notice(_("This command is deprecated. Please use 'apt-mark showauto' instead."));
    return true;
 }
 									/*}}}*/
@@ -1699,7 +1696,6 @@ bool ShowHelp(CommandLine &Cmd)
       "   unmet - Show unmet dependencies\n"
       "   search - Search the package list for a regex pattern\n"
       "   show - Show a readable record for the package\n"
-      "   showauto - Display a list of automatically installed packages\n"
       "   depends - Show raw dependency information for a package\n"
       "   rdepends - Show reverse dependency information for a package\n"
       "   pkgnames - List the names of all packages in the system\n"

+ 26 - 9
cmdline/apt-get.cc

@@ -2050,8 +2050,8 @@ bool DoInstall(CommandLine &CmdL)
 
    return InstallPackages(Cache,false);   
 }
-
-/* mark packages as automatically/manually installed. */
+									/*}}}*/
+/* mark packages as automatically/manually installed.			{{{*/
 bool DoMarkAuto(CommandLine &CmdL)
 {
    bool Action = true;
@@ -2086,6 +2086,9 @@ bool DoMarkAuto(CommandLine &CmdL)
          AutoMarkChanged++;
       }
    }
+
+   _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
+
    if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false))
       return Cache->writeStateFile(NULL);
    return false;
@@ -2386,8 +2389,10 @@ bool DoSource(CommandLine &CmdL)
       string Src;
       pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
       
-      if (Last == 0)
+      if (Last == 0) {
+	 delete[] Dsc;
 	 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
+      }
       
       string srec = Last->AsStr();
       string::size_type pos = srec.find("\nVcs-");
@@ -2418,8 +2423,10 @@ bool DoSource(CommandLine &CmdL)
 
       // Back track
       vector<pkgSrcRecords::File> Lst;
-      if (Last->Files(Lst) == false)
+      if (Last->Files(Lst) == false) {
+	 delete[] Dsc;
 	 return false;
+      }
 
       // Load them into the fetcher
       for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
@@ -2480,6 +2487,7 @@ bool DoSource(CommandLine &CmdL)
    struct statvfs Buf;
    string OutputDir = ".";
    if (statvfs(OutputDir.c_str(),&Buf) != 0) {
+      delete[] Dsc;
       if (errno == EOVERFLOW)
 	 return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
 				OutputDir.c_str());
@@ -2493,10 +2501,12 @@ bool DoSource(CommandLine &CmdL)
 #if HAVE_STRUCT_STATFS_F_TYPE
            || unsigned(Stat.f_type) != RAMFS_MAGIC
 #endif
-           ) 
+           )  {
+	 delete[] Dsc;
           return _error->Error(_("You don't have enough free space in %s"),
               OutputDir.c_str());
-      }
+       }
+     }
    
    // Number of bytes
    if (DebBytes != FetchBytes)
@@ -2531,7 +2541,10 @@ bool DoSource(CommandLine &CmdL)
    
    // Run it
    if (Fetcher.Run() == pkgAcquire::Failed)
+   {
+      delete[] Dsc;
       return false;
+   }
 
    // Print error messages
    bool Failed = false;
@@ -2546,8 +2559,11 @@ bool DoSource(CommandLine &CmdL)
       Failed = true;
    }
    if (Failed == true)
+   {
+      delete[] Dsc;
       return _error->Error(_("Failed to fetch some archives."));
-   
+   }
+
    if (_config->FindB("APT::Get::Download-only",false) == true)
    {
       c1out << _("Download complete and in download only mode") << endl;
@@ -2638,6 +2654,9 @@ bool DoSource(CommandLine &CmdL)
 bool DoBuildDep(CommandLine &CmdL)
 {
    CacheFile Cache;
+
+   _config->Set("APT::Install-Recommends", false);
+   
    if (Cache.Open(true) == false)
       return false;
 
@@ -3168,8 +3187,6 @@ bool ShowHelp(CommandLine &CmdL)
       "   clean - Erase downloaded archive files\n"
       "   autoclean - Erase old downloaded archive files\n"
       "   check - Verify that there are no broken dependencies\n"
-      "   markauto - Mark the given packages as automatically installed\n"
-      "   unmarkauto - Mark the given packages as manually installed\n"
       "   changelog - Download and display the changelog for the given package\n"
       "   download - Download the binary package into the current directory\n"
       "\n"

+ 0 - 101
cmdline/apt-mark

@@ -1,101 +0,0 @@
-#!/usr/bin/python
-
-from optparse import OptionParser
-
-import sys
-import os.path
-    
-try:
-    import apt_pkg
-except ImportError:
-    print >> sys.stderr, "Error importing apt_pkg, is python-apt installed?"
-    sys.exit(1)
-    
-actions = { "markauto" : 1,
-            "unmarkauto": 0
-          }
-
-def show_automatic(filename):
-    if not os.path.exists(STATE_FILE):
-        return
-    auto = set()
-    tagfile = apt_pkg.TagFile(open(STATE_FILE))
-    for section in tagfile:
-        pkgname = section.get("Package")
-        autoInst = section.get("Auto-Installed")
-        if int(autoInst):
-            auto.add(pkgname)
-    print "\n".join(sorted(auto))
-    
-
-def mark_unmark_automatic(filename, action, pkgs):
-    " mark or unmark automatic flag"
-    # open the statefile
-    if os.path.exists(STATE_FILE):
-        try:
-            tagfile = apt_pkg.TagFile(open(STATE_FILE))
-            outfile = open(STATE_FILE+".tmp","w")
-        except IOError, msg:
-            print "%s, are you root?" % (msg)
-            sys.exit(1)
-        for section in tagfile:
-            pkgname = section.get("Package")
-            autoInst = section.get("Auto-Installed")
-            if pkgname in pkgs:
-                if options.verbose:
-                    print "changing %s to %s" % (pkgname,action)
-                newsec = apt_pkg.rewrite_section(section,
-                                       [],
-                                       [ ("Auto-Installed",str(action)) ])
-                pkgs.remove(pkgname)
-                outfile.write(newsec+"\n")
-            else:
-                outfile.write(str(section)+"\n")
-        if action == 1:
-            for pkgname in pkgs:
-                if options.verbose:
-                    print "changing %s to %s" % (pkgname,action)
-                outfile.write("Package: %s\nAuto-Installed: %d\n\n" % (pkgname, action))
-        # all done, rename the tmpfile
-        os.chmod(outfile.name, 0644)
-        os.rename(outfile.name, STATE_FILE)
-        os.chmod(STATE_FILE, 0644)
-
-
-if __name__ == "__main__":
-    apt_pkg.init()
-
-    # option parsing
-    parser = OptionParser()
-    parser.usage = "%prog [options] {markauto|unmarkauto} packages..."
-    parser.epilog = "apt-mark is deprecated, use apt-get markauto/unmarkauto."
-    parser.add_option("-f", "--file", action="store", type="string",
-                      dest="filename",
-                      help="read/write a different file")
-    parser.add_option("-v", "--verbose",
-                      action="store_true", dest="verbose", default=False,
-                      help="print verbose status messages to stdout")
-    (options, args) = parser.parse_args()
-
-    if not args:
-        parser.print_help()
-        sys.exit(1)
-
-    # get the state-file
-    if not options.filename:
-        STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
-    else:
-        STATE_FILE=options.filename
-
-    if len(args) == 0:
-        parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
-
-    if args[0] == "showauto":
-        show_automatic(STATE_FILE)
-    else:
-        # get pkgs to change
-        if args[0] not in actions.keys():
-            parser.error("first argument must be 'markauto', 'unmarkauto' or 'showauto'")
-        pkgs = args[1:]
-        action = actions[args[0]]
-        mark_unmark_automatic(STATE_FILE, action, pkgs)

+ 373 - 0
cmdline/apt-mark.cc

@@ -0,0 +1,373 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* #####################################################################
+   apt-mark - show and change auto-installed bit information
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/cacheset.h>
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/strutl.h>
+
+#include <config.h>
+#include <apti18n.h>
+
+#include <algorithm>
+									/*}}}*/
+using namespace std;
+
+ostream c0out(0);
+ostream c1out(0);
+ostream c2out(0);
+ofstream devnull("/dev/null");
+/* DoAuto - mark packages as automatically/manually installed		{{{*/
+bool DoAuto(CommandLine &CmdL)
+{
+   pkgCacheFile CacheFile;
+   pkgCache *Cache = CacheFile.GetPkgCache();
+   pkgDepCache *DepCache = CacheFile.GetDepCache();
+   if (unlikely(Cache == NULL || DepCache == NULL))
+      return false;
+
+   APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+   if (pkgset.empty() == true)
+      return _error->Error(_("No packages found"));
+
+   bool MarkAuto = strcasecmp(CmdL.FileList[0],"auto") == 0;
+   int AutoMarkChanged = 0;
+
+   for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+   {
+      if (Pkg->CurrentVer == 0)
+      {
+	 ioprintf(c1out,_("%s can not be marked as it is not installed.\n"), Pkg.FullName(true).c_str());
+	 continue;
+      }
+      else if ((((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto)
+      {
+	 if (MarkAuto == false)
+	    ioprintf(c1out,_("%s was already set to manually installed.\n"), Pkg.FullName(true).c_str());
+	 else
+	    ioprintf(c1out,_("%s was already set to automatically installed.\n"), Pkg.FullName(true).c_str());
+	 continue;
+      }
+
+      if (MarkAuto == false)
+	 ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.FullName(true).c_str());
+      else
+	 ioprintf(c1out,_("%s set to automatically installed.\n"), Pkg.FullName(true).c_str());
+
+      DepCache->MarkAuto(Pkg, MarkAuto);
+      ++AutoMarkChanged;
+   }
+   if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false)
+      return DepCache->writeStateFile(NULL);
+   return true;
+}
+									/*}}}*/
+/* DoMarkAuto - mark packages as automatically/manually installed	{{{*/
+/* Does the same as DoAuto but tries to do it exactly the same why as
+   the python implementation did it so it can be a drop-in replacement */
+bool DoMarkAuto(CommandLine &CmdL)
+{
+   pkgCacheFile CacheFile;
+   pkgCache *Cache = CacheFile.GetPkgCache();
+   pkgDepCache *DepCache = CacheFile.GetDepCache();
+   if (unlikely(Cache == NULL || DepCache == NULL))
+      return false;
+
+   APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+   if (pkgset.empty() == true)
+      return _error->Error(_("No packages found"));
+
+   bool const MarkAuto = strcasecmp(CmdL.FileList[0],"markauto") == 0;
+   bool const Verbose = _config->FindB("APT::MarkAuto::Verbose", false);
+   int AutoMarkChanged = 0;
+
+   for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+   {
+      if (Pkg->CurrentVer == 0 ||
+	  (((*DepCache)[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == MarkAuto)
+	 continue;
+
+      if (Verbose == true)
+	 ioprintf(c1out, "changing %s to %d\n", Pkg.Name(), (MarkAuto == false) ? 0 : 1);
+
+      DepCache->MarkAuto(Pkg, MarkAuto);
+      ++AutoMarkChanged;
+   }
+   if (AutoMarkChanged > 0 && _config->FindB("APT::Mark::Simulate", false) == false)
+      return DepCache->writeStateFile(NULL);
+
+   _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
+
+   return true;
+}
+									/*}}}*/
+/* ShowAuto - show automatically installed packages (sorted)		{{{*/
+bool ShowAuto(CommandLine &CmdL)
+{
+   pkgCacheFile CacheFile;
+   pkgCache *Cache = CacheFile.GetPkgCache();
+   pkgDepCache *DepCache = CacheFile.GetDepCache();
+   if (unlikely(Cache == NULL || DepCache == NULL))
+      return false;
+
+   std::vector<string> packages;
+
+   bool const ShowAuto = strcasecmp(CmdL.FileList[0],"showauto") == 0;
+
+   if (CmdL.FileList[1] == 0)
+   {
+      packages.reserve(Cache->HeaderP->PackageCount / 3);
+      for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+	 if (P->CurrentVer != 0 &&
+	     (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto)
+	    packages.push_back(P.FullName(true));
+   }
+   else
+   {
+      APT::CacheSetHelper helper(false); // do not show errors
+      APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
+      packages.reserve(pkgset.size());
+      for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P)
+	 if (P->CurrentVer != 0 &&
+	     (((*DepCache)[P].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) == ShowAuto)
+	    packages.push_back(P.FullName(true));
+   }
+
+   std::sort(packages.begin(), packages.end());
+
+   for (vector<string>::const_iterator I = packages.begin(); I != packages.end(); ++I)
+      std::cout << *I << std::endl;
+
+   return true;
+}
+									/*}}}*/
+/* DoHold - mark packages as hold by dpkg				{{{*/
+bool DoHold(CommandLine &CmdL)
+{
+   pkgCacheFile CacheFile;
+   pkgCache *Cache = CacheFile.GetPkgCache();
+   if (unlikely(Cache == NULL))
+      return false;
+
+   APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1);
+   if (pkgset.empty() == true)
+      return _error->Error(_("No packages found"));
+
+   bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0;
+
+   for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+   {
+      if ((Pkg->SelectedState == pkgCache::State::Hold) == MarkHold)
+      {
+	 if (MarkHold == true)
+	    ioprintf(c1out,_("%s was already set on hold.\n"), Pkg.FullName(true).c_str());
+	 else
+	    ioprintf(c1out,_("%s was already not hold.\n"), Pkg.FullName(true).c_str());
+	 pkgset.erase(Pkg);
+	 continue;
+      }
+   }
+
+   if (pkgset.empty() == true)
+      return true;
+
+   if (_config->FindB("APT::Mark::Simulate", false) == true)
+   {
+      for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+      {
+	 if (MarkHold == false)
+	    ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str());
+	 else
+	    ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str());
+      }
+      return true;
+   }
+
+   string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg");
+   std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options");
+   for (std::vector<string>::const_iterator o = dpkgoptions.begin();
+	o != dpkgoptions.end(); ++o)
+      dpkgcall.append(" ").append(*o);
+   dpkgcall.append(" --set-selections");
+   FILE *dpkg = popen(dpkgcall.c_str(), "w");
+   if (dpkg == NULL)
+      return _error->Errno("DoHold", "fdopen on dpkg stdin failed");
+
+   for (APT::PackageSet::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+   {
+      if (MarkHold == true)
+      {
+	 fprintf(dpkg, "%s hold\n", Pkg.FullName(true).c_str());
+	 ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str());
+      }
+      else
+      {
+	 fprintf(dpkg, "%s install\n", Pkg.FullName(true).c_str());
+	 ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str());
+      }
+   }
+
+   int const status = pclose(dpkg);
+   if (status == -1)
+      return _error->Errno("DoHold", "dpkg execution failed in the end");
+   if (WIFEXITED(status) == false || WEXITSTATUS(status) != 0)
+      return _error->Error(_("Executing dpkg failed. Are you root?"));
+   return true;
+}
+									/*}}}*/
+/* ShowHold - show packages set on hold in dpkg status			{{{*/
+bool ShowHold(CommandLine &CmdL)
+{
+   pkgCacheFile CacheFile;
+   pkgCache *Cache = CacheFile.GetPkgCache();
+   if (unlikely(Cache == NULL))
+      return false;
+
+   std::vector<string> packages;
+
+   if (CmdL.FileList[1] == 0)
+   {
+      packages.reserve(50); // how many holds are realistic? I hope just a few…
+      for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
+	 if (P->SelectedState == pkgCache::State::Hold)
+	    packages.push_back(P.FullName(true));
+   }
+   else
+   {
+      APT::CacheSetHelper helper(false); // do not show errors
+      APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
+      packages.reserve(pkgset.size());
+      for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P)
+	 if (P->SelectedState == pkgCache::State::Hold)
+	    packages.push_back(P.FullName(true));
+   }
+
+   std::sort(packages.begin(), packages.end());
+
+   for (vector<string>::const_iterator I = packages.begin(); I != packages.end(); ++I)
+      std::cout << *I << std::endl;
+
+   return true;
+}
+									/*}}}*/
+// ShowHelp - Show a help screen					/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool ShowHelp(CommandLine &CmdL)
+{
+   ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION,
+	    COMMON_ARCH,__DATE__,__TIME__);
+
+   cout <<
+    _("Usage: apt-mark [options] {auto|manual} pkg1 [pkg2 ...]\n"
+      "\n"
+      "apt-mark is a simple command line interface for marking packages\n"
+      "as manual or automatical installed. It can also list marks.\n"
+      "\n"
+      "Commands:\n"
+      "   auto - Mark the given packages as automatically installed\n"
+      "   manual - Mark the given packages as manually installed\n"
+      "\n"
+      "Options:\n"
+      "  -h  This help text.\n"
+      "  -q  Loggable output - no progress indicator\n"
+      "  -qq No output except for errors\n"
+      "  -s  No-act. Just prints what would be done.\n"
+      "  -f  read/write auto/manual marking in the given file\n"
+      "  -c=? Read this configuration file\n"
+      "  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
+      "See the apt-mark(8) and apt.conf(5) manual pages for more information.")
+      << std::endl;
+   return true;
+}
+									/*}}}*/
+int main(int argc,const char *argv[])					/*{{{*/
+{
+   CommandLine::Args Args[] = {
+      {'h',"help","help",0},
+      {0,"version","version",0},
+      {'q',"quiet","quiet",CommandLine::IntLevel},
+      {'q',"silent","quiet",CommandLine::IntLevel},
+      {'v',"verbose","APT::MarkAuto::Verbose",0},
+      {'s',"simulate","APT::Mark::Simulate",0},
+      {'s',"just-print","APT::Mark::Simulate",0},
+      {'s',"recon","APT::Mark::Simulate",0},
+      {'s',"dry-run","APT::Mark::Simulate",0},
+      {'s',"no-act","APT::Mark::Simulate",0},
+      {'f',"file","Dir::State::extended_states",CommandLine::HasArg},
+      {'c',"config-file",0,CommandLine::ConfigFile},
+      {'o',"option",0,CommandLine::ArbItem},
+      {0,0,0,0}};
+   CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
+				   {"auto",&DoAuto},
+				   {"manual",&DoAuto},
+				   {"hold",&DoHold},
+				   {"unhold",&DoHold},
+				   {"showauto",&ShowAuto},
+				   {"showmanual",&ShowAuto},
+				   {"showhold",&ShowHold},
+				   // be nice and forgive the typo
+				   {"showholds",&ShowHold},
+				   // be nice and forgive it as it is technical right
+				   {"install",&DoHold},
+				   // obsolete commands for compatibility
+				   {"markauto", &DoMarkAuto},
+				   {"unmarkauto", &DoMarkAuto},
+                                   {0,0}};
+
+   // Set up gettext support
+   setlocale(LC_ALL,"");
+   textdomain(PACKAGE);
+
+   // Parse the command line and initialize the package library
+   CommandLine CmdL(Args,_config);
+   if (pkgInitConfig(*_config) == false ||
+       CmdL.Parse(argc,argv) == false ||
+       pkgInitSystem(*_config,_system) == false)
+   {
+      if (_config->FindB("version") == true)
+	 ShowHelp(CmdL);
+      _error->DumpErrors();
+      return 100;
+   }
+
+   // See if the help should be shown
+   if (_config->FindB("help") == true ||
+       _config->FindB("version") == true ||
+       CmdL.FileSize() == 0)
+   {
+      ShowHelp(CmdL);
+      return 0;
+   }
+
+   // Deal with stdout not being a tty
+   if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
+      _config->Set("quiet","1");
+
+   // Setup the output streams
+   c0out.rdbuf(cout.rdbuf());
+   c1out.rdbuf(cout.rdbuf());
+   c2out.rdbuf(cout.rdbuf());
+   if (_config->FindI("quiet",0) > 0)
+      c0out.rdbuf(devnull.rdbuf());
+   if (_config->FindI("quiet",0) > 1)
+      c1out.rdbuf(devnull.rdbuf());
+
+   // Match the operation
+   CmdL.DispatchArg(Cmds);
+
+   // Print any errors or warnings found during parsing
+   bool const Errors = _error->PendingError();
+   if (_config->FindI("quiet",0) > 0)
+      _error->DumpErrors();
+   else
+      _error->DumpErrors(GlobalError::DEBUG);
+   return Errors == true ? 100 : 0;
+}
+									/*}}}*/

+ 5 - 4
cmdline/makefile

@@ -54,10 +54,11 @@ TARGET=program
 include $(COPY_H)
 
 # The apt-mark program
-SOURCE=apt-mark
-TO=$(BIN)
-TARGET=program
-include $(COPY_H)
+PROGRAM=apt-mark
+SLIBS = -lapt-pkg $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile
+SOURCE = apt-mark.cc
+include $(PROGRAM_H)
 
 # The apt-report-mirror-failure program
 #SOURCE=apt-report-mirror-failure

+ 4 - 2
debian/apt-utils.symbols

@@ -111,11 +111,13 @@ libapt-inst.so.1.2 libapt-inst1.2
  (c++|optional)"vtable for pkgCache::Iterator<pkgCache::Package, pkgCache::PkgIterator>@Base" 0.8.0
  (c++|optional)"vtable for pkgCache::Iterator<pkgCache::Version, pkgCache::VerIterator>@Base" 0.8.0
 ### gcc-4.4 specific
+# (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
+# (c++|optional=std)"std::basic_string<char, std::char_traits<char>, std::allocator<char> >& std::basic_string<char, std::char_traits<char>, std::allocator<char> >::append<unsigned char*>(unsigned char*, unsigned char*)@Base" 0.8.0
+### gcc-4.6 specific
+ (c++|optional=std)"std::vector<APT::Configuration::Compressor, std::allocator<APT::Configuration::Compressor> >::~vector()@Base" 0.8.12 1
  (c++|optional=std)"std::basic_string<char, std::char_traits<char>, std::allocator<char> >& std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_dispatch<unsigned char*>(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, unsigned char*, unsigned char*, std::__false_type)@Base" 0.8.0
 ### try to ignore std:: template instances
- (c++|optional=std)"std::basic_string<char, std::char_traits<char>, std::allocator<char> >& std::basic_string<char, std::char_traits<char>, std::allocator<char> >::append<unsigned char*>(unsigned char*, unsigned char*)@Base" 0.8.0
  (c++|regex|optional=std)"^std::basic_string<.+ >\(.+\)@Base$" 0.8.0
- (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
  (c++|regex|optional=std)"^typeinfo name for std::iterator<.*>@Base$" 0.8.0
  (c++|regex|optional=std)"^typeinfo for std::iterator<.*>@Base$" 0.8.0
 ###

+ 22 - 16
debian/apt.cron.daily

@@ -305,6 +305,26 @@ debug_echo()
     fi
 }
 
+check_power(){
+    # laptop check, on_ac_power returns:
+    #       0 (true)    System is on main power
+    #       1 (false)   System is not on main power
+    #       255 (false) Power status could not be determined
+    # Desktop systems always return 255 it seems
+    if which on_ac_power >/dev/null; then
+        on_ac_power
+        POWER=$?
+        if [ $POWER -eq 1 ]; then
+	    debug_echo "exit: system NOT on main power"
+	    return 1
+        elif [ $POWER -ne 0 ]; then
+	    debug_echo "power status ($POWER) undetermined, continuing"
+        fi
+        debug_echo "system is on main power."
+    fi
+    return 0
+}
+
 # ------------------------ main ----------------------------
 
 # Backup the 7 last versions of APT's extended_states file
@@ -350,22 +370,7 @@ if [ "$VERBOSE" -ge 3 ]; then
     set -x
 fi
 
-# laptop check, on_ac_power returns:
-#       0 (true)    System is on main power
-#       1 (false)   System is not on main power
-#       255 (false) Power status could not be determined
-# Desktop systems always return 255 it seems
-if which on_ac_power >/dev/null; then
-    on_ac_power
-    POWER=$?
-    if [ $POWER -eq 1 ]; then
-	debug_echo "exit: system NOT on main power"
-	exit 0
-    elif [ $POWER -ne 0 ]; then
-	debug_echo "power status ($POWER) undetermined, continuing"
-    fi
-    debug_echo "system is on main power."
-fi
+check_power || exit 0
 
 # check if we can lock the cache and if the cache is clean
 if which apt-get >/dev/null && ! eval apt-get check -f $XAPTOPT $XSTDERR ; then
@@ -416,6 +421,7 @@ do_cache_backup $BackupArchiveInterval
 # sleep random amount of time to avoid hitting the 
 # mirrors at the same time
 random_sleep
+check_power || exit 0
 
 # include default system language so that "apt-get update" will
 # fetch the right translated package descriptions

+ 0 - 3
debian/apt.lintian-overrides

@@ -1,3 +0,0 @@
-# apt-mark is rarely used auxiliary script, we don't want to depend on
-# python-apt only for it. 
-apt binary: python-script-but-no-python-dep ./usr/bin/apt-mark

Разница между файлами не показана из-за своего большого размера
+ 50 - 33
debian/apt.symbols


+ 108 - 5
debian/changelog

@@ -1,8 +1,106 @@
-apt (0.8.13.3) unstable; urgency=low
+apt (0.8.15) UNRELEASED; urgency=low
 
-  [ Thorsten Spindler ]
-  * debian/zzapt.cron.daily:
-    - move cron job to the end of execution (LP: #727685)
+  [ Julian Andres Klode ]
+  * apt-pkg/depcache.cc:
+    - Really release action groups only once (Closes: #622744)
+    - Make purge work again for config-files (LP: #244598) (Closes: #150831)
+  * apt-pkg/acquire-item.cc:
+    - Reject files known to be invalid (LP: #346386) (Closes: #627642)
+  * debian/apt.cron.daily:
+    - Check power after wait, patch by manuel-soto (LP: #705269)
+  * debian/control:
+    - Move ${shlibs:Depends} to Pre-Depends, as we do not want APT
+      unpacked if a library is too old and thus break upgrades
+  * doc/apt-key.8.xml:
+    - Document apt-key net-update (LP: #192810)
+
+  [ Christian Perrier ]
+  * Galician translation update (Miguel Anxo Bouzada). Closes: #626505
+  * Italian translation update (Milo Casagrande). Closes: #627834
+
+  [ David Kalnischkies ]
+  * fix a bunch of cppcheck warnings/errors based on a patch by
+    Niels Thykier, thanks! (Closes: #622805)
+  * apt-pkg/depcache.cc:
+    - really include 'rc' packages in the delete count by fixing a
+      typo which exists since 1999 in the source… (LP: #761175)
+    - if critical or-group can't be satisfied, exit directly.
+  * apt-pkg/acquire-method.cc:
+    - write directly to stdout instead of creating the message in
+      memory first before writing to avoid hitting limits
+    - fix order of CurrentURI and UsedMirror in Status() and Log()
+  * apt-pkg/orderlist.cc:
+    - let VisitRProvides report if the calls were successful
+  * apt-pkg/deb/dpkgpm.cc:
+    - replace obsolete usleep with nanosleep
+  * debian/apt{,-utils}.symbols:
+    - update both experimental symbol-files to reflect 0.8.14 state
+  * debian/rules:
+    - remove unused embedded jquery by doxygen from libapt-pkg-doc
+  * cmdline/apt-mark.cc:
+    - reimplement apt-mark in c++
+    - provide a 'showmanual' command (Closes: #582791)
+    - provide a 'dpkg --set-selections' wrapper to set/release holds
+  * cmdline/apt-get.cc:
+    - deprecate mostly undocumented 'markauto' in favor of 'apt-mark'
+  * cmdline/apt-cache.cc:
+    - deprecate mostly undocumented 'showauto' in favor of 'apt-mark'
+  * apt-pkg/pkgcache.cc:
+    - really ignore :arch in FindPkg() in non-multiarch environment
+  * doc/po/de.po:
+    - undo the translation of the command 'dump' in manpage of apt-config
+      as report by Burghard Grossmann on debian-l10n-german, thanks!
+  * apt-pkg/deb/debmetaindex.cc:
+    - do not download TranslationIndex if no Translation-* will be
+      downloaded later on anyway (Closes: #624218)
+  * test/versions.lst:
+    - disable obscure version number tests with versions dpkg doesn't
+      allow any more as they don't start with a number
+  * apt-pkg/acquire-worker.cc:
+    - print filename in the unmatching size warning (Closes: #623137)
+  * apt-pkg/acquire-item.cc:
+    - apply fix for poorly worded 'locate file' error message from
+      Ben Finney, thanks! (Closes: #623171)
+  * methods/http.cc:
+    - add config option to ignore a closed stdin to be able to easily
+      use the method as a simple standalone downloader
+    - Location header in redirects should be absolute URI, but some
+      servers just send an absolute path so still deal with it properly
+    - dequote URL taken from Location in redirects as we will otherwise
+      quote an already quoted string in the request later (Closes: #602412)
+  * apt-pkg/contrib/netrc.cc:
+    - replace non-posix gnu-extension strdupa with strdup
+  * apt-pkg/packagemanager.cc:
+    - ensure for Multi-Arch:same packages that they are unpacked in
+      lock step even in immediate configuration (Closes: #618288)
+
+ -- Michael Vogt <mvo@debian.org>  Mon, 16 May 2011 14:57:52 +0200
+
+apt (0.8.14.1) unstable; urgency=low
+
+  * apt-pkg/acquire-item.cc:
+    - Only try to rename existing Release files (Closes: #622912)
+
+ -- Julian Andres Klode <jak@debian.org>  Sat, 16 Apr 2011 14:36:10 +0200
+
+apt (0.8.14) unstable; urgency=low
+
+  [ Julian Andres Klode ]
+  * apt-pkg/indexcopy.cc:
+    - Use RealFileExists() instead of FileExists(), allows amongst other
+      things a directory named Sources to exist on a CD-ROM (LP: #750694).
+  * apt-pkg/acquire-item.cc:
+    - Use Release files even if they cannot be verified (LP: #704595)
+  * cmdline/apt-get.cc:
+    - Do not install recommends for build-dep (Closes: #454479) (LP: #245273)
+  * apt-pkg/deb/deblistparser.cc:
+    - Handle no space before "[" in build-dependencies (LP: #72344)
+  * apt-pkg/policy.cc:
+    - Allow pinning by glob() expressions, and regular expressions
+      surrounded by slashes (the "/" character) (LP: #399474)
+      (Closes: #121132)
+  * debian/control:
+    - Set Standards-Version to 3.9.2
   
   [ Michael Vogt ]
   * mirror method:
@@ -13,7 +111,12 @@ apt (0.8.13.3) unstable; urgency=low
     - run unattended-upgrades even if there was a error during
       the apt-get update (LP: #676295)
 
- -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 10 Mar 2011 15:56:54 +0100
+  [ David Kalnischkies ]
+  * apt-pkg/pkgcache.cc:
+    - use the native Architecture stored in the cache header instead of
+      loading it from configuration as suggested by Julian Andres Klode
+
+ -- Julian Andres Klode <jak@debian.org>  Fri, 15 Apr 2011 14:28:15 +0200
 
 apt (0.8.13.2) unstable; urgency=low
 

+ 3 - 2
debian/control

@@ -5,7 +5,7 @@ Maintainer: APT Development Team <deity@lists.debian.org>
 Uploaders: Michael Vogt <mvo@debian.org>, Otavio Salvador <otavio@debian.org>,
  Christian Perrier <bubulle@debian.org>, Daniel Burrows <dburrows@debian.org>,
  Julian Andres Klode <jak@debian.org>
-Standards-Version: 3.9.0
+Standards-Version: 3.9.2
 Build-Depends: dpkg-dev (>= 1.15.8), debhelper (>= 7.2.3~), libdb-dev, gettext (>= 0.12), libcurl4-gnutls-dev (>= 7.19.0), zlib1g-dev | libz-dev, debiandoc-sgml, xsltproc, docbook-xsl, docbook-xml, po4a (>= 0.34-2), autotools-dev, autoconf, automake, doxygen
 Build-Conflicts: autoconf2.13, automake1.4
 Vcs-Bzr: http://bzr.debian.org/apt/debian-sid/
@@ -13,7 +13,8 @@ Vcs-Browser: http://bzr.debian.org/loggerhead/apt/debian-sid/
 
 Package: apt
 Architecture: any
-Depends: ${shlibs:Depends}, debian-archive-keyring, ${misc:Depends}, gnupg
+Pre-Depends: ${shlibs:Depends}
+Depends: debian-archive-keyring, ${misc:Depends}, gnupg
 Replaces: manpages-pl (<< 20060617-3~)
 Provides: ${libapt-pkg:provides}
 Conflicts: python-apt (<< 0.7.93.2~)

+ 3 - 0
debian/rules

@@ -120,6 +120,9 @@ libapt-pkg-doc: build-doc
 #
 # libapt-pkg-doc install
 #
+	# remove doxygen's embedded jquery as we don't use it anyway (#622147)
+	rm -f $(BLD)/doc/doxygen/html/jquery.js
+
 	dh_installdocs -p$@ $(BLD)/docs/design* \
 			    $(BLD)/docs/dpkg-tech* \
 			    $(BLD)/docs/files* \

+ 16 - 0
doc/apt-key.8.xml

@@ -136,6 +136,22 @@
 
      </listitem>
      </varlistentry>
+     
+     <varlistentry><term>net-update</term>
+     <listitem>
+     <para>
+
+       Update the local keyring with the keys of a key server
+       and removes from the keyring the archive keys which are no
+       longer valid. This requires an installed wget and an APT
+       build configured to have a server to fetch from. APT in
+       Debian does not support this command, but Ubuntu's APT
+       does.
+
+     </para>
+
+     </listitem>
+     </varlistentry>
    </variablelist>
 </refsect1>
 

+ 43 - 24
doc/apt-mark.8.xml

@@ -18,7 +18,7 @@
    &apt-email;
    &apt-product;
    <!-- The last update date -->
-   <date>9 August 2009</date>
+   <date>21 April 2011</date>
  </refentryinfo>
  
  <refmeta>
@@ -42,12 +42,13 @@
 	<group choice="plain">
 		<arg choice="plain">
 			<group choice="req">
-				<arg choice="plain">markauto</arg>
-				<arg choice="plain">unmarkauto</arg>
+				<arg choice="plain">auto</arg>
+				<arg choice="plain">manual</arg>
+				<arg choice="plain">showauto</arg>
+				<arg choice="plain">showmanual</arg>
 			</group>
 			<arg choice="plain" rep="repeat"><replaceable>package</replaceable></arg>
 		</arg>
-		<arg choice="plain">showauto</arg>
 	</group>
    </cmdsynopsis>
  </refsynopsisdiv>
@@ -65,27 +66,60 @@
      <command>apt-get</command> or <command>aptitude</command>.
    </para>
      <variablelist>
-       <varlistentry><term>markauto</term>
-	 <listitem><para><literal>markauto</literal> is used to mark a
+       <varlistentry><term>auto</term>
+	 <listitem><para><literal>auto</literal> is used to mark a
      package as being automatically installed, which will cause the
      package to be removed when no more manually installed packages
      depend on this package.
        </para></listitem>
        </varlistentry>
 
-       <varlistentry><term>unmarkauto</term>
-	 <listitem><para><literal>unmarkauto</literal> is used to mark a
+       <varlistentry><term>manual</term>
+	 <listitem><para><literal>manual</literal> is used to mark a
      package as being manually installed, which will prevent the
      package from being automatically removed if no other packages
      depend on it.
        </para></listitem>
        </varlistentry>
 
+       <varlistentry><term>hold</term>
+	 <listitem><para><literal>hold</literal> is used to mark a
+       package as hold back, which will prevent the package from being
+       automatically installed, upgraded or removed.
+       The command is only a wrapper around <command>dpkg --set-selections</command>
+       and the state is therefore maintained by &dpkg; and not effected
+       by the <option>--filename</option> option.
+       </para></listitem>
+       </varlistentry>
+
+       <varlistentry><term>unhold</term>
+	 <listitem><para><literal>unhold</literal> is used to cancel a
+       previously set hold on a package to allow all actions again.
+       </para></listitem>
+       </varlistentry>
+
        <varlistentry><term>showauto</term>
 	 <listitem><para><literal>showauto</literal> is used to print a
      list of automatically installed packages with each package on a new line.
+     All automatically installed packages will be listed if no package is given.
+     If packages are given only those which are automatically installed will be shown.
+       </para></listitem>
+       </varlistentry>
+
+       <varlistentry><term>showmanual</term>
+	 <listitem><para><literal>showmanual</literal> can be used in
+     the same way as <literal>showauto</literal> except that it will print
+     a list of manually installed packages instead.
        </para></listitem>
        </varlistentry>
+
+       <varlistentry><term>showhold</term>
+	 <listitem><para><literal>showhold</literal> is used to print a list
+     of packages on hold in the same way as for the other show commands.
+       </para></listitem>
+       </varlistentry>
+
+
      </variablelist>
  </refsect1>
  
@@ -102,23 +136,8 @@
      is <filename>extended_status</filename> in the directory defined
      by the Configuration Item: <literal>Dir::State</literal>.</para></listitem>
      </varlistentry>
-   
-     <varlistentry><term><option>-h</option></term>
-     <term><option>--help</option></term>
-     <listitem><para>Show a short usage summary.
-     </para>
-     </listitem>
-     </varlistentry>
-     
-     <varlistentry>
-      <term><option>-v</option></term>
-      <term><option>--version</option></term>
-      <listitem><para>Show the program version.
-     </para>
-     </listitem>
-     </varlistentry>
 
-     
+     &apt-commonoptions;
    </variablelist>
  </refsect1>
 

+ 43 - 0
doc/apt_preferences.5.xml

@@ -259,6 +259,49 @@ Pin-Priority: 500
 
 </refsect2>
 
+<refsect2><title>Regular expressions and glob() syntax</title>
+<para>
+APT also supports pinning by glob() expressions and regular
+expressions surrounded by /. For example, the following
+example assigns the priority 500 to all packages from
+experimental where the name starts with gnome (as a glob()-like
+expression or contains the word kde (as a POSIX extended regular
+expression surrounded by slashes).
+</para>
+
+<programlisting>
+Package: gnome* /kde/
+Pin: release n=experimental
+Pin-Priority: 500
+</programlisting>
+
+<para>
+The rule for those expressions is that they can occur anywhere
+where a string can occur. Those, the following pin assigns the
+priority 990 to all packages from a release starting with karmic.
+</para>
+
+<programlisting>
+Package: *
+Pin: release n=karmic*
+Pin-Priority: 990
+</programlisting>
+
+If a regular expression occurs in a <literal>Package</literal> field,
+the behavior is the same as if this regular expression were replaced
+with a list of all package names it matches. It is undecided whether
+this will change in the future, thus you should always list wild-card
+pins first, so later specific pins override it.
+
+The pattern "<literal>*</literal>" in a Package field is not considered
+a glob() expression in itself.
+
+</refsect2>
+
+
+
+
+
 <refsect2>
 <title>How APT Interprets Priorities</title>
 

+ 1 - 1
doc/po/de.po

@@ -1912,7 +1912,7 @@ msgstr ""
 "<command>apt-config</command><arg><option>-hv</option></arg><arg><option>-"
 "o=<replaceable>Konfigurationszeichenkette</replaceable></option></"
 "arg><arg><option>-c=<replaceable>Datei</replaceable></option></arg><group "
-"choice=\"req\"> <arg>shell</arg> <arg>Abbild</arg> </group>"
+"choice=\"req\"> <arg>shell</arg> <arg>dump</arg> </group>"
 
 #. type: Content of: <refentry><refsect1><para>
 #: apt-config.8.xml:51

+ 28 - 5
methods/http.cc

@@ -778,9 +778,10 @@ bool HttpMethod::Go(bool ToFile,ServerState *Srv)
    
    if (Srv->In.WriteSpace() == true && ToFile == true && FileFD != -1)
       FD_SET(FileFD,&wfds);
-   
+
    // Add stdin
-   FD_SET(STDIN_FILENO,&rfds);
+   if (_config->FindB("Acquire::http::DependOnSTDIN", true) == true)
+      FD_SET(STDIN_FILENO,&rfds);
 	  
    // Figure out the max fd
    int MaxFd = FileFD;
@@ -947,9 +948,25 @@ HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
            && Srv->Result != 304    // Not Modified
            && Srv->Result != 306))  // (Not part of HTTP/1.1, reserved)
    {
-      if (!Srv->Location.empty())
+      if (Srv->Location.empty() == true);
+      else if (Srv->Location[0] == '/' && Queue->Uri.empty() == false)
       {
-         NextURI = Srv->Location;
+	 URI Uri = Queue->Uri;
+	 if (Uri.Host.empty() == false)
+	 {
+	    if (Uri.Port != 0)
+	       strprintf(NextURI, "http://%s:%u", Uri.Host.c_str(), Uri.Port);
+	    else
+	       NextURI = "http://" + Uri.Host;
+	 }
+	 else
+	    NextURI.clear();
+	 NextURI.append(DeQuoteString(Srv->Location));
+	 return TRY_AGAIN_OR_REDIRECT;
+      }
+      else
+      {
+         NextURI = DeQuoteString(Srv->Location);
          return TRY_AGAIN_OR_REDIRECT;
       }
       /* else pass through for error message */
@@ -1113,7 +1130,13 @@ int HttpMethod::Loop()
          do a WaitFd above.. Otherwise the FD is closed. */
       int Result = Run(true);
       if (Result != -1 && (Result != 0 || Queue == 0))
-	 return 100;
+      {
+	 if(FailReason.empty() == false ||
+	    _config->FindB("Acquire::http::DependOnSTDIN", true) == true)
+	    return 100;
+	 else
+	    return 0;
+      }
 
       if (Queue == 0)
 	 continue;

+ 2 - 2
po/apt-all.pot

@@ -2719,8 +2719,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1424
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1479

+ 2 - 2
po/ar.po

@@ -2792,8 +2792,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1686

+ 2 - 2
po/ast.po

@@ -3013,8 +3013,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Nun pudo alcontrase un ficheru pal paquete %s. Esto puede significar que "
 "necesites iguar manualmente esti paquete"

+ 2 - 2
po/bg.po

@@ -3051,8 +3051,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Неуспех при намирането на файл за пакет %s. Това може да означава, че трябва "
 "ръчно да оправите този пакет."

+ 2 - 2
po/bs.po

@@ -2789,8 +2789,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1686

+ 2 - 2
po/ca.po

@@ -3048,8 +3048,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "No s'ha trobat un fitxer pel paquet %s. Això podria significar que haureu "
 "d'arreglar aquest paquet manualment."

+ 2 - 2
po/cs.po

@@ -2992,8 +2992,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Nebyl jsem schopen nalézt soubor s balíkem %s. Asi budete muset tento balík "
 "opravit ručně."

+ 2 - 2
po/cy.po

@@ -3080,8 +3080,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Methais i leoli ffeila r gyfer y pecyn %s. Fa all hyn olygu bod rhaid i chi "
 "drwsio'r pecyn hyn a law."

+ 2 - 2
po/da.po

@@ -3014,8 +3014,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Jeg kunne ikke lokalisere filen til %s-pakken. Det betyder muligvis at du er "
 "nødt til manuelt at reparere denne pakke."

+ 2 - 2
po/de.po

@@ -3089,8 +3089,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Es konnte keine Datei für Paket %s gefunden werden. Das könnte heißen, dass "
 "Sie dieses Paket von Hand korrigieren müssen."

+ 2 - 2
po/dz.po

@@ -3001,8 +3001,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 " %s་ཐུམ་སྒྲིལ་གི་དོན་ལུ་ང་་གི་ཡིག་སྣོད་ཅིག་ག་ཡོད་འཚོལ་མི་འཐོབ་པས། འདི་འབདཝ་ལས་ཁྱོད་ཀྱི་ལག་ཐོག་ལས་ "
 "འ་ནི་ཐུམ་སྒྲིལ་འདི་གི་དཀའ་ངལ་སེལ་དགོཔ་འདུག "

+ 2 - 2
po/el.po

@@ -3035,8 +3035,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Αδύνατος ο εντοπισμός ενός αρχείου για το πακέτο %s. Αυτό ίσως σημαίνει ότι "
 "χρειάζεται να διορθώσετε χειροκίνητα το πακέτο."

+ 2 - 2
po/es.po

@@ -3116,8 +3116,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "No se pudo localizar un archivo para el paquete %s. Esto puede significar "
 "que necesita arreglar manualmente este paquete."

+ 2 - 2
po/eu.po

@@ -2996,8 +2996,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Ezin izan dut %s paketeko fitxategi bat lokalizatu. Beharbada eskuz konpondu "
 "beharko duzu paketea."

+ 2 - 2
po/fi.po

@@ -2988,8 +2988,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Pakettia %s vastaavaa tiedostoa ei löytynyt. Voit ehkä joutua korjaamaan "
 "tämän paketin itse."

+ 2 - 2
po/fr.po

@@ -3107,8 +3107,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Impossible de localiser un fichier du paquet %s. Cela signifie que vous "
 "devrez corriger ce paquet vous-même."

Разница между файлами не показана из-за своего большого размера
+ 1031 - 902
po/gl.po


+ 2 - 2
po/he.po

@@ -2562,8 +2562,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1275
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1316

+ 2 - 2
po/hu.po

@@ -2983,8 +2983,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Nem találtam egy fájlt a(z) %s csomaghoz. Ez azt jelentheti, hogy kézzel "
 "kell kijavítani a csomagot."

+ 16 - 7
po/it.po

@@ -9,14 +9,16 @@ msgstr ""
 "Project-Id-Version: apt\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2011-01-12 17:42+0100\n"
-"PO-Revision-Date: 2011-02-21 18:35+0100\n"
+"PO-Revision-Date: 2011-05-16 21:38+0200\n"
 "Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
 "Language: it\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8-bit\n"
+"Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Launchpad-Export-Date: 2011-02-21 18:00+0000\n"
+"X-Generator: Launchpad (build 12406)\n"
 
 #: cmdline/apt-cache.cc:156
 #, c-format
@@ -1907,8 +1909,10 @@ msgid "Couldn't change to %s"
 msgstr "Impossibile passare a %s"
 
 #: apt-inst/deb/debfile.cc:140
+#, fuzzy
+#| msgid "Internal error, could not locate member %s"
 msgid "Internal error, could not locate member"
-msgstr "Errore interno, impossibile localizzare il membro"
+msgstr "Errore interno, impossibile trovare il membro %s"
 
 #: apt-inst/deb/debfile.cc:173
 msgid "Failed to locate a valid control file"
@@ -2710,7 +2714,6 @@ msgstr "Scrittura del file temporaneo di stato %s non riuscita"
 #, c-format
 msgid "Internal error, group '%s' has no installable pseudo package"
 msgstr ""
-"Errore interno, il gruppo \"%s\" non ha uno pseudo pacchetto installabile"
 
 #: apt-pkg/tagfile.cc:102
 #, c-format
@@ -3113,10 +3116,13 @@ msgstr ""
 "sistemare manualmente questo pacchetto (a causa dell'architettura mancante)."
 
 #: apt-pkg/acquire-item.cc:1424
-#, c-format
+#, fuzzy, c-format
+#| msgid ""
+#| "I wasn't able to locate file for the %s package. This might mean you need "
+#| "to manually fix this package."
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Impossibile trovare un file per il pacchetto %s. Potrebbe essere necessario "
 "sistemare manualmente questo pacchetto."
@@ -3581,3 +3587,6 @@ msgstr "Connessione chiusa prematuramente"
 
 #~ msgid "Unable to find hash sum for '%s' in Release file"
 #~ msgstr "Impossibile trovare la somma hash per \"%s\" nel file Release"
+
+#~ msgid "Can not read mirror file '%s'"
+#~ msgstr "Impossibile leggere il file mirror \"%s\""

+ 2 - 2
po/ja.po

@@ -3035,8 +3035,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "パッケージ %s のファイルの位置を特定できません。おそらくこのパッケージを手動"
 "で修正する必要があります。"

+ 2 - 2
po/km.po

@@ -2964,8 +2964,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "ខ្ញុំ​មិន​អាច​រកទីតាំង​ឯកសារ​សម្រាប់​កញ្ចប់ %s បានទេ ។ ​មាន​ន័យ​ថា​អ្នក​ត្រូវការ​ជួសជុល​កញ្ចប់​នេះ​ដោយ​ដៃ ។"
 

+ 2 - 2
po/ko.po

@@ -2986,8 +2986,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "%s 패키지의 파일을 찾을 수 없습니다. 수동으로 이 패키지를 고쳐야 할 수도 있습"
 "니다."

+ 2 - 2
po/ku.po

@@ -2792,8 +2792,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1686

+ 2 - 2
po/lt.po

@@ -2889,8 +2889,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 
 #: apt-pkg/acquire-item.cc:1686

+ 2 - 2
po/mr.po

@@ -2972,8 +2972,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "मी %s पॅकेजकरीता संचिका शोधण्यास  समर्थ नव्हतो. याचा अर्थ असाकी तुम्हालाहे पॅकेज स्वहस्ते "
 "स्थिर/निश्चित करण्याची गरज आहे."

+ 2 - 2
po/nb.po

@@ -3013,8 +3013,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Klarte ikke å finne en fil for pakken %s. Det kan bety at du må ordne denne "
 "pakken selv."

+ 2 - 2
po/ne.po

@@ -2967,8 +2967,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "%s प्याकेजको लागि मैले फाइल स्थित गर्न सकिन । यसको मतलब तपाईँले म्यानुल्ली यो प्याकेज "
 "निश्चित गर्नुहोस् ।"

+ 2 - 2
po/nl.po

@@ -3047,8 +3047,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Er kon geen bestand gevonden worden voor pakket %s. Dit kan betekenen dat u "
 "dit pakket handmatig moet repareren."

+ 2 - 2
po/nn.po

@@ -2988,8 +2988,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Fann ikkje fila for pakken %s. Det kan henda du må fiksa denne pakken sjølv."
 

+ 2 - 2
po/pl.po

@@ -3018,8 +3018,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Nie udało się odnaleźć pliku dla pakietu %s. Może to oznaczać, że trzeba "
 "będzie ręcznie naprawić ten pakiet."

+ 2 - 2
po/pt.po

@@ -3046,8 +3046,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Não foi possível localizar arquivo para o pacote %s. Isto pode significar "
 "que você precisa consertar manualmente este pacote."

+ 2 - 2
po/pt_BR.po

@@ -3025,8 +3025,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Não foi possível localizar arquivo para o pacote %s. Isto pode significar "
 "que você precisa consertar manualmente este pacote."

+ 2 - 2
po/ro.po

@@ -3034,8 +3034,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "N-am putut localiza un fișier pentru pachetul %s. Aceasta ar putea însemna "
 "că aveți nevoie să depanați manual acest pachet."

+ 2 - 2
po/ru.po

@@ -3056,8 +3056,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Не удалось обнаружить файл пакета %s. Это может означать, что вам придётся "
 "вручную исправить этот пакет."

+ 2 - 2
po/sk.po

@@ -3008,8 +3008,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Nedá sa nájsť súbor s balíkom %s. Asi budete musieť opraviť tento balík "
 "manuálne."

+ 2 - 2
po/sl.po

@@ -3023,8 +3023,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Ni bilo mogoče najti datoteke za paket %s. Morda boste morali ročno "
 "popraviti ta paket."

+ 2 - 2
po/sv.po

@@ -3038,8 +3038,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Jag kunde inte hitta någon fil för paketet %s. Detta kan betyda att du "
 "manuellt måste reparera detta paket."

+ 2 - 2
po/th.po

@@ -2946,8 +2946,8 @@ msgstr "ไม่พบแฟ้มสำหรับแพกเกจ %s ค
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr "ไม่พบแฟ้มสำหรับแพกเกจ %s คุณอาจต้องแก้ปัญหาแพกเกจนี้เอง"
 
 #: apt-pkg/acquire-item.cc:1686

+ 2 - 2
po/tl.po

@@ -3016,8 +3016,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Hindi ko mahanap ang talaksan para sa paketeng %s. Maaaring kailanganin "
 "niyong ayusin ng de kamay ang paketeng ito."

+ 2 - 2
po/uk.po

@@ -3035,8 +3035,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Я не можу знайти файл для пакунку %s. Можливо, Ви захочете власноруч "
 "виправити цей пакунок."

+ 2 - 2
po/vi.po

@@ -3053,8 +3053,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "Không tìm thấy tập tin liên quan đến gói %s. Có lẽ bạn cần phải tự sửa gói "
 "này."

+ 2 - 2
po/zh_CN.po

@@ -2961,8 +2961,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr ""
 "我无法找到对应 %s 软件包的文件。在这种情况下您可能需要手动修正这个软件包。"
 

+ 2 - 2
po/zh_TW.po

@@ -2949,8 +2949,8 @@ msgstr ""
 #: apt-pkg/acquire-item.cc:1631
 #, c-format
 msgid ""
-"I wasn't able to locate file for the %s package. This might mean you need to "
-"manually fix this package."
+"I wasn't able to locate a file for the %s package. This might mean you need "
+"to manually fix this package."
 msgstr "找不到 %s 套件的某個檔案。這意味著您可能要手動修復這個套件。"
 
 #: apt-pkg/acquire-item.cc:1686

+ 47 - 28
test/integration/framework

@@ -145,6 +145,7 @@ setupenvironment() {
 	echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf
 	echo 'quiet::NoUpdate "true";' >> aptconfig.conf
 	export LC_ALL=C
+	export PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
 	msgdone "info"
 }
 
@@ -218,6 +219,7 @@ buildsimplenativepackage() {
 	local DEPENDENCIES="$5"
 	local DESCRIPTION="$6"
 	local SECTION="${7:-others}"
+	local PRIORITY="${8:-optional}"
 	local DISTSECTION
 	if [ "$SECTION" = "$(echo "$SECTION" | cut -d'/' -f 2)" ]; then
 		DISTSECTION="main"
@@ -240,7 +242,7 @@ echo '$NAME says \"Hello!\"'" > ${BUILDDIR}/${NAME}
  -- Joe Sixpack <joe@example.org>  $(date -R)" > ${BUILDDIR}/debian/changelog
 	echo "Source: $NAME
 Section: $SECTION
-Priority: optional
+Priority: $PRIORITY
 Maintainer: Joe Sixpack <joe@example.org>
 Standards-Version: 3.9.1
 
@@ -396,29 +398,34 @@ insertpackage() {
 	local ARCH="$3"
 	local VERSION="$4"
 	local DEPENDENCIES="$5"
-	local ARCHS="$ARCH"
-	if [ "$ARCHS" = "all" ]; then
-		ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')"
-	fi
-	for BUILDARCH in $ARCHS; do
-		local PPATH="aptarchive/dists/${RELEASE}/main/binary-${BUILDARCH}"
-		mkdir -p $PPATH aptarchive/dists/${RELEASE}/main/source
-		touch aptarchive/dists/${RELEASE}/main/source/Sources
-		local FILE="${PPATH}/Packages"
-		echo "Package: $NAME
-Priority: optional
+	local PRIORITY="${6:-optional}"
+	local ARCHS=""
+	for arch in $(echo "$ARCH" | sed -e 's#,#\n#g'); do
+		if [ "$arch" = "all" ]; then
+			ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')"
+		else
+			ARCHS="$arch"
+		fi
+		for BUILDARCH in $ARCHS; do
+			local PPATH="aptarchive/dists/${RELEASE}/main/binary-${BUILDARCH}"
+			mkdir -p $PPATH aptarchive/dists/${RELEASE}/main/source
+			touch aptarchive/dists/${RELEASE}/main/source/Sources
+			local FILE="${PPATH}/Packages"
+			echo "Package: $NAME
+Priority: $PRIORITY
 Section: other
 Installed-Size: 42
 Maintainer: Joe Sixpack <joe@example.org>
-Architecture: $ARCH
+Architecture: $arch
 Version: $VERSION
-Filename: pool/main/${NAME}/${NAME}_${VERSION}_${ARCH}.deb" >> $FILE
-		test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
-		echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
+Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE
+			test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
+			echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
  If you find such a package installed on your system,
  YOU did something horribly wrong! They are autogenerated
  und used only by testcases for APT and surf no other propose…
 " >> $FILE
+		done
 	done
 }
 
@@ -427,21 +434,24 @@ insertinstalledpackage() {
 	local ARCH="$2"
 	local VERSION="$3"
 	local DEPENDENCIES="$4"
+	local PRIORITY="${5:-optional}"
 	local FILE="rootdir/var/lib/dpkg/status"
-	echo "Package: $NAME
+	for arch in $(echo "$ARCH" | sed -e 's#,#\n#g'); do
+		echo "Package: $NAME
 Status: install ok installed
-Priority: optional
+Priority: $PRIORITY
 Section: other
 Installed-Size: 42
 Maintainer: Joe Sixpack <joe@example.org>
-Architecture: $ARCH
+Architecture: $arch
 Version: $VERSION" >> $FILE
-	test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
-	echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
+		test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
+		echo "Description: an autogenerated dummy ${NAME}=${VERSION}/installed
  If you find such a package installed on your system,
  YOU did something horribly wrong! They are autogenerated
  und used only by testcases for APT and surf no other propose…
 " >> $FILE
+	done
 }
 
 
@@ -563,13 +573,22 @@ changetowebserver() {
 	if which weborf > /dev/null; then
 		weborf -xb aptarchive/ 2>&1 > /dev/null &
 		addtrap "kill $!;"
-		local APTARCHIVE="file://$(readlink -f ./aptarchive)"
-		for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do
-			sed -i $LIST -e "s#$APTARCHIVE#http://localhost:8080/#"
-		done
-		return 0
+	elif which lighttpd > /dev/null; then
+		echo "server.document-root = \"$(readlink -f ./aptarchive)\"
+server.port = 8080
+server.stat-cache-engine = \"disable\"" > lighttpd.conf
+		lighttpd -t -f lighttpd.conf >/dev/null || msgdie 'Can not change to webserver: our lighttpd config is invalid'
+		lighttpd -D -f lighttpd.conf 2>/dev/null >/dev/null &
+		addtrap "kill $!;"
+	else
+		msgdie 'You have to install weborf or lighttpd first'
+		return 1
 	fi
-	return 1
+	local APTARCHIVE="file://$(readlink -f ./aptarchive)"
+	for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do
+		sed -i $LIST -e "s#$APTARCHIVE#http://localhost:8080/#"
+	done
+	return 0
 }
 
 checkdiff() {
@@ -685,7 +704,7 @@ testmarkedauto() {
 		while [ -n "$1" ]; do echo "$1"; shift; done | sort > $COMPAREFILE
 	else
 		msgtest 'Test for correctly marked as auto-installed' 'no package'
-		echo > $COMPAREFILE
+		echo -n > $COMPAREFILE
 	fi
 	aptmark showauto 2>&1 | checkdiff $COMPAREFILE - && msgpass || msgfail
 }

+ 36 - 0
test/integration/skip-bug-602412-dequote-redirect

@@ -0,0 +1,36 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+if ! which lighttpd > /dev/null; then
+	msgdie 'You need lighttpd for this testcase, sorry…'
+	exit 1
+fi
+
+buildsimplenativepackage 'unrelated' 'all' '0.5~squeeze1' 'unstable'
+
+setupaptarchive
+
+echo "server.modules = ( \"mod_redirect\" )
+server.document-root = \"$(readlink -f ./aptarchive)\"
+server.port = 8080
+server.stat-cache-engine = \"disable\"
+url.redirect = ( \"^/pool/(.*)$\" => \"/newpool/\$1\" )" > lighttpd.conf
+
+mv aptarchive/pool aptarchive/newpool
+lighttpd -t -f lighttpd.conf >/dev/null || msgdie 'Can not change to webserver: our lighttpd config is invalid'
+lighttpd -D -f lighttpd.conf 2>/dev/null >/dev/null &
+addtrap "kill $!;"
+
+local APTARCHIVE="file://$(readlink -f ./aptarchive)"
+for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do
+	sed -i $LIST -e "s#$APTARCHIVE#http://localhost:8080/#"
+done
+
+aptget update -qq || msgdie 'apt-get update failed'
+aptget install unrelated --download-only -qq || msgdie 'downloading package failed'
+

+ 172 - 0
test/integration/test-bug-470115-new-and-tighten-recommends

@@ -0,0 +1,172 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+insertinstalledpackage 'cool' 'all' '1'
+insertinstalledpackage 'stuff' 'all' '1'
+insertinstalledpackage 'coolstuff' 'all' '1'
+
+insertpackage 'unstable' 'cool' 'all' '2'
+insertpackage 'unstable' 'stuff' 'all' '2'
+insertpackage 'unstable' 'coolstuff' 'all' '2'
+insertpackage 'unstable' 'super' 'all' '2'
+
+insertinstalledpackage 'tighten-cool' 'all' '1' 'Recommends: cool (>= 1)'
+insertpackage 'unstable' 'tighten-cool' 'all' '2' 'Recommends: cool (>= 2)'
+
+insertinstalledpackage 'tighten-coolorstuff' 'all' '1' 'Recommends: cool (>= 1) | stuff (>= 1)'
+insertpackage 'unstable' 'tighten-coolorstuff' 'all' '2' 'Recommends: stuff (>= 2) | cool (>= 2)'
+
+insertinstalledpackage 'tighten-coolorstuff2' 'all' '1' 'Recommends: cool (>= 1) | stuff (>= 1)'
+insertpackage 'unstable' 'tighten-coolorstuff2' 'all' '2' 'Recommends: stuff2 (>= 2) | cool (>= 2)'
+
+insertinstalledpackage 'newrec-cool' 'all' '1'
+insertpackage 'unstable' 'newrec-cool' 'all' '2' 'Recommends: cool (>= 2)'
+
+insertinstalledpackage 'newrec-super' 'all' '1'
+insertpackage 'unstable' 'newrec-super' 'all' '2' 'Recommends: super'
+
+insertinstalledpackage 'newrec-coolorstuff' 'all' '1'
+insertpackage 'unstable' 'newrec-coolorstuff' 'all' '2' 'Recommends: cool (>= 2) | stuff (>= 2)'
+
+insertinstalledpackage 'cool-gone' 'all' '1' 'Recommends: cool (>= 1) | stuff (>= 2)'
+insertpackage 'unstable' 'cool-gone' 'all' '2' 'Recommends: stuff (>= 2)'
+
+insertinstalledpackage 'super-overtake' 'all' '1' 'Recommends: cool | super, stuff | super'
+insertpackage 'unstable' 'super-overtake' 'all' '2' 'Recommends: stuff (>= 3) | super, super | cool (>= 2)'
+
+insertinstalledpackage 'upgrade-over-new' 'all' '1' 'Recommends: cool'
+insertpackage 'unstable' 'upgrade-over-new' 'all' '2' 'Recommends: cool (>= 2) | super'
+
+insertinstalledpackage 'now-satisfiable' 'all' '1' 'Recommends: cool (>= 3)'
+insertpackage 'unstable' 'now-satisfiable' 'all' '2' 'Recommends: cool (>= 2)'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following packages will be upgraded:
+  cool tighten-cool
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool [1] (2 unstable [all])
+Inst tighten-cool [1] (2 unstable [all])
+Conf cool (2 unstable [all])
+Conf tighten-cool (2 unstable [all])' aptget install tighten-cool -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  stuff
+The following packages will be upgraded:
+  stuff tighten-coolorstuff
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst stuff [1] (2 unstable [all])
+Inst tighten-coolorstuff [1] (2 unstable [all])
+Conf stuff (2 unstable [all])
+Conf tighten-coolorstuff (2 unstable [all])' aptget install tighten-coolorstuff -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following packages will be upgraded:
+  cool tighten-coolorstuff2
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool [1] (2 unstable [all])
+Inst tighten-coolorstuff2 [1] (2 unstable [all])
+Conf cool (2 unstable [all])
+Conf tighten-coolorstuff2 (2 unstable [all])' aptget install tighten-coolorstuff2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following packages will be upgraded:
+  cool newrec-cool
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool [1] (2 unstable [all])
+Inst newrec-cool [1] (2 unstable [all])
+Conf cool (2 unstable [all])
+Conf newrec-cool (2 unstable [all])' aptget install newrec-cool -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  super
+The following NEW packages will be installed:
+  super
+The following packages will be upgraded:
+  newrec-super
+1 upgraded, 1 newly installed, 0 to remove and 12 not upgraded.
+Inst newrec-super [1] (2 unstable [all])
+Inst super (2 unstable [all])
+Conf newrec-super (2 unstable [all])
+Conf super (2 unstable [all])' aptget install newrec-super -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following packages will be upgraded:
+  cool newrec-coolorstuff
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool [1] (2 unstable [all])
+Inst newrec-coolorstuff [1] (2 unstable [all])
+Conf cool (2 unstable [all])
+Conf newrec-coolorstuff (2 unstable [all])' aptget install newrec-coolorstuff -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  stuff
+The following packages will be upgraded:
+  cool-gone stuff
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool-gone [1] (2 unstable [all])
+Inst stuff [1] (2 unstable [all])
+Conf cool-gone (2 unstable [all])
+Conf stuff (2 unstable [all])' aptget install cool-gone -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  super
+The following NEW packages will be installed:
+  super
+The following packages will be upgraded:
+  super-overtake
+1 upgraded, 1 newly installed, 0 to remove and 12 not upgraded.
+Inst super (2 unstable [all])
+Inst super-overtake [1] (2 unstable [all])
+Conf super (2 unstable [all])
+Conf super-overtake (2 unstable [all])' aptget install super-overtake -s
+
+# if super would be in front, we would get a new here as it is new and
+# the first option in an or-group should be the preferred one…
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following packages will be upgraded:
+  cool upgrade-over-new
+2 upgraded, 0 newly installed, 0 to remove and 11 not upgraded.
+Inst cool [1] (2 unstable [all])
+Inst upgrade-over-new [1] (2 unstable [all])
+Conf cool (2 unstable [all])
+Conf upgrade-over-new (2 unstable [all])' aptget install upgrade-over-new -s
+
+# the recommends wasn't used before so while we could do it now,
+# the user doesn't seem to need it so avoid upgrading it
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be upgraded:
+  now-satisfiable
+1 upgraded, 0 newly installed, 0 to remove and 12 not upgraded.
+Inst now-satisfiable [1] (2 unstable [all])
+Conf now-satisfiable (2 unstable [all])' aptget install now-satisfiable -s

+ 3 - 3
test/integration/test-bug-612557-garbage-upgrade

@@ -13,9 +13,9 @@ insertpackage 'unstable' 'libreoffice-common' 'all' '1:3.3.0-2' 'Conflicts: open
 setupaptarchive
 
 touch rootdir/var/lib/apt/extended_states
-aptmark markauto python-uno ure uno-libs3 openoffice.org-common openoffice.org-style-galaxy
+aptmark markauto python-uno openoffice.org-common
 #aptmark unmarkauto openoffice.org-emailmerge
-testmarkedauto python-uno ure uno-libs3 openoffice.org-common openoffice.org-style-galaxy
+testmarkedauto python-uno openoffice.org-common
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -33,7 +33,7 @@ After this operation, 53.2 MB disk space will be freed.
 E: Trivial Only specified but this is not a trivial operation.' aptget --trivial-only install python-uno
 
 aptmark markauto openoffice.org-emailmerge
-testmarkedauto python-uno ure uno-libs3 openoffice.org-common openoffice.org-style-galaxy openoffice.org-emailmerge
+testmarkedauto python-uno openoffice.org-common openoffice.org-emailmerge
 
 testequal 'Reading package lists...
 Building dependency tree...

+ 32 - 0
test/integration/test-bug-618288-multiarch-same-lockstep

@@ -0,0 +1,32 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'i386'
+
+insertinstalledpackage 'libsame' 'i386,amd64' '1' 'Multi-Arch: same' 'required'
+insertinstalledpackage 'apt' 'i386' '1' 'Depends: libsame (= 1)
+Essential: yes' 'required'
+insertinstalledpackage 'apt2' 'amd64' '1' 'Depends: libsame (= 1)
+Essential: yes' 'required'
+buildsimplenativepackage 'libsame' 'i386,amd64' '2' 'unstable' 'Multi-Arch: same' '' 'required'
+buildsimplenativepackage 'apt' 'i386' '2' 'unstable' 'Depends: libsame (= 2)' '' 'required'
+buildsimplenativepackage 'apt2' 'amd64' '2' 'unstable' 'Depends: libsame (= 2)' '' 'required'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be upgraded:
+  apt:i386 apt2 libsame libsame:i386
+4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
+Inst libsame [1] (2 unstable [amd64]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:i386 apt2:amd64 ]
+Inst libsame:i386 [1] (2 unstable [i386]) [apt2:amd64 apt:i386 ]
+Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ]
+Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ]
+Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ]
+Conf apt2 (2 unstable [amd64]) [apt:i386 ]
+Inst apt:i386 [1] (2 unstable [i386])
+Conf apt:i386 (2 unstable [i386])' aptget dist-upgrade -s

+ 108 - 0
test/integration/test-handling-broken-orgroups

@@ -0,0 +1,108 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+insertpackage 'unstable' 'cool' 'all' '1.0-1'
+insertpackage 'unstable' 'stuff' 'all' '1.0-1'
+insertpackage 'unstable' 'coolstuff' 'all' '1.0-1' 'Depends: cool | stuff'
+insertpackage 'unstable' 'coolstuff2' 'all' '1.0-1' 'Depends: cool2 | stuff'
+insertpackage 'unstable' 'coolstuff-broken' 'all' '1.0-1' 'Depends: cool2 | stuff2'
+insertpackage 'unstable' 'coolstuff-brokenrec' 'all' '1.0-1' 'Recommends: cool2 | stuff2'
+insertpackage 'unstable' 'coolstuff-conflict' 'all' '1.0-1' 'Depends: cool | stuff
+Conflicts: cool'
+insertpackage 'unstable' 'coolstuff-provided' 'all' '1.0-1' 'Depends: cool2 | stuff-abi'
+insertpackage 'unstable' 'extrastuff' 'all' '1.0-1' 'Provides: stuff-abi'
+
+insertpackage 'unstable' 'coolstuff-provided-broken' 'all' '1.0-1' 'Depends: cool2 | stuff-abi-2'
+insertpackage 'unstable' 'extrastuff' 'all' '1.0-1' 'Depends: stuff2
+Provides: stuff-abi-2'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  cool
+The following NEW packages will be installed:
+  cool coolstuff
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst cool (1.0-1 unstable [all])
+Inst coolstuff (1.0-1 unstable [all])
+Conf cool (1.0-1 unstable [all])
+Conf coolstuff (1.0-1 unstable [all])' aptget install coolstuff -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  stuff
+The following NEW packages will be installed:
+  coolstuff2 stuff
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst stuff (1.0-1 unstable [all])
+Inst coolstuff2 (1.0-1 unstable [all])
+Conf stuff (1.0-1 unstable [all])
+Conf coolstuff2 (1.0-1 unstable [all])' aptget install coolstuff2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ coolstuff-broken : Depends: cool2 but it is not installable or
+                             stuff2 but it is not installable
+E: Broken packages' aptget install coolstuff-broken -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Recommended packages:
+  cool2 stuff2
+The following NEW packages will be installed:
+  coolstuff-brokenrec
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst coolstuff-brokenrec (1.0-1 unstable [all])
+Conf coolstuff-brokenrec (1.0-1 unstable [all])' aptget install coolstuff-brokenrec -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  stuff
+The following NEW packages will be installed:
+  coolstuff-conflict stuff
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst stuff (1.0-1 unstable [all])
+Inst coolstuff-conflict (1.0-1 unstable [all])
+Conf stuff (1.0-1 unstable [all])
+Conf coolstuff-conflict (1.0-1 unstable [all])' aptget install coolstuff-conflict -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  extrastuff
+The following NEW packages will be installed:
+  coolstuff-provided extrastuff
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst extrastuff (1.0-1 unstable [all])
+Inst coolstuff-provided (1.0-1 unstable [all])
+Conf extrastuff (1.0-1 unstable [all])
+Conf coolstuff-provided (1.0-1 unstable [all])' aptget install coolstuff-provided -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ coolstuff-provided-broken : Depends: cool2 but it is not installable or
+                                      stuff-abi-2
+E: Broken packages' aptget install coolstuff-provided-broken -s

+ 38 - 0
test/integration/test-ubuntu-bug-761175-remove-purge

@@ -0,0 +1,38 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+setupsimplenativepackage 'compiz-core' 'i386' '1.0' 'unstable'
+BUILDDIR='incoming/compiz-core-1.0'
+mkdir -p ${BUILDDIR}/debian/compiz-core/etc
+echo 'foo=bar;' > ${BUILDDIR}/compiz.conf
+echo 'compiz.conf	/etc/compiz.conf' >> ${BUILDDIR}/debian/install
+buildpackage "$BUILDDIR" 'unstable' 'main'
+rm -rf "$BUILDDIR"
+
+setupaptarchive
+
+
+testdpkgnotinstalled compiz-core
+msgtest 'Install package' 'compiz-core'
+aptget install compiz-core -qq 2>&1 >/dev/null && msgpass || msgfail
+testdpkginstalled compiz-core
+
+msgtest 'Remove package' 'compiz-core'
+aptget remove compiz-core -y -qq 2>&1 >/dev/null && msgpass || msgfail
+testdpkgnotinstalled compiz-core
+
+msgtest 'Check that conffiles are still around for' 'compiz-core'
+dpkg -l compiz-core | grep '^rc' 2>&1 >/dev/null && msgpass || msgfail
+
+testequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be REMOVED:
+  compiz-core*
+0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
+Purg compiz-core' aptget purge compiz-core -s

+ 5 - 2
test/testextract.cc

@@ -71,9 +71,12 @@ bool Go(int argc,char *argv[])
 	       Itm.Type = pkgDirStream::Item::Directory;
 
 	    int Fd;
-	    if (Extract.DoItem(Itm,Fd) == false)
+	    if (Extract.DoItem(Itm,Fd) == false) {
+	       fclose(F);
 	       return false;
-	 }	 
+	    }
+	 }
+	 fclose(F);
       }
       else
 	 if (Deb.ExtractArchive(Extract) == false)

+ 6 - 6
test/versions.lst

@@ -10,13 +10,16 @@
 1.3 1.2.2 1
 
 # Important attributes
-# disabled as dpkg --compare-versions doesn't like them…
+# disabled as dpkg --compare-versions doesn't like them… (versions have to start with a number)
 #- . -1
 #p - -1
 #a - -1
 #z - -1
-a . -1
-z . -1
+#a . -1
+#z . -1
+
+# disabled as dpkg --compare-versions doesn't like them… (versions have to start with a number)
+#III-alpha9.8 III-alpha9.8-1.5 -1
 
 # Epochs
 1:0.4 10.3 1
@@ -49,9 +52,6 @@ z . -1
 
 1:3.0.5-2 1:3.0.5.1 -1
 
-# #194327
-III-alpha9.8 III-alpha9.8-1.5 -1
-
 # #205960
 3.0~rc1-1 3.0-1 -1