]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
* merged with apt--mvo
[apt.git] / apt-pkg / acquire-item.cc
index b8886a750aafa84ee5dc178a84bb55f0c9a5c2cb..9fb7b57c242a03d1be43fa1575bb61eb7e5561df 100644 (file)
@@ -134,35 +134,37 @@ void pkgAcquire::Item::Rename(string From,string To)
 }
                                                                        /*}}}*/
 
-// AcqIndexDiffs::AcqIndexDiffs - Constructor                  
+
+// AcqDiffIndex::AcqDiffIndex - Constructor                    
 // ---------------------------------------------------------------------
-/* The package diff is added to the queue. one object is constructed
- * for each diff and the index
+/* Get the DiffIndex file first and see if there are patches availabe 
+ * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
+ * patches. If anything goes wrong in that process, it will fall back to
+ * the original packages file
  */
-pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
-                                  string URI,string URIDesc,string ShortDesc,
-                                  string ExpectedMD5, vector<DiffInfo> diffs)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
-     available_patches(diffs)
+pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
+                                string URI,string URIDesc,string ShortDesc,
+                                string ExpectedMD5)
+   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), Description(URIDesc)
 {
    
-   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(URI);
-
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 
-   Desc.Description = URIDesc;
+   Desc.Description = URIDesc + "/DiffIndex";
    Desc.Owner = this;
    Desc.ShortDesc = ShortDesc;
+   Desc.URI = URI + ".diff/Index";
+
+   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+   DestFile += URItoFileName(URI) + string(".DiffIndex");
 
+   if(Debug)
+      std::clog << "pkgAcqDiffIndex: " << Desc.URI << std::endl;
+
+   // look for the current package file
    CurrentPackagesFile = _config->FindDir("Dir::State::lists");
    CurrentPackagesFile += URItoFileName(RealURI);
 
-   if(Debug) {
-      std::clog << "pkgAcqIndexDiffs::pkgAcqIndexDiffs(): " 
-               << CurrentPackagesFile << std::endl;
-   }
-
    if(!FileExists(CurrentPackagesFile) || 
       !_config->FindB("Acquire::Diffs",true)) {
       // we don't have a pkg file or we don't want to queue
@@ -172,37 +174,20 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
       return;
    }
 
-   if(available_patches.size() == 0) {
-      State = StateFetchIndex;
-      QueueDiffIndex(URI);
-   } else {
-      State = StateFetchDiff;
-      QueueNextDiff();
+   if(Debug) {
+      std::clog << "pkgAcqIndexDiffs::pkgAcqIndexDiffs(): " 
+               << CurrentPackagesFile << std::endl;
    }
-}
-
-void pkgAcqIndexDiffs::QueueDiffIndex(string URI)
-{
-   Desc.URI = URI + ".diff/Index";
-   Desc.Description = Description + "IndexDiff";
-   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(URI) + string(".IndexDiff");
-
-   if(Debug)
-      std::clog << "QueueDiffIndex: " << Desc.URI << std::endl;
 
    QueueURI(Desc);
+
 }
 
 // AcqIndex::Custom600Headers - Insert custom request headers          /*{{{*/
 // ---------------------------------------------------------------------
 /* The only header we use is the last-modified header. */
-string pkgAcqIndexDiffs::Custom600Headers()
+string pkgAcqDiffIndex::Custom600Headers()
 {
-   // we only care for the IndexDiff file
-   if(State != StateFetchIndex)
-      return string("");
-
    string Final = _config->FindDir("Dir::State::lists");
    Final += URItoFileName(RealURI) + string(".IndexDiff");
    
@@ -216,11 +201,169 @@ string pkgAcqIndexDiffs::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 
+
+bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
+{
+   if(Debug)
+      std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
+               << std::endl;
+
+   pkgTagSection Tags;
+   string ServerSha1;
+   vector<DiffInfo> available_patches;
+   
+   FileFd Fd(IndexDiffFile,FileFd::ReadOnly);
+   pkgTagFile TF(&Fd);
+   if (_error->PendingError() == true)
+      return false;
+
+   if(TF.Step(Tags) == true)
+   {
+      string local_sha1;
+      bool found = false;
+      DiffInfo d;
+      string size;
+
+      string tmp = Tags.FindS("SHA1-Current");
+      std::stringstream ss(tmp);
+      ss >> ServerSha1;
+
+      FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
+      SHA1Summation SHA1;
+      SHA1.AddFD(fd.Fd(), fd.Size());
+      local_sha1 = string(SHA1.Result());
+
+      if(local_sha1 == ServerSha1) {
+        if(Debug)
+           std::clog << "Package file is up-to-date" << std::endl;
+        // set found to true, this will queue a pkgAcqIndexDiffs with
+        // a empty availabe_patches
+        found = true;
+      } else {
+        if(Debug)
+           std::clog << "SHA1-Current: " << ServerSha1 << std::endl;
+
+        // check the historie and see what patches we need
+        string history = Tags.FindS("SHA1-History");     
+        std::stringstream hist(history);
+        while(hist >> d.sha1 >> size >> d.file) {
+           d.size = atoi(size.c_str());
+           // read until the first match is found
+           if(d.sha1 == local_sha1) 
+              found=true;
+           // from that point on, we probably need all diffs
+           if(found) {
+              if(Debug)
+                 std::clog << "Need to get diff: " << d.file << std::endl;
+              available_patches.push_back(d);
+           }
+        }
+      }
+
+      // no information how to get the patches, bail out
+      if(!found) {
+        if(Debug)
+           std::clog << "Can't find a patch in the index file" << std::endl;
+        // Failed will queue a big package file
+        Failed("", NULL);
+      } else {
+        // queue the diffs
+        new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
+                             ExpectedMD5, available_patches);
+        Complete = false;
+        Status = StatDone;
+        Dequeue();
+        return true;
+      }
+   }
+
+   return false;
+}
+
+void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+{
+   if(Debug)
+      std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
+               << "Falling back to normal index file aquire" << std::endl;
+
+   new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
+                  ExpectedMD5);
+
+   Complete = false;
+   Status = StatDone;
+   Dequeue();
+}
+
+void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
+                          pkgAcquire::MethodConfig *Cnf)
+{
+   if(Debug)
+      std::clog << "pkgAcqDiffIndex::Done(): " << Desc.URI << std::endl;
+
+   Item::Done(Message,Size,Md5Hash,Cnf);
+
+   string FinalFile;
+   FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
+
+   // sucess in downloading the index
+   // rename the index
+   FinalFile += string(".IndexDiff");
+   if(Debug)
+      std::clog << "Renaming: " << DestFile << " -> " << FinalFile 
+               << std::endl;
+   Rename(DestFile,FinalFile);
+   chmod(FinalFile.c_str(),0644);
+   DestFile = FinalFile;
+
+   if(!ParseDiffIndex(DestFile))
+      return Failed("", NULL);
+
+   Complete = true;
+   Status = StatDone;
+   Dequeue();
+   return;
+}
+
+
+
+// AcqIndexDiffs::AcqIndexDiffs - Constructor                  
+// ---------------------------------------------------------------------
+/* The package diff is added to the queue. one object is constructed
+ * for each diff and the index
+ */
+pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
+                                  string URI,string URIDesc,string ShortDesc,
+                                  string ExpectedMD5, vector<DiffInfo> diffs)
+   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
+     available_patches(diffs)
+{
+   
+   DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+   DestFile += URItoFileName(URI);
+
+   Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
+
+   Desc.Description = URIDesc;
+   Desc.Owner = this;
+   Desc.ShortDesc = ShortDesc;
+
+   if(available_patches.size() == 0) {
+      // we are done (yeah!)
+      Finish(true);
+   } else {
+      // get the next diff
+      State = StateFetchDiff;
+      QueueNextDiff();
+   }
+}
+
+
 void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 {
-   std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
-            << "Falling back to normal index file aquire" << std::endl;
-   new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, 
+   if(Debug)
+      std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
+               << "Falling back to normal index file aquire" << std::endl;
+   new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
                   ExpectedMD5);
    Finish();
 }
@@ -232,15 +375,32 @@ void pkgAcqIndexDiffs::Finish(bool allDone)
    // we restore the original name, this is required, otherwise
    // the file will be cleaned
    if(allDone) {
-      // this is for the "real" finish
       DestFile = _config->FindDir("Dir::State::lists");
       DestFile += URItoFileName(RealURI);
+
+      // do the final md5sum checking
+      MD5Summation sum;
+      FileFd Fd(DestFile, FileFd::ReadOnly);
+      sum.AddFD(Fd.Fd(), Fd.Size());
+      Fd.Close();
+      string MD5 = (string)sum.Result();
+
+      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
+      {
+        Status = StatAuthError;
+        ErrorText = _("MD5Sum mismatch");
+        Rename(DestFile,DestFile + ".FAILED");
+        Dequeue();
+        return;
+      }
+
+      // this is for the "real" finish
       Complete = true;
+      Status = StatDone;
       Dequeue();
       if(Debug)
         std::clog << "\n\nallDone: " << DestFile << "\n" << std::endl;
       return;
-
    }
 
    if(Debug)
@@ -284,11 +444,11 @@ bool pkgAcqIndexDiffs::QueueNextDiff()
    }
 
    // queue the right diff
-   Desc.URI = string(RealURI) + string(".diff/") + available_patches[0].file + string(".gz");
+   Desc.URI = string(RealURI) + ".diff/" + available_patches[0].file + ".gz";
    Desc.Description = available_patches[0].file + string(".pdiff");
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(RealURI + string(".diff/") + available_patches[0].file);
+   DestFile += URItoFileName(RealURI + ".diff/" + available_patches[0].file);
 
    if(Debug)
       std::clog << "pkgAcqIndexDiffs::QueueNextDiff(): " << Desc.URI << std::endl;
@@ -298,74 +458,6 @@ bool pkgAcqIndexDiffs::QueueNextDiff()
    return true;
 }
 
-bool pkgAcqIndexDiffs::ParseIndexDiff(string IndexDiffFile)
-{
-   if(Debug)
-      std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile 
-               << std::endl;
-   
-   FileFd Fd(IndexDiffFile,FileFd::ReadOnly);
-   pkgTagFile TF(&Fd);
-   if (_error->PendingError() == true)
-      return false;
-   pkgTagSection Tags;
-   if(TF.Step(Tags) == true)
-   {
-      string local_sha1;
-      string tmp = Tags.FindS("SHA1-Current");
-      std::stringstream ss(tmp);
-      ss >> ServerSha1;
-
-      FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
-      SHA1Summation SHA1;
-      SHA1.AddFD(fd.Fd(), fd.Size());
-      local_sha1 = string(SHA1.Result());
-
-      if(local_sha1 == ServerSha1) {
-        if(Debug)
-           std::clog << "Package file is up-to-date" << std::endl;
-        Finish(true);
-        return true;
-      }
-      if(Debug)
-        std::clog << "SHA1-Current: " << ServerSha1 << std::endl;
-
-      // check the historie and see what patches we need
-      string history = Tags.FindS("SHA1-History");     
-      std::stringstream hist(history);
-      DiffInfo d;
-      string size;
-      bool found = false;
-      while(hist >> d.sha1 >> size >> d.file) {
-        d.size = atoi(size.c_str());
-        // read until the first match is found
-        if(d.sha1 == local_sha1) 
-           found=true;
-        // from that point on, we probably need all diffs
-        if(found) {
-           if(Debug)
-              std::clog << "Need to get diff: " << d.file << std::endl;
-           available_patches.push_back(d);
-        }
-      }
-
-      // no information how to get the patches, bail out
-      if(!found) {
-        if(Debug)
-           std::clog << "Can't find a patch in the index file" << std::endl;
-        // Failed will queue a big package file
-        Failed("", NULL);
-      } else {
-        // queue the diffs
-        new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
-                             ExpectedMD5, available_patches);
-        Finish();
-        return true;
-      }
-   }
-
-   return false;
-}
 
 
 void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
@@ -379,24 +471,6 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
    string FinalFile;
    FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
 
-   // sucess in downloading the index
-   if(State == StateFetchIndex) 
-   {
-      // rename the index
-      FinalFile += string(".IndexDiff");
-      if(Debug)
-        std::clog << "Renaming: " << DestFile << " -> " << FinalFile 
-                  << std::endl;
-      Rename(DestFile,FinalFile);
-      chmod(FinalFile.c_str(),0644);
-      DestFile = FinalFile;
-
-      if(!ParseIndexDiff(DestFile))
-        return Failed("", NULL);
-      else 
-        return Finish();
-   }
-
    // sucess in downloading a diff, enter ApplyDiff state
    if(State == StateFetchDiff) 
    {
@@ -467,20 +541,21 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 {
    Decompression = false;
    Erase = false;
-   
+
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
    DestFile += URItoFileName(URI);
 
    if(comprExt.empty()) 
    {
-      // autoselect 
-      if(FileExists("/usr/bin/bzip2"))
-        Desc.URI = URI + ".bz2"; 
-      else
-        Desc.URI = URI + ".gz"; 
+      // autoselect the compression method
+      if(FileExists("/usr/bin/bzip2")) 
+        CompressionExtension = ".bz2";
+      else 
+        CompressionExtension = ".gz";
    } else {
-      Desc.URI = URI + comprExt; 
+      CompressionExtension = comprExt;
    }
+   Desc.URI = URI + CompressionExtension; 
 
    Desc.Description = URIDesc;
    Desc.Owner = this;
@@ -632,6 +707,35 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
    Mode = decompProg;
 }
 
+// AcqIndexTrans::pkgAcqIndexTrans - Constructor                       /*{{{*/
+// ---------------------------------------------------------------------
+/* The Translation file is added to the queue */
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
+                           string URI,string URIDesc,string ShortDesc) :
+                      pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, "", "")
+{
+}
+
+                                                                       /*}}}*/
+// AcqIndexTrans::Failed - Silence failure messages for missing files  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+{
+   if (Cnf->LocalOnly == true || 
+       StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
+   {      
+      // Ignore this
+      Status = StatDone;
+      Complete = false;
+      Dequeue();
+      return;
+   }
+   
+   Item::Failed(Message,Cnf);
+}
+                                                                       /*}}}*/
+
 pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
                             string URI,string URIDesc,string ShortDesc,
                             string MetaIndexURI, string MetaIndexURIDesc,
@@ -725,6 +829,13 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
    unlink(Final.c_str());
 
+   // if we get a timeout if fail
+   if(LookupTag(Message,"FailReason") == "Timeout" || 
+      LookupTag(Message,"FailReason") == "TmpResolveFailure") {
+      Item::Failed(Message,Cnf);
+      return;
+   }
+
    // queue a pkgAcqMetaIndex with no sigfile
    new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
                       "", IndexTargets, MetaIndexParser);
@@ -924,8 +1035,8 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
       }
       
       // Queue Packages file
-      new pkgAcqIndexDiffs(Owner, (*Target)->URI, (*Target)->Description,
-                          (*Target)->ShortDesc, ExpectedIndexMD5);
+      new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
+                         (*Target)->ShortDesc, ExpectedIndexMD5);
    }
 }
 
@@ -1087,6 +1198,12 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
       }
    }
 
+   // "allow-unauthenticated" restores apts old fetching behaviour
+   // that means that e.g. unauthenticated file:// uris are higher
+   // priority than authenticated http:// uris
+   if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true)
+      Trusted = false;
+
    // Select a source
    if (QueueNext() == false && _error->PendingError() == false)
       _error->Error(_("I wasn't able to locate file for the %s package. "
@@ -1223,7 +1340,8 @@ void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
       {
         Status = StatError;
         ErrorText = _("MD5Sum mismatch");
-        Rename(DestFile,DestFile + ".FAILED");
+        if(FileExists(DestFile))
+           Rename(DestFile,DestFile + ".FAILED");
         return;
       }
    }