cleanup.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * dpkg - main program for package management
  3. * cleanup.c - cleanup functions, used when we need to unwind
  4. *
  5. * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2,
  10. * or (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public
  18. * License along with dpkg; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <utime.h>
  26. #include <assert.h>
  27. #include <time.h>
  28. #include <ctype.h>
  29. #include <fcntl.h>
  30. #include <sys/stat.h>
  31. #include <sys/types.h>
  32. #include "config.h"
  33. #include "dpkg.h"
  34. #include "dpkg-db.h"
  35. #include "myopt.h"
  36. #include "tarfn.h"
  37. #include "filesdb.h"
  38. #include "main.h"
  39. #include "archives.h"
  40. int cleanup_pkg_failed=0, cleanup_conflictor_failed=0;
  41. void cu_installnew(int argc, void **argv) {
  42. /* Something went wrong and we're undoing.
  43. * We have the following possible situations for non-conffiles:
  44. * <foo>.dpkg-tmp exists - in this case we want to remove
  45. * <foo> if it exists and replace it with <foo>.dpkg-tmp.
  46. * This undoes the backup operation. We also make sure
  47. * we delete <foo>.dpkg-new in case that's still hanging around.
  48. * <foo>.dpkg-tmp does not exist - in this case we haven't
  49. * got as far as creating it (or there wasn't an old version).
  50. * In this case we just delete <foo>.dpkg-new if it exists,
  51. * as it may be a half-extracted thing.
  52. * For conffiles, we simply delete <foo>.dpkg-new. For these,
  53. * <foo>.dpkg-tmp shouldn't exist, as we don't make a backup
  54. * at this stage. Just to be on the safe side, though, we don't
  55. * look for it.
  56. */
  57. struct fileinlist *nifd= (struct fileinlist*)argv[0];
  58. struct filenamenode *namenode;
  59. struct stat stab;
  60. cleanup_pkg_failed++; cleanup_conflictor_failed++;
  61. namenode= nifd->namenode;
  62. debug(dbg_eachfile,"cu_installnew `%s' flags=%o",namenode->name,namenode->flags);
  63. setupfnamevbs(namenode->name);
  64. if (!(namenode->flags & fnnf_new_conff) && !lstat(fnametmpvb.buf,&stab)) {
  65. /* OK, <foo>.dpkg-tmp exists. Remove <foo> and
  66. * restore <foo>.dpkg-tmp ...
  67. */
  68. if (namenode->flags & fnnf_no_atomic_overwrite) {
  69. /* If we can't do an atomic overwrite we have to delete first any
  70. * link to the new version we may have created.
  71. */
  72. debug(dbg_eachfiledetail,"cu_installnew restoring nonatomic");
  73. if (unlinkorrmdir(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
  74. ohshite("unable to remove newly-installed version of `%.250s' to allow"
  75. " reinstallation of backup copy",namenode->name);
  76. } else {
  77. debug(dbg_eachfiledetail,"cu_installnew restoring atomic");
  78. }
  79. /* Either we can do an atomic restore, or we've made room: */
  80. if (rename(fnametmpvb.buf,fnamevb.buf))
  81. ohshite("unable to restore backup version of `%.250s'",namenode->name);
  82. } else {
  83. debug(dbg_eachfiledetail,"cu_installnew not restoring");
  84. }
  85. /* Whatever, we delete <foo>.dpkg-new now, if it still exists. */
  86. if (unlinkorrmdir(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR)
  87. ohshite("unable to remove newly-extracted version of `%.250s'",namenode->name);
  88. cleanup_pkg_failed--; cleanup_conflictor_failed--;
  89. }
  90. void cu_prermupgrade(int argc, void **argv) {
  91. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  92. if (cleanup_pkg_failed++) return;
  93. maintainer_script_installed(pkg,POSTINSTFILE,"post-installation",
  94. "abort-upgrade",
  95. versiondescribe(&pkg->available.version,
  96. vdew_nonambig),
  97. (char*)0);
  98. pkg->status= stat_installed;
  99. pkg->eflag &= ~eflagf_reinstreq;
  100. modstatdb_note(pkg);
  101. cleanup_pkg_failed--;
  102. }
  103. void ok_prermdeconfigure(int argc, void **argv) {
  104. struct pkginfo *deconf= (struct pkginfo*)argv[0];
  105. /* also has conflictor in argv[1] and infavour in argv[2] */
  106. if (cipaction->arg == act_install)
  107. add_to_queue(deconf);
  108. }
  109. void cu_prermdeconfigure(int argc, void **argv) {
  110. struct pkginfo *deconf= (struct pkginfo*)argv[0];
  111. struct pkginfo *conflictor= (struct pkginfo*)argv[1];
  112. struct pkginfo *infavour= (struct pkginfo*)argv[2];
  113. maintainer_script_installed(deconf,POSTINSTFILE,"post-installation",
  114. "abort-deconfigure", "in-favour", infavour->name,
  115. versiondescribe(&infavour->available.version,
  116. vdew_nonambig),
  117. "removing", conflictor->name,
  118. versiondescribe(&conflictor->installed.version,
  119. vdew_nonambig),
  120. (char*)0);
  121. deconf->status= stat_installed;
  122. modstatdb_note(deconf);
  123. }
  124. void cu_prerminfavour(int argc, void **argv) {
  125. struct pkginfo *conflictor= (struct pkginfo*)argv[0];
  126. struct pkginfo *infavour= (struct pkginfo*)argv[1];
  127. if (cleanup_conflictor_failed++) return;
  128. maintainer_script_installed(conflictor,POSTINSTFILE,"post-installation",
  129. "abort-remove", "in-favour", infavour->name,
  130. versiondescribe(&infavour->available.version,
  131. vdew_nonambig),
  132. (char*)0);
  133. conflictor->status= stat_installed;
  134. conflictor->eflag &= ~eflagf_reinstreq;
  135. modstatdb_note(conflictor);
  136. cleanup_conflictor_failed--;
  137. }
  138. void cu_preinstverynew(int argc, void **argv) {
  139. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  140. char *cidir= (char*)argv[1];
  141. char *cidirrest= (char*)argv[2];
  142. if (cleanup_pkg_failed++) return;
  143. maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest,
  144. "abort-install",(char*)0);
  145. pkg->status= stat_notinstalled;
  146. pkg->eflag &= ~eflagf_reinstreq;
  147. modstatdb_note(pkg);
  148. cleanup_pkg_failed--;
  149. }
  150. void cu_preinstnew(int argc, void **argv) {
  151. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  152. char *cidir= (char*)argv[1];
  153. char *cidirrest= (char*)argv[2];
  154. if (cleanup_pkg_failed++) return;
  155. maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest,
  156. "abort-install", versiondescribe(&pkg->installed.version,
  157. vdew_nonambig),
  158. (char*)0);
  159. pkg->status= stat_configfiles;
  160. pkg->eflag &= ~eflagf_reinstreq;
  161. modstatdb_note(pkg);
  162. cleanup_pkg_failed--;
  163. }
  164. void cu_preinstupgrade(int argc, void **argv) {
  165. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  166. char *cidir= (char*)argv[1];
  167. char *cidirrest= (char*)argv[2];
  168. enum pkgstatus *oldstatusp= (enum pkgstatus*)argv[3];
  169. if (cleanup_pkg_failed++) return;
  170. maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest,
  171. "abort-upgrade",
  172. versiondescribe(&pkg->installed.version,
  173. vdew_nonambig),
  174. (char*)0);
  175. pkg->status= *oldstatusp;
  176. pkg->eflag &= ~eflagf_reinstreq;
  177. modstatdb_note(pkg);
  178. cleanup_pkg_failed--;
  179. }
  180. void cu_postrmupgrade(int argc, void **argv) {
  181. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  182. if (cleanup_pkg_failed++) return;
  183. maintainer_script_installed(pkg,PREINSTFILE,"pre-installation",
  184. "abort-upgrade", versiondescribe(&pkg->available.version,
  185. vdew_nonambig),
  186. (char*)0);
  187. cleanup_pkg_failed--;
  188. }
  189. void cu_prermremove(int argc, void **argv) {
  190. struct pkginfo *pkg= (struct pkginfo*)argv[0];
  191. if (cleanup_pkg_failed++) return;
  192. maintainer_script_installed(pkg,POSTINSTFILE,"post-installation",
  193. "abort-remove", (char*)0);
  194. pkg->status= stat_installed;
  195. pkg->eflag &= ~eflagf_reinstreq;
  196. modstatdb_note(pkg);
  197. cleanup_pkg_failed--;
  198. }