You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

725 lines
23 KiB

  1. #include <config.h>
  2. #include <apt-pkg/error.h>
  3. #include <apt-pkg/debmetaindex.h>
  4. #include <apt-pkg/debindexfile.h>
  5. #include <apt-pkg/strutl.h>
  6. #include <apt-pkg/fileutl.h>
  7. #include <apt-pkg/acquire-item.h>
  8. #include <apt-pkg/configuration.h>
  9. #include <apt-pkg/aptconfiguration.h>
  10. #include <apt-pkg/sourcelist.h>
  11. #include <apt-pkg/hashes.h>
  12. #include <apt-pkg/metaindex.h>
  13. #include <apt-pkg/pkgcachegen.h>
  14. #include <apt-pkg/tagfile.h>
  15. #include <apt-pkg/gpgv.h>
  16. #include <apt-pkg/macros.h>
  17. #include <map>
  18. #include <string>
  19. #include <utility>
  20. #include <vector>
  21. #include <set>
  22. #include <algorithm>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <unistd.h>
  26. #include <string.h>
  27. #include <apti18n.h>
  28. class APT_HIDDEN debReleaseIndexPrivate /*{{{*/
  29. {
  30. public:
  31. struct APT_HIDDEN debSectionEntry
  32. {
  33. std::string Name;
  34. std::vector<std::string> Targets;
  35. std::vector<std::string> Architectures;
  36. std::vector<std::string> Languages;
  37. };
  38. std::vector<debSectionEntry> DebEntries;
  39. std::vector<debSectionEntry> DebSrcEntries;
  40. debReleaseIndexPrivate() {}
  41. };
  42. /*}}}*/
  43. // ReleaseIndex::MetaIndex* - display helpers /*{{{*/
  44. std::string debReleaseIndex::MetaIndexInfo(const char *Type) const
  45. {
  46. std::string Info = ::URI::ArchiveOnly(URI) + ' ';
  47. if (Dist[Dist.size() - 1] == '/')
  48. {
  49. if (Dist != "/")
  50. Info += Dist;
  51. }
  52. else
  53. Info += Dist;
  54. Info += " ";
  55. Info += Type;
  56. return Info;
  57. }
  58. std::string debReleaseIndex::Describe() const
  59. {
  60. return MetaIndexInfo("Release");
  61. }
  62. std::string debReleaseIndex::MetaIndexFile(const char *Type) const
  63. {
  64. return _config->FindDir("Dir::State::lists") +
  65. URItoFileName(MetaIndexURI(Type));
  66. }
  67. std::string debReleaseIndex::MetaIndexURI(const char *Type) const
  68. {
  69. std::string Res;
  70. if (Dist == "/")
  71. Res = URI;
  72. else if (Dist[Dist.size()-1] == '/')
  73. Res = URI + Dist;
  74. else
  75. Res = URI + "dists/" + Dist + "/";
  76. Res += Type;
  77. return Res;
  78. }
  79. /*}}}*/
  80. // ReleaseIndex Con- and Destructors /*{{{*/
  81. debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist) :
  82. metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate())
  83. {}
  84. debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const pTrusted) :
  85. metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate())
  86. {
  87. Trusted = pTrusted ? TRI_YES : TRI_NO;
  88. }
  89. debReleaseIndex::~debReleaseIndex() {
  90. if (d != NULL)
  91. delete d;
  92. }
  93. /*}}}*/
  94. // ReleaseIndex::GetIndexTargets /*{{{*/
  95. static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string const &Dist,
  96. std::vector<debReleaseIndexPrivate::debSectionEntry> const &entries,
  97. std::vector<IndexTarget> &IndexTargets)
  98. {
  99. bool const flatArchive = (Dist[Dist.length() - 1] == '/');
  100. std::string baseURI = URI;
  101. if (flatArchive)
  102. {
  103. if (Dist != "/")
  104. baseURI += Dist;
  105. }
  106. else
  107. baseURI += "dists/" + Dist + "/";
  108. std::string const Release = (Dist == "/") ? "" : Dist;
  109. std::string const Site = ::URI::ArchiveOnly(URI);
  110. for (std::vector<debReleaseIndexPrivate::debSectionEntry>::const_iterator E = entries.begin(); E != entries.end(); ++E)
  111. {
  112. for (std::vector<std::string>::const_iterator T = E->Targets.begin(); T != E->Targets.end(); ++T)
  113. {
  114. #define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::") + Type + "::" + *T + "::" + (X))
  115. std::string const tplMetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey");
  116. std::string const tplShortDesc = APT_T_CONFIG("ShortDescription");
  117. std::string const tplLongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description");
  118. bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb-src::") + *T + "::Optional", true);
  119. #undef APT_T_CONFIG
  120. if (tplMetaKey.empty())
  121. continue;
  122. for (std::vector<std::string>::const_iterator L = E->Languages.begin(); L != E->Languages.end(); ++L)
  123. {
  124. if (*L == "none" && tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
  125. continue;
  126. for (std::vector<std::string>::const_iterator A = E->Architectures.begin(); A != E->Architectures.end(); ++A)
  127. {
  128. std::map<std::string, std::string> Options;
  129. Options.insert(std::make_pair("SITE", Site));
  130. Options.insert(std::make_pair("RELEASE", Release));
  131. if (tplMetaKey.find("$(COMPONENT)") != std::string::npos)
  132. Options.insert(std::make_pair("COMPONENT", E->Name));
  133. if (tplMetaKey.find("$(LANGUAGE)") != std::string::npos)
  134. Options.insert(std::make_pair("LANGUAGE", *L));
  135. if (tplMetaKey.find("$(ARCHITECTURE)") != std::string::npos)
  136. Options.insert(std::make_pair("ARCHITECTURE", *A));
  137. Options.insert(std::make_pair("BASE_URI", baseURI));
  138. Options.insert(std::make_pair("REPO_URI", URI));
  139. Options.insert(std::make_pair("TARGET_OF", "deb-src"));
  140. Options.insert(std::make_pair("CREATED_BY", *T));
  141. std::string MetaKey = tplMetaKey;
  142. std::string ShortDesc = tplShortDesc;
  143. std::string LongDesc = tplLongDesc;
  144. for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
  145. {
  146. MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second);
  147. ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second);
  148. LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second);
  149. }
  150. IndexTarget Target(
  151. MetaKey,
  152. ShortDesc,
  153. LongDesc,
  154. Options.find("BASE_URI")->second + MetaKey,
  155. IsOptional,
  156. Options
  157. );
  158. IndexTargets.push_back(Target);
  159. if (tplMetaKey.find("$(ARCHITECTURE)") == std::string::npos)
  160. break;
  161. }
  162. if (tplMetaKey.find("$(LANGUAGE)") == std::string::npos)
  163. break;
  164. }
  165. }
  166. }
  167. }
  168. std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const
  169. {
  170. std::vector<IndexTarget> IndexTargets;
  171. GetIndexTargetsFor("deb-src", URI, Dist, d->DebSrcEntries, IndexTargets);
  172. GetIndexTargetsFor("deb", URI, Dist, d->DebEntries, IndexTargets);
  173. return IndexTargets;
  174. }
  175. /*}}}*/
  176. void debReleaseIndex::AddComponent(bool const isSrc, std::string const &Name,/*{{{*/
  177. std::vector<std::string> const &Targets,
  178. std::vector<std::string> const &Architectures,
  179. std::vector<std::string> Languages)
  180. {
  181. if (Languages.empty() == true)
  182. Languages.push_back("none");
  183. debReleaseIndexPrivate::debSectionEntry const entry = {
  184. Name, Targets, Architectures, Languages
  185. };
  186. if (isSrc)
  187. d->DebSrcEntries.push_back(entry);
  188. else
  189. d->DebEntries.push_back(entry);
  190. }
  191. /*}}}*/
  192. bool debReleaseIndex::Load(std::string const &Filename, std::string * const ErrorText)/*{{{*/
  193. {
  194. LoadedSuccessfully = TRI_NO;
  195. FileFd Fd;
  196. if (OpenMaybeClearSignedFile(Filename, Fd) == false)
  197. return false;
  198. pkgTagFile TagFile(&Fd, Fd.Size());
  199. if (_error->PendingError() == true)
  200. {
  201. if (ErrorText != NULL)
  202. strprintf(*ErrorText, _("Unable to parse Release file %s"),Filename.c_str());
  203. return false;
  204. }
  205. pkgTagSection Section;
  206. const char *Start, *End;
  207. if (TagFile.Step(Section) == false)
  208. {
  209. if (ErrorText != NULL)
  210. strprintf(*ErrorText, _("No sections in Release file %s"), Filename.c_str());
  211. return false;
  212. }
  213. // FIXME: find better tag name
  214. SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false);
  215. Suite = Section.FindS("Suite");
  216. Codename = Section.FindS("Codename");
  217. bool FoundHashSum = false;
  218. for (int i=0;HashString::SupportedHashes()[i] != NULL; i++)
  219. {
  220. if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
  221. continue;
  222. std::string Name;
  223. std::string Hash;
  224. unsigned long long Size;
  225. while (Start < End)
  226. {
  227. if (!parseSumData(Start, End, Name, Hash, Size))
  228. return false;
  229. if (Entries.find(Name) == Entries.end())
  230. {
  231. metaIndex::checkSum *Sum = new metaIndex::checkSum;
  232. Sum->MetaKeyFilename = Name;
  233. Sum->Size = Size;
  234. Sum->Hashes.FileSize(Size);
  235. APT_IGNORE_DEPRECATED(Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);)
  236. Entries[Name] = Sum;
  237. }
  238. Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
  239. FoundHashSum = true;
  240. }
  241. }
  242. if(FoundHashSum == false)
  243. {
  244. if (ErrorText != NULL)
  245. strprintf(*ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
  246. return false;
  247. }
  248. std::string const StrDate = Section.FindS("Date");
  249. if (RFC1123StrToTime(StrDate.c_str(), Date) == false)
  250. {
  251. if (ErrorText != NULL)
  252. strprintf(*ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str());
  253. return false;
  254. }
  255. std::string const Label = Section.FindS("Label");
  256. std::string const StrValidUntil = Section.FindS("Valid-Until");
  257. // if we have a Valid-Until header in the Release file, use it as default
  258. if (StrValidUntil.empty() == false)
  259. {
  260. if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false)
  261. {
  262. if (ErrorText != NULL)
  263. strprintf(*ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str());
  264. return false;
  265. }
  266. }
  267. // get the user settings for this archive and use what expires earlier
  268. int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0);
  269. if (Label.empty() == false)
  270. MaxAge = _config->FindI(("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge);
  271. int MinAge = _config->FindI("Acquire::Min-ValidTime", 0);
  272. if (Label.empty() == false)
  273. MinAge = _config->FindI(("Acquire::Min-ValidTime::" + Label).c_str(), MinAge);
  274. LoadedSuccessfully = TRI_YES;
  275. if(MaxAge == 0 &&
  276. (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file
  277. return true;
  278. if (MinAge != 0 && ValidUntil != 0) {
  279. time_t const min_date = Date + MinAge;
  280. if (ValidUntil < min_date)
  281. ValidUntil = min_date;
  282. }
  283. if (MaxAge != 0) {
  284. time_t const max_date = Date + MaxAge;
  285. if (ValidUntil == 0 || ValidUntil > max_date)
  286. ValidUntil = max_date;
  287. }
  288. return true;
  289. }
  290. /*}}}*/
  291. metaIndex * debReleaseIndex::UnloadedClone() const /*{{{*/
  292. {
  293. if (Trusted == TRI_NO)
  294. return new debReleaseIndex(URI, Dist, false);
  295. else if (Trusted == TRI_YES)
  296. return new debReleaseIndex(URI, Dist, true);
  297. else
  298. return new debReleaseIndex(URI, Dist);
  299. }
  300. /*}}}*/
  301. bool debReleaseIndex::parseSumData(const char *&Start, const char *End, /*{{{*/
  302. std::string &Name, std::string &Hash, unsigned long long &Size)
  303. {
  304. Name = "";
  305. Hash = "";
  306. Size = 0;
  307. /* Skip over the first blank */
  308. while ((*Start == '\t' || *Start == ' ' || *Start == '\n' || *Start == '\r')
  309. && Start < End)
  310. Start++;
  311. if (Start >= End)
  312. return false;
  313. /* Move EntryEnd to the end of the first entry (the hash) */
  314. const char *EntryEnd = Start;
  315. while ((*EntryEnd != '\t' && *EntryEnd != ' ')
  316. && EntryEnd < End)
  317. EntryEnd++;
  318. if (EntryEnd == End)
  319. return false;
  320. Hash.append(Start, EntryEnd-Start);
  321. /* Skip over intermediate blanks */
  322. Start = EntryEnd;
  323. while (*Start == '\t' || *Start == ' ')
  324. Start++;
  325. if (Start >= End)
  326. return false;
  327. EntryEnd = Start;
  328. /* Find the end of the second entry (the size) */
  329. while ((*EntryEnd != '\t' && *EntryEnd != ' ' )
  330. && EntryEnd < End)
  331. EntryEnd++;
  332. if (EntryEnd == End)
  333. return false;
  334. Size = strtoull (Start, NULL, 10);
  335. /* Skip over intermediate blanks */
  336. Start = EntryEnd;
  337. while (*Start == '\t' || *Start == ' ')
  338. Start++;
  339. if (Start >= End)
  340. return false;
  341. EntryEnd = Start;
  342. /* Find the end of the third entry (the filename) */
  343. while ((*EntryEnd != '\t' && *EntryEnd != ' ' &&
  344. *EntryEnd != '\n' && *EntryEnd != '\r')
  345. && EntryEnd < End)
  346. EntryEnd++;
  347. Name.append(Start, EntryEnd-Start);
  348. Start = EntryEnd; //prepare for the next round
  349. return true;
  350. }
  351. /*}}}*/
  352. bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/
  353. {
  354. std::vector<IndexTarget> const targets = GetIndexTargets();
  355. #define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map<std::string,std::string>())
  356. pkgAcqMetaClearSig * const TransactionManager = new pkgAcqMetaClearSig(Owner,
  357. APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"),
  358. targets, this);
  359. #undef APT_TARGET
  360. // special case for --print-uris
  361. if (GetAll)
  362. {
  363. for (std::vector<IndexTarget>::const_iterator Target = targets.begin(); Target != targets.end(); ++Target)
  364. new pkgAcqIndex(Owner, TransactionManager, *Target);
  365. }
  366. return true;
  367. }
  368. /*}}}*/
  369. // ReleaseIndex::IsTrusted /*{{{*/
  370. bool debReleaseIndex::SetTrusted(TriState const pTrusted)
  371. {
  372. if (Trusted == TRI_UNSET)
  373. Trusted = pTrusted;
  374. else if (Trusted != pTrusted)
  375. // TRANSLATOR: The first is an option name from sources.list manpage, the other two URI and Suite
  376. return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Trusted", URI.c_str(), Dist.c_str());
  377. return true;
  378. }
  379. bool debReleaseIndex::IsTrusted() const
  380. {
  381. if (Trusted == TRI_YES)
  382. return true;
  383. else if (Trusted == TRI_NO)
  384. return false;
  385. if(_config->FindB("APT::Authentication::TrustCDROM", false))
  386. if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
  387. return true;
  388. if (FileExists(MetaIndexFile("Release.gpg")))
  389. return true;
  390. return FileExists(MetaIndexFile("InRelease"));
  391. }
  392. /*}}}*/
  393. std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() /*{{{*/
  394. {
  395. if (Indexes != NULL)
  396. return Indexes;
  397. Indexes = new std::vector<pkgIndexFile*>();
  398. std::vector<IndexTarget> const Targets = GetIndexTargets();
  399. bool const istrusted = IsTrusted();
  400. for (std::vector<IndexTarget>::const_iterator T = Targets.begin(); T != Targets.end(); ++T)
  401. {
  402. std::string const TargetName = T->Option(IndexTarget::CREATED_BY);
  403. if (TargetName == "Packages")
  404. Indexes->push_back(new debPackagesIndex(*T, istrusted));
  405. else if (TargetName == "Sources")
  406. Indexes->push_back(new debSourcesIndex(*T, istrusted));
  407. else if (TargetName == "Translations")
  408. Indexes->push_back(new debTranslationsIndex(*T));
  409. }
  410. return Indexes;
  411. }
  412. /*}}}*/
  413. static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile)/*{{{*/
  414. {
  415. ReleaseFile = That->MetaIndexFile("InRelease");
  416. bool releaseExists = false;
  417. if (FileExists(ReleaseFile) == true)
  418. releaseExists = true;
  419. else
  420. {
  421. ReleaseFile = That->MetaIndexFile("Release");
  422. if (FileExists(ReleaseFile))
  423. releaseExists = true;
  424. }
  425. return releaseExists;
  426. }
  427. /*}}}*/
  428. bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/
  429. {
  430. std::string ReleaseFile;
  431. bool const releaseExists = ReleaseFileName(this, ReleaseFile);
  432. ::URI Tmp(URI);
  433. if (Gen.SelectReleaseFile(ReleaseFile, Tmp.Host) == false)
  434. return _error->Error("Problem with SelectReleaseFile %s", ReleaseFile.c_str());
  435. if (releaseExists == false)
  436. return true;
  437. FileFd Rel;
  438. // Beware: The 'Release' file might be clearsigned in case the
  439. // signature for an 'InRelease' file couldn't be checked
  440. if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
  441. return false;
  442. if (_error->PendingError() == true)
  443. return false;
  444. // Store the IMS information
  445. pkgCache::RlsFileIterator File = Gen.GetCurRlsFile();
  446. pkgCacheGenerator::Dynamic<pkgCache::RlsFileIterator> DynFile(File);
  447. // Rel can't be used as this is potentially a temporary file
  448. struct stat Buf;
  449. if (stat(ReleaseFile.c_str(), &Buf) != 0)
  450. return _error->Errno("fstat", "Unable to stat file %s", ReleaseFile.c_str());
  451. File->Size = Buf.st_size;
  452. File->mtime = Buf.st_mtime;
  453. pkgTagFile TagFile(&Rel, Rel.Size());
  454. pkgTagSection Section;
  455. if (_error->PendingError() == true || TagFile.Step(Section) == false)
  456. return false;
  457. std::string data;
  458. #define APT_INRELEASE(TYPE, TAG, STORE) \
  459. data = Section.FindS(TAG); \
  460. if (data.empty() == false) \
  461. { \
  462. map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::TYPE, data); \
  463. STORE = storage; \
  464. }
  465. APT_INRELEASE(MIXED, "Suite", File->Archive)
  466. APT_INRELEASE(VERSIONNUMBER, "Version", File->Version)
  467. APT_INRELEASE(MIXED, "Origin", File->Origin)
  468. APT_INRELEASE(MIXED, "Codename", File->Codename)
  469. APT_INRELEASE(MIXED, "Label", File->Label)
  470. #undef APT_INRELEASE
  471. Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic);
  472. Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades);
  473. return !_error->PendingError();
  474. }
  475. /*}}}*/
  476. // ReleaseIndex::FindInCache - Find this index /*{{{*/
  477. pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool const ModifyCheck) const
  478. {
  479. std::string ReleaseFile;
  480. bool const releaseExists = ReleaseFileName(this, ReleaseFile);
  481. pkgCache::RlsFileIterator File = Cache.RlsFileBegin();
  482. for (; File.end() == false; ++File)
  483. {
  484. if (File->FileName == 0 || ReleaseFile != File.FileName())
  485. continue;
  486. // empty means the file does not exist by "design"
  487. if (ModifyCheck == false || (releaseExists == false && File->Size == 0))
  488. return File;
  489. struct stat St;
  490. if (stat(File.FileName(),&St) != 0)
  491. {
  492. if (_config->FindB("Debug::pkgCacheGen", false))
  493. std::clog << "ReleaseIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  494. return pkgCache::RlsFileIterator(Cache);
  495. }
  496. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  497. {
  498. if (_config->FindB("Debug::pkgCacheGen", false))
  499. std::clog << "ReleaseIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  500. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  501. << ") doesn't match for " << File.FileName() << std::endl;
  502. return pkgCache::RlsFileIterator(Cache);
  503. }
  504. return File;
  505. }
  506. return File;
  507. }
  508. /*}}}*/
  509. static std::vector<std::string> parsePlusMinusOptions(std::string const &Name, /*{{{*/
  510. std::map<std::string, std::string> const &Options, std::vector<std::string> const &defaultValues)
  511. {
  512. std::map<std::string, std::string>::const_iterator val = Options.find(Name);
  513. std::vector<std::string> Values;
  514. if (val != Options.end())
  515. Values = VectorizeString(val->second, ',');
  516. else
  517. Values = defaultValues;
  518. if ((val = Options.find(Name + "+")) != Options.end())
  519. {
  520. std::vector<std::string> const plusArch = VectorizeString(val->second, ',');
  521. for (std::vector<std::string>::const_iterator plus = plusArch.begin(); plus != plusArch.end(); ++plus)
  522. if (std::find(Values.begin(), Values.end(), *plus) == Values.end())
  523. Values.push_back(*plus);
  524. }
  525. if ((val = Options.find(Name + "-")) != Options.end())
  526. {
  527. std::vector<std::string> const minusArch = VectorizeString(val->second, ',');
  528. for (std::vector<std::string>::const_iterator minus = minusArch.begin(); minus != minusArch.end(); ++minus)
  529. {
  530. std::vector<std::string>::iterator kill = std::find(Values.begin(), Values.end(), *minus);
  531. if (kill != Values.end())
  532. Values.erase(kill);
  533. }
  534. }
  535. return Values;
  536. }
  537. /*}}}*/
  538. class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
  539. {
  540. protected:
  541. bool CreateItemInternal(std::vector<metaIndex *> &List, std::string const &URI,
  542. std::string const &Dist, std::string const &Section,
  543. bool const &IsSrc, std::map<std::string, std::string> const &Options) const
  544. {
  545. debReleaseIndex *Deb = NULL;
  546. for (std::vector<metaIndex *>::const_iterator I = List.begin();
  547. I != List.end(); ++I)
  548. {
  549. // We only worry about debian entries here
  550. if (strcmp((*I)->GetType(), "deb") != 0)
  551. continue;
  552. /* This check insures that there will be only one Release file
  553. queued for all the Packages files and Sources files it
  554. corresponds to. */
  555. if ((*I)->GetURI() == URI && (*I)->GetDist() == Dist)
  556. {
  557. Deb = dynamic_cast<debReleaseIndex*>(*I);
  558. if (Deb != NULL)
  559. break;
  560. }
  561. }
  562. // No currently created Release file indexes this entry, so we create a new one.
  563. if (Deb == NULL)
  564. {
  565. Deb = new debReleaseIndex(URI, Dist);
  566. List.push_back(Deb);
  567. }
  568. Deb->AddComponent(
  569. IsSrc,
  570. Section,
  571. parsePlusMinusOptions("target", Options, _config->FindVector(std::string("APT::Acquire::Targets::") + Name, "", true)),
  572. parsePlusMinusOptions("arch", Options, APT::Configuration::getArchitectures()),
  573. parsePlusMinusOptions("lang", Options, APT::Configuration::getLanguages(true))
  574. );
  575. std::map<std::string, std::string>::const_iterator const trusted = Options.find("trusted");
  576. if (trusted != Options.end())
  577. {
  578. if (Deb->SetTrusted(StringToBool(trusted->second, false) ? debReleaseIndex::TRI_YES : debReleaseIndex::TRI_NO) == false)
  579. return false;
  580. }
  581. else if (Deb->SetTrusted(debReleaseIndex::TRI_DONTCARE) == false)
  582. return false;
  583. return true;
  584. }
  585. debSLTypeDebian(char const * const Name, char const * const Label) : Type(Name, Label)
  586. {
  587. }
  588. };
  589. /*}}}*/
  590. class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian /*{{{*/
  591. {
  592. public:
  593. bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
  594. std::string const &Dist, std::string const &Section,
  595. std::map<std::string, std::string> const &Options) const
  596. {
  597. return CreateItemInternal(List, URI, Dist, Section, false, Options);
  598. }
  599. debSLTypeDeb() : debSLTypeDebian("deb", "Debian binary tree")
  600. {
  601. }
  602. };
  603. /*}}}*/
  604. class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian /*{{{*/
  605. {
  606. public:
  607. bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
  608. std::string const &Dist, std::string const &Section,
  609. std::map<std::string, std::string> const &Options) const
  610. {
  611. return CreateItemInternal(List, URI, Dist, Section, true, Options);
  612. }
  613. debSLTypeDebSrc() : debSLTypeDebian("deb-src", "Debian source tree")
  614. {
  615. }
  616. };
  617. /*}}}*/
  618. debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile) /*{{{*/
  619. : metaIndex(DebFile, "local-uri", "deb-dist"), d(NULL), DebFile(DebFile)
  620. {
  621. DebIndex = new debDebPkgFileIndex(DebFile);
  622. Indexes = new std::vector<pkgIndexFile *>();
  623. Indexes->push_back(DebIndex);
  624. }
  625. debDebFileMetaIndex::~debDebFileMetaIndex() {}
  626. /*}}}*/
  627. class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type /*{{{*/
  628. {
  629. public:
  630. bool CreateItem(std::vector<metaIndex *> &List, std::string const &URI,
  631. std::string const &/*Dist*/, std::string const &/*Section*/,
  632. std::map<std::string, std::string> const &/*Options*/) const
  633. {
  634. metaIndex *mi = new debDebFileMetaIndex(URI);
  635. List.push_back(mi);
  636. return true;
  637. }
  638. debSLTypeDebFile() : Type("deb-file", "Debian local deb file")
  639. {
  640. }
  641. };
  642. /*}}}*/
  643. APT_HIDDEN debSLTypeDeb _apt_DebType;
  644. APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType;
  645. APT_HIDDEN debSLTypeDebFile _apt_DebFileType;