+// Acquire::Item::ReportMirrorFailure /*{{{*/
+// ---------------------------------------------------------------------
+void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
+{
+ // we only act if a mirror was used at all
+ if(UsedMirror.empty())
+ return;
+#if 0
+ std::cerr << "\nReportMirrorFailure: "
+ << UsedMirror
+ << " Uri: " << DescURI()
+ << " FailCode: "
+ << FailCode << std::endl;
+#endif
+ const char *Args[40];
+ unsigned int i = 0;
+ string report = _config->Find("Methods::Mirror::ProblemReporting",
+ "/usr/lib/apt/apt-report-mirror-failure");
+ if(!FileExists(report))
+ return;
+ Args[i++] = report.c_str();
+ Args[i++] = UsedMirror.c_str();
+ Args[i++] = DescURI().c_str();
+ Args[i++] = FailCode.c_str();
+ Args[i++] = NULL;
+ pid_t pid = ExecFork();
+ if(pid < 0)
+ {
+ _error->Error("ReportMirrorFailure Fork failed");
+ return;
+ }
+ else if(pid == 0)
+ {
+ execvp(Args[0], (char**)Args);
+ std::cerr << "Could not exec " << Args[0] << std::endl;
+ _exit(100);
+ }
+ if(!ExecWait(pid, "report-mirror-failure"))
+ {
+ _error->Warning("Couldn't report problem to '%s'",
+ _config->Find("Methods::Mirror::ProblemReporting").c_str());
+ }
+}
+ /*}}}*/
+// AcqSubIndex::AcqSubIndex - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* Get the Index file first and see if there are languages available
+ * If so, create a pkgAcqIndexTrans for the found language(s).
+ */
+pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,
+ string const &URIDesc, string const &ShortDesc,
+ HashString const &ExpectedHash)
+ : Item(Owner), ExpectedHash(ExpectedHash)
+{
+ Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
+
+ DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+ DestFile += URItoFileName(URI);
+
+ Desc.URI = URI;
+ Desc.Description = URIDesc;
+ Desc.Owner = this;
+ Desc.ShortDesc = ShortDesc;
+
+ QueueURI(Desc);
+
+ if(Debug)
+ std::clog << "pkgAcqSubIndex: " << Desc.URI << std::endl;
+}
+ /*}}}*/
+// AcqSubIndex::Custom600Headers - Insert custom request headers /*{{{*/
+// ---------------------------------------------------------------------
+/* The only header we use is the last-modified header. */
+string pkgAcqSubIndex::Custom600Headers()
+{
+ string Final = _config->FindDir("Dir::State::lists");
+ Final += URItoFileName(Desc.URI);
+
+ struct stat Buf;
+ if (stat(Final.c_str(),&Buf) != 0)
+ return "\nIndex-File: true\nFail-Ignore: true\n";
+ return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
+}
+ /*}}}*/
+void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
+{
+ if(Debug)
+ std::clog << "pkgAcqSubIndex failed: " << Desc.URI << std::endl;
+
+ Complete = false;
+ Status = StatDone;
+ Dequeue();
+
+ // No good Index is provided, so try guessing
+ std::vector<std::string> langs = APT::Configuration::getLanguages(true);
+ for (std::vector<std::string>::const_iterator l = langs.begin();
+ l != langs.end(); ++l)
+ {
+ if (*l == "none") continue;
+ string const file = "Translation-" + *l;
+ new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file),
+ Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file),
+ file);
+ }
+}
+ /*}}}*/
+void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
+ pkgAcquire::MethodConfig *Cnf)
+{
+ if(Debug)
+ std::clog << "pkgAcqSubIndex::Done(): " << Desc.URI << std::endl;
+
+ string FileName = LookupTag(Message,"Filename");
+ if (FileName.empty() == true)
+ {
+ Status = StatError;
+ ErrorText = "Method gave a blank filename";
+ return;
+ }
+
+ if (FileName != DestFile)
+ {
+ Local = true;
+ Desc.URI = "copy:" + FileName;
+ QueueURI(Desc);
+ return;
+ }
+
+ Item::Done(Message,Size,Md5Hash,Cnf);
+
+ string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
+
+ // sucess in downloading the index
+ // rename the index
+ if(Debug)
+ std::clog << "Renaming: " << DestFile << " -> " << FinalFile << std::endl;
+ Rename(DestFile,FinalFile);
+ chmod(FinalFile.c_str(),0644);
+ DestFile = FinalFile;
+
+ if(ParseIndex(DestFile) == false)
+ return Failed("", NULL);
+
+ Complete = true;
+ Status = StatDone;
+ Dequeue();
+ return;
+}
+ /*}}}*/
+bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/
+{
+ indexRecords SubIndexParser;
+ if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
+ return false;
+
+ std::vector<std::string> lang = APT::Configuration::getLanguages(true);
+ for (std::vector<std::string>::const_iterator l = lang.begin();
+ l != lang.end(); ++l)
+ {
+ if (*l == "none")
+ continue;
+
+ string file = "Translation-" + *l;
+ indexRecords::checkSum const *Record = SubIndexParser.Lookup(file);
+ HashString expected;
+ if (Record == NULL)
+ {
+ // FIXME: the Index file provided by debian currently only includes bz2 records
+ Record = SubIndexParser.Lookup(file + ".bz2");
+ if (Record == NULL)
+ continue;
+ }
+ else
+ {
+ expected = Record->Hash;
+ if (expected.empty() == true)
+ continue;
+ }
+
+ IndexTarget target;
+ target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file);
+ target.MetaKey = file;
+ target.ShortDesc = file;
+ target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file);
+ new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser);
+ }
+ return true;
+}
+ /*}}}*/