debindexfile.cc 22 KB

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