1 /*
2  * dpkg - main program for package management
3  * cleanup.c - cleanup functions, used when we need to unwind
4  *
5  * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6  * Copyright © 2007-2015 Guillem Jover <guillem@debian.org>
7  *
8  * This is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 #include <compat.h>
24 
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 
28 #include <errno.h>
29 #include <string.h>
30 #include <time.h>
31 #include <utime.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 
37 #include <dpkg/i18n.h>
38 #include <dpkg/dpkg.h>
39 #include <dpkg/dpkg-db.h>
40 #include <dpkg/pkg.h>
41 #include <dpkg/path.h>
42 #include <dpkg/options.h>
43 #include <dpkg/db-fsys.h>
44 
45 #include "main.h"
46 #include "archives.h"
47 
48 int cleanup_pkg_failed=0, cleanup_conflictor_failed=0;
49 
50 /**
51  * Something went wrong and we're undoing.
52  *
53  * We have the following possible situations for non-conffiles:
54  *   «pathname».dpkg-tmp exists - in this case we want to remove
55  *    «pathname» if it exists and replace it with «pathname».dpkg-tmp.
56  *    This undoes the backup operation.
57  *   «pathname».dpkg-tmp does not exist - «pathname» may be on the disk,
58  *    as a new file which didn't fail, remove it if it is.
59  *
60  * In both cases, we also make sure we delete «pathname».dpkg-new in
61  * case that's still hanging around.
62  *
63  * For conffiles, we simply delete «pathname».dpkg-new. For these,
64  * «pathname».dpkg-tmp shouldn't exist, as we don't make a backup
65  * at this stage. Just to be on the safe side, though, we don't
66  * look for it.
67  */
cu_installnew(int argc,void ** argv)68 void cu_installnew(int argc, void **argv) {
69   struct fsys_namenode *namenode = argv[0];
70   struct stat stab;
71 
72   cleanup_pkg_failed++; cleanup_conflictor_failed++;
73 
74   debug(dbg_eachfile, "cu_installnew '%s' flags=%o",
75         namenode->name, namenode->flags);
76 
77   setupfnamevbs(namenode->name);
78 
79   if (!(namenode->flags & FNNF_NEW_CONFF) && !lstat(fnametmpvb.buf,&stab)) {
80     /* OK, «pathname».dpkg-tmp exists. Remove «pathname» and
81      * restore «pathname».dpkg-tmp ... */
82     if (namenode->flags & FNNF_NO_ATOMIC_OVERWRITE) {
83       /* If we can't do an atomic overwrite we have to delete first any
84        * link to the new version we may have created. */
85       debug(dbg_eachfiledetail,"cu_installnew restoring nonatomic");
86       if (secure_remove(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
87         ohshite(_("unable to remove newly-installed version of '%.250s' to allow"
88                 " reinstallation of backup copy"),namenode->name);
89     } else {
90       debug(dbg_eachfiledetail,"cu_installnew restoring atomic");
91     }
92     /* Either we can do an atomic restore, or we've made room: */
93     if (rename(fnametmpvb.buf,fnamevb.buf))
94       ohshite(_("unable to restore backup version of '%.250s'"), namenode->name);
95     /* If «pathname».dpkg-tmp was still a hard link to «pathname», then the
96      * atomic rename did nothing, so we make sure to remove the backup. */
97     else if (unlink(fnametmpvb.buf) && errno != ENOENT)
98       ohshite(_("unable to remove backup copy of '%.250s'"), namenode->name);
99   } else if (namenode->flags & FNNF_PLACED_ON_DISK) {
100     debug(dbg_eachfiledetail,"cu_installnew removing new file");
101     if (secure_remove(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
102       ohshite(_("unable to remove newly-installed version of '%.250s'"),
103 	      namenode->name);
104   } else {
105     debug(dbg_eachfiledetail,"cu_installnew not restoring");
106   }
107   /* Whatever, we delete «pathname».dpkg-new now, if it still exists. */
108   if (secure_remove(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR)
109     ohshite(_("unable to remove newly-extracted version of '%.250s'"),
110             namenode->name);
111 
112   cleanup_pkg_failed--; cleanup_conflictor_failed--;
113 }
114 
cu_prermupgrade(int argc,void ** argv)115 void cu_prermupgrade(int argc, void **argv) {
116   struct pkginfo *pkg= (struct pkginfo*)argv[0];
117 
118   if (cleanup_pkg_failed++) return;
119   maintscript_postinst(pkg, "abort-upgrade",
120                        versiondescribe(&pkg->available.version, vdew_nonambig),
121                        NULL);
122   pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
123   post_postinst_tasks(pkg, PKG_STAT_INSTALLED);
124   cleanup_pkg_failed--;
125 }
126 
127 /*
128  * Also has conflictor in argv[1] and infavour in argv[2].
129  * conflictor may be NULL if deconfigure was due to Breaks.
130  */
ok_prermdeconfigure(int argc,void ** argv)131 void ok_prermdeconfigure(int argc, void **argv) {
132   struct pkginfo *deconf= (struct pkginfo*)argv[0];
133 
134   if (cipaction->arg_int == act_install)
135     enqueue_package(deconf);
136 }
137 
138 /*
139  * conflictor may be NULL.
140  */
cu_prermdeconfigure(int argc,void ** argv)141 void cu_prermdeconfigure(int argc, void **argv) {
142   struct pkginfo *deconf= (struct pkginfo*)argv[0];
143   struct pkginfo *conflictor = (struct pkginfo *)argv[1];
144   struct pkginfo *infavour= (struct pkginfo*)argv[2];
145 
146   if (conflictor) {
147     maintscript_postinst(deconf, "abort-deconfigure",
148                          "in-favour",
149                          pkgbin_name(infavour, &infavour->available,
150                                      pnaw_nonambig),
151                          versiondescribe(&infavour->available.version,
152                                          vdew_nonambig),
153                          "removing",
154                          pkg_name(conflictor, pnaw_nonambig),
155                          versiondescribe(&conflictor->installed.version,
156                                          vdew_nonambig),
157                          NULL);
158   } else {
159     maintscript_postinst(deconf, "abort-deconfigure",
160                          "in-favour",
161                          pkgbin_name(infavour, &infavour->available,
162                                      pnaw_nonambig),
163                          versiondescribe(&infavour->available.version,
164                                          vdew_nonambig),
165                          NULL);
166   }
167 
168   post_postinst_tasks(deconf, PKG_STAT_INSTALLED);
169 }
170 
cu_prerminfavour(int argc,void ** argv)171 void cu_prerminfavour(int argc, void **argv) {
172   struct pkginfo *conflictor= (struct pkginfo*)argv[0];
173   struct pkginfo *infavour= (struct pkginfo*)argv[1];
174 
175   if (cleanup_conflictor_failed++) return;
176   maintscript_postinst(conflictor, "abort-remove",
177                        "in-favour",
178                        pkgbin_name(infavour, &infavour->available,
179                                    pnaw_nonambig),
180                        versiondescribe(&infavour->available.version,
181                                        vdew_nonambig),
182                        NULL);
183   pkg_clear_eflags(conflictor, PKG_EFLAG_REINSTREQ);
184   post_postinst_tasks(conflictor, PKG_STAT_INSTALLED);
185   cleanup_conflictor_failed--;
186 }
187 
cu_preinstverynew(int argc,void ** argv)188 void cu_preinstverynew(int argc, void **argv) {
189   struct pkginfo *pkg= (struct pkginfo*)argv[0];
190   char *cidir= (char*)argv[1];
191   char *cidirrest= (char*)argv[2];
192 
193   if (cleanup_pkg_failed++) return;
194   maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
195                   "abort-install", NULL);
196   pkg_set_status(pkg, PKG_STAT_NOTINSTALLED);
197   pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
198   pkgbin_blank(&pkg->installed);
199   modstatdb_note(pkg);
200   cleanup_pkg_failed--;
201 }
202 
cu_preinstnew(int argc,void ** argv)203 void cu_preinstnew(int argc, void **argv) {
204   struct pkginfo *pkg= (struct pkginfo*)argv[0];
205   char *cidir= (char*)argv[1];
206   char *cidirrest= (char*)argv[2];
207 
208   if (cleanup_pkg_failed++) return;
209   maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
210                   "abort-install",
211                   versiondescribe(&pkg->installed.version, vdew_nonambig),
212                   versiondescribe(&pkg->available.version, vdew_nonambig),
213                   NULL);
214   pkg_set_status(pkg, PKG_STAT_CONFIGFILES);
215   pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
216   modstatdb_note(pkg);
217   cleanup_pkg_failed--;
218 }
219 
cu_preinstupgrade(int argc,void ** argv)220 void cu_preinstupgrade(int argc, void **argv) {
221   struct pkginfo *pkg= (struct pkginfo*)argv[0];
222   char *cidir= (char*)argv[1];
223   char *cidirrest= (char*)argv[2];
224   enum pkgstatus *oldstatusp= (enum pkgstatus*)argv[3];
225 
226   if (cleanup_pkg_failed++) return;
227   maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
228                   "abort-upgrade",
229                   versiondescribe(&pkg->installed.version, vdew_nonambig),
230                   versiondescribe(&pkg->available.version, vdew_nonambig),
231                   NULL);
232   pkg_set_status(pkg, *oldstatusp);
233   pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
234   modstatdb_note(pkg);
235   cleanup_pkg_failed--;
236 }
237 
cu_postrmupgrade(int argc,void ** argv)238 void cu_postrmupgrade(int argc, void **argv) {
239   struct pkginfo *pkg= (struct pkginfo*)argv[0];
240 
241   if (cleanup_pkg_failed++) return;
242   maintscript_installed(pkg, PREINSTFILE, "pre-installation",
243                         "abort-upgrade",
244                         versiondescribe(&pkg->available.version, vdew_nonambig),
245                         NULL);
246   cleanup_pkg_failed--;
247 }
248 
cu_prermremove(int argc,void ** argv)249 void cu_prermremove(int argc, void **argv) {
250   struct pkginfo *pkg= (struct pkginfo*)argv[0];
251   enum pkgstatus *oldpkgstatus= (enum pkgstatus*)argv[1];
252 
253   if (cleanup_pkg_failed++) return;
254   maintscript_postinst(pkg, "abort-remove", NULL);
255   pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
256   post_postinst_tasks(pkg, *oldpkgstatus);
257   cleanup_pkg_failed--;
258 }
259