debindexfile.cc 27 KB

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