Branch data Line data Source code
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 : : */
68 : 0 : void cu_installnew(int argc, void **argv) {
69 : 0 : struct fsys_namenode *namenode = argv[0];
70 : : struct stat stab;
71 : :
72 : 0 : cleanup_pkg_failed++; cleanup_conflictor_failed++;
73 : :
74 : 0 : debug(dbg_eachfile, "cu_installnew '%s' flags=%o",
75 : 0 : namenode->name, namenode->flags);
76 : :
77 : 0 : setupfnamevbs(namenode->name);
78 : :
79 [ # # # # ]: 0 : 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 [ # # ]: 0 : 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 : 0 : debug(dbg_eachfiledetail,"cu_installnew restoring nonatomic");
86 [ # # # # : 0 : if (secure_remove(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
# # ]
87 : 0 : ohshite(_("unable to remove newly-installed version of '%.250s' to allow"
88 : : " reinstallation of backup copy"),namenode->name);
89 : : } else {
90 : 0 : debug(dbg_eachfiledetail,"cu_installnew restoring atomic");
91 : : }
92 : : /* Either we can do an atomic restore, or we've made room: */
93 [ # # ]: 0 : if (rename(fnametmpvb.buf,fnamevb.buf))
94 : 0 : 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 [ # # # # ]: 0 : else if (unlink(fnametmpvb.buf) && errno != ENOENT)
98 : 0 : ohshite(_("unable to remove backup copy of '%.250s'"), namenode->name);
99 [ # # ]: 0 : } else if (namenode->flags & FNNF_PLACED_ON_DISK) {
100 : 0 : debug(dbg_eachfiledetail,"cu_installnew removing new file");
101 [ # # # # : 0 : if (secure_remove(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
# # ]
102 : 0 : ohshite(_("unable to remove newly-installed version of '%.250s'"),
103 : : namenode->name);
104 : : } else {
105 : 0 : debug(dbg_eachfiledetail,"cu_installnew not restoring");
106 : : }
107 : : /* Whatever, we delete «pathname».dpkg-new now, if it still exists. */
108 [ # # # # : 0 : if (secure_remove(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR)
# # ]
109 : 0 : ohshite(_("unable to remove newly-extracted version of '%.250s'"),
110 : : namenode->name);
111 : :
112 : 0 : cleanup_pkg_failed--; cleanup_conflictor_failed--;
113 : 0 : }
114 : :
115 : 0 : void cu_prermupgrade(int argc, void **argv) {
116 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
117 : :
118 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
119 : 0 : maintscript_postinst(pkg, "abort-upgrade",
120 : 0 : versiondescribe(&pkg->available.version, vdew_nonambig),
121 : : NULL);
122 : 0 : pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
123 : 0 : post_postinst_tasks(pkg, PKG_STAT_INSTALLED);
124 : 0 : 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 or multi-arch
130 : : * instance sync.
131 : : */
132 : 0 : void ok_prermdeconfigure(int argc, void **argv) {
133 : 0 : struct pkginfo *deconf= (struct pkginfo*)argv[0];
134 : :
135 [ # # ]: 0 : if (cipaction->arg_int == act_install)
136 : 0 : enqueue_package(deconf);
137 : 0 : }
138 : :
139 : : /*
140 : : * conflictor may be NULL if deconfigure was due to Breaks or multi-arch
141 : : * instance sync.
142 : : */
143 : 0 : void cu_prermdeconfigure(int argc, void **argv) {
144 : 0 : struct pkginfo *deconf= (struct pkginfo*)argv[0];
145 : 0 : struct pkginfo *conflictor = (struct pkginfo *)argv[1];
146 : 0 : struct pkginfo *infavour= (struct pkginfo*)argv[2];
147 : :
148 [ # # ]: 0 : if (conflictor) {
149 : 0 : maintscript_postinst(deconf, "abort-deconfigure",
150 : : "in-favour",
151 : : pkgbin_name(infavour, &infavour->available,
152 : : pnaw_nonambig),
153 : 0 : versiondescribe(&infavour->available.version,
154 : : vdew_nonambig),
155 : : "removing",
156 : : pkg_name(conflictor, pnaw_nonambig),
157 : 0 : versiondescribe(&conflictor->installed.version,
158 : : vdew_nonambig),
159 : : NULL);
160 : : } else {
161 : 0 : maintscript_postinst(deconf, "abort-deconfigure",
162 : : "in-favour",
163 : : pkgbin_name(infavour, &infavour->available,
164 : : pnaw_nonambig),
165 : 0 : versiondescribe(&infavour->available.version,
166 : : vdew_nonambig),
167 : : NULL);
168 : : }
169 : :
170 : 0 : post_postinst_tasks(deconf, PKG_STAT_INSTALLED);
171 : 0 : }
172 : :
173 : 0 : void cu_prerminfavour(int argc, void **argv) {
174 : 0 : struct pkginfo *conflictor= (struct pkginfo*)argv[0];
175 : 0 : struct pkginfo *infavour= (struct pkginfo*)argv[1];
176 : :
177 [ # # ]: 0 : if (cleanup_conflictor_failed++) return;
178 : 0 : maintscript_postinst(conflictor, "abort-remove",
179 : : "in-favour",
180 : : pkgbin_name(infavour, &infavour->available,
181 : : pnaw_nonambig),
182 : 0 : versiondescribe(&infavour->available.version,
183 : : vdew_nonambig),
184 : : NULL);
185 : 0 : pkg_clear_eflags(conflictor, PKG_EFLAG_REINSTREQ);
186 : 0 : post_postinst_tasks(conflictor, PKG_STAT_INSTALLED);
187 : 0 : cleanup_conflictor_failed--;
188 : : }
189 : :
190 : 0 : void cu_preinstverynew(int argc, void **argv) {
191 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
192 : 0 : char *cidir= (char*)argv[1];
193 : 0 : char *cidirrest= (char*)argv[2];
194 : :
195 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
196 : 0 : maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
197 : : "abort-install", NULL);
198 : 0 : pkg_set_status(pkg, PKG_STAT_NOTINSTALLED);
199 : 0 : pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
200 : 0 : pkgbin_blank(&pkg->installed);
201 : 0 : modstatdb_note(pkg);
202 : 0 : cleanup_pkg_failed--;
203 : : }
204 : :
205 : 0 : void cu_preinstnew(int argc, void **argv) {
206 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
207 : 0 : char *cidir= (char*)argv[1];
208 : 0 : char *cidirrest= (char*)argv[2];
209 : :
210 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
211 : 0 : maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
212 : : "abort-install",
213 : 0 : versiondescribe(&pkg->installed.version, vdew_nonambig),
214 : 0 : versiondescribe(&pkg->available.version, vdew_nonambig),
215 : : NULL);
216 : 0 : pkg_set_status(pkg, PKG_STAT_CONFIGFILES);
217 : 0 : pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
218 : 0 : modstatdb_note(pkg);
219 : 0 : cleanup_pkg_failed--;
220 : : }
221 : :
222 : 0 : void cu_preinstupgrade(int argc, void **argv) {
223 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
224 : 0 : char *cidir= (char*)argv[1];
225 : 0 : char *cidirrest= (char*)argv[2];
226 : 0 : enum pkgstatus *oldstatusp= (enum pkgstatus*)argv[3];
227 : :
228 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
229 : 0 : maintscript_new(pkg, POSTRMFILE, "post-removal", cidir, cidirrest,
230 : : "abort-upgrade",
231 : 0 : versiondescribe(&pkg->installed.version, vdew_nonambig),
232 : 0 : versiondescribe(&pkg->available.version, vdew_nonambig),
233 : : NULL);
234 : 0 : pkg_set_status(pkg, *oldstatusp);
235 : 0 : pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
236 : 0 : modstatdb_note(pkg);
237 : 0 : cleanup_pkg_failed--;
238 : : }
239 : :
240 : 0 : void cu_postrmupgrade(int argc, void **argv) {
241 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
242 : :
243 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
244 : 0 : maintscript_installed(pkg, PREINSTFILE, "pre-installation",
245 : : "abort-upgrade",
246 : 0 : versiondescribe(&pkg->available.version, vdew_nonambig),
247 : : NULL);
248 : 0 : cleanup_pkg_failed--;
249 : : }
250 : :
251 : 0 : void cu_prermremove(int argc, void **argv) {
252 : 0 : struct pkginfo *pkg= (struct pkginfo*)argv[0];
253 : 0 : const enum pkgstatus *oldpkgstatus = (enum pkgstatus *)argv[1];
254 : :
255 [ # # ]: 0 : if (cleanup_pkg_failed++) return;
256 : 0 : maintscript_postinst(pkg, "abort-remove", NULL);
257 : 0 : pkg_clear_eflags(pkg, PKG_EFLAG_REINSTREQ);
258 : 0 : post_postinst_tasks(pkg, *oldpkgstatus);
259 : 0 : cleanup_pkg_failed--;
260 : : }
|