diff options
author | Ian Jackson <ian@chiark.chu.cam.ac.uk> | 1996-04-04 01:58:40 +0100 |
---|---|---|
committer | Ian Jackson <ian@chiark.chu.cam.ac.uk> | 1996-04-04 01:58:40 +0100 |
commit | 1b80fb16c22db72457d7a456ffbf1f70a8dfc0a5 (patch) | |
tree | c0ee53eba4e71f4c246ee9e45fbd90e931bbd1f9 /main/cleanup.c | |
download | dpkg-1b80fb16c22db72457d7a456ffbf1f70a8dfc0a5.tar.gz |
dpkg (1.1.4); priority=MEDIUM
* Allow overwriting of conflicting packages being removed. (Bug#2614.)
* a.out control file says Pre-Depends: libc4 | libc. (Bug#2640.)
* ELF control file and libc dependencies changed to use finalised scheme.
* ELF control file and libc dependencies for i386 only. (Bug#2617.)
* Guidelines say use only released libraries and compilers.
* Install wishlist as /usr/doc/dpkg/WISHLIST.
* Remove spurious entries for Guidelines in info dir file.
* dpkg-deb --build checks permissions on control (DEBIAN) directory.
* Spaces in control file fields not copied by dpkg-split. (Bug#2633.)
* Spaces in split file part control data ignore. (Bug#2633.)
* Portability fixes, including patch from Richard Kettlewell.
* Fixed minor configure.in bug causing mangled GCC -W options.
-- Ian Jackson <ian@chiark.chu.cam.ac.uk> Thu, 4 Apr 1996 01:58:40 +0100
Diffstat (limited to 'main/cleanup.c')
-rw-r--r-- | main/cleanup.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/main/cleanup.c b/main/cleanup.c new file mode 100644 index 000000000..b12e3cf16 --- /dev/null +++ b/main/cleanup.c @@ -0,0 +1,226 @@ +/* + * dpkg - main program for package management + * cleanup.c - cleanup functions, used when we need to unwind + * + * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <utime.h> +#include <assert.h> +#include <time.h> +#include <ctype.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "config.h" +#include "dpkg.h" +#include "dpkg-db.h" +#include "myopt.h" +#include "tarfn.h" + +#include "filesdb.h" +#include "main.h" +#include "archives.h" + +int cleanup_pkg_failed=0, cleanup_conflictor_failed=0; + +void cu_installnew(int argc, void **argv) { + /* Something went wrong and we're undoing. + * We have the following possible situations for non-conffiles: + * <foo>.dpkg-tmp exists - in this case we want to remove + * <foo> if it exists and replace it with <foo>.dpkg-tmp. + * This undoes the backup operation. We also make sure + * we delete <foo>.dpkg-new in case that's still hanging around. + * <foo>.dpkg-tmp does not exist - in this case we haven't + * got as far as creating it (or there wasn't an old version). + * In this case we just delete <foo>.dpkg-new if it exists, + * as it may be a half-extracted thing. + * For conffiles, we simply delete <foo>.dpkg-new. For these, + * <foo>.dpkg-tmp shouldn't exist, as we don't make a backup + * at this stage. Just to be on the safe side, though, we don't + * look for it. + */ + struct fileinlist *nifd= (struct fileinlist*)argv[0]; + struct filenamenode *namenode; + struct stat stab; + + cleanup_pkg_failed++; cleanup_conflictor_failed++; + + namenode= nifd->namenode; + debug(dbg_eachfile,"cu_installnew `%s' flags=%o",namenode->name,namenode->flags); + + setupfnamevbs(namenode->name); + + if (!(namenode->flags & fnnf_new_conff) && !lstat(fnametmpvb.buf,&stab)) { + /* OK, <foo>.dpkg-tmp exists. Remove <foo> and + * restore <foo>.dpkg-tmp ... + */ + if (namenode->flags & fnnf_no_atomic_overwrite) { + /* If we can't do an atomic overwrite we have to delete first any + * link to the new version we may have created. + */ + debug(dbg_eachfiledetail,"cu_installnew restoring nonatomic"); + if (unlinkorrmdir(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR) + ohshite("unable to remove newly-installed version of `%.250s' to allow" + " reinstallation of backup copy",namenode->name); + } else { + debug(dbg_eachfiledetail,"cu_installnew restoring atomic"); + } + /* Either we can do an atomic restore, or we've made room: */ + if (rename(fnametmpvb.buf,fnamevb.buf)) + ohshite("unable to restore backup version of `%.250s'",namenode->name); + } else { + debug(dbg_eachfiledetail,"cu_installnew not restoring"); + } + /* Whatever, we delete <foo>.dpkg-new now, if it still exists. */ + if (unlinkorrmdir(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR) + ohshite("unable to remove newly-extracted version of `%.250s'",namenode->name); + + cleanup_pkg_failed--; cleanup_conflictor_failed--; +} + +void cu_prermupgrade(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + + if (cleanup_pkg_failed++) return; + maintainer_script_installed(pkg,POSTINSTFILE,"post-installation", + "abort-upgrade", + versiondescribe(pkg->available.version, + pkg->available.revision), + (char*)0); + pkg->status= stat_installed; + pkg->eflag &= ~eflagf_reinstreq; + modstatdb_note(pkg); + cleanup_pkg_failed--; +} + +void ok_prermdeconfigure(int argc, void **argv) { + struct pkginfo *deconf= (struct pkginfo*)argv[0]; + /* also has conflictor in argv[1] and infavour in argv[2] */ + + if (cipaction->arg == act_install) + add_to_queue(deconf); +} + +void cu_prermdeconfigure(int argc, void **argv) { + struct pkginfo *deconf= (struct pkginfo*)argv[0]; + struct pkginfo *conflictor= (struct pkginfo*)argv[1]; + struct pkginfo *infavour= (struct pkginfo*)argv[2]; + + maintainer_script_installed(deconf,POSTINSTFILE,"post-installation", + "abort-deconfigure", "in-favour", infavour->name, + versiondescribe(infavour->available.version, + infavour->available.revision), + "removing", conflictor->name, + versiondescribe(conflictor->installed.version, + conflictor->installed.revision), + (char*)0); + deconf->status= stat_installed; + modstatdb_note(deconf); +} + +void cu_prerminfavour(int argc, void **argv) { + struct pkginfo *conflictor= (struct pkginfo*)argv[0]; + struct pkginfo *infavour= (struct pkginfo*)argv[1]; + + if (cleanup_conflictor_failed++) return; + maintainer_script_installed(conflictor,POSTINSTFILE,"post-installation", + "abort-remove", "in-favour", infavour->name, + versiondescribe(infavour->available.version, + infavour->available.revision), + (char*)0); + conflictor->status= stat_installed; + conflictor->eflag &= ~eflagf_reinstreq; + modstatdb_note(conflictor); + cleanup_conflictor_failed--; +} + +void cu_preinstverynew(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + char *cidir= (char*)argv[1]; + char *cidirrest= (char*)argv[2]; + + if (cleanup_pkg_failed++) return; + maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest, + "abort-install",(char*)0); + pkg->status= stat_notinstalled; + pkg->eflag &= ~eflagf_reinstreq; + modstatdb_note(pkg); + cleanup_pkg_failed--; +} + +void cu_preinstnew(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + char *cidir= (char*)argv[1]; + char *cidirrest= (char*)argv[2]; + + if (cleanup_pkg_failed++) return; + maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest, + "abort-install", versiondescribe(pkg->installed.version, + pkg->installed.revision), + (char*)0); + pkg->status= stat_configfiles; + pkg->eflag &= ~eflagf_reinstreq; + modstatdb_note(pkg); + cleanup_pkg_failed--; +} + +void cu_preinstupgrade(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + char *cidir= (char*)argv[1]; + char *cidirrest= (char*)argv[2]; + enum pkgstatus *oldstatusp= (enum pkgstatus*)argv[3]; + + if (cleanup_pkg_failed++) return; + maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest, + "abort-upgrade", + versiondescribe(pkg->installed.version, + pkg->installed.revision), + (char*)0); + pkg->status= *oldstatusp; + pkg->eflag &= ~eflagf_reinstreq; + modstatdb_note(pkg); + cleanup_pkg_failed--; +} + +void cu_postrmupgrade(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + + if (cleanup_pkg_failed++) return; + maintainer_script_installed(pkg,PREINSTFILE,"pre-installation", + "abort-upgrade", versiondescribe(pkg->available.version, + pkg->available.revision), + (char*)0); + cleanup_pkg_failed--; +} + +void cu_prermremove(int argc, void **argv) { + struct pkginfo *pkg= (struct pkginfo*)argv[0]; + + if (cleanup_pkg_failed++) return; + maintainer_script_installed(pkg,POSTINSTFILE,"post-installation", + "abort-remove", (char*)0); + pkg->status= stat_installed; + pkg->eflag &= ~eflagf_reinstreq; + modstatdb_note(pkg); + cleanup_pkg_failed--; +} |