debsystem.cc 7.2 KB

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