pkgcachegen.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: pkgcachegen.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $
  4. /* ######################################################################
  5. Package Cache Generator - Generator for the cache structure.
  6. This builds the cache structure from the abstract package list parser.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #include <pkglib/pkgcachegen.h>
  11. #include <pkglib/error.h>
  12. #include <pkglib/version.h>
  13. #include <sys/stat.h>
  14. #include <unistd.h>
  15. /*}}}*/
  16. // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
  17. // ---------------------------------------------------------------------
  18. /* We set the diry flag and make sure that is written to the disk */
  19. pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map) : Map(Map), Cache(Map)
  20. {
  21. if (_error->PendingError() == true)
  22. return;
  23. if (Map.Size() == 0)
  24. {
  25. Map.RawAllocate(sizeof(pkgCache::Header));
  26. *Cache.HeaderP = pkgCache::Header();
  27. }
  28. Cache.HeaderP->Dirty = true;
  29. Map.Sync(0,sizeof(pkgCache::Header));
  30. Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
  31. }
  32. /*}}}*/
  33. // CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/
  34. // ---------------------------------------------------------------------
  35. /* We sync the data then unset the dirty flag in two steps so as to
  36. advoid a problem during a crash */
  37. pkgCacheGenerator::~pkgCacheGenerator()
  38. {
  39. if (_error->PendingError() == true)
  40. return;
  41. if (Map.Sync() == false)
  42. return;
  43. Cache.HeaderP->Dirty = false;
  44. Map.Sync(0,sizeof(pkgCache::Header));
  45. }
  46. /*}}}*/
  47. // CacheGenerator::MergeList - Merge the package list /*{{{*/
  48. // ---------------------------------------------------------------------
  49. /* This provides the generation of the entries in the cache. Each loop
  50. goes through a single package record from the underlying parse engine. */
  51. bool pkgCacheGenerator::MergeList(ListParser &List)
  52. {
  53. List.Owner = this;
  54. do
  55. {
  56. // Get a pointer to the package structure
  57. string Package = List.Package();
  58. pkgCache::PkgIterator Pkg = Cache.FindPkg(Package);
  59. if (Pkg.end() == false)
  60. {
  61. if (NewPackage(Pkg,Package) == false)
  62. return false;
  63. if (List.NewPackage(Pkg) == false)
  64. return false;
  65. }
  66. if (List.UsePackage(Pkg) == false)
  67. return false;
  68. /* Get a pointer to the version structure. We know the list is sorted
  69. so we use that fact in the search. Insertion of new versions is
  70. done with correct sorting */
  71. string Version = List.Version();
  72. pkgCache::VerIterator Ver = Pkg.VersionList();
  73. unsigned long *Last = &Pkg->VersionList;
  74. int Res;
  75. for (; Ver.end() == false; Ver++, Last = &Ver->NextVer)
  76. {
  77. Res = pkgVersionCompare(Version.begin(),Version.end(),Ver.VerStr(),
  78. Ver.VerStr() + strlen(Ver.VerStr()));
  79. if (Res >= 0)
  80. break;
  81. }
  82. /* We already have a version for this item, record that we
  83. saw it */
  84. if (Res == 0)
  85. {
  86. if (NewFileVer(Ver,List) == false)
  87. return false;
  88. continue;
  89. }
  90. // Add a new version
  91. *Last = NewVersion(Ver,*Last);
  92. if (List.NewVersion(Ver) == false)
  93. return false;
  94. if (NewFileVer(Ver,List) == false)
  95. return false;
  96. }
  97. while (List.Step() == true);
  98. return true;
  99. }
  100. /*}}}*/
  101. // CacheGenerator::NewPackage - Add a new package /*{{{*/
  102. // ---------------------------------------------------------------------
  103. /* This creates a new package structure and adds it to the hash table */
  104. bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator Pkg,string Name)
  105. {
  106. // Get a structure
  107. unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
  108. if (Package == 0)
  109. return false;
  110. Pkg = pkgCache::PkgIterator(Cache,Cache.PackageP + Package);
  111. // Insert it into the hash table
  112. unsigned long Hash = Map.Hash(Name);
  113. Pkg->NextPackage = Cache.HeaderP->HashTable[Hash];
  114. Cache.HeaderP->HashTable[Hash] = Package;
  115. // Set the name and the ID
  116. Pkg->Name = Map.WriteString(Name);
  117. if (Pkg->Name == 0)
  118. return false;
  119. Pkg->ID = Cache.HeaderP->PackageCount++;
  120. return true;
  121. }
  122. /*}}}*/
  123. // CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
  124. // ---------------------------------------------------------------------
  125. /* */
  126. bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator Ver,
  127. ListParser &List)
  128. {
  129. }
  130. /*}}}*/
  131. // CacheGenerator::NewVersion - Create a new Version /*{{{*/
  132. // ---------------------------------------------------------------------
  133. /* */
  134. unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
  135. unsigned long Next)
  136. {
  137. }
  138. /*}}}*/
  139. // CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
  140. // ---------------------------------------------------------------------
  141. /* This is used to select which file is to be associated with all newly
  142. added versions. */
  143. bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags)
  144. {
  145. struct stat Buf;
  146. if (stat(File.c_str(),&Buf) == -1)
  147. return _error->Errno("stat","Couldn't stat ",File.c_str());
  148. // Get some space for the structure
  149. CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile));
  150. if (CurrentFile == Cache.PkgFileP)
  151. return false;
  152. // Fill it in
  153. CurrentFile->FileName = Map.WriteString(File);
  154. CurrentFile->Size = Buf.st_size;
  155. CurrentFile->mtime = Buf.st_mtime;
  156. CurrentFile->NextFile = Cache.HeaderP->FileList;
  157. CurrentFile->Flags = Flags;
  158. PkgFileName = File;
  159. if (CurrentFile->FileName == 0)
  160. return false;
  161. }
  162. /*}}}*/