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
00014
00015
00016
00017
00018
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
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
00070 for (j = 0; j < i; j++) {
00071 if (!sameProblem(conflicts + i, conflicts + j))
00072 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
00093 static inline int vsnprintf(char * buf, int nb,
00094 const char * fmt, va_list ap)
00095 {
00096 return vsprintf(buf, fmt, ap);
00097 }
00098
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
00107 rc = vsnprintf(buf, nb, fmt, ap);
00108
00109 va_end(ap);
00110 return rc;
00111 }
00112 #endif
00113
00114 const char * rpmProblemString(const rpmProblem prob)
00115 {
00116
00117 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "");
00118
00119 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "");
00120
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 }