Your message dated Wed, 05 Sep 2007 05:32:02 +0000
with message-id <[EMAIL PROTECTED]>
and subject line Bug#379140: fixed in dpkg 1.14.6
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: dpkg
Version: 1.13.22
Severity: wishlist
Tags: patch

Attached is the implementation of the new `Breaks' dependency
relationship, as discussed on debian-dpkg recently and debian-devel in
1997.

To apply this patch you need to first apply the patches I've supplied
in #375703 ("Parse, but reject, `Breaks' dependency field") and
#375711 ("Inconsistent formatting in a few files").

I think this patch should be safe to apply to sid's dpkg (the patch
from #375703 definitely is) but I haven't done a deployment plan for
Debian yet; I hope to be able to send a mail about that this weekend.

I'll be filing another bug with consequential changes to the policy
manual, of course.

Ian.

diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/debian/changelog dpkg-1.13.21ubuntu3/debian/changelog
--- orig/dpkg-1.13.21ubuntu3/debian/changelog   2006-07-21 17:17:55.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/debian/changelog        2006-07-21 17:33:57.000000000 
+0100
@@ -1,4 +1,47 @@
-dpkg (1.13.21ubuntu3) edgy; urgency=low
+dpkg (1.13.22ubuntu4) edgy; urgency=low
+
+  * Implement Breaks.  References:
+     http://lists.debian.org/debian-devel/1997/10/msg00643.html
+     https://wiki.ubuntu.com/PackageDependencyFieldBreaks
+
+  Decisions made:
+  * Specifying Breaks: <virtual package> is fairly meaningless
+    without versioned Provides but to make versioned Provides easier
+    in the future we support it fully.
+  * We do not transitively deconfigure things when we deconfigure
+    due to Breaks, just as we don't do so when we deconfigure due
+    to removal due to Conflicts (see also #378009).
+  * Just as for deconfigure due to Conflicts, we don't deconfigure
+    Essential packages without --force-remove-essential.
+  * We aren't willing to deconfigure more than one package as a result
+    of a single element of a Breaks, just as we aren't willing to
+    remove more than one package as a result of a single element of
+    a Conflicts.  (Note that this can only occur due to virtual
+    packages so it can be worked around by specifying the individual
+    real packages instead.)
+  * We're happy to deconfigure a package that's on hold even if
+    afterwards, due to Breaks, there might not be a way to reconfigure it.
+    (This is analogous to the situation where we install a package
+    which no longer satisfies the dependencies of an on-hold
+    package; it's not clear what the right answer is.)
+  * We invent a new --force-breaks which does much the
+    same as --force-conflicts.
+  * --ignore-depends works for Breaks even though it doesn't work
+    for Conflicts.
+  * <deconfigured's prerm> deconfigure in-favour <installing> <ver>
+      as well as
+    <deconfigured's prerm> deconfigure in-favour <installing> <ver> \
+                                       removing <conflictor> <ver>
+      and of course the corresponding
+    <deconfigured's postinst> abort-deconfigure in-favour <installing> <ver>
+
+  Two other changes bundled:
+  * mlib contains m_strdup (part of the fix for #379028).
+  * Fix for #378003 (multiple deconfigurations).
+
+ -- Ian Jackson <[EMAIL PROTECTED]>  Fri, 21 Jul 2006 17:22:24 +0100
+
+dpkg (1.13.22ubuntu3) edgy; urgency=low
 
   * Fix formatting of these files:
        lib/showpkg.c
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/lib/dpkg.h dpkg-1.13.21ubuntu3/lib/dpkg.h
--- orig/dpkg-1.13.21ubuntu3/lib/dpkg.h 2006-01-18 08:30:03.000000000 +0000
+++ dpkg-1.13.21ubuntu3/lib/dpkg.h      2006-07-21 17:20:25.000000000 +0100
@@ -223,6 +223,7 @@
 void setcloexec(int fd, const char* fn);
 void *m_malloc(size_t);
 void *m_realloc(void*, size_t);
+char *m_strdup(const char *s);
 int m_fork(void);
 void m_dup2(int oldfd, int newfd);
 void m_pipe(int fds[2]);
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/lib/mlib.c dpkg-1.13.21ubuntu3/lib/mlib.c
--- orig/dpkg-1.13.21ubuntu3/lib/mlib.c 2006-02-06 21:49:20.000000000 +0000
+++ dpkg-1.13.21ubuntu3/lib/mlib.c      2006-07-21 17:20:25.000000000 +0100
@@ -79,6 +79,15 @@
    */
 }
 
+char *m_strdup(const char *s) {
+  size_t l;
+  char *r;
+  l= strlen(s);
+  r= m_malloc(l+1);
+  strcpy(r,s);
+  return r;
+}
+
 int m_fork(void) {
   pid_t r;
   r= fork();
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/man/C/dpkg.1 dpkg-1.13.21ubuntu3/man/C/dpkg.1
--- orig/dpkg-1.13.21ubuntu3/man/C/dpkg.1       2006-05-17 06:38:11.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/man/C/dpkg.1    2006-07-21 17:31:07.000000000 +0100
@@ -371,6 +371,9 @@
 \fBdepends\-version\fP:
 Don't care about versions when checking dependencies.
 
+\fBbreaks\fP:
+Install, even if this would break another package.
+
 \fBconflicts\fP:
 Install, even if it conflicts with another package. This is dangerous,
 for it will usually cause overwriting of some files.
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/archives.c dpkg-1.13.21ubuntu3/src/archives.c
--- orig/dpkg-1.13.21ubuntu3/src/archives.c     2006-07-21 17:15:29.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/src/archives.c  2006-07-21 17:20:25.000000000 +0100
@@ -821,42 +821,124 @@
   return 0;
 }
 
-static int try_remove_can(struct deppossi *pdep,
-                          struct pkginfo *fixbyrm,
-                          const char *why) {
+static int try_deconfigure_can(int (*force_p)(struct deppossi*),
+                              struct pkginfo *pkg,
+                              struct deppossi *pdep,
+                              const char *action,
+                              struct pkginfo *removal,
+                              const char *why) {
+  /* Also checks whether the pdep is forced, first, according to force_p.
+   * force_p may be 0 in which case nothing is considered forced.
+   *
+   * Action is a string describing the action which causes the
+   * deconfiguration:
+   *     removal of <package>         (due to Conflicts+Depends   removal!=0)
+   *     installation of <package>    (due to Breaks              removal==0)
+   *
+   * Return values:  2: forced (no deconfiguration needed, why is printed)
+   *                 1: deconfiguration queued ok (no message printed)
+   *                 0: not possible (why is printed)
+   */
   struct packageinlist *newdeconf;
   
-  if (force_depends(pdep)) {
+  if (force_p && force_p(pdep)) {
     fprintf(stderr, _("dpkg: warning - "
-            "ignoring dependency problem with removal of %s:\n%s"),
-            fixbyrm->name, why);
-    return 1;
+            "ignoring dependency problem with %s:\n%s"),
+            action, why);
+    return 2;
   } else if (f_autodeconf) {
-    if (pdep->up->up->installed.essential) {
+    if (pkg->installed.essential) {
       if (fc_removeessential) {
         fprintf(stderr, _("dpkg: warning - considering deconfiguration of 
essential\n"
-                " package %s, to enable removal of %s.\n"),
-                pdep->up->up->name,fixbyrm->name);
+                " package %s, to enable %s.\n"),
+                pkg->name, action);
       } else {
         fprintf(stderr, _("dpkg: no, %s is essential, will not deconfigure\n"
-                " it in order to enable removal of %s.\n"),
-                pdep->up->up->name,fixbyrm->name);
+                " it in order to enable %s.\n"),
+                pkg->name, action);
         return 0;
       }
     }
-    pdep->up->up->clientdata->istobe= itb_deconfigure;
+    pkg->clientdata->istobe= itb_deconfigure;
     newdeconf= malloc(sizeof(struct packageinlist));
     newdeconf->next= deconfigure;
-    newdeconf->pkg= pdep->up->up;
+    newdeconf->pkg= pkg;
+    newdeconf->xinfo= removal;
     deconfigure= newdeconf;
     return 1;
   } else {
-    fprintf(stderr, _("dpkg: no, cannot remove %s (--auto-deconfigure will 
help):\n%s"),
-            fixbyrm->name, why);
+    fprintf(stderr, _("dpkg: no, cannot proceed with %s (--auto-deconfigure 
will help):\n%s"),
+            action, why);
     return 0;
   }
 }
 
+static int try_remove_can(struct deppossi *pdep,
+                          struct pkginfo *fixbyrm,
+                          const char *why) {
+  char action[512];
+  sprintf(action,_("removal of %.250s"),fixbyrm->name);
+  return try_deconfigure_can(force_depends, pdep->up->up, pdep,
+                            action, fixbyrm, why);
+}
+
+void check_breaks(struct dependency *dep, struct pkginfo *pkg,
+                 const char *pfilename) {
+  struct pkginfo *fixbydeconf;
+  struct varbuf why;
+  int ok;
+
+  varbufinit(&why);
+
+  fixbydeconf= 0;
+  if (depisok(dep, &why, &fixbydeconf, 0)) {
+    varbuffree(&why);
+    return;
+  }
+
+  varbufaddc(&why,0);
+  
+  if (fixbydeconf && f_autodeconf) {
+    char action[512];
+
+    ensure_package_clientdata(fixbydeconf);
+    assert(fixbydeconf->clientdata->istobe == itb_normal);
+
+    sprintf(action,_("installation of %.250s"),pkg->name);
+    fprintf(stderr, _("dpkg: considering deconfiguration of %s,"
+                     " which would be broken by %s ...\n"),
+           fixbydeconf->name, action);
+
+    ok= try_deconfigure_can(force_breaks, fixbydeconf, dep->list,
+                           action, 0, why.buf);
+    if (ok==1) {
+      fprintf(stderr, _("dpkg: yes, will deconfigure %s (broken by %s).\n"),
+             fixbydeconf->name, pkg->name);
+    }
+  } else {
+    fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
+           pfilename, pkg->name, why.buf);
+    ok= 0;
+  }
+  varbuffree(&why);
+  if (ok>0) return;
+  
+  if (force_breaks(dep->list)) {
+    fprintf(stderr, _("dpkg: warning - ignoring breakage,"
+                     " may proceed anyway !\n"));
+    return;
+  }
+
+  if (fixbydeconf && !f_autodeconf) {
+    ohshit(_("installing %.250s would break %.250s, and\n"
+ " deconfiguration is not permitted (--auto-deconfigure might help)"),
+          pkg->name, fixbydeconf->name);
+  } else {
+    ohshit(_("installing %.250s would break existing software"),
+          pkg->name);
+  }
+}
+
 void check_conflict(struct dependency *dep, struct pkginfo *pkg,
                     const char *pfilename) {
   struct pkginfo *fixbyrm;
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/archives.h dpkg-1.13.21ubuntu3/src/archives.h
--- orig/dpkg-1.13.21ubuntu3/src/archives.h     2006-02-10 16:22:50.000000000 
+0000
+++ dpkg-1.13.21ubuntu3/src/archives.h  2006-07-21 17:20:25.000000000 +0100
@@ -65,6 +65,8 @@
 
 void check_conflict(struct dependency *dep, struct pkginfo *pkg,
                     const char *pfilename);
+void check_breaks(struct dependency *dep, struct pkginfo *pkg,
+                 const char *pfilename);
 
 struct fileinlist *addfiletolist(struct tarcontext *tc,
                                 struct filenamenode *namenode);
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/cleanup.c dpkg-1.13.21ubuntu3/src/cleanup.c
--- orig/dpkg-1.13.21ubuntu3/src/cleanup.c      2006-01-18 08:30:03.000000000 
+0000
+++ dpkg-1.13.21ubuntu3/src/cleanup.c   2006-07-21 17:20:25.000000000 +0100
@@ -120,7 +120,8 @@
 
 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] */
+  /* also has conflictor in argv[1] and infavour in argv[2].
+   * conflictor may be 0 if deconfigure was due to Breaks */
   
   if (cipaction->arg == act_install)
     add_to_queue(deconf);
@@ -128,16 +129,17 @@
 
 void cu_prermdeconfigure(int argc, void **argv) {
   struct pkginfo *deconf= (struct pkginfo*)argv[0];
-  struct pkginfo *conflictor= (struct pkginfo*)argv[1];
+  struct pkginfo *conflictor= (struct pkginfo*)argv[1]; /* may be 0 */
   struct pkginfo *infavour= (struct pkginfo*)argv[2];
 
   maintainer_script_installed(deconf,POSTINSTFILE,"post-installation",
                               "abort-deconfigure", "in-favour", infavour->name,
                               versiondescribe(&infavour->available.version,
                                               vdew_nonambig),
-                              "removing", conflictor->name,
-                              versiondescribe(&conflictor->installed.version,
-                                              vdew_nonambig),
+                              conflictor ? "removing" : (char*)0,
+                             conflictor ? conflictor->name : (char*)0,
+                              conflictor ? 
versiondescribe(&conflictor->installed.version,
+                                              vdew_nonambig) : (char*)0,
                               (char*)0);
   deconf->status= stat_installed;
   modstatdb_note(deconf);
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/configure.c dpkg-1.13.21ubuntu3/src/configure.c
--- orig/dpkg-1.13.21ubuntu3/src/configure.c    2006-07-21 17:15:29.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/src/configure.c 2006-07-21 17:20:25.000000000 +0100
@@ -108,7 +108,9 @@
     pkg->clientdata->istobe= itb_installnew;
     add_to_queue(pkg);
     return;
-  } else if (ok == 0) {
+  }
+  ok= breakses_ok(pkg,&aemsgs) ? ok : 0;
+  if (ok == 0) {
     sincenothing= 0;
     varbufaddc(&aemsgs,0);
     fprintf(stderr,
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/depcon.c dpkg-1.13.21ubuntu3/src/depcon.c
--- orig/dpkg-1.13.21ubuntu3/src/depcon.c       2006-07-11 19:01:38.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/src/depcon.c    2006-07-21 17:20:25.000000000 +0100
@@ -173,6 +173,10 @@
    * before a package is unpacked, when it is sufficient for the package
    * to be unpacked provided that both the unpacked and previously-configured
    * versions are acceptable.
+   * On 0 return (`not OK'), *canfixbyremove refers to a package which
+   * if removed (dep_conflicts) or deconfigured (dep_breaks) will fix
+   * the problem.  Caller may pass 0 for canfixbyremove and need not
+   * initialise *canfixbyremove.
    */
   struct deppossi *possi;
   struct deppossi *provider;
@@ -188,8 +192,10 @@
   assert(dep->type == dep_depends || dep->type == dep_predepends ||
          dep->type == dep_conflicts || dep->type == dep_recommends ||
         dep->type == dep_suggests || dep->type == dep_enhances ||
-        dep->type == dep_breaks );
+        dep->type == dep_breaks);
   
+  if (canfixbyremove) *canfixbyremove= 0;
+
   /* The dependency is always OK if we're trying to remove the depend*ing*
    * package.
    */
@@ -214,16 +220,6 @@
     internerr("unknown istobe depending");
   }
 
-  if (dep->type == dep_breaks)
-    /* We don't implement this and we can only be in this state
-     * if either a Breaks-ignorant or a Breaks-supporting dpkg
-     * installed the package.  In both cases it's probably too
-     * late to do anything useful about it now in this version
-     * so we just ignore it and hope.
-     * fixme-implement-Breaks
-     */
-    return 1;
-
   /* Describe the dependency, in case we have to moan about it. */
   varbufreset(whynot);
   varbufaddc(whynot, ' ');
@@ -357,12 +353,11 @@
       }
     }
 
-    if (canfixbyremove) *canfixbyremove= 0;
     return 0;
 
   } else {
     
-    /* It's a conflict.  There's only one main alternative,
+    /* It's conflicts or breaks.  There's only one main alternative,
      * but we also have to consider Providers.  We return `0' as soon
      * as we find something that matches the conflict, and only describe
      * it then.  If we get to the end without finding anything we return `1'.
@@ -372,11 +367,12 @@
     nconflicts= 0;
 
     if (possi->ed != possi->up->up) {
-      /* If the package conflicts with itself it must mean that it conflicts
-       * with other packages which provide the same virtual name.  We therefore
-       * don't look at the real package and go on to the virtual ones.
+      /* If the package conflicts with or breaks itself it must mean
+       * other packages which provide the same virtual name.  We
+       * therefore don't look at the real package and go on to the
+       * virtual ones.
        */
-      
+
       switch (possi->ed->clientdata->istobe) {
       case itb_remove:
         break;
@@ -390,11 +386,17 @@
         nconflicts++;
         *canfixbyremove= possi->ed;
         break;
-      case itb_normal: case itb_deconfigure: case itb_preinstall:
+      case itb_deconfigure:
+       if (dep->type == dep_breaks) break; /* already deconfiguring this */
+       /* fall through */
+      case itb_normal: case itb_preinstall:
         switch (possi->ed->status) {
         case stat_notinstalled: case stat_configfiles:
           break;
-        default:
+       case stat_halfinstalled: case stat_unpacked:
+       case stat_halfconfigured: 
+         if (dep->type == dep_breaks) break; /* no problem */
+        case stat_installed:
           if (!versionsatisfied(&possi->ed->installed, possi)) break;
           sprintf(linebuf, _("  %.250s (version %.250s) is %s.\n"),
                   possi->ed->name,
@@ -413,7 +415,7 @@
 
     /* If there was no version specified we try looking for Providers. */
     if (possi->verrel == dvr_none) {
-        
+
       /* See if the package we're about to install Provides it. */
       for (provider= possi->ed->available.depended;
            provider;
@@ -447,11 +449,16 @@
           continue; 
         case itb_remove:
           continue;
-        case itb_normal: case itb_deconfigure: case itb_preinstall:
+       case itb_deconfigure:
+         if (dep->type == dep_breaks) continue; /* already deconfiguring */
+        case itb_normal: case itb_preinstall:
           switch (provider->up->up->status) {
           case stat_notinstalled: case stat_configfiles:
             continue;
-          default:
+         case stat_halfinstalled: case stat_unpacked:
+         case stat_halfconfigured: 
+           if (dep->type == dep_breaks) break; /* no problem */
+          case stat_installed:
             sprintf(linebuf, _("  %.250s provides %.250s and is %s.\n"),
                     provider->up->up->name, possi->ed->name,
                     gettext(statusstrings[provider->up->up->status]));
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/help.c dpkg-1.13.21ubuntu3/src/help.c
--- orig/dpkg-1.13.21ubuntu3/src/help.c 2006-05-19 23:46:39.000000000 +0100
+++ dpkg-1.13.21ubuntu3/src/help.c      2006-07-21 17:20:25.000000000 +0100
@@ -152,6 +152,12 @@
          ignore_depends(possi->up->up);
 }
 
+int force_breaks(struct deppossi *possi) {
+  return fc_breaks ||
+         ignore_depends(possi->ed) ||
+         ignore_depends(possi->up->up);
+}
+
 int force_conflicts(struct deppossi *possi) {
   return fc_conflicts;
 }
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/main.c dpkg-1.13.21ubuntu3/src/main.c
--- orig/dpkg-1.13.21ubuntu3/src/main.c 2006-06-02 04:45:21.000000000 +0100
+++ dpkg-1.13.21ubuntu3/src/main.c      2006-07-21 17:20:25.000000000 +0100
@@ -154,7 +154,7 @@
 /* Change fc_overwrite to 1 to enable force-overwrite by default */
 int fc_downgrade=1, fc_configureany=0, fc_hold=0, fc_removereinstreq=0, 
fc_overwrite=0;
 int fc_removeessential=0, fc_conflicts=0, fc_depends=0, fc_dependsversion=0;
-int fc_badpath=0, fc_overwritediverted=0, fc_architecture=0;
+int fc_breaks=0, fc_badpath=0, fc_overwritediverted=0, fc_architecture=0;
 int fc_nonroot=0, fc_overwritedir=0, fc_conff_new=0, fc_conff_miss=0;
 int fc_conff_old=0, fc_conff_def=0;
 int fc_badverify = 0;
@@ -180,6 +180,7 @@
   { "confmiss",            &fc_conff_miss               },
   { "depends",             &fc_depends                  },
   { "depends-version",     &fc_dependsversion           },
+  { "breaks",              &fc_breaks                   },
   { "bad-path",            &fc_badpath                  },
   { "not-root",            &fc_nonroot                  },
   { "overwrite",           &fc_overwrite                },
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/main.h dpkg-1.13.21ubuntu3/src/main.h
--- orig/dpkg-1.13.21ubuntu3/src/main.h 2006-05-19 23:46:39.000000000 +0100
+++ dpkg-1.13.21ubuntu3/src/main.h      2006-07-21 17:20:25.000000000 +0100
@@ -46,6 +46,7 @@
 struct packageinlist {
   struct packageinlist *next;
   struct pkginfo *pkg;
+  void *xinfo;
 };
 
 enum action { act_unset, act_install, act_unpack, act_avail, act_configure,
@@ -86,7 +87,7 @@
 extern unsigned long f_debug;
 extern int fc_downgrade, fc_configureany, fc_hold, fc_removereinstreq, 
fc_overwrite;
 extern int fc_removeessential, fc_conflicts, fc_depends, fc_dependsversion;
-extern int fc_badpath, fc_overwritediverted, fc_architecture;
+extern int fc_breaks, fc_badpath, fc_overwritediverted, fc_architecture;
 extern int fc_nonroot, fc_overwritedir, fc_conff_new, fc_conff_miss;
 extern int fc_conff_old, fc_conff_def;
 extern int fc_badverify;
@@ -150,7 +151,8 @@
 void removal_bulk(struct pkginfo *pkg);
 int conffderef(struct pkginfo *pkg, struct varbuf *result, const char *in);
 int dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
-                    struct varbuf *aemsgs);
+                    struct varbuf *aemsgs); /* checks [Pre]-Depends only */
+int breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs);
 
 void deferred_remove(struct pkginfo *pkg);
 void deferred_configure(struct pkginfo *pkg);
@@ -177,6 +179,7 @@
 void cu_closefd(int argc, void **argv);
 
 int ignore_depends(struct pkginfo *pkg);
+int force_breaks(struct deppossi *possi);
 int force_depends(struct deppossi *possi);
 int force_conff_new(struct deppossi *possi);
 int force_conff_miss(struct deppossi *possi);
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/packages.c dpkg-1.13.21ubuntu3/src/packages.c
--- orig/dpkg-1.13.21ubuntu3/src/packages.c     2006-07-11 19:01:38.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/src/packages.c  2006-07-21 17:20:25.000000000 +0100
@@ -339,6 +339,82 @@
   }
 }
 
+static void breaks_check_one(struct varbuf *aemsgs, int *ok,
+                            struct deppossi *breaks,
+                            struct pkginfo *broken,
+                            struct pkginfo *breaker,
+                            struct pkginfo *virtbroken) {
+  struct varbuf depmsg;
+                 
+  debug(dbg_depcondetail,"      checking breaker %s virtbroken %s",
+       breaker->name, virtbroken ? virtbroken->name : "<none>");
+
+  if (breaker->status == stat_notinstalled ||
+      breaker->status == stat_configfiles) return;
+  if (broken == breaker) return;
+  if (!versionsatisfied(&breaker->installed, breaks)) return;
+  if (ignore_depends(breaker)) return;
+  if (virtbroken && ignore_depends(virtbroken)) return;
+
+  varbufinit(&depmsg);
+  varbufdependency(&depmsg, breaks->up);
+  varbufaddc(&depmsg, 0);
+  varbufprintf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"),
+              breaker->name, 
+              versiondescribe(&breaker->installed.version,
+                              vdew_nonambig),
+              depmsg.buf,
+              gettext(statusstrings[breaker->status]));
+  varbuffree(&depmsg);
+  
+  if (virtbroken) {
+    varbufprintf(aemsgs, _("  %s (%s) provides %s.\n"),
+                broken->name,
+                versiondescribe(&broken->installed.version,
+                                vdew_nonambig),
+                virtbroken->name);
+  } else if (breaks->verrel != dvr_none) {
+    varbufprintf(aemsgs, _("  Version of %s to be configured is %s.\n"),
+                broken->name,
+                versiondescribe(&broken->installed.version,
+                                vdew_nonambig));
+    if (fc_dependsversion) return;
+  }
+  if (force_breaks(breaks)) return;
+  *ok= 0;
+}  
+
+void breaks_check_target(struct varbuf *aemsgs, int *ok,
+                        struct pkginfo *broken,
+                        struct pkginfo *target,
+                        struct pkginfo *virtbroken) {
+  struct deppossi *possi;
+  
+  for (possi= target->installed.depended; possi; possi= possi->nextrev) {
+    if (possi->up->type != dep_breaks) continue;
+    if (virtbroken && possi->verrel != dvr_none) continue;
+    breaks_check_one(aemsgs,ok, possi,broken,possi->up->up,virtbroken);
+  }
+}
+
+int breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs) {
+  struct dependency *dep;
+  struct pkginfo *virtbroken;
+  int ok= 2;
+
+  debug(dbg_depcon,"    checking Breaks");
+
+  breaks_check_target(aemsgs,&ok, pkg,pkg,0);
+
+  for (dep= pkg->installed.depends; dep; dep= dep->next) {
+    if (dep->type != dep_provides) continue;
+    virtbroken= dep->list->ed;
+    debug(dbg_depcondetail,"     checking virtbroken %s", virtbroken->name);
+    breaks_check_target(aemsgs,&ok, pkg,virtbroken,virtbroken);
+  }
+  return ok;
+}
+
 int dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
                     struct varbuf *aemsgs) {
   int ok, matched, found, thisf, interestingwarnings;
@@ -352,9 +428,6 @@
   debug(dbg_depcon,"checking dependencies of %s (- %s)",
         pkg->name, removing ? removing->name : "<none>");
   assert(pkg->installed.valid);
-  /* To implement Breaks we need to add code here which prevents
-   * configuration of Broken packages.
-   * fixme-implement-Breaks */
   for (dep= pkg->installed.depends; dep; dep= dep->next) {
     if (dep->type != dep_depends && dep->type != dep_predepends) continue;
     debug(dbg_depcondetail,"  checking group ...");
diff --exclude='*.orig' --exclude=TAGS --exclude='*~' -ruN 
orig/dpkg-1.13.21ubuntu3/src/processarc.c dpkg-1.13.21ubuntu3/src/processarc.c
--- orig/dpkg-1.13.21ubuntu3/src/processarc.c   2006-07-11 19:01:38.000000000 
+0100
+++ dpkg-1.13.21ubuntu3/src/processarc.c        2006-07-21 17:20:25.000000000 
+0100
@@ -241,6 +241,10 @@
       /* Look for things we conflict with. */
       check_conflict(dsearch, pkg, pfilename);
       break;
+    case dep_breaks:
+      /* Look for things we break. */
+      check_breaks(dsearch, pkg, pfilename);
+      break;
     case dep_provides:
       /* Look for things that conflict with what we provide. */
       if (dsearch->list->ed->installed.valid) {
@@ -252,16 +256,6 @@
         }
       }
       break;
-    case dep_breaks:
-      fprintf(stderr, _("dpkg: regarding %s containing %s:\n"
-                       " package uses Breaks; not supported in this dpkg\n"),
-             pfilename, pkg->name);
-      if (!force_depends(dsearch->list))
-       ohshit(_("unsupported dependency problem - not installing %.250s"),
-              pkg->name);
-      fprintf(stderr, _("dpkg: warning - ignoring Breaks !\n"));
-      /* fixme-implement-Breaks */
-      break;
     case dep_suggests:
     case dep_recommends:
     case dep_depends:
@@ -404,31 +398,36 @@
     modstatdb_note(pkg);
   }
 
+  for (deconpil= deconfigure; deconpil; deconpil= deconpil->next) {
+    struct pkginfo *removing= deconpil->xinfo;
+    
+    printf(removing ?
+          _("De-configuring %s, to allow removal of %s ...\n") :
+          _("De-configuring %s ...\n"),
+          deconpil->pkg->name, removing ? removing->name : 0);
+    deconpil->pkg->status= stat_halfconfigured;
+    modstatdb_note(deconpil->pkg);
+    /* This means that we *either* go and run postinst abort-deconfigure,
+     * *or* queue the package for later configure processing, depending
+     * on which error cleanup route gets taken.
+     */
+    push_cleanup(cu_prermdeconfigure,~ehflag_normaltidy,
+                ok_prermdeconfigure,ehflag_normaltidy,
+                3,(void*)deconpil->pkg,(void*)removing,(void*)pkg);
+    maintainer_script_installed(deconpil->pkg, PRERMFILE, "pre-removal",
+                               "deconfigure", "in-favour", pkg->name,
+                               versiondescribe(&pkg->available.version,
+                                               vdew_nonambig),
+                               removing ? "removing" : (char*)0,
+                               removing ? removing->name : (char*)0,
+                               removing ? 
versiondescribe(&removing->installed.version,
+                                               vdew_nonambig) : (char*)0,
+                               (char*)0);
+  }
+
   for (i = 0 ; i < cflict_index ; i++) {
     if (!(conflictor[i]->status == stat_halfconfigured ||
          conflictor[i]->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[i]->name);
-      deconpil->pkg->status= stat_halfconfigured;
-      modstatdb_note(deconpil->pkg);
-      /* This means that we *either* go and run postinst abort-deconfigure,
-       * *or* queue the package for later configure processing, depending
-       * on which error cleanup route gets taken.
-       */
-      push_cleanup(cu_prermdeconfigure,~ehflag_normaltidy,
-                   ok_prermdeconfigure,ehflag_normaltidy,
-                   3,(void*)deconpil->pkg,
-                  (void*)conflictor[i],(void*)pkg);
-      maintainer_script_installed(deconpil->pkg, PRERMFILE, "pre-removal",
-                                  "deconfigure", "in-favour", pkg->name,
-                                  versiondescribe(&pkg->available.version,
-                                                  vdew_nonambig),
-                                  "removing", conflictor[i]->name,
-                                  
versiondescribe(&conflictor[i]->installed.version,
-                                                  vdew_nonambig),
-                                  (char*)0);
-    }
     conflictor[i]->status= stat_halfconfigured;
     modstatdb_note(conflictor[i]);
     push_cleanup(cu_prerminfavour,~ehflag_normaltidy, 0,0,

--- End Message ---
--- Begin Message ---
Source: dpkg
Source-Version: 1.14.6

We believe that the bug you reported is fixed in the latest version of
dpkg, which is due to be installed in the Debian FTP archive:

dpkg-dev_1.14.6_all.deb
  to pool/main/d/dpkg/dpkg-dev_1.14.6_all.deb
dpkg_1.14.6.dsc
  to pool/main/d/dpkg/dpkg_1.14.6.dsc
dpkg_1.14.6.tar.gz
  to pool/main/d/dpkg/dpkg_1.14.6.tar.gz
dpkg_1.14.6_i386.deb
  to pool/main/d/dpkg/dpkg_1.14.6_i386.deb
dselect_1.14.6_i386.deb
  to pool/main/d/dpkg/dselect_1.14.6_i386.deb



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [EMAIL PROTECTED],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Guillem Jover <[EMAIL PROTECTED]> (supplier of updated dpkg package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [EMAIL PROTECTED])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.7
Date: Wed, 05 Sep 2007 07:36:02 +0300
Source: dpkg
Binary: dpkg dselect dpkg-dev
Architecture: source i386 all
Version: 1.14.6
Distribution: unstable
Urgency: low
Maintainer: Dpkg Developers <[EMAIL PROTECTED]>
Changed-By: Guillem Jover <[EMAIL PROTECTED]>
Description: 
 dpkg       - package maintenance system for Debian
 dpkg-dev   - package building tools for Debian
 dselect    - user tool to manage Debian packages
Closes: 142324 321520 377682 378003 379140 392317 411699 428427 430931 435353 
436147 436149 438416 439306
Changes: 
 dpkg (1.14.6) unstable; urgency=low
 .
   [ Frank Lichtenheld ]
   * Synchronise usage information of dpkg, dpkg-deb, and
     dpkg-query man pages. This fixes some small mistakes
     and also Closes: #321520
 .
   [ Guillem Jover ]
   * Man pages cleanup:
     - Some italics and bold fixes.
     - Unify ellipsis, argument separator, and remove redundant program name
       preceding the options.
     - Substitute 'FILES' header with 'SEE ALSO' in dpkg-buildpackage(1),
       and remove leftover string from man page split. Closes: #439306
     - Split option descriptions so that it gets easier to distinguish.
     - Unify author and copyright information formatting.
   * Move variables automatically modified at build time for the perl scripts
     to a new style perl module (Dpkg) and make all programs use it.
   * Switch 'dpkg-gettext.pl' to a new style perl module (Dpkg::Gettext).
   * Implement support for Breaks field. Closes: #379140
     Thanks to Ian Jackson.
   * Run the deconfiguration of each package to be deconfigured once, instead
     of once per each conflicting package being removed. Closes: #378003
     Thanks to Ian Jackson.
   * Do not segfault when the result from a 'dpkg-query -l' is bigger than
     the total number of current packages, and do not produce repeated
     results with overlapping patterns on 'dpkg-query -W'. Closes: #428427
   * Tightening dpkg-dev versioned Depends to dpkg 1.14.6, and dpkg Conflicts
     against << dpkg-dev 1.14.6, where the perl modularization started.
   * Do not print empty lines after 'Setting up ...' output. Closes: #392317
   * When a slave alternative is inapplicable do not attempt to create the
     slave link before removing it again. Closes: #411699
     Thanks to Ian Jackson.
   * Do not consider it a file conflict if the package contains a symlink
     to a directory where the existing symlink on-disk points to the
     same place. Closes: #377682
     Thanks to Ian Jackson.
   * Fix perl warnings:
     - When removing a non diverted file with dpkg-divert. Closes: #438416
   * Implement support for Homepage field. Closes: #142324
   * Ignore XB- fields instead of XC- fields from control file binary package
     stanzas in dpkg-genchanges.
   * Explicitely ignore all known fields from the control file source package
     stanza in dpkg-genchanges, instead of leaving unknown fields unwarned.
   * Implement support for Vcs-Browser, Vcs-Arch, Vcs-Bzr, Vcs-Cvs, Vcs-Darcs,
     Vcs-Git, Vcs-Hg, Vcs-Mtn and Vcs-Svn fields in control file source
     package stanza.
   * Implement support for Tag field.
 .
   [ Updated scripts translations ]
   * French (Frédéric Bothamy, Christian Perrier).
   * Swedish (Peter Karlsson).
 .
   [ Updated dpkg translations ]
   * Dzongkha (Tshewang Norbu). Closes: #430931
   * Nepali (Shiva Prasad Pokharel). Closes: #435353
   * Polish (Robert Luberda).
   * Russian (Yuri Kozlov). Closes: #436147
   * Swedish (Peter Karlsson).
 .
   [ Updated dselect translations ]
   * Russian (Yuri Kozlov). Closes: #436149
   * Swedish (Peter Karlsson).
 .
   [ Updated man pages translations ]
   * German (Helge Kreutzmann).
   * Polish (Robert Luberda).
   * Swedish (Peter Karlsson).
Files: 
 c0d88fcd7bad5417cb3503ed12cae3be 851 admin required dpkg_1.14.6.dsc
 f9b0466056968ee4db5c92985a00c1da 5897896 admin required dpkg_1.14.6.tar.gz
 42315dd96e45dcc1d74f5da2b168699f 2079804 admin required dpkg_1.14.6_i386.deb
 0171b24aa7f84adaebf4a3c972176a43 508956 admin required dselect_1.14.6_i386.deb
 10e88fc08548f55b7b1702495858b85e 227124 utils optional dpkg-dev_1.14.6_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFG3jy+uW9ciZ2SjJsRAuKwAJsHdxpgHdZ2ebGJokHQ3R5Jx84T6QCg8O9S
vw84tKS6W9S+S+XQ4Fz7H9o=
=+QsJ
-----END PGP SIGNATURE-----


--- End Message ---

Reply via email to