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