Procházet zdrojové kódy

* apt-pkg/contrib/strutl.cc:
- fix TimeToStr i18n (LP: #289807)
* [ABI break] merge support for http redirects, thanks to
Jeff Licquia and Anthony Towns
* [ABI break] use int for the package IDs (thanks to Steve Cotton)
* apt-pkg/pkgcache.cc:
- do not run "dpkg --configure pkg" if pkg is in trigger-awaited
state (LP: #322955)
* methods/https.cc:
- add Acquire::https::AllowRedirect support
* Clarify the --help for 'purge' (LP: #243948)
* cmdline/apt-get.cc
- fix "apt-get source pkg" if there is a binary package and
a source package of the same name but from different
packages (LP: #330103)
* cmdline/acqprogress.cc:
- Call pkgAcquireStatus::Pulse even if quiet, so that we still get
dlstatus messages on the status-fd (LP: #290234).

Michael Vogt před 17 roky
rodič
revize
09fab2442c

+ 5 - 0
.bzr-builddeb/default.conf

@@ -0,0 +1,5 @@
+[BUILDDEB]
+native = true
+
+[HOOKS]
+pre-build=./pre-build.sh

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

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

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

@@ -447,6 +447,38 @@ void pkgAcqMethod::Status(const char *Format,...)
 }
 									/*}}}*/
 
+// AcqMethod::Redirect - Send a redirect message                       /*{{{*/
+// ---------------------------------------------------------------------
+/* This method sends the redirect message and also manipulates the queue
+   to keep the pipeline synchronized. */
+void pkgAcqMethod::Redirect(const string &NewURI)
+{
+   string CurrentURI = "<UNKNOWN>";
+   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);
+
+   // Change the URI for the request.
+   Queue->Uri = NewURI;
+
+   /* To keep the pipeline synchronized, move the current request to
+      the end of the queue, past the end of the current pipeline. */
+   FetchItem *I;
+   for (I = Queue; I->Next != 0; I = I->Next) ;
+   I->Next = Queue;
+   Queue = Queue->Next;
+   I->Next->Next = 0;
+   if (QueueBack == 0)
+      QueueBack = I->Next;
+}
+                                                                        /*}}}*/
+
 // AcqMethod::FetchResult::FetchResult - Constructor			/*{{{*/
 // ---------------------------------------------------------------------
 /* */

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

@@ -84,6 +84,8 @@ class pkgAcqMethod
    void Log(const char *Format,...);
    void Status(const char *Format,...);
    
+   void Redirect(const string &NewURI);
+ 
    int Run(bool Single = false);
    inline void SetFailExtraMsg(string Msg) {FailExtra = Msg;};
    

+ 14 - 0
apt-pkg/acquire-worker.cc

@@ -220,6 +220,20 @@ bool pkgAcquire::Worker::RunMessages()
 	 Status = LookupTag(Message,"Message");
 	 break;
 	    
+         // 103 Redirect
+         case 103:
+         {
+            if (Itm == 0)
+            {
+               _error->Error("Method gave invalid 103 Redirect message");
+               break;
+            }
+ 
+            string NewURI = LookupTag(Message,"New-URI",URI.c_str());
+            Itm->URI = NewURI;
+            break;
+         }
+   
 	 // 200 URI Start
 	 case 200:
 	 {

+ 9 - 5
apt-pkg/contrib/strutl.cc

@@ -331,23 +331,27 @@ string TimeToStr(unsigned long Sec)
    {
       if (Sec > 60*60*24)
       {
-	 sprintf(S,"%lid %lih%limin%lis",Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60);
+	 //d means days, h means hours, min means minutes, s means seconds
+	 sprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60);
 	 break;
       }
       
       if (Sec > 60*60)
       {
-	 sprintf(S,"%lih%limin%lis",Sec/60/60,(Sec/60) % 60,Sec % 60);
+	 //h means hours, min means minutes, s means seconds
+	 sprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60);
 	 break;
       }
       
       if (Sec > 60)
       {
-	 sprintf(S,"%limin%lis",Sec/60,Sec % 60);
+	 //min means minutes, s means seconds
+	 sprintf(S,_("%limin %lis"),Sec/60,Sec % 60);
 	 break;
       }
-      
-      sprintf(S,"%lis",Sec);
+
+      //s means seconds
+      sprintf(S,_("%lis"),Sec);
       break;
    }
    

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

@@ -96,7 +96,7 @@ bool debSystem::UnLock(bool NoErrors)
       return false;
    
    if (LockCount < 1)
-      return _error->Error("Not locked");
+      return _error->Error(_("Not locked"));
    if (--LockCount == 0)
    {
       close(LockFD);

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

@@ -777,16 +777,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN);
 
       struct	termios tt;
-      struct	termios tt_out;
       struct	winsize win;
       int	master;
       int	slave;
 
       // FIXME: setup sensible signal handling (*ick*)
       tcgetattr(0, &tt);
-      tcgetattr(1, &tt_out);
       ioctl(0, TIOCGWINSZ, (char *)&win);
-      if (openpty(&master, &slave, NULL, &tt_out, &win) < 0) 
+      if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
       {
 	 const char *s = _("Can not write log, openpty() "
 			   "failed (/dev/pts not mounted?)\n");

+ 1 - 1
apt-pkg/makefile

@@ -13,7 +13,7 @@ include ../buildlib/defaults.mak
 # methods/makefile - FIXME
 LIBRARY=apt-pkg
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=4.6
+MAJOR=4.7
 MINOR=0
 SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil
 APT_DOMAIN:=libapt-pkg$(MAJOR)

+ 6 - 2
apt-pkg/pkgcache.cc

@@ -275,8 +275,12 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
    
    if (Pkg->CurrentState == pkgCache::State::UnPacked ||
        Pkg->CurrentState == pkgCache::State::HalfConfigured ||
-       Pkg->CurrentState == pkgCache::State::TriggersPending ||
-       Pkg->CurrentState == pkgCache::State::TriggersAwaited)
+      //we don't need to care for triggers awaiting packages
+      //dpkg will deal with them automatically when the 
+      //trigger pending action is run (those packages are usually
+      //in half-configured or triggers-pending state)
+      //Pkg->CurrentState == pkgCache::State::TriggersAwaited
+       Pkg->CurrentState == pkgCache::State::TriggersPending)
       return NeedsConfigure;
    
    if (Pkg->CurrentState == pkgCache::State::HalfInstalled ||

+ 4 - 4
apt-pkg/pkgcache.h

@@ -214,7 +214,7 @@ struct pkgCache::Package
    unsigned char InstState;         // Flags
    unsigned char CurrentState;      // State
    
-   unsigned short ID;
+   unsigned int ID;
    unsigned long Flags;
 };
 
@@ -235,7 +235,7 @@ struct pkgCache::PackageFile
    
    // Linked list
    map_ptrloc NextFile;        // PackageFile
-   unsigned short ID;
+   unsigned int ID;
    time_t mtime;                  // Modification time for the file
 };
 
@@ -272,7 +272,7 @@ struct pkgCache::Version
    map_ptrloc Size;              // These are the .deb size
    map_ptrloc InstalledSize;
    unsigned short Hash;
-   unsigned short ID;
+   unsigned int ID;
    unsigned char Priority;
 };
 
@@ -289,7 +289,7 @@ struct pkgCache::Description
    map_ptrloc NextDesc;          // Description
    map_ptrloc ParentPkg;         // Package
 
-   unsigned short ID;
+   unsigned int ID;
 };
 
 struct pkgCache::Dependency

+ 2 - 2
cmdline/acqprogress.cc

@@ -145,11 +145,11 @@ void AcqTextStatus::Stop()
    bandwidth and ETA indicator. */
 bool AcqTextStatus::Pulse(pkgAcquire *Owner)
 {
+   pkgAcquireStatus::Pulse(Owner);
+   
    if (Quiet > 0)
       return true;
    
-   pkgAcquireStatus::Pulse(Owner);
-   
    enum {Long = 0,Medium,Short} Mode = Long;
    
    char Buffer[sizeof(BlankLine)];

+ 15 - 10
cmdline/apt-get.cc

@@ -1272,16 +1272,23 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
 	 }
       }   
    }
-   
-   // No source package name..
-   if (Src.empty() == true)
-      Src = TmpSrc;
-   
+
    // The best hit
    pkgSrcRecords::Parser *Last = 0;
    unsigned long Offset = 0;
    string Version;
    bool IsMatch = false;
+   bool MatchSrcOnly = false;
+
+   // No source package name..
+   if (Src.empty() == true)
+      Src = TmpSrc;
+   else 
+      // if we have a source pkg name, make sure to only search
+      // for srcpkg names, otherwise apt gets confused if there
+      // is a binary package "pkg1" and a source package "pkg1"
+      // with the same name but that comes from different packages
+      MatchSrcOnly = true;
    
    // If we are matching by version then we need exact matches to be happy
    if (VerTag.empty() == false)
@@ -1291,13 +1298,11 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
       binary packages in the search */
    pkgSrcRecords::Parser *Parse;
    SrcRecs.Restart();
-   while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
+   while ((Parse = SrcRecs.Find(Src.c_str(), MatchSrcOnly)) != 0)
    {
       string Ver = Parse->Version();
       
-      // Skip name mismatches
-      if (IsMatch == true && Parse->Package() != Src)
-	 continue;
+	 ioprintf(c1out,  _("No source package '%s' picking '%s' instead\n"), Parse->Package().c_str(), Src.c_str());
       
       if (VerTag.empty() == false)
       {
@@ -2632,7 +2637,7 @@ bool ShowHelp(CommandLine &CmdL)
       "   install - Install new packages (pkg is libc6 not libc6.deb)\n"
       "   remove - Remove packages\n"
       "   autoremove - Remove automatically all unused packages\n"
-      "   purge - Remove and purge packages\n"
+      "   purge - Remove packages and config files\n"
       "   source - Download source archives\n"
       "   build-dep - Configure build-dependencies for source packages\n"
       "   dist-upgrade - Distribution upgrade, see apt-get(8)\n"

+ 20 - 0
debian/changelog

@@ -18,6 +18,26 @@ apt (0.7.20.3) UNRELEASED; urgency=low
   [ Michael Vogt ]
   * methods/gpgv.cc:
     - properly check for expired and revoked keys (closes: #433091)
+  * apt-pkg/contrib/strutl.cc:
+    - fix TimeToStr i18n (LP: #289807)
+  * [ABI break] merge support for http redirects, thanks to
+    Jeff Licquia and Anthony Towns
+  * [ABI break] use int for the package IDs (thanks to Steve Cotton)
+  * apt-pkg/pkgcache.cc:
+    - do not run "dpkg --configure pkg" if pkg is in trigger-awaited
+      state (LP: #322955)
+  * methods/https.cc:
+    - add Acquire::https::AllowRedirect support
+  * Clarify the --help for 'purge' (LP: #243948)
+  * cmdline/apt-get.cc
+    - fix "apt-get source pkg" if there is a binary package and
+      a source package of the same name but from different 
+      packages (LP: #330103)
+
+  [ Colin Watson ]
+  * cmdline/acqprogress.cc:
+    - Call pkgAcquireStatus::Pulse even if quiet, so that we still get
+      dlstatus messages on the status-fd (LP: #290234).
 
  -- Michael Vogt <mvo@debian.org>  Wed, 08 Apr 2009 22:37:01 +0200
 

+ 4 - 2
doc/examples/configure-index

@@ -133,7 +133,8 @@ Acquire
     Proxy::http.us.debian.org "DIRECT";  // Specific per-host setting
     Timeout "120";
     Pipeline-Depth "5";
-    
+    AllowRedirect  "true";
+
     // Cache Control. Note these do not work with Squid 2.0.2
     No-Cache "false";
     Max-Age "86400";     // 1 Day age on index files
@@ -150,7 +151,8 @@ Acquire
 	Verify-Peer "false";
 	SslCert "/etc/apt/some.pem";
         CaPath  "/etc/ssl/certs";
-        Verify-Host" "2";
+        Verify-Host" "true";
+        AllowRedirect  "true";
   };
 
   ftp

+ 1 - 0
ftparchive/cachedb.cc

@@ -463,6 +463,7 @@ bool CacheDB::Clean()
       
       Cursor->c_del(Cursor,0);
    }
+   Dbp->compact(Dbp, NULL, NULL, NULL, NULL, DB_FREE_SPACE, NULL);
 
    return true;
 }

+ 77 - 1
methods/http.cc

@@ -39,6 +39,7 @@
 #include <errno.h>
 #include <string.h>
 #include <iostream>
+#include <map>
 #include <apti18n.h>
 
 // Internet stuff
@@ -57,6 +58,7 @@ int HttpMethod::FailFd = -1;
 time_t HttpMethod::FailTime = 0;
 unsigned long PipelineDepth = 10;
 unsigned long TimeOut = 120;
+bool AllowRedirect = false;
 bool Debug = false;
 URI Proxy;
 
@@ -628,6 +630,12 @@ bool ServerState::HeaderLine(string Line)
       return true;
    }
 
+   if (stringcasecmp(Tag,"Location:") == 0)
+   {
+      Location = Val;
+      return true;
+   }
+
    return true;
 }
 									/*}}}*/
@@ -900,7 +908,9 @@ bool HttpMethod::ServerDie(ServerState *Srv)
      1 - IMS hit
      3 - Unrecoverable error 
      4 - Error with error content page
-     5 - Unrecoverable non-server error (close the connection) */
+     5 - Unrecoverable non-server error (close the connection) 
+     6 - Try again with a new or changed URI
+ */
 int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
 {
    // Not Modified
@@ -912,6 +922,27 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv)
       return 1;
    }
    
+   /* Redirect
+    *
+    * Note that it is only OK for us to treat all redirection the same
+    * because we *always* use GET, not other HTTP methods.  There are
+    * three redirection codes for which it is not appropriate that we
+    * redirect.  Pass on those codes so the error handling kicks in.
+    */
+   if (AllowRedirect
+       && (Srv->Result > 300 && Srv->Result < 400)
+       && (Srv->Result != 300       // Multiple Choices
+           && Srv->Result != 304    // Not Modified
+           && Srv->Result != 306))  // (Not part of HTTP/1.1, reserved)
+   {
+      if (!Srv->Location.empty())
+      {
+         NextURI = Srv->Location;
+         return 6;
+      }
+      /* else pass through for error message */
+   }
+ 
    /* We have a reply we dont handle. This should indicate a perm server
       failure */
    if (Srv->Result < 200 || Srv->Result >= 300)
@@ -1026,6 +1057,7 @@ bool HttpMethod::Configuration(string Message)
    if (pkgAcqMethod::Configuration(Message) == false)
       return false;
    
+   AllowRedirect = _config->FindB("Acquire::http::AllowRedirect",true);
    TimeOut = _config->FindI("Acquire::http::Timeout",TimeOut);
    PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth",
 				  PipelineDepth);
@@ -1039,6 +1071,10 @@ bool HttpMethod::Configuration(string Message)
 /* */
 int HttpMethod::Loop()
 {
+   typedef vector<string> StringVector;
+   typedef vector<string>::iterator StringVectorIterator;
+   map<string, StringVector> Redirected;
+
    signal(SIGTERM,SigTerm);
    signal(SIGINT,SigTerm);
    
@@ -1225,6 +1261,46 @@ int HttpMethod::Loop()
 	    break;
 	 }
 	 
+         // Try again with a new URL
+         case 6:
+         {
+            // Clear rest of response if there is content
+            if (Server->HaveContent)
+            {
+               File = new FileFd("/dev/null",FileFd::WriteExists);
+               Server->RunData();
+               delete File;
+               File = 0;
+            }
+
+            /* Detect redirect loops.  No more redirects are allowed
+               after the same URI is seen twice in a queue item. */
+            StringVector &R = Redirected[Queue->DestFile];
+            bool StopRedirects = false;
+            if (R.size() == 0)
+               R.push_back(Queue->Uri);
+            else if (R[0] == "STOP" || R.size() > 10)
+               StopRedirects = true;
+            else
+            {
+               for (StringVectorIterator I = R.begin(); I != R.end(); I++)
+                  if (Queue->Uri == *I)
+                  {
+                     R[0] = "STOP";
+                     break;
+                  }
+ 
+               R.push_back(Queue->Uri);
+            }
+ 
+            if (StopRedirects == false)
+               Redirect(NextURI);
+            else
+               Fail();
+ 
+            break;
+         }
+
 	 default:
 	 Fail(_("Internal error"));
 	 break;

+ 3 - 0
methods/http.h

@@ -99,6 +99,7 @@ struct ServerState
    enum {Chunked,Stream,Closes} Encoding;
    enum {Header, Data} State;
    bool Persistent;
+   string Location;
    
    // This is a Persistent attribute of the server itself.
    bool Pipeline;
@@ -143,6 +144,8 @@ class HttpMethod : public pkgAcqMethod
    static time_t FailTime;
    static void SigTerm(int);
    
+   string NextURI;
+   
    public:
    friend class ServerState;
 

+ 5 - 1
methods/https.cc

@@ -208,6 +208,11 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
 
+   // set redirect options and default to 10 redirects
+   bool AllowRedirect = _config->FindI("Acquire::https::AllowRedirect", true);
+   curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, AllowRedirect);
+   curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10);
+
    // debug
    if(_config->FindB("Debug::Acquire::https", false))
       curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
@@ -248,7 +253,6 @@ bool HttpsMethod::Fetch(FetchItem *Itm)
    // cleanup
    if(success != 0) 
    {
-      unlink(File->Name().c_str());
       _error->Error("%s", curl_errorstr);
       Fail();
       return true;

+ 1 - 1
methods/makefile

@@ -7,7 +7,7 @@ include ../buildlib/defaults.mak
 BIN := $(BIN)/methods
 
 # FIXME..
-LIB_APT_PKG_MAJOR = 4.6
+LIB_APT_PKG_MAJOR = 4.7
 APT_DOMAIN := libapt-pkg$(LIB_APT_PKG_MAJOR)
 
 # The file method

+ 3 - 0
pre-build.sh

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+make -f Makefile startup doc