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.
 
 
 
 
 
 

370 lines
11 KiB

  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. /*}}}*/
  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 NULL;
  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. Res.erase(Target.Description.rfind(' '));
  77. Res += " ";
  78. Res += Ver.ParentPkg().Name();
  79. Res += " ";
  80. std::string const Dist = Target.Option(IndexTarget::RELEASE);
  81. if (Dist.empty() == false && Dist[Dist.size() - 1] != '/')
  82. Res.append(Ver.Arch()).append(" ");
  83. Res += Ver.VerStr();
  84. return Res;
  85. }
  86. uint8_t debPackagesIndex::GetIndexFlags() const
  87. {
  88. return 0;
  89. }
  90. /*}}}*/
  91. // Translation-* Index /*{{{*/
  92. debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) :
  93. pkgDebianIndexTargetFile(Target, true), d(NULL)
  94. {}
  95. bool debTranslationsIndex::HasPackages() const
  96. {
  97. return Exists();
  98. }
  99. bool debTranslationsIndex::OpenListFile(FileFd &Pkg, std::string const &FileName)
  100. {
  101. if (FileExists(FileName))
  102. return pkgDebianIndexTargetFile::OpenListFile(Pkg, FileName);
  103. return true;
  104. }
  105. uint8_t debTranslationsIndex::GetIndexFlags() const
  106. {
  107. return pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages;
  108. }
  109. std::string debTranslationsIndex::GetArchitecture() const
  110. {
  111. return std::string();
  112. }
  113. pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg)
  114. {
  115. if (Pkg.IsOpen() == false)
  116. return NULL;
  117. _error->PushToStack();
  118. pkgCacheListParser * const Parser = new debTranslationsParser(&Pkg);
  119. bool const newError = _error->PendingError();
  120. _error->MergeWithStack();
  121. return newError ? NULL : Parser;
  122. }
  123. /*}}}*/
  124. // dpkg/status Index /*{{{*/
  125. debStatusIndex::debStatusIndex(std::string const &File) : pkgDebianIndexRealFile(File, true), d(NULL)
  126. {
  127. }
  128. std::string debStatusIndex::GetArchitecture() const
  129. {
  130. return std::string();
  131. }
  132. std::string debStatusIndex::GetComponent() const
  133. {
  134. return "now";
  135. }
  136. uint8_t debStatusIndex::GetIndexFlags() const
  137. {
  138. return pkgCache::Flag::NotSource;
  139. }
  140. pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg)
  141. {
  142. if (Pkg.IsOpen() == false)
  143. return NULL;
  144. _error->PushToStack();
  145. pkgCacheListParser * const Parser = new debStatusListParser(&Pkg);
  146. bool const newError = _error->PendingError();
  147. _error->MergeWithStack();
  148. return newError ? NULL : Parser;
  149. }
  150. /*}}}*/
  151. // DebPkgFile Index - a single .deb file as an index /*{{{*/
  152. debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile)
  153. : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile)
  154. {
  155. }
  156. bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile)
  157. {
  158. struct stat Buf;
  159. if (stat(debfile.c_str(), &Buf) != 0)
  160. return false;
  161. // get the control data out of the deb file via dpkg-deb -I
  162. std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb");
  163. std::vector<const char *> Args;
  164. Args.push_back(dpkg.c_str());
  165. Args.push_back("-I");
  166. Args.push_back(debfile.c_str());
  167. Args.push_back("control");
  168. Args.push_back(NULL);
  169. FileFd PipeFd;
  170. pid_t Child;
  171. if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
  172. return _error->Error("Popen failed");
  173. char buffer[1024];
  174. do {
  175. unsigned long long actual = 0;
  176. if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false)
  177. return _error->Errno("read", "Failed to read dpkg pipe");
  178. if (actual == 0)
  179. break;
  180. buffer[actual] = '\0';
  181. content << buffer;
  182. } while(true);
  183. ExecWait(Child, "Popen");
  184. content << "Filename: " << debfile << "\n";
  185. content << "Size: " << Buf.st_size << "\n";
  186. return true;
  187. }
  188. bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName)
  189. {
  190. // write the control data to a tempfile
  191. if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL)
  192. return false;
  193. std::ostringstream content;
  194. if (GetContent(content, FileName) == false)
  195. return false;
  196. std::string const contentstr = content.str();
  197. if (contentstr.empty())
  198. return true;
  199. if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false)
  200. return false;
  201. return true;
  202. }
  203. pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg)
  204. {
  205. if (Pkg.IsOpen() == false)
  206. return NULL;
  207. _error->PushToStack();
  208. pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile);
  209. bool const newError = _error->PendingError();
  210. _error->MergeWithStack();
  211. return newError ? NULL : Parser;
  212. }
  213. uint8_t debDebPkgFileIndex::GetIndexFlags() const
  214. {
  215. return pkgCache::Flag::LocalSource;
  216. }
  217. std::string debDebPkgFileIndex::GetArchitecture() const
  218. {
  219. return std::string();
  220. }
  221. std::string debDebPkgFileIndex::GetComponent() const
  222. {
  223. return "local-deb";
  224. }
  225. pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const
  226. {
  227. std::string const FileName = IndexFileName();
  228. pkgCache::PkgFileIterator File = Cache.FileBegin();
  229. for (; File.end() == false; ++File)
  230. {
  231. if (File.FileName() == NULL || FileName != File.FileName())
  232. continue;
  233. // we can't do size checks here as file size != content size
  234. return File;
  235. }
  236. return File;
  237. }
  238. /*}}}*/
  239. // DscFile Index - a single .dsc file as an index /*{{{*/
  240. debDscFileIndex::debDscFileIndex(std::string const &DscFile)
  241. : pkgDebianIndexRealFile(DscFile, true), d(NULL)
  242. {
  243. }
  244. pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
  245. {
  246. if (Exists() == false)
  247. return NULL;
  248. return new debDscRecordParser(File, this);
  249. }
  250. /*}}}*/
  251. // Index File types for Debian /*{{{*/
  252. class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type
  253. {
  254. public:
  255. debIFTypeSrc() {Label = "Debian Source Index";};
  256. };
  257. class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type
  258. {
  259. public:
  260. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  261. {
  262. return new debRecordParser(File.FileName(),*File.Cache());
  263. };
  264. debIFTypePkg() {Label = "Debian Package Index";};
  265. };
  266. class APT_HIDDEN debIFTypeTrans : public debIFTypePkg
  267. {
  268. public:
  269. debIFTypeTrans() {Label = "Debian Translation Index";};
  270. };
  271. class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type
  272. {
  273. public:
  274. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  275. {
  276. return new debRecordParser(File.FileName(),*File.Cache());
  277. };
  278. debIFTypeStatus() {Label = "Debian dpkg status file";};
  279. };
  280. class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type
  281. {
  282. public:
  283. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE
  284. {
  285. return new debDebFileRecordParser(File.FileName());
  286. };
  287. debIFTypeDebPkgFile() {Label = "Debian deb file";};
  288. };
  289. class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type
  290. {
  291. public:
  292. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE
  293. {
  294. return new debDscRecordParser(DscFile, NULL);
  295. };
  296. debIFTypeDscFile() {Label = "Debian dsc file";};
  297. };
  298. class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type
  299. {
  300. public:
  301. virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE
  302. {
  303. return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL);
  304. };
  305. debIFTypeDebianSourceDir() {Label = "Debian control file";};
  306. };
  307. APT_HIDDEN debIFTypeSrc _apt_Src;
  308. APT_HIDDEN debIFTypePkg _apt_Pkg;
  309. APT_HIDDEN debIFTypeTrans _apt_Trans;
  310. APT_HIDDEN debIFTypeStatus _apt_Status;
  311. APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile;
  312. // file based pseudo indexes
  313. APT_HIDDEN debIFTypeDscFile _apt_DscFile;
  314. APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir;
  315. const pkgIndexFile::Type *debSourcesIndex::GetType() const
  316. {
  317. return &_apt_Src;
  318. }
  319. const pkgIndexFile::Type *debPackagesIndex::GetType() const
  320. {
  321. return &_apt_Pkg;
  322. }
  323. const pkgIndexFile::Type *debTranslationsIndex::GetType() const
  324. {
  325. return &_apt_Trans;
  326. }
  327. const pkgIndexFile::Type *debStatusIndex::GetType() const
  328. {
  329. return &_apt_Status;
  330. }
  331. const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
  332. {
  333. return &_apt_DebPkgFile;
  334. }
  335. const pkgIndexFile::Type *debDscFileIndex::GetType() const
  336. {
  337. return &_apt_DscFile;
  338. }
  339. const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const
  340. {
  341. return &_apt_DebianSourceDir;
  342. }
  343. /*}}}*/
  344. debStatusIndex::~debStatusIndex() {}
  345. debPackagesIndex::~debPackagesIndex() {}
  346. debTranslationsIndex::~debTranslationsIndex() {}
  347. debSourcesIndex::~debSourcesIndex() {}
  348. debDebPkgFileIndex::~debDebPkgFileIndex() {}
  349. debDscFileIndex::~debDscFileIndex() {}