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.
 
 
 
 
 
 

912 lines
27 KiB

  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: debindexfile.cc,v 1.5.2.3 2004/01/04 19:11:00 mdz Exp $
  4. /* ######################################################################
  5. Debian Specific sources.list types and the three sorts of Debian
  6. index files.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #include <config.h>
  11. #include <apt-pkg/debindexfile.h>
  12. #include <apt-pkg/debsrcrecords.h>
  13. #include <apt-pkg/deblistparser.h>
  14. #include <apt-pkg/debrecords.h>
  15. #include <apt-pkg/configuration.h>
  16. #include <apt-pkg/progress.h>
  17. #include <apt-pkg/error.h>
  18. #include <apt-pkg/strutl.h>
  19. #include <apt-pkg/acquire-item.h>
  20. #include <apt-pkg/debmetaindex.h>
  21. #include <apt-pkg/gpgv.h>
  22. #include <apt-pkg/fileutl.h>
  23. #include <apt-pkg/indexfile.h>
  24. #include <apt-pkg/mmap.h>
  25. #include <apt-pkg/pkgcache.h>
  26. #include <apt-pkg/cacheiterators.h>
  27. #include <apt-pkg/pkgcachegen.h>
  28. #include <apt-pkg/pkgrecords.h>
  29. #include <apt-pkg/srcrecords.h>
  30. #include <apt-pkg/sptr.h>
  31. #include <stdio.h>
  32. #include <iostream>
  33. #include <sstream>
  34. #include <string>
  35. #include <sys/stat.h>
  36. /*}}}*/
  37. using std::string;
  38. // SourcesIndex::debSourcesIndex - Constructor /*{{{*/
  39. // ---------------------------------------------------------------------
  40. /* */
  41. debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) :
  42. pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section)
  43. {
  44. }
  45. /*}}}*/
  46. // SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
  47. // ---------------------------------------------------------------------
  48. /* The result looks like:
  49. http://foo/debian/ stable/main src 1.1.1 (dsc) */
  50. string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
  51. pkgSrcRecords::File const &File) const
  52. {
  53. string Res;
  54. Res = ::URI::NoUserPassword(URI) + ' ';
  55. if (Dist[Dist.size() - 1] == '/')
  56. {
  57. if (Dist != "/")
  58. Res += Dist;
  59. }
  60. else
  61. Res += Dist + '/' + Section;
  62. Res += " ";
  63. Res += Record.Package();
  64. Res += " ";
  65. Res += Record.Version();
  66. if (File.Type.empty() == false)
  67. Res += " (" + File.Type + ")";
  68. return Res;
  69. }
  70. /*}}}*/
  71. // SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
  72. // ---------------------------------------------------------------------
  73. /* */
  74. pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
  75. {
  76. string SourcesURI = _config->FindDir("Dir::State::lists") +
  77. URItoFileName(IndexURI("Sources"));
  78. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  79. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  80. {
  81. string p;
  82. p = SourcesURI + '.' + *t;
  83. if (FileExists(p))
  84. return new debSrcRecordParser(p, this);
  85. }
  86. if (FileExists(SourcesURI))
  87. return new debSrcRecordParser(SourcesURI, this);
  88. return NULL;
  89. }
  90. /*}}}*/
  91. // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
  92. // ---------------------------------------------------------------------
  93. /* */
  94. string debSourcesIndex::Describe(bool Short) const
  95. {
  96. char S[300];
  97. if (Short == true)
  98. snprintf(S,sizeof(S),"%s",Info("Sources").c_str());
  99. else
  100. snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(),
  101. IndexFile("Sources").c_str());
  102. return S;
  103. }
  104. /*}}}*/
  105. // SourcesIndex::Info - One liner describing the index URI /*{{{*/
  106. // ---------------------------------------------------------------------
  107. /* */
  108. string debSourcesIndex::Info(const char *Type) const
  109. {
  110. string Info = ::URI::NoUserPassword(URI) + ' ';
  111. if (Dist[Dist.size() - 1] == '/')
  112. {
  113. if (Dist != "/")
  114. Info += Dist;
  115. }
  116. else
  117. Info += Dist + '/' + Section;
  118. Info += " ";
  119. Info += Type;
  120. return Info;
  121. }
  122. /*}}}*/
  123. // SourcesIndex::Index* - Return the URI to the index files /*{{{*/
  124. // ---------------------------------------------------------------------
  125. /* */
  126. string debSourcesIndex::IndexFile(const char *Type) const
  127. {
  128. string s = URItoFileName(IndexURI(Type));
  129. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  130. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  131. {
  132. string p = s + '.' + *t;
  133. if (FileExists(p))
  134. return p;
  135. }
  136. return s;
  137. }
  138. string debSourcesIndex::IndexURI(const char *Type) 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. }
  148. else
  149. Res = URI + "dists/" + Dist + '/' + Section +
  150. "/source/";
  151. Res += Type;
  152. return Res;
  153. }
  154. /*}}}*/
  155. // SourcesIndex::Exists - Check if the index is available /*{{{*/
  156. // ---------------------------------------------------------------------
  157. /* */
  158. bool debSourcesIndex::Exists() const
  159. {
  160. return FileExists(IndexFile("Sources"));
  161. }
  162. /*}}}*/
  163. // SourcesIndex::Size - Return the size of the index /*{{{*/
  164. // ---------------------------------------------------------------------
  165. /* */
  166. unsigned long debSourcesIndex::Size() const
  167. {
  168. unsigned long size = 0;
  169. /* we need to ignore errors here; if the lists are absent, just return 0 */
  170. _error->PushToStack();
  171. FileFd f(IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
  172. if (!f.Failed())
  173. size = f.Size();
  174. if (_error->PendingError() == true)
  175. size = 0;
  176. _error->RevertToStack();
  177. return size;
  178. }
  179. /*}}}*/
  180. // PackagesIndex::debPackagesIndex - Contructor /*{{{*/
  181. // ---------------------------------------------------------------------
  182. /* */
  183. debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section,
  184. bool const &Trusted, string const &Arch) :
  185. pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch)
  186. {
  187. if (Architecture == "native")
  188. Architecture = _config->Find("APT::Architecture");
  189. }
  190. /*}}}*/
  191. // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
  192. // ---------------------------------------------------------------------
  193. /* This is a shorter version that is designed to be < 60 chars or so */
  194. string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
  195. {
  196. string Res = ::URI::NoUserPassword(URI) + ' ';
  197. if (Dist[Dist.size() - 1] == '/')
  198. {
  199. if (Dist != "/")
  200. Res += Dist;
  201. }
  202. else
  203. Res += Dist + '/' + Section;
  204. Res += " ";
  205. Res += Ver.ParentPkg().Name();
  206. Res += " ";
  207. if (Dist[Dist.size() - 1] != '/')
  208. Res.append(Ver.Arch()).append(" ");
  209. Res += Ver.VerStr();
  210. return Res;
  211. }
  212. /*}}}*/
  213. // PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
  214. // ---------------------------------------------------------------------
  215. /* This should help the user find the index in the sources.list and
  216. in the filesystem for problem solving */
  217. string debPackagesIndex::Describe(bool Short) const
  218. {
  219. char S[300];
  220. if (Short == true)
  221. snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
  222. else
  223. snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
  224. IndexFile("Packages").c_str());
  225. return S;
  226. }
  227. /*}}}*/
  228. // PackagesIndex::Info - One liner describing the index URI /*{{{*/
  229. // ---------------------------------------------------------------------
  230. /* */
  231. string debPackagesIndex::Info(const char *Type) const
  232. {
  233. string Info = ::URI::NoUserPassword(URI) + ' ';
  234. if (Dist[Dist.size() - 1] == '/')
  235. {
  236. if (Dist != "/")
  237. Info += Dist;
  238. }
  239. else
  240. Info += Dist + '/' + Section;
  241. Info += " ";
  242. if (Dist[Dist.size() - 1] != '/')
  243. Info += Architecture + " ";
  244. Info += Type;
  245. return Info;
  246. }
  247. /*}}}*/
  248. // PackagesIndex::Index* - Return the URI to the index files /*{{{*/
  249. // ---------------------------------------------------------------------
  250. /* */
  251. string debPackagesIndex::IndexFile(const char *Type) const
  252. {
  253. string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
  254. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  255. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  256. {
  257. string p = s + '.' + *t;
  258. if (FileExists(p))
  259. return p;
  260. }
  261. return s;
  262. }
  263. string debPackagesIndex::IndexURI(const char *Type) const
  264. {
  265. string Res;
  266. if (Dist[Dist.size() - 1] == '/')
  267. {
  268. if (Dist != "/")
  269. Res = URI + Dist;
  270. else
  271. Res = URI;
  272. }
  273. else
  274. Res = URI + "dists/" + Dist + '/' + Section +
  275. "/binary-" + Architecture + '/';
  276. Res += Type;
  277. return Res;
  278. }
  279. /*}}}*/
  280. // PackagesIndex::Exists - Check if the index is available /*{{{*/
  281. // ---------------------------------------------------------------------
  282. /* */
  283. bool debPackagesIndex::Exists() const
  284. {
  285. return FileExists(IndexFile("Packages"));
  286. }
  287. /*}}}*/
  288. // PackagesIndex::Size - Return the size of the index /*{{{*/
  289. // ---------------------------------------------------------------------
  290. /* This is really only used for progress reporting. */
  291. unsigned long debPackagesIndex::Size() const
  292. {
  293. unsigned long size = 0;
  294. /* we need to ignore errors here; if the lists are absent, just return 0 */
  295. _error->PushToStack();
  296. FileFd f(IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
  297. if (!f.Failed())
  298. size = f.Size();
  299. if (_error->PendingError() == true)
  300. size = 0;
  301. _error->RevertToStack();
  302. return size;
  303. }
  304. /*}}}*/
  305. // PackagesIndex::Merge - Load the index file into a cache /*{{{*/
  306. // ---------------------------------------------------------------------
  307. /* */
  308. bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  309. {
  310. string PackageFile = IndexFile("Packages");
  311. FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
  312. debListParser Parser(&Pkg, Architecture);
  313. if (_error->PendingError() == true)
  314. return _error->Error("Problem opening %s",PackageFile.c_str());
  315. if (Prog != NULL)
  316. Prog->SubProgress(0,Info("Packages"));
  317. ::URI Tmp(URI);
  318. if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
  319. return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
  320. // Store the IMS information
  321. pkgCache::PkgFileIterator File = Gen.GetCurFile();
  322. pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
  323. File->Size = Pkg.FileSize();
  324. File->mtime = Pkg.ModificationTime();
  325. if (Gen.MergeList(Parser) == false)
  326. return _error->Error("Problem with MergeList %s",PackageFile.c_str());
  327. // Check the release file
  328. string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease");
  329. bool releaseExists = false;
  330. if (FileExists(ReleaseFile) == true)
  331. releaseExists = true;
  332. else
  333. ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
  334. if (releaseExists == true || FileExists(ReleaseFile) == true)
  335. {
  336. FileFd Rel;
  337. // Beware: The 'Release' file might be clearsigned in case the
  338. // signature for an 'InRelease' file couldn't be checked
  339. if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
  340. return false;
  341. if (_error->PendingError() == true)
  342. return false;
  343. Parser.LoadReleaseInfo(File,Rel,Section);
  344. }
  345. return true;
  346. }
  347. /*}}}*/
  348. // PackagesIndex::FindInCache - Find this index /*{{{*/
  349. // ---------------------------------------------------------------------
  350. /* */
  351. pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
  352. {
  353. string FileName = IndexFile("Packages");
  354. pkgCache::PkgFileIterator File = Cache.FileBegin();
  355. for (; File.end() == false; ++File)
  356. {
  357. if (File.FileName() == NULL || FileName != File.FileName())
  358. continue;
  359. struct stat St;
  360. if (stat(File.FileName(),&St) != 0)
  361. {
  362. if (_config->FindB("Debug::pkgCacheGen", false))
  363. std::clog << "PackagesIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  364. return pkgCache::PkgFileIterator(Cache);
  365. }
  366. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  367. {
  368. if (_config->FindB("Debug::pkgCacheGen", false))
  369. std::clog << "PackagesIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  370. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  371. << ") doesn't match for " << File.FileName() << std::endl;
  372. return pkgCache::PkgFileIterator(Cache);
  373. }
  374. return File;
  375. }
  376. return File;
  377. }
  378. /*}}}*/
  379. // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/
  380. // ---------------------------------------------------------------------
  381. /* */
  382. debTranslationsIndex::debTranslationsIndex(std::string const &URI, std::string const &Dist,
  383. std::string const &Section, std::string const &Translation) :
  384. pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section),
  385. Language(Translation)
  386. {}
  387. /*}}}*/
  388. // TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/
  389. // ---------------------------------------------------------------------
  390. /* */
  391. string debTranslationsIndex::IndexFile(const char *Type) const
  392. {
  393. string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
  394. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  395. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  396. {
  397. string p = s + '.' + *t;
  398. if (FileExists(p))
  399. return p;
  400. }
  401. return s;
  402. }
  403. string debTranslationsIndex::IndexURI(const char *Type) const
  404. {
  405. string Res;
  406. if (Dist[Dist.size() - 1] == '/')
  407. {
  408. if (Dist != "/")
  409. Res = URI + Dist;
  410. else
  411. Res = URI;
  412. }
  413. else
  414. Res = URI + "dists/" + Dist + '/' + Section +
  415. "/i18n/Translation-";
  416. Res += Type;
  417. return Res;
  418. }
  419. /*}}}*/
  420. // TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/
  421. // ---------------------------------------------------------------------
  422. /* This should help the user find the index in the sources.list and
  423. in the filesystem for problem solving */
  424. string debTranslationsIndex::Describe(bool Short) const
  425. {
  426. std::string S;
  427. if (Short == true)
  428. strprintf(S,"%s",Info(TranslationFile().c_str()).c_str());
  429. else
  430. strprintf(S,"%s (%s)",Info(TranslationFile().c_str()).c_str(),
  431. IndexFile(Language.c_str()).c_str());
  432. return S;
  433. }
  434. /*}}}*/
  435. // TranslationsIndex::Info - One liner describing the index URI /*{{{*/
  436. // ---------------------------------------------------------------------
  437. /* */
  438. string debTranslationsIndex::Info(const char *Type) const
  439. {
  440. string Info = ::URI::NoUserPassword(URI) + ' ';
  441. if (Dist[Dist.size() - 1] == '/')
  442. {
  443. if (Dist != "/")
  444. Info += Dist;
  445. }
  446. else
  447. Info += Dist + '/' + Section;
  448. Info += " ";
  449. Info += Type;
  450. return Info;
  451. }
  452. /*}}}*/
  453. bool debTranslationsIndex::HasPackages() const /*{{{*/
  454. {
  455. return FileExists(IndexFile(Language.c_str()));
  456. }
  457. /*}}}*/
  458. // TranslationsIndex::Exists - Check if the index is available /*{{{*/
  459. // ---------------------------------------------------------------------
  460. /* */
  461. bool debTranslationsIndex::Exists() const
  462. {
  463. return FileExists(IndexFile(Language.c_str()));
  464. }
  465. /*}}}*/
  466. // TranslationsIndex::Size - Return the size of the index /*{{{*/
  467. // ---------------------------------------------------------------------
  468. /* This is really only used for progress reporting. */
  469. unsigned long debTranslationsIndex::Size() const
  470. {
  471. unsigned long size = 0;
  472. /* we need to ignore errors here; if the lists are absent, just return 0 */
  473. _error->PushToStack();
  474. FileFd f(IndexFile(Language.c_str()), FileFd::ReadOnly, FileFd::Extension);
  475. if (!f.Failed())
  476. size = f.Size();
  477. if (_error->PendingError() == true)
  478. size = 0;
  479. _error->RevertToStack();
  480. return size;
  481. }
  482. /*}}}*/
  483. // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/
  484. // ---------------------------------------------------------------------
  485. /* */
  486. bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  487. {
  488. // Check the translation file, if in use
  489. string TranslationFile = IndexFile(Language.c_str());
  490. if (FileExists(TranslationFile))
  491. {
  492. FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
  493. debTranslationsParser TransParser(&Trans);
  494. if (_error->PendingError() == true)
  495. return false;
  496. if (Prog != NULL)
  497. Prog->SubProgress(0, Info(TranslationFile.c_str()));
  498. if (Gen.SelectFile(TranslationFile,string(),*this) == false)
  499. return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
  500. // Store the IMS information
  501. pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
  502. TransFile->Size = Trans.FileSize();
  503. TransFile->mtime = Trans.ModificationTime();
  504. if (Gen.MergeList(TransParser) == false)
  505. return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
  506. }
  507. return true;
  508. }
  509. /*}}}*/
  510. // TranslationsIndex::FindInCache - Find this index /*{{{*/
  511. // ---------------------------------------------------------------------
  512. /* */
  513. pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const
  514. {
  515. string FileName = IndexFile(Language.c_str());
  516. pkgCache::PkgFileIterator File = Cache.FileBegin();
  517. for (; File.end() == false; ++File)
  518. {
  519. if (FileName != File.FileName())
  520. continue;
  521. struct stat St;
  522. if (stat(File.FileName(),&St) != 0)
  523. {
  524. if (_config->FindB("Debug::pkgCacheGen", false))
  525. std::clog << "TranslationIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  526. return pkgCache::PkgFileIterator(Cache);
  527. }
  528. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  529. {
  530. if (_config->FindB("Debug::pkgCacheGen", false))
  531. std::clog << "TranslationIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  532. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  533. << ") doesn't match for " << File.FileName() << std::endl;
  534. return pkgCache::PkgFileIterator(Cache);
  535. }
  536. return File;
  537. }
  538. return File;
  539. }
  540. /*}}}*/
  541. // StatusIndex::debStatusIndex - Constructor /*{{{*/
  542. // ---------------------------------------------------------------------
  543. /* */
  544. debStatusIndex::debStatusIndex(string File) : pkgIndexFile(true), File(File)
  545. {
  546. }
  547. /*}}}*/
  548. // StatusIndex::Size - Return the size of the index /*{{{*/
  549. // ---------------------------------------------------------------------
  550. /* */
  551. unsigned long debStatusIndex::Size() const
  552. {
  553. struct stat S;
  554. if (stat(File.c_str(),&S) != 0)
  555. return 0;
  556. return S.st_size;
  557. }
  558. /*}}}*/
  559. // StatusIndex::Merge - Load the index file into a cache /*{{{*/
  560. // ---------------------------------------------------------------------
  561. /* */
  562. bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  563. {
  564. FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension);
  565. if (_error->PendingError() == true)
  566. return false;
  567. debListParser Parser(&Pkg);
  568. if (_error->PendingError() == true)
  569. return false;
  570. if (Prog != NULL)
  571. Prog->SubProgress(0,File);
  572. if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
  573. return _error->Error("Problem with SelectFile %s",File.c_str());
  574. // Store the IMS information
  575. pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
  576. CFile->Size = Pkg.FileSize();
  577. CFile->mtime = Pkg.ModificationTime();
  578. map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now");
  579. CFile->Archive = storage;
  580. if (Gen.MergeList(Parser) == false)
  581. return _error->Error("Problem with MergeList %s",File.c_str());
  582. return true;
  583. }
  584. /*}}}*/
  585. // StatusIndex::FindInCache - Find this index /*{{{*/
  586. // ---------------------------------------------------------------------
  587. /* */
  588. pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const
  589. {
  590. pkgCache::PkgFileIterator File = Cache.FileBegin();
  591. for (; File.end() == false; ++File)
  592. {
  593. if (this->File != File.FileName())
  594. continue;
  595. struct stat St;
  596. if (stat(File.FileName(),&St) != 0)
  597. {
  598. if (_config->FindB("Debug::pkgCacheGen", false))
  599. std::clog << "StatusIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  600. return pkgCache::PkgFileIterator(Cache);
  601. }
  602. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  603. {
  604. if (_config->FindB("Debug::pkgCacheGen", false))
  605. std::clog << "StatusIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  606. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  607. << ") doesn't match for " << File.FileName() << std::endl;
  608. return pkgCache::PkgFileIterator(Cache);
  609. }
  610. return File;
  611. }
  612. return File;
  613. }
  614. /*}}}*/
  615. // StatusIndex::Exists - Check if the index is available /*{{{*/
  616. // ---------------------------------------------------------------------
  617. /* */
  618. APT_CONST bool debStatusIndex::Exists() const
  619. {
  620. // Abort if the file does not exist.
  621. return true;
  622. }
  623. /*}}}*/
  624. // debDebPkgFile - Single .deb file /*{{{*/
  625. debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
  626. : pkgIndexFile(true), DebFile(DebFile)
  627. {
  628. DebFileFullPath = flAbsPath(DebFile);
  629. }
  630. std::string debDebPkgFileIndex::ArchiveURI(std::string /*File*/) const
  631. {
  632. return "file:" + DebFileFullPath;
  633. }
  634. bool debDebPkgFileIndex::Exists() const
  635. {
  636. return FileExists(DebFile);
  637. }
  638. bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile)
  639. {
  640. // get the control data out of the deb file via dpkg-deb -I
  641. std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb");
  642. std::vector<const char *> Args;
  643. Args.push_back(dpkg.c_str());
  644. Args.push_back("-I");
  645. Args.push_back(debfile.c_str());
  646. Args.push_back("control");
  647. Args.push_back(NULL);
  648. FileFd PipeFd;
  649. pid_t Child;
  650. if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
  651. return _error->Error("Popen failed");
  652. char buffer[1024];
  653. do {
  654. unsigned long long actual = 0;
  655. if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false)
  656. return _error->Errno("read", "Failed to read dpkg pipe");
  657. if (actual == 0)
  658. break;
  659. buffer[actual] = '\0';
  660. content << buffer;
  661. } while(true);
  662. ExecWait(Child, "Popen");
  663. content << "Filename: " << debfile << "\n";
  664. struct stat Buf;
  665. if (stat(debfile.c_str(), &Buf) != 0)
  666. return false;
  667. content << "Size: " << Buf.st_size << "\n";
  668. return true;
  669. }
  670. bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
  671. {
  672. if(Prog)
  673. Prog->SubProgress(0, "Reading deb file");
  674. // write the control data to a tempfile
  675. SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile));
  676. if(DebControl == NULL)
  677. return false;
  678. std::ostringstream content;
  679. if (GetContent(content, DebFile) == false)
  680. return false;
  681. std::string const contentstr = content.str();
  682. DebControl->Write(contentstr.c_str(), contentstr.length());
  683. // rewind for the listparser
  684. DebControl->Seek(0);
  685. // and give it to the list parser
  686. debDebFileParser Parser(DebControl, DebFile);
  687. if(Gen.SelectFile(DebFile, "local", *this, pkgCache::Flag::LocalSource) == false)
  688. return _error->Error("Problem with SelectFile %s", DebFile.c_str());
  689. pkgCache::PkgFileIterator File = Gen.GetCurFile();
  690. File->Size = DebControl->Size();
  691. File->mtime = DebControl->ModificationTime();
  692. if (Gen.MergeList(Parser) == false)
  693. return _error->Error("Problem with MergeLister for %s", DebFile.c_str());
  694. return true;
  695. }
  696. pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const
  697. {
  698. pkgCache::PkgFileIterator File = Cache.FileBegin();
  699. for (; File.end() == false; ++File)
  700. {
  701. if (File.FileName() == NULL || DebFile != File.FileName())
  702. continue;
  703. return File;
  704. }
  705. return File;
  706. }
  707. unsigned long debDebPkgFileIndex::Size() const
  708. {
  709. struct stat buf;
  710. if(stat(DebFile.c_str(), &buf) != 0)
  711. return 0;
  712. return buf.st_size;
  713. }
  714. /*}}}*/
  715. // debDscFileIndex stuff
  716. debDscFileIndex::debDscFileIndex(std::string &DscFile)
  717. : pkgIndexFile(true), DscFile(DscFile)
  718. {
  719. }
  720. bool debDscFileIndex::Exists() const
  721. {
  722. return FileExists(DscFile);
  723. }
  724. unsigned long debDscFileIndex::Size() const
  725. {
  726. struct stat buf;
  727. if(stat(DscFile.c_str(), &buf) == 0)
  728. return buf.st_size;
  729. return 0;
  730. }
  731. // DscFileIndex::CreateSrcParser - Get a parser for the .dsc file /*{{{*/
  732. pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
  733. {
  734. if (!FileExists(DscFile))
  735. return NULL;
  736. return new debDscRecordParser(DscFile,this);
  737. }
  738. /*}}}*/
  739. // Index File types for Debian /*{{{*/
  740. class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type
  741. {
  742. public:
  743. debIFTypeSrc() {Label = "Debian Source Index";};
  744. };
  745. class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type
  746. {
  747. public:
  748. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  749. {
  750. return new debRecordParser(File.FileName(),*File.Cache());
  751. };
  752. debIFTypePkg() {Label = "Debian Package Index";};
  753. };
  754. class APT_HIDDEN debIFTypeTrans : public debIFTypePkg
  755. {
  756. public:
  757. debIFTypeTrans() {Label = "Debian Translation Index";};
  758. };
  759. class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type
  760. {
  761. public:
  762. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  763. {
  764. return new debRecordParser(File.FileName(),*File.Cache());
  765. };
  766. debIFTypeStatus() {Label = "Debian dpkg status file";};
  767. };
  768. class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type
  769. {
  770. public:
  771. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  772. {
  773. return new debDebFileRecordParser(File.FileName());
  774. };
  775. debIFTypeDebPkgFile() {Label = "deb Package file";};
  776. };
  777. class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
  778. {
  779. public:
  780. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const
  781. {
  782. return new debDscRecordParser(DscFile, NULL);
  783. };
  784. debIFTypeDscFile() {Label = "dsc File Source Index";};
  785. };
  786. class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
  787. {
  788. public:
  789. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const
  790. {
  791. return new debDscRecordParser(SourceDir + string("/debian/control"), NULL);
  792. };
  793. debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
  794. };
  795. APT_HIDDEN debIFTypeSrc _apt_Src;
  796. APT_HIDDEN debIFTypePkg _apt_Pkg;
  797. APT_HIDDEN debIFTypeTrans _apt_Trans;
  798. APT_HIDDEN debIFTypeStatus _apt_Status;
  799. APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile;
  800. // file based pseudo indexes
  801. APT_HIDDEN debIFTypeDscFile _apt_DscFile;
  802. APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir;
  803. const pkgIndexFile::Type *debSourcesIndex::GetType() const
  804. {
  805. return &_apt_Src;
  806. }
  807. const pkgIndexFile::Type *debPackagesIndex::GetType() const
  808. {
  809. return &_apt_Pkg;
  810. }
  811. const pkgIndexFile::Type *debTranslationsIndex::GetType() const
  812. {
  813. return &_apt_Trans;
  814. }
  815. const pkgIndexFile::Type *debStatusIndex::GetType() const
  816. {
  817. return &_apt_Status;
  818. }
  819. const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
  820. {
  821. return &_apt_DebPkgFile;
  822. }
  823. const pkgIndexFile::Type *debDscFileIndex::GetType() const
  824. {
  825. return &_apt_DscFile;
  826. }
  827. const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const
  828. {
  829. return &_apt_DebianSourceDir;
  830. }
  831. /*}}}*/
  832. debStatusIndex::~debStatusIndex() {}
  833. debPackagesIndex::~debPackagesIndex() {}
  834. debTranslationsIndex::~debTranslationsIndex() {}
  835. debSourcesIndex::~debSourcesIndex() {}
  836. debDebPkgFileIndex::~debDebPkgFileIndex() {}