static rpmRC inst(const char *fn) { rpmRC rc = RPMRC_FAIL; rpmts ts = rpmtsCreate(); FD_t fd = Fopen(fn, "r"); Header h = NULL; int upgrade = 1; rpmRelocation relocs = NULL; rpmps ps = NULL; rpmprobFilterFlags probFilter = 0; assert(ts); (void) rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)0)); if (fd == NULL || Ferror(fd)) goto exit; (void) rpmReadPackageFile(ts, fd, fn, &h); if ((rc = rpmtsAddInstallElement(ts, h, fn, upgrade, relocs)) != 0 || (rc = rpmcliInstallCheck(ts)) != 0 || (rc = rpmcliInstallOrder(ts)) != 0 || (rc = rpmcliInstallRun(ts, ps, probFilter)) != 0) goto exit; exit: h = headerFree(h); if (fd) (void) Fclose(fd); fd = NULL; ts = rpmtsFree(ts); if (rc) fprintf(stderr, "<== %s(%s) rc %d\n", __FUNCTION__, fn, rc); return rc; }
static PyObject * rpmts_HdrFromFdno(rpmtsObject * s, PyObject *arg) { PyObject *ho = NULL; rpmfdObject *fdo = NULL; Header h; rpmRC rpmrc; if (!PyArg_Parse(arg, "O&:HdrFromFdno", rpmfdFromPyObject, &fdo)) return NULL; Py_BEGIN_ALLOW_THREADS; rpmrc = rpmReadPackageFile(s->ts, rpmfdGetFd(fdo), "rpmts_HdrFromFdno", &h); Py_END_ALLOW_THREADS; Py_XDECREF(fdo); if (rpmrc == RPMRC_OK) { ho = hdr_Wrap(&hdr_Type, h); h = headerFree(h); /* ref held by python object */ } else { Py_INCREF(Py_None); ho = Py_None; } return Py_BuildValue("(iN)", rpmrc, ho); }
void _rpm2header(rpmts ts, char * filename, int checkmode) { FD_t fd; Header ret = NULL; rpmRC rc; dSP; if ((fd = Fopen(filename, "r"))) { rc = rpmReadPackageFile(ts, fd, filename, &ret); if (checkmode) { XPUSHs(sv_2mortal(newSViv(rc))); (void)headerFree(ret); /* For checking the package, we don't keep the header */ ret = NULL; } else { if (rc == 0) { XPUSHs(sv_2mortal(sv_setref_pv(newSVpv("", 0), "RPM::Header", (void *)ret))); } else { XPUSHs(sv_2mortal(&PL_sv_undef)); } } Fclose(fd); } else { XPUSHs(sv_2mortal(&PL_sv_undef)); } PUTBACK; return; }
int add_for_install(rpmts ts, char *file, int upgrade) { FD_t fd; Header hdr; int rc = 0; /* Read package header */ fd = Fopen(file, "r.ufdio"); if (fd == NULL) { printf("Unable to open file %s\n", file); return 1; } rc = rpmReadPackageFile(ts, fd, file, &hdr); if (rc != RPMRC_OK) { printf("Unable to read package %s\n", file); return rc; } /* Add it to the transaction set */ rc = rpmtsAddInstallElement(ts, hdr, file, upgrade, 0); if (rc) { printf("Error adding %s to transaction\n", file); goto out; } out: headerFree(hdr); Fclose(fd); return rc; }
static int tryReadHeader(rpmts ts, struct rpmEIU * eiu, Header * hdrp) { /* Try to read the header from a package file. */ FD_t fd = Fopen(*eiu->fnp, "r.ufdio"); if (fd == NULL || Ferror(fd)) { rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, Fstrerror(fd)); if (fd != NULL) { Fclose(fd); fd = NULL; } eiu->numFailed++; *eiu->fnp = NULL; return RPMRC_FAIL; } /* Read the header, verifying signatures (if present). */ eiu->rpmrc = rpmReadPackageFile(ts, fd, *eiu->fnp, hdrp); Fclose(fd); fd = NULL; /* Honor --nomanifest */ if (eiu->rpmrc == RPMRC_NOTFOUND && (giFlags & RPMGI_NOMANIFEST)) eiu->rpmrc = RPMRC_FAIL; if (eiu->rpmrc == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); eiu->numFailed++; *eiu->fnp = NULL; } return RPMRC_OK; }
Header rpmgiReadHeader(rpmgi gi, const char * path) { FD_t fd = rpmgiOpen(path, "r%{?_rpmgio}"); Header h = NULL; if (fd != NULL) { /* XXX what if path needs expansion? */ rpmRC rpmrc = rpmReadPackageFile(gi->ts, fd, path, &h); (void) Fclose(fd); switch (rpmrc) { case RPMRC_NOTFOUND: /* XXX Read a package manifest. Restart ftswalk on success. */ case RPMRC_FAIL: default: (void)headerFree(h); h = NULL; gi->rc = rpmrc; break; case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; } } else { gi->rc = RPMRC_NOTFOUND; /* XXX other failures? */ } return h; }
rpmRC rpmReadPackageInfo(FD_t fd, Header * sigp, Header * hdrp) { rpmRC rc; rpmts ts = rpmtsCreate(); rc = rpmReadPackageFile(ts, fd, "readRPM", hdrp); ts = rpmtsFree(ts); if (sigp) *sigp = NULL; /* XXX HACK */ return rc; }
string_list * rpm_file_list(const char * pkg) { rpmReadConfigFiles(NULL, NULL); FD_t fd = Fopen(pkg, "r.ufdio"); rpmts ts = rpmtsCreate(); Header h; rpmReadPackageFile(ts, fd, NULL, &h); rpmtsFree(ts); string_list * sl = string_list_new(); rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); if (fi) { while (rpmfiNext(fi) != -1) { string_list_append(sl, rpmfiFN(fi)); } fi = rpmfiFree(fi); } return sl; }
int ssds_add_to_transaction(rpmts ts, char *pkg, int action) { FD_t fd; Header hdr; int rc = 0; /* Read package header */ fd = Fopen(pkg, "r.ufdio"); if (fd == NULL) { ssds_log(logERROR, "Unable to open file %s.\n", pkg); return 1; } ssds_log(logDEBUG, "File %s is opened.\n", pkg); rc = rpmReadPackageFile(ts, fd, pkg, &hdr); if (rc != RPMRC_OK) { ssds_log(logERROR,"Unable to read package %s.\n", pkg); return rc; } ssds_log(logDEBUG, "Package is ok.\n"); /* Add it to the transaction set */ rc = rpmtsAddInstallElement(ts, hdr, (fnpyKey) pkg, action, 0); if (rc) { ssds_log(logERROR ,"Error adding %s to transaction.\n", pkg); } ssds_log(logDEBUG, "Package added to transaction with code %d.\n", rc); headerFree(hdr); Fclose(fd); return rc; }
rpmRC readRPM(const char *fileName, rpmSpec *specp, Header *sigs, CSA_t csa) { FD_t fdi; rpmSpec spec; rpmRC rc; fdi = (fileName != NULL) ? Fopen(fileName, "r.ufdio") : fdDup(STDIN_FILENO); if (fdi == NULL || Ferror(fdi)) { rpmlog(RPMLOG_ERR, _("readRPM: open %s: %s\n"), (fileName ? fileName : "<stdin>"), Fstrerror(fdi)); if (fdi) (void) Fclose(fdi); return RPMRC_FAIL; } /* XXX FIXME: EPIPE on <stdin> */ if (Fseek(fdi, 0, SEEK_SET) == -1) { rpmlog(RPMLOG_ERR, _("%s: Fseek failed: %s\n"), (fileName ? fileName : "<stdin>"), Fstrerror(fdi)); return RPMRC_FAIL; } /* Reallocate build data structures */ spec = newSpec(); spec->packages = newPackage(spec); /* XXX the header just allocated will be allocated again */ spec->packages->header = headerFree(spec->packages->header); /* Read the rpm lead, signatures, and header */ { rpmts ts = rpmtsCreate(); /* XXX W2DO? pass fileName? */ /* LCL: segfault */ rc = rpmReadPackageFile(ts, fdi, "readRPM", &spec->packages->header); ts = rpmtsFree(ts); if (sigs) *sigs = NULL; /* XXX HACK */ } switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: rpmlog(RPMLOG_ERR, _("readRPM: %s is not an RPM package\n"), (fileName ? fileName : "<stdin>")); return RPMRC_FAIL; case RPMRC_FAIL: default: rpmlog(RPMLOG_ERR, _("readRPM: reading header from %s\n"), (fileName ? fileName : "<stdin>")); return RPMRC_FAIL; break; } if (specp) *specp = spec; else spec = freeSpec(spec); if (csa != NULL) csa->cpioFdIn = fdi; else (void) Fclose(fdi); return RPMRC_OK; }
uint32_t VerifyRpmSig( rpmKeyring pKeyring, const char* pszPkgFile ) { uint32_t dwError = 0; FD_t pFD_t = NULL; rpmts pTS = NULL; rpmtd pTD = NULL; Header pPkgHeader = NULL; pgpDig pDigest = NULL; if(!pKeyring || IsNullOrEmptyString(pszPkgFile)) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pFD_t = Fopen(pszPkgFile, "r.fdio"); if(!pFD_t) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } pTS = rpmtsCreate(); if(!pTS) { dwError = ERROR_TDNF_RPMTS_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } rpmtsSetVSFlags (pTS, _RPMVSF_NOSIGNATURES); pTD = rpmtdNew(); if(!pTD) { dwError = ERROR_TDNF_RPMTD_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } dwError = rpmReadPackageFile(pTS, pFD_t, pszPkgFile, &pPkgHeader); BAIL_ON_TDNF_RPM_ERROR(dwError); if(!headerConvert(pPkgHeader, HEADERCONV_RETROFIT_V3)) { dwError = ERROR_TDNF_RPM_HEADER_CONVERT_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } if(!headerGet(pPkgHeader, RPMTAG_RSAHEADER, pTD, HEADERGET_MINMEM)) { dwError = ERROR_TDNF_RPM_GET_RSAHEADER_FAILED; BAIL_ON_TDNF_ERROR(dwError); } pDigest = pgpNewDig(); if(pgpPrtPkts(pTD->data, pTD->count, pDigest, 0)) { dwError = ERROR_TDNF_RPM_GPG_PARSE_FAILED; BAIL_ON_TDNF_ERROR(dwError); } if(rpmKeyringLookup(pKeyring, pDigest) != RPMRC_OK) { dwError = ERROR_TDNF_RPM_GPG_NO_MATCH; BAIL_ON_TDNF_ERROR(dwError); } cleanup: if(pFD_t) { Fclose(pFD_t); } if(pDigest) { pgpFreeDig(pDigest); } if(pPkgHeader) { headerFree(pPkgHeader); } if(pTD) { rpmtdFree(pTD); } if(pTS) { rpmtsFree(pTS); } return dwError; error: goto cleanup; }
static int process_package(rpmts ts, char * filename) { FD_t fdi; FD_t gzdi; Header h; int rc = 0; char * rpmio_flags = NULL; struct archive *a; struct archive_entry *entry; if (!strcmp(filename, "-")) { fdi = fdDup(STDIN_FILENO); } else { fdi = Fopen(filename, "r.ufdio"); } if (Ferror(fdi)) { fprintf(stderr, "rpm2archive: %s: %s\n", filename, Fstrerror(fdi)); exit(EXIT_FAILURE); } rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: fprintf(stderr, _("argument is not an RPM package\n")); exit(EXIT_FAILURE); break; case RPMRC_FAIL: default: fprintf(stderr, _("error reading header from package\n")); exit(EXIT_FAILURE); break; } /* Retrieve payload size and compression type. */ { const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL); } gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */ free(rpmio_flags); if (gzdi == NULL) { fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi)); exit(EXIT_FAILURE); } rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER); rpmfi fi = rpmfiNewArchiveReader(gzdi, files, RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST); /* create archive */ a = archive_write_new(); archive_write_add_filter_gzip(a); archive_write_set_format_pax_restricted(a); if (!strcmp(filename, "-")) { if (isatty(STDOUT_FILENO)) { fprintf(stderr, "Error: refusing to output archive data to a terminal.\n"); exit(EXIT_FAILURE); } archive_write_open_fd(a, STDOUT_FILENO); } else { char * outname = rstrscat(NULL, filename, ".tgz", NULL); archive_write_open_filename(a, outname); _free(outname); // XXX error handling } entry = archive_entry_new(); char * buf = xmalloc(BUFSIZE); char * hardlink = NULL; rc = 0; while (rc >= 0) { rc = rpmfiNext(fi); if (rc == RPMERR_ITER_END) { break; } rpm_mode_t mode = rpmfiFMode(fi); int nlink = rpmfiFNlink(fi); fill_archive_entry(a, entry, fi); if (nlink > 1) { if (rpmfiArchiveHasContent(fi)) { _free(hardlink); hardlink = rstrscat(NULL, ".", rpmfiFN(fi), NULL); } else { archive_entry_set_hardlink(entry, hardlink); } } archive_write_header(a, entry); if (S_ISREG(mode) && (nlink == 1 || rpmfiArchiveHasContent(fi))) { write_file_content(a, buf, fi); } } /* End of iteration is not an error */ if (rc == RPMERR_ITER_END) { rc = 0; } _free(hardlink); Fclose(gzdi); /* XXX gzdi == fdi */ archive_entry_free(entry); archive_write_close(a); archive_write_free(a); buf = _free(buf); rpmfilesFree(files); rpmfiFree(fi); headerFree(h); return rc; }
/** @todo Generalize --freshen policies. */ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) { struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu)); rpmps ps; rpmprobFilterFlags probFilter; rpmRelocation * relocations; char * fileURL = NULL; int stopInstall = 0; rpmVSFlags vsflags, ovsflags, tvsflags; int rc; int xx; int i; if (fileArgv == NULL) goto exit; rpmcliPackagesTotal = 0; (void) rpmtsSetFlags(ts, ia->transFlags); probFilter = ia->probFilter; relocations = ia->relocations; if (ia->installInterfaceFlags & INSTALL_UPGRADE) vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); else vsflags = rpmExpandNumeric("%{?_vsflags_install}"); if (ia->qva_flags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (ia->qva_flags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (ia->qva_flags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); { int notifyFlags; notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); xx = rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)notifyFlags)); } if ((eiu->relocations = relocations) != NULL) { while (eiu->relocations->oldPath) eiu->relocations++; if (eiu->relocations->newPath == NULL) eiu->relocations = NULL; } /* Build fully globbed list of arguments in argv[argc]. */ for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) { ARGV_t av = NULL; int ac = 0; char * fn; fn = rpmEscapeSpaces(*eiu->fnp); rc = rpmGlob(fn, &ac, &av); fn = _free(fn); if (rc || ac == 0) { rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp); eiu->numFailed++; continue; } argvAppend(&(eiu->argv), av); argvFree(av); eiu->argc += ac; } restart: /* Allocate sufficient storage for next set of args. */ if (eiu->pkgx >= eiu->numPkgs) { eiu->numPkgs = eiu->pkgx + eiu->argc; eiu->pkgURL = xrealloc(eiu->pkgURL, (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL)); memset(eiu->pkgURL + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgURL))); eiu->pkgState = xrealloc(eiu->pkgState, (eiu->numPkgs + 1) * sizeof(*eiu->pkgState)); memset(eiu->pkgState + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgState))); } /* Retrieve next set of args, cache on local storage. */ for (i = 0; i < eiu->argc; i++) { fileURL = _free(fileURL); fileURL = eiu->argv[i]; eiu->argv[i] = NULL; switch (urlIsURL(fileURL)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: { char *tfn; FD_t tfd; if (rpmIsVerbose()) fprintf(stdout, _("Retrieving %s\n"), fileURL); tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn); if (tfd && tfn) { Fclose(tfd); rc = urlGetFile(fileURL, tfn); } else { rc = -1; } if (rc != 0) { rpmlog(RPMLOG_ERR, _("skipping %s - transfer failed\n"), fileURL); eiu->numFailed++; eiu->pkgURL[eiu->pkgx] = NULL; tfn = _free(tfn); break; } eiu->pkgState[eiu->pkgx] = 1; eiu->pkgURL[eiu->pkgx] = tfn; eiu->pkgx++; } break; case URL_IS_PATH: case URL_IS_DASH: /* WRONG WRONG WRONG */ case URL_IS_HKP: /* WRONG WRONG WRONG */ default: eiu->pkgURL[eiu->pkgx] = fileURL; fileURL = NULL; eiu->pkgx++; break; } } fileURL = _free(fileURL); if (eiu->numFailed) goto exit; /* Continue processing file arguments, building transaction set. */ for (eiu->fnp = eiu->pkgURL+eiu->prevx; *eiu->fnp != NULL; eiu->fnp++, eiu->prevx++) { const char * fileName; rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp); (void) urlPath(*eiu->fnp, &fileName); /* Try to read the header from a package file. */ eiu->fd = Fopen(*eiu->fnp, "r.ufdio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } eiu->numFailed++; *eiu->fnp = NULL; continue; } /* Read the header, verifying signatures (if present). */ tvsflags = rpmtsSetVSFlags(ts, vsflags); eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h); tvsflags = rpmtsSetVSFlags(ts, tvsflags); xx = Fclose(eiu->fd); eiu->fd = NULL; switch (eiu->rpmrc) { case RPMRC_FAIL: rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); eiu->numFailed++; *eiu->fnp = NULL; continue; break; case RPMRC_NOTFOUND: goto maybe_manifest; break; case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: default: break; } eiu->isSource = headerIsSource(eiu->h); if (eiu->isSource) { rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", eiu->numSRPMS); eiu->sourceURL = xrealloc(eiu->sourceURL, (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL)); eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp; *eiu->fnp = NULL; eiu->numSRPMS++; eiu->sourceURL[eiu->numSRPMS] = NULL; continue; } if (eiu->relocations) { struct rpmtd_s prefixes; headerGet(eiu->h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT); if (rpmtdCount(&prefixes) == 1) { eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes)); rpmtdFreeData(&prefixes); } else { const char * name; xx = headerNVR(eiu->h, &name, NULL, NULL); rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"), name); eiu->numFailed++; goto exit; } } /* On --freshen, verify package is installed and newer */ if (ia->installInterfaceFlags & INSTALL_FRESHEN) { rpmdbMatchIterator mi; const char * name; Header oldH; int count; xx = headerNVR(eiu->h, &name, NULL, NULL); mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0); count = rpmdbGetIteratorCount(mi); while ((oldH = rpmdbNextIterator(mi)) != NULL) { if (rpmVersionCompare(oldH, eiu->h) < 0) continue; /* same or newer package already installed */ count = 0; break; } mi = rpmdbFreeIterator(mi); if (count == 0) { eiu->h = headerFree(eiu->h); continue; } /* Package is newer than those currently installed. */ } rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName, (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, relocations); /* XXX reference held by transaction set */ eiu->h = headerFree(eiu->h); if (eiu->relocations) eiu->relocations->oldPath = _free(eiu->relocations->oldPath); switch(rc) { case 0: rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n", eiu->numRPMS); break; case 1: rpmlog(RPMLOG_ERR, _("error reading from file %s\n"), *eiu->fnp); eiu->numFailed++; goto exit; break; case 2: rpmlog(RPMLOG_ERR, _("file %s requires a newer version of RPM\n"), *eiu->fnp); eiu->numFailed++; goto exit; break; default: eiu->numFailed++; goto exit; break; } eiu->numRPMS++; continue; maybe_manifest: /* Try to read a package manifest. */ eiu->fd = Fopen(*eiu->fnp, "r.fpio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } eiu->numFailed++; *eiu->fnp = NULL; break; } /* Read list of packages from manifest. */ /* FIX: *eiu->argv can be NULL */ rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv); if (rc != RPMRC_OK) rpmlog(RPMLOG_ERR, _("%s: not an rpm package (or package manifest): %s\n"), *eiu->fnp, Fstrerror(eiu->fd)); xx = Fclose(eiu->fd); eiu->fd = NULL; /* If successful, restart the query loop. */ if (rc == RPMRC_OK) { eiu->prevx++; goto restart; } eiu->numFailed++; *eiu->fnp = NULL; break; } rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n", eiu->numSRPMS, eiu->numRPMS); if (eiu->numFailed) goto exit; if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) { if (rpmtsCheck(ts)) { eiu->numFailed = eiu->numPkgs; stopInstall = 1; } ps = rpmtsProblems(ts); if (!stopInstall && rpmpsNumProblems(ps) > 0) { rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); rpmpsPrint(NULL, ps); eiu->numFailed = eiu->numPkgs; stopInstall = 1; } ps = rpmpsFree(ps); } if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { if (rpmtsOrder(ts)) { eiu->numFailed = eiu->numPkgs; stopInstall = 1; } } if (eiu->numRPMS && !stopInstall) { rpmcliPackagesTotal += eiu->numSRPMS; rpmlog(RPMLOG_DEBUG, "installing binary packages\n"); /* Drop added/available package indices and dependency sets. */ rpmtsClean(ts); rc = rpmtsRun(ts, NULL, probFilter); ps = rpmtsProblems(ts); if (rc < 0) { eiu->numFailed += eiu->numRPMS; } else if (rc > 0) { eiu->numFailed += rc; if (rpmpsNumProblems(ps) > 0) rpmpsPrint(stderr, ps); } ps = rpmpsFree(ps); } if (eiu->numSRPMS && !stopInstall) { if (eiu->sourceURL != NULL) for (i = 0; i < eiu->numSRPMS; i++) { rpmdbCheckSignals(); if (eiu->sourceURL[i] == NULL) continue; eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio"); if (eiu->fd == NULL || Ferror(eiu->fd)) { rpmlog(RPMLOG_ERR, _("cannot open file %s: %s\n"), eiu->sourceURL[i], Fstrerror(eiu->fd)); if (eiu->fd != NULL) { xx = Fclose(eiu->fd); eiu->fd = NULL; } continue; } if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL); if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++; } xx = Fclose(eiu->fd); eiu->fd = NULL; } } exit: if (eiu->pkgURL != NULL) for (i = 0; i < eiu->numPkgs; i++) { if (eiu->pkgURL[i] == NULL) continue; if (eiu->pkgState[i] == 1) (void) unlink(eiu->pkgURL[i]); eiu->pkgURL[i] = _free(eiu->pkgURL[i]); } eiu->pkgState = _free(eiu->pkgState); eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); rc = eiu->numFailed; free(eiu); rpmtsEmpty(ts); return rc; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; specix = headerFindSpec(h); if (specix < 0) { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int fc = rpmfsFC(fs); for (int i = 0; i < fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te, PKG_INSTALL); if (rpmpsmUnpack(psm) == RPMRC_OK) rpmrc = RPMRC_OK; rpmpsmFree(psm); exit: if (rpmrc == RPMRC_OK && specix >= 0) { if (cookie) *cookie = headerGetAsString(h, RPMTAG_COOKIE); if (specFilePtr) { rpmfiles files = rpmteFiles(te); *specFilePtr = rpmfilesFN(files, specix); rpmfilesFree(files); } } /* XXX nuke the added package(s). */ headerFree(h); rpmtsEmpty(ts); return rpmrc; }
/* * explode source RPM into the current directory * use filters to skip packages and files we do not need */ int explodeRPM(const char *source, filterfunc filter, dependencyfunc provides, dependencyfunc deps, void* userptr) { char buffer[BUFFERSIZE+1]; /* make space for trailing \0 */ FD_t fdi; Header h; char * rpmio_flags = NULL; rpmRC rc; FD_t gzdi; struct archive *cpio; struct archive_entry *cpio_entry; struct cpio_mydata cpio_mydata; rpmts ts; rpmVSFlags vsflags; const char *compr; if (strcmp(source, "-") == 0) fdi = fdDup(STDIN_FILENO); else fdi = Fopen(source, "r.ufdio"); if (Ferror(fdi)) { const char *srcname = (strcmp(source, "-") == 0) ? "<stdin>" : source; logMessage(ERROR, "%s: %s\n", srcname, Fstrerror(fdi)); return EXIT_FAILURE; } rpmReadConfigFiles(NULL, NULL); /* Initialize RPM transaction */ ts = rpmtsCreate(); vsflags = 0; /* Do not check digests, signatures or headers */ vsflags |= _RPMVSF_NODIGESTS; vsflags |= _RPMVSF_NOSIGNATURES; vsflags |= RPMVSF_NOHDRCHK; (void) rpmtsSetVSFlags(ts, vsflags); rc = rpmReadPackageFile(ts, fdi, "rpm2dir", &h); ts = rpmtsFree(ts); switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: logMessage(ERROR, "%s is not an RPM package", source); return EXIT_FAILURE; break; case RPMRC_FAIL: default: logMessage(ERROR, "error reading header from %s package\n", source); return EXIT_FAILURE; break; } /* Retrieve all dependencies and run them through deps function */ while (deps) { struct rpmtd_s td; const char *depname; if (!headerGet(h, RPMTAG_REQUIRENAME, &td, HEADERGET_MINMEM)) break; /* iterator */ while ((depname = rpmtdNextString(&td))) { if (deps(depname, userptr)) { Fclose(fdi); return EXIT_BADDEPS; } } rpmtdFreeData(&td); break; } /* Retrieve all provides and run them through provides function */ while (provides) { struct rpmtd_s td; const char *depname; int found = 0; if (!headerGet(h, RPMTAG_PROVIDES, &td, HEADERGET_MINMEM)) break; /* iterator */ while ((depname = rpmtdNextString(&td))) { if (!provides(depname, userptr)) { found++; } } rpmtdFreeData(&td); if (found<=0) return EXIT_BADDEPS; break; } /* Retrieve type of payload compression. */ compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); if (compr && strcmp(compr, "gzip")) { checked_asprintf(&rpmio_flags, "r.%sdio", compr); } else { checked_asprintf(&rpmio_flags, "r.gzdio"); } /* Open uncompressed cpio stream */ gzdi = Fdopen(fdi, rpmio_flags); free(rpmio_flags); if (gzdi == NULL) { logMessage(ERROR, "cannot re-open payload: %s\n", Fstrerror(gzdi)); return EXIT_FAILURE; } /* initialize cpio decompressor */ cpio = archive_read_new(); if (cpio==NULL) { Fclose(gzdi); return -1; } cpio_mydata.gzdi = gzdi; cpio_mydata.buffer = buffer; archive_read_support_compression_all(cpio); archive_read_support_format_all(cpio); rc = archive_read_open(cpio, &cpio_mydata, NULL, rpm_myread, rpm_myclose); /* check the status of archive_open */ if (rc != ARCHIVE_OK){ Fclose(gzdi); return -1; } /* read all files in cpio archive */ while ((rc = archive_read_next_header(cpio, &cpio_entry)) == ARCHIVE_OK){ const struct stat *fstat; int64_t fsize; const char* filename; int needskip = 1; /* do we need to read the data to get to the next header? */ int offset = 0; int towrite = 0; filename = archive_entry_pathname(cpio_entry); fstat = archive_entry_stat(cpio_entry); fsize = archive_entry_size(cpio_entry); /* Strip leading slashes */ while (filename[offset] == '/') offset+=1; /* Strip leading ./ */ while (filename[offset] == '.' && filename[offset+1] == '/') offset+=2; /* Other file type - we do not care except special cases */ if (!S_ISREG(fstat->st_mode)) towrite = 1; else towrite = 2; if (filter && filter(filename+offset, fstat, userptr)) { /* filter this file */ towrite = 0; } /* Create directories */ char* dirname = strdup(filename+offset); /* If the dup fails, let's hope the dirs already exist */ if (dirname){ char* dirptr = dirname; while (dirptr && *dirptr) { dirptr = strchr(dirptr, '/'); if (dirptr) { *dirptr = 0; mkdir(dirname, 0700); *dirptr = '/'; dirptr++; } } free(dirname); } /* Regular file */ if (towrite>=2) { FILE *fdout = fopen(filename+offset, "w"); if (fdout==NULL){ rc = 33; break; } rc = archive_read_data_into_fd(cpio, fileno(fdout)); if (rc!=ARCHIVE_OK) { /* XXX We didn't get the file.. well.. */ needskip = 0; } else { needskip = 0; fclose(fdout); } } /* symlink, we assume that the path contained in symlink * is shorter than BUFFERSIZE */ while (towrite && S_ISLNK(fstat->st_mode)) { char symlinkbuffer[BUFFERSIZE-1]; needskip = 0; if ((rc = archive_read_data(cpio, symlinkbuffer, fsize))!=ARCHIVE_OK) { /* XXX We didn't get the file.. well.. */ break; } if (symlink(buffer, filename+offset)) { logMessage(ERROR, "Failed to create symlink %s -> %s", filename+offset, buffer); } break; } if(needskip) archive_read_data_skip(cpio); } archive_read_finish(cpio); return rc != ARCHIVE_OK; }
int main(int argc, char *argv[]) { FD_t fdi, fdo; Header h; char * rpmio_flags; rpmRC rc; FD_t gzdi; setprogname(argv[0]); /* Retrofit glibc __progname */ if (argc == 1) fdi = fdDup(STDIN_FILENO); else fdi = Fopen(argv[1], "r.ufdio"); if (Ferror(fdi)) { fprintf(stderr, "%s: %s: %s\n", argv[0], (argc == 1 ? "<stdin>" : argv[1]), Fstrerror(fdi)); exit(EXIT_FAILURE); } fdo = fdDup(STDOUT_FILENO); rpmReadConfigFiles(NULL, NULL); { rpmts ts = rpmtsCreate(); rpmVSFlags vsflags = 0; /* XXX retain the ageless behavior of rpm2cpio */ vsflags |= _RPMVSF_NODIGESTS; vsflags |= _RPMVSF_NOSIGNATURES; vsflags |= RPMVSF_NOHDRCHK; (void) rpmtsSetVSFlags(ts, vsflags); /* LCL: segfault */ rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); ts = rpmtsFree(ts); } switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: fprintf(stderr, _("argument is not an RPM package\n")); exit(EXIT_FAILURE); break; case RPMRC_FAIL: default: fprintf(stderr, _("error reading header from package\n")); exit(EXIT_FAILURE); break; } /* Retrieve type of payload compression. */ { const char * payload_compressor = NULL; struct rpmtd_s pc; headerGet(h, RPMTAG_PAYLOADCOMPRESSOR, &pc, HEADERGET_DEFAULT); payload_compressor = rpmtdGetString(&pc); if (!payload_compressor) payload_compressor = "gzip"; if (!strcmp(payload_compressor, "gzip")) rpmio_flags = "r.gzdio"; if (!strcmp(payload_compressor, "bzip2")) rpmio_flags = "r.bzdio"; if (!strcmp(payload_compressor, "lzma")) rpmio_flags = "r.lzdio"; rpmtdFreeData(&pc); } gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */ if (gzdi == NULL) { fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi)); exit(EXIT_FAILURE); } rc = ufdCopy(gzdi, fdo); rc = (rc <= 0) ? EXIT_FAILURE : EXIT_SUCCESS; Fclose(fdo); Fclose(gzdi); /* XXX gzdi == fdi */ return rc; }
int main(int argc, char *argv[]) { FD_t fdi, fdo; Header h; char * rpmio_flags = NULL; rpmRC rc; FD_t gzdi; setprogname(argv[0]); /* Retrofit glibc __progname */ rpmReadConfigFiles(NULL, NULL); if (argc == 1) fdi = fdDup(STDIN_FILENO); else { if (rstreq(argv[1], "-h") || rstreq(argv[1], "--help")) { fprintf(stderr, "Usage: rpm2cpio file.rpm\n"); exit(EXIT_FAILURE); } fdi = Fopen(argv[1], "r.ufdio"); } if (Ferror(fdi)) { fprintf(stderr, "%s: %s: %s\n", argv[0], (argc == 1 ? "<stdin>" : argv[1]), Fstrerror(fdi)); exit(EXIT_FAILURE); } fdo = fdDup(STDOUT_FILENO); { rpmts ts = rpmtsCreate(); rpmVSFlags vsflags = 0; /* XXX retain the ageless behavior of rpm2cpio */ vsflags |= _RPMVSF_NODIGESTS; vsflags |= _RPMVSF_NOSIGNATURES; vsflags |= RPMVSF_NOHDRCHK; (void) rpmtsSetVSFlags(ts, vsflags); rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); ts = rpmtsFree(ts); } switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: fprintf(stderr, _("argument is not an RPM package\n")); exit(EXIT_FAILURE); break; case RPMRC_FAIL: default: fprintf(stderr, _("error reading header from package\n")); exit(EXIT_FAILURE); break; } /* Retrieve type of payload compression. */ { const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL); } gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */ free(rpmio_flags); if (gzdi == NULL) { fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi)); exit(EXIT_FAILURE); } rc = ufdCopy(gzdi, fdo); rc = (rc <= 0) ? EXIT_FAILURE : EXIT_SUCCESS; Fclose(fdo); Fclose(gzdi); /* XXX gzdi == fdi */ return rc; }
/** * dnf_keyring_check_untrusted_file: */ gboolean dnf_keyring_check_untrusted_file(rpmKeyring keyring, const gchar *filename, GError **error) { FD_t fd = NULL; gboolean ret = FALSE; Header hdr = NULL; pgpDig dig = NULL; rpmRC rc; rpmtd td = NULL; rpmts ts = NULL; /* open the file for reading */ fd = Fopen(filename, "r.fdio"); if (fd == NULL) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to open %s", filename); goto out; } if (Ferror(fd)) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to open %s: %s", filename, Fstrerror(fd)); goto out; } /* we don't want to abort on missing keys */ ts = rpmtsCreate(); rpmtsSetVSFlags(ts, _RPMVSF_NOSIGNATURES); /* read in the file */ rc = rpmReadPackageFile(ts, fd, filename, &hdr); if (rc != RPMRC_OK) { /* we only return SHA1 and MD5 failures, as we're not * checking signatures at this stage */ g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "%s could not be verified", filename); goto out; } /* convert and upscale */ headerConvert(hdr, HEADERCONV_RETROFIT_V3); /* get RSA key */ td = rpmtdNew(); rc = headerGet(hdr, RPMTAG_RSAHEADER, td, HEADERGET_MINMEM); if (rc != 1) { /* try to read DSA key as a fallback */ rc = headerGet(hdr, RPMTAG_DSAHEADER, td, HEADERGET_MINMEM); } /* the package has no signing key */ if (rc != 1) { g_autofree char *package_filename = g_path_get_basename(filename); ret = FALSE; g_set_error(error, DNF_ERROR, DNF_ERROR_GPG_SIGNATURE_INVALID, "package not signed: %s", package_filename); goto out; } /* make it into a digest */ dig = pgpNewDig(); rc = pgpPrtPkts(td->data, td->count, dig, 0); if (rc != 0) { g_set_error(error, DNF_ERROR, DNF_ERROR_FILE_INVALID, "failed to parse digest header for %s", filename); goto out; } /* does the key exist in the keyring */ rc = rpmKeyringLookup(keyring, dig); if (rc != RPMRC_OK) { g_set_error(error, DNF_ERROR, DNF_ERROR_GPG_SIGNATURE_INVALID, "failed to lookup digest in keyring for %s", filename); goto out; } /* the package is signed by a key we trust */ g_debug("%s has been verified as trusted", filename); ret = TRUE; out: if (dig != NULL) pgpFreeDig(dig); if (td != NULL) { rpmtdFreeData(td); rpmtdFree(td); } if (ts != NULL) rpmtsFree(ts); if (hdr != NULL) headerFree(hdr); if (fd != NULL) Fclose(fd); return ret; }
uint32_t TDNFTransAddInstallPkg( PTDNFRPMTS pTS, PTDNF pTdnf, HyPackage hPkg, int nUpgrade ) { uint32_t dwError = 0; int nGPGCheck = 0; char* pszRpmCacheDir = NULL; char* pszFilePath = NULL; const char* pszRepoName = NULL; char* pszHyName = NULL; Header rpmHeader = NULL; FD_t fp = NULL; char* pszDownloadCacheDir = NULL; char* pszUrlGPGKey = NULL; pszRepoName = hy_package_get_reponame(hPkg); pszHyName = hy_package_get_location(hPkg); pszRpmCacheDir = g_build_filename( G_DIR_SEPARATOR_S, pTdnf->pConf->pszCacheDir, pszRepoName, "rpms", G_DIR_SEPARATOR_S, NULL); pszFilePath = g_build_filename(pszRpmCacheDir, pszHyName, NULL); if(pTS->pCachedRpmsArray) { if(!g_array_append_val(pTS->pCachedRpmsArray, pszFilePath)) { dwError = ERROR_TDNF_OUT_OF_MEMORY; BAIL_ON_TDNF_ERROR(dwError); } } pszDownloadCacheDir = g_path_get_dirname(pszFilePath); if(!pszDownloadCacheDir) { dwError = ENOENT; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } if(access(pszDownloadCacheDir, F_OK)) { if(errno != ENOENT) { dwError = errno; } BAIL_ON_TDNF_SYSTEM_ERROR(dwError); dwError = TDNFUtilsMakeDirs(pszDownloadCacheDir); BAIL_ON_TDNF_ERROR(dwError); } if(access(pszFilePath, F_OK)) { if(errno != ENOENT) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } dwError = TDNFDownloadPackage(pTdnf, hPkg, pszDownloadCacheDir); BAIL_ON_TDNF_ERROR(dwError); } //A download could have been triggered. //So check access and bail if not available if(access(pszFilePath, F_OK)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } //Check override, then repo config and launch //gpg check if needed dwError = TDNFGetGPGCheck(pTdnf, pszRepoName, &nGPGCheck, &pszUrlGPGKey); BAIL_ON_TDNF_ERROR(dwError); if(nGPGCheck) { dwError = TDNFGPGCheck(pTS->pKeyring, pszUrlGPGKey, pszFilePath); BAIL_ON_TDNF_ERROR(dwError); } fp = Fopen (pszFilePath, "r.ufdio"); if(!fp) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } dwError = rpmReadPackageFile( pTS->pTS, fp, pszFilePath, &rpmHeader); //If not checking gpg sigs, ignore signature errors if(!nGPGCheck && (dwError == RPMRC_NOTTRUSTED || dwError == RPMRC_NOKEY)) { dwError = 0; } BAIL_ON_TDNF_RPM_ERROR(dwError); dwError = rpmtsAddInstallElement( pTS->pTS, rpmHeader, (fnpyKey)pszFilePath, nUpgrade, NULL); BAIL_ON_TDNF_RPM_ERROR(dwError); cleanup: TDNF_SAFE_FREE_MEMORY(pszUrlGPGKey); if(pszHyName) { hy_free(pszHyName); } if(pszDownloadCacheDir) { g_free(pszDownloadCacheDir); } if(pszRpmCacheDir) { g_free(pszRpmCacheDir); } if(fp) { Fclose(fp); } if(rpmHeader) { headerFree(rpmHeader); } return dwError; error: goto cleanup; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { rpmfi fi = NULL; char * specFile = NULL; const char *rootdir = rpmtsRootDir(ts); Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; struct rpmtd_s filenames; rpmtdReset(&filenames); rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_ALLOC)) { struct rpmtd_s td; const char *str; const char *_cookie = headerGetString(h, RPMTAG_COOKIE); if (cookie && _cookie) *cookie = xstrdup(_cookie); /* Try to find spec by file flags */ if (_cookie && headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) { rpmfileAttrs *flags; while (specix < 0 && (flags = rpmtdNextUint32(&td))) { if (*flags & RPMFILE_SPECFILE) specix = rpmtdGetIndex(&td); } } /* Still no spec? Look by filename. */ while (specix < 0 && (str = rpmtdNextString(&filenames))) { if (rpmFileHasSuffix(str, ".spec")) specix = rpmtdGetIndex(&filenames); } } if (rootdir && rstreq(rootdir, "/")) rootdir = NULL; /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h); if (specix >= 0) { const char *bn; headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); rpmtdInit(&filenames); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rpmtsRootDir(ts), spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); if (spec) specFile = xstrdup(fn); free(fn); } headerConvert(h, HEADERCONV_COMPRESSFILELIST); } else { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); h = headerFree(h); if (fi == NULL) { goto exit; } fi->apath = filenames.data; /* Ick */ rpmteSetFI(te, fi); fi = rpmfiFree(fi); if (rpmMkdirs(rpmtsRootDir(ts), "%{_topdir}:%{_sourcedir}:%{_specdir}")) { goto exit; } { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int i; unsigned int fc = rpmfiFC(fi); for (i=0; i<fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te); psm->goal = PKG_INSTALL; /* FIX: psm->fi->dnl should be owned. */ if (rpmpsmStage(psm, PSM_PROCESS) == RPMRC_OK) rpmrc = RPMRC_OK; (void) rpmpsmStage(psm, PSM_FINI); rpmpsmFree(psm); exit: if (specFilePtr && specFile && rpmrc == RPMRC_OK) *specFilePtr = specFile; else free(specFile); headerFree(h); rpmfiFree(fi); /* XXX nuke the added package(s). */ rpmtsClean(ts); return rpmrc; }
int main ( int argc, char * * argv ) { int rc = -1; rpmts pts = NULL; /* Transaction Set */ FD_t pfd = NULL; Header pheader = NULL; char * pszPath = "/home/knaka/rpm/RPMS/i686/file-4.14-1.i686.rpm"; char * psz = NULL; char * * ppsz = NULL; int iType; void * pv; int_32 nCount; int_32 iTag; int_32 aiTag[] = { RPMTAG_NAME, RPMTAG_REQUIRENAME }; int i; int nNumTag = (sizeof (aiTag)) / sizeof (int_32); if (! (pfd = Fopen(pszPath, "r.ufdio"))) { fprintf(stderr, "Failed to open file.\n"); goto except; } if (! (pts = rpmtsCreate())) { fprintf(stderr, "Failed to create transaction set.\n"); goto except; } rpmtsSetVSFlags(pts, RPMVSF_NOMD5 | RPMVSF_NODSA | RPMVSF_NORSA); if (rpmReadPackageFile(pts, pfd, pszPath, & pheader) != RPMRC_OK) { fprintf(stderr, "Failed to read file.\n"); goto except; } for (i = 0; i < nNumTag; ++ i) { iTag = aiTag[i]; /* return: 1 on success, 0 on failure */ if (headerIsEntry(pheader, iTag) == 0) { fprintf(stderr, "No such entry.\n"); goto except; } /* headerGetEntryMinMemory() allocates only for the pointer vector of RPM_STRING_ARRAY_TYPE */ /* return: 1 on success, 0 on failure */ /* if (headerGetEntryMinMemory(pheader, iTag, & iType, */ if (headerGetEntry(pheader, iTag, & iType, (void *) & pv, & nCount ) == 0) { fprintf(stderr, "Failed to get size.\n"); goto except; } switch (iType) { case RPM_STRING_ARRAY_TYPE: { int i; const char * * ppszSrc = (const char * *) pv; ppsz = (char * *) malloc((sizeof (char *)) * (nCount + 1)); fprintf(stderr, "d2-0: %d\n", nCount); for (i = 0; i < nCount; ++ i) { ppsz[i] = strdup(ppszSrc[i]); fprintf(stderr, "d2 (%d, %p): %s\n", i, ppsz[i], ppsz[i]); /* free(ppszSrc[i]); */ } ppsz[i] = NULL; fprintf(stderr, "d3 (%p)\n", pv); free(pv); break; } case RPM_STRING_TYPE: case RPM_I18NSTRING_TYPE: { psz = strdup(pv); fprintf(stderr, "d1: %s\n", psz); free(pv); break; } case RPM_BIN_TYPE: { /* free(pv); */ break; } default: { fprintf(stderr, "Unknown type.\n"); goto except; } } if (ppsz) { int i; for (i = 0; ppsz[i]; ++ i) { free(ppsz[i]); } free(ppsz); ppsz = NULL; } if (psz) { free(psz); psz = NULL; } } rc = 0; except: if (ppsz) { int i; for (i = 0; ppsz[i]; ++ i) { free(ppsz[i]); } free(ppsz); } if (psz) { free(psz); } if (pheader) { headerFree(pheader); } if (pts) { rpmtsFree(pts); } if (pfd) { Fclose(pfd); } return (rc); }