debindexfile.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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/error.h>
  17. #include <apt-pkg/fileutl.h>
  18. #include <apt-pkg/indexfile.h>
  19. #include <apt-pkg/pkgcache.h>
  20. #include <apt-pkg/cacheiterators.h>
  21. #include <apt-pkg/pkgrecords.h>
  22. #include <apt-pkg/srcrecords.h>
  23. #include <stdio.h>
  24. #include <iostream>
  25. #include <string>
  26. #include <sstream>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. /*}}}*/
  30. // Sources Index /*{{{*/
  31. debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) :
  32. pkgDebianIndexTargetFile(Target, Trusted), d(NULL)
  33. {
  34. }
  35. std::string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
  36. pkgSrcRecords::File const &File) const
  37. {
  38. // The result looks like: http://foo/debian/ stable/main src 1.1.1 (dsc)
  39. std::string Res = Target.Description;
  40. Res.erase(Target.Description.rfind(' '));
  41. Res += " ";
  42. Res += Record.Package();
  43. Res += " ";
  44. Res += Record.Version();
  45. if (File.Type.empty() == false)
  46. Res += " (" + File.Type + ")";
  47. return Res;
  48. }
  49. pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
  50. {
  51. std::string const SourcesURI = IndexFileName();
  52. if (FileExists(SourcesURI))
  53. return new debSrcRecordParser(SourcesURI, this);
  54. return NULL;
  55. }
  56. bool debSourcesIndex::OpenListFile(FileFd &, std::string const &)
  57. {
  58. return true;
  59. }
  60. pkgCacheListParser * debSourcesIndex::CreateListParser(FileFd &)
  61. {
  62. return NULL;
  63. }
  64. uint8_t debSourcesIndex::GetIndexFlags() const
  65. {
  66. return 0;
  67. }
  68. /*}}}*/
  69. // Packages Index /*{{{*/
  70. debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) :
  71. pkgDebianIndexTargetFile(Target, Trusted), d(NULL)
  72. {
  73. }
  74. std::string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator const &Ver) const
  75. {
  76. std::string Res = Target.Description;
  77. {
  78. auto const space = Target.Description.rfind(' ');
  79. if (space != std::string::npos)
  80. Res.erase(space);
  81. }
  82. Res += " ";
  83. Res += Ver.ParentPkg().Name();
  84. Res += " ";
  85. std::string const Dist = Target.Option(IndexTarget::RELEASE);
  86. if (Dist.empty() == false && Dist[Dist.size() - 1] != '/')
  87. Res.append(Ver.Arch()).append(" ");
  88. Res += Ver.VerStr();
  89. return Res;
  90. }
  91. uint8_t debPackagesIndex::GetIndexFlags() const
  92. {
  93. return 0;
  94. }
  95. /*}}}*/
  96. // Translation-* Index /*{{{*/
  97. debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) :
  98. pkgDebianIndexTargetFile(Target, true), d(NULL)
  99. {}
  100. bool debTranslationsIndex::HasPackages() const
  101. {
  102. return Exists();
  103. }
  104. bool debTranslationsIndex::OpenListFile(FileFd &Pkg, std::string const &FileName)
  105. {
  106. if (FileExists(FileName))
  107. return pkgDebianIndexTargetFile::OpenListFile(Pkg, FileName);
  108. return true;
  109. }
  110. uint8_t debTranslationsIndex::GetIndexFlags() const
  111. {
  112. return pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages;
  113. }
  114. std::string debTranslationsIndex::GetArchitecture() const
  115. {
  116. return std::string();
  117. }
  118. pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg)
  119. {
  120. if (Pkg.IsOpen() == false)
  121. return nullptr;
  122. _error->PushToStack();
  123. pkgCacheListParser * const Parser = new debTranslationsParser(&Pkg);
  124. bool const newError = _error->PendingError();
  125. _error->MergeWithStack();
  126. if (newError)
  127. {
  128. delete Parser;
  129. _error->ReturnError();
  130. return nullptr;
  131. }
  132. else
  133. return Parser;
  134. }
  135. /*}}}*/
  136. // dpkg/status Index /*{{{*/
  137. debStatusIndex::debStatusIndex(std::string const &File) : pkgDebianIndexRealFile(File, true), d(NULL)
  138. {
  139. }
  140. std::string debStatusIndex::GetArchitecture() const
  141. {
  142. return std::string();
  143. }
  144. std::string debStatusIndex::GetComponent() const
  145. {
  146. return "now";
  147. }
  148. uint8_t debStatusIndex::GetIndexFlags() const
  149. {
  150. return pkgCache::Flag::NotSource;
  151. }
  152. pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg)
  153. {
  154. if (Pkg.IsOpen() == false)
  155. return nullptr;
  156. _error->PushToStack();
  157. pkgCacheListParser * const Parser = new debStatusListParser(&Pkg);
  158. bool const newError = _error->PendingError();
  159. _error->MergeWithStack();
  160. if (newError)
  161. {
  162. delete Parser;
  163. _error->ReturnError();
  164. return nullptr;
  165. }
  166. else
  167. return Parser;
  168. }
  169. /*}}}*/
  170. // DebPkgFile Index - a single .deb file as an index /*{{{*/
  171. debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile)
  172. : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile)
  173. {
  174. }
  175. bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile)
  176. {
  177. struct stat Buf;
  178. if (stat(debfile.c_str(), &Buf) != 0)
  179. return false;
  180. // get the control data out of the deb file via dpkg-deb -I
  181. std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb");
  182. std::vector<const char *> Args;
  183. Args.push_back(dpkg.c_str());
  184. Args.push_back("-I");
  185. Args.push_back(debfile.c_str());
  186. Args.push_back("control");
  187. Args.push_back(NULL);
  188. FileFd PipeFd;
  189. pid_t Child;
  190. if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
  191. return _error->Error("Popen failed");
  192. content << "Filename: " << debfile << "\n";
  193. content << "Size: " << std::to_string(Buf.st_size) << "\n";
  194. bool first_line_seen = false;
  195. char buffer[1024];
  196. do {
  197. unsigned long long actual = 0;
  198. if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false)
  199. return _error->Errno("read", "Failed to read dpkg pipe");
  200. if (actual == 0)
  201. break;
  202. buffer[actual] = '\0';
  203. char const * b = buffer;
  204. if (first_line_seen == false)
  205. {
  206. for (; *b != '\0' && (*b == '\n' || *b == '\r'); ++b)
  207. /* skip over leading newlines */;
  208. if (*b == '\0')
  209. continue;
  210. first_line_seen = true;
  211. }
  212. content << b;
  213. } while(true);
  214. ExecWait(Child, "Popen");
  215. return true;
  216. }
  217. bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName)
  218. {
  219. // write the control data to a tempfile
  220. if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL)
  221. return false;
  222. std::ostringstream content;
  223. if (GetContent(content, FileName) == false)
  224. return false;
  225. std::string const contentstr = content.str();
  226. if (contentstr.empty())
  227. return true;
  228. if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false)
  229. return false;
  230. return true;
  231. }
  232. pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg)
  233. {
  234. if (Pkg.IsOpen() == false)
  235. return nullptr;
  236. _error->PushToStack();
  237. pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile);
  238. bool const newError = _error->PendingError();
  239. _error->MergeWithStack();
  240. if (newError)
  241. {
  242. delete Parser;
  243. _error->ReturnError();
  244. return nullptr;
  245. }
  246. else
  247. return Parser;
  248. }
  249. uint8_t debDebPkgFileIndex::GetIndexFlags() const
  250. {
  251. return pkgCache::Flag::LocalSource;
  252. }
  253. std::string debDebPkgFileIndex::GetArchitecture() const
  254. {
  255. return std::string();
  256. }
  257. std::string debDebPkgFileIndex::GetComponent() const
  258. {
  259. return "local-deb";
  260. }
  261. pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const
  262. {
  263. std::string const FileName = IndexFileName();
  264. pkgCache::PkgFileIterator File = Cache.FileBegin();
  265. for (; File.end() == false; ++File)
  266. {
  267. if (File.FileName() == NULL || FileName != File.FileName())
  268. continue;
  269. // we can't do size checks here as file size != content size
  270. return File;
  271. }
  272. return File;
  273. }
  274. std::string debDebPkgFileIndex::ArchiveInfo_impl(pkgCache::VerIterator const &Ver) const
  275. {
  276. std::string Res = IndexFileName() + " ";
  277. Res.append(Ver.ParentPkg().Name()).append(" ");
  278. Res.append(Ver.Arch()).append(" ");
  279. Res.append(Ver.VerStr());
  280. return Res;
  281. }
  282. /*}}}*/
  283. // DscFile Index - a single .dsc file as an index /*{{{*/
  284. debDscFileIndex::debDscFileIndex(std::string const &DscFile)
  285. : pkgDebianIndexRealFile(DscFile, true), d(NULL)
  286. {
  287. }
  288. pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
  289. {
  290. if (Exists() == false)
  291. return NULL;
  292. return new debDscRecordParser(File, this);
  293. }
  294. std::string debDscFileIndex::GetComponent() const
  295. {
  296. return "local-dsc";
  297. }
  298. std::string debDscFileIndex::GetArchitecture() const
  299. {
  300. return "source";
  301. }
  302. uint8_t debDscFileIndex::GetIndexFlags() const
  303. {
  304. return pkgCache::Flag::LocalSource;
  305. }
  306. /*}}}*/
  307. // ControlFile Index - a directory with a debian/control file /*{{{*/
  308. std::string debDebianSourceDirIndex::GetComponent() const
  309. {
  310. return "local-control";
  311. }
  312. /*}}}*/
  313. // String Package Index - a string of Packages file content /*{{{*/
  314. std::string debStringPackageIndex::GetArchitecture() const
  315. {
  316. return std::string();
  317. }
  318. std::string debStringPackageIndex::GetComponent() const
  319. {
  320. return "apt-tmp-index";
  321. }
  322. uint8_t debStringPackageIndex::GetIndexFlags() const
  323. {
  324. return pkgCache::Flag::NotSource;
  325. }
  326. const pkgIndexFile::Type *debStringPackageIndex::GetType() const
  327. {
  328. return pkgIndexFile::Type::GetType("Debian Package Index");
  329. }
  330. debStringPackageIndex::debStringPackageIndex(std::string const &content) :
  331. pkgDebianIndexRealFile("", false), d(NULL)
  332. {
  333. char fn[1024];
  334. std::string const tempdir = GetTempDir();
  335. snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", tempdir.c_str(), "apt-tmp-index");
  336. int const fd = mkstemp(fn);
  337. File = fn;
  338. FileFd::Write(fd, content.data(), content.length());
  339. close(fd);
  340. }
  341. debStringPackageIndex::~debStringPackageIndex()
  342. {
  343. RemoveFile("~debStringPackageIndex", File);
  344. }
  345. /*}}}*/
  346. // Index File types for Debian /*{{{*/
  347. class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type
  348. {
  349. public:
  350. debIFTypeSrc() {Label = "Debian Source Index";};
  351. };
  352. class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type
  353. {
  354. public:
  355. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  356. {
  357. return new debRecordParser(File.FileName(),*File.Cache());
  358. };
  359. debIFTypePkg() {Label = "Debian Package Index";};
  360. };
  361. class APT_HIDDEN debIFTypeTrans : public debIFTypePkg
  362. {
  363. public:
  364. debIFTypeTrans() {Label = "Debian Translation Index";};
  365. };
  366. class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type
  367. {
  368. public:
  369. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  370. {
  371. return new debRecordParser(File.FileName(),*File.Cache());
  372. };
  373. debIFTypeStatus() {Label = "Debian dpkg status file";};
  374. };
  375. class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type
  376. {
  377. public:
  378. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  379. {
  380. return new debDebFileRecordParser(File.FileName());
  381. };
  382. debIFTypeDebPkgFile() {Label = "Debian deb file";};
  383. };
  384. class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
  385. {
  386. public:
  387. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE
  388. {
  389. return new debDscRecordParser(DscFile, NULL);
  390. };
  391. debIFTypeDscFile() {Label = "Debian dsc file";};
  392. };
  393. class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
  394. {
  395. public:
  396. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE
  397. {
  398. return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL);
  399. };
  400. debIFTypeDebianSourceDir() {Label = "Debian control file";};
  401. };
  402. APT_HIDDEN debIFTypeSrc _apt_Src;
  403. APT_HIDDEN debIFTypePkg _apt_Pkg;
  404. APT_HIDDEN debIFTypeTrans _apt_Trans;
  405. APT_HIDDEN debIFTypeStatus _apt_Status;
  406. APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile;
  407. // file based pseudo indexes
  408. APT_HIDDEN debIFTypeDscFile _apt_DscFile;
  409. APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir;
  410. const pkgIndexFile::Type *debSourcesIndex::GetType() const
  411. {
  412. return &_apt_Src;
  413. }
  414. const pkgIndexFile::Type *debPackagesIndex::GetType() const
  415. {
  416. return &_apt_Pkg;
  417. }
  418. const pkgIndexFile::Type *debTranslationsIndex::GetType() const
  419. {
  420. return &_apt_Trans;
  421. }
  422. const pkgIndexFile::Type *debStatusIndex::GetType() const
  423. {
  424. return &_apt_Status;
  425. }
  426. const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
  427. {
  428. return &_apt_DebPkgFile;
  429. }
  430. const pkgIndexFile::Type *debDscFileIndex::GetType() const
  431. {
  432. return &_apt_DscFile;
  433. }
  434. const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const
  435. {
  436. return &_apt_DebianSourceDir;
  437. }
  438. /*}}}*/
  439. debStatusIndex::~debStatusIndex() {}
  440. debPackagesIndex::~debPackagesIndex() {}
  441. debTranslationsIndex::~debTranslationsIndex() {}
  442. debSourcesIndex::~debSourcesIndex() {}
  443. debDebPkgFileIndex::~debDebPkgFileIndex() {}
  444. debDscFileIndex::~debDscFileIndex() {}