From: Ben Collins Date: Sat, 23 Oct 1999 21:15:29 +0000 (+0000) Subject: * Implemented a nice fix for multiple conflicts and replaces. Also added X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95cca77a063e0c2bbb754e454f09328c20b731e4;p=dpkg * Implemented a nice fix for multiple conflicts and replaces. Also added --assert-multi-conrep. --- diff --git a/ChangeLog b/ChangeLog index cc57986f..c96d48d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Oct 23 16:25:16 EDT 1999 Ben Collins + + * Implemented a nice fix for multiple conflicts and replaces. Also added + --assert-multi-conrep. + Sat Oct 23 09:22:16 EDT 1999 Ben Collins * Leave file info intact in available when installing packages. MD5sum, diff --git a/debian/changelog b/debian/changelog index 784ca7bf..6a9936d7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,8 @@ dpkg (1.4.1.19) unstable; urgency=low Filename, and MSDOS-Filename used to get lost when installing a package. * Added armv4l to archtable + * Implemented a nice fix for multiple conflicts and replaces. Also added + --assert-multi-conrep. -- Wichert Akkerman UNRELEASED diff --git a/include/dpkg-db.h b/include/dpkg-db.h index a1b89d92..f597dce3 100644 --- a/include/dpkg-db.h +++ b/include/dpkg-db.h @@ -71,6 +71,11 @@ struct deppossi { int cyclebreak; }; +struct conflict { + struct pkginfo *cflict; + struct conflict *next; +}; + struct arbitraryfield { struct arbitraryfield *next; char *name; diff --git a/main/archives.c b/main/archives.c index 65fab3a2..0b4b8f43 100644 --- a/main/archives.c +++ b/main/archives.c @@ -569,7 +569,7 @@ static int try_remove_can(struct deppossi *pdep, } void check_conflict(struct dependency *dep, struct pkginfo *pkg, - const char *pfilename, struct pkginfo **conflictorp) { + const char *pfilename, struct conflict **conflictorp) { struct pkginfo *fixbyrm; struct deppossi *pdep, flagdeppossi; struct varbuf conflictwhy, removalwhy; @@ -578,8 +578,10 @@ void check_conflict(struct dependency *dep, struct pkginfo *pkg, varbufinit(&conflictwhy); varbufinit(&removalwhy); + for ( ; *conflictorp && (*conflictorp)->next ; *conflictorp= (*conflictorp)->next ); + fixbyrm= 0; - if (depisok(dep, &conflictwhy, *conflictorp ? 0 : &fixbyrm, 0)) { + if (depisok(dep, &conflictwhy, &fixbyrm, 0)) { varbuffree(&conflictwhy); varbuffree(&removalwhy); return; @@ -652,7 +654,15 @@ void check_conflict(struct dependency *dep, struct pkginfo *pkg, } if (!pdep) { /* This conflict is OK - we'll remove the conflictor. */ - *conflictorp= fixbyrm; + if (*conflictorp) { + (*conflictorp)->next= nfmalloc(sizeof(struct conflict)); + (*conflictorp)->next->cflict= fixbyrm; + (*conflictorp)->next->next= 0; + } else { + *conflictorp= nfmalloc(sizeof(struct conflict)); + (*conflictorp)->next= 0; + (*conflictorp)->cflict= fixbyrm; + } varbuffree(&conflictwhy); varbuffree(&removalwhy); fprintf(stderr, _("dpkg: yes, will remove %s in favour of %s.\n"), fixbyrm->name, pkg->name); diff --git a/main/archives.h b/main/archives.h index 90f028c1..06f1dd52 100644 --- a/main/archives.h +++ b/main/archives.h @@ -61,7 +61,7 @@ int filesavespackage(struct fileinlist*, struct pkginfo*, struct pkginfo *pkgbeinginstalled); void check_conflict(struct dependency *dep, struct pkginfo *pkg, - const char *pfilename, struct pkginfo **conflictorp); + const char *pfilename, struct conflict **conflictorp); extern int cleanup_pkg_failed, cleanup_conflictor_failed; diff --git a/main/enquiry.c b/main/enquiry.c index e4d7efe6..b2cf5983 100644 --- a/main/enquiry.c +++ b/main/enquiry.c @@ -511,6 +511,11 @@ void assertlongfilenames(const char *const *argv) { assertversion(argv,&epochversion,"1.4.1.17"); } +void assertmulticonrep(const char *const *argv) { + static struct versionrevision epochversion = {~0UL,0,0}; + assertversion(argv,&epochversion,"1.4.1.19"); +} + void predeppackage(const char *const *argv) { /* Print a single package which: * (a) is the target of one or more relevant predependencies. diff --git a/main/main.c b/main/main.c index 0a215758..87c22a3f 100644 --- a/main/main.c +++ b/main/main.c @@ -86,7 +86,7 @@ Use dpkg -b|--build|-c|--contents|-e|--control|-I|--info|-f|--field|\n\ -x|--extract|-X|--vextract|--fsys-tarfile on archives (type %s --help.)\n\ \n\ For internal use: dpkg --assert-support-predepends | --predep-package |\n\ - --assert-working-epoch | --assert-longfilenames\n\ + --assert-working-epoch | --assert-longfilenames | --assert-multi-conrep\n\ \n\ Options:\n\ --admindir= Use instead of %s\n\ @@ -344,6 +344,7 @@ static const struct cmdinfo cmdinfos[]= { ACTION( "assert-support-predepends", 0, act_assertpredep, assertpredep ), ACTION( "assert-working-epoch", 0, act_assertepoch, assertepoch ), ACTION( "assert-long-filenames", 0, act_assertlongfilenames, assertlongfilenames ), + ACTION( "assert-multi-conrep", 0, act_assertmulticonrep, assertmulticonrep ), ACTION( "print-installation-architecture", 0, act_printinstarch, printinstarch ), ACTION( "predep-package", 0, act_predeppackage, predeppackage ), ACTION( "compare-versions", 0, act_cmpversions, cmpversions ), diff --git a/main/main.h b/main/main.h index 03ad1f9d..24ee4c69 100644 --- a/main/main.h +++ b/main/main.h @@ -54,7 +54,7 @@ enum action { act_unset, act_install, act_unpack, act_avail, act_configure, act_assertpredep, act_printarch, act_predeppackage, act_cmpversions, act_printinstarch, act_compareversions, act_printavail, act_avclear, act_forgetold, act_getselections, act_setselections, act_printgnuarch, - act_assertepoch, act_assertlongfilenames }; + act_assertepoch, act_assertlongfilenames, act_assertmulticonrep }; enum conffopt { cfof_prompt = 001, @@ -117,6 +117,7 @@ void enqperpackage(const char *const *argv); void assertepoch(const char *const *argv); void assertpredep(const char *const *argv); void assertlongfilenames(const char *const *argv); +void assertmulticonrep(const char *const *argv); void predeppackage(const char *const *argv); void printarch(const char *const *argv); void printinstarch(const char *const *argv); diff --git a/main/processarc.c b/main/processarc.c index 54e81358..ce413c81 100644 --- a/main/processarc.c +++ b/main/processarc.c @@ -65,7 +65,8 @@ void process_archive(const char *filename) { int c1, r, admindirlen, i, infodirlen, infodirbaseused, status; struct pkgiterator *it; - struct pkginfo *pkg, *conflictor, *otherpkg, *divpkg; + struct pkginfo *pkg, *otherpkg, *divpkg; + struct conflict *conflictor, *cflict; char *cidir, *cidirrest, *p; char pfilenamebuf[35], conffilenamebuf[MAXCONFFILENAME]; const char *pfilename, *newinfofilename; @@ -207,6 +208,8 @@ void process_archive(const char *filename) { return; } + /* Check if anything is installed that we conflict with, or not installed + * that we need */ pkg->clientdata->istobe= itb_installnew; conflictor= 0; for (dsearch= pkg->available.depends; dsearch; dsearch= dsearch->next) { @@ -340,13 +343,15 @@ void process_archive(const char *filename) { * them if they seem to disappear completely. */ oldconffsetflags(pkg->installed.conffiles); - if (conflictor) oldconffsetflags(conflictor->installed.conffiles); + for (cflict= conflictor ; cflict ; cflict= cflict->next) { + oldconffsetflags(cflict->cflict->installed.conffiles); + } oldversionstatus= pkg->status; assert(oldversionstatus <= stat_configfiles); - debug(dbg_general,"process_archive oldversionstatus=%s conflictor=%s", - statusstrings[oldversionstatus], conflictor ? conflictor->name : ""); + debug(dbg_general,"process_archive oldversionstatus=%s", + statusstrings[oldversionstatus]); if (oldversionstatus == stat_halfconfigured || oldversionstatus == stat_installed) { pkg->eflag |= eflagf_reinstreq; @@ -360,13 +365,12 @@ void process_archive(const char *filename) { modstatdb_note(pkg); } - if (conflictor && - (conflictor->status == stat_halfconfigured || - conflictor->status == stat_installed)) { - + for (cflict= conflictor ; cflict ; cflict= cflict->next) { + if (!(cflict->cflict->status == stat_halfconfigured || + cflict->cflict->status == stat_installed)) continue; for (deconpil= deconfigure; deconpil; deconpil= deconpil->next) { printf(_("De-configuring %s, so that we can remove %s ...\n"), - deconpil->pkg->name, conflictor->name); + deconpil->pkg->name, cflict->cflict->name); deconpil->pkg->status= stat_halfconfigured; modstatdb_note(deconpil->pkg); /* This means that we *either* go and run postinst abort-deconfigure, @@ -375,27 +379,27 @@ void process_archive(const char *filename) { */ push_cleanup(cu_prermdeconfigure,~ehflag_normaltidy, ok_prermdeconfigure,ehflag_normaltidy, - 3,(void*)deconpil->pkg,(void*)conflictor,(void*)pkg); + 3,(void*)deconpil->pkg,(void*)cflict->cflict,(void*)pkg); maintainer_script_installed(deconpil->pkg, PRERMFILE, "pre-removal", "deconfigure", "in-favour", pkg->name, versiondescribe(&pkg->available.version, vdew_nonambig), - "removing", conflictor->name, - versiondescribe(&conflictor->installed.version, + "removing", cflict->cflict->name, + versiondescribe(&cflict->cflict->installed.version, vdew_nonambig), (char*)0); } - conflictor->status= stat_halfconfigured; - modstatdb_note(conflictor); + cflict->cflict->status= stat_halfconfigured; + modstatdb_note(cflict->cflict); push_cleanup(cu_prerminfavour,~ehflag_normaltidy, 0,0, - 2,(void*)conflictor,(void*)pkg); - maintainer_script_installed(conflictor, PRERMFILE, "pre-removal", + 2,(void*)cflict->cflict,(void*)pkg); + maintainer_script_installed(cflict->cflict, PRERMFILE, "pre-removal", "remove", "in-favour", pkg->name, versiondescribe(&pkg->available.version, vdew_nonambig), (char*)0); - conflictor->status= stat_halfinstalled; - modstatdb_note(conflictor); + cflict->cflict->status= stat_halfinstalled; + modstatdb_note(cflict->cflict); } pkg->eflag |= eflagf_reinstreq; @@ -797,10 +801,12 @@ void process_archive(const char *filename) { while ((otherpkg= iterpkgnext(it)) != 0) { ensure_package_clientdata(otherpkg); if (otherpkg == pkg || - otherpkg == conflictor || otherpkg->status == stat_notinstalled || otherpkg->status == stat_configfiles || !otherpkg->clientdata->files) continue; + for (cflict= conflictor ; cflict && cflict->cflict != otherpkg ; + cflict= cflict->next); + if (cflict) continue; debug(dbg_veryverbose, "process_archive checking disappearance %s",otherpkg->name); assert(otherpkg->clientdata->istobe == itb_normal || otherpkg->clientdata->istobe == itb_deconfigure); @@ -1002,10 +1008,10 @@ void process_archive(const char *filename) { * as we have not yet updated the filename->packages mappings; however, * the package->filenames mapping is */ - if (conflictor) { + for (cflict= conflictor ; cflict ; cflict= cflict->next) { /* We need to have the most up-to-date info about which files are what ... */ ensure_allinstfiles_available(); - removal_bulk(conflictor); + removal_bulk(cflict->cflict); } if (cipaction->arg == act_install) add_to_queue(pkg);