debsystem.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: debsystem.cc,v 1.3 2001/04/29 05:13:51 jgg Exp $
  4. /* ######################################################################
  5. System - Abstraction for running on different systems.
  6. Basic general structure..
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #ifdef __GNUG__
  11. #pragma implementation "apt-pkg/debsystem.h"
  12. #endif
  13. #include <apt-pkg/debsystem.h>
  14. #include <apt-pkg/debversion.h>
  15. #include <apt-pkg/debindexfile.h>
  16. #include <apt-pkg/dpkgpm.h>
  17. #include <apt-pkg/configuration.h>
  18. #include <apt-pkg/error.h>
  19. #include <apt-pkg/fileutl.h>
  20. #include <sys/types.h>
  21. #include <unistd.h>
  22. #include <dirent.h>
  23. #include <errno.h>
  24. /*}}}*/
  25. debSystem debSys;
  26. // System::debSystem - Constructor /*{{{*/
  27. // ---------------------------------------------------------------------
  28. /* */
  29. debSystem::debSystem()
  30. {
  31. LockFD = -1;
  32. LockCount = 0;
  33. Label = "Debian dpkg interface";
  34. VS = &debVS;
  35. }
  36. /*}}}*/
  37. // System::~debSystem - Destructor /*{{{*/
  38. // ---------------------------------------------------------------------
  39. /* */
  40. debSystem::~debSystem()
  41. {
  42. delete StatusFile;
  43. }
  44. /*}}}*/
  45. // System::Lock - Get the lock /*{{{*/
  46. // ---------------------------------------------------------------------
  47. /* This mirrors the operations dpkg does when it starts up. Note the
  48. checking of the updates directory. */
  49. bool debSystem::Lock()
  50. {
  51. // Disable file locking
  52. if (_config->FindB("Debug::NoLocking",false) == true || LockCount > 1)
  53. {
  54. LockCount++;
  55. return true;
  56. }
  57. // Create the lockfile
  58. string AdminDir = flNotFile(_config->Find("Dir::State::status"));
  59. LockFD = GetLock(AdminDir + "lock");
  60. if (LockFD == -1)
  61. {
  62. if (errno == EACCES || errno == EAGAIN)
  63. return _error->Error("Unable to lock the administration directory (%s), "
  64. "is another process using it?",AdminDir.c_str());
  65. else
  66. return _error->Error("Unable to lock the administration directory (%s), "
  67. "are you root?",AdminDir.c_str());
  68. }
  69. // See if we need to abort with a dirty journal
  70. if (CheckUpdates() == true)
  71. {
  72. close(LockFD);
  73. LockFD = -1;
  74. return _error->Error("dpkg was interrupted, you must manually "
  75. "run 'dpkg --configure -a' to correct the problem. ");
  76. }
  77. LockCount++;
  78. return true;
  79. }
  80. /*}}}*/
  81. // System::UnLock - Drop a lock /*{{{*/
  82. // ---------------------------------------------------------------------
  83. /* */
  84. bool debSystem::UnLock(bool NoErrors)
  85. {
  86. if (LockCount == 0 && NoErrors == true)
  87. return false;
  88. if (LockCount < 1)
  89. return _error->Error("Not locked");
  90. if (--LockCount == 0)
  91. {
  92. close(LockFD);
  93. LockCount = 0;
  94. }
  95. return true;
  96. }
  97. /*}}}*/
  98. // System::CheckUpdates - Check if the updates dir is dirty /*{{{*/
  99. // ---------------------------------------------------------------------
  100. /* This does a check of the updates directory (dpkg journal) to see if it has
  101. any entries in it. */
  102. bool debSystem::CheckUpdates()
  103. {
  104. // Check for updates.. (dirty)
  105. string File = flNotFile(_config->Find("Dir::State::status")) + "updates/";
  106. DIR *DirP = opendir(File.c_str());
  107. if (DirP == 0)
  108. return false;
  109. /* We ignore any files that are not all digits, this skips .,.. and
  110. some tmp files dpkg will leave behind.. */
  111. bool Damaged = false;
  112. for (struct dirent *Ent = readdir(DirP); Ent != 0; Ent = readdir(DirP))
  113. {
  114. Damaged = true;
  115. for (unsigned int I = 0; Ent->d_name[I] != 0; I++)
  116. {
  117. // Check if its not a digit..
  118. if (isdigit(Ent->d_name[I]) == 0)
  119. {
  120. Damaged = false;
  121. break;
  122. }
  123. }
  124. if (Damaged == true)
  125. break;
  126. }
  127. closedir(DirP);
  128. return Damaged;
  129. }
  130. /*}}}*/
  131. // System::CreatePM - Create the underlying package manager /*{{{*/
  132. // ---------------------------------------------------------------------
  133. /* */
  134. pkgPackageManager *debSystem::CreatePM(pkgDepCache *Cache) const
  135. {
  136. return new pkgDPkgPM(Cache);
  137. }
  138. /*}}}*/
  139. // System::Initialize - Setup the configuration space.. /*{{{*/
  140. // ---------------------------------------------------------------------
  141. /* These are the Debian specific configuration variables.. */
  142. bool debSystem::Initialize(Configuration &Cnf)
  143. {
  144. /* These really should be jammed into a generic 'Local Database' engine
  145. which is yet to be determined. The functions in pkgcachegen should
  146. be the only users of these */
  147. Cnf.CndSet("Dir::State::userstatus","status.user"); // Defunct
  148. Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status");
  149. Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
  150. return true;
  151. }
  152. /*}}}*/
  153. // System::ArchiveSupported - Is a file format supported /*{{{*/
  154. // ---------------------------------------------------------------------
  155. /* The standard name for a deb is 'deb'.. There are no seperate versions
  156. of .deb to worry about.. */
  157. bool debSystem::ArchiveSupported(const char *Type)
  158. {
  159. if (strcmp(Type,"deb") == 0)
  160. return true;
  161. return false;
  162. }
  163. /*}}}*/
  164. // System::Score - Determine how 'Debiany' this sys is.. /*{{{*/
  165. // ---------------------------------------------------------------------
  166. /* We check some files that are sure tell signs of this being a Debian
  167. System.. */
  168. signed debSystem::Score(Configuration const &Cnf)
  169. {
  170. signed Score = 0;
  171. if (FileExists(Cnf.FindFile("Dir::State::status","/var/lib/dpkg/status")) == true)
  172. Score += 10;
  173. if (FileExists(Cnf.FindFile("Dir::Bin::dpkg","/usr/bin/dpkg")) == true)
  174. Score += 10;
  175. if (FileExists("/etc/debian_version") == true)
  176. Score += 10;
  177. return Score;
  178. }
  179. /*}}}*/
  180. // System::AddStatusFiles - Register the status files /*{{{*/
  181. // ---------------------------------------------------------------------
  182. /* */
  183. bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List)
  184. {
  185. if (StatusFile == 0)
  186. StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status"));
  187. List.push_back(StatusFile);
  188. return true;
  189. }
  190. /*}}}*/
  191. // System::FindIndex - Get an index file for status files /*{{{*/
  192. // ---------------------------------------------------------------------
  193. /* */
  194. bool debSystem::FindIndex(pkgCache::PkgFileIterator File,
  195. pkgIndexFile *&Found) const
  196. {
  197. if (StatusFile == 0)
  198. return false;
  199. if (StatusFile->FindInCache(*File.Cache()) == File)
  200. {
  201. Found = StatusFile;
  202. return true;
  203. }
  204. return false;
  205. }
  206. /*}}}*/