"Fossies" - the Fresh Open Source Software Archive

Member "dpkg-1.19.7/src/depcon.c" (19 Apr 2019, 25035 Bytes) of package /linux/misc/dpkg_1.19.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "depcon.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.19.2_vs_1.19.3.

    1 /*
    2  * dpkg - main program for package management
    3  * depcon.c - dependency and conflict checking
    4  *
    5  * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
    6  * Copyright © 2006-2014 Guillem Jover <guillem@debian.org>
    7  * Copyright © 2011 Linaro Limited
    8  * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
    9  *
   10  * This is free software; you can redistribute it and/or modify
   11  * it under the terms of the GNU General Public License as published by
   12  * the Free Software Foundation; either version 2 of the License, or
   13  * (at your option) any later version.
   14  *
   15  * This is distributed in the hope that it will be useful,
   16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18  * GNU General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
   22  */
   23 
   24 #include <config.h>
   25 #include <compat.h>
   26 
   27 #include <sys/types.h>
   28 #include <sys/stat.h>
   29 
   30 #include <errno.h>
   31 #include <stdlib.h>
   32 #include <unistd.h>
   33 
   34 #include <dpkg/i18n.h>
   35 #include <dpkg/dpkg.h>
   36 #include <dpkg/dpkg-db.h>
   37 #include <dpkg/db-ctrl.h>
   38 #include <dpkg/db-fsys.h>
   39 
   40 #include "main.h"
   41 
   42 struct deppossi_pkg_iterator {
   43   struct deppossi *possi;
   44   struct pkginfo *pkg_next;
   45   enum which_pkgbin which_pkgbin;
   46 };
   47 
   48 struct deppossi_pkg_iterator *
   49 deppossi_pkg_iter_new(struct deppossi *possi, enum which_pkgbin wpb)
   50 {
   51   struct deppossi_pkg_iterator *iter;
   52 
   53   iter = m_malloc(sizeof(*iter));
   54   iter->possi = possi;
   55   iter->pkg_next = &possi->ed->pkg;
   56   iter->which_pkgbin = wpb;
   57 
   58   return iter;
   59 }
   60 
   61 struct pkginfo *
   62 deppossi_pkg_iter_next(struct deppossi_pkg_iterator *iter)
   63 {
   64   struct pkginfo *pkg_cur;
   65   struct pkgbin *pkgbin;
   66 
   67   while ((pkg_cur = iter->pkg_next)) {
   68     iter->pkg_next = pkg_cur->arch_next;
   69 
   70     switch (iter->which_pkgbin) {
   71     case wpb_installed:
   72       pkgbin = &pkg_cur->installed;
   73       break;
   74     case wpb_available:
   75       pkgbin = &pkg_cur->available;
   76       break;
   77     case wpb_by_istobe:
   78       if (pkg_cur->clientdata &&
   79           pkg_cur->clientdata->istobe == PKG_ISTOBE_INSTALLNEW)
   80         pkgbin = &pkg_cur->available;
   81       else
   82         pkgbin = &pkg_cur->installed;
   83       break;
   84     default:
   85       internerr("unknown which_pkgbin %d", iter->which_pkgbin);
   86     }
   87 
   88     if (archsatisfied(pkgbin, iter->possi))
   89       return pkg_cur;
   90   }
   91 
   92   return NULL;
   93 }
   94 
   95 void
   96 deppossi_pkg_iter_free(struct deppossi_pkg_iterator *iter)
   97 {
   98   free(iter);
   99 }
  100 
  101 struct cyclesofarlink {
  102   struct cyclesofarlink *prev;
  103   struct pkginfo *pkg;
  104   struct deppossi *possi;
  105 };
  106 
  107 static bool findbreakcyclerecursive(struct pkginfo *pkg,
  108                                     struct cyclesofarlink *sofar);
  109 
  110 static bool
  111 foundcyclebroken(struct cyclesofarlink *thislink, struct cyclesofarlink *sofar,
  112                  struct pkginfo *dependedon, struct deppossi *possi)
  113 {
  114   struct cyclesofarlink *sol;
  115 
  116   if(!possi)
  117     return false;
  118 
  119   /* We're investigating the dependency ‘possi’ to see if it
  120    * is part of a loop. To this end we look to see whether the
  121    * depended-on package is already one of the packages whose
  122    * dependencies we're searching. */
  123   for (sol = sofar; sol && sol->pkg != dependedon; sol = sol->prev);
  124 
  125   /* If not, we do a recursive search on it to see what we find. */
  126   if (!sol)
  127     return findbreakcyclerecursive(dependedon, thislink);
  128 
  129   debug(dbg_depcon,"found cycle");
  130   /* Right, we now break one of the links. We prefer to break
  131    * a dependency of a package without a postinst script, as
  132    * this is a null operation. If this is not possible we break
  133    * the other link in the recursive calling tree which mentions
  134    * this package (this being the first package involved in the
  135    * cycle). It doesn't particularly matter which we pick, but if
  136    * we break the earliest dependency we came across we may be
  137    * able to do something straight away when findbreakcycle returns. */
  138   sofar= thislink;
  139   for (sol = sofar; !(sol != sofar && sol->pkg == dependedon); sol = sol->prev) {
  140     if (!pkg_infodb_has_file(sol->pkg, &sol->pkg->installed, POSTINSTFILE))
  141       break;
  142   }
  143 
  144   /* Now we have either a package with no postinst, or the other
  145    * occurrence of the current package in the list. */
  146   sol->possi->cyclebreak = true;
  147 
  148   debug(dbg_depcon, "cycle broken at %s -> %s",
  149         pkg_name(sol->possi->up->up, pnaw_always), sol->possi->ed->name);
  150 
  151   return true;
  152 }
  153 
  154 /**
  155  * Cycle breaking works recursively down the package dependency tree.
  156  *
  157  * ‘sofar’ is the list of packages we've descended down already - if we
  158  * encounter any of its packages again in a dependency we have found a cycle.
  159  */
  160 static bool
  161 findbreakcyclerecursive(struct pkginfo *pkg, struct cyclesofarlink *sofar)
  162 {
  163   struct cyclesofarlink thislink, *sol;
  164   struct dependency *dep;
  165   struct deppossi *possi, *providelink;
  166   struct pkginfo *provider, *pkg_pos;
  167 
  168   if (pkg->clientdata->color == PKG_CYCLE_BLACK)
  169     return false;
  170   pkg->clientdata->color = PKG_CYCLE_GRAY;
  171 
  172   if (debug_has_flag(dbg_depcondetail)) {
  173     struct varbuf str_pkgs = VARBUF_INIT;
  174 
  175     for (sol = sofar; sol; sol = sol->prev) {
  176       varbuf_add_str(&str_pkgs, " <- ");
  177       varbuf_add_pkgbin_name(&str_pkgs, sol->pkg, &sol->pkg->installed, pnaw_nonambig);
  178     }
  179     varbuf_end_str(&str_pkgs);
  180     debug(dbg_depcondetail, "findbreakcyclerecursive %s %s",
  181           pkg_name(pkg, pnaw_always), str_pkgs.buf);
  182     varbuf_destroy(&str_pkgs);
  183   }
  184   thislink.pkg= pkg;
  185   thislink.prev = sofar;
  186   thislink.possi = NULL;
  187   for (dep= pkg->installed.depends; dep; dep= dep->next) {
  188     if (dep->type != dep_depends && dep->type != dep_predepends) continue;
  189     for (possi= dep->list; possi; possi= possi->next) {
  190       struct deppossi_pkg_iterator *possi_iter;
  191 
  192       /* Don't find the same cycles again. */
  193       if (possi->cyclebreak) continue;
  194       thislink.possi= possi;
  195 
  196       possi_iter = deppossi_pkg_iter_new(possi, wpb_installed);
  197       while ((pkg_pos = deppossi_pkg_iter_next(possi_iter)))
  198         if (foundcyclebroken(&thislink, sofar, pkg_pos, possi)) {
  199           deppossi_pkg_iter_free(possi_iter);
  200           return true;
  201         }
  202       deppossi_pkg_iter_free(possi_iter);
  203 
  204       /* Right, now we try all the providers ... */
  205       for (providelink = possi->ed->depended.installed;
  206            providelink;
  207            providelink = providelink->rev_next) {
  208         if (providelink->up->type != dep_provides) continue;
  209         provider= providelink->up->up;
  210         if (provider->clientdata->istobe == PKG_ISTOBE_NORMAL)
  211           continue;
  212         /* We don't break things at ‘provides’ links, so ‘possi’ is
  213          * still the one we use. */
  214         if (foundcyclebroken(&thislink, sofar, provider, possi))
  215           return true;
  216       }
  217     }
  218   }
  219   /* Nope, we didn't find a cycle to break. */
  220   pkg->clientdata->color = PKG_CYCLE_BLACK;
  221   return false;
  222 }
  223 
  224 bool
  225 findbreakcycle(struct pkginfo *pkg)
  226 {
  227   struct pkg_hash_iter *iter;
  228   struct pkginfo *tpkg;
  229 
  230   /* Clear the visited flag of all packages before we traverse them. */
  231   iter = pkg_hash_iter_new();
  232   while ((tpkg = pkg_hash_iter_next_pkg(iter))) {
  233     ensure_package_clientdata(tpkg);
  234     tpkg->clientdata->color = PKG_CYCLE_WHITE;
  235   }
  236   pkg_hash_iter_free(iter);
  237 
  238   return findbreakcyclerecursive(pkg, NULL);
  239 }
  240 
  241 void describedepcon(struct varbuf *addto, struct dependency *dep) {
  242   const char *fmt;
  243   struct varbuf depstr = VARBUF_INIT;
  244 
  245   switch (dep->type) {
  246   case dep_depends:
  247     fmt = _("%s depends on %s");
  248     break;
  249   case dep_predepends:
  250     fmt = _("%s pre-depends on %s");
  251     break;
  252   case dep_recommends:
  253     fmt = _("%s recommends %s");
  254     break;
  255   case dep_suggests:
  256     fmt = _("%s suggests %s");
  257     break;
  258   case dep_breaks:
  259     fmt = _("%s breaks %s");
  260     break;
  261   case dep_conflicts:
  262     fmt = _("%s conflicts with %s");
  263     break;
  264   case dep_enhances:
  265     fmt = _("%s enhances %s");
  266     break;
  267   default:
  268     internerr("unknown deptype '%d'", dep->type);
  269   }
  270 
  271   varbufdependency(&depstr, dep);
  272   varbuf_end_str(&depstr);
  273 
  274   varbuf_printf(addto, fmt, pkg_name(dep->up, pnaw_nonambig), depstr.buf);
  275   varbuf_destroy(&depstr);
  276 }
  277 
  278 /*
  279  * *whynot must already have been initialized; it need not be
  280  * empty though - it will be reset before use.
  281  *
  282  * If depisok returns false for ‘not OK’ it will contain a description,
  283  * newline-terminated BUT NOT NUL-TERMINATED, of the reason.
  284  *
  285  * If depisok returns true it will contain garbage.
  286  * allowunconfigd should be non-zero during the ‘Pre-Depends’ checking
  287  * before a package is unpacked, when it is sufficient for the package
  288  * to be unpacked provided that both the unpacked and previously-configured
  289  * versions are acceptable.
  290  *
  291  * On false return (‘not OK’), *canfixbyremove refers to a package which
  292  * if removed (dep_conflicts) or deconfigured (dep_breaks) will fix
  293  * the problem. Caller may pass NULL for canfixbyremove and need not
  294  * initialize *canfixbyremove.
  295  *
  296  * On false return (‘not OK’), *canfixbytrigaw refers to a package which
  297  * can fix the problem if all the packages listed in Triggers-Awaited have
  298  * their triggers processed. Caller may pass NULL for canfixbytrigaw and
  299  * need not initialize *canfixbytrigaw.
  300  */
  301 bool
  302 depisok(struct dependency *dep, struct varbuf *whynot,
  303         struct pkginfo **canfixbyremove, struct pkginfo **canfixbytrigaw,
  304         bool allowunconfigd)
  305 {
  306   struct deppossi *possi;
  307   struct deppossi *provider;
  308   struct pkginfo *pkg_pos;
  309   int nconflicts;
  310 
  311   /* Use this buffer so that when internationalisation comes along we
  312    * don't have to rewrite the code completely, only redo the sprintf strings
  313    * (assuming we have the fancy argument-number-specifiers).
  314    * Allow 250x3 for package names, versions, &c, + 250 for ourselves. */
  315   char linebuf[1024];
  316 
  317   if (dep->type != dep_depends &&
  318       dep->type != dep_predepends &&
  319       dep->type != dep_breaks &&
  320       dep->type != dep_conflicts &&
  321       dep->type != dep_recommends &&
  322       dep->type != dep_suggests &&
  323       dep->type != dep_enhances)
  324     internerr("unknown dependency type %d", dep->type);
  325 
  326   if (canfixbyremove)
  327     *canfixbyremove = NULL;
  328   if (canfixbytrigaw)
  329     *canfixbytrigaw = NULL;
  330 
  331   /* The dependency is always OK if we're trying to remove the depend*ing*
  332    * package. */
  333   switch (dep->up->clientdata->istobe) {
  334   case PKG_ISTOBE_REMOVE:
  335   case PKG_ISTOBE_DECONFIGURE:
  336     return true;
  337   case PKG_ISTOBE_NORMAL:
  338     /* Only installed packages can be made dependency problems. */
  339     switch (dep->up->status) {
  340     case PKG_STAT_INSTALLED:
  341     case PKG_STAT_TRIGGERSPENDING:
  342     case PKG_STAT_TRIGGERSAWAITED:
  343       break;
  344     case PKG_STAT_HALFCONFIGURED:
  345     case PKG_STAT_UNPACKED:
  346     case PKG_STAT_HALFINSTALLED:
  347       if (dep->type == dep_predepends ||
  348           dep->type == dep_conflicts ||
  349           dep->type == dep_breaks)
  350         break;
  351       /* Fall through. */
  352     case PKG_STAT_CONFIGFILES:
  353     case PKG_STAT_NOTINSTALLED:
  354       return true;
  355     default:
  356       internerr("unknown status depending '%d'", dep->up->status);
  357     }
  358     break;
  359   case PKG_ISTOBE_INSTALLNEW:
  360   case PKG_ISTOBE_PREINSTALL:
  361     break;
  362   default:
  363     internerr("unknown istobe depending '%d'", dep->up->clientdata->istobe);
  364   }
  365 
  366   /* Describe the dependency, in case we have to moan about it. */
  367   varbuf_reset(whynot);
  368   varbuf_add_char(whynot, ' ');
  369   describedepcon(whynot, dep);
  370   varbuf_add_char(whynot, '\n');
  371 
  372   /* TODO: Check dep_enhances as well. */
  373   if (dep->type == dep_depends || dep->type == dep_predepends ||
  374       dep->type == dep_recommends || dep->type == dep_suggests ) {
  375     /* Go through the alternatives. As soon as we find one that
  376      * we like, we return ‘true’ straight away. Otherwise, when we get to
  377      * the end we'll have accumulated all the reasons in whynot and
  378      * can return ‘false’. */
  379 
  380     for (possi= dep->list; possi; possi= possi->next) {
  381       struct deppossi_pkg_iterator *possi_iter;
  382 
  383       possi_iter = deppossi_pkg_iter_new(possi, wpb_by_istobe);
  384       while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) {
  385         switch (pkg_pos->clientdata->istobe) {
  386         case PKG_ISTOBE_REMOVE:
  387           sprintf(linebuf, _("  %.250s is to be removed.\n"),
  388                   pkg_name(pkg_pos, pnaw_nonambig));
  389           break;
  390         case PKG_ISTOBE_DECONFIGURE:
  391           sprintf(linebuf, _("  %.250s is to be deconfigured.\n"),
  392                   pkg_name(pkg_pos, pnaw_nonambig));
  393           break;
  394         case PKG_ISTOBE_INSTALLNEW:
  395           if (versionsatisfied(&pkg_pos->available, possi)) {
  396             deppossi_pkg_iter_free(possi_iter);
  397             return true;
  398           }
  399           sprintf(linebuf, _("  %.250s is to be installed, but is version "
  400                              "%.250s.\n"),
  401                   pkgbin_name(pkg_pos, &pkg_pos->available, pnaw_nonambig),
  402                   versiondescribe(&pkg_pos->available.version, vdew_nonambig));
  403           break;
  404         case PKG_ISTOBE_NORMAL:
  405         case PKG_ISTOBE_PREINSTALL:
  406           switch (pkg_pos->status) {
  407           case PKG_STAT_INSTALLED:
  408           case PKG_STAT_TRIGGERSPENDING:
  409             if (versionsatisfied(&pkg_pos->installed, possi)) {
  410               deppossi_pkg_iter_free(possi_iter);
  411               return true;
  412             }
  413             sprintf(linebuf, _("  %.250s is installed, but is version "
  414                                "%.250s.\n"),
  415                     pkg_name(pkg_pos, pnaw_nonambig),
  416                     versiondescribe(&pkg_pos->installed.version, vdew_nonambig));
  417             break;
  418           case PKG_STAT_NOTINSTALLED:
  419             /* Don't say anything about this yet - it might be a virtual package.
  420              * Later on, if nothing has put anything in linebuf, we know that it
  421              * isn't and issue a diagnostic then. */
  422             *linebuf = '\0';
  423             break;
  424           case PKG_STAT_TRIGGERSAWAITED:
  425               if (canfixbytrigaw && versionsatisfied(&pkg_pos->installed, possi))
  426                 *canfixbytrigaw = pkg_pos;
  427               /* Fall through. */
  428           case PKG_STAT_UNPACKED:
  429           case PKG_STAT_HALFCONFIGURED:
  430             if (allowunconfigd) {
  431               if (!dpkg_version_is_informative(&pkg_pos->configversion)) {
  432                 sprintf(linebuf, _("  %.250s is unpacked, but has never been "
  433                                    "configured.\n"),
  434                         pkg_name(pkg_pos, pnaw_nonambig));
  435                 break;
  436               } else if (!versionsatisfied(&pkg_pos->installed, possi)) {
  437                 sprintf(linebuf, _("  %.250s is unpacked, but is version "
  438                                    "%.250s.\n"),
  439                         pkg_name(pkg_pos, pnaw_nonambig),
  440                         versiondescribe(&pkg_pos->installed.version,
  441                                         vdew_nonambig));
  442                 break;
  443               } else if (!dpkg_version_relate(&pkg_pos->configversion,
  444                                               possi->verrel,
  445                                               &possi->version)) {
  446                 sprintf(linebuf, _("  %.250s latest configured version is "
  447                                    "%.250s.\n"),
  448                         pkg_name(pkg_pos, pnaw_nonambig),
  449                         versiondescribe(&pkg_pos->configversion, vdew_nonambig));
  450                 break;
  451               } else {
  452                 deppossi_pkg_iter_free(possi_iter);
  453                 return true;
  454               }
  455             }
  456             /* Fall through. */
  457           default:
  458             sprintf(linebuf, _("  %.250s is %s.\n"),
  459                     pkg_name(pkg_pos, pnaw_nonambig),
  460                     gettext(statusstrings[pkg_pos->status]));
  461             break;
  462           }
  463           break;
  464         default:
  465           internerr("unknown istobe depended '%d'", pkg_pos->clientdata->istobe);
  466         }
  467         varbuf_add_str(whynot, linebuf);
  468       }
  469       deppossi_pkg_iter_free(possi_iter);
  470 
  471         /* See if the package we're about to install Provides it. */
  472         for (provider = possi->ed->depended.available;
  473              provider;
  474              provider = provider->rev_next) {
  475           if (provider->up->type != dep_provides) continue;
  476           if (!pkg_virtual_deppossi_satisfied(possi, provider))
  477             continue;
  478           if (provider->up->up->clientdata->istobe == PKG_ISTOBE_INSTALLNEW)
  479             return true;
  480         }
  481 
  482         /* Now look at the packages already on the system. */
  483         for (provider = possi->ed->depended.installed;
  484              provider;
  485              provider = provider->rev_next) {
  486           if (provider->up->type != dep_provides) continue;
  487           if (!pkg_virtual_deppossi_satisfied(possi, provider))
  488             continue;
  489 
  490           switch (provider->up->up->clientdata->istobe) {
  491           case PKG_ISTOBE_INSTALLNEW:
  492             /* Don't pay any attention to the Provides field of the
  493              * currently-installed version of the package we're trying
  494              * to install. We dealt with that by using the available
  495              * information above. */
  496             continue;
  497           case PKG_ISTOBE_REMOVE:
  498             sprintf(linebuf, _("  %.250s provides %.250s but is to be removed.\n"),
  499                     pkg_name(provider->up->up, pnaw_nonambig),
  500                     possi->ed->name);
  501             break;
  502           case PKG_ISTOBE_DECONFIGURE:
  503             sprintf(linebuf, _("  %.250s provides %.250s but is to be deconfigured.\n"),
  504                     pkg_name(provider->up->up, pnaw_nonambig),
  505                     possi->ed->name);
  506             break;
  507           case PKG_ISTOBE_NORMAL:
  508           case PKG_ISTOBE_PREINSTALL:
  509             if (provider->up->up->status == PKG_STAT_INSTALLED ||
  510                 provider->up->up->status == PKG_STAT_TRIGGERSPENDING)
  511               return true;
  512             if (provider->up->up->status == PKG_STAT_TRIGGERSAWAITED)
  513               *canfixbytrigaw = provider->up->up;
  514             sprintf(linebuf, _("  %.250s provides %.250s but is %s.\n"),
  515                     pkg_name(provider->up->up, pnaw_nonambig),
  516                     possi->ed->name,
  517                     gettext(statusstrings[provider->up->up->status]));
  518             break;
  519           default:
  520             internerr("unknown istobe provider '%d'",
  521                       provider->up->up->clientdata->istobe);
  522           }
  523           varbuf_add_str(whynot, linebuf);
  524         }
  525 
  526         if (!*linebuf) {
  527           /* If the package wasn't installed at all, and we haven't said
  528            * yet why this isn't satisfied, we should say so now. */
  529           sprintf(linebuf, _("  %.250s is not installed.\n"), possi->ed->name);
  530           varbuf_add_str(whynot, linebuf);
  531         }
  532     }
  533 
  534     return false;
  535   } else {
  536     /* It's conflicts or breaks. There's only one main alternative,
  537      * but we also have to consider Providers. We return ‘false’ as soon
  538      * as we find something that matches the conflict, and only describe
  539      * it then. If we get to the end without finding anything we return
  540      * ‘true’. */
  541 
  542     possi= dep->list;
  543     nconflicts= 0;
  544 
  545     if (possi->ed != possi->up->up->set) {
  546       struct deppossi_pkg_iterator *possi_iter;
  547 
  548       /* If the package conflicts with or breaks itself it must mean
  549        * other packages which provide the same virtual name. We
  550        * therefore don't look at the real package and go on to the
  551        * virtual ones. */
  552 
  553       possi_iter = deppossi_pkg_iter_new(possi, wpb_by_istobe);
  554       while ((pkg_pos = deppossi_pkg_iter_next(possi_iter))) {
  555         switch (pkg_pos->clientdata->istobe) {
  556         case PKG_ISTOBE_REMOVE:
  557           break;
  558         case PKG_ISTOBE_INSTALLNEW:
  559           if (!versionsatisfied(&pkg_pos->available, possi))
  560             break;
  561           sprintf(linebuf, _("  %.250s (version %.250s) is to be installed.\n"),
  562                   pkgbin_name(pkg_pos, &pkg_pos->available, pnaw_nonambig),
  563                   versiondescribe(&pkg_pos->available.version, vdew_nonambig));
  564           varbuf_add_str(whynot, linebuf);
  565           if (!canfixbyremove) {
  566             deppossi_pkg_iter_free(possi_iter);
  567             return false;
  568           }
  569           nconflicts++;
  570           *canfixbyremove = pkg_pos;
  571           break;
  572         case PKG_ISTOBE_DECONFIGURE:
  573           if (dep->type == dep_breaks)
  574             break; /* Already deconfiguring this. */
  575           /* Fall through. */
  576         case PKG_ISTOBE_NORMAL:
  577         case PKG_ISTOBE_PREINSTALL:
  578           switch (pkg_pos->status) {
  579           case PKG_STAT_NOTINSTALLED:
  580           case PKG_STAT_CONFIGFILES:
  581             break;
  582           case PKG_STAT_HALFINSTALLED:
  583           case PKG_STAT_UNPACKED:
  584           case PKG_STAT_HALFCONFIGURED:
  585             if (dep->type == dep_breaks)
  586               break; /* No problem. */
  587             /* Fall through. */
  588           case PKG_STAT_INSTALLED:
  589           case PKG_STAT_TRIGGERSPENDING:
  590           case PKG_STAT_TRIGGERSAWAITED:
  591             if (!versionsatisfied(&pkg_pos->installed, possi))
  592               break;
  593             sprintf(linebuf, _("  %.250s (version %.250s) is present and %s.\n"),
  594                     pkg_name(pkg_pos, pnaw_nonambig),
  595                     versiondescribe(&pkg_pos->installed.version, vdew_nonambig),
  596                     gettext(statusstrings[pkg_pos->status]));
  597             varbuf_add_str(whynot, linebuf);
  598             if (!canfixbyremove) {
  599               deppossi_pkg_iter_free(possi_iter);
  600               return false;
  601             }
  602             nconflicts++;
  603             *canfixbyremove = pkg_pos;
  604           }
  605           break;
  606         default:
  607           internerr("unknown istobe conflict '%d'", pkg_pos->clientdata->istobe);
  608         }
  609       }
  610       deppossi_pkg_iter_free(possi_iter);
  611     }
  612 
  613       /* See if the package we're about to install Provides it. */
  614       for (provider = possi->ed->depended.available;
  615            provider;
  616            provider = provider->rev_next) {
  617         if (provider->up->type != dep_provides) continue;
  618         if (provider->up->up->clientdata->istobe != PKG_ISTOBE_INSTALLNEW)
  619           continue;
  620         if (provider->up->up->set == dep->up->set)
  621           continue; /* Conflicts and provides the same. */
  622         if (!pkg_virtual_deppossi_satisfied(possi, provider))
  623           continue;
  624         sprintf(linebuf, _("  %.250s provides %.250s and is to be installed.\n"),
  625                 pkgbin_name(provider->up->up, &provider->up->up->available,
  626                             pnaw_nonambig), possi->ed->name);
  627         varbuf_add_str(whynot, linebuf);
  628         /* We can't remove the one we're about to install: */
  629         if (canfixbyremove)
  630           *canfixbyremove = NULL;
  631         return false;
  632       }
  633 
  634       /* Now look at the packages already on the system. */
  635       for (provider = possi->ed->depended.installed;
  636            provider;
  637            provider = provider->rev_next) {
  638         if (provider->up->type != dep_provides) continue;
  639 
  640         if (provider->up->up->set == dep->up->set)
  641           continue; /* Conflicts and provides the same. */
  642 
  643         if (!pkg_virtual_deppossi_satisfied(possi, provider))
  644           continue;
  645 
  646         switch (provider->up->up->clientdata->istobe) {
  647         case PKG_ISTOBE_INSTALLNEW:
  648           /* Don't pay any attention to the Provides field of the
  649            * currently-installed version of the package we're trying
  650            * to install. We dealt with that package by using the
  651            * available information above. */
  652           continue;
  653         case PKG_ISTOBE_REMOVE:
  654           continue;
  655         case PKG_ISTOBE_DECONFIGURE:
  656           if (dep->type == dep_breaks)
  657             continue; /* Already deconfiguring. */
  658           /* Fall through. */
  659         case PKG_ISTOBE_NORMAL:
  660         case PKG_ISTOBE_PREINSTALL:
  661           switch (provider->up->up->status) {
  662           case PKG_STAT_NOTINSTALLED:
  663           case PKG_STAT_CONFIGFILES:
  664             continue;
  665           case PKG_STAT_HALFINSTALLED:
  666           case PKG_STAT_UNPACKED:
  667           case PKG_STAT_HALFCONFIGURED:
  668             if (dep->type == dep_breaks)
  669               break; /* No problem. */
  670             /* Fall through. */
  671           case PKG_STAT_INSTALLED:
  672           case PKG_STAT_TRIGGERSPENDING:
  673           case PKG_STAT_TRIGGERSAWAITED:
  674             sprintf(linebuf,
  675                     _("  %.250s provides %.250s and is present and %s.\n"),
  676                     pkg_name(provider->up->up, pnaw_nonambig), possi->ed->name,
  677                     gettext(statusstrings[provider->up->up->status]));
  678             varbuf_add_str(whynot, linebuf);
  679             if (!canfixbyremove)
  680               return false;
  681             nconflicts++;
  682             *canfixbyremove= provider->up->up;
  683             break;
  684           }
  685           break;
  686         default:
  687           internerr("unknown istobe conflict provider '%d'",
  688                     provider->up->up->clientdata->istobe);
  689         }
  690       }
  691 
  692     if (!nconflicts)
  693       return true;
  694     if (nconflicts > 1)
  695       *canfixbyremove = NULL;
  696     return false;
  697 
  698   } /* if (dependency) {...} else {...} */
  699 }