lib/rpmgi.c

Go to the documentation of this file.
00001 /*@-modfilesys@*/
00005 #include "system.h"
00006 
00007 #include <rpmlib.h>
00008 #include <rpmte.h>              /* XXX rpmElementType */
00009 
00010 #define _RPMGI_INTERNAL
00011 #define _RPMTS_INTERNAL         /* XXX ts->probs et al */
00012 #include <rpmgi.h>
00013 
00014 #include <rpmdb.h>
00015 #include <rpmmacro.h>           /* XXX rpmExpand */
00016 #include "manifest.h"
00017 
00018 #include "debug.h"
00019 
00020 /*@access fnpyKey @*/
00021 /*@access rpmdbMatchIterator @*/
00022 /*@access rpmts @*/
00023 /*@access rpmps @*/
00024 
00025 /*@unchecked@*/
00026 int _rpmgi_debug = 0;
00027 
00028 /*@unchecked@*/
00029 rpmgiFlags giFlags = RPMGI_NONE;
00030 
00031 /*@unchecked@*/
00032 static int indent = 2;
00033 
00034 /*@unchecked@*/ /*@observer@*/
00035 static const char * ftsInfoStrings[] = {
00036     "UNKNOWN",
00037     "D",
00038     "DC",
00039     "DEFAULT",
00040     "DNR",
00041     "DOT",
00042     "DP",
00043     "ERR",
00044     "F",
00045     "INIT",
00046     "NS",
00047     "NSOK",
00048     "SL",
00049     "SLNONE",
00050     "W",
00051 };
00052 
00053 /*@observer@*/
00054 static const char * ftsInfoStr(int fts_info)
00055         /*@*/
00056 {
00057 
00058     if (!(fts_info >= 1 && fts_info <= 14))
00059         fts_info = 0;
00060 /*@-compmempass@*/
00061     return ftsInfoStrings[ fts_info ];
00062 /*@=compmempass@*/
00063 }
00064 
00072 /*@null@*/
00073 static FD_t rpmgiOpen(const char * path, const char * fmode)
00074         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00075         /*@modifies rpmGlobalMacroContext, h_errno, internalState @*/
00076 {
00077     const char * fn = rpmExpand(path, NULL);
00078     FD_t fd = Fopen(fn, fmode);
00079 
00080     if (fd == NULL || Ferror(fd)) {
00081         rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fn, Fstrerror(fd));
00082         if (fd != NULL) (void) Fclose(fd);
00083         fd = NULL;
00084     }
00085     fn = _free(fn);
00086 
00087     return fd;
00088 }
00089 
00096 static rpmRC rpmgiLoadManifest(rpmgi gi, const char * path)
00097         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00098         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00099 {
00100     FD_t fd = rpmgiOpen(path, "r.ufdio");
00101     rpmRC rpmrc = RPMRC_FAIL;
00102 
00103     if (fd != NULL) {
00104         rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv);
00105         (void) Fclose(fd);
00106     }
00107     return rpmrc;
00108 }
00109 
00116 /*@null@*/
00117 static Header rpmgiReadHeader(rpmgi gi, const char * path)
00118         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00119         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00120 {
00121     FD_t fd = rpmgiOpen(path, "r.ufdio");
00122     Header h = NULL;
00123 
00124     if (fd != NULL) {
00125         /* XXX what if path needs expansion? */
00126         rpmRC rpmrc = rpmReadPackageFile(gi->ts, fd, path, &h);
00127 
00128         (void) Fclose(fd);
00129 
00130         switch (rpmrc) {
00131         case RPMRC_NOTFOUND:
00132             /* XXX Read a package manifest. Restart ftswalk on success. */
00133         case RPMRC_FAIL:
00134         default:
00135             h = headerFree(h);
00136             break;
00137         case RPMRC_NOTTRUSTED:
00138         case RPMRC_NOKEY:
00139         case RPMRC_OK:
00140             break;
00141         }
00142     }
00143 
00144     return h;
00145 }
00146 
00154 /*@null@*/
00155 static rpmRC rpmgiLoadReadHeader(rpmgi gi)
00156         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00157         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00158 {
00159     rpmRC rpmrc = RPMRC_NOTFOUND;
00160     Header h = NULL;
00161 
00162     if (gi->argv != NULL && gi->argv[gi->i] != NULL)
00163     do {
00164         const char * fn;        /* XXX gi->hdrPath? */
00165 
00166         fn = gi->argv[gi->i];
00167         if (!(gi->flags & RPMGI_NOHEADER)) {
00168             h = rpmgiReadHeader(gi, fn);
00169             if (h != NULL)
00170                 rpmrc = RPMRC_OK;
00171         } else
00172             rpmrc = RPMRC_OK;
00173 
00174         if (rpmrc == RPMRC_OK || gi->flags & RPMGI_NOMANIFEST)
00175             break;
00176         if (errno == ENOENT) {
00177             break;
00178         }
00179 
00180         /* Not a header, so try for a manifest. */
00181         gi->argv[gi->i] = NULL;         /* Mark the insertion point */
00182         rpmrc = rpmgiLoadManifest(gi, fn);
00183         if (rpmrc != RPMRC_OK) {
00184             gi->argv[gi->i] = fn;       /* Manifest failed, restore fn */
00185             break;
00186         }
00187         fn = _free(fn);
00188         rpmrc = RPMRC_NOTFOUND;
00189     } while (1);
00190 
00191     if (rpmrc == RPMRC_OK && h != NULL)
00192         gi->h = headerLink(h);
00193     h = headerFree(h);
00194 
00195     return rpmrc;
00196 }
00197 
00203 /*@null@*/
00204 static rpmRC rpmgiWalkPathFilter(rpmgi gi)
00205         /*@*/
00206 {
00207     FTSENT * fts = gi->fts;
00208     rpmRC rpmrc = RPMRC_NOTFOUND;
00209     const char * s;
00210 
00211 if (_rpmgi_debug < 0)
00212 rpmMessage(RPMMESS_DEBUG, "FTS_%s\t%*s %s%s\n", ftsInfoStr(fts->fts_info),
00213                 indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
00214                 fts->fts_name,
00215         ((fts->fts_info == FTS_D || fts->fts_info == FTS_DP) ? "/" : ""));
00216 
00217     switch (fts->fts_info) {
00218     case FTS_D:         /* preorder directory */
00219         break;
00220     case FTS_DP:        /* postorder directory */
00221         break;
00222     case FTS_F:         /* regular file */
00223         /* Ignore all but *.rpm files. */
00224         s = fts->fts_name + fts->fts_namelen + 1 - sizeof(".rpm");
00225         if (strcmp(s, ".rpm"))
00226             break;
00227         rpmrc = RPMRC_OK;
00228         break;
00229     case FTS_NS:        /* stat(2) failed */
00230     case FTS_DNR:       /* unreadable directory */
00231     case FTS_ERR:       /* error; errno is set */
00232         break;
00233     case FTS_DC:        /* directory that causes cycles */
00234     case FTS_DEFAULT:   /* none of the above */
00235     case FTS_DOT:       /* dot or dot-dot */
00236     case FTS_INIT:      /* initialized only */
00237     case FTS_NSOK:      /* no stat(2) requested */
00238     case FTS_SL:        /* symbolic link */
00239     case FTS_SLNONE:    /* symbolic link without target */
00240     case FTS_W:         /* whiteout object */
00241     default:
00242         break;
00243     }
00244     return rpmrc;
00245 }
00246 
00252 /*@null@*/
00253 static rpmRC rpmgiWalkReadHeader(rpmgi gi)
00254         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00255         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00256 {
00257     rpmRC rpmrc = RPMRC_NOTFOUND;
00258 
00259     if (gi->ftsp != NULL)
00260     while ((gi->fts = Fts_read(gi->ftsp)) != NULL) {
00261         rpmrc = rpmgiWalkPathFilter(gi);
00262         if (rpmrc == RPMRC_OK)
00263             break;
00264     }
00265 
00266     if (rpmrc == RPMRC_OK) {
00267         Header h = NULL;
00268         if (!(gi->flags & RPMGI_NOHEADER)) {
00269             /* XXX rpmrc = rpmgiLoadReadHeader(gi); */
00270             if (gi->fts != NULL)        /* XXX can't happen */
00271                 h = rpmgiReadHeader(gi, gi->fts->fts_path);
00272         }
00273         if (h != NULL)
00274             gi->h = headerLink(h);
00275         h = headerFree(h);
00276     }
00277 
00278     return rpmrc;
00279 }
00280 
00287 static rpmRC rpmgiGlobArgv(rpmgi gi, /*@null@*/ ARGV_t argv)
00288         /*@globals internalState @*/
00289         /*@modifies gi, internalState @*/
00290 {
00291     const char * arg;
00292     rpmRC rpmrc = RPMRC_OK;
00293     int ac = 0;
00294     int xx;
00295 
00296     /* XXX Expand globs only if requested or for gi specific tags */
00297     if ((gi->flags & RPMGI_NOGLOB)
00298      || !(gi->tag == RPMDBI_HDLIST || gi->tag == RPMDBI_ARGLIST || gi->tag == RPMDBI_FTSWALK))
00299     {
00300         if (argv != NULL) {
00301             while (argv[ac] != NULL)
00302                 ac++;
00303 /*@-nullstate@*/ /* XXX argv is not NULL */
00304             xx = argvAppend(&gi->argv, argv);
00305 /*@=nullstate@*/
00306         }
00307         gi->argc = ac;
00308         return rpmrc;
00309     }
00310 
00311     if (argv != NULL)
00312     while ((arg = *argv++) != NULL) {
00313         char * t = rpmEscapeSpaces(arg);
00314         ARGV_t av = NULL;
00315 
00316         xx = rpmGlob(t, &ac, &av);
00317         xx = argvAppend(&gi->argv, av);
00318         gi->argc += ac;
00319         av = argvFree(av);
00320         t = _free(t);
00321         ac = 0;
00322     }
00323     return rpmrc;
00324 }
00325 
00331 static rpmRC rpmgiInitFilter(rpmgi gi)
00332         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00333         /*@modifies gi, rpmGlobalMacroContext, h_errno, internalState @*/
00334 {
00335     rpmRC rpmrc = RPMRC_OK;
00336     ARGV_t av;
00337     int res = 0;
00338 
00339     gi->mi = rpmtsInitIterator(gi->ts, gi->tag, gi->keyp, gi->keylen);
00340 
00341 if (_rpmgi_debug < 0)
00342 fprintf(stderr, "*** gi %p\tmi %p\n", gi, gi->mi);
00343 
00344     if (gi->argv != NULL)
00345     for (av = (const char **) gi->argv; *av != NULL; av++) {
00346         int tag = RPMTAG_NAME;
00347         const char * pat;
00348         char * a, * ae;
00349 
00350         pat = a = xstrdup(*av);
00351         tag = RPMTAG_NAME;
00352 
00353         /* Parse for "tag=pattern" args. */
00354 /*@-branchstate@*/
00355         if ((ae = strchr(a, '=')) != NULL) {
00356             *ae++ = '\0';
00357             tag = tagValue(a);
00358             if (tag < 0) {
00359                 rpmError(RPMERR_QUERYINFO, _("unknown tag: \"%s\"\n"), a);
00360                 res = 1;
00361             }
00362             pat = ae;
00363         }
00364 /*@=branchstate@*/
00365 
00366         if (!res) {
00367 if (_rpmgi_debug  < 0)
00368 fprintf(stderr, "\tav %p[%d]: \"%s\" -> %s ~= \"%s\"\n", gi->argv, (av - gi->argv), *av, tagName(tag), pat);
00369             res = rpmdbSetIteratorRE(gi->mi, tag, RPMMIRE_DEFAULT, pat);
00370         }
00371         a = _free(a);
00372 
00373         if (res == 0)
00374             continue;
00375 
00376         gi->mi = rpmdbFreeIterator(gi->mi);     /* XXX odd side effect? */
00377         rpmrc = RPMRC_FAIL;
00378         break;
00379     }
00380 
00381     return rpmrc;
00382 }
00383 
00384 rpmgi XrpmgiUnlink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
00385 {
00386     if (gi == NULL) return NULL;
00387 
00388 if (_rpmgi_debug && msg != NULL)
00389 fprintf(stderr, "--> gi %p -- %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
00390 
00391     gi->nrefs--;
00392     return NULL;
00393 }
00394 
00395 rpmgi XrpmgiLink(rpmgi gi, const char * msg, const char * fn, unsigned ln)
00396 {
00397     if (gi == NULL) return NULL;
00398     gi->nrefs++;
00399 
00400 if (_rpmgi_debug && msg != NULL)
00401 fprintf(stderr, "--> gi %p ++ %d %s at %s:%u\n", gi, gi->nrefs, msg, fn, ln);
00402 
00403     /*@-refcounttrans@*/ return gi; /*@=refcounttrans@*/
00404 }
00405 
00406 rpmgi rpmgiFree(rpmgi gi)
00407 {
00408     if (gi == NULL)
00409         return NULL;
00410 
00411     if (gi->nrefs > 1)
00412         return rpmgiUnlink(gi, __FUNCTION__);
00413 
00414     (void) rpmgiUnlink(gi, __FUNCTION__);
00415 
00416 /*@-usereleased@*/
00417 
00418     gi->hdrPath = _free(gi->hdrPath);
00419     gi->h = headerFree(gi->h);
00420 
00421     gi->argv = argvFree(gi->argv);
00422 
00423     if (gi->ftsp != NULL) {
00424         int xx;
00425         xx = Fts_close(gi->ftsp);
00426         gi->ftsp = NULL;
00427         gi->fts = NULL;
00428     }
00429     if (gi->fd != NULL) {
00430         (void) Fclose(gi->fd);
00431         gi->fd = NULL;
00432     }
00433     gi->tsi = rpmtsiFree(gi->tsi);
00434     gi->mi = rpmdbFreeIterator(gi->mi);
00435     gi->ts = rpmtsFree(gi->ts);
00436 
00437     memset(gi, 0, sizeof(*gi));         /* XXX trash and burn */
00438 /*@-refcounttrans@*/
00439     gi = _free(gi);
00440 /*@=refcounttrans@*/
00441 /*@=usereleased@*/
00442     return NULL;
00443 }
00444 
00445 rpmgi rpmgiNew(rpmts ts, int tag, const void * keyp, size_t keylen)
00446 {
00447     rpmgi gi = xcalloc(1, sizeof(*gi));
00448 
00449     if (gi == NULL)
00450         return NULL;
00451 
00452     gi->ts = rpmtsLink(ts, __FUNCTION__);
00453     gi->tag = tag;
00454 /*@-assignexpose@*/
00455     gi->keyp = keyp;
00456 /*@=assignexpose@*/
00457     gi->keylen = keylen;
00458 
00459     gi->flags = 0;
00460     gi->active = 0;
00461     gi->i = -1;
00462     gi->errors = 0;
00463     gi->hdrPath = NULL;
00464     gi->h = NULL;
00465 
00466     gi->tsi = NULL;
00467     gi->mi = NULL;
00468     gi->fd = NULL;
00469     gi->argv = xcalloc(1, sizeof(*gi->argv));
00470     gi->argc = 0;
00471     gi->ftsOpts = 0;
00472     gi->ftsp = NULL;
00473     gi->fts = NULL;
00474 
00475     gi = rpmgiLink(gi, __FUNCTION__);
00476 
00477     return gi;
00478 }
00479 
00480 rpmRC rpmgiNext(/*@null@*/ rpmgi gi)
00481 {
00482     char hnum[32];
00483     rpmRC rpmrc = RPMRC_NOTFOUND;
00484     int xx;
00485 
00486     if (gi == NULL)
00487         return rpmrc;
00488 
00489     /* Free header from previous iteration. */
00490     gi->h = headerFree(gi->h);
00491     gi->hdrPath = _free(gi->hdrPath);
00492     hnum[0] = '\0';
00493 
00494 /*@-branchstate@*/
00495     if (++gi->i >= 0)
00496     switch (gi->tag) {
00497     default:
00498     case RPMDBI_PACKAGES:
00499         if (!gi->active) {
00500             rpmrc = rpmgiInitFilter(gi);
00501             if (rpmrc != RPMRC_OK) {
00502                 gi->mi = rpmdbFreeIterator(gi->mi);     /* XXX unnecessary */
00503                 goto enditer;
00504             }
00505             rpmrc = RPMRC_NOTFOUND;     /* XXX hack */
00506             gi->active = 1;
00507         }
00508         if (gi->mi != NULL) {   /* XXX unnecessary */
00509             Header h = rpmdbNextIterator(gi->mi);
00510             if (h != NULL) {
00511                 if (!(gi->flags & RPMGI_NOHEADER))
00512                     gi->h = headerLink(h);
00513                 sprintf(hnum, "%u", rpmdbGetIteratorOffset(gi->mi));
00514                 gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL);
00515                 rpmrc = RPMRC_OK;
00516                 /* XXX header reference held by iterator, so no headerFree */
00517             }
00518         }
00519         if (rpmrc != RPMRC_OK) {
00520             gi->mi = rpmdbFreeIterator(gi->mi);
00521             goto enditer;
00522         }
00523         break;
00524     case RPMDBI_ADDED:
00525     {   rpmte p;
00526 
00527         if (!gi->active) {
00528             gi->tsi = rpmtsiInit(gi->ts);
00529             gi->active = 1;
00530         }
00531         if ((p = rpmtsiNext(gi->tsi, TR_ADDED)) != NULL) {
00532             Header h = rpmteHeader(p);
00533             if (h != NULL)
00534                 if (!(gi->flags & RPMGI_NOHEADER)) {
00535                     gi->h = headerLink(h);
00536                 sprintf(hnum, "%u", (unsigned)gi->i);
00537                 gi->hdrPath = rpmExpand("added h# ", hnum, NULL);
00538                 rpmrc = RPMRC_OK;
00539                 h = headerFree(h);
00540             }
00541         }
00542         if (rpmrc != RPMRC_OK) {
00543             gi->tsi = rpmtsiFree(gi->tsi);
00544             goto enditer;
00545         }
00546     }   break;
00547     case RPMDBI_HDLIST:
00548         if (!gi->active) {
00549             const char * path = "/usr/share/comps/%{_arch}/hdlist";
00550             gi->fd = rpmgiOpen(path, "r.ufdio");
00551             gi->active = 1;
00552         }
00553         if (gi->fd != NULL) {
00554             Header h = headerRead(gi->fd, HEADER_MAGIC_YES);
00555             if (h != NULL) {
00556                 if (!(gi->flags & RPMGI_NOHEADER))
00557                     gi->h = headerLink(h);
00558                 sprintf(hnum, "%u", (unsigned)gi->i);
00559                 gi->hdrPath = rpmExpand("hdlist h# ", hnum, NULL);
00560                 rpmrc = RPMRC_OK;
00561                 h = headerFree(h);
00562             }
00563         }
00564         if (rpmrc != RPMRC_OK) {
00565             if (gi->fd != NULL) (void) Fclose(gi->fd);
00566             gi->fd = NULL;
00567             goto enditer;
00568         }
00569         break;
00570     case RPMDBI_ARGLIST: 
00571         /* XXX gi->active initialize? */
00572 if (_rpmgi_debug  < 0)
00573 fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
00574 
00575         /* 
00576          * Read next header, lazily expanding manifests as found,
00577          * count + skip errors.
00578          */
00579         rpmrc = RPMRC_NOTFOUND; 
00580         while (gi->i < gi->argc) {
00581             if ((rpmrc = rpmgiLoadReadHeader(gi)) == RPMRC_OK) 
00582                 break;
00583             gi->errors++;
00584             gi->i++;
00585         }
00586 
00587         if (rpmrc != RPMRC_OK)  /* XXX check this */
00588             goto enditer;
00589 
00590         gi->hdrPath = xstrdup(gi->argv[gi->i]);
00591         break;
00592     case RPMDBI_FTSWALK:
00593         if (gi->argv == NULL)           /* HACK */
00594             goto enditer;
00595 
00596         if (!gi->active) {
00597             gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL);
00598             /* XXX NULL with open(2)/malloc(3) errno set */
00599             gi->active = 1;
00600         }
00601 
00602         /* Read next header, lazily walking file tree. */
00603         rpmrc = rpmgiWalkReadHeader(gi);
00604 
00605         if (rpmrc != RPMRC_OK) {
00606             xx = Fts_close(gi->ftsp);
00607             gi->ftsp = NULL;
00608             goto enditer;
00609         }
00610 
00611         if (gi->fts != NULL)
00612             gi->hdrPath = xstrdup(gi->fts->fts_path);
00613         break;
00614     }
00615 /*@=branchstate@*/
00616 
00617     if ((gi->flags & RPMGI_TSADD) && gi->h != NULL) {
00618         /* XXX rpmgi hack: Save header in transaction element. */
00619         xx = rpmtsAddInstallElement(gi->ts, gi->h, (fnpyKey)gi->hdrPath, 2, NULL);
00620     }
00621 
00622     return rpmrc;
00623 
00624 enditer:
00625     if (gi->flags & RPMGI_TSORDER) {
00626         rpmts ts = gi->ts;
00627         rpmps ps;
00628         int i;
00629 
00630         /* XXX installed database needs close here. */
00631         xx = rpmtsCloseDB(ts);
00632         ts->dbmode = -1;        /* XXX disable lazy opens */
00633 
00634         xx = rpmtsCheck(ts);
00635 
00636         /* XXX query/verify will need the glop added to a buffer instead. */
00637         ps = rpmtsProblems(ts);
00638         if (rpmpsNumProblems(ps) > 0) {
00639             /* XXX rpminstall will need RPMMESS_ERROR */
00640             rpmMessage(RPMMESS_VERBOSE, _("Failed dependencies:\n"));
00641             if (rpmIsVerbose())
00642                 rpmpsPrint(NULL, ps);
00643 
00644 /*@-branchstate@*/
00645             if (ts->suggests != NULL && ts->nsuggests > 0) {
00646                 rpmMessage(RPMMESS_VERBOSE, _("    Suggested resolutions:\n"));
00647                 for (i = 0; i < ts->nsuggests; i++) {
00648                     const char * str = ts->suggests[i];
00649 
00650                     if (str == NULL)
00651                         break;
00652 
00653                     rpmMessage(RPMMESS_VERBOSE, "\t%s\n", str);
00654                 
00655                     ts->suggests[i] = NULL;
00656                     str = _free(str);
00657                 }
00658                 ts->suggests = _free(ts->suggests);
00659             }
00660 /*@=branchstate@*/
00661 
00662         }
00663         ps = rpmpsFree(ps);
00664         ts->probs = rpmpsFree(ts->probs);       /* XXX hackery */
00665 
00666         xx = rpmtsOrder(ts);
00667 
00668         gi->tag = RPMDBI_ADDED;                 /* XXX hackery */
00669         gi->flags &= ~(RPMGI_TSADD|RPMGI_TSORDER);
00670 
00671     }
00672 
00673     gi->h = headerFree(gi->h);
00674     gi->hdrPath = _free(gi->hdrPath);
00675     gi->i = -1;
00676     gi->active = 0;
00677     return rpmrc;
00678 }
00679 
00680 const char * rpmgiHdrPath(rpmgi gi)
00681 {
00682     return (gi != NULL ? gi->hdrPath : NULL);
00683 }
00684 
00685 Header rpmgiHeader(rpmgi gi)
00686 {
00687 /*@-compdef -refcounttrans -retexpose -usereleased@*/
00688     return (gi != NULL ? gi->h : NULL);
00689 /*@=compdef =refcounttrans =retexpose =usereleased@*/
00690 }
00691 
00692 rpmts rpmgiTs(rpmgi gi)
00693 {
00694 /*@-compdef -refcounttrans -retexpose -usereleased@*/
00695     return (gi != NULL ? gi->ts : NULL);
00696 /*@=compdef =refcounttrans =retexpose =usereleased@*/
00697 }
00698 
00699 rpmRC rpmgiSetArgs(rpmgi gi, ARGV_t argv, int ftsOpts, rpmgiFlags flags)
00700 {
00701     gi->ftsOpts = ftsOpts;
00702     gi->flags = flags;
00703     return rpmgiGlobArgv(gi, argv);
00704 }
00705 
00706 int rpmgiNumErrors(rpmgi gi)
00707 {
00708     return (gi != NULL ? gi->errors : -1);
00709 }
00710 
00711 /*@=modfilesys@*/

Generated on Sun Jun 1 21:56:21 2008 for rpm by  doxygen 1.5.4