/** * \file lib/rpmps.c */ #include "system.h" #include #include #include #include #include "debug.h" struct rpmProblem_s { char * pkgNEVR; char * altNEVR; fnpyKey key; rpmProblemType type; char * str1; uint64_t num1; int nrefs; }; static rpmProblem rpmProblemUnlink(rpmProblem prob); rpmProblem rpmProblemCreate(rpmProblemType type, const char * pkgNEVR, fnpyKey key, const char * altNEVR, const char * str, uint64_t number) { rpmProblem p = xcalloc(1, sizeof(*p)); p->type = type; p->key = key; p->num1 = number; p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL); p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL); p->str1 = (str ? xstrdup(str) : NULL); return rpmProblemLink(p); } rpmProblem rpmProblemFree(rpmProblem prob) { if (prob == NULL) return NULL; if (prob->nrefs > 1) { return rpmProblemUnlink(prob); } prob->pkgNEVR = _free(prob->pkgNEVR); prob->altNEVR = _free(prob->altNEVR); prob->str1 = _free(prob->str1); free(prob); return NULL; } rpmProblem rpmProblemLink(rpmProblem prob) { if (prob) { prob->nrefs++; } return prob; } static rpmProblem rpmProblemUnlink(rpmProblem prob) { if (prob) { prob->nrefs--; } return NULL; } const char * rpmProblemGetPkgNEVR(rpmProblem p) { return (p->pkgNEVR); } const char * rpmProblemGetAltNEVR(rpmProblem p) { return (p->altNEVR); } fnpyKey rpmProblemGetKey(rpmProblem p) { return (p->key); } rpmProblemType rpmProblemGetType(rpmProblem p) { return (p->type); } const char * rpmProblemGetStr(rpmProblem p) { return (p->str1); } rpm_loff_t rpmProblemGetDiskNeed(rpmProblem p) { return (p->num1); } char * rpmProblemString(rpmProblem prob) { const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?"); const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "? ?altNEVR?"); const char * str1 = (prob->str1 ? prob->str1 : N_("different")); char * buf = NULL; switch (prob->type) { case RPMPROB_BADARCH: rasprintf(&buf, _("package %s is intended for a %s architecture"), pkgNEVR, str1); break; case RPMPROB_BADOS: rasprintf(&buf, _("package %s is intended for a %s operating system"), pkgNEVR, str1); break; case RPMPROB_PKG_INSTALLED: rasprintf(&buf, _("package %s is already installed"), pkgNEVR); break; case RPMPROB_BADRELOCATE: rasprintf(&buf, _("path %s in package %s is not relocatable"), str1, pkgNEVR); break; case RPMPROB_NEW_FILE_CONFLICT: rasprintf(&buf, _("file %s conflicts between attempted installs of %s and %s"), str1, pkgNEVR, altNEVR); break; case RPMPROB_FILE_CONFLICT: rasprintf(&buf, _("file %s from install of %s conflicts with file from package %s"), str1, pkgNEVR, altNEVR); break; case RPMPROB_OLDPACKAGE: rasprintf(&buf, _("package %s (which is newer than %s) is already installed"), altNEVR, pkgNEVR); break; case RPMPROB_DISKSPACE: rasprintf(&buf, _("installing package %s needs %" PRIu64 "%cB on the %s filesystem"), pkgNEVR, prob->num1 > (1024*1024) ? (prob->num1 + 1024 * 1024 - 1) / (1024 * 1024) : (prob->num1 + 1023) / 1024, prob->num1 > (1024*1024) ? 'M' : 'K', str1); break; case RPMPROB_DISKNODES: rasprintf(&buf, _("installing package %s needs %" PRIu64 " inodes on the %s filesystem"), pkgNEVR, prob->num1, str1); break; case RPMPROB_REQUIRES: rasprintf(&buf, _("%s is needed by %s%s"), prob->str1, (prob->num1 ? _("(installed) ") : ""), altNEVR); break; case RPMPROB_CONFLICT: rasprintf(&buf, _("%s conflicts with %s%s"), prob->str1, (prob->num1 ? _("(installed) ") : ""), altNEVR); break; case RPMPROB_OBSOLETES: rasprintf(&buf, _("%s is obsoleted by %s%s"), prob->str1, (prob->num1 ? _("(installed) ") : ""), altNEVR); break; default: rasprintf(&buf, _("unknown error %d encountered while manipulating package %s"), prob->type, pkgNEVR); break; } return buf; } static int cmpStr(const char *s1, const char *s2) { if (s1 == s2) return 0; if (s1 && s2) return strcmp(s1, s2); return 1; } int rpmProblemCompare(rpmProblem ap, rpmProblem bp) { if (ap == bp) return 0; if (ap == NULL || bp == NULL) return 1; if (ap->type != bp->type) return 1; if (ap->key != bp->key) return 1; if (ap->num1 != bp->num1) return 1; if (cmpStr(ap->pkgNEVR, bp->pkgNEVR)) return 1; if (cmpStr(ap->altNEVR, bp->altNEVR)) return 1; if (cmpStr(ap->str1, bp->str1)) return 1; return 0; }