+ /* We need to find a filename to determine the extension. We make the
+ assumption here that all the available sources for this version share
+ the same extension.. */
+ // Skip not source sources, they do not have file fields.
+ for (; Vf.end() == false; Vf++)
+ {
+ if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0)
+ continue;
+ break;
+ }
+
+ // Does not really matter here.. we are going to fail out below
+ if (Vf.end() != true)
+ {
+ // If this fails to get a file name we will bomb out below.
+ pkgRecords::Parser &Parse = Recs->Lookup(Vf);
+ if (_error->PendingError() == true)
+ return;
+
+ // Generate the final file name as: package_version_arch.foo
+ StoreFilename = QuoteString(Version.ParentPkg().Name(),"_:") + '_' +
+ QuoteString(Version.VerStr(),"_:") + '_' +
+ QuoteString(Version.Arch(),"_:.") +
+ "." + flExtension(Parse.FileName());
+ }
+
+ // check if we have one trusted source for the package. if so, switch
+ // to "TrustedOnly" mode
+ for (pkgCache::VerFileIterator i = Version.FileList(); i.end() == false; i++)
+ {
+ pkgIndexFile *Index;
+ if (Sources->FindIndex(i.File(),Index) == false)
+ continue;
+ if (_config->FindB("Debug::pkgAcquire::Auth", false))
+ {
+ std::cerr << "Checking index: " << Index->Describe()
+ << "(Trusted=" << Index->IsTrusted() << ")\n";
+ }
+ if (Index->IsTrusted()) {
+ Trusted = true;
+ break;
+ }
+ }
+
+ // Select a source
+ if (QueueNext() == false && _error->PendingError() == false)
+ _error->Error(_("I wasn't able to locate file for the %s package. "
+ "This might mean you need to manually fix this package."),
+ Version.ParentPkg().Name());
+}
+ /*}}}*/
+// AcqArchive::QueueNext - Queue the next file source /*{{{*/
+// ---------------------------------------------------------------------
+/* This queues the next available file version for download. It checks if
+ the archive is already available in the cache and stashs the MD5 for
+ checking later. */
+bool pkgAcqArchive::QueueNext()
+{
+ for (; Vf.end() == false; Vf++)
+ {
+ // Ignore not source sources
+ if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0)
+ continue;
+
+ // Try to cross match against the source list
+ pkgIndexFile *Index;
+ if (Sources->FindIndex(Vf.File(),Index) == false)
+ continue;
+
+ // only try to get a trusted package from another source if that source
+ // is also trusted
+ if(Trusted && !Index->IsTrusted())
+ continue;
+
+ // Grab the text package record
+ pkgRecords::Parser &Parse = Recs->Lookup(Vf);
+ if (_error->PendingError() == true)
+ return false;
+
+ string PkgFile = Parse.FileName();
+ MD5 = Parse.MD5Hash();
+ if (PkgFile.empty() == true)
+ return _error->Error(_("The package index files are corrupted. No Filename: "
+ "field for package %s."),
+ Version.ParentPkg().Name());
+
+ Desc.URI = Index->ArchiveURI(PkgFile);
+ Desc.Description = Index->ArchiveInfo(Version);
+ Desc.Owner = this;
+ Desc.ShortDesc = Version.ParentPkg().Name();
+
+ // See if we already have the file. (Legacy filenames)
+ FileSize = Version->Size;
+ string FinalFile = _config->FindDir("Dir::Cache::Archives") + flNotDir(PkgFile);
+ struct stat Buf;
+ if (stat(FinalFile.c_str(),&Buf) == 0)
+ {
+ // Make sure the size matches
+ if ((unsigned)Buf.st_size == Version->Size)
+ {
+ Complete = true;
+ Local = true;
+ Status = StatDone;
+ StoreFilename = DestFile = FinalFile;
+ return true;
+ }
+
+ /* Hmm, we have a file and its size does not match, this means it is
+ an old style mismatched arch */
+ unlink(FinalFile.c_str());
+ }
+
+ // Check it again using the new style output filenames
+ FinalFile = _config->FindDir("Dir::Cache::Archives") + flNotDir(StoreFilename);
+ if (stat(FinalFile.c_str(),&Buf) == 0)
+ {
+ // Make sure the size matches
+ if ((unsigned)Buf.st_size == Version->Size)
+ {
+ Complete = true;
+ Local = true;
+ Status = StatDone;
+ StoreFilename = DestFile = FinalFile;
+ return true;
+ }
+
+ /* Hmm, we have a file and its size does not match, this shouldnt
+ happen.. */
+ unlink(FinalFile.c_str());
+ }
+
+ DestFile = _config->FindDir("Dir::Cache::Archives") + "partial/" + flNotDir(StoreFilename);
+
+ // Check the destination file
+ if (stat(DestFile.c_str(),&Buf) == 0)
+ {
+ // Hmm, the partial file is too big, erase it
+ if ((unsigned)Buf.st_size > Version->Size)
+ unlink(DestFile.c_str());
+ else
+ PartialSize = Buf.st_size;
+ }
+
+ // Create the item
+ Local = false;
+ Desc.URI = Index->ArchiveURI(PkgFile);
+ Desc.Description = Index->ArchiveInfo(Version);
+ Desc.Owner = this;
+ Desc.ShortDesc = Version.ParentPkg().Name();
+ QueueURI(Desc);
+
+ Vf++;
+ return true;
+ }
+ return false;
+}
+ /*}}}*/
+// AcqArchive::Done - Finished fetching /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
+ pkgAcquire::MethodConfig *Cfg)
+{
+ Item::Done(Message,Size,Md5Hash,Cfg);
+
+ // Check the size
+ if (Size != Version->Size)
+ {
+ Status = StatError;
+ ErrorText = _("Size mismatch");
+ return;
+ }
+
+ // Check the md5
+ if (Md5Hash.empty() == false && MD5.empty() == false)
+ {
+ if (Md5Hash != MD5)
+ {
+ Status = StatError;
+ ErrorText = _("MD5Sum mismatch");
+ Rename(DestFile,DestFile + ".FAILED");
+ return;
+ }
+ }
+
+ // Grab the output filename
+ string FileName = LookupTag(Message,"Filename");
+ if (FileName.empty() == true)
+ {
+ Status = StatError;
+ ErrorText = "Method gave a blank filename";
+ return;
+ }
+
+ Complete = true;
+
+ // Reference filename