rpm 5.3.12
|
00001 00005 #include "system.h" 00006 00007 #include <rpmio.h> 00008 #include <rpmiotypes.h> /* XXX fnpyKey */ 00009 #include <rpmtypes.h> 00010 00011 #define _RPMPS_INTERNAL 00012 #include "rpmps.h" 00013 00014 #include "debug.h" 00015 00016 /*@access fnpyKey @*/ 00017 /*@access rpmProblem @*/ 00018 00019 /*@unchecked@*/ 00020 int _rpmps_debug = 0; 00021 00022 static void rpmpsFini(void * _ps) 00023 { 00024 rpmps ps = _ps; 00025 int i; 00026 00027 if (ps == NULL) return; 00028 if (ps->probs) 00029 for (i = 0; i < ps->numProblems; i++) { 00030 rpmProblem p = ps->probs + i; 00031 p->pkgNEVR = _free(p->pkgNEVR); 00032 p->altNEVR = _free(p->altNEVR); 00033 p->str1 = _free(p->str1); 00034 } 00035 ps->probs = _free(ps->probs); 00036 } 00037 00038 /*@unchecked@*/ /*@only@*/ /*@null@*/ 00039 rpmioPool _rpmpsPool; 00040 00041 static rpmps rpmpsGetPool(/*@null@*/ rpmioPool pool) 00042 /*@globals _rpmpsPool, fileSystem, internalState @*/ 00043 /*@modifies pool, _rpmpsPool, fileSystem, internalState @*/ 00044 { 00045 rpmps ps; 00046 00047 if (_rpmpsPool == NULL) { 00048 _rpmpsPool = rpmioNewPool("ps", sizeof(*ps), -1, _rpmps_debug, 00049 NULL, NULL, rpmpsFini); 00050 pool = _rpmpsPool; 00051 } 00052 return (rpmps) rpmioGetPool(pool, sizeof(*ps)); 00053 } 00054 00055 rpmps rpmpsCreate(void) 00056 { 00057 rpmps ps = rpmpsGetPool(_rpmpsPool); 00058 ps->numProblems = 0; 00059 ps->numProblemsAlloced = 0; 00060 ps->probs = NULL; 00061 return rpmpsLink(ps, "create"); 00062 } 00063 00064 int rpmpsNumProblems(rpmps ps) 00065 { 00066 int numProblems = 0; 00067 if (ps && ps->probs) 00068 numProblems = ps->numProblems; 00069 return numProblems; 00070 } 00071 00072 rpmpsi rpmpsInitIterator(rpmps ps) 00073 { 00074 rpmpsi psi = NULL; 00075 if (ps != NULL) { 00076 psi = xcalloc(1, sizeof(*psi)); 00077 /*@-assignexpose -castexpose @*/ 00078 psi->ps = rpmpsLink(ps, "iter ref"); 00079 /*@=assignexpose =castexpose @*/ 00080 psi->ix = -1; 00081 } 00082 return psi; 00083 } 00084 00085 rpmpsi rpmpsFreeIterator(rpmpsi psi) 00086 { 00087 if (psi != NULL) { 00088 psi->ps = rpmpsUnlink(psi->ps, "iter unref"); 00089 psi = _free(psi); 00090 } 00091 return NULL; 00092 } 00093 00094 int rpmpsNextIterator(rpmpsi psi) 00095 { 00096 int i = -1; 00097 00098 if (psi != NULL && ++psi->ix >= 0) { 00099 if (psi->ix < rpmpsNumProblems(psi->ps)) { 00100 i = psi->ix; 00101 } else { 00102 psi->ix = -1; 00103 } 00104 } 00105 return i; 00106 } 00107 00108 rpmProblem rpmpsProblem(rpmpsi psi) 00109 { 00110 rpmProblem p = NULL; 00111 if (psi != NULL && psi->ix >= 0 && psi->ix < rpmpsNumProblems(psi->ps)) { 00112 p = psi->ps->probs + psi->ix; 00113 } 00114 return p; 00115 } 00116 00117 void rpmpsAppend(rpmps ps, rpmProblemType type, 00118 const char * pkgNEVR, fnpyKey key, 00119 const char * dn, const char * bn, 00120 const char * altNEVR, rpmuint64_t ulong1) 00121 { 00122 rpmProblem p; 00123 char *t; 00124 00125 if (ps == NULL) return; 00126 00127 if (ps->numProblems == ps->numProblemsAlloced) { 00128 if (ps->numProblemsAlloced) 00129 ps->numProblemsAlloced *= 2; 00130 else 00131 ps->numProblemsAlloced = 2; 00132 ps->probs = xrealloc(ps->probs, 00133 ps->numProblemsAlloced * sizeof(*ps->probs)); 00134 } 00135 00136 p = ps->probs + ps->numProblems; 00137 ps->numProblems++; 00138 memset(p, 0, sizeof(*p)); 00139 00140 p->type = type; 00141 p->key = key; 00142 p->ulong1 = ulong1; 00143 p->ignoreProblem = 0; 00144 00145 p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL); 00146 p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL); 00147 00148 p->str1 = NULL; 00149 if (dn != NULL || bn != NULL) { 00150 t = xcalloc(1, (dn != NULL ? strlen(dn) : 0) + 00151 (bn != NULL ? strlen(bn) : 0) + 1); 00152 p->str1 = t; 00153 if (dn != NULL) t = stpcpy(t, dn); 00154 if (bn != NULL) t = stpcpy(t, bn); 00155 } 00156 } 00157 00158 #define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b)))) 00159 00160 int rpmpsTrim(rpmps ps, rpmps filter) 00161 { 00162 rpmProblem t; 00163 rpmProblem f; 00164 int gotProblems = 0; 00165 00166 if (ps == NULL || ps->numProblems == 0) 00167 return 0; 00168 00169 if (filter == NULL) 00170 return (ps->numProblems == 0 ? 0 : 1); 00171 00172 t = ps->probs; 00173 f = filter->probs; 00174 00175 while ((f - filter->probs) < filter->numProblems) { 00176 if (!f->ignoreProblem) { 00177 f++; 00178 continue; 00179 } 00180 while ((t - ps->probs) < ps->numProblems) { 00181 /*@-nullpass@*/ /* LCL: looks good to me <shrug> */ 00182 if (f->type == t->type && t->key == f->key && 00183 XSTRCMP(f->str1, t->str1)) 00184 /*@innerbreak@*/ break; 00185 /*@=nullpass@*/ 00186 t++; 00187 gotProblems = 1; 00188 } 00189 00190 /* XXX This can't happen, but let's be sane in case it does. */ 00191 if ((t - ps->probs) == ps->numProblems) 00192 break; 00193 00194 t->ignoreProblem = f->ignoreProblem; 00195 t++, f++; 00196 } 00197 00198 if ((t - ps->probs) < ps->numProblems) 00199 gotProblems = 1; 00200 00201 return gotProblems; 00202 } 00203 00204 #if !defined(HAVE_VSNPRINTF) 00205 /*@-shadow -bufferoverflowhigh @*/ 00206 static inline int vsnprintf(/*@out@*/ char * buf, /*@unused@*/ int nb, 00207 const char * fmt, va_list ap) 00208 { 00209 return vsprintf(buf, fmt, ap); 00210 } 00211 /*@=shadow =bufferoverflowhigh @*/ 00212 #endif 00213 #if !defined(HAVE_SNPRINTF) 00214 static inline int snprintf(/*@out@*/ char * buf, int nb, const char * fmt, ...) 00215 { 00216 va_list ap; 00217 int rc; 00218 va_start(ap, fmt); 00219 rc = vsnprintf(buf, nb, fmt, ap); 00220 va_end(ap); 00221 return rc; 00222 } 00223 #endif 00224 00225 const char * rpmProblemString(const rpmProblem prob) 00226 { 00227 /*@observer@*/ 00228 const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?"); 00229 /*@observer@*/ 00230 const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "? ?altNEVR?"); 00231 /*@observer@*/ 00232 const char * str1 = (prob->str1 ? prob->str1 : N_("different")); 00233 size_t nb = strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 1024; 00234 char * buf = xmalloc(nb+1); 00235 int rc; 00236 00237 switch (prob->type) { 00238 case RPMPROB_BADPLATFORM: 00239 rc = snprintf(buf, nb, 00240 _("package %s is intended for a %s platform"), 00241 pkgNEVR, str1); 00242 break; 00243 case RPMPROB_PKG_INSTALLED: 00244 rc = snprintf(buf, nb, 00245 _("package %s is already installed"), 00246 pkgNEVR); 00247 break; 00248 case RPMPROB_NOREPACKAGE: 00249 rc = snprintf(buf, nb, 00250 _("re-packaged package with %s: %s is missing"), 00251 str1, altNEVR); 00252 break; 00253 case RPMPROB_BADRELOCATE: 00254 rc = snprintf(buf, nb, 00255 _("path %s in package %s is not relocatable"), 00256 str1, pkgNEVR); 00257 break; 00258 case RPMPROB_NEW_FILE_CONFLICT: 00259 rc = snprintf(buf, nb, 00260 _("file %s conflicts between attempted installs of %s and %s"), 00261 str1, pkgNEVR, altNEVR); 00262 break; 00263 case RPMPROB_FILE_CONFLICT: 00264 rc = snprintf(buf, nb, 00265 _("file %s from install of %s conflicts with file from package %s"), 00266 str1, pkgNEVR, altNEVR); 00267 break; 00268 case RPMPROB_OLDPACKAGE: 00269 rc = snprintf(buf, nb, 00270 _("package %s (which is newer than %s) is already installed"), 00271 altNEVR, pkgNEVR); 00272 break; 00273 case RPMPROB_DISKSPACE: 00274 rc = snprintf(buf, nb, 00275 _("installing package %s needs %lu%cB on the %s filesystem"), 00276 pkgNEVR, 00277 (unsigned long) (prob->ulong1 > (1024*1024) 00278 ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024) 00279 : (prob->ulong1 + 1023) / 1024), 00280 prob->ulong1 > (1024*1024) ? 'M' : 'K', 00281 str1); 00282 break; 00283 case RPMPROB_DISKNODES: 00284 rc = snprintf(buf, nb, 00285 _("installing package %s needs %lu inodes on the %s filesystem"), 00286 pkgNEVR, (unsigned long)prob->ulong1, str1); 00287 break; 00288 case RPMPROB_BADPRETRANS: 00289 rc = snprintf(buf, nb, 00290 _("package %s pre-transaction syscall(s): %s failed: %s"), 00291 pkgNEVR, str1, strerror((int)(prob->ulong1))); 00292 break; 00293 case RPMPROB_REQUIRES: 00294 rc = snprintf(buf, nb, _("%s is needed by %s%s"), 00295 altNEVR+2, 00296 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR); 00297 break; 00298 case RPMPROB_CONFLICT: 00299 rc = snprintf(buf, nb, _("%s conflicts with %s%s"), 00300 altNEVR+2, 00301 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR); 00302 break; 00303 case RPMPROB_RDONLY: 00304 rc = snprintf(buf, nb, 00305 _("installing package %s on %s rdonly filesystem"), 00306 pkgNEVR, str1); 00307 break; 00308 default: 00309 rc = snprintf(buf, nb, 00310 _("unknown error %d encountered while manipulating package %s"), 00311 prob->type, pkgNEVR); 00312 break; 00313 } 00314 00315 buf[nb] = '\0'; 00316 return buf; 00317 } 00318 00319 static int sameProblem(const rpmProblem ap, const rpmProblem bp) 00320 /*@*/ 00321 { 00322 if (ap->type != bp->type) 00323 return 1; 00324 if (ap->pkgNEVR) 00325 if (bp->pkgNEVR && strcmp(ap->pkgNEVR, bp->pkgNEVR)) 00326 return 1; 00327 if (ap->altNEVR) 00328 if (bp->altNEVR && strcmp(ap->altNEVR, bp->altNEVR)) 00329 return 1; 00330 if (ap->str1) 00331 if (bp->str1 && strcmp(ap->str1, bp->str1)) 00332 return 1; 00333 00334 if (ap->ulong1 != bp->ulong1) 00335 return 1; 00336 00337 return 0; 00338 } 00339 00340 void rpmpsPrint(FILE *fp, rpmps ps) 00341 { 00342 const char * msg; 00343 rpmpsi psi; 00344 int i; 00345 00346 if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0) 00347 return; 00348 00349 if (fp == NULL) 00350 fp = stderr; 00351 00352 psi = rpmpsInitIterator(ps); 00353 while ((i = rpmpsNextIterator(psi)) >= 0) { 00354 rpmProblem p = rpmpsProblem(psi); 00355 rpmpsi psif; 00356 int j; 00357 00358 if (p->ignoreProblem) 00359 continue; 00360 00361 /* Filter already displayed problems. */ 00362 psif = rpmpsInitIterator(ps); 00363 while ((j = rpmpsNextIterator(psif)) < i) { 00364 if (!sameProblem(p, rpmpsProblem(psif))) 00365 /*@innerbreak@*/ break; 00366 } 00367 psif = rpmpsFreeIterator(psif); 00368 00369 if (j < i) 00370 continue; 00371 00372 msg = rpmProblemString(p); 00373 fprintf(fp, "\t%s\n", msg); 00374 msg = _free(msg); 00375 00376 } 00377 psi = rpmpsFreeIterator(psi); 00378 } 00379 00380 rpmProblem rpmpsGetProblem(rpmps ps, int num) 00381 { 00382 if (ps == NULL) 00383 return(NULL); 00384 /* XXX Retrieve last problem with negative index. */ 00385 if (num < 0) 00386 num = ps->numProblems - 1; 00387 if (num >= ps->numProblems) 00388 return(NULL); 00389 return (ps->probs + num); 00390 } 00391 00392 char * rpmProblemGetPkgNEVR(rpmProblem prob) 00393 { 00394 return prob->pkgNEVR; 00395 } 00396 00397 char * rpmProblemGetAltNEVR(rpmProblem prob) 00398 { 00399 return prob->altNEVR; 00400 } 00401 00402 char * rpmProblemGetStr(rpmProblem prob) 00403 { 00404 return prob->str1; 00405 } 00406 00407 rpmuint64_t rpmProblemGetDiskNeed(rpmProblem prob) 00408 { 00409 return prob->ulong1; 00410 } 00411 00412 rpmProblemType rpmProblemGetType(rpmProblem prob) 00413 { 00414 return prob->type; 00415 } 00416 00417 fnpyKey rpmProblemKey(rpmProblem prob) 00418 { 00419 return prob->key; 00420 }