15 /*@access rpmProblem @*/
20 rpmps XrpmpsUnlink(rpmps ps, const char * msg,
21 const char * fn, unsigned ln)
24 if (_rpmps_debug > 0 && msg != NULL)
25 fprintf(stderr, "--> ps %p -- %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
33 rpmps XrpmpsLink(rpmps ps, const char * msg,
34 const char * fn, unsigned ln)
38 if (_rpmps_debug > 0 && msg != NULL)
39 fprintf(stderr, "--> ps %p ++ %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
46 int rpmpsNumProblems(rpmps ps)
50 numProblems = ps->numProblems;
54 rpmps rpmpsCreate(void)
56 rpmps ps = xcalloc(1, sizeof(*ps));
57 return rpmpsLink(ps, "create");
60 rpmps rpmpsFree(rpmps ps)
62 if (ps == NULL) return NULL;
63 ps = rpmpsUnlink(ps, "dereference");
69 for (i = 0; i < ps->numProblems; i++) {
70 rpmProblem p = ps->probs + i;
71 p->pkgNEVR = _free(p->pkgNEVR);
72 p->altNEVR = _free(p->altNEVR);
73 p->str1 = _free(p->str1);
75 ps->probs = _free(ps->probs);
81 void rpmpsAppend(rpmps ps, rpmProblemType type,
82 const char * pkgNEVR, fnpyKey key,
83 const char * dn, const char * bn,
84 const char * altNEVR, unsigned long ulong1)
89 if (ps == NULL) return;
91 if (ps->numProblems == ps->numProblemsAlloced) {
92 if (ps->numProblemsAlloced)
93 ps->numProblemsAlloced *= 2;
95 ps->numProblemsAlloced = 2;
96 ps->probs = xrealloc(ps->probs,
97 ps->numProblemsAlloced * sizeof(*ps->probs));
100 p = ps->probs + ps->numProblems;
103 memset(p, 0, sizeof(*p));
109 p->ignoreProblem = 0;
111 p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL);
112 p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL);
115 if (dn != NULL || bn != NULL) {
117 t = xcalloc(1, (dn != NULL ? strlen(dn) : 0) +
118 (bn != NULL ? strlen(bn) : 0) + 1);
120 if (dn != NULL) t = stpcpy(t, dn);
121 if (bn != NULL) t = stpcpy(t, bn);
126 #define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b))))
128 int rpmpsTrim(rpmps ps, rpmps filter)
134 if (ps == NULL || ps->numProblems == 0)
138 return (ps->numProblems == 0 ? 0 : 1);
143 while ((f - filter->probs) < filter->numProblems) {
144 if (!f->ignoreProblem) {
148 while ((t - ps->probs) < ps->numProblems) {
149 /*@-nullpass@*/ /* LCL: looks good to me <shrug> */
150 if (f->type == t->type && t->key == f->key &&
151 XSTRCMP(f->str1, t->str1))
152 /*@innerbreak@*/ break;
158 /* XXX This can't happen, but let's be sane in case it does. */
159 if ((t - ps->probs) == ps->numProblems)
162 t->ignoreProblem = f->ignoreProblem;
166 if ((t - ps->probs) < ps->numProblems)
172 #if !defined(HAVE_VSNPRINTF)
173 /*@-shadow -bufferoverflowhigh @*/
174 static inline int vsnprintf(/*@out@*/ char * buf, /*@unused@*/ int nb,
175 const char * fmt, va_list ap)
177 return vsprintf(buf, fmt, ap);
179 /*@=shadow =bufferoverflowhigh @*/
181 #if !defined(HAVE_SNPRINTF)
182 static inline int snprintf(/*@out@*/ char * buf, int nb, const char * fmt, ...)
187 rc = vsnprintf(buf, nb, fmt, ap);
193 const char * rpmProblemString(const rpmProblem prob)
196 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?");
198 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "? ?altNEVR?");
200 const char * str1 = (prob->str1 ? prob->str1 : N_("different"));
201 int nb = strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
202 char * buf = xmalloc(nb+1);
205 switch (prob->type) {
206 case RPMPROB_BADARCH:
207 rc = snprintf(buf, nb,
208 _("package %s is intended for a %s architecture"),
212 rc = snprintf(buf, nb,
213 _("package %s is intended for a %s operating system"),
216 case RPMPROB_PKG_INSTALLED:
217 rc = snprintf(buf, nb,
218 _("package %s is already installed"),
221 case RPMPROB_BADRELOCATE:
222 rc = snprintf(buf, nb,
223 _("path %s in package %s is not relocateable"),
226 case RPMPROB_NEW_FILE_CONFLICT:
227 rc = snprintf(buf, nb,
228 _("file %s conflicts between attempted installs of %s and %s"),
229 str1, pkgNEVR, altNEVR);
231 case RPMPROB_FILE_CONFLICT:
232 rc = snprintf(buf, nb,
233 _("file %s from install of %s conflicts with file from package %s"),
234 str1, pkgNEVR, altNEVR);
236 case RPMPROB_OLDPACKAGE:
237 rc = snprintf(buf, nb,
238 _("package %s (which is newer than %s) is already installed"),
241 case RPMPROB_DISKSPACE:
242 rc = snprintf(buf, nb,
243 _("installing package %s needs %ld%cB on the %s filesystem"),
245 prob->ulong1 > (1024*1024)
246 ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
247 : (prob->ulong1 + 1023) / 1024,
248 prob->ulong1 > (1024*1024) ? 'M' : 'K',
251 case RPMPROB_DISKNODES:
252 rc = snprintf(buf, nb,
253 _("installing package %s needs %ld inodes on the %s filesystem"),
254 pkgNEVR, (long)prob->ulong1, str1);
256 case RPMPROB_BADPRETRANS:
257 rc = snprintf(buf, nb,
258 _("package %s pre-transaction syscall(s): %s failed: %s"),
259 pkgNEVR, str1, strerror(prob->ulong1));
261 case RPMPROB_REQUIRES:
262 rc = snprintf(buf, nb, _("%s is needed by %s%s"),
264 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
266 case RPMPROB_CONFLICT:
267 rc = snprintf(buf, nb, _("%s conflicts with %s%s"),
269 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
272 rc = snprintf(buf, nb,
273 _("unknown error %d encountered while manipulating package %s"),
274 prob->type, pkgNEVR);
282 static int sameProblem(const rpmProblem ap, const rpmProblem bp)
285 if (ap->type != bp->type)
288 if (bp->pkgNEVR && strcmp(ap->pkgNEVR, bp->pkgNEVR))
291 if (bp->altNEVR && strcmp(ap->altNEVR, bp->altNEVR))
294 if (bp->str1 && strcmp(ap->str1, bp->str1))
297 if (ap->ulong1 != bp->ulong1)
303 void rpmpsPrint(FILE *fp, rpmps ps)
308 if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0)
314 for (i = 0; i < ps->numProblems; i++) {
320 if (p->ignoreProblem)
323 /* Filter already displayed problems. */
324 for (j = 0; j < i; j++) {
325 if (!sameProblem(p, ps->probs + j))
326 /*@innerbreak@*/ break;
331 msg = rpmProblemString(p);
332 fprintf(fp, "\t%s\n", msg);