debindexfile.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: debindexfile.cc,v 1.3 2001/02/23 06:41:55 jgg Exp $
  4. /* ######################################################################
  5. Debian Specific sources.list types and the three sorts of Debian
  6. index files.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #ifdef __GNUG__
  11. #pragma implementation "apt-pkg/debindexfile.h"
  12. #endif
  13. #include <apt-pkg/debindexfile.h>
  14. #include <apt-pkg/debsrcrecords.h>
  15. #include <apt-pkg/deblistparser.h>
  16. #include <apt-pkg/debrecords.h>
  17. #include <apt-pkg/sourcelist.h>
  18. #include <apt-pkg/configuration.h>
  19. #include <apt-pkg/progress.h>
  20. #include <apt-pkg/error.h>
  21. #include <apt-pkg/strutl.h>
  22. #include <apt-pkg/acquire-item.h>
  23. #include <sys/stat.h>
  24. /*}}}*/
  25. // SourcesIndex::debSourcesIndex - Constructor /*{{{*/
  26. // ---------------------------------------------------------------------
  27. /* */
  28. debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section) :
  29. URI(URI), Dist(Dist), Section(Section)
  30. {
  31. }
  32. /*}}}*/
  33. // SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
  34. // ---------------------------------------------------------------------
  35. /* The result looks like:
  36. http://foo/ stable/main src 1.1.1 (dsc) */
  37. string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
  38. pkgSrcRecords::File const &File) const
  39. {
  40. string Res;
  41. Res = ::URI::SiteOnly(URI) + ' ';
  42. if (Dist[Dist.size() - 1] == '/')
  43. {
  44. if (Dist != "/")
  45. Res += Dist;
  46. }
  47. else
  48. Res += Dist + '/' + Section;
  49. Res += " ";
  50. Res += Record.Package();
  51. Res += " ";
  52. Res += Record.Version();
  53. if (File.Type.empty() == false)
  54. Res += " (" + File.Type + ")";
  55. return Res;
  56. }
  57. /*}}}*/
  58. // SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
  59. // ---------------------------------------------------------------------
  60. /* */
  61. pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
  62. {
  63. string SourcesURI = URItoFileName(IndexURI("Sources"));
  64. return new debSrcRecordParser(_config->FindDir("Dir::State::lists") +
  65. SourcesURI,this);
  66. }
  67. /*}}}*/
  68. // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
  69. // ---------------------------------------------------------------------
  70. /* */
  71. string debSourcesIndex::Describe() const
  72. {
  73. char S[300];
  74. snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
  75. IndexFile("Sources").c_str());
  76. return S;
  77. }
  78. /*}}}*/
  79. // SourcesIndex::Info - One liner describing the index URI /*{{{*/
  80. // ---------------------------------------------------------------------
  81. /* */
  82. string debSourcesIndex::Info(const char *Type) const
  83. {
  84. string Info = ::URI::SiteOnly(URI) + ' ';
  85. if (Dist[Dist.size() - 1] == '/')
  86. {
  87. if (Dist != "/")
  88. Info += Dist;
  89. }
  90. else
  91. Info += Dist + '/' + Section;
  92. Info += " ";
  93. Info += Type;
  94. return Info;
  95. }
  96. /*}}}*/
  97. // SourcesIndex::Index* - Return the URI to the index files /*{{{*/
  98. // ---------------------------------------------------------------------
  99. /* */
  100. inline string debSourcesIndex::IndexFile(const char *Type) const
  101. {
  102. return URItoFileName(IndexURI(Type));
  103. }
  104. string debSourcesIndex::IndexURI(const char *Type) const
  105. {
  106. string Res;
  107. if (Dist[Dist.size() - 1] == '/')
  108. {
  109. if (Dist != "/")
  110. Res = URI + Dist;
  111. else
  112. Res = URI;
  113. }
  114. else
  115. Res = URI + "dists/" + Dist + '/' + Section +
  116. "/source/";
  117. Res += Type;
  118. return Res;
  119. }
  120. /*}}}*/
  121. // SourcesIndex::GetIndexes - Fetch the index files /*{{{*/
  122. // ---------------------------------------------------------------------
  123. /* */
  124. bool debSourcesIndex::GetIndexes(pkgAcquire *Owner) const
  125. {
  126. new pkgAcqIndex(Owner,IndexURI("Sources"),Info("Sources"),"Sources");
  127. new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
  128. return true;
  129. }
  130. /*}}}*/
  131. // SourcesIndex::Exists - Check if the index is available /*{{{*/
  132. // ---------------------------------------------------------------------
  133. /* */
  134. bool debSourcesIndex::Exists() const
  135. {
  136. return FileExists(IndexFile("Sources"));
  137. }
  138. /*}}}*/
  139. // SourcesIndex::Size - Return the size of the index /*{{{*/
  140. // ---------------------------------------------------------------------
  141. /* */
  142. unsigned long debSourcesIndex::Size() const
  143. {
  144. struct stat S;
  145. if (stat(IndexFile("Sources").c_str(),&S) != 0)
  146. return 0;
  147. return S.st_size;
  148. }
  149. /*}}}*/
  150. // PackagesIndex::debPackagesIndex - Contructor /*{{{*/
  151. // ---------------------------------------------------------------------
  152. /* */
  153. debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section) :
  154. URI(URI), Dist(Dist), Section(Section)
  155. {
  156. }
  157. /*}}}*/
  158. // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
  159. // ---------------------------------------------------------------------
  160. /* This is a shorter version that is designed to be < 60 chars or so */
  161. string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
  162. {
  163. string Res = ::URI::SiteOnly(URI) + ' ';
  164. if (Dist[Dist.size() - 1] == '/')
  165. {
  166. if (Dist != "/")
  167. Res += Dist;
  168. }
  169. else
  170. Res += Dist + '/' + Section;
  171. Res += " ";
  172. Res += Ver.ParentPkg().Name();
  173. Res += " ";
  174. Res += Ver.VerStr();
  175. return Res;
  176. }
  177. /*}}}*/
  178. // PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
  179. // ---------------------------------------------------------------------
  180. /* This should help the user find the index in the sources.list and
  181. in the filesystem for problem solving */
  182. string debPackagesIndex::Describe() const
  183. {
  184. char S[300];
  185. snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
  186. IndexFile("Packages").c_str());
  187. return S;
  188. }
  189. /*}}}*/
  190. // PackagesIndex::Info - One liner describing the index URI /*{{{*/
  191. // ---------------------------------------------------------------------
  192. /* */
  193. string debPackagesIndex::Info(const char *Type) const
  194. {
  195. string Info = ::URI::SiteOnly(URI) + ' ';
  196. if (Dist[Dist.size() - 1] == '/')
  197. {
  198. if (Dist != "/")
  199. Info += Dist;
  200. }
  201. else
  202. Info += Dist + '/' + Section;
  203. Info += " ";
  204. Info += Type;
  205. return Info;
  206. }
  207. /*}}}*/
  208. // PackagesIndex::Index* - Return the URI to the index files /*{{{*/
  209. // ---------------------------------------------------------------------
  210. /* */
  211. inline string debPackagesIndex::IndexFile(const char *Type) const
  212. {
  213. return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
  214. }
  215. string debPackagesIndex::IndexURI(const char *Type) const
  216. {
  217. string Res;
  218. if (Dist[Dist.size() - 1] == '/')
  219. {
  220. if (Dist != "/")
  221. Res = URI + Dist;
  222. else
  223. Res = URI;
  224. }
  225. else
  226. Res = URI + "dists/" + Dist + '/' + Section +
  227. "/binary-" + _config->Find("APT::Architecture") + '/';
  228. Res += Type;
  229. return Res;
  230. }
  231. /*}}}*/
  232. // PackagesIndex::GetIndexes - Fetch the index files /*{{{*/
  233. // ---------------------------------------------------------------------
  234. /* */
  235. bool debPackagesIndex::GetIndexes(pkgAcquire *Owner) const
  236. {
  237. new pkgAcqIndex(Owner,IndexURI("Packages"),Info("Packages"),"Packages");
  238. new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
  239. return true;
  240. }
  241. /*}}}*/
  242. // PackagesIndex::Exists - Check if the index is available /*{{{*/
  243. // ---------------------------------------------------------------------
  244. /* */
  245. bool debPackagesIndex::Exists() const
  246. {
  247. return FileExists(IndexFile("Packages"));
  248. }
  249. /*}}}*/
  250. // PackagesIndex::Size - Return the size of the index /*{{{*/
  251. // ---------------------------------------------------------------------
  252. /* This is really only used for progress reporting. */
  253. unsigned long debPackagesIndex::Size() const
  254. {
  255. struct stat S;
  256. if (stat(IndexFile("Packages").c_str(),&S) != 0)
  257. return 0;
  258. return S.st_size;
  259. }
  260. /*}}}*/
  261. // PackagesIndex::Merge - Load the index file into a cache /*{{{*/
  262. // ---------------------------------------------------------------------
  263. /* */
  264. bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
  265. {
  266. string PackageFile = IndexFile("Packages");
  267. FileFd Pkg(PackageFile,FileFd::ReadOnly);
  268. debListParser Parser(&Pkg);
  269. if (_error->PendingError() == true)
  270. return _error->Error("Problem opening %s",PackageFile.c_str());
  271. Prog.SubProgress(0,Info("Packages"));
  272. ::URI Tmp(URI);
  273. if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
  274. return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
  275. // Store the IMS information
  276. pkgCache::PkgFileIterator File = Gen.GetCurFile();
  277. struct stat St;
  278. if (fstat(Pkg.Fd(),&St) != 0)
  279. return _error->Errno("fstat","Failed to stat");
  280. File->Size = St.st_size;
  281. File->mtime = St.st_mtime;
  282. if (Gen.MergeList(Parser) == false)
  283. return _error->Error("Problem with MergeList %s",PackageFile.c_str());
  284. // Check the release file
  285. string ReleaseFile = IndexFile("Release");
  286. if (FileExists(ReleaseFile) == true)
  287. {
  288. FileFd Rel(ReleaseFile,FileFd::ReadOnly);
  289. if (_error->PendingError() == true)
  290. return false;
  291. Parser.LoadReleaseInfo(File,Rel);
  292. }
  293. return true;
  294. }
  295. /*}}}*/
  296. // PackagesIndex::FindInCache - Find this index /*{{{*/
  297. // ---------------------------------------------------------------------
  298. /* */
  299. pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
  300. {
  301. string FileName = IndexFile("Packages");
  302. pkgCache::PkgFileIterator File = Cache.FileBegin();
  303. for (; File.end() == false; File++)
  304. {
  305. if (FileName != File.FileName())
  306. continue;
  307. struct stat St;
  308. if (stat(File.FileName(),&St) != 0)
  309. return pkgCache::PkgFileIterator(Cache);
  310. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  311. return pkgCache::PkgFileIterator(Cache);
  312. return File;
  313. }
  314. return File;
  315. }
  316. /*}}}*/
  317. // StatusIndex::debStatusIndex - Constructor /*{{{*/
  318. // ---------------------------------------------------------------------
  319. /* */
  320. debStatusIndex::debStatusIndex(string File) : File(File)
  321. {
  322. }
  323. /*}}}*/
  324. // StatusIndex::Size - Return the size of the index /*{{{*/
  325. // ---------------------------------------------------------------------
  326. /* */
  327. unsigned long debStatusIndex::Size() const
  328. {
  329. struct stat S;
  330. if (stat(File.c_str(),&S) != 0)
  331. return 0;
  332. return S.st_size;
  333. }
  334. /*}}}*/
  335. // StatusIndex::Merge - Load the index file into a cache /*{{{*/
  336. // ---------------------------------------------------------------------
  337. /* */
  338. bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
  339. {
  340. FileFd Pkg(File,FileFd::ReadOnly);
  341. if (_error->PendingError() == true)
  342. return false;
  343. debListParser Parser(&Pkg);
  344. if (_error->PendingError() == true)
  345. return false;
  346. Prog.SubProgress(0,File);
  347. if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
  348. return _error->Error("Problem with SelectFile %s",File.c_str());
  349. // Store the IMS information
  350. pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
  351. struct stat St;
  352. if (fstat(Pkg.Fd(),&St) != 0)
  353. return _error->Errno("fstat","Failed to stat");
  354. CFile->Size = St.st_size;
  355. CFile->mtime = St.st_mtime;
  356. CFile->Archive = Gen.WriteUniqString("now");
  357. if (Gen.MergeList(Parser) == false)
  358. return _error->Error("Problem with MergeList %s",File.c_str());
  359. return true;
  360. }
  361. /*}}}*/
  362. // StatusIndex::FindInCache - Find this index /*{{{*/
  363. // ---------------------------------------------------------------------
  364. /* */
  365. pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const
  366. {
  367. pkgCache::PkgFileIterator File = Cache.FileBegin();
  368. for (; File.end() == false; File++)
  369. {
  370. if (this->File != File.FileName())
  371. continue;
  372. struct stat St;
  373. if (stat(File.FileName(),&St) != 0)
  374. return pkgCache::PkgFileIterator(Cache);
  375. if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
  376. return pkgCache::PkgFileIterator(Cache);
  377. return File;
  378. }
  379. return File;
  380. }
  381. /*}}}*/
  382. // StatusIndex::Exists - Check if the index is available /*{{{*/
  383. // ---------------------------------------------------------------------
  384. /* */
  385. bool debStatusIndex::Exists() const
  386. {
  387. // Abort if the file does not exist.
  388. return true;
  389. }
  390. /*}}}*/
  391. // Source List types for Debian /*{{{*/
  392. class debSLTypeDeb : public pkgSourceList::Type
  393. {
  394. public:
  395. bool CreateItem(vector<pkgIndexFile *> &List,string URI,
  396. string Dist,string Section) const
  397. {
  398. List.push_back(new debPackagesIndex(URI,Dist,Section));
  399. return true;
  400. };
  401. debSLTypeDeb()
  402. {
  403. Name = "deb";
  404. Label = "Standard Debian binary tree";
  405. }
  406. };
  407. class debSLTypeDebSrc : public pkgSourceList::Type
  408. {
  409. public:
  410. bool CreateItem(vector<pkgIndexFile *> &List,string URI,
  411. string Dist,string Section) const
  412. {
  413. List.push_back(new debSourcesIndex(URI,Dist,Section));
  414. return true;
  415. };
  416. debSLTypeDebSrc()
  417. {
  418. Name = "deb-src";
  419. Label = "Standard Debian source tree";
  420. }
  421. };
  422. debSLTypeDeb _apt_DebType;
  423. debSLTypeDebSrc _apt_DebSrcType;
  424. /*}}}*/
  425. // Index File types for Debian /*{{{*/
  426. class debIFTypeSrc : public pkgIndexFile::Type
  427. {
  428. public:
  429. debIFTypeSrc() {Label = "Debian Source Index";};
  430. };
  431. class debIFTypePkg : public pkgIndexFile::Type
  432. {
  433. public:
  434. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  435. {
  436. return new debRecordParser(File.FileName(),*File.Cache());
  437. };
  438. debIFTypePkg() {Label = "Debian Package Index";};
  439. };
  440. class debIFTypeStatus : public pkgIndexFile::Type
  441. {
  442. public:
  443. virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
  444. {
  445. return new debRecordParser(File.FileName(),*File.Cache());
  446. };
  447. debIFTypeStatus() {Label = "Debian dpkg status file";};
  448. };
  449. static debIFTypeSrc _apt_Src;
  450. static debIFTypePkg _apt_Pkg;
  451. static debIFTypeStatus _apt_Status;
  452. const pkgIndexFile::Type *debSourcesIndex::GetType() const
  453. {
  454. return &_apt_Src;
  455. }
  456. const pkgIndexFile::Type *debPackagesIndex::GetType() const
  457. {
  458. return &_apt_Pkg;
  459. }
  460. const pkgIndexFile::Type *debStatusIndex::GetType() const
  461. {
  462. return &_apt_Status;
  463. }
  464. /*}}}*/