15 /*@access rpmProblem@*/
16 /*@access rpmProblemSet@*/
19 static int _ps_debug = 0;
21 rpmProblemSet XrpmpsUnlink(rpmProblemSet ps, const char * msg,
22 const char * fn, unsigned ln)
26 fprintf(stderr, "--> ps %p -- %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
32 rpmProblemSet XrpmpsLink(rpmProblemSet ps, const char * msg,
33 const char * fn, unsigned ln)
38 fprintf(stderr, "--> ps %p ++ %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
40 /*@-refcounttrans@*/ return ps; /*@=refcounttrans@*/
43 rpmProblemSet rpmProblemSetCreate(void)
47 ps = xcalloc(1, sizeof(*ps));
48 ps->numProblems = ps->numProblemsAlloced = 0;
52 return rpmpsLink(ps, "create");
55 /* XXX FIXME: merge into problems */
56 rpmProblem rpmdepFreeConflicts(rpmProblem probs, int numProblems)
61 for (i = 0; i < numProblems; i++) {
62 rpmProblem p = probs + i;
63 p->pkgNEVR = _free(p->pkgNEVR);
64 p->altNEVR = _free(p->altNEVR);
65 p->str1 = _free(p->str1);
71 rpmProblemSet rpmProblemSetFree(rpmProblemSet ps)
73 if (ps == NULL) return NULL;
75 return rpmpsUnlink(ps, "dereference");
79 for (i = 0; i < ps->numProblems; i++) {
80 rpmProblem p = ps->probs + i;
81 p->pkgNEVR = _free(p->pkgNEVR);
82 p->altNEVR = _free(p->altNEVR);
83 p->str1 = _free(p->str1);
86 (void) rpmpsUnlink(ps, "destroy");
87 /*@-refcounttrans -usereleased@*/
89 /*@=refcounttrans =usereleased@*/
93 void rpmProblemSetAppend(rpmProblemSet ps, rpmProblemType type,
94 const char * pkgNEVR, fnpyKey key,
95 const char * dn, const char * bn,
96 const char * altNEVR, unsigned long ulong1)
101 if (ps == NULL) return;
103 if (ps->numProblems == ps->numProblemsAlloced) {
104 if (ps->numProblemsAlloced)
105 ps->numProblemsAlloced *= 2;
107 ps->numProblemsAlloced = 2;
108 ps->probs = xrealloc(ps->probs,
109 ps->numProblemsAlloced * sizeof(*ps->probs));
112 p = ps->probs + ps->numProblems;
114 memset(p, 0, sizeof(*p));
119 p->ignoreProblem = 0;
121 p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL);
122 p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL);
125 if (dn != NULL || bn != NULL) {
126 t = xcalloc(1, (dn != NULL ? strlen(dn) : 0) +
127 (bn != NULL ? strlen(bn) : 0) + 1);
129 if (dn != NULL) t = stpcpy(t, dn);
130 if (bn != NULL) t = stpcpy(t, bn);
134 #define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b))))
136 int rpmProblemSetTrim(rpmProblemSet ps, rpmProblemSet filter)
142 if (ps == NULL || ps->numProblems == 0)
146 return (ps->numProblems == 0 ? 0 : 1);
152 while ((f - filter->probs) < filter->numProblems) {
153 if (!f->ignoreProblem) {
157 while ((t - ps->probs) < ps->numProblems) {
158 /*@-nullpass@*/ /* LCL: looks good to me <shrug> */
159 if (f->type == t->type && t->key == f->key &&
160 XSTRCMP(f->str1, t->str1))
161 /*@innerbreak@*/ break;
167 /* XXX This can't happen, but let's be sane in case it does. */
168 if ((t - ps->probs) == ps->numProblems)
171 t->ignoreProblem = f->ignoreProblem;
176 if ((t - ps->probs) < ps->numProblems)
182 /* XXX FIXME: merge into problems */
183 /* XXX used in verify.c rpmlibprov.c */
184 void printDepFlags(FILE * fp, const char * version, int flags)
189 if (flags & RPMSENSE_LESS)
191 if (flags & RPMSENSE_GREATER)
193 if (flags & RPMSENSE_EQUAL)
197 fprintf(fp, " %s", version);
200 #if !defined(HAVE_VSNPRINTF)
201 /*@-shadow -bufferoverflowhigh @*/
202 static inline int vsnprintf(/*@out@*/ char * buf, /*@unused@*/ int nb,
203 const char * fmt, va_list ap)
205 return vsprintf(buf, fmt, ap);
207 /*@=shadow =bufferoverflowhigh @*/
209 #if !defined(HAVE_SNPRINTF)
210 static inline int snprintf(/*@out@*/ char * buf, int nb, const char * fmt, ...)
215 rc = vsnprintf(buf, nb, fmt, ap);
221 const char * rpmProblemString(const rpmProblem prob)
224 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?");
226 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "?altNEVR?");
228 const char * str1 = (prob->str1 ? prob->str1 : N_("different"));
229 int nb = strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
230 char * buf = xmalloc(nb+1);
233 switch (prob->type) {
234 case RPMPROB_BADARCH:
235 rc = snprintf(buf, nb,
236 _("package %s is intended for a %s architecture"),
240 rc = snprintf(buf, nb,
241 _("package %s is intended for a %s operating system"),
244 case RPMPROB_PKG_INSTALLED:
245 rc = snprintf(buf, nb,
246 _("package %s is already installed"),
249 case RPMPROB_BADRELOCATE:
250 rc = snprintf(buf, nb,
251 _("path %s in package %s is not relocateable"),
254 case RPMPROB_NEW_FILE_CONFLICT:
255 rc = snprintf(buf, nb,
256 _("file %s conflicts between attempted installs of %s and %s"),
257 str1, pkgNEVR, altNEVR);
259 case RPMPROB_FILE_CONFLICT:
260 rc = snprintf(buf, nb,
261 _("file %s from install of %s conflicts with file from package %s"),
262 str1, pkgNEVR, altNEVR);
264 case RPMPROB_OLDPACKAGE:
265 rc = snprintf(buf, nb,
266 _("package %s (which is newer than %s) is already installed"),
269 case RPMPROB_DISKSPACE:
270 rc = snprintf(buf, nb,
271 _("installing package %s needs %ld%cb on the %s filesystem"),
273 prob->ulong1 > (1024*1024)
274 ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
275 : (prob->ulong1 + 1023) / 1024,
276 prob->ulong1 > (1024*1024) ? 'M' : 'K',
279 case RPMPROB_DISKNODES:
280 rc = snprintf(buf, nb,
281 _("installing package %s needs %ld inodes on the %s filesystem"),
282 pkgNEVR, (long)prob->ulong1, str1);
284 case RPMPROB_BADPRETRANS:
285 rc = snprintf(buf, nb,
286 _("package %s pre-transaction syscall(s): %s failed: %s"),
287 pkgNEVR, str1, strerror(prob->ulong1));
289 case RPMPROB_REQUIRES:
290 rc = snprintf(buf, nb, _("package %s has unsatisfied Requires: %s\n"),
293 case RPMPROB_CONFLICT:
294 rc = snprintf(buf, nb, _("package %s has unsatisfied Conflicts: %s\n"),
298 rc = snprintf(buf, nb,
299 _("unknown error %d encountered while manipulating package %s"),
300 prob->type, pkgNEVR);
308 void rpmProblemPrint(FILE *fp, rpmProblem prob)
310 const char * msg = rpmProblemString(prob);
311 fprintf(fp, "%s\n", msg);
315 void rpmProblemSetPrint(FILE *fp, rpmProblemSet ps)
325 for (i = 0; i < ps->numProblems; i++) {
326 rpmProblem myprob = ps->probs + i;
327 if (!myprob->ignoreProblem)
328 rpmProblemPrint(fp, myprob);
332 static int sameProblem(const rpmProblem ap, const rpmProblem bp)
335 if (ap->type != bp->type)
338 if (bp->pkgNEVR && strcmp(ap->pkgNEVR, bp->pkgNEVR))
341 if (bp->altNEVR && strcmp(ap->altNEVR, bp->altNEVR))
344 if (bp->str1 && strcmp(ap->str1, bp->str1))
347 if (ap->ulong1 != bp->ulong1)
353 /* XXX FIXME: merge into rpmProblemSetPrint */
354 void printDepProblems(FILE * fp, rpmProblem probs, int numProblems)
356 const char * pkgNEVR, * altNEVR;
361 for (i = 0; i < numProblems; i++) {
366 /* Filter already displayed problems. */
367 for (j = 0; j < i; j++) {
368 if (!sameProblem(p, probs + j))
369 /*@innerbreak@*/ break;
374 pkgNEVR = (p->pkgNEVR ? p->pkgNEVR : "?pkgNEVR?");
375 altNEVR = (p->altNEVR ? p->altNEVR : "? ?altNEVR?");
377 fprintf(fp, "\t%s %s %s\n", altNEVR+2,
378 ((altNEVR[0] == 'C' && altNEVR[1] == ' ')
379 ? _("conflicts with") : _("is needed by")),