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