• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

lib/rpmgi.c

Go to the documentation of this file.
00001 /*@-modfilesys@*/
00005 #include "system.h"
00006 
00007 #include <rpmio.h>
00008 #include <rpmcb.h>              /* XXX fnpyKey */
00009 #include <rpmmacro.h>           /* XXX rpmExpand */
00010 #include <rpmlib.h>
00011 #include <rpmte.h>              /* XXX rpmElementType */
00012 #include <pkgio.h>              /* XXX rpmElementType */
00013 
00014 #define _RPMGI_INTERNAL
00015 #define _RPMTS_INTERNAL         /* XXX ts->probs et al */
00016 #include <rpmgi.h>
00017 
00018 #include <rpmdb.h>
00019 #include "manifest.h"
00020 
00021 #include "debug.h"
00022 
00023 /*@access FD_t @*/              /* XXX void * arg */
00024 /*@access fnpyKey @*/
00025 /*@access rpmdbMatchIterator @*/
00026 /*@access rpmts @*/
00027 /*@access rpmps @*/
00028 
00031 /*@unchecked@*/
00032 int _rpmgi_debug = 0;
00033 
00036 /*@unchecked@*/
00037 rpmgiFlags giFlags = RPMGI_NONE;
00038 
00041 /*@unchecked@*/
00042 static int indent = 2;
00043 
00046 /*@unchecked@*/ /*@observer@*/
00047 static const char * ftsInfoStrings[] = {
00048     "UNKNOWN",
00049     "D",
00050     "DC",
00051     "DEFAULT",
00052     "DNR",
00053     "DOT",
00054     "DP",
00055     "ERR",
00056     "F",
00057     "INIT",
00058     "NS",
00059     "NSOK",
00060     "SL",
00061     "SLNONE",
00062     "W",
00063 };
00064 
00067 /*@observer@*/
00068 static const char * ftsInfoStr(int fts_info)
00069         /*@*/
00070 {
00071 
00072     if (!(fts_info >= 1 && fts_info <= 14))
00073         fts_info = 0;
00074 /*@-compmempass@*/
00075     return ftsInfoStrings[ fts_info ];
00076 /*@=compmempass@*/
00077 }
00078 
00086 /*@null@*/
00087 static FD_t rpmgiOpen(const char * path, const char * fmode)
00088         /*@globals rpmGlobalMacroContext, h_errno, errno, internalState @*/
00089         /*@modifies rpmGlobalMacroContext, h_errno, errno, internalState @*/
00090 {
00091     const char * fn = rpmExpand(path, NULL);
00092     FD_t fd;
00093 
00094     /* FIXME (see http://rpm5.org/community/rpm-devel/0523.html) */
00095     errno = 0;
00096     fd = Fopen(fn, fmode);
00097 
00098     if (fd == NULL || Ferror(fd)) {
00099         rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), fn, Fstrerror(fd));
00100         if (fd != NULL) (void) Fclose(fd);
00101         fd = NULL;
00102     }
00103     fn = _free(fn);
00104 
00105     return fd;
00106 }
00107 
00114 static rpmRC rpmgiLoadManifest(rpmgi gi, const char * path)
00115         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00116         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00117 {
00118     FD_t fd = rpmgiOpen(path, "r%{?_rpmgio}");
00119     rpmRC rpmrc = RPMRC_FAIL;
00120 
00121     if (fd != NULL) {
00122         rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv);
00123         (void) Fclose(fd);
00124     }
00125     return rpmrc;
00126 }
00127 
00134 /*@null@*/
00135 static Header rpmgiReadHeader(rpmgi gi, const char * path)
00136         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00137         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00138 {
00139     FD_t fd = rpmgiOpen(path, "r%{?_rpmgio}");
00140     Header h = NULL;
00141 
00142     if (fd != NULL) {
00143         /* XXX what if path needs expansion? */
00144         rpmRC rpmrc = rpmReadPackageFile(gi->ts, fd, path, &h);
00145 
00146         (void) Fclose(fd);
00147 
00148         switch (rpmrc) {
00149         case RPMRC_NOTFOUND:
00150             /* XXX Read a package manifest. Restart ftswalk on success. */
00151         case RPMRC_FAIL:
00152         default:
00153             h = headerFree(h);
00154             break;
00155         case RPMRC_NOTTRUSTED:
00156         case RPMRC_NOKEY:
00157         case RPMRC_OK:
00158             break;
00159         }
00160     }
00161 
00162     return h;
00163 }
00164 
00170 static rpmRC rpmgiLoadNextKey(rpmgi gi)
00171         /*@modifies gi @*/
00172 {
00173     rpmRC rpmrc = RPMRC_NOTFOUND;
00174     if (gi->argv != NULL && gi->argv[gi->i] != NULL) {
00175         gi->keyp = gi->argv[gi->i];
00176         gi->keylen = 0;
00177         rpmrc = RPMRC_OK;
00178     } else {
00179         gi->i = -1;
00180         gi->keyp = NULL;
00181         gi->keylen = 0;
00182     }
00183     return rpmrc;
00184 }
00185 
00194 static rpmRC rpmgiLoadReadHeader(rpmgi gi)
00195         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00196         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00197 {
00198     rpmRC rpmrc = RPMRC_NOTFOUND;
00199     Header h = NULL;
00200 
00201     if (gi->argv != NULL && gi->argv[gi->i] != NULL)
00202     do {
00203         const char * fn;        /* XXX gi->hdrPath? */
00204 
00205         fn = gi->argv[gi->i];
00206         if (!(gi->flags & RPMGI_NOHEADER)) {
00207             h = rpmgiReadHeader(gi, fn);
00208             if (h != NULL)
00209                 rpmrc = RPMRC_OK;
00210         } else
00211             rpmrc = RPMRC_OK;
00212 
00213         if (rpmrc == RPMRC_OK || gi->flags & RPMGI_NOMANIFEST)
00214             break;
00215         if (errno == ENOENT)
00216             break;
00217 
00218         /* Not a header, so try for a manifest. */
00219         gi->argv[gi->i] = NULL;         /* Mark the insertion point */
00220         rpmrc = rpmgiLoadManifest(gi, fn);
00221         if (rpmrc != RPMRC_OK) {
00222             gi->argv[gi->i] = fn;       /* Manifest failed, restore fn */
00223             break;
00224         }
00225         fn = _free(fn);
00226         rpmrc = RPMRC_NOTFOUND;
00227     } while (1);
00228 
00229     if (rpmrc == RPMRC_OK && h != NULL)
00230         gi->h = headerLink(h);
00231     h = headerFree(h);
00232 
00233     return rpmrc;
00234 }
00235 
00241 /*@null@*/
00242 static rpmRC rpmgiWalkPathFilter(rpmgi gi)
00243         /*@*/
00244 {
00245     FTSENT * fts = gi->fts;
00246     rpmRC rpmrc = RPMRC_NOTFOUND;
00247     const char * s;
00248 
00249 if (_rpmgi_debug < 0)
00250 rpmlog(RPMLOG_DEBUG, "FTS_%s\t%*s %s%s\n", ftsInfoStr(fts->fts_info),
00251                 indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
00252                 fts->fts_name,
00253         ((fts->fts_info == FTS_D || fts->fts_info == FTS_DP) ? "/" : ""));
00254 
00255     switch (fts->fts_info) {
00256     case FTS_D:         /* preorder directory */
00257         break;
00258     case FTS_DP:        /* postorder directory */
00259         break;
00260     case FTS_F:         /* regular file */
00261         /* Ignore all but *.rpm files. */
00262         s = fts->fts_name + fts->fts_namelen + 1 - sizeof(".rpm");
00263         if (strcmp(s, ".rpm"))
00264             break;
00265         rpmrc = RPMRC_OK;
00266         break;
00267     case FTS_NS:        /* stat(2) failed */
00268     case FTS_DNR:       /* unreadable directory */
00269     case FTS_ERR:       /* error; errno is set */
00270         break;
00271     case FTS_DC:        /* directory that causes cycles */
00272     case FTS_DEFAULT:   /* none of the above */
00273     case FTS_DOT:       /* dot or dot-dot */
00274     case FTS_INIT:      /* initialized only */
00275     case FTS_NSOK:      /* no stat(2) requested */
00276     case FTS_SL:        /* symbolic link */
00277     case FTS_SLNONE:    /* symbolic link without target */
00278     case FTS_W:         /* whiteout object */
00279     default:
00280         break;
00281     }
00282     return rpmrc;
00283 }
00284 
00290 /*@null@*/
00291 static rpmRC rpmgiWalkReadHeader(rpmgi gi)
00292         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00293         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00294 {
00295     rpmRC rpmrc = RPMRC_NOTFOUND;
00296 
00297     if (gi->ftsp != NULL)
00298     while ((gi->fts = Fts_read(gi->ftsp)) != NULL) {
00299         if (gi->walkPathFilter)
00300             rpmrc = (*gi->walkPathFilter) (gi);
00301         else
00302             rpmrc = rpmgiWalkPathFilter(gi);
00303         if (rpmrc == RPMRC_OK)
00304             break;
00305     }
00306 
00307     if (rpmrc == RPMRC_OK) {
00308         Header h = NULL;
00309         if (!(gi->flags & RPMGI_NOHEADER)) {
00310             /* XXX rpmrc = rpmgiLoadReadHeader(gi); */
00311             if (gi->fts != NULL)        /* XXX can't happen */
00312                 h = rpmgiReadHeader(gi, gi->fts->fts_path);
00313         }
00314         if (h != NULL) {
00315             gi->h = headerLink(h);
00316             h = headerFree(h);
00317 /*@-noeffectuncon@*/
00318             if (gi->stash != NULL)
00319                 (void) (*gi->stash) (gi, gi->h);
00320 /*@=noeffectuncon@*/
00321         }
00322     }
00323 
00324     return rpmrc;
00325 }
00326 
00327 const char * rpmgiEscapeSpaces(const char * s)
00328 {
00329     const char * se;
00330     const char * t;
00331     char * te;
00332     size_t nb = 0;
00333 
00334     for (se = s; *se; se++) {
00335         if (isspace(*se))
00336             nb++;
00337         nb++;
00338     }
00339     nb++;
00340 
00341     t = te = xmalloc(nb);
00342     for (se = s; *se; se++) {
00343         if (isspace(*se))
00344             *te++ = '\\';
00345         *te++ = *se;
00346     }
00347     *te = '\0';
00348     return t;
00349 }
00350 
00357 static rpmRC rpmgiGlobArgv(rpmgi gi, /*@null@*/ ARGV_t argv)
00358         /*@globals internalState @*/
00359         /*@modifies gi, internalState @*/
00360 {
00361     const char * arg;
00362     rpmRC rpmrc = RPMRC_OK;
00363     int ac = 0;
00364     int xx;
00365 
00366     /* XXX Expand globs only if requested or for gi specific tags */
00367     if ((gi->flags & RPMGI_NOGLOB)
00368      || !(gi->tag == RPMDBI_HDLIST || gi->tag == RPMDBI_ARGLIST || gi->tag == RPMDBI_FTSWALK))
00369     {
00370         if (argv != NULL) {
00371             while (argv[ac] != NULL)
00372                 ac++;
00373 /*@-nullstate@*/ /* XXX argv is not NULL */
00374             xx = argvAppend(&gi->argv, argv);
00375 /*@=nullstate@*/
00376         }
00377         gi->argc = ac;
00378         return rpmrc;
00379     }
00380 
00381     if (argv != NULL)
00382     while ((arg = *argv++) != NULL) {
00383         const char * t = rpmgiEscapeSpaces(arg);
00384         ARGV_t av = NULL;
00385 
00386         xx = rpmGlob(t, &ac, &av);
00387         xx = argvAppend(&gi->argv, av);
00388         gi->argc += ac;
00389         av = argvFree(av);
00390         t = _free(t);
00391         ac = 0;
00392     }
00393     return rpmrc;
00394 }
00395 
00401 static rpmRC rpmgiInitFilter(rpmgi gi)
00402         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00403         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00404 {
00405     rpmRC rpmrc = RPMRC_OK;
00406     ARGV_t av;
00407     int res = 0;
00408 
00409     gi->mi = rpmtsInitIterator(gi->ts, gi->tag, gi->keyp, gi->keylen);
00410 
00411 if (_rpmgi_debug < 0)
00412 fprintf(stderr, "*** gi %p key %p[%d]\tmi %p\n", gi, gi->keyp, (int)gi->keylen, gi->mi);
00413 
00414     if (gi->argv != NULL)
00415     for (av = (const char **) gi->argv; *av != NULL; av++) {
00416         if (gi->tag == RPMDBI_PACKAGES) {
00417             int tag = RPMTAG_NAME;
00418             const char * pat;
00419             char * a, * ae;
00420 
00421             pat = a = xstrdup(*av);
00422             tag = RPMTAG_NAME;
00423 
00424             /* Parse for "tag=pattern" args. */
00425             if ((ae = strchr(a, '=')) != NULL) {
00426                 *ae++ = '\0';
00427                 if (*a != '\0') {       /* XXX HACK: permit '=foo' */
00428                     tag = tagValue(a);
00429                     if (tag < 0) {
00430                         rpmlog(RPMLOG_NOTICE, _("unknown tag: \"%s\"\n"), a);
00431                         res = 1;
00432                     }
00433                 }
00434                 pat = ae;
00435             }
00436             if (!res) {
00437 if (_rpmgi_debug  < 0)
00438 fprintf(stderr, "\tav %p[%d]: \"%s\" -> %s ~= \"%s\"\n", gi->argv, (int)(av - gi->argv), *av, tagName(tag), pat);
00439                 res = rpmdbSetIteratorRE(gi->mi, tag, RPMMIRE_DEFAULT, pat);
00440             }
00441             a = _free(a);
00442         }
00443 
00444         if (res == 0)
00445             continue;
00446 
00447         gi->mi = rpmdbFreeIterator(gi->mi);     /* XXX odd side effect? */
00448         rpmrc = RPMRC_FAIL;
00449         break;
00450     }
00451 
00452     return rpmrc;
00453 }
00454 
00455 rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
00456 {
00457     if (gi == NULL) return NULL;
00458 
00459 if (_rpmgi_debug && msg != NULL)
00460 fprintf(stderr, "--> gi %p -- %d %s(%s) at %s:%u\n", gi, gi->nrefs, msg, tagName(gi->tag), fn, ln);
00461 
00462     gi->nrefs--;
00463     return NULL;
00464 }
00465 
00466 rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
00467 {
00468     if (gi == NULL) return NULL;
00469     gi->nrefs++;
00470 
00471 if (_rpmgi_debug && msg != NULL)
00472 fprintf(stderr, "--> gi %p ++ %d %s(%s) at %s:%u\n", gi, gi->nrefs, msg, tagName(gi->tag), fn, ln);
00473 
00474     /*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
00475 }
00476 
00477 rpmgi rpmgiFree(rpmgi gi)
00478 {
00479     if (gi == NULL)
00480         return NULL;
00481 
00482     if (gi->nrefs > 1)
00483         return rpmgiUnlink(gi, "rpmgiFree");
00484 
00485     (void) rpmgiUnlink(gi, "rpmgiFree");
00486 
00487 /*@-usereleased@*/
00488 
00489     gi->hdrPath = _free(gi->hdrPath);
00490     gi->h = headerFree(gi->h);
00491 
00492     gi->argv = argvFree(gi->argv);
00493 
00494     if (gi->ftsp != NULL) {
00495         int xx;
00496         xx = Fts_close(gi->ftsp);
00497         gi->ftsp = NULL;
00498         gi->fts = NULL;
00499     }
00500     if (gi->fd != NULL) {
00501         (void) Fclose(gi->fd);
00502         gi->fd = NULL;
00503     }
00504     gi->tsi = rpmtsiFree(gi->tsi);
00505     gi->mi = rpmdbFreeIterator(gi->mi);
00506     gi->ts = rpmtsFree(gi->ts);
00507 
00508     memset(gi, 0, sizeof(*gi));         /* XXX trash and burn */
00509 /*@-refcounttrans@*/
00510     gi = _free(gi);
00511 /*@=refcounttrans@*/
00512 /*@=usereleased@*/
00513     return NULL;
00514 }
00515 
00516 rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
00517 {
00518     rpmgi gi = xcalloc(1, sizeof(*gi));
00519 
00520     if (gi == NULL)
00521         return NULL;
00522 
00523     gi->ts = rpmtsLink(ts, "rpmgiNew");
00524     gi->tsOrder = rpmtsOrder;
00525     gi->tag = tag;
00526 /*@-assignexpose@*/
00527     gi->keyp = keyp;
00528 /*@=assignexpose@*/
00529     gi->keylen = keylen;
00530 
00531     gi->flags = 0;
00532     gi->active = 0;
00533     gi->i = -1;
00534     gi->hdrPath = NULL;
00535     gi->h = NULL;
00536 
00537     gi->tsi = NULL;
00538     gi->mi = NULL;
00539     gi->fd = NULL;
00540     gi->argv = xcalloc(1, sizeof(*gi->argv));
00541     gi->argc = 0;
00542     gi->ftsOpts = 0;
00543     gi->ftsp = NULL;
00544     gi->fts = NULL;
00545     gi->walkPathFilter = NULL;
00546 
00547     gi = rpmgiLink(gi, "rpmgiNew");
00548 
00549     return gi;
00550 }
00551 
00552 /*@observer@*/ /*@unchecked@*/
00553 static const char * _query_hdlist_path  = "/usr/share/comps/%{_arch}/hdlist";
00554 
00555 rpmRC rpmgiNext(/*@null@*/ rpmgi gi)
00556 {
00557     char hnum[32];
00558     rpmRC rpmrc = RPMRC_NOTFOUND;
00559     int xx;
00560 
00561     if (gi == NULL)
00562         return rpmrc;
00563 
00564 if (_rpmgi_debug)
00565 fprintf(stderr, "*** rpmgiNext(%p) tag %s\n", gi, tagName(gi->tag));
00566 
00567     /* Free header from previous iteration. */
00568     gi->h = headerFree(gi->h);
00569     gi->hdrPath = _free(gi->hdrPath);
00570     hnum[0] = '\0';
00571 
00572     if (++gi->i >= 0)
00573     switch (gi->tag) {
00574     default:
00575         if (!gi->active) {
00576 nextkey:
00577             rpmrc = rpmgiLoadNextKey(gi);
00578             if (rpmrc != RPMRC_OK)
00579                 goto enditer;
00580             rpmrc = rpmgiInitFilter(gi);
00581             if (rpmrc != RPMRC_OK || gi->mi == NULL) {
00582                 gi->mi = rpmdbFreeIterator(gi->mi);     /* XXX unnecessary */
00583                 gi->i++;
00584                 goto nextkey;
00585             }
00586             rpmrc = RPMRC_NOTFOUND;     /* XXX hack */
00587             gi->active = 1;
00588         }
00589         if (gi->mi != NULL) {   /* XXX unnecessary */
00590             Header h = rpmdbNextIterator(gi->mi);
00591             if (h != NULL) {
00592                 if (!(gi->flags & RPMGI_NOHEADER))
00593                     gi->h = headerLink(h);
00594                 sprintf(hnum, "%u", rpmdbGetIteratorOffset(gi->mi));
00595                 gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL);
00596                 rpmrc = RPMRC_OK;
00597                 /* XXX header reference held by iterator, so no headerFree */
00598             }
00599         }
00600         if (rpmrc != RPMRC_OK) {
00601             gi->mi = rpmdbFreeIterator(gi->mi);
00602             goto nextkey;
00603         }
00604         break;
00605     case RPMDBI_PACKAGES:
00606         if (!gi->active) {
00607             rpmrc = rpmgiInitFilter(gi);
00608             if (rpmrc != RPMRC_OK) {
00609                 gi->mi = rpmdbFreeIterator(gi->mi);     /* XXX unnecessary */
00610                 goto enditer;
00611             }
00612             rpmrc = RPMRC_NOTFOUND;     /* XXX hack */
00613             gi->active = 1;
00614         }
00615         if (gi->mi != NULL) {   /* XXX unnecessary */
00616             Header h = rpmdbNextIterator(gi->mi);
00617             if (h != NULL) {
00618                 if (!(gi->flags & RPMGI_NOHEADER))
00619                     gi->h = headerLink(h);
00620                 sprintf(hnum, "%u", rpmdbGetIteratorOffset(gi->mi));
00621                 gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL);
00622                 rpmrc = RPMRC_OK;
00623                 /* XXX header reference held by iterator, so no headerFree */
00624             }
00625         }
00626         if (rpmrc != RPMRC_OK) {
00627             gi->mi = rpmdbFreeIterator(gi->mi);
00628             goto enditer;
00629         }
00630         break;
00631     case RPMDBI_REMOVED:
00632     case RPMDBI_ADDED:
00633     {   rpmte p;
00634         int teType = 0;
00635         const char * teTypeString = NULL;
00636 
00637         if (!gi->active) {
00638             gi->tsi = rpmtsiInit(gi->ts);
00639             gi->active = 1;
00640         }
00641         if ((p = rpmtsiNext(gi->tsi, teType)) != NULL) {
00642             Header h = rpmteHeader(p);
00643             if (h != NULL)
00644                 if (!(gi->flags & RPMGI_NOHEADER)) {
00645                     gi->h = headerLink(h);
00646                 switch(rpmteType(p)) {
00647                 case TR_ADDED:  teTypeString = "+++";   /*@switchbreak@*/break;
00648                 case TR_REMOVED: teTypeString = "---";  /*@switchbreak@*/break;
00649                 }
00650                 sprintf(hnum, "%u", (unsigned)gi->i);
00651                 gi->hdrPath = rpmExpand("%s h# ", teTypeString, hnum, NULL);
00652                 rpmrc = RPMRC_OK;
00653                 h = headerFree(h);
00654             }
00655         }
00656         if (rpmrc != RPMRC_OK) {
00657             gi->tsi = rpmtsiFree(gi->tsi);
00658             goto enditer;
00659         }
00660     }   break;
00661     case RPMDBI_HDLIST:
00662         if (!gi->active) {
00663             const char * path = rpmExpand("%{?_query_hdlist_path}", NULL);
00664             if (path == NULL || *path == '\0') {
00665                 path = _free(path);
00666                 path = rpmExpand(_query_hdlist_path, NULL);
00667             }
00668             gi->fd = rpmgiOpen(path, "rm%{?_rpmgio}");
00669             gi->active = 1;
00670             path = _free(path);
00671         }
00672         if (gi->fd != NULL) {
00673             Header h = NULL;
00674             const char item[] = "Header";
00675             const char * msg = NULL;
00676 /*@+voidabstract@*/
00677             rpmrc = rpmpkgRead(item, gi->fd, &h, &msg);
00678 /*@=voidabstract@*/
00679             if (rpmrc != RPMRC_OK) {
00680                 rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg);
00681                 h = NULL;
00682             }
00683             msg = _free(msg);
00684             if (h != NULL) {
00685                 if (!(gi->flags & RPMGI_NOHEADER))
00686                     gi->h = headerLink(h);
00687                 sprintf(hnum, "%u", (unsigned)gi->i);
00688                 gi->hdrPath = rpmExpand("hdlist h# ", hnum, NULL);
00689                 rpmrc = RPMRC_OK;
00690                 h = headerFree(h);
00691             }
00692         }
00693         if (rpmrc != RPMRC_OK) {
00694             if (gi->fd != NULL) (void) Fclose(gi->fd);
00695             gi->fd = NULL;
00696             goto enditer;
00697         }
00698         break;
00699     case RPMDBI_ARGLIST:
00700         /* XXX gi->active initialize? */
00701 if (_rpmgi_debug  < 0)
00702 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
00703         /* Read next header, lazily expanding manifests as found. */
00704         rpmrc = rpmgiLoadReadHeader(gi);
00705 
00706         if (rpmrc != RPMRC_OK)  /* XXX check this */
00707             goto enditer;
00708 
00709         gi->hdrPath = xstrdup(gi->argv[gi->i]);
00710         break;
00711     case RPMDBI_FTSWALK:
00712         if (gi->argv == NULL || gi->argv[0] == NULL)            /* HACK */
00713             goto enditer;
00714 
00715         if (!gi->active) {
00716             gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL);
00717             /* XXX NULL with open(2)/malloc(3) errno set */
00718             gi->active = 1;
00719         }
00720 
00721         /* Read next header, lazily walking file tree. */
00722         rpmrc = rpmgiWalkReadHeader(gi);
00723 
00724         if (rpmrc != RPMRC_OK) {
00725             xx = Fts_close(gi->ftsp);
00726             gi->ftsp = NULL;
00727             goto enditer;
00728         }
00729 
00730         if (gi->fts != NULL)
00731             gi->hdrPath = xstrdup(gi->fts->fts_path);
00732         break;
00733     }
00734 
00735     if ((gi->flags & RPMGI_TSADD) && gi->h != NULL) {
00736         /* XXX rpmgi hack: Save header in transaction element. */
00737         if (gi->flags & RPMGI_ERASING) {
00738             static int hdrx = 0;
00739             int dboffset = headerGetInstance(gi->h);
00740             if (dboffset <= 0)
00741                 dboffset = --hdrx;
00742             xx = rpmtsAddEraseElement(gi->ts, gi->h, dboffset);
00743         } else
00744             xx = rpmtsAddInstallElement(gi->ts, gi->h, (fnpyKey)gi->hdrPath, 2, NULL);
00745     }
00746 
00747     return rpmrc;
00748 
00749 enditer:
00750     if (gi->flags & RPMGI_TSORDER) {
00751         rpmts ts = gi->ts;
00752         rpmps ps;
00753         int i;
00754 
00755         /* Block access to indices used for depsolving. */
00756         if (!(gi->flags & RPMGI_ERASING)) {
00757             (void) rpmtsSetGoal(ts, TSM_INSTALL);
00758             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMDBI_DEPENDS);
00759             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_BASENAMES);
00760             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_PROVIDENAME);
00761         } else {
00762             (void) rpmtsSetGoal(ts, TSM_ERASE);
00763         }
00764 
00765         xx = rpmtsCheck(ts);
00766 
00767         /* Permit access to indices used for depsolving. */
00768         if (!(gi->flags & RPMGI_ERASING)) {
00769             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), +RPMTAG_PROVIDENAME);
00770             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), +RPMTAG_BASENAMES);
00771             xx = rpmdbBlockDBI(rpmtsGetRdb(ts), +RPMDBI_DEPENDS);
00772         }
00773 
00774         /* XXX query/verify will need the glop added to a buffer instead. */
00775         ps = rpmtsProblems(ts);
00776         if (rpmpsNumProblems(ps) > 0) {
00777             /* XXX rpminstall will need RPMLOG_ERR */
00778             rpmlog(RPMLOG_INFO, _("Failed dependencies:\n"));
00779             if (rpmIsVerbose())
00780                 rpmpsPrint(NULL, ps);
00781 
00782             if (ts->suggests != NULL && ts->nsuggests > 0) {
00783                 rpmlog(RPMLOG_INFO, _("    Suggested resolutions:\n"));
00784                 for (i = 0; i < ts->nsuggests; i++) {
00785                     const char * str = ts->suggests[i];
00786 
00787                     if (str == NULL)
00788                         break;
00789 
00790                     rpmlog(RPMLOG_INFO, "\t%s\n", str);
00791                 
00792                     ts->suggests[i] = NULL;
00793                     str = _free(str);
00794                 }
00795                 ts->suggests = _free(ts->suggests);
00796             }
00797 
00798         }
00799         ps = rpmpsFree(ps);
00800         ts->probs = rpmpsFree(ts->probs);       /* XXX hackery */
00801 
00802         /* XXX Display dependency loops with rpm -qvT. */
00803         if (rpmIsVerbose())
00804             (void) rpmtsSetDFlags(ts, (rpmtsDFlags(ts) | RPMDEPS_FLAG_DEPLOOPS));
00805 
00806         xx = (*gi->tsOrder) (ts);
00807 
00808         /* XXX hackery alert! */
00809         gi->tag = (!(gi->flags & RPMGI_ERASING) ? RPMDBI_ADDED : RPMDBI_REMOVED);
00810         gi->flags &= ~(RPMGI_TSADD|RPMGI_TSORDER);
00811 
00812     }
00813 
00814     gi->h = headerFree(gi->h);
00815     gi->hdrPath = _free(gi->hdrPath);
00816     gi->i = -1;
00817     gi->active = 0;
00818     return rpmrc;
00819 }
00820 
00821 rpmgiFlags rpmgiGetFlags(rpmgi gi)
00822 {
00823     return (gi != NULL ? gi->flags : RPMGI_NONE);
00824 }
00825 
00826 const char * rpmgiHdrPath(rpmgi gi)
00827 {
00828     return (gi != NULL ? gi->hdrPath : NULL);
00829 }
00830 
00831 Header rpmgiHeader(rpmgi gi)
00832 {
00833 /*@-compdef -refcounttrans -retexpose -usereleased@*/
00834     return (gi != NULL ? gi->h : NULL);
00835 /*@=compdef =refcounttrans =retexpose =usereleased@*/
00836 }
00837 
00838 rpmts rpmgiTs(rpmgi gi)
00839 {
00840 /*@-compdef -refcounttrans -retexpose -usereleased@*/
00841     return (gi != NULL ? gi->ts : NULL);
00842 /*@=compdef =refcounttrans =retexpose =usereleased@*/
00843 }
00844 
00845 rpmRC rpmgiSetArgs(rpmgi gi, ARGV_t argv, int ftsOpts, rpmgiFlags flags)
00846 {
00847     if (gi == NULL) return RPMRC_FAIL;
00848     gi->ftsOpts = ftsOpts;
00849     gi->flags = flags;
00850     return rpmgiGlobArgv(gi, argv);
00851 }
00852 
00853 /*@=modfilesys@*/

Generated on Mon Nov 29 2010 05:18:44 for rpm by  doxygen 1.7.2