17 rpmps XrpmpsUnlink(rpmps ps, const char * msg,
18 const char * fn, unsigned ln)
20 if (_rpmps_debug > 0 && msg != NULL)
21 fprintf(stderr, "--> ps %p -- %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
26 rpmps XrpmpsLink(rpmps ps, const char * msg,
27 const char * fn, unsigned ln)
30 if (_rpmps_debug > 0 && msg != NULL)
31 fprintf(stderr, "--> ps %p ++ %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
35 int rpmpsNumProblems(rpmps ps)
39 numProblems = ps->numProblems;
43 rpmpsi rpmpsInitIterator(rpmps ps)
47 psi = xcalloc(1, sizeof(*psi));
48 psi->ps = rpmpsLink(ps, "iter ref");
54 rpmpsi rpmpsFreeIterator(rpmpsi psi)
57 rpmpsUnlink(psi->ps, "iter unref");
64 int rpmpsNextIterator(rpmpsi psi)
68 if (psi != NULL && ++psi->ix >= 0) {
69 if (psi->ix < rpmpsNumProblems(psi->ps)) {
78 rpmProblem rpmpsProblem(rpmpsi psi)
81 if (psi != NULL && psi->ix >= 0 && psi->ix < rpmpsNumProblems(psi->ps)) {
82 p = psi->ps->probs + psi->ix;
87 rpmps rpmpsCreate(void)
89 rpmps ps = xcalloc(1, sizeof(*ps));
90 return rpmpsLink(ps, "create");
93 rpmps rpmpsFree(rpmps ps)
95 if (ps == NULL) return NULL;
96 ps = rpmpsUnlink(ps, "dereference");
102 for (i = 0; i < ps->numProblems; i++) {
103 rpmProblem p = ps->probs + i;
104 p->pkgNEVR = _free(p->pkgNEVR);
105 p->altNEVR = _free(p->altNEVR);
106 p->str1 = _free(p->str1);
108 ps->probs = _free(ps->probs);
114 void rpmpsAppend(rpmps ps, rpmProblemType type,
115 const char * pkgNEVR, fnpyKey key,
116 const char * dn, const char * bn,
117 const char * altNEVR, unsigned long ulong1)
122 if (ps == NULL) return;
124 if (ps->numProblems == ps->numProblemsAlloced) {
125 if (ps->numProblemsAlloced)
126 ps->numProblemsAlloced *= 2;
128 ps->numProblemsAlloced = 2;
129 ps->probs = xrealloc(ps->probs,
130 ps->numProblemsAlloced * sizeof(*ps->probs));
133 p = ps->probs + ps->numProblems;
135 memset(p, 0, sizeof(*p));
140 p->ignoreProblem = 0;
142 p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL);
143 p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL);
146 if (dn != NULL || bn != NULL) {
147 t = xcalloc(1, (dn != NULL ? strlen(dn) : 0) +
148 (bn != NULL ? strlen(bn) : 0) + 1);
150 if (dn != NULL) t = stpcpy(t, dn);
151 if (bn != NULL) t = stpcpy(t, bn);
155 #define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b))))
157 int rpmpsTrim(rpmps ps, rpmps filter)
163 if (ps == NULL || ps->numProblems == 0)
167 return (ps->numProblems == 0 ? 0 : 1);
172 while ((f - filter->probs) < filter->numProblems) {
173 if (!f->ignoreProblem) {
177 while ((t - ps->probs) < ps->numProblems) {
178 /* LCL: looks good to me <shrug> */
179 if (f->type == t->type && t->key == f->key &&
180 XSTRCMP(f->str1, t->str1))
186 /* XXX This can't happen, but let's be sane in case it does. */
187 if ((t - ps->probs) == ps->numProblems)
190 t->ignoreProblem = f->ignoreProblem;
194 if ((t - ps->probs) < ps->numProblems)
200 #if !defined(HAVE_VSNPRINTF)
201 static inline int vsnprintf(char * buf, int nb,
202 const char * fmt, va_list ap)
204 return vsprintf(buf, fmt, ap);
207 #if !defined(HAVE_SNPRINTF)
208 static inline int snprintf(char * buf, int nb, const char * fmt, ...)
213 rc = vsnprintf(buf, nb, fmt, ap);
219 const char * rpmProblemString(const rpmProblem prob)
221 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?");
222 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "? ?altNEVR?");
223 const char * str1 = (prob->str1 ? prob->str1 : N_("different"));
224 int nb = strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
225 char * buf = xmalloc(nb+1);
228 switch (prob->type) {
229 case RPMPROB_BADARCH:
230 rc = snprintf(buf, nb,
231 _("package %s is intended for a %s architecture"),
235 rc = snprintf(buf, nb,
236 _("package %s is intended for a %s operating system"),
239 case RPMPROB_PKG_INSTALLED:
240 rc = snprintf(buf, nb,
241 _("package %s is already installed"),
244 case RPMPROB_BADRELOCATE:
245 rc = snprintf(buf, nb,
246 _("path %s in package %s is not relocatable"),
249 case RPMPROB_NEW_FILE_CONFLICT:
250 rc = snprintf(buf, nb,
251 _("file %s conflicts between attempted installs of %s and %s"),
252 str1, pkgNEVR, altNEVR);
254 case RPMPROB_FILE_CONFLICT:
255 rc = snprintf(buf, nb,
256 _("file %s from install of %s conflicts with file from package %s"),
257 str1, pkgNEVR, altNEVR);
259 case RPMPROB_OLDPACKAGE:
260 rc = snprintf(buf, nb,
261 _("package %s (which is newer than %s) is already installed"),
264 case RPMPROB_DISKSPACE:
265 rc = snprintf(buf, nb,
266 _("installing package %s needs %ld%cB on the %s filesystem"),
268 prob->ulong1 > (1024*1024)
269 ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
270 : (prob->ulong1 + 1023) / 1024,
271 prob->ulong1 > (1024*1024) ? 'M' : 'K',
274 case RPMPROB_DISKNODES:
275 rc = snprintf(buf, nb,
276 _("installing package %s needs %ld inodes on the %s filesystem"),
277 pkgNEVR, (long)prob->ulong1, str1);
279 case RPMPROB_REQUIRES:
280 rc = snprintf(buf, nb, _("%s is needed by %s%s"),
282 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
284 case RPMPROB_CONFLICT:
285 rc = snprintf(buf, nb, _("%s conflicts with %s%s"),
287 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
290 rc = snprintf(buf, nb,
291 _("unknown error %d encountered while manipulating package %s"),
292 prob->type, pkgNEVR);
300 static int sameProblem(const rpmProblem ap, const rpmProblem bp)
302 if (ap->type != bp->type)
305 if (bp->pkgNEVR && strcmp(ap->pkgNEVR, bp->pkgNEVR))
308 if (bp->altNEVR && strcmp(ap->altNEVR, bp->altNEVR))
311 if (bp->str1 && strcmp(ap->str1, bp->str1))
314 if (ap->ulong1 != bp->ulong1)
320 void rpmpsPrint(FILE *fp, rpmps ps)
326 if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0)
332 psi = rpmpsInitIterator(ps);
333 while ((i = rpmpsNextIterator(psi)) >= 0) {
335 rpmProblem p = rpmpsProblem(psi);
337 if (p->ignoreProblem)
340 rpmpsi psif = rpmpsInitIterator(ps);
341 /* Filter already displayed problems. */
342 while ((j = rpmpsNextIterator(psif)) < i) {
343 if (!sameProblem(p, rpmpsProblem(psif)))
346 rpmpsFreeIterator(psif);
350 msg = rpmProblemString(p);
351 fprintf(fp, "\t%s\n", msg);
355 psi = rpmpsFreeIterator(psi);