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) || defined(__LCLINT__)
00092 static inline int vsnprintf(char * buf, int nb,
00093 const char * fmt, va_list ap)
00094 {
00095 return vsprintf(buf, fmt, ap);
00096 }
00097 #endif
00098 #if !defined(HAVE_SNPRINTF) || defined(__LCLINT__)
00099 static inline int snprintf(char * buf, int nb, const char * fmt, ...)
00100 {
00101 va_list ap;
00102 int rc;
00103 va_start(ap, fmt);
00104
00105 rc = vsnprintf(buf, nb, fmt, ap);
00106
00107 va_end(ap);
00108 return rc;
00109 }
00110 #endif
00111
00112 const char * rpmProblemString(const rpmProblem prob)
00113 {
00114 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "");
00115 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "");
00116 const char * str1 = (prob->str1 ? prob->str1 : "");
00117 int nb = strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
00118 char * buf = xmalloc(nb+1);
00119
00120 switch (prob->type) {
00121 case RPMPROB_BADARCH:
00122 (void) snprintf(buf, nb,
00123 _("package %s is for a different architecture"),
00124 pkgNEVR);
00125 break;
00126 case RPMPROB_BADOS:
00127 (void) snprintf(buf, nb,
00128 _("package %s is for a different operating system"),
00129 pkgNEVR);
00130 break;
00131 case RPMPROB_PKG_INSTALLED:
00132 (void) snprintf(buf, nb,
00133 _("package %s is already installed"),
00134 pkgNEVR);
00135 break;
00136 case RPMPROB_BADRELOCATE:
00137 (void) snprintf(buf, nb,
00138 _("path %s in package %s is not relocateable"),
00139 str1, pkgNEVR);
00140 break;
00141 case RPMPROB_NEW_FILE_CONFLICT:
00142 (void) snprintf(buf, nb,
00143 _("file %s conflicts between attempted installs of %s and %s"),
00144 str1, pkgNEVR, altNEVR);
00145 break;
00146 case RPMPROB_FILE_CONFLICT:
00147 (void) snprintf(buf, nb,
00148 _("file %s from install of %s conflicts with file from package %s"),
00149 str1, pkgNEVR, altNEVR);
00150 break;
00151 case RPMPROB_OLDPACKAGE:
00152 (void) snprintf(buf, nb,
00153 _("package %s (which is newer than %s) is already installed"),
00154 altNEVR, pkgNEVR);
00155 break;
00156 case RPMPROB_DISKSPACE:
00157 (void) snprintf(buf, nb,
00158 _("installing package %s needs %ld%cb on the %s filesystem"),
00159 pkgNEVR,
00160 prob->ulong1 > (1024*1024)
00161 ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
00162 : (prob->ulong1 + 1023) / 1024,
00163 prob->ulong1 > (1024*1024) ? 'M' : 'K',
00164 str1);
00165 break;
00166 case RPMPROB_DISKNODES:
00167 (void) snprintf(buf, nb,
00168 _("installing package %s needs %ld inodes on the %s filesystem"),
00169 pkgNEVR, (long)prob->ulong1, str1);
00170 break;
00171 case RPMPROB_BADPRETRANS:
00172 (void) snprintf(buf, nb,
00173 _("package %s pre-transaction syscall(s): %s failed: %s"),
00174 pkgNEVR, str1, strerror(prob->ulong1));
00175 break;
00176 case RPMPROB_REQUIRES:
00177 case RPMPROB_CONFLICT:
00178 default:
00179 (void) snprintf(buf, nb,
00180 _("unknown error %d encountered while manipulating package %s"),
00181 prob->type, pkgNEVR);
00182 break;
00183 }
00184
00185 buf[nb] = '\0';
00186 return buf;
00187 }
00188
00189 void rpmProblemPrint(FILE *fp, rpmProblem prob)
00190 {
00191 const char * msg = rpmProblemString(prob);
00192 fprintf(fp, "%s\n", msg);
00193 msg = _free(msg);
00194 }
00195
00196 void rpmProblemSetPrint(FILE *fp, rpmProblemSet probs)
00197 {
00198 int i;
00199
00200 if (probs == NULL)
00201 return;
00202
00203 if (fp == NULL)
00204 fp = stderr;
00205
00206 for (i = 0; i < probs->numProblems; i++) {
00207 rpmProblem myprob = probs->probs + i;
00208 if (!myprob->ignoreProblem)
00209 rpmProblemPrint(fp, myprob);
00210 }
00211 }