]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'upstream/debian/experimental' into feature/no-more...
authorMichael Vogt <mvo@ubuntu.com>
Thu, 6 Nov 2014 07:55:06 +0000 (08:55 +0100)
committerMichael Vogt <mvo@ubuntu.com>
Thu, 6 Nov 2014 07:55:06 +0000 (08:55 +0100)
Conflicts:
apt-pkg/acquire-item.cc

1  2 
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
test/integration/test-apt-update-filesize-mismatch
test/integration/test-apt-update-hashsum-mismatch

diff --combined apt-pkg/acquire-item.cc
index 0e406f3688e111ad5f69c3904354d893808ce0c3,f684e81f182f0661620fc238e938160879ad80a2..605ca7ae4b31feb87b1708954f14112ff6382278
@@@ -44,9 -44,6 +44,6 @@@
  #include <sstream>
  #include <stdio.h>
  #include <ctime>
- #include <sys/types.h>
- #include <pwd.h>
- #include <grp.h>
  
  #include <apti18n.h>
                                                                        /*}}}*/
@@@ -65,20 -62,6 +62,6 @@@ static void printHashSumComparision(std
        std::cerr <<  "\t- " << hs->toStr() << std::endl;
  }
                                                                        /*}}}*/
- static void ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) /*{{{*/
- {
-    // ensure the file is owned by root and has good permissions
-    struct passwd const * const pw = getpwnam(user);
-    struct group const * const gr = getgrnam(group);
-    if (getuid() == 0) // if we aren't root, we can't chown, so don't try it
-    {
-       if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0)
-        _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file);
-    }
-    if (chmod(file, mode) != 0)
-       _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file);
- }
-                                                                       /*}}}*/
  static std::string GetPartialFileName(std::string const &file)                /*{{{*/
  {
     std::string DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@@ -155,7 -138,7 +138,7 @@@ pkgAcquire::Item::~Item(
     fetch this object */
  void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
-    if(ErrorText == "")
+    if(ErrorText.empty())
        ErrorText = LookupTag(Message,"Message");
     UsedMirror =  LookupTag(Message,"UsedMirror");
     if (QueueCounter <= 1)
        Status = StatIdle;
  
     // check fail reason
-    string FailReason = LookupTag(Message, "FailReason");
+    string const FailReason = LookupTag(Message, "FailReason");
     if(FailReason == "MaximumSizeExceeded")
-       Rename(DestFile, DestFile+".FAILED");
+       RenameOnError(MaximumSizeExceeded);
  
     // report mirror failure back to LP if we actually use a mirror
     if(FailReason.size() != 0)
  void pkgAcquire::Item::Start(string /*Message*/,unsigned long long Size)
  {
     Status = StatFetching;
+    ErrorText.clear();
     if (FileSize == 0 && Complete == false)
        FileSize = Size;
  }
@@@ -242,12 -226,6 +226,6 @@@ bool pkgAcquire::Item::Rename(string Fr
                                                                        /*}}}*/
  void pkgAcquire::Item::QueueURI(ItemDesc &Item)                               /*{{{*/
  {
-    if (RealFileExists(DestFile))
-    {
-       std::string SandboxUser = _config->Find("APT::Sandbox::User");
-       ChangeOwnerAndPermissionOfFile("Item::QueueURI", DestFile.c_str(),
-                                      SandboxUser.c_str(), "root", 0600);
-    }
     Owner->Enqueue(Item);
  }
                                                                        /*}}}*/
@@@ -258,7 -236,7 +236,7 @@@ void pkgAcquire::Item::Dequeue()                                   /*
                                                                        /*}}}*/
  bool pkgAcquire::Item::RenameOnError(pkgAcquire::Item::RenameOnErrorState const error)/*{{{*/
  {
-    if(FileExists(DestFile))
+    if (RealFileExists(DestFile))
        Rename(DestFile, DestFile + ".FAILED");
  
     switch (error)
         Status = StatError;
         break;
        case NotClearsigned:
-          ErrorText = _("Does not start with a cleartext signature");
+        ErrorText = _("Does not start with a cleartext signature");
+        Status = StatError;
+        break;
+       case MaximumSizeExceeded:
+        // the method is expected to report a good error for this
         Status = StatError;
         break;
     }
@@@ -702,14 -684,14 +684,14 @@@ bool pkgAcqDiffIndex::ParseDiffIndex(st
                                                                        /*}}}*/
  void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig * Cnf)/*{{{*/
  {
+    Item::Failed(Message,Cnf);
+    Status = StatDone;
     if(Debug)
        std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
                << "Falling back to normal index file acquire" << std::endl;
  
     new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
-    Item::Failed(Message,Cnf);
-    Status = StatDone;
  }
                                                                        /*}}}*/
  void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes,       /*{{{*/
@@@ -792,8 -774,11 +774,11 @@@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgA
     }
  }
                                                                        /*}}}*/
- void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)/*{{{*/
+ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig * Cnf)/*{{{*/
  {
+    Item::Failed(Message,Cnf);
+    Status = StatDone;
     if(Debug)
        std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl
                << "Falling back to normal index file acquire" << std::endl;
@@@ -1275,20 -1260,20 +1260,23 @@@ string pkgAcqIndex::Custom600Headers() 
     if (stat(Final.c_str(),&Buf) == 0)
        msg += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
  
 +   if(Target->IsOptional())
 +      msg += "\nFail-Ignore: true";
 +
     return msg;
  }
                                                                        /*}}}*/
  // pkgAcqIndex::Failed - getting the indexfile failed                 /*{{{*/
  void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
+    Item::Failed(Message,Cnf);
     size_t const nextExt = CompressionExtensions.find(' ');
     if (nextExt != std::string::npos)
     {
        CompressionExtensions = CompressionExtensions.substr(nextExt+1);
        Init(RealURI, Desc.Description, Desc.ShortDesc);
+       Status = StatIdle;
        return;
     }
  
        unlink(EraseFileName.c_str());
     }
  
 -   /// cancel the entire transaction
 -   TransactionManager->AbortTransaction();
 +   Item::Failed(Message,Cnf);
 +
 +   if(Target->IsOptional() && ExpectedHashes.empty() && Stage == STAGE_DOWNLOAD)
 +      Status = StatDone;
 +   else
 +      TransactionManager->AbortTransaction();
  }
                                                                        /*}}}*/
  // pkgAcqIndex::GetFinalFilename - Return the full final file path    /*{{{*/
@@@ -1495,6 -1476,57 +1483,6 @@@ void pkgAcqIndex::StageDecompressDone(s
     return;
  }
                                                                        /*}}}*/
 -// 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, HashStringList())
 -{
 -}
 -pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
 -                                   pkgAcqMetaBase *TransactionManager,
 -                                   IndexTarget const * const Target,
 -                                   HashStringList const &ExpectedHashes,
 -                                   indexRecords *MetaIndexParser)
 -   : pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser)
 -{
 -}
 -                                                                      /*}}}*/
 -// AcqIndexTrans::Custom600Headers - Insert custom request headers    /*{{{*/
 -string pkgAcqIndexTrans::Custom600Headers() const
 -{
 -   string Final = GetFinalFilename();
 -
 -   struct stat Buf;
 -   if (stat(Final.c_str(),&Buf) != 0)
 -      return "\nFail-Ignore: true\nIndex-File: true";
 -   return "\nFail-Ignore: true\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 -}
 -                                                                      /*}}}*/
 -// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
 -void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 -{
 -   Item::Failed(Message,Cnf);
 -
 -   size_t const nextExt = CompressionExtensions.find(' ');
 -   if (nextExt != std::string::npos)
 -   {
 -      CompressionExtensions = CompressionExtensions.substr(nextExt+1);
 -      Init(RealURI, Desc.Description, Desc.ShortDesc);
 -      Status = StatIdle;
 -      return;
 -   }
 -
 -   // FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor
 -   if (Cnf->LocalOnly == true ||
 -       StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
 -   {
 -      // Ignore this
 -      Status = StatDone;
 -   }
 -}
 -                                                                      /*}}}*/
  // AcqMetaBase::Add - Add a item to the current Transaction           /*{{{*/
  void pkgAcqMetaBase::Add(Item *I)
  {
@@@ -1515,19 -1547,10 +1503,10 @@@ void pkgAcqMetaBase::AbortTransaction(
           std::clog << "  Cancel: " << (*I)->DestFile << std::endl;
        // the transaction will abort, so stop anything that is idle
        if ((*I)->Status == pkgAcquire::Item::StatIdle)
-          (*I)->Status = pkgAcquire::Item::StatDone;
-       // kill failed files in partial
-       if ((*I)->Status == pkgAcquire::Item::StatError)
        {
-          std::string const PartialFile = GetPartialFileName(flNotDir((*I)->DestFile));
-          if(FileExists(PartialFile))
-             Rename(PartialFile, PartialFile + ".FAILED");
+          (*I)->Status = pkgAcquire::Item::StatDone;
+          (*I)->Dequeue();
        }
-       // fix permissions for existing files which were part of a reverify
-       // like InRelease files or files in partial we might work with next time
-       else if (FileExists((*I)->DestFile))
-        ChangeOwnerAndPermissionOfFile("AbortTransaction", (*I)->DestFile.c_str(), "root", "root", 0644);
     }
     Transaction.clear();
  }
@@@ -1562,8 -1585,6 +1541,6 @@@ void pkgAcqMetaBase::CommitTransaction(
               << (*I)->DescURI() << std::endl;
  
         Rename((*I)->PartialFile, (*I)->DestFile);
-        ChangeOwnerAndPermissionOfFile("CommitTransaction", (*I)->DestFile.c_str(), "root", "root", 0644);
        } else {
           if(_config->FindB("Debug::Acquire::Transaction", false) == true)
              std::clog << "rm "
@@@ -1712,16 -1733,17 +1689,17 @@@ void pkgAcqMetaSig::Done(string Message
                                                                        /*}}}*/
  void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
  {
-    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+    Item::Failed(Message,Cnf);
  
     // check if we need to fail at this point 
     if (AuthPass == true && CheckStopAuthentication(RealURI, Message))
           return;
  
     // FIXME: meh, this is not really elegant
-    string InReleaseURI = RealURI.replace(RealURI.rfind("Release.gpg"), 12,
+    string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+    string const InReleaseURI = RealURI.replace(RealURI.rfind("Release.gpg"), 12,
                                           "InRelease");
-    string FinalInRelease = _config->FindDir("Dir::State::lists") + URItoFileName(InReleaseURI);
+    string const FinalInRelease = _config->FindDir("Dir::State::lists") + URItoFileName(InReleaseURI);
  
     if (RealFileExists(Final) || RealFileExists(FinalInRelease))
     {
           _error->Warning(_("This is normally not allowed, but the option "
                             "Acquire::AllowDowngradeToInsecureRepositories was "
                             "given to override it."));
-          
+          Status = StatDone;
        } else {
           _error->Error("%s", downgrade_msg.c_str());
           Rename(MetaIndexFile, MetaIndexFile+".FAILED");
        QueueIndexes(true);
     }
  
-    Item::Failed(Message,Cnf);
     // FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor
     if (Cnf->LocalOnly == true ||
         StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
@@@ -1953,59 -1973,87 +1929,59 @@@ bool pkgAcqMetaBase::CheckDownloadDone(
                                                                        /*}}}*/
  void pkgAcqMetaBase::QueueIndexes(bool verify)                                /*{{{*/
  {
 -   bool transInRelease = false;
 -   {
 -      std::vector<std::string> const keys = MetaIndexParser->MetaKeys();
 -      for (std::vector<std::string>::const_iterator k = keys.begin(); k != keys.end(); ++k)
 -       // FIXME: Feels wrong to check for hardcoded string here, but what should we do elseā€¦
 -       if (k->find("Translation-") != std::string::npos)
 -       {
 -          transInRelease = true;
 -          break;
 -       }
 -   }
 -
     // at this point the real Items are loaded in the fetcher
     ExpectedAdditionalItems = 0;
 -   for (vector <IndexTarget*>::const_iterator Target = IndexTargets->begin();
 +
 +   vector <struct IndexTarget*>::const_iterator Target;
 +   for (Target = IndexTargets->begin();
          Target != IndexTargets->end();
          ++Target)
     {
        HashStringList ExpectedIndexHashes;
        const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
 -      bool compressedAvailable = false;
 -      if (Record == NULL)
 +
 +      // optional target that we do not have in the Release file are 
 +      // skipped
 +      if (verify == true && Record == NULL && (*Target)->IsOptional())
 +         continue;
 +
 +      // targets without a hash record are a error when verify is required
 +      if (verify == true && Record == NULL)
        {
 -       if ((*Target)->IsOptional() == true)
 -       {
 -          std::vector<std::string> types = APT::Configuration::getCompressionTypes();
 -          for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
 -             if (MetaIndexParser->Exists((*Target)->MetaKey + "." + *t) == true)
 -             {
 -                compressedAvailable = true;
 -                break;
 -             }
 -       }
 -       else if (verify == true)
 -       {
 -          Status = StatAuthError;
 -          strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str());
 -          return;
 -       }
 +         Status = StatAuthError;
 +         strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str());
 +         return;
        }
 -      else
 +
 +      if (Record)
 +         ExpectedIndexHashes = Record->Hashes;
 +      
 +      if (_config->FindB("Debug::pkgAcquire::Auth", false))
        {
 -       ExpectedIndexHashes = Record->Hashes;
 -       if (_config->FindB("Debug::pkgAcquire::Auth", false))
 -       {
 -          std::cerr << "Queueing: " << (*Target)->URI << std::endl
 -             << "Expected Hash:" << std::endl;
 -          for (HashStringList::const_iterator hs = ExpectedIndexHashes.begin(); hs != ExpectedIndexHashes.end(); ++hs)
 -             std::cerr <<  "\t- " << hs->toStr() << std::endl;
 -          std::cerr << "For: " << Record->MetaKeyFilename << std::endl;
 -       }
 -       if (verify == true && ExpectedIndexHashes.empty() == true && (*Target)->IsOptional() == false)
 -       {
 -          Status = StatAuthError;
 -          strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str());
 -          return;
 -       }
 -      }
 +         std::cerr << "Queueing: " << (*Target)->URI << std::endl
 +                   << "Expected Hash:" << std::endl;
 +         for (HashStringList::const_iterator hs = ExpectedIndexHashes.begin(); hs != ExpectedIndexHashes.end(); ++hs)
 +            std::cerr <<  "\t- " << hs->toStr() << std::endl;
 +         std::cerr << "For: " << Record->MetaKeyFilename << std::endl;
  
 -      if ((*Target)->IsOptional() == true)
 +      }
 +      if (verify == true && ExpectedIndexHashes.empty() == true)
        {
 -       if (transInRelease == false || Record != NULL || compressedAvailable == true)
 -       {
 -          if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
 -              MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
 -             new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
 -          else
 -             new pkgAcqIndexTrans(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
 -       }
 -       continue;
 +         Status = StatAuthError;
 +         strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str());
 +         return;
        }
  
 -      /* Queue Packages file (either diff or full packages files, depending
 +      /* Queue the Index file (Packages, Sources, Translation-$foo
 +         (either diff or full packages files, depending
           on the users option) - we also check if the PDiff Index file is listed
           in the Meta-Index file. Ideal would be if pkgAcqDiffIndex would test this
           instead, but passing the required info to it is to much hassle */
        if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false ||
 -        MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true))
 -       new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
 +          MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true))
 +         new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
        else
 -       new pkgAcqIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
 +         new pkgAcqIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
     }
  }
                                                                        /*}}}*/
@@@ -2152,10 -2200,12 +2128,12 @@@ string pkgAcqMetaClearSig::Custom600Hea
                                                                        /*}}}*/
  // pkgAcqMetaClearSig::Done - We got a file                           /*{{{*/
  // ---------------------------------------------------------------------
- void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long /*Size*/,
-                               HashStringList const &/*Hashes*/,
+ void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long Size,
+                               HashStringList const &Hashes,
                                pkgAcquire::MethodConfig *Cnf)
  {
+    Item::Done(Message, Size, Hashes, Cnf);
     // if we expect a ClearTextSignature (InRelase), ensure that
     // this is what we get and if not fail to queue a 
     // Release/Release.gpg, see #346386
@@@ -2420,11 -2470,7 +2398,7 @@@ bool pkgAcqArchive::QueueNext(
         if ((unsigned long long)Buf.st_size > Version->Size)
            unlink(DestFile.c_str());
         else
-        {
            PartialSize = Buf.st_size;
-             std::string SandboxUser = _config->Find("APT::Sandbox::User");
-           ChangeOwnerAndPermissionOfFile("pkgAcqArchive::QueueNext",DestFile.c_str(), SandboxUser.c_str(), "root", 0600);
-        }
        }
  
        // Disables download of archives - useful if no real installation follows,
@@@ -2493,7 -2539,6 +2467,6 @@@ void pkgAcqArchive::Done(string Message
     string FinalFile = _config->FindDir("Dir::Cache::Archives");
     FinalFile += flNotDir(StoreFilename);
     Rename(DestFile,FinalFile);
-    ChangeOwnerAndPermissionOfFile("pkgAcqArchive::Done", FinalFile.c_str(), "root", "root", 0644);
     StoreFilename = DestFile = FinalFile;
     Complete = true;
  }
  /* Here we try other sources */
  void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
-    ErrorText = LookupTag(Message,"Message");
-    
+    Item::Failed(Message,Cnf);
     /* We don't really want to retry on failed media swaps, this prevents 
        that. An interesting observation is that permanent failures are not
        recorded. */
        // Vf = Version.FileList();
        while (Vf.end() == false) ++Vf;
        StoreFilename = string();
-       Item::Failed(Message,Cnf);
        return;
     }
-    
+    Status = StatIdle;
     if (QueueNext() == false)
     {
        // This is the retry counter
         if (QueueNext() == true)
            return;
        }
-       
        StoreFilename = string();
-       Item::Failed(Message,Cnf);
+       Status = StatError;
     }
  }
                                                                        /*}}}*/
@@@ -2589,11 -2634,7 +2562,7 @@@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owne
        if ((Size > 0) && (unsigned long long)Buf.st_size > Size)
         unlink(DestFile.c_str());
        else
-       {
         PartialSize = Buf.st_size;
-          std::string SandboxUser = _config->Find("APT::Sandbox::User");
-        ChangeOwnerAndPermissionOfFile("pkgAcqFile", DestFile.c_str(), SandboxUser.c_str(), "root", 0600);
-       }
     }
  
     QueueURI(Desc);
@@@ -2652,7 -2693,12 +2621,12 @@@ void pkgAcqFile::Done(string Message,un
        // Symlink the file
        if (symlink(FileName.c_str(),DestFile.c_str()) != 0)
        {
-        ErrorText = "Link to " + DestFile + " failure ";
+        _error->PushToStack();
+        _error->Errno("pkgAcqFile::Done", "Symlinking file %s failed", DestFile.c_str());
+        std::stringstream msg;
+        _error->DumpErrors(msg);
+        _error->RevertToStack();
+        ErrorText = msg.str();
         Status = StatError;
         Complete = false;
        }      
  /* Here we try other sources */
  void pkgAcqFile::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
  {
-    ErrorText = LookupTag(Message,"Message");
-    
+    Item::Failed(Message,Cnf);
     // This is the retry counter
     if (Retries != 0 &&
         Cnf->LocalOnly == false &&
         StringToBool(LookupTag(Message,"Transient-Failure"),false) == true)
     {
-       Retries--;
+       --Retries;
        QueueURI(Desc);
+       Status = StatIdle;
        return;
     }
-    
-    Item::Failed(Message,Cnf);
  }
                                                                        /*}}}*/
  // AcqIndex::Custom600Headers - Insert custom request headers         /*{{{*/
diff --combined apt-pkg/acquire-item.h
index 7adc1976b056a3f186271c2286b680f82c766d88,ff1bf563a9f00da1bc696588bdefbe747f755eb3..10d7e6a09d71a69f0e15df357168d5f247f34d48
@@@ -63,6 -63,8 +63,8 @@@ class pkgAcqMetaBase
   */
  class pkgAcquire::Item : public WeakPointable
  {  
+    friend class pkgAcqMetaBase;
     void *d;
  
     protected:
        InvalidFormat,
        SignatureError,
        NotClearsigned,
+       MaximumSizeExceeded
     };
  
     /** \brief Rename failed file and set error
@@@ -1024,6 -1027,43 +1027,6 @@@ class pkgAcqIndex : public pkgAcqBaseIn
               std::string const &ShortDesc);
  };
                                                                        /*}}}*/
 -/** \brief An acquire item that is responsible for fetching a         {{{
 - *  translated index file.
 - *
 - *  The only difference from pkgAcqIndex is that transient failures
 - *  are suppressed: no error occurs if the translated index file is
 - *  missing.
 - */
 -class pkgAcqIndexTrans : public pkgAcqIndex
 -{
 -   void *d;
 -
 -   public:
 -  
 -   virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf);
 -   virtual std::string Custom600Headers() const;
 -
 -   /** \brief Create a pkgAcqIndexTrans.
 -    *
 -    *  \param Owner The pkgAcquire object with which this item is
 -    *  associated.
 -    *
 -    *  \param URI The URI of the index file that is to be downloaded.
 -    *
 -    *  \param URIDesc A "URI-style" description of this index file.
 -    *
 -    *  \param ShortDesc A brief description of this index file.
 -    */
 -   pkgAcqIndexTrans(pkgAcquire *Owner,
 -                    std::string URI,std::string URIDesc,
 -                  std::string ShortDesc);
 -   pkgAcqIndexTrans(pkgAcquire *Owner,
 -                    pkgAcqMetaBase *TransactionManager,
 -                    IndexTarget const * const Target,
 -                    HashStringList const &ExpectedHashes,
 -                    indexRecords *MetaIndexParser);
 -};
 -                                                                      /*}}}*/
  /** \brief Information about an index file. */                                /*{{{*/
  class IndexTarget
  {
index 0000000000000000000000000000000000000000,b484c5161645d36a03a456b7f74a3a426101ee62..f78b83b5ff6d1ca858fbe303db948e810235ff49
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,55 +1,50 @@@
 -              TEST='testfailure'
 -              if expr match "$COMPRESSFILE" '^.*Translation-.*$' >/dev/null; then
 -                      TEST='testsuccess'
 -                      unset COMPRESSFILE
 -              fi
 -              $TEST aptget update -o Debug::pkgAcquire::Worker=1
 -              cp rootdir/tmp/${TEST}.output rootdir/tmp/update.output
+ #!/bin/sh
+ set -e
+ TESTDIR=$(readlink -f $(dirname $0))
+ . $TESTDIR/framework
+ setupenvironment
+ configarchitecture 'i386'
+ configcompression 'gz'
+ insertpackage 'testing' 'foo' 'all' '1'
+ insertpackage 'testing' 'foo2' 'all' '1'
+ insertsource 'testing' 'foo' 'all' '1'
+ insertsource 'testing' 'foo2' 'all' '1'
+ setupaptarchive --no-update
+ changetowebserver
+ find aptarchive \( -name 'Packages' -o -name 'Sources' -o -name 'Translation-en' \) -delete
+ for release in $(find aptarchive -name 'Release'); do
+       cp "$release" "${release}.backup"
+ done
+ testsuccess aptget update
+ testsuccess aptcache show foo
+ testsuccess aptget install foo -s
+ for get in $(sed -n 's#^GET /\([^ ]\+\.gz\) HTTP.\+$#\1#p' aptarchive/webserver.log); do
+       for ext in '' '.gz'; do
+               COMPRESSFILE="$get"
+               get="${get}${ext}"
+               FILE="$(basename "$get" '.gz')"
+               msgmsg 'Test filesize mismatch with file' "$FILE"
+               rm -rf rootdir/var/lib/apt/lists
+               for release in $(find aptarchive -name 'Release'); do
+                       SIZE="$(awk "/$FILE\$/ { print \$2; exit }" "${release}.backup")"
+                       sed "s# $SIZE # $(($SIZE + 111)) #" "${release}.backup" > "$release"
+               done
+               signreleasefiles
 -              $TEST aptcache show foo
 -              $TEST aptget install foo -s
++              testfailure aptget update -o Debug::pkgAcquire::Worker=1
++              cp rootdir/tmp/testfailure.output rootdir/tmp/update.output
+               testsuccess grep -E "$(basename -s '.gz' "$COMPRESSFILE").*Hash Sum mismatch" rootdir/tmp/update.output
++              testfailure aptcache show foo
++              testfailure aptget install foo -s
+               testfailure aptcache show bar
+               testfailure aptget install bar -s
+       done
+ done
index 0000000000000000000000000000000000000000,747418c53872d7ea3b00071f9997646f3fc74833..c2c5b388797d57c9aea4ee0b778fb128859605e8
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,49 +1,44 @@@
 -      TEST='testfailure'
 -      if expr match "$get" '^.*Translation-.*$' >/dev/null; then
 -              TEST='testsuccess'
 -              unset get
 -      fi
 -      $TEST aptget update
 -      cp rootdir/tmp/${TEST}.output rootdir/tmp/update.output
+ #!/bin/sh
+ set -e
+ TESTDIR=$(readlink -f $(dirname $0))
+ . $TESTDIR/framework
+ setupenvironment
+ configarchitecture 'i386'
+ configcompression 'gz'
+ insertpackage 'testing' 'foo' 'all' '1'
+ insertpackage 'testing' 'foo2' 'all' '1'
+ insertsource 'testing' 'foo' 'all' '1'
+ insertsource 'testing' 'foo2' 'all' '1'
+ setupaptarchive --no-update
+ changetowebserver
+ echo 'Package: bar
+ Maintainer: Doctor Evil <evil@example.com>
+ Description: come to the dark side
+ ' > aptarchive/DoctorEvil
+ compressfile aptarchive/DoctorEvil
+ find aptarchive \( -name 'Packages' -o -name 'Sources' -o -name 'Translation-en' \) -delete
+ testsuccess aptget update
+ testsuccess aptcache show foo
+ testsuccess aptget install foo -s
+ for get in $(sed -n 's#^GET /\([^ ]\+\.gz\) HTTP.\+$#\1#p' aptarchive/webserver.log); do
+       msgmsg 'Test hashsum mismatch with file' "$get"
+       rm -rf rootdir/var/lib/apt/lists
+       webserverconfig 'aptwebserver::overwrite' ''
+       webserverconfig "aptwebserver::overwrite::$(printf '%s' "${get}" | sed 's#/#%2F#g' )::filename" '%2FDoctorEvil.gz'
 -      $TEST aptcache show foo
 -      $TEST aptget install foo -s
++      testfailure aptget update
++      cp rootdir/tmp/testfailure.output rootdir/tmp/update.output
+       testsuccess grep -E "$(basename -s '.gz' "$get").*Hash Sum mismatch" rootdir/tmp/update.output
++      testfailure aptcache show foo
++      testfailure aptget install foo -s
+       testfailure aptcache show bar
+       testfailure aptget install bar -s
+ done