Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

lib/rpmps.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmlib.h>
00008 
00009 #define _RPMPS_INTERNAL
00010 #include "rpmps.h"
00011 
00012 #include "misc.h"
00013 #include "debug.h"
00014 
00015 /*@access fnpyKey @*/
00016 /*@access rpmProblem @*/
00017 
00018 /*@unchecked@*/
00019 int _rpmps_debug = 0;
00020 
00021 rpmps XrpmpsUnlink(rpmps ps, const char * msg,
00022                 const char * fn, unsigned ln)
00023 {
00024 /*@-modfilesys@*/
00025 if (_rpmps_debug && msg != NULL)
00026 fprintf(stderr, "--> ps %p -- %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
00027 /*@=modfilesys@*/
00028     ps->nrefs--;
00029 /*@-refcounttrans@*/
00030     return ps;
00031 /*@=refcounttrans@*/
00032 }
00033 
00034 rpmps XrpmpsLink(rpmps ps, const char * msg,
00035                 const char * fn, unsigned ln)
00036 {
00037     ps->nrefs++;
00038 /*@-modfilesys@*/
00039 if (_rpmps_debug && msg != NULL)
00040 fprintf(stderr, "--> ps %p ++ %d %s at %s:%u\n", ps, ps->nrefs, msg, fn, ln);
00041 /*@=modfilesys@*/
00042 /*@-refcounttrans@*/
00043     return ps;
00044 /*@=refcounttrans@*/
00045 }
00046 
00047 int rpmpsNumProblems(rpmps ps)
00048 {
00049     int numProblems = 0;
00050     if (ps && ps->probs)
00051         numProblems = ps->numProblems;
00052     return numProblems;
00053 }
00054 
00055 rpmps rpmpsCreate(void)
00056 {
00057     rpmps ps = xcalloc(1, sizeof(*ps));
00058     return rpmpsLink(ps, "create");
00059 }
00060 
00061 rpmps rpmpsFree(rpmps ps)
00062 {
00063     if (ps == NULL) return NULL;
00064     ps = rpmpsUnlink(ps, "dereference");
00065     if (ps->nrefs > 0)
00066         return NULL;
00067         
00068     if (ps->probs) {
00069         int i;
00070         for (i = 0; i < ps->numProblems; i++) {
00071             rpmProblem p = ps->probs + i;
00072             p->pkgNEVR = _free(p->pkgNEVR);
00073             p->altNEVR = _free(p->altNEVR);
00074             p->str1 = _free(p->str1);
00075         }
00076         ps->probs = _free(ps->probs);
00077     }
00078     ps = _free(ps);
00079     return NULL;
00080 }
00081 
00082 void rpmpsAppend(rpmps ps, rpmProblemType type,
00083                 const char * pkgNEVR, fnpyKey key,
00084                 const char * dn, const char * bn,
00085                 const char * altNEVR, unsigned long long ulong1)
00086 {
00087     rpmProblem p;
00088     char *t;
00089 
00090     if (ps == NULL) return;
00091 
00092     if (ps->numProblems == ps->numProblemsAlloced) {
00093         if (ps->numProblemsAlloced)
00094             ps->numProblemsAlloced *= 2;
00095         else
00096             ps->numProblemsAlloced = 2;
00097         ps->probs = xrealloc(ps->probs,
00098                         ps->numProblemsAlloced * sizeof(*ps->probs));
00099     }
00100 
00101     p = ps->probs + ps->numProblems;
00102     ps->numProblems++;
00103 /*@-boundswrite@*/
00104     memset(p, 0, sizeof(*p));
00105 /*@=boundswrite@*/
00106 
00107     p->type = type;
00108     p->key = key;
00109     p->ulong1 = ulong1;
00110     p->ignoreProblem = 0;
00111 
00112     p->pkgNEVR = (pkgNEVR ? xstrdup(pkgNEVR) : NULL);
00113     p->altNEVR = (altNEVR ? xstrdup(altNEVR) : NULL);
00114 
00115     p->str1 = NULL;
00116     if (dn != NULL || bn != NULL) {
00117 /*@-boundswrite@*/
00118         t = xcalloc(1,  (dn != NULL ? strlen(dn) : 0) +
00119                         (bn != NULL ? strlen(bn) : 0) + 1);
00120         p->str1 = t;
00121         if (dn != NULL) t = stpcpy(t, dn);
00122         if (bn != NULL) t = stpcpy(t, bn);
00123 /*@=boundswrite@*/
00124     }
00125 }
00126 
00127 #define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b))))
00128 
00129 int rpmpsTrim(rpmps ps, rpmps filter)
00130 {
00131     rpmProblem t;
00132     rpmProblem f;
00133     int gotProblems = 0;
00134 
00135     if (ps == NULL || ps->numProblems == 0)
00136         return 0;
00137 
00138     if (filter == NULL)
00139         return (ps->numProblems == 0 ? 0 : 1);
00140 
00141     t = ps->probs;
00142     f = filter->probs;
00143 
00144     while ((f - filter->probs) < filter->numProblems) {
00145         if (!f->ignoreProblem) {
00146             f++;
00147             continue;
00148         }
00149         while ((t - ps->probs) < ps->numProblems) {
00150             /*@-nullpass@*/     /* LCL: looks good to me <shrug> */
00151             if (f->type == t->type && t->key == f->key &&
00152                      XSTRCMP(f->str1, t->str1))
00153                 /*@innerbreak@*/ break;
00154             /*@=nullpass@*/
00155             t++;
00156             gotProblems = 1;
00157         }
00158 
00159         /* XXX This can't happen, but let's be sane in case it does. */
00160         if ((t - ps->probs) == ps->numProblems)
00161             break;
00162 
00163         t->ignoreProblem = f->ignoreProblem;
00164         t++, f++;
00165     }
00166 
00167     if ((t - ps->probs) < ps->numProblems)
00168         gotProblems = 1;
00169 
00170     return gotProblems;
00171 }
00172 
00173 #if !defined(HAVE_VSNPRINTF)
00174 /*@-shadow -bufferoverflowhigh @*/
00175 static inline int vsnprintf(/*@out@*/ char * buf, /*@unused@*/ int nb,
00176         const char * fmt, va_list ap)
00177 {
00178     return vsprintf(buf, fmt, ap);
00179 }
00180 /*@=shadow =bufferoverflowhigh @*/
00181 #endif
00182 #if !defined(HAVE_SNPRINTF)
00183 static inline int snprintf(/*@out@*/ char * buf, int nb, const char * fmt, ...)
00184 {
00185     va_list ap;
00186     int rc;
00187     va_start(ap, fmt);
00188     rc = vsnprintf(buf, nb, fmt, ap);
00189     va_end(ap);
00190     return rc;
00191 }
00192 #endif
00193 
00194 const char * rpmProblemString(const rpmProblem prob)
00195 {
00196 /*@observer@*/
00197     const char * pkgNEVR = (prob->pkgNEVR ? prob->pkgNEVR : "?pkgNEVR?");
00198 /*@observer@*/
00199     const char * altNEVR = (prob->altNEVR ? prob->altNEVR : "? ?altNEVR?");
00200 /*@observer@*/
00201     const char * str1 = (prob->str1 ? prob->str1 : N_("different"));
00202     int nb =    strlen(pkgNEVR) + strlen(str1) + strlen(altNEVR) + 100;
00203     char * buf = xmalloc(nb+1);
00204     int rc;
00205 
00206     switch (prob->type) {
00207     case RPMPROB_BADPLATFORM:
00208         rc = snprintf(buf, nb,
00209                 _("package %s is intended for a %s platform"),
00210                 pkgNEVR, str1);
00211         break;
00212     case RPMPROB_PKG_INSTALLED:
00213         rc = snprintf(buf, nb,
00214                 _("package %s is already installed"),
00215                 pkgNEVR);
00216         break;
00217     case RPMPROB_NOREPACKAGE:
00218         rc = snprintf(buf, nb,
00219                 _("re-packaged package with %s: %s is missing"),
00220                 str1, altNEVR);
00221         break;
00222     case RPMPROB_BADRELOCATE:
00223         rc = snprintf(buf, nb,
00224                 _("path %s in package %s is not relocatable"),
00225                 str1, pkgNEVR);
00226         break;
00227     case RPMPROB_NEW_FILE_CONFLICT:
00228         rc = snprintf(buf, nb,
00229                 _("file %s conflicts between attempted installs of %s and %s"),
00230                 str1, pkgNEVR, altNEVR);
00231         break;
00232     case RPMPROB_FILE_CONFLICT:
00233         rc = snprintf(buf, nb,
00234             _("file %s from install of %s conflicts with file from package %s"),
00235                 str1, pkgNEVR, altNEVR);
00236         break;
00237     case RPMPROB_OLDPACKAGE:
00238         rc = snprintf(buf, nb,
00239                 _("package %s (which is newer than %s) is already installed"),
00240                 altNEVR, pkgNEVR);
00241         break;
00242     case RPMPROB_DISKSPACE:
00243         rc = snprintf(buf, nb,
00244             _("installing package %s needs %lu%cB on the %s filesystem"),
00245                 pkgNEVR,
00246                 (unsigned long) (prob->ulong1 > (1024*1024)
00247                     ? (prob->ulong1 + 1024 * 1024 - 1) / (1024 * 1024)
00248                     : (prob->ulong1 + 1023) / 1024),
00249                 prob->ulong1 > (1024*1024) ? 'M' : 'K',
00250                 str1);
00251         break;
00252     case RPMPROB_DISKNODES:
00253         rc = snprintf(buf, nb,
00254             _("installing package %s needs %lu inodes on the %s filesystem"),
00255                 pkgNEVR, (unsigned long)prob->ulong1, str1);
00256         break;
00257     case RPMPROB_BADPRETRANS:
00258         rc = snprintf(buf, nb,
00259                 _("package %s pre-transaction syscall(s): %s failed: %s"),
00260                 pkgNEVR, str1, strerror((int)(prob->ulong1)));
00261         break;
00262     case RPMPROB_REQUIRES:
00263         rc = snprintf(buf, nb, _("%s is needed by %s%s"),
00264                 altNEVR+2,
00265                 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
00266         break;
00267     case RPMPROB_CONFLICT:
00268         rc = snprintf(buf, nb, _("%s conflicts with %s%s"),
00269                 altNEVR+2,
00270                 (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR);
00271         break;
00272     case RPMPROB_RDONLY:
00273         rc = snprintf(buf, nb,
00274             _("installing package %s on %s rdonly filesystem"),
00275                 pkgNEVR, str1);
00276         break;
00277     default:
00278         rc = snprintf(buf, nb,
00279                 _("unknown error %d encountered while manipulating package %s"),
00280                 prob->type, pkgNEVR);
00281         break;
00282     }
00283 
00284     buf[nb] = '\0';
00285     return buf;
00286 }
00287 
00288 static int sameProblem(const rpmProblem ap, const rpmProblem bp)
00289         /*@*/
00290 {
00291     if (ap->type != bp->type)
00292         return 1;
00293     if (ap->pkgNEVR)
00294         if (bp->pkgNEVR && strcmp(ap->pkgNEVR, bp->pkgNEVR))
00295             return 1;
00296     if (ap->altNEVR)
00297         if (bp->altNEVR && strcmp(ap->altNEVR, bp->altNEVR))
00298             return 1;
00299     if (ap->str1)
00300         if (bp->str1 && strcmp(ap->str1, bp->str1))
00301             return 1;
00302 
00303     if (ap->ulong1 != bp->ulong1)
00304         return 1;
00305 
00306     return 0;
00307 }
00308 
00309 void rpmpsPrint(FILE *fp, rpmps ps)
00310 {
00311     const char * msg;
00312     int i;
00313 
00314     if (ps == NULL || ps->probs == NULL || ps->numProblems <= 0)
00315         return;
00316 
00317     if (fp == NULL)
00318         fp = stderr;
00319 
00320     for (i = 0; i < ps->numProblems; i++) {
00321         rpmProblem p;
00322         int j;
00323 
00324         p = ps->probs + i;
00325 
00326         if (p->ignoreProblem)
00327             continue;
00328 
00329         /* Filter already displayed problems. */
00330         for (j = 0; j < i; j++) {
00331             if (!sameProblem(p, ps->probs + j))
00332                 /*@innerbreak@*/ break;
00333         }
00334         if (j < i)
00335             continue;
00336 
00337         msg = rpmProblemString(p);
00338         fprintf(fp, "\t%s\n", msg);
00339         msg = _free(msg);
00340 
00341     }
00342 }

Generated on Sat Oct 1 21:46:12 2011 for rpm by  doxygen 1.4.4