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.
 
 
 
 
 
 

512 lines
15 KiB

  1. #include <config.h>
  2. #include <apt-pkg/debmetaindex.h>
  3. #include <apt-pkg/debindexfile.h>
  4. #include <apt-pkg/strutl.h>
  5. #include <apt-pkg/fileutl.h>
  6. #include <apt-pkg/acquire-item.h>
  7. #include <apt-pkg/configuration.h>
  8. #include <apt-pkg/aptconfiguration.h>
  9. #include <apt-pkg/indexrecords.h>
  10. #include <apt-pkg/sourcelist.h>
  11. #include <apt-pkg/hashes.h>
  12. #include <apt-pkg/macros.h>
  13. #include <apt-pkg/metaindex.h>
  14. #include <string.h>
  15. #include <map>
  16. #include <string>
  17. #include <utility>
  18. #include <vector>
  19. #include <set>
  20. #include <algorithm>
  21. using namespace std;
  22. string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const
  23. {
  24. string Info = ::URI::SiteOnly(URI) + ' ';
  25. if (Dist[Dist.size() - 1] == '/')
  26. {
  27. if (Dist != "/")
  28. Info += Dist;
  29. }
  30. else
  31. {
  32. Info += Dist + '/' + Section;
  33. if (Arch.empty() != true)
  34. Info += " " + Arch;
  35. }
  36. Info += " ";
  37. Info += Type;
  38. return Info;
  39. }
  40. string debReleaseIndex::MetaIndexInfo(const char *Type) const
  41. {
  42. string Info = ::URI::SiteOnly(URI) + ' ';
  43. if (Dist[Dist.size() - 1] == '/')
  44. {
  45. if (Dist != "/")
  46. Info += Dist;
  47. }
  48. else
  49. Info += Dist;
  50. Info += " ";
  51. Info += Type;
  52. return Info;
  53. }
  54. string debReleaseIndex::MetaIndexFile(const char *Type) const
  55. {
  56. return _config->FindDir("Dir::State::lists") +
  57. URItoFileName(MetaIndexURI(Type));
  58. }
  59. string debReleaseIndex::MetaIndexURI(const char *Type) const
  60. {
  61. string Res;
  62. if (Dist == "/")
  63. Res = URI;
  64. else if (Dist[Dist.size()-1] == '/')
  65. Res = URI + Dist;
  66. else
  67. Res = URI + "dists/" + Dist + "/";
  68. Res += Type;
  69. return Res;
  70. }
  71. #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
  72. std::string debReleaseIndex::LocalFileName() const
  73. {
  74. // see if we have a InRelease file
  75. std::string PathInRelease = MetaIndexFile("InRelease");
  76. if (FileExists(PathInRelease))
  77. return PathInRelease;
  78. // and if not return the normal one
  79. if (FileExists(PathInRelease))
  80. return MetaIndexFile("Release");
  81. return "";
  82. }
  83. #endif
  84. string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const
  85. {
  86. string Res ="";
  87. if (Dist[Dist.size() - 1] != '/')
  88. {
  89. if (Arch == "native")
  90. Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/';
  91. else
  92. Res += Section + "/binary-" + Arch + '/';
  93. }
  94. return Res + Type;
  95. }
  96. string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const
  97. {
  98. if (Dist[Dist.size() - 1] == '/')
  99. {
  100. string Res;
  101. if (Dist != "/")
  102. Res = URI + Dist;
  103. else
  104. Res = URI;
  105. return Res + Type;
  106. }
  107. else
  108. return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section, Arch);
  109. }
  110. string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const
  111. {
  112. string Res ="";
  113. if (Dist[Dist.size() - 1] != '/')
  114. Res += Section + "/source/";
  115. return Res + Type;
  116. }
  117. string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const
  118. {
  119. string Res;
  120. if (Dist[Dist.size() - 1] == '/')
  121. {
  122. if (Dist != "/")
  123. Res = URI + Dist;
  124. else
  125. Res = URI;
  126. return Res + Type;
  127. }
  128. else
  129. return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
  130. }
  131. string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const
  132. {
  133. string Res ="";
  134. if (Dist[Dist.size() - 1] != '/')
  135. Res += Section + "/i18n/Translation-";
  136. return Res + Type;
  137. }
  138. string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const
  139. {
  140. string Res;
  141. if (Dist[Dist.size() - 1] == '/')
  142. {
  143. if (Dist != "/")
  144. Res = URI + Dist;
  145. else
  146. Res = URI;
  147. return Res + Type;
  148. }
  149. else
  150. return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section);
  151. }
  152. debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) :
  153. metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST)
  154. {}
  155. debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) :
  156. metaIndex(URI, Dist, "deb") {
  157. SetTrusted(Trusted);
  158. }
  159. debReleaseIndex::~debReleaseIndex() {
  160. for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin();
  161. A != ArchEntries.end(); ++A)
  162. for (vector<const debSectionEntry *>::const_iterator S = A->second.begin();
  163. S != A->second.end(); ++S)
  164. delete *S;
  165. }
  166. vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
  167. vector <IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
  168. map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
  169. if (src != ArchEntries.end()) {
  170. vector<debSectionEntry const*> const SectionEntries = src->second;
  171. for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
  172. I != SectionEntries.end(); ++I) {
  173. IndexTarget * Target = new IndexTarget();
  174. Target->ShortDesc = "Sources";
  175. Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
  176. Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section);
  177. Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
  178. IndexTargets->push_back (Target);
  179. }
  180. }
  181. // Only source release
  182. if (IndexTargets->empty() == false && ArchEntries.size() == 1)
  183. return IndexTargets;
  184. std::set<std::string> sections;
  185. for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
  186. a != ArchEntries.end(); ++a) {
  187. if (a->first == "source")
  188. continue;
  189. for (vector <const debSectionEntry *>::const_iterator I = a->second.begin();
  190. I != a->second.end(); ++I) {
  191. IndexTarget * Target = new IndexTarget();
  192. Target->ShortDesc = "Packages";
  193. Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first);
  194. Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first);
  195. Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first);
  196. IndexTargets->push_back (Target);
  197. sections.insert((*I)->Section);
  198. }
  199. }
  200. std::vector<std::string> lang = APT::Configuration::getLanguages(true);
  201. std::vector<std::string>::iterator lend = std::remove(lang.begin(), lang.end(), "none");
  202. if (lend != lang.end())
  203. lang.erase(lend);
  204. if (lang.empty() == true)
  205. return IndexTargets;
  206. // get the Translation-* files, later we will skip download of non-existent if we have an index
  207. for (std::set<std::string>::const_iterator s = sections.begin();
  208. s != sections.end(); ++s) {
  209. for (std::vector<std::string>::const_iterator l = lang.begin();
  210. l != lang.end(); ++l) {
  211. IndexTarget * Target = new OptionalIndexTarget();
  212. Target->ShortDesc = "Translation-" + *l;
  213. Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
  214. Target->URI = TranslationIndexURI(l->c_str(), *s);
  215. Target->Description = Info (Target->ShortDesc.c_str(), *s);
  216. IndexTargets->push_back(Target);
  217. }
  218. }
  219. return IndexTargets;
  220. }
  221. /*}}}*/
  222. bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
  223. {
  224. bool const tryInRelease = _config->FindB("Acquire::TryInRelease", true);
  225. // special case for --print-uris
  226. if (GetAll) {
  227. vector <IndexTarget *> *targets = ComputeIndexTargets();
  228. for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target) {
  229. new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
  230. (*Target)->ShortDesc, HashString());
  231. }
  232. delete targets;
  233. // this is normally created in pkgAcqMetaSig, but if we run
  234. // in --print-uris mode, we add it here
  235. if (tryInRelease == false)
  236. new pkgAcqMetaIndex(Owner, MetaIndexURI("Release"),
  237. MetaIndexInfo("Release"), "Release",
  238. MetaIndexURI("Release.gpg"),
  239. ComputeIndexTargets(),
  240. new indexRecords (Dist));
  241. }
  242. if (tryInRelease == true)
  243. new pkgAcqMetaClearSig(Owner, MetaIndexURI("InRelease"),
  244. MetaIndexInfo("InRelease"), "InRelease",
  245. MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
  246. MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
  247. ComputeIndexTargets(),
  248. new indexRecords (Dist));
  249. else
  250. new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),
  251. MetaIndexInfo("Release.gpg"), "Release.gpg",
  252. MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
  253. ComputeIndexTargets(),
  254. new indexRecords (Dist));
  255. return true;
  256. }
  257. void debReleaseIndex::SetTrusted(bool const Trusted)
  258. {
  259. if (Trusted == true)
  260. this->Trusted = ALWAYS_TRUSTED;
  261. else
  262. this->Trusted = NEVER_TRUSTED;
  263. }
  264. bool debReleaseIndex::IsTrusted() const
  265. {
  266. if (Trusted == ALWAYS_TRUSTED)
  267. return true;
  268. else if (Trusted == NEVER_TRUSTED)
  269. return false;
  270. if(_config->FindB("APT::Authentication::TrustCDROM", false))
  271. if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
  272. return true;
  273. string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
  274. URItoFileName(MetaIndexURI("Release")) + ".gpg";
  275. if (FileExists(VerifiedSigFile))
  276. return true;
  277. VerifiedSigFile = _config->FindDir("Dir::State::lists") +
  278. URItoFileName(MetaIndexURI("InRelease"));
  279. return FileExists(VerifiedSigFile);
  280. }
  281. vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() {
  282. if (Indexes != NULL)
  283. return Indexes;
  284. Indexes = new vector <pkgIndexFile*>;
  285. map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
  286. if (src != ArchEntries.end()) {
  287. vector<debSectionEntry const*> const SectionEntries = src->second;
  288. for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
  289. I != SectionEntries.end(); ++I)
  290. Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
  291. }
  292. // Only source release
  293. if (Indexes->empty() == false && ArchEntries.size() == 1)
  294. return Indexes;
  295. std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
  296. map<string, set<string> > sections;
  297. for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
  298. a != ArchEntries.end(); ++a) {
  299. if (a->first == "source")
  300. continue;
  301. for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
  302. I != a->second.end(); ++I) {
  303. Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first));
  304. sections[(*I)->Section].insert(lang.begin(), lang.end());
  305. }
  306. }
  307. for (map<string, set<string> >::const_iterator s = sections.begin();
  308. s != sections.end(); ++s)
  309. for (set<string>::const_iterator l = s->second.begin();
  310. l != s->second.end(); ++l) {
  311. if (*l == "none") continue;
  312. Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str()));
  313. }
  314. return Indexes;
  315. }
  316. void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
  317. for (vector<string>::const_iterator a = Archs.begin();
  318. a != Archs.end(); ++a)
  319. ArchEntries[*a].push_back(new debSectionEntry(Entry->Section, Entry->IsSrc));
  320. delete Entry;
  321. }
  322. void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry *Entry) {
  323. ArchEntries[Arch].push_back(Entry);
  324. }
  325. void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) {
  326. if (Entry->IsSrc == true)
  327. PushSectionEntry("source", Entry);
  328. else {
  329. for (map<string, vector<const debSectionEntry *> >::iterator a = ArchEntries.begin();
  330. a != ArchEntries.end(); ++a) {
  331. a->second.push_back(Entry);
  332. }
  333. }
  334. }
  335. debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section,
  336. bool const &IsSrc): Section(Section), IsSrc(IsSrc)
  337. {}
  338. class debSLTypeDebian : public pkgSourceList::Type
  339. {
  340. protected:
  341. bool CreateItemInternal(vector<metaIndex *> &List, string const &URI,
  342. string const &Dist, string const &Section,
  343. bool const &IsSrc, map<string, string> const &Options) const
  344. {
  345. // parse arch=, arch+= and arch-= settings
  346. map<string, string>::const_iterator arch = Options.find("arch");
  347. vector<string> Archs =
  348. (arch != Options.end()) ? VectorizeString(arch->second, ',') :
  349. APT::Configuration::getArchitectures();
  350. if ((arch = Options.find("arch+")) != Options.end())
  351. {
  352. std::vector<std::string> const plusArch = VectorizeString(arch->second, ',');
  353. for (std::vector<std::string>::const_iterator plus = plusArch.begin(); plus != plusArch.end(); ++plus)
  354. if (std::find(Archs.begin(), Archs.end(), *plus) == Archs.end())
  355. Archs.push_back(*plus);
  356. }
  357. if ((arch = Options.find("arch-")) != Options.end())
  358. {
  359. std::vector<std::string> const minusArch = VectorizeString(arch->second, ',');
  360. for (std::vector<std::string>::const_iterator minus = minusArch.begin(); minus != minusArch.end(); ++minus)
  361. {
  362. std::vector<std::string>::iterator kill = std::find(Archs.begin(), Archs.end(), *minus);
  363. if (kill != Archs.end())
  364. Archs.erase(kill);
  365. }
  366. }
  367. map<string, string>::const_iterator const trusted = Options.find("trusted");
  368. for (vector<metaIndex *>::const_iterator I = List.begin();
  369. I != List.end(); ++I)
  370. {
  371. // We only worry about debian entries here
  372. if (strcmp((*I)->GetType(), "deb") != 0)
  373. continue;
  374. debReleaseIndex *Deb = (debReleaseIndex *) (*I);
  375. if (trusted != Options.end())
  376. Deb->SetTrusted(StringToBool(trusted->second, false));
  377. /* This check insures that there will be only one Release file
  378. queued for all the Packages files and Sources files it
  379. corresponds to. */
  380. if (Deb->GetURI() == URI && Deb->GetDist() == Dist)
  381. {
  382. if (IsSrc == true)
  383. Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
  384. else
  385. {
  386. if (Dist[Dist.size() - 1] == '/')
  387. Deb->PushSectionEntry("any", new debReleaseIndex::debSectionEntry(Section, IsSrc));
  388. else
  389. Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
  390. }
  391. return true;
  392. }
  393. }
  394. // No currently created Release file indexes this entry, so we create a new one.
  395. debReleaseIndex *Deb;
  396. if (trusted != Options.end())
  397. Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false));
  398. else
  399. Deb = new debReleaseIndex(URI, Dist);
  400. if (IsSrc == true)
  401. Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
  402. else
  403. {
  404. if (Dist[Dist.size() - 1] == '/')
  405. Deb->PushSectionEntry ("any", new debReleaseIndex::debSectionEntry(Section, IsSrc));
  406. else
  407. Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
  408. }
  409. List.push_back(Deb);
  410. return true;
  411. }
  412. };
  413. class debSLTypeDeb : public debSLTypeDebian
  414. {
  415. public:
  416. bool CreateItem(vector<metaIndex *> &List, string const &URI,
  417. string const &Dist, string const &Section,
  418. std::map<string, string> const &Options) const
  419. {
  420. return CreateItemInternal(List, URI, Dist, Section, false, Options);
  421. }
  422. debSLTypeDeb()
  423. {
  424. Name = "deb";
  425. Label = "Standard Debian binary tree";
  426. }
  427. };
  428. class debSLTypeDebSrc : public debSLTypeDebian
  429. {
  430. public:
  431. bool CreateItem(vector<metaIndex *> &List, string const &URI,
  432. string const &Dist, string const &Section,
  433. std::map<string, string> const &Options) const
  434. {
  435. return CreateItemInternal(List, URI, Dist, Section, true, Options);
  436. }
  437. debSLTypeDebSrc()
  438. {
  439. Name = "deb-src";
  440. Label = "Standard Debian source tree";
  441. }
  442. };
  443. debSLTypeDeb _apt_DebType;
  444. debSLTypeDebSrc _apt_DebSrcType;