int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg) { int res = 1; const char * targets = rpmcliTargets; char *target; const char * t; const char * te; int nqueries = 0; if (qva->qva_showPackage == NULL) goto exit; if (targets == NULL) { res = _specQuery(ts, qva, arg, NULL); nqueries++; goto exit; } rpmlog(RPMLOG_DEBUG, _("Query specfile for platform(s): %s\n"), targets); for (t = targets; *t != '\0'; t = te) { /* Parse out next target platform. */ if ((te = strchr(t, ',')) == NULL) te = t + strlen(t); target = alloca(te-t+1); strncpy(target, t, (te-t)); target[te-t] = '\0'; if (*te != '\0') te++; /* Query spec for this target platform. */ rpmlog(RPMLOG_DEBUG, _(" target platform: %s\n"), target); /* Read in configuration for target. */ if (t != targets) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, target); } res = _specQuery(ts, qva, arg, target); nqueries++; if (res) break; } exit: /* Restore original configuration. */ if (nqueries > 1) { t = targets; if ((te = strchr(t, ',')) == NULL) te = t + strlen(t); target = alloca(te-t+1); strncpy(target, t, (te-t)); target[te-t] = '\0'; if (*te != '\0') te++; rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, target); } return res; }
static char *rpm_get_nvr_by_pkg_name(const char *pkg_name) { int status = rpmReadConfigFiles((const char *) NULL, (const char *) NULL); if (status) error_msg_and_die("error reading RPM rc files"); char *nvr = NULL; rpmts ts = rpmtsCreate(); rpmdbMatchIterator iter = rpmtsInitIterator(ts, RPMTAG_NAME, pkg_name, 0); Header header = rpmdbNextIterator(iter); if (!header) goto error; const char *errmsg = NULL; nvr = headerFormat(header, "%{name}-%{version}-%{release}", &errmsg); if (!nvr && errmsg) error_msg("cannot get nvr. reason: %s", errmsg); error: rpmdbFreeIterator(iter); rpmtsFree(ts); rpmFreeRpmrc(); rpmFreeCrypto(); rpmFreeMacros(NULL); return nvr; }
poptContext rpmcliFini(poptContext optCon) { poptFreeContext(optCon); rpmFreeMacros(NULL); rpmFreeMacros(rpmCLIMacroContext); rpmFreeRpmrc(); rpmlogClose(); rpmcliInitialized = -1; return NULL; }
QueryData genRpmPackages(QueryContext& context) { QueryData results; auto dropper = DropPrivileges::get(); if (!dropper->dropTo("nobody") && isUserAdmin()) { LOG(WARNING) << "Cannot drop privileges for rpm_packages"; return results; } // Isolate RPM/package inspection to the canonical: /usr/lib/rpm. RpmEnvironmentManager env_manager; // The following implementation uses http://rpm.org/api/4.11.1/ rpmInitCrypto(); if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files"; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["name"].exists(EQUALS)) { auto name = (*context.constraints["name"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { Row r; rpmtd td = rpmtdNew(); r["name"] = getRpmAttribute(header, RPMTAG_NAME, td); r["version"] = getRpmAttribute(header, RPMTAG_VERSION, td); r["release"] = getRpmAttribute(header, RPMTAG_RELEASE, td); r["source"] = getRpmAttribute(header, RPMTAG_SOURCERPM, td); r["size"] = getRpmAttribute(header, RPMTAG_SIZE, td); r["sha1"] = getRpmAttribute(header, RPMTAG_SHA1HEADER, td); r["arch"] = getRpmAttribute(header, RPMTAG_ARCH, td); rpmtdFree(td); results.push_back(r); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeCrypto(); rpmFreeRpmrc(); return results; }
static PyObject * reloadConfig(PyObject * self, PyObject * args, PyObject *kwds) { const char * target = NULL; char * kwlist[] = { "target", NULL }; int rc; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &target)) return NULL; rpmFreeMacros(NULL); rpmFreeRpmrc(); rc = rpmReadConfigFiles(NULL, target) ; return PyBool_FromLong(rc == 0); }
void probe_fini (void *ptr) { struct rpm_probe_global *r = (struct rpm_probe_global *)ptr; rpmFreeCrypto(); rpmFreeRpmrc(); rpmFreeMacros(NULL); rpmlogClose(); // If probe_init() failed r->rpmts and r->mutex were not initialized if (r == NULL) return; rpmtsFree(r->rpmts); pthread_mutex_destroy (&(r->mutex)); return; }
QueryData genRpmPackages(QueryContext& context) { QueryData results; // The following implementation uses http://rpm.org/api/4.11.1/ rpmInitCrypto(); if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files."; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["name"].exists()) { auto name = (*context.constraints["name"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { Row r; rpmtd td = rpmtdNew(); r["name"] = getRpmAttribute(header, RPMTAG_NAME, td); r["version"] = getRpmAttribute(header, RPMTAG_VERSION, td); r["release"] = getRpmAttribute(header, RPMTAG_RELEASE, td); r["source"] = getRpmAttribute(header, RPMTAG_SOURCERPM, td); r["size"] = getRpmAttribute(header, RPMTAG_SIZE, td); r["sha1"] = getRpmAttribute(header, RPMTAG_SHA1HEADER, td); r["arch"] = getRpmAttribute(header, RPMTAG_ARCH, td); rpmtdFree(td); results.push_back(r); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeCrypto(); rpmFreeRpmrc(); return results; }
void rpm_destroy() { #ifdef HAVE_LIBRPM /* Mirroring the order of deinit calls in rpm-4.11.1/lib/poptALL.c::rpmcliFini() */ rpmFreeCrypto(); rpmFreeMacros(NULL); rpmFreeRpmrc(); /* rpm >= 4.14 handles this automatically on exit */ #if 0 /* RPM doc says "clean up any open iterators and databases". * Observed to eliminate these Berkeley DB warnings: * "BDB2053 Freeing read locks for locker 0x1e0: 28718/139661746636736" */ rpmdbCheckTerminate(1); #endif #endif list_free_with_free(list_fingerprints); list_fingerprints = NULL; }
int main(int argc, char *argv[]) { rpmts ts = NULL; QVA_t qva = &rpmQVKArgs; poptContext optCon; int ec = 0; xsetprogname(argv[0]); /* Portability call -- see system.h */ optCon = rpmcliInit(argc, argv, optionsTable); if (rpmcliPipeOutput && initPipe()) exit(EXIT_FAILURE); if (target) { rpmFreeMacros(NULL); rpmFreeRpmrc(); rpmReadConfigFiles(rpmcliRcfile, target); } ts = rpmtsCreate(); switch (mode) { case MODE_QUERY: if (!poptPeekArg(optCon)) argerror(_("no arguments given for query")); qva->qva_queryFormat = queryformat; qva->qva_source = source; qva->qva_specQuery = rpmspecQuery; ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon)); break; case MODE_PARSE: { const char * spath; if (!poptPeekArg(optCon)) argerror(_("no arguments given for parse")); while ((spath = poptGetArg(optCon)) != NULL) { rpmSpec spec = rpmSpecParse(spath, (RPMSPEC_ANYARCH|RPMSPEC_FORCE), NULL); if (spec == NULL) { ec++; continue; } fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE)); rpmSpecFree(spec); } break; } case MODE_UNKNOWN: if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) { printUsage(optCon, stderr, 0); ec = argc; } break; } rpmtsFree(ts); if (finishPipe()) ec = EXIT_FAILURE; free(qva->qva_queryFormat); rpmcliFini(optCon); return RETVAL(ec); }
QueryData genRpmPackageFiles(QueryContext& context) { QueryData results; if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files."; return results; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["package"].exists()) { auto name = (*context.constraints["package"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { rpmtd td = rpmtdNew(); rpmfi fi = rpmfiNew(ts, header, RPMTAG_BASENAMES, RPMFI_NOHEADER); auto file_count = rpmfiFC(fi); if (file_count <= 0 || file_count > MAX_RPM_FILES) { // This package contains no or too many files. rpmfiFree(fi); continue; } // Iterate over every file in this package. for (size_t i = 0; rpmfiNext(fi) >= 0 && i < file_count; i++) { Row r; r["package"] = getRpmAttribute(header, RPMTAG_NAME, td); auto path = rpmfiFN(fi); r["path"] = (path != nullptr) ? path : ""; auto username = rpmfiFUser(fi); r["username"] = (username != nullptr) ? username : ""; auto groupname = rpmfiFGroup(fi); r["groupname"] = (groupname != nullptr) ? groupname : ""; r["mode"] = lsperms(rpmfiFMode(fi)); r["size"] = BIGINT(rpmfiFSize(fi)); #ifdef CENTOS_CENTOS6 // Older versions of rpmlib/rpmip use a hash algorithm enum. pgpHashAlgo digest_algo; #else int digest_algo; #endif auto digest = rpmfiFDigestHex(fi, &digest_algo); if (digest_algo == PGPHASHALGO_SHA256) { r["sha256"] = (digest != nullptr) ? digest : ""; } results.push_back(r); } rpmfiFree(fi); rpmtdFree(td); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeRpmrc(); return results; }
int main(int argc, const char ** argv) #endif /*@globals rpmEVR, RPMVERSION, rpmGlobalMacroContext, rpmCLIMacroContext, h_errno, fileSystem, internalState@*/ /*@modifies fileSystem, internalState@*/ { poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable); rpmts ts = NULL; enum modes bigMode = MODE_UNKNOWN; #if defined(IAM_RPMQV) QVA_t qva = &rpmQVKArgs; #endif #ifdef IAM_RPMBT BTA_t ba = &rpmBTArgs; #endif #ifdef IAM_RPMEIU QVA_t ia = &rpmIArgs; #endif #if defined(IAM_RPMDB) QVA_t da = &rpmDBArgs; #endif #if defined(IAM_RPMK) QVA_t ka = &rpmQVKArgs; #endif #if defined(IAM_RPMBT) || defined(IAM_RPMK) char * passPhrase = ""; #endif pid_t pipeChild = 0; int ec = 0; int status; int p[2]; #ifdef IAM_RPMEIU int xx; #endif #if !defined(__GLIBC__) && !defined(__LCLINT__) environ = envp; #else /* XXX limit the fiddle up to linux for now. */ #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) (void) initproctitle(argc, (char **)argv, environ); #endif #endif /* Set the major mode based on argv[0] */ /*@-nullpass@*/ #ifdef IAM_RPMBT if (!strcmp(__progname, "rpmb")) bigMode = MODE_BUILD; if (!strcmp(__progname, "lt-rpmb")) bigMode = MODE_BUILD; if (!strcmp(__progname, "rpmt")) bigMode = MODE_TARBUILD; if (!strcmp(__progname, "rpmbuild")) bigMode = MODE_BUILD; #endif #ifdef IAM_RPMQV if (!strcmp(__progname, "rpmq")) bigMode = MODE_QUERY; if (!strcmp(__progname, "lt-rpmq")) bigMode = MODE_QUERY; if (!strcmp(__progname, "rpmv")) bigMode = MODE_VERIFY; if (!strcmp(__progname, "rpmquery")) bigMode = MODE_QUERY; if (!strcmp(__progname, "rpmverify")) bigMode = MODE_VERIFY; #endif #ifdef RPMEIU if (!strcmp(__progname, "rpme")) bigMode = MODE_ERASE; if (!strcmp(__progname, "rpmi")) bigMode = MODE_INSTALL; if (!strcmp(__progname, "lt-rpmi")) bigMode = MODE_INSTALL; if (!strcmp(__progname, "rpmu")) bigMode = MODE_INSTALL; #endif /*@=nullpass@*/ #if defined(IAM_RPMQV) /* Jumpstart option from argv[0] if necessary. */ switch (bigMode) { case MODE_QUERY: qva->qva_mode = 'q'; break; case MODE_VERIFY: qva->qva_mode = 'V'; break; case MODE_CHECKSIG: qva->qva_mode = 'K'; break; case MODE_RESIGN: qva->qva_mode = 'R'; break; case MODE_INSTALL: case MODE_ERASE: case MODE_BUILD: case MODE_REBUILD: case MODE_RECOMPILE: case MODE_TARBUILD: case MODE_REBUILDDB: case MODE_UNKNOWN: default: break; } #endif rpmcliConfigured(); #ifdef IAM_RPMBT switch (ba->buildMode) { case 'b': bigMode = MODE_BUILD; break; case 't': bigMode = MODE_TARBUILD; break; case 'B': bigMode = MODE_REBUILD; break; case 'C': bigMode = MODE_RECOMPILE; break; } if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN) bigMode = MODE_BUILD; if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN) bigMode = MODE_BUILD; #endif /* IAM_RPMBT */ #ifdef IAM_RPMDB if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) { if (da->rebuild) { if (bigMode != MODE_UNKNOWN) argerror(_("only one major mode may be specified")); else bigMode = MODE_REBUILDDB; } } #endif /* IAM_RPMDB */ #ifdef IAM_RPMQV if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) { switch (qva->qva_mode) { case 'q': bigMode = MODE_QUERY; break; case 'V': bigMode = MODE_VERIFY; break; } if (qva->qva_sourceCount) { if (qva->qva_sourceCount > 2) argerror(_("one type of query/verify may be performed at a " "time")); } if (qva->qva_flags && (bigMode & ~MODES_QV)) argerror(_("unexpected query flags")); if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) argerror(_("unexpected query format")); if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) argerror(_("unexpected query source")); } #endif /* IAM_RPMQV */ #ifdef IAM_RPMEIU if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE)) { int iflags = (ia->installInterfaceFlags & (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL)); int eflags = (ia->installInterfaceFlags & INSTALL_ERASE); if (iflags & eflags) argerror(_("only one major mode may be specified")); else if (iflags) bigMode = MODE_INSTALL; else if (eflags) bigMode = MODE_ERASE; } #endif /* IAM_RPMEIU */ #ifdef IAM_RPMK if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) { switch (ka->qva_mode) { case RPMSIGN_NONE: ka->sign = 0; break; case RPMSIGN_IMPORT_PUBKEY: case RPMSIGN_CHK_SIGNATURE: bigMode = MODE_CHECKSIG; ka->sign = 0; break; case RPMSIGN_ADD_SIGNATURE: case RPMSIGN_NEW_SIGNATURE: case RPMSIGN_DEL_SIGNATURE: bigMode = MODE_RESIGN; ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE); break; } } #endif /* IAM_RPMK */ #if defined(IAM_RPMEIU) if (!( bigMode == MODE_INSTALL ) && (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE))) argerror(_("only installation, upgrading, rmsource and rmspec may be forced")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE)) argerror(_("files may only be relocated during package installation")); if (ia->relocations && ia->qva_prefix) argerror(_("cannot use --prefix with --relocate or --excludepath")); if (bigMode != MODE_INSTALL && ia->relocations) argerror(_("--relocate and --excludepath may only be used when installing new packages")); if (bigMode != MODE_INSTALL && ia->qva_prefix) argerror(_("--prefix may only be used when installing new packages")); if (ia->qva_prefix && ia->qva_prefix[0] != '/') argerror(_("arguments to --prefix must begin with a /")); if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH)) argerror(_("--hash (-h) may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT)) argerror(_("--percent may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG)) argerror(_("--replacepkgs may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) argerror(_("--excludedocs may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && ia->incldocs) argerror(_("--includedocs may only be specified during package " "installation")); if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) argerror(_("only one of --excludedocs and --includedocs may be " "specified")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH)) argerror(_("--ignorearch may only be specified during package " "installation")); if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS)) argerror(_("--ignoreos may only be specified during package " "installation")); if ((ia->installInterfaceFlags & INSTALL_ALLMATCHES) && bigMode != MODE_ERASE) argerror(_("--allmatches may only be specified during package " "erasure")); if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL) argerror(_("--allfiles may only be specified during package " "installation")); if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) && bigMode != MODE_INSTALL && bigMode != MODE_ERASE) argerror(_("--justdb may only be specified during package " "installation and erasure")); if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers))) argerror(_("script disabling options may only be specified during " "package installation and erasure")); if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers))) argerror(_("trigger disabling options may only be specified during " "package installation and erasure")); if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS)) argerror(_("--nodeps may only be specified during package " "building, rebuilding, recompilation, installation, " "erasure, and verification")); if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST)) argerror(_("--test may only be specified during package installation, " "erasure, and building")); #endif /* IAM_RPMEIU */ if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT)) argerror(_("--root (-r) may only be specified during " "installation, erasure, querying, and " "database rebuilds")); if (rpmioRootDir) { switch (urlIsURL(rpmioRootDir)) { default: if (bigMode & MODES_FOR_ROOT) break; /*@fallthrough@*/ case URL_IS_UNKNOWN: if (rpmioRootDir[0] != '/') argerror(_("arguments to --root (-r) must begin with a /")); break; } } #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ integrity_check(__progname, bigMode); #endif #if defined(IAM_RPMBT) || defined(IAM_RPMK) if (0 #if defined(IAM_RPMBT) || ba->sign #endif #if defined(IAM_RPMK) || ka->sign #endif ) /*@-branchstate@*/ { if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD || bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD) { const char ** av; struct stat sb; int errors = 0; if ((av = poptGetArgs(optCon)) == NULL) { fprintf(stderr, _("no files to sign\n")); errors++; } else while (*av) { if (Stat(*av, &sb)) { fprintf(stderr, _("cannot access file %s\n"), *av); errors++; } av++; } if (errors) { ec = errors; goto exit; } if (poptPeekArg(optCon) #if defined(IAM_RPMBT) && !ba->nopassword #endif #if defined(IAM_RPMK) && !ka->nopassword #endif ) { passPhrase = Getpass(_("Enter pass phrase: ")); if (rpmCheckPassPhrase(passPhrase)) { fprintf(stderr, _("Pass phrase check failed\n")); ec = EXIT_FAILURE; goto exit; } fprintf(stderr, _("Pass phrase is good.\n")); /* XXX Getpass() should realloc instead. */ passPhrase = xstrdup(passPhrase); } } } /*@=branchstate@*/ #endif /* IAM_RPMBT || IAM_RPMK */ if (rpmioPipeOutput) { if (pipe(p) < 0) { fprintf(stderr, _("creating a pipe for --pipe failed: %m\n")); goto exit; } if (!(pipeChild = fork())) { (void) close(p[1]); (void) dup2(p[0], STDIN_FILENO); (void) close(p[0]); (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL); fprintf(stderr, _("exec failed\n")); } (void) close(p[0]); (void) dup2(p[1], STDOUT_FILENO); (void) close(p[1]); } ts = rpmtsCreate(); (void) rpmtsSetRootDir(ts, rpmioRootDir); switch (bigMode) { #ifdef IAM_RPMDB case MODE_REBUILDDB: { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}"); rpmVSFlags ovsflags; if (rpmcliQueryFlags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (rpmcliQueryFlags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmtsRebuildDB(ts); vsflags = rpmtsSetVSFlags(ts, ovsflags); } break; #endif /* IAM_RPMDB */ #ifdef IAM_RPMBT case MODE_REBUILD: case MODE_RECOMPILE: { const char * pkg; int nbuilds = 0; while (!rpmIsVerbose()) rpmIncreaseVerbosity(); if (!poptPeekArg(optCon)) argerror(_("no packages files given for rebuild")); ba->buildAmount = RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK; if (bigMode == MODE_REBUILD) { ba->buildAmount |= RPMBUILD_PACKAGEBINARY; ba->buildAmount |= RPMBUILD_RMSOURCE; ba->buildAmount |= RPMBUILD_RMSPEC; ba->buildAmount |= RPMBUILD_CLEAN; ba->buildAmount |= RPMBUILD_RMBUILD; } while ((pkg = poptGetArg(optCon))) { if (nbuilds++ > 0) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, NULL); } ba->specFile = NULL; ba->cookie = NULL; ec = rpmInstallSource(ts, pkg, &ba->specFile, &ba->cookie); if (ec == 0) { ba->rootdir = rpmioRootDir; ba->passPhrase = passPhrase; ec = build(ts, ba, NULL); } ba->cookie = _free(ba->cookie); ba->specFile = _free(ba->specFile); if (ec) /*@loopbreak@*/ break; } } break; case MODE_BUILD: case MODE_TARBUILD: { int nbuilds = 0; #if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */ if (ba->buildChar != 't' && ba->buildChar != 'f') #endif while (!rpmIsVerbose()) rpmIncreaseVerbosity(); switch (ba->buildChar) { case 'a': ba->buildAmount |= RPMBUILD_PACKAGESOURCE; /*@fallthrough@*/ case 'b': ba->buildAmount |= RPMBUILD_PACKAGEBINARY; ba->buildAmount |= RPMBUILD_CLEAN; #if defined(RPM_VENDOR_MANDRIVA) if ((ba->buildChar == 'a' || ba->buildChar == 'b') && ba->shortCircuit) #else if ((ba->buildChar == 'b') && ba->shortCircuit) #endif /*@innerbreak@*/ break; /*@fallthrough@*/ case 'i': ba->buildAmount |= RPMBUILD_INSTALL; ba->buildAmount |= RPMBUILD_CHECK; if ((ba->buildChar == 'i') && ba->shortCircuit) /*@innerbreak@*/ break; /*@fallthrough@*/ case 'c': ba->buildAmount |= RPMBUILD_BUILD; if ((ba->buildChar == 'c') && ba->shortCircuit) /*@innerbreak@*/ break; /*@fallthrough@*/ case 'p': ba->buildAmount |= RPMBUILD_PREP; /*@innerbreak@*/ break; case 'l': ba->buildAmount |= RPMBUILD_FILECHECK; /*@innerbreak@*/ break; case 's': ba->buildAmount |= RPMBUILD_PACKAGESOURCE; #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */ /* enforce no dependency checking when rolling a source RPM */ ba->noDeps = 1; #endif /*@innerbreak@*/ break; case 't': /* support extracting the "%track" script/section */ ba->buildAmount |= RPMBUILD_TRACK; /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */ ba->noDeps = 1; rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE); rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE); rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE); /*@innerbreak@*/ break; case 'f': ba->buildAmount |= RPMBUILD_FETCHSOURCE; ba->noDeps = 1; /*@innerbreak@*/ break; } if (!poptPeekArg(optCon)) { if (bigMode == MODE_BUILD) argerror(_("no spec files given for build")); else argerror(_("no tar files given for build")); } while ((ba->specFile = poptGetArg(optCon))) { if (nbuilds++ > 0) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(NULL, NULL); } ba->rootdir = rpmioRootDir; ba->passPhrase = passPhrase; ba->cookie = NULL; ec = build(ts, ba, NULL); if (ec) /*@loopbreak@*/ break; } } break; #endif /* IAM_RPMBT */ #ifdef IAM_RPMEIU case MODE_ERASE: ia->depFlags = global_depFlags; if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; if (!poptPeekArg(optCon)) { if (ia->rbtid == 0) argerror(_("no packages given for erase")); ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; ia->rbCheck = rpmcliInstallCheck; ia->rbOrder = rpmcliInstallOrder; ia->rbRun = rpmcliInstallRun; ec += rpmRollback(ts, ia, NULL); } else { ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon)); } break; case MODE_INSTALL: /* RPMTRANS_FLAG_KEEPOBSOLETE */ ia->depFlags = global_depFlags; if (!ia->incldocs) { if (ia->transFlags & RPMTRANS_FLAG_NODOCS) { ; } else if (rpmExpandNumeric("%{_excludedocs}")) ia->transFlags |= RPMTRANS_FLAG_NODOCS; } if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; /* we've already ensured !(!ia->prefix && !ia->relocations) */ /*@-branchstate@*/ if (ia->qva_prefix) { xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, ia->qva_prefix); xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, NULL); } else if (ia->relocations) { xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, NULL, NULL); } /*@=branchstate@*/ if (!poptPeekArg(optCon)) { if (ia->rbtid == 0) argerror(_("no packages given for install")); ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; ia->rbCheck = rpmcliInstallCheck; ia->rbOrder = rpmcliInstallOrder; ia->rbRun = rpmcliInstallRun; /*@i@*/ ec += rpmRollback(ts, ia, NULL); } else { /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */ ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon)); /*@=compdef =compmempass@*/ } break; #endif /* IAM_RPMEIU */ #ifdef IAM_RPMQV case MODE_QUERY: if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) argerror(_("no arguments given for query")); qva->depFlags = global_depFlags; qva->qva_specQuery = rpmspecQuery; ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon)); qva->qva_specQuery = NULL; break; case MODE_VERIFY: { rpmVerifyFlags verifyFlags = VERIFY_ALL; qva->depFlags = global_depFlags; verifyFlags &= ~qva->qva_flags; qva->qva_flags = (rpmQueryFlags) verifyFlags; if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) argerror(_("no arguments given for verify")); ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon)); } break; #endif /* IAM_RPMQV */ #ifdef IAM_RPMK case MODE_CHECKSIG: { rpmVerifyFlags verifyFlags = (VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE); verifyFlags &= ~ka->qva_flags; ka->qva_flags = (rpmQueryFlags) verifyFlags; } /*@fallthrough@*/ case MODE_RESIGN: if (!poptPeekArg(optCon)) argerror(_("no arguments given")); ka->passPhrase = passPhrase; ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon)); break; #endif /* IAM_RPMK */ #if !defined(IAM_RPMQV) case MODE_QUERY: case MODE_VERIFY: #endif #if !defined(IAM_RPMK) case MODE_CHECKSIG: case MODE_RESIGN: #endif #if !defined(IAM_RPMDB) case MODE_REBUILDDB: #endif #if !defined(IAM_RPMBT) case MODE_BUILD: case MODE_REBUILD: case MODE_RECOMPILE: case MODE_TARBUILD: #endif #if !defined(IAM_RPMEIU) case MODE_INSTALL: case MODE_ERASE: #endif case MODE_UNKNOWN: #ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */ if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) { printUsage(optCon, stderr, 0); ec = argc; } #endif break; } #if defined(IAM_RPMBT) || defined(IAM_RPMK) exit: #endif /* IAM_RPMBT || IAM_RPMK */ (void)rpmtsFree(ts); ts = NULL; if (pipeChild) { (void) fclose(stdout); (void) waitpid(pipeChild, &status, 0); } #ifdef IAM_RPMQV qva->qva_queryFormat = _free(qva->qva_queryFormat); #endif #ifdef IAM_RPMBT freeNames(); /* XXX _specPool/_pkgPool teardown should be done somewhere else. */ { extern rpmioPool _pkgPool; extern rpmioPool _specPool; _pkgPool = rpmioFreePool(_pkgPool); _specPool = rpmioFreePool(_specPool); } #endif #ifdef IAM_RPMEIU ia->relocations = rpmfiFreeRelocations(ia->relocations); #endif optCon = rpmcliFini(optCon); /* XXX limit the fiddle up to linux for now. */ #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) (void) finiproctitle(); #endif /* XXX don't overflow single byte exit status */ /* XXX status 255 is special to xargs(1) */ if (ec > 254) ec = 254; rpmlog(RPMLOG_DEBUG, D_("exit code: %d\n"), ec); /*@-globstate@*/ return ec; /*@=globstate@*/ }
poptContext rpmcliFini(poptContext optCon) /*@globals keyids @*/ /*@modifies keyids @*/ { /*@-nestedextern@*/ extern rpmioPool _rpmjsPool; extern rpmioPool _rpmrubyPool; extern rpmioPool _headerPool; extern rpmioPool _rpmmiPool; extern rpmioPool _dbiPool; extern rpmioPool _rpmdbPool; extern rpmioPool _rpmrepoPool; extern rpmioPool _rpmwfPool; extern const char * evr_tuple_order; extern const char * evr_tuple_match; extern miRE evr_tuple_mire; /*@=nestedextern@*/ /*@-mods@*/ evr_tuple_order = _free(evr_tuple_order); evr_tuple_match = _free(evr_tuple_match); evr_tuple_mire = mireFree(evr_tuple_mire); /*@-onlyunqglobaltrans@*/ /* Realease (and dereference) embedded interpreter global objects first. */ _rpmjsI = rpmjsFree(_rpmjsI); _rpmjsPool = rpmioFreePool(_rpmjsPool); _rpmrubyI = rpmrubyFree(_rpmrubyI); _rpmrubyPool = rpmioFreePool(_rpmrubyPool); _rpmgiPool = rpmioFreePool(_rpmgiPool); _rpmmiPool = rpmioFreePool(_rpmmiPool); _psmPool = rpmioFreePool(_psmPool); _rpmtsiPool = rpmioFreePool(_rpmtsiPool); _rpmtsPool = rpmioFreePool(_rpmtsPool); _rpmtePool = rpmioFreePool(_rpmtePool); _rpmpsPool = rpmioFreePool(_rpmpsPool); _rpmfcPool = rpmioFreePool(_rpmfcPool); rpmnsClean(); _rpmdsPool = rpmioFreePool(_rpmdsPool); _rpmfiPool = rpmioFreePool(_rpmfiPool); _rpmwfPool = rpmioFreePool(_rpmwfPool); _rpmdbPool = rpmioFreePool(_rpmdbPool); _rpmrepoPool = rpmioFreePool(_rpmrepoPool); _dbiPool = rpmioFreePool(_dbiPool); _headerPool = rpmioFreePool(_headerPool); /*@=onlyunqglobaltrans@*/ /*@=mods@*/ /* XXX this should be done in the rpmioClean() wrapper. */ /* keeps memory leak checkers quiet */ rpmFreeMacros(NULL); /*@i@*/ rpmFreeMacros(rpmCLIMacroContext); rpmFreeRpmrc(); /* XXX mireFreeAll(platpat) before rpmioFreePool. */ rpmFreeFilesystems(); /*@i@*/ rpmcliTargets = _free(rpmcliTargets); keyids = _free(keyids); tagClean(NULL); /* Free header tag indices. */ rpmioClean(); /* XXX rpmioFreePool()'s after everything else. */ optCon = poptFreeContext(optCon); #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE) /*@-noeffect@*/ muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */ /*@=noeffect@*/ #endif /*@-globstate@*/ return NULL; /*@=globstate@*/ }
void genRpmPackageFiles(RowYield& yield, QueryContext& context) { auto dropper = DropPrivileges::get(); if (!dropper->dropTo("nobody") && isUserAdmin()) { LOG(WARNING) << "Cannot drop privileges for rpm_package_files"; return; } // Isolate RPM/package inspection to the canonical: /usr/lib/rpm. RpmEnvironmentManager env_manager; if (rpmReadConfigFiles(nullptr, nullptr) != 0) { TLOG << "Cannot read RPM configuration files"; return; } rpmts ts = rpmtsCreate(); rpmdbMatchIterator matches; if (context.constraints["package"].exists(EQUALS)) { auto name = (*context.constraints["package"].getAll(EQUALS).begin()); matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size()); } else { matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0); } Header header; while ((header = rpmdbNextIterator(matches)) != nullptr) { rpmtd td = rpmtdNew(); rpmfi fi = rpmfiNew(ts, header, RPMTAG_BASENAMES, RPMFI_NOHEADER); std::string package_name = getRpmAttribute(header, RPMTAG_NAME, td); auto file_count = rpmfiFC(fi); if (file_count <= 0) { VLOG(1) << "RPM package " << package_name << " contains 0 files"; rpmfiFree(fi); continue; } else if (file_count > MAX_RPM_FILES) { VLOG(1) << "RPM package " << package_name << " contains over " << MAX_RPM_FILES << " files"; rpmfiFree(fi); continue; } // Iterate over every file in this package. for (size_t i = 0; rpmfiNext(fi) >= 0 && i < file_count; i++) { Row r; auto path = rpmfiFN(fi); r["package"] = package_name; r["path"] = (path != nullptr) ? path : ""; auto username = rpmfiFUser(fi); r["username"] = (username != nullptr) ? username : ""; auto groupname = rpmfiFGroup(fi); r["groupname"] = (groupname != nullptr) ? groupname : ""; r["mode"] = lsperms(rpmfiFMode(fi)); r["size"] = BIGINT(rpmfiFSize(fi)); int digest_algo; auto digest = rpmfiFDigestHex(fi, &digest_algo); if (digest_algo == PGPHASHALGO_SHA256) { r["sha256"] = (digest != nullptr) ? digest : ""; } yield(r); } rpmfiFree(fi); rpmtdFree(td); } rpmdbFreeIterator(matches); rpmtsFree(ts); rpmFreeRpmrc(); }
int build(rpmts ts, BTA_t ba, const char * rcfile) { const char *t, *te; int rc = 0; const char * targets = rpmcliTargets; char *target; #define buildCleanMask (RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC) int cleanFlags = ba->buildAmount & buildCleanMask; rpmVSFlags vsflags, ovsflags; int nbuilds = 0; vsflags = rpmExpandNumeric("%{_vsflags_build}"); if (ba->qva_flags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (ba->qva_flags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (ba->qva_flags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; ovsflags = rpmtsSetVSFlags(ts, vsflags); if (targets == NULL) { rc = buildForTarget(ts, ba); nbuilds++; goto exit; } /* parse up the build operators */ printf(_("Building target platforms: %s\n"), targets); ba->buildAmount &= ~buildCleanMask; for (t = targets; *t != '\0'; t = te) { /* Parse out next target platform. */ if ((te = strchr(t, ',')) == NULL) te = t + strlen(t); target = alloca(te-t+1); strncpy(target, t, (te-t)); target[te-t] = '\0'; if (*te != '\0') te++; else /* XXX Perform clean-up after last target build. */ ba->buildAmount |= cleanFlags; rpmlog(RPMLOG_DEBUG, _(" target platform: %s\n"), target); /* Read in configuration for target. */ if (t != targets) { rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(rcfile, target); } rc = buildForTarget(ts, ba); nbuilds++; if (rc) break; } exit: /* Restore original configuration. */ if (nbuilds > 1) { t = targets; if ((te = strchr(t, ',')) == NULL) te = t + strlen(t); target = alloca(te-t+1); strncpy(target, t, (te-t)); target[te-t] = '\0'; if (*te != '\0') te++; rpmFreeMacros(NULL); rpmFreeRpmrc(); (void) rpmReadConfigFiles(rcfile, target); } vsflags = rpmtsSetVSFlags(ts, ovsflags); return rc; }