static int rpmfd_init(rpmfdObject *s, PyObject *args, PyObject *kwds) { char *kwlist[] = { "obj", "mode", "flags", NULL }; const char *mode = "r"; const char *flags = "ufdio"; char *rpmio_mode = NULL; PyObject *fo = NULL; FD_t fd = NULL; int fdno; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ss", kwlist, &fo, &mode, &flags)) return -1; rpmio_mode = rstrscat(NULL, mode, ".", flags, NULL); if (PyBytes_Check(fo)) { fd = openPath(PyBytes_AsString(fo), rpmio_mode); } else if (PyUnicode_Check(fo)) { PyObject *enc = NULL; int rc; #if PY_MAJOR_VERSION >= 3 rc = PyUnicode_FSConverter(fo, &enc); #else rc = utf8FromPyObject(fo, &enc); #endif if (rc) { fd = openPath(PyBytes_AsString(enc), rpmio_mode); Py_DECREF(enc); } } else if (rpmfdObject_Check(fo)) { rpmfdObject *fdo = (rpmfdObject *)fo; fd = openFd(fdDup(Fileno(fdo->fd)), rpmio_mode); } else if ((fdno = PyObject_AsFileDescriptor(fo)) >= 0) { fd = openFd(fdDup(fdno), rpmio_mode); } else { PyErr_SetString(PyExc_TypeError, "path or file object expected"); } if (fd != NULL) { Fclose(s->fd); /* in case __init__ was called again */ free(s->mode); free(s->flags); s->fd = fd; s->mode = rstrdup(mode); s->flags = rstrdup(flags); } else { PyErr_SetString(PyExc_IOError, Fstrerror(fd)); } free(rpmio_mode); return (fd == NULL) ? -1 : 0; }
/** * @todo Create transaction set *much* earlier. */ static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char * fmodeMacro) { char *failedFile = NULL; FD_t cfd; int fsmrc; (void) Fflush(fdo); cfd = Fdopen(fdDup(Fileno(fdo)), fmodeMacro); if (cfd == NULL) return RPMRC_FAIL; fsmrc = rpmPackageFilesArchive(csa->cpioList, headerIsSource(h), cfd, &csa->cpioArchiveSize, &failedFile); if (fsmrc) { if (failedFile) rpmlog(RPMLOG_ERR, _("create archive failed on file %s\n"), failedFile); else rpmlog(RPMLOG_ERR, _("create archive failed\n")); } free(failedFile); Fclose(cfd); return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL; }
int showVerifyPackage(QVA_t qva, rpmts ts, Header h) { int ec = 0; int rc; if (qva->qva_flags & VERIFY_DEPS) { int save_noise = _rpmds_unspecified_epoch_noise; if (rpmIsVerbose()) _rpmds_unspecified_epoch_noise = 1; if ((rc = verifyDependencies(qva, ts, h)) != 0) ec = rc; _rpmds_unspecified_epoch_noise = save_noise; } if (qva->qva_flags & VERIFY_FILES) { if ((rc = verifyHeader(qva, ts, h)) != 0) ec = rc; } if ((qva->qva_flags & VERIFY_SCRIPT) && headerIsEntry(h, RPMTAG_VERIFYSCRIPT)) { FD_t fdo = fdDup(STDOUT_FILENO); if ((rc = rpmVerifyScript(qva, ts, h, fdo)) != 0) ec = rc; if (fdo != NULL) rc = Fclose(fdo); } return ec; }
/** * @todo Create transaction set *much* earlier. */ static rpmRC cpio_doio(FD_t fdo, Package pkg, const char * fmodeMacro, rpm_loff_t *archiveSize) { char *failedFile = NULL; FD_t cfd; int fsmrc; (void) Fflush(fdo); cfd = Fdopen(fdDup(Fileno(fdo)), fmodeMacro); if (cfd == NULL) return RPMRC_FAIL; fsmrc = rpmPackageFilesArchive(pkg->cpioList, headerIsSource(pkg->header), cfd, pkg->dpaths, archiveSize, &failedFile); if (fsmrc) { char *emsg = rpmfileStrerror(fsmrc); if (failedFile) rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"), failedFile, emsg); else rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), emsg); free(emsg); } free(failedFile); Fclose(cfd); return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL; }
PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds) { FD_t fd; int fileno; PyObject * list; int rc; int matchTag; char * kwlist[] = {"list", "fd", "matchTag", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list, &fileno, &matchTag)) return NULL; if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "first parameter must be a list"); return NULL; } fd = fdDup(fileno); rc = rpmMergeHeaders (list, fd, matchTag); Fclose(fd); if (rc) { return NULL; } Py_RETURN_NONE; }
/** * @todo Create transaction set *much* earlier. */ static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char * fmodeMacro) { rpmts ts = rpmtsCreate(); rpmfi fi = csa->cpioList; rpmte te = NULL; rpmfs fs = NULL; char *failedFile = NULL; FD_t cfd; rpmRC rc = RPMRC_OK; int xx, i; { char *fmode = rpmExpand(fmodeMacro, NULL); if (!(fmode && fmode[0] == 'w')) fmode = xstrdup("w9.gzdio"); (void) Fflush(fdo); cfd = Fdopen(fdDup(Fileno(fdo)), fmode); fmode = _free(fmode); } if (cfd == NULL) return RPMRC_FAIL; /* make up a transaction element for passing to fsm */ rpmtsAddInstallElement(ts, h, NULL, 0, NULL); te = rpmtsElement(ts, 0); fs = rpmteGetFileStates(te); fi = rpmfiInit(fi, 0); while ((i = rpmfiNext(fi)) >= 0) { if (rpmfiFFlags(fi) & RPMFILE_GHOST) rpmfsSetAction(fs, i, FA_SKIP); else rpmfsSetAction(fs, i, FA_COPYOUT); } xx = fsmSetup(rpmfiFSM(fi), FSM_PKGBUILD, ts, te, fi, cfd, &csa->cpioArchiveSize, &failedFile); if (xx) rc = RPMRC_FAIL; (void) Fclose(cfd); xx = fsmTeardown(rpmfiFSM(fi)); if (rc == RPMRC_OK && xx) rc = RPMRC_FAIL; if (rc) { if (failedFile) rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"), failedFile, cpioStrerror(rc)); else rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), cpioStrerror(rc)); rc = RPMRC_FAIL; } rpmtsEmpty(ts); failedFile = _free(failedFile); ts = rpmtsFree(ts); return rc; }
static void * rpmtsCallback(const void * hd, const rpmCallbackType what, const rpm_loff_t amount, const rpm_loff_t total, const void * pkgKey, rpmCallbackData data) { Header h = (Header) hd; struct rpmtsCallbackType_s * cbInfo = data; PyObject * pkgObj = (PyObject *) pkgKey; PyObject * args, * result; static FD_t fd; if (cbInfo->cb == Py_None) return NULL; /* Synthesize a python object for callback (if necessary). */ if (pkgObj == NULL) { if (h) { pkgObj = Py_BuildValue("s", headerGetString(h, RPMTAG_NAME)); } else { pkgObj = Py_None; Py_INCREF(pkgObj); } } else Py_INCREF(pkgObj); PyEval_RestoreThread(cbInfo->_save); args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data); result = PyEval_CallObject(cbInfo->cb, args); Py_DECREF(args); Py_DECREF(pkgObj); if (!result) { die(cbInfo->cb); } if (what == RPMCALLBACK_INST_OPEN_FILE) { int fdno; if (!PyArg_Parse(result, "i", &fdno)) { die(cbInfo->cb); } Py_DECREF(result); cbInfo->_save = PyEval_SaveThread(); fd = fdDup(fdno); fcntl(Fileno(fd), F_SETFD, FD_CLOEXEC); return fd; } else if (what == RPMCALLBACK_INST_CLOSE_FILE) { Fclose (fd); } Py_DECREF(result); cbInfo->_save = PyEval_SaveThread(); return NULL; }
/* * Set the transaction script file handle * i.e stdout/stderr on scriptlet execution * @param [File] file File handle */ VALUE rpm_transaction_set_script_file(VALUE trans, VALUE file) { if (TYPE(file) != T_FILE) { rb_raise(rb_eTypeError, "illegal argument type"); } rb_ivar_set(trans, id_sf, file); RPM_SCRIPT_FD(trans) = fdDup(NUM2INT(rb_Integer(file))); #if RPM_VERSION_CODE < RPM_VERSION(4,1,0) rpmtransSetScriptFd(RPM_TRANSACTION(trans), RPM_SCRIPT_FD(trans)); #else rpmtsSetScriptFd(RPM_TRANSACTION(trans), RPM_SCRIPT_FD(trans)); #endif return Qnil; }
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv) { rpmVSFlags vsflags, ovsflags; int ec = 0; FD_t scriptFd = fdDup(STDOUT_FILENO); /* * Open the DB + indices explicitly before possible chroot, * otherwises BDB is going to be unhappy... */ rpmtsOpenDB(ts, O_RDONLY); rpmdbOpenAll(rpmtsGetRdb(ts)); if (rpmChrootSet(rpmtsRootDir(ts)) || rpmChrootIn()) { ec = 1; goto exit; } if (qva->qva_showPackage == NULL) qva->qva_showPackage = showVerifyPackage; vsflags = rpmExpandNumeric("%{?_vsflags_verify}"); if (rpmcliQueryFlags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (rpmcliQueryFlags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (rpmcliQueryFlags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; vsflags &= ~RPMVSF_NEEDPAYLOAD; rpmtsSetScriptFd(ts, scriptFd); ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmcliArgIter(ts, qva, argv); vsflags = rpmtsSetVSFlags(ts, ovsflags); rpmtsSetScriptFd(ts, NULL); if (qva->qva_showPackage == showVerifyPackage) qva->qva_showPackage = NULL; rpmtsEmpty(ts); if (rpmChrootOut() || rpmChrootSet(NULL)) ec = 1; exit: Fclose(scriptFd); return ec; }
static FD_t ufdOpen(const char * url, int flags, mode_t mode) { FD_t fd = NULL; const char * path; urltype urlType = urlPath(url, &path); if (_rpmio_debug) fprintf(stderr, "*** ufdOpen(%s,0x%x,0%o)\n", url, (unsigned)flags, (unsigned)mode); switch (urlType) { case URL_IS_FTP: case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_HKP: fd = urlOpen(url, flags, mode); /* we're dealing with local file when urlOpen() returns */ urlType = URL_IS_UNKNOWN; break; case URL_IS_DASH: if ((flags & O_ACCMODE) == O_RDWR) { fd = NULL; } else { fd = fdDup((flags & O_ACCMODE) == O_WRONLY ? STDOUT_FILENO : STDIN_FILENO); } break; case URL_IS_PATH: case URL_IS_UNKNOWN: default: fd = fdOpen(path, flags, mode); break; } if (fd == NULL) return NULL; fdSetIo(fd, ufdio); fd->urlType = urlType; if (Fileno(fd) < 0) { (void) fdClose(fd); return NULL; } return fd; }
FD_t rpmMkTemp(char *templ) { mode_t mode; int sfd; FD_t tfd = NULL; mode = umask(0077); sfd = mkstemp(templ); umask(mode); if (sfd < 0) { goto exit; } tfd = fdDup(sfd); close(sfd); exit: return tfd; }
static void* transaction_callback(const void* hd, const rpmCallbackType type, const rpmCallbackSize_t amount, const rpmCallbackSize_t total, fnpyKey key, rpmCallbackData data) { VALUE trans = (VALUE)data; FD_t fdt; const Header hdr = (Header)hd; VALUE sig; VALUE rv; sig = rb_struct_new(rpm_sCallbackData, INT2NUM(type), key ? (VALUE)key:Qnil, rpm_package_new_from_header(hdr), UINT2NUM(amount), UINT2NUM(total)); rv = rb_yield(sig); switch (type) { case RPMCALLBACK_INST_OPEN_FILE: if (TYPE(rv) != T_FILE) { rb_raise(rb_eTypeError, "illegal return value type"); } rb_ivar_set(trans, id_file, rv); fdt = fdDup(NUM2INT(rb_Integer(rv))); rb_ivar_set(trans, id_fdt, INT2NUM((long)fdt)); return fdt; case RPMCALLBACK_INST_CLOSE_FILE: Fclose((FD_t)NUM2LONG(rb_ivar_get(trans, id_fdt))); rb_ivar_set(trans, id_file, Qnil); rb_ivar_set(trans, id_fdt, Qnil); default: break; } return NULL; }
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; }
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; }
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; }
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; }
int showVerifyPackage(QVA_t qva, rpmts ts, Header h) { static int scareMem = 0; rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS); int spew = (qva->qva_mode != 'v'); /* XXX no output w verify(...) probe. */ int ec = 0; int i; rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem); uint32_t fc = rpmfiFC(fi); { /* Verify header digest/signature. */ if (qva->qva_flags & (VERIFY_DIGEST | VERIFY_SIGNATURE)) { const char * horigin = headerGetOrigin(h); const char * msg = NULL; size_t uhlen = 0; void * uh = headerUnload(h, &uhlen); int lvl = headerCheck(rpmtsDig(ts), uh, uhlen, &msg) == RPMRC_FAIL ? RPMLOG_ERR : RPMLOG_DEBUG; rpmlog(lvl, "%s: %s\n", (horigin ? horigin : "verify"), (msg ? msg : "")); rpmtsCleanDig(ts); uh = _free(uh); msg = _free(msg); } /* Verify file digests. */ if (fc > 0 && (qva->qva_flags & VERIFY_FILES)) #if defined(_OPENMP) #pragma omp parallel for private(i) reduction(+:ec) #endif for (i = 0; i < (int)fc; i++) { int fflags = fi->fflags[i]; rpmvf vf; int rc; /* If not querying %config, skip config files. */ if ((qva->qva_fflags & RPMFILE_CONFIG) && (fflags & RPMFILE_CONFIG)) continue; /* If not querying %doc, skip doc files. */ if ((qva->qva_fflags & RPMFILE_DOC) && (fflags & RPMFILE_DOC)) continue; /* If not verifying %ghost, skip ghost files. */ /* XXX the broken!!! logic disables %ghost queries always. */ if (!(qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST)) continue; /* Gather per-file data into a carrier. */ vf = rpmvfNew(ts, fi, i, omitMask); /* Verify per-file metadata. */ rc = rpmvfVerify(vf, spew); if (rc) ec += rc; (void) rpmvfFree(vf); vf = NULL; } /* Run verify/sanity scripts (if any). */ if (qva->qva_flags & VERIFY_SCRIPT) { int rc; if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT) || headerIsEntry(h, RPMTAG_SANITYCHECK)) { FD_t fdo = fdDup(STDOUT_FILENO); rc = rpmfiSetHeader(fi, h); if ((rc = rpmVerifyScript(qva, ts, fi, fdo)) != 0) ec += rc; if (fdo != NULL) rc = Fclose(fdo); rc = rpmfiSetHeader(fi, NULL); } } /* Verify dependency assertions. */ if (qva->qva_flags & VERIFY_DEPS) { int save_noise = _rpmds_unspecified_epoch_noise; int rc; /*@-mods@*/ if (rpmIsVerbose()) _rpmds_unspecified_epoch_noise = 1; if ((rc = verifyDependencies(qva, ts, h)) != 0) ec += rc; _rpmds_unspecified_epoch_noise = save_noise; /*@=mods@*/ } } fi = rpmfiFree(fi); return ec; }
int rpmDoDigest(int algo, const char * fn,int asAscii, unsigned char * digest, rpm_loff_t * fsizep) { const char * path; urltype ut = urlPath(fn, &path); unsigned char * dig = NULL; size_t diglen; unsigned char buf[32*BUFSIZ]; FD_t fd; rpm_loff_t fsize = 0; pid_t pid = 0; int rc = 0; int fdno; fdno = open_dso(path, &pid, &fsize); if (fdno < 0) { rc = 1; goto exit; } switch(ut) { case URL_IS_PATH: case URL_IS_UNKNOWN: case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: case URL_IS_HKP: case URL_IS_DASH: default: /* Either use the pipe to prelink -y or open the URL. */ fd = (pid != 0) ? fdDup(fdno) : Fopen(fn, "r.ufdio"); (void) close(fdno); if (fd == NULL || Ferror(fd)) { rc = 1; if (fd != NULL) (void) Fclose(fd); break; } fdInitDigest(fd, algo, 0); fsize = 0; while ((rc = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) fsize += rc; fdFiniDigest(fd, algo, (void **)&dig, &diglen, asAscii); if (dig == NULL || Ferror(fd)) rc = 1; (void) Fclose(fd); break; } /* Reap the prelink -y helper. */ if (pid) { int status; (void) waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status)) rc = 1; } exit: if (fsizep) *fsizep = fsize; if (!rc) memcpy(digest, dig, diglen); dig = _free(dig); return rc; }
/* * 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; }
/** * Run an external script. */ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes, const char *sname, rpmlogLvl lvl, FD_t scriptFd, ARGV_t * argvp, const char *script, int arg1, int arg2) { FD_t out = NULL; char * fn = NULL; pid_t pid, reaped; int status; rpmRC rc = RPMRC_FAIL; rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", sname); if (script) { fn = writeScript(*argvp[0], script); if (fn == NULL) { rpmlog(RPMLOG_ERR, _("Couldn't create temporary file for %s: %s\n"), sname, strerror(errno)); goto exit; } argvAdd(argvp, fn); if (arg1 >= 0) { argvAddNum(argvp, arg1); } if (arg2 >= 0) { argvAddNum(argvp, arg2); } } if (scriptFd != NULL) { if (rpmIsVerbose()) { out = fdDup(Fileno(scriptFd)); } else { out = Fopen("/dev/null", "w.fdio"); if (Ferror(out)) { out = fdDup(Fileno(scriptFd)); } } } else { out = fdDup(STDOUT_FILENO); } if (out == NULL) { rpmlog(RPMLOG_ERR, _("Couldn't duplicate file descriptor: %s: %s\n"), sname, strerror(errno)); goto exit; } pid = fork(); if (pid == (pid_t) -1) { rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"), sname, strerror(errno)); goto exit; } else if (pid == 0) {/* Child */ rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n", sname, *argvp[0], (unsigned)getpid()); /* Run scriptlet post fork hook for all plugins */ if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) { doScriptExec(*argvp, prefixes, scriptFd, out); } else { _exit(126); /* exit 126 for compatibility with bash(1) */ } } do { reaped = waitpid(pid, &status, 0); } while (reaped == -1 && errno == EINTR); rpmlog(RPMLOG_DEBUG, "%s: waitpid(%d) rc %d status %x\n", sname, (unsigned)pid, (unsigned)reaped, status); if (reaped < 0) { rpmlog(lvl, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"), sname, pid, reaped, strerror(errno)); } else if (!WIFEXITED(status) || WEXITSTATUS(status)) { if (WIFSIGNALED(status)) { rpmlog(lvl, _("%s scriptlet failed, signal %d\n"), sname, WTERMSIG(status)); } else { rpmlog(lvl, _("%s scriptlet failed, exit status %d\n"), sname, WEXITSTATUS(status)); } } else { /* if we get this far we're clear */ rc = RPMRC_OK; } exit: if (out) Fclose(out); /* XXX dup'd STDOUT_FILENO */ if (fn) { if (!rpmIsDebug()) unlink(fn); free(fn); } return rc; }