debsystem.cc 6.5 KB

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