# lib/problems.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include <rpmlib.h>
    00008
    00009 #include "depends.h"
    00010 #include "misc.h"
    00011 #include "debug.h"
    00012
    00013 /*@access rpmProblemSet@*/
    00014 /*@access rpmProblem@*/
    00015 /*@access rpmDependencyConflict@*/
    00016
    00017 /* XXX FIXME: merge into problems */
    00018 /* XXX used in verify.c rpmlibprov.c */
    00019 void printDepFlags(FILE * fp, const char * version, int flags)
    00020 {
    00021     if (flags)
    00022         fprintf(fp, " ");
    00023
    00024     if (flags & RPMSENSE_LESS)
    00025         fprintf(fp, "<");
    00026     if (flags & RPMSENSE_GREATER)
    00027         fprintf(fp, ">");
    00028     if (flags & RPMSENSE_EQUAL)
    00029         fprintf(fp, "=");
    00030
    00031     if (flags)
    00032         fprintf(fp, " %s", version);
    00033 }
    00034
    00035 static int sameProblem(const rpmDependencyConflict ap,
    00036                 const rpmDependencyConflict bp)
    00037         /*@*/
    00038 {
    00039
    00040     if (ap->sense != bp->sense)
    00041         return 1;
    00042
    00043     if (ap->byName && bp->byName && strcmp(ap->byName, bp->byName))
    00044         return 1;
    00045     if (ap->byVersion && bp->byVersion && strcmp(ap->byVersion, bp->byVersion))
    00046         return 1;
    00047     if (ap->byRelease && bp->byRelease && strcmp(ap->byRelease, bp->byRelease))
    00048         return 1;
    00049
    00050     if (ap->needsName && bp->needsName && strcmp(ap->needsName, bp->needsName))
    00051         return 1;
    00052     if (ap->needsVersion && bp->needsVersion && strcmp(ap->needsVersion, bp->needsVersion))
    00053         return 1;
    00054     if (ap->needsFlags && bp->needsFlags && ap->needsFlags != bp->needsFlags)
    00055         return 1;
    00056
    00057     return 0;
    00058 }
    00059
    00060 /* XXX FIXME: merge into problems */
    00061 void printDepProblems(FILE * fp,
    00062                 const rpmDependencyConflict conflicts, int numConflicts)
    00063 {
    00064     int i;
    00065
    00066     for (i = 0; i < numConflicts; i++) {
    00067         int j;
    00068
    00069         /* Filter already displayed problems. */
    00070         for (j = 0; j < i; j++) {
    00071             if (!sameProblem(conflicts + i, conflicts + j))
    00072                 /*@innerbreak@*/ break;
    00073         }
    00074         if (j < i)
    00075             continue;
    00076
    00077         fprintf(fp, "\t%s", conflicts[i].needsName);
    00078         if (conflicts[i].needsFlags)
    00079             printDepFlags(fp, conflicts[i].needsVersion,
    00080                           conflicts[i].needsFlags);
    00081
    00082         if (conflicts[i].sense == RPMDEP_SENSE_REQUIRES)
    00083             fprintf(fp, _(" is needed by %s-%s-%s\n"), conflicts[i].byName,
    00084                     conflicts[i].byVersion, conflicts[i].byRelease);
    00085         else
    00086             fprintf(fp, _(" conflicts with %s-%s-%s\n"), conflicts[i].byName,
    00087                     conflicts[i].byVersion, conflicts[i].byRelease);
    00088     }
    00089 }
    00090
    00091 #if !defined(HAVE_VSNPRINTF)
    00092 /*@-shadow -bufferoverflowhigh @*/
    00093 static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
    00094         const char * fmt, va_list ap)
    00095 {
    00096     return vsprintf(buf, fmt, ap);
    00097 }
    00098 /*@=shadow =bufferoverflowhigh @*/
    00099 #endif
    00100 #if !defined(HAVE_SNPRINTF)
    00101 static inline int snprintf(char * buf, int nb, const char * fmt, ...)
    00102 {
    00103     va_list ap;
    00104     int rc;
    00105     va_start(ap, fmt);
    00106     /*@-modunconnomods@*/
    00107     rc = vsnprintf(buf, nb, fmt, ap);
    00108     /*@=modunconnomods@*/
    00109     va_end(ap);
    00110     return rc;
    00111 }
    00112 #endif
    00113
    00114 const char * rpmProblemString(const rpmProblem prob)
    00115 {
    00116 /*@observer@*/
    00117     const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "");
    00118 /*@observer@*/
    00119     const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "");
    00120 /*@observer@*/
    00121     const char * str1 = (prob->str1 ? prob->str1 : "");
    00122     int nb =    strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
    00123     char * buf = xmalloc(nb+1);
    00124     int rc;
    00125
    00126     *buf = '\0';
    00127     switch (prob->type) {
    00128     case RPMPROB_BADARCH:
    00129         rc = snprintf(buf, nb,
    00130                 _("package %s is for a different architecture"),
    00131                 pkgNEVR);
    00132         break;
    00133     case RPMPROB_BADOS:
    00134         rc = snprintf(buf, nb,
    00135                 _("package %s is for a different operating system"),
    00136                 pkgNEVR);
    00137         break;
    00138     case RPMPROB_PKG_INSTALLED:
    00139         rc = snprintf(buf, nb,
    00140                 _("package %s is already installed"),
    00141                 pkgNEVR);
    00142         break;
    00143     case RPMPROB_BADRELOCATE:
    00144         rc = snprintf(buf, nb,
    00145                 _("path %s in package %s is not relocateable"),
    00146                 str1, pkgNEVR);
    00147         break;
    00148     case RPMPROB_NEW_FILE_CONFLICT:
    00149         rc = snprintf(buf, nb,
    00150                 _("file %s conflicts between attempted installs of %s and %s"),
    00151                 str1, pkgNEVR, altNEVR);
    00152         break;
    00153     case RPMPROB_FILE_CONFLICT:
    00154         rc = snprintf(buf, nb,
    00155             _("file %s from install of %s conflicts with file from package %s"),
    00156                 str1, pkgNEVR, altNEVR);
    00157         break;
    00158     case RPMPROB_OLDPACKAGE:
    00159         rc = snprintf(buf, nb,
    00160                 _("package %s (which is newer than %s) is already installed"),
    00161                 altNEVR, pkgNEVR);
    00162         break;
    00163     case RPMPROB_DISKSPACE:
    00164         rc = snprintf(buf, nb,
    00165             _("installing package %s needs %ld%cb on the %s filesystem"),
    00166                 pkgNEVR,
    00167                 prob->ulong1 > (1024*1024)
    00168                     ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
    00169                     : (prob->ulong1 + 1023) / 1024,
    00170                 prob->ulong1 > (1024*1024) ? 'M' : 'K',
    00171                 str1);
    00172         break;
    00173     case RPMPROB_DISKNODES:
    00174         rc = snprintf(buf, nb,
    00175             _("installing package %s needs %ld inodes on the %s filesystem"),
    00176                 pkgNEVR, (long)prob->ulong1, str1);
    00177         break;
    00178     case RPMPROB_BADPRETRANS:
    00179         rc = snprintf(buf, nb,
    00180                 _("package %s pre-transaction syscall(s): %s failed: %s"),
    00181                 pkgNEVR, str1, strerror(prob->ulong1));
    00182         break;
    00183      case RPMPROB_REQUIRES:
    00184         rc = snprintf(buf, nb, _("package %s has unsatisfied Requires: %s\n"),
    00185                 pkgNEVR, altNEVR+2);
    00186         break;
    00187      case RPMPROB_CONFLICT:
    00188         rc = snprintf(buf, nb, _("package %s has unsatisfied Conflicts: %s\n"),
    00189                 pkgNEVR, altNEVR+2);
    00190         break;
    00191     default:
    00192         rc = snprintf(buf, nb,
    00193                 _("unknown error %d encountered while manipulating package %s"),
    00194                 prob->type, pkgNEVR);
    00195         break;
    00196     }
    00197
    00198     buf[nb] = '\0';
    00199     return buf;
    00200 }
    00201
    00202 void rpmProblemPrint(FILE *fp, rpmProblem prob)
    00203 {
    00204     const char * msg = rpmProblemString(prob);
    00205     fprintf(fp, "%s\n", msg);
    00206     msg = _free(msg);
    00207 }
    00208
    00209 void rpmProblemSetPrint(FILE *fp, rpmProblemSet probs)
    00210 {
    00211     int i;
    00212
    00213     if (probs == NULL)
    00214         return;
    00215
    00216     if (fp == NULL)
    00217         fp = stderr;
    00218
    00219     for (i = 0; i < probs->numProblems; i++) {
    00220         rpmProblem myprob = probs->probs + i;
    00221         if (!myprob->ignoreProblem)
    00222             rpmProblemPrint(fp, myprob);
    00223     }
    00224 }