debsystem.cc 7.1 KB

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