You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

432 lines
12 KiB

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