debindexfile.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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 <stdio.h>
  31. #include <iostream>
  32. #include <string>
  33. #include <sys/stat.h>
  34. /*}}}*/
  35. using std::string;
  36. // SourcesIndex::debSourcesIndex - Constructor /*{{{*/
  37. // ---------------------------------------------------------------------
  38. /* */
  39. debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) :
  40. pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section)
  41. {
  42. }
  43. /*}}}*/
  44. // SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
  45. // ---------------------------------------------------------------------
  46. /* The result looks like:
  47. http://foo/debian/ stable/main src 1.1.1 (dsc) */
  48. string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
  49. pkgSrcRecords::File const &File) const
  50. {
  51. string Res;
  52. Res = ::URI::NoUserPassword(URI) + ' ';
  53. if (Dist[Dist.size() - 1] == '/')
  54. {
  55. if (Dist != "/")
  56. Res += Dist;
  57. }
  58. else
  59. Res += Dist + '/' + Section;
  60. Res += " ";
  61. Res += Record.Package();
  62. Res += " ";
  63. Res += Record.Version();
  64. if (File.Type.empty() == false)
  65. Res += " (" + File.Type + ")";
  66. return Res;
  67. }
  68. /*}}}*/
  69. // SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
  70. // ---------------------------------------------------------------------
  71. /* */
  72. pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
  73. {
  74. string SourcesURI = _config->FindDir("Dir::State::lists") +
  75. URItoFileName(IndexURI("Sources"));
  76. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  77. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  78. {
  79. string p;
  80. p = SourcesURI + '.' + *t;
  81. if (FileExists(p))
  82. return new debSrcRecordParser(p, this);
  83. }
  84. if (FileExists(SourcesURI))
  85. return new debSrcRecordParser(SourcesURI, this);
  86. return NULL;
  87. }
  88. /*}}}*/
  89. // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
  90. // ---------------------------------------------------------------------
  91. /* */
  92. string debSourcesIndex::Describe(bool Short) const
  93. {
  94. char S[300];
  95. if (Short == true)
  96. snprintf(S,sizeof(S),"%s",Info("Sources").c_str());
  97. else
  98. snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(),
  99. IndexFile("Sources").c_str());
  100. return S;
  101. }
  102. /*}}}*/
  103. // SourcesIndex::Info - One liner describing the index URI /*{{{*/
  104. // ---------------------------------------------------------------------
  105. /* */
  106. string debSourcesIndex::Info(const char *Type) const
  107. {
  108. string Info = ::URI::NoUserPassword(URI) + ' ';
  109. if (Dist[Dist.size() - 1] == '/')
  110. {
  111. if (Dist != "/")
  112. Info += Dist;
  113. }
  114. else
  115. Info += Dist + '/' + Section;
  116. Info += " ";
  117. Info += Type;
  118. return Info;
  119. }
  120. /*}}}*/
  121. // SourcesIndex::Index* - Return the URI to the index files /*{{{*/
  122. // ---------------------------------------------------------------------
  123. /* */
  124. inline string debSourcesIndex::IndexFile(const char *Type) const
  125. {
  126. string s = URItoFileName(IndexURI(Type));
  127. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  128. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  129. {
  130. string p = s + '.' + *t;
  131. if (FileExists(p))
  132. return p;
  133. }
  134. return s;
  135. }
  136. string debSourcesIndex::IndexURI(const char *Type) const
  137. {
  138. string Res;
  139. if (Dist[Dist.size() - 1] == '/')
  140. {
  141. if (Dist != "/")
  142. Res = URI + Dist;
  143. else
  144. Res = URI;
  145. }
  146. else
  147. Res = URI + "dists/" + Dist + '/' + Section +
  148. "/source/";
  149. Res += Type;
  150. return Res;
  151. }
  152. /*}}}*/
  153. // SourcesIndex::Exists - Check if the index is available /*{{{*/
  154. // ---------------------------------------------------------------------
  155. /* */
  156. bool debSourcesIndex::Exists() const
  157. {
  158. return FileExists(IndexFile("Sources"));
  159. }
  160. /*}}}*/
  161. // SourcesIndex::Size - Return the size of the index /*{{{*/
  162. // ---------------------------------------------------------------------
  163. /* */
  164. unsigned long debSourcesIndex::Size() const
  165. {
  166. unsigned long size = 0;
  167. /* we need to ignore errors here; if the lists are absent, just return 0 */
  168. _error->PushToStack();
  169. FileFd f(IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
  170. if (!f.Failed())
  171. size = f.Size();
  172. if (_error->PendingError() == true)
  173. size = 0;
  174. _error->RevertToStack();
  175. return size;
  176. }
  177. /*}}}*/
  178. // PackagesIndex::debPackagesIndex - Contructor /*{{{*/
  179. // ---------------------------------------------------------------------
  180. /* */
  181. debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section,
  182. bool const &Trusted, string const &Arch) :
  183. pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch)
  184. {
  185. if (Architecture == "native")
  186. Architecture = _config->Find("APT::Architecture");
  187. }
  188. /*}}}*/
  189. // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
  190. // ---------------------------------------------------------------------
  191. /* This is a shorter version that is designed to be < 60 chars or so */
  192. string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
  193. {
  194. string Res = ::URI::NoUserPassword(URI) + ' ';
  195. if (Dist[Dist.size() - 1] == '/')
  196. {
  197. if (Dist != "/")
  198. Res += Dist;
  199. }
  200. else
  201. Res += Dist + '/' + Section;
  202. Res += " ";
  203. Res += Ver.ParentPkg().Name();
  204. Res += " ";
  205. if (Dist[Dist.size() - 1] != '/')
  206. Res.append(Ver.Arch()).append(" ");
  207. Res += Ver.VerStr();
  208. return Res;
  209. }
  210. /*}}}*/
  211. // PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
  212. // ---------------------------------------------------------------------
  213. /* This should help the user find the index in the sources.list and
  214. in the filesystem for problem solving */
  215. string debPackagesIndex::Describe(bool Short) const
  216. {
  217. char S[300];
  218. if (Short == true)
  219. snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
  220. else
  221. snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
  222. IndexFile("Packages").c_str());
  223. return S;
  224. }
  225. /*}}}*/
  226. // PackagesIndex::Info - One liner describing the index URI /*{{{*/
  227. // ---------------------------------------------------------------------
  228. /* */
  229. string debPackagesIndex::Info(const char *Type) const
  230. {
  231. string Info = ::URI::NoUserPassword(URI) + ' ';
  232. if (Dist[Dist.size() - 1] == '/')
  233. {
  234. if (Dist != "/")
  235. Info += Dist;
  236. }
  237. else
  238. Info += Dist + '/' + Section;
  239. Info += " ";
  240. if (Dist[Dist.size() - 1] != '/')
  241. Info += Architecture + " ";
  242. Info += Type;
  243. return Info;
  244. }
  245. /*}}}*/
  246. // PackagesIndex::Index* - Return the URI to the index files /*{{{*/
  247. // ---------------------------------------------------------------------
  248. /* */
  249. inline string debPackagesIndex::IndexFile(const char *Type) const
  250. {
  251. string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
  252. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  253. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  254. {
  255. string p = s + '.' + *t;
  256. if (FileExists(p))
  257. return p;
  258. }
  259. return s;
  260. }
  261. string debPackagesIndex::IndexURI(const char *Type) const
  262. {
  263. string Res;
  264. if (Dist[Dist.size() - 1] == '/')
  265. {
  266. if (Dist != "/")
  267. Res = URI + Dist;
  268. else
  269. Res = URI;
  270. }
  271. else
  272. Res = URI + "dists/" + Dist + '/' + Section +
  273. "/binary-" + Architecture + '/';
  274. Res += Type;
  275. return Res;
  276. }
  277. /*}}}*/
  278. // PackagesIndex::Exists - Check if the index is available /*{{{*/
  279. // ---------------------------------------------------------------------
  280. /* */
  281. bool debPackagesIndex::Exists() const
  282. {
  283. return FileExists(IndexFile("Packages"));
  284. }
  285. /*}}}*/
  286. // PackagesIndex::Size - Return the size of the index /*{{{*/
  287. // ---------------------------------------------------------------------
  288. /* This is really only used for progress reporting. */
  289. unsigned long debPackagesIndex::Size() const
  290. {
  291. unsigned long size = 0;
  292. /* we need to ignore errors here; if the lists are absent, just return 0 */
  293. _error->PushToStack();
  294. FileFd f(IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
  295. if (!f.Failed())
  296. size = f.Size();
  297. if (_error->PendingError() == true)
  298. size = 0;
  299. _error->RevertToStack();
  300. return size;
  301. }
  302. /*}}}*/
  303. // PackagesIndex::Merge - Load the index file into a cache /*{{{*/
  304. // ---------------------------------------------------------------------
  305. /* */
  306. bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  307. {
  308. string PackageFile = IndexFile("Packages");
  309. FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
  310. debListParser Parser(&Pkg, Architecture);
  311. if (_error->PendingError() == true)
  312. return _error->Error("Problem opening %s",PackageFile.c_str());
  313. if (Prog != NULL)
  314. Prog->SubProgress(0,Info("Packages"));
  315. ::URI Tmp(URI);
  316. if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
  317. return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
  318. // Store the IMS information
  319. pkgCache::PkgFileIterator File = Gen.GetCurFile();
  320. pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
  321. File->Size = Pkg.FileSize();
  322. File->mtime = Pkg.ModificationTime();
  323. if (Gen.MergeList(Parser) == false)
  324. return _error->Error("Problem with MergeList %s",PackageFile.c_str());
  325. // Check the release file
  326. string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease");
  327. bool releaseExists = false;
  328. if (FileExists(ReleaseFile) == true)
  329. releaseExists = true;
  330. else
  331. ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
  332. if (releaseExists == true || FileExists(ReleaseFile) == true)
  333. {
  334. FileFd Rel;
  335. // Beware: The 'Release' file might be clearsigned in case the
  336. // signature for an 'InRelease' file couldn't be checked
  337. if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
  338. return false;
  339. if (_error->PendingError() == true)
  340. return false;
  341. Parser.LoadReleaseInfo(File,Rel,Section);
  342. }
  343. return true;
  344. }
  345. /*}}}*/
  346. // PackagesIndex::FindInCache - Find this index /*{{{*/
  347. // ---------------------------------------------------------------------
  348. /* */
  349. pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
  350. {
  351. string FileName = IndexFile("Packages");
  352. pkgCache::PkgFileIterator File = Cache.FileBegin();
  353. for (; File.end() == false; ++File)
  354. {
  355. if (File.FileName() == NULL || FileName != File.FileName())
  356. continue;
  357. struct stat St;
  358. if (stat(File.FileName(),&St) != 0)
  359. {
  360. if (_config->FindB("Debug::pkgCacheGen", false))
  361. std::clog << "PackagesIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  362. return pkgCache::PkgFileIterator(Cache);
  363. }
  364. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  365. {
  366. if (_config->FindB("Debug::pkgCacheGen", false))
  367. std::clog << "PackagesIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  368. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  369. << ") doesn't match for " << File.FileName() << std::endl;
  370. return pkgCache::PkgFileIterator(Cache);
  371. }
  372. return File;
  373. }
  374. return File;
  375. }
  376. /*}}}*/
  377. // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/
  378. // ---------------------------------------------------------------------
  379. /* */
  380. debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section,
  381. char const * const Translation) :
  382. pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section),
  383. Language(Translation)
  384. {}
  385. /*}}}*/
  386. // TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/
  387. // ---------------------------------------------------------------------
  388. /* */
  389. inline string debTranslationsIndex::IndexFile(const char *Type) const
  390. {
  391. string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
  392. std::vector<std::string> types = APT::Configuration::getCompressionTypes();
  393. for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  394. {
  395. string p = s + '.' + *t;
  396. if (FileExists(p))
  397. return p;
  398. }
  399. return s;
  400. }
  401. string debTranslationsIndex::IndexURI(const char *Type) const
  402. {
  403. string Res;
  404. if (Dist[Dist.size() - 1] == '/')
  405. {
  406. if (Dist != "/")
  407. Res = URI + Dist;
  408. else
  409. Res = URI;
  410. }
  411. else
  412. Res = URI + "dists/" + Dist + '/' + Section +
  413. "/i18n/Translation-";
  414. Res += Type;
  415. return Res;
  416. }
  417. /*}}}*/
  418. // TranslationsIndex::GetIndexes - Fetch the index files /*{{{*/
  419. // ---------------------------------------------------------------------
  420. /* */
  421. bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const
  422. {
  423. string const TranslationFile = string("Translation-").append(Language);
  424. new pkgAcqIndexTrans(Owner, IndexURI(Language),
  425. Info(TranslationFile.c_str()),
  426. TranslationFile);
  427. return true;
  428. }
  429. /*}}}*/
  430. // TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/
  431. // ---------------------------------------------------------------------
  432. /* This should help the user find the index in the sources.list and
  433. in the filesystem for problem solving */
  434. string debTranslationsIndex::Describe(bool Short) const
  435. {
  436. char S[300];
  437. if (Short == true)
  438. snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str());
  439. else
  440. snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(),
  441. IndexFile(Language).c_str());
  442. return S;
  443. }
  444. /*}}}*/
  445. // TranslationsIndex::Info - One liner describing the index URI /*{{{*/
  446. // ---------------------------------------------------------------------
  447. /* */
  448. string debTranslationsIndex::Info(const char *Type) const
  449. {
  450. string Info = ::URI::NoUserPassword(URI) + ' ';
  451. if (Dist[Dist.size() - 1] == '/')
  452. {
  453. if (Dist != "/")
  454. Info += Dist;
  455. }
  456. else
  457. Info += Dist + '/' + Section;
  458. Info += " ";
  459. Info += Type;
  460. return Info;
  461. }
  462. /*}}}*/
  463. bool debTranslationsIndex::HasPackages() const /*{{{*/
  464. {
  465. return FileExists(IndexFile(Language));
  466. }
  467. /*}}}*/
  468. // TranslationsIndex::Exists - Check if the index is available /*{{{*/
  469. // ---------------------------------------------------------------------
  470. /* */
  471. bool debTranslationsIndex::Exists() const
  472. {
  473. return FileExists(IndexFile(Language));
  474. }
  475. /*}}}*/
  476. // TranslationsIndex::Size - Return the size of the index /*{{{*/
  477. // ---------------------------------------------------------------------
  478. /* This is really only used for progress reporting. */
  479. unsigned long debTranslationsIndex::Size() const
  480. {
  481. unsigned long size = 0;
  482. /* we need to ignore errors here; if the lists are absent, just return 0 */
  483. _error->PushToStack();
  484. FileFd f(IndexFile(Language), FileFd::ReadOnly, FileFd::Extension);
  485. if (!f.Failed())
  486. size = f.Size();
  487. if (_error->PendingError() == true)
  488. size = 0;
  489. _error->RevertToStack();
  490. return size;
  491. }
  492. /*}}}*/
  493. // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/
  494. // ---------------------------------------------------------------------
  495. /* */
  496. bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  497. {
  498. // Check the translation file, if in use
  499. string TranslationFile = IndexFile(Language);
  500. if (FileExists(TranslationFile))
  501. {
  502. FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
  503. debTranslationsParser TransParser(&Trans);
  504. if (_error->PendingError() == true)
  505. return false;
  506. if (Prog != NULL)
  507. Prog->SubProgress(0, Info(TranslationFile.c_str()));
  508. if (Gen.SelectFile(TranslationFile,string(),*this) == false)
  509. return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
  510. // Store the IMS information
  511. pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
  512. TransFile->Size = Trans.FileSize();
  513. TransFile->mtime = Trans.ModificationTime();
  514. if (Gen.MergeList(TransParser) == false)
  515. return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
  516. }
  517. return true;
  518. }
  519. /*}}}*/
  520. // TranslationsIndex::FindInCache - Find this index /*{{{*/
  521. // ---------------------------------------------------------------------
  522. /* */
  523. pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const
  524. {
  525. string FileName = IndexFile(Language);
  526. pkgCache::PkgFileIterator File = Cache.FileBegin();
  527. for (; File.end() == false; ++File)
  528. {
  529. if (FileName != File.FileName())
  530. continue;
  531. struct stat St;
  532. if (stat(File.FileName(),&St) != 0)
  533. {
  534. if (_config->FindB("Debug::pkgCacheGen", false))
  535. std::clog << "TranslationIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  536. return pkgCache::PkgFileIterator(Cache);
  537. }
  538. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  539. {
  540. if (_config->FindB("Debug::pkgCacheGen", false))
  541. std::clog << "TranslationIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  542. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  543. << ") doesn't match for " << File.FileName() << std::endl;
  544. return pkgCache::PkgFileIterator(Cache);
  545. }
  546. return File;
  547. }
  548. return File;
  549. }
  550. /*}}}*/
  551. // StatusIndex::debStatusIndex - Constructor /*{{{*/
  552. // ---------------------------------------------------------------------
  553. /* */
  554. debStatusIndex::debStatusIndex(string File) : pkgIndexFile(true), File(File)
  555. {
  556. }
  557. /*}}}*/
  558. // StatusIndex::Size - Return the size of the index /*{{{*/
  559. // ---------------------------------------------------------------------
  560. /* */
  561. unsigned long debStatusIndex::Size() const
  562. {
  563. struct stat S;
  564. if (stat(File.c_str(),&S) != 0)
  565. return 0;
  566. return S.st_size;
  567. }
  568. /*}}}*/
  569. // StatusIndex::Merge - Load the index file into a cache /*{{{*/
  570. // ---------------------------------------------------------------------
  571. /* */
  572. bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
  573. {
  574. FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension);
  575. if (_error->PendingError() == true)
  576. return false;
  577. debListParser Parser(&Pkg);
  578. if (_error->PendingError() == true)
  579. return false;
  580. if (Prog != NULL)
  581. Prog->SubProgress(0,File);
  582. if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
  583. return _error->Error("Problem with SelectFile %s",File.c_str());
  584. // Store the IMS information
  585. pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
  586. CFile->Size = Pkg.FileSize();
  587. CFile->mtime = Pkg.ModificationTime();
  588. map_ptrloc const storage = Gen.WriteUniqString("now");
  589. CFile->Archive = storage;
  590. if (Gen.MergeList(Parser) == false)
  591. return _error->Error("Problem with MergeList %s",File.c_str());
  592. return true;
  593. }
  594. /*}}}*/
  595. // StatusIndex::FindInCache - Find this index /*{{{*/
  596. // ---------------------------------------------------------------------
  597. /* */
  598. pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const
  599. {
  600. pkgCache::PkgFileIterator File = Cache.FileBegin();
  601. for (; File.end() == false; ++File)
  602. {
  603. if (this->File != File.FileName())
  604. continue;
  605. struct stat St;
  606. if (stat(File.FileName(),&St) != 0)
  607. {
  608. if (_config->FindB("Debug::pkgCacheGen", false))
  609. std::clog << "StatusIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
  610. return pkgCache::PkgFileIterator(Cache);
  611. }
  612. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  613. {
  614. if (_config->FindB("Debug::pkgCacheGen", false))
  615. std::clog << "StatusIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
  616. << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  617. << ") doesn't match for " << File.FileName() << std::endl;
  618. return pkgCache::PkgFileIterator(Cache);
  619. }
  620. return File;
  621. }
  622. return File;
  623. }
  624. /*}}}*/
  625. // StatusIndex::Exists - Check if the index is available /*{{{*/
  626. // ---------------------------------------------------------------------
  627. /* */
  628. APT_CONST bool debStatusIndex::Exists() const
  629. {
  630. // Abort if the file does not exist.
  631. return true;
  632. }
  633. /*}}}*/
  634. // Index File types for Debian /*{{{*/
  635. class debIFTypeSrc : public pkgIndexFile::Type
  636. {
  637. public:
  638. debIFTypeSrc() {Label = "Debian Source Index";};
  639. };
  640. class debIFTypePkg : public pkgIndexFile::Type
  641. {
  642. public:
  643. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  644. {
  645. return new debRecordParser(File.FileName(),*File.Cache());
  646. };
  647. debIFTypePkg() {Label = "Debian Package Index";};
  648. };
  649. class debIFTypeTrans : public debIFTypePkg
  650. {
  651. public:
  652. debIFTypeTrans() {Label = "Debian Translation Index";};
  653. };
  654. class debIFTypeStatus : public pkgIndexFile::Type
  655. {
  656. public:
  657. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  658. {
  659. return new debRecordParser(File.FileName(),*File.Cache());
  660. };
  661. debIFTypeStatus() {Label = "Debian dpkg status file";};
  662. };
  663. static debIFTypeSrc _apt_Src;
  664. static debIFTypePkg _apt_Pkg;
  665. static debIFTypeTrans _apt_Trans;
  666. static debIFTypeStatus _apt_Status;
  667. const pkgIndexFile::Type *debSourcesIndex::GetType() const
  668. {
  669. return &_apt_Src;
  670. }
  671. const pkgIndexFile::Type *debPackagesIndex::GetType() const
  672. {
  673. return &_apt_Pkg;
  674. }
  675. const pkgIndexFile::Type *debTranslationsIndex::GetType() const
  676. {
  677. return &_apt_Trans;
  678. }
  679. const pkgIndexFile::Type *debStatusIndex::GetType() const
  680. {
  681. return &_apt_Status;
  682. }
  683. /*}}}*/