Procházet zdrojové kódy

* Implemented a nice fix for multiple conflicts and replaces. Also added
--assert-multi-conrep.

Ben Collins před 27 roky
rodič
revize
95cca77a06
9 změnil soubory, kde provedl 62 přidání a 27 odebrání
  1. 5 0
      ChangeLog
  2. 2 0
      debian/changelog
  3. 5 0
      include/dpkg-db.h
  4. 13 3
      main/archives.c
  5. 1 1
      main/archives.h
  6. 5 0
      main/enquiry.c
  7. 2 1
      main/main.c
  8. 2 1
      main/main.h
  9. 27 21
      main/processarc.c

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+Sat Oct 23 16:25:16 EDT 1999 Ben Collins <bcollins.debian.org>
+
+  * Implemented a nice fix for multiple conflicts and replaces. Also added
+    --assert-multi-conrep.
+
 Sat Oct 23 09:22:16 EDT 1999 Ben Collins <bcollins.debian.org>
 
   * Leave file info intact in available when installing packages. MD5sum,

+ 2 - 0
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 <wakkerma@debian.org>  UNRELEASED
 

+ 5 - 0
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;

+ 13 - 3
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);

+ 1 - 1
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;
 

+ 5 - 0
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.

+ 2 - 1
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=<directory>     Use <directory> 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     ),

+ 2 - 1
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);

+ 27 - 21
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 : "<none>");
+  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);