Browse Source

use pkgAcqArchive in 'download' for proper errors

With a bit of trickery we can reuse the usual infrastructure we have in
place to acquire deb files for the 'download' operation as well, which
gains us authentification check & display, error messages, correct
filenames and "downloads" from the root-owned archives.
David Kalnischkies 12 years ago
parent
commit
d57f6084aa

+ 2 - 3
apt-pkg/acquire-item.cc

@@ -1768,9 +1768,8 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources,
 
    // Select a source
    if (QueueNext() == false && _error->PendingError() == false)
-      _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());
+      _error->Error(_("Can't find a source to download version '%s' of '%s'"),
+		    Version.VerStr(), Version.ParentPkg().FullName(false).c_str());
 }
 									/*}}}*/
 // AcqArchive::QueueNext - Queue the next file source			/*{{{*/

+ 35 - 45
cmdline/apt-get.cc

@@ -525,7 +525,7 @@ bool DoDownload(CommandLine &CmdL)
    CacheFile Cache;
    if (Cache.ReadOnlyOpen() == false)
       return false;
-   
+
    APT::CacheSetHelper helper(c0out);
    APT::VersionList verset = APT::VersionList::FromCommandLine(Cache,
 		CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper);
@@ -533,67 +533,57 @@ bool DoDownload(CommandLine &CmdL)
    if (verset.empty() == true)
       return false;
 
+   AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0));
    pkgAcquire Fetcher;
-   AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
-   if (_config->FindB("APT::Get::Print-URIs") == false)
-      Fetcher.Setup(&Stat);
+   if (Fetcher.Setup(&Stat) == false)
+      return false;
 
    pkgRecords Recs(Cache);
    pkgSourceList *SrcList = Cache.GetSourceList();
-   bool gotAll = true;
 
-   for (APT::VersionList::const_iterator Ver = verset.begin(); 
-        Ver != verset.end(); 
-        ++Ver) 
+   // reuse the usual acquire methods for deb files, but don't drop them into
+   // the usual directories - keep everything in the current directory
+   std::vector<std::string> storefile(verset.size());
+   std::string const cwd = SafeGetCWD();
+   _config->Set("Dir::Cache::Archives", cwd);
+   int i = 0;
+   for (APT::VersionList::const_iterator Ver = verset.begin();
+	 Ver != verset.end(); ++Ver, ++i)
    {
-      string descr;
-      // get the right version
-      pkgCache::PkgIterator Pkg = Ver.ParentPkg();
-      pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList());
-      pkgCache::VerFileIterator Vf = Ver.FileList();
-      if (Vf.end() == true)
-      {
-	 _error->Error("Can not find VerFile for %s in version %s", Pkg.FullName().c_str(), Ver.VerStr());
-	 gotAll = false;
-	 continue;
-      }
-      pkgCache::PkgFileIterator F = Vf.File();
-      pkgIndexFile *index;
-      if(SrcList->FindIndex(F, index) == false)
-      {
-	 _error->Error(_("Can't find a source to download version '%s' of '%s'"), Ver.VerStr(), Pkg.FullName().c_str());
-	 gotAll = false;
-	 continue;
-      }
-      string uri = index->ArchiveURI(rec.FileName());
-      strprintf(descr, _("Downloading %s %s"), Pkg.Name(), Ver.VerStr());
-      // get the most appropriate hash
-      HashString hash;
-      if (rec.SHA512Hash() != "")
-         hash = HashString("sha512", rec.SHA512Hash());
-      else if (rec.SHA256Hash() != "")
-         hash = HashString("sha256", rec.SHA256Hash());
-      else if (rec.SHA1Hash() != "")
-         hash = HashString("sha1", rec.SHA1Hash());
-      else if (rec.MD5Hash() != "")
-         hash = HashString("md5", rec.MD5Hash());
-      // get the file
-      new pkgAcqFile(&Fetcher, uri, hash.toStr(), (*Ver)->Size, descr, Pkg.Name(), ".");
+      pkgAcquire::Item *I = new pkgAcqArchive(&Fetcher, SrcList, &Recs, *Ver, storefile[i]);
+      std::string const filename = cwd + flNotDir(storefile[i]);
+      storefile[i].assign(filename);
+      I->DestFile.assign(filename);
    }
-   if (gotAll == false)
-      return false;
 
    // Just print out the uris and exit if the --print-uris flag was used
    if (_config->FindB("APT::Get::Print-URIs") == true)
    {
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); ++I)
-	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
+	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
 	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
    }
 
-   return (Fetcher.Run() == pkgAcquire::Continue);
+   if (_error->PendingError() == true || CheckAuth(Fetcher, false) == false)
+      return false;
+
+   bool Failed = false;
+   if (AcquireRun(Fetcher, 0, &Failed, NULL) == false)
+      return false;
+
+   // copy files in local sources to the current directory
+   for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
+      if ((*I)->Local == true && (*I)->Status == pkgAcquire::Item::StatDone)
+      {
+	 std::string const filename = cwd + flNotDir((*I)->DestFile);
+	 std::ifstream src((*I)->DestFile.c_str(), std::ios::binary);
+	 std::ofstream dst(filename.c_str(), std::ios::binary);
+	 dst << src.rdbuf();
+      }
+
+   return Failed == false;
 }
 									/*}}}*/
 // DoCheck - Perform the check operation				/*{{{*/

+ 2 - 1
test/integration/test-apt-get-download

@@ -20,13 +20,14 @@ testdownload() {
 	fi
 	msgtest "Test download of package file $1 with" "$APT"
 	aptget -qq download ${APT} && test -f $1 && msgpass || msgfail
+	rm $1
 }
 
 testdownload apt_1.0_all.deb apt stable
 testdownload apt_2.0_all.deb apt
 
 DEBFILE="$(readlink -f aptarchive)/pool/apt_2.0_all.deb"
-testequal "'file://${DEBFILE}' apt_2.0_all.deb $(stat -c%s $DEBFILE) sha512:$(sha512sum $DEBFILE | cut -d' ' -f 1)" aptget download apt --print-uris
+testequal "'file://${DEBFILE}' apt_2.0_all.deb $(stat -c%s $DEBFILE) SHA512:$(sha512sum $DEBFILE | cut -d' ' -f 1)" aptget download apt --print-uris
 
 # deb:677887
 testequal "E: Can't find a source to download version '1.0' of 'vrms:i386'" aptget download vrms

+ 20 - 9
test/integration/test-bug-617690-allow-unauthenticated-makes-all-untrusted

@@ -26,17 +26,26 @@ testrun() {
 	rm -rf rootdir/var/lib/apt
 	testsuccess aptget update
 
-	testsuccess aptget download cool
-	testfileexists 'cool_1.0_i386.deb'
+	if [ "$1" = 'trusted' ]; then
+		testsuccess aptget download cool
+		testfileexists 'cool_1.0_i386.deb'
+
+		testsuccess aptget download cool --allow-unauthenticated
+		testfileexists 'cool_1.0_i386.deb'
+	else
+		testfailure aptget download cool
+		testfilemissing 'cool_1.0_i386.deb'
+
+		testsuccess aptget download cool --allow-unauthenticated
+		testfileexists 'cool_1.0_i386.deb'
+	fi
 
 	mv aptarchive/pool/cool_1.0_i386.deb aptarchive/pool/cool_1.0_i386.deb.bak
 	echo 'this is not a good package' > aptarchive/pool/cool_1.0_i386.deb
-	# FIXME: apt-get download should exit non-zero if download fails
-	aptget download cool
+	testfailure aptget download cool
 	testfilemissing cool_1.0_i386.deb
 
-	# FIXME: apt-get download should exit non-zero if download fails
-	aptget download cool --allow-unauthenticated  # unauthenticated doesn't mean unchecked
+	testfailure aptget download cool --allow-unauthenticated  # unauthenticated doesn't mean unchecked
 	testfilemissing cool_1.0_i386.deb
 
 	rm -f aptarchive/pool/cool_1.0_i386.deb
@@ -45,8 +54,10 @@ testrun() {
 	testfileexists 'cool_1.0_i386.deb'
 }
 
-testrun
+testrun 'trusted'
 
 find aptarchive/ \( -name 'Release.gpg' -o -name 'InRelease' \) -delete
-# FIXME: apt-get download should warn about untrusted downloads
-testrun
+testrun 'untrusted'
+
+changetowebserver
+testrun 'untrusted'

+ 1 - 1
test/integration/test-bug-722207-print-uris-even-if-very-quiet

@@ -19,7 +19,7 @@ APTARCHIVE=$(readlink -f ./aptarchive)
 testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 MD5Sum:" aptget upgrade -qq --print-uris
 testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 MD5Sum:" aptget dist-upgrade -qq --print-uris
 testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 MD5Sum:" aptget install apt -qq --print-uris
-testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 :" aptget download apt -qq --print-uris
+testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 MD5Sum:" aptget download apt -qq --print-uris
 testequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e
 'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt -qq --print-uris
 testequal "'http://packages.debian.org/changelogs/pool/main/apt/apt_2/changelog'" aptget changelog apt -qq --print-uris