/
githubmirror
/
rpm
Обзор
Документация
Войти
/
githubmirror
/
rpm
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tools/rpmspec.cc
213 строк
5 KB
SleedSurfer
rpmspec: add --sources and --patches flags
27 июл 2026, 17:23
27 июл 2026, 17:23
aaac001
Код
Авторство
О чём код?
#include "system.h" #include <rpm/rpmcli.h> #include <rpm/rpmbuild.h> #include <rpm/rpmlog.h> #include <rpm/rpmts.h> #ifdef HAVE_READLINE #include <readline/readline.h> #include <readline/history.h> #endif #include "cliutils.hh" #include "debug.h" enum modes { MODE_UNKNOWN = 0, MODE_QUERY = (1 << 0), MODE_PARSE = (1 << 1), MODE_SHELL = (1 << 2), MODE_SOURCES = (1 << 3), MODE_PATCHES = (1 << 4), }; static int mode = MODE_UNKNOWN; static int source = RPMQV_SPECRPMS; static bool full = 0; char *queryformat = NULL; static struct poptOption specOptsTable[] = { { "parse", 'P', POPT_ARG_VAL, &mode, MODE_PARSE, N_("parse spec file(s) to stdout"), NULL }, { "query", 'q', POPT_ARG_VAL, &mode, MODE_QUERY, N_("query spec file(s)"), NULL }, #ifdef HAVE_READLINE { "shell", 0, POPT_ARG_VAL, &mode, MODE_SHELL, N_("interactive macro shell"), NULL }, #endif { "sources", 0, POPT_ARG_VAL, &mode, MODE_SOURCES, N_("list all sources from spec file(s)"), NULL }, { "patches", 0, POPT_ARG_VAL, &mode, MODE_PATCHES, N_("list all patches from spec file(s)"), NULL }, { "full", 0, POPT_ARG_NONE, &full, 0, N_("output full path for sources/patches"), NULL }, { "rpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECRPMS, N_("operate on binary rpms generated by spec (default)"), NULL }, { "builtrpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECBUILTRPMS, N_("operate on binary package header(s) that would be built from spec"), NULL }, { "srpm", 0, POPT_ARG_VAL, &source, RPMQV_SPECSRPM, N_("operate on source package header generated by spec"), NULL }, { "queryformat", 0, POPT_ARG_STRING, &queryformat, 0, N_("use the following query format"), "QUERYFORMAT" }, { "qf", 0, (POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN), &queryformat, 0, NULL, NULL }, POPT_TABLEEND }; /* the structure describing the options we take and the defaults */ static struct poptOption optionsTable[] = { { NULL, '\0', POPT_ARG_INCLUDE_TABLE, specOptsTable, 0, N_("Spec options:"), NULL }, { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0, N_("Common options for all rpm modes and executables:"), NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; typedef int (*parsecb)(rpmSpec spec); #ifdef HAVE_READLINE static int doShell(rpmSpec spec) { fprintf(stderr, _("RPM version %s macro shell\n"), rpmEVR); char *line = NULL; while ((line = readline("> ")) != NULL) { char *exp = rpmExpand(line, NULL); if (*exp) fprintf(stdout, "%s\n", exp); free(exp); if (*line) add_history(line); free(line); } return 0; } #endif static int printSourceFilenames(rpmSpec spec, rpmSourceFlags what) { rpmSpecSrcIter iter = rpmSpecSrcIterInit(spec); rpmSpecSrc src; while ((src = rpmSpecSrcIterNext(iter)) != NULL) { if (rpmSpecSrcFlags(src) & what) { const char* url = rpmSpecSrcFilename(src, full); if (url) fprintf(stdout, "%s\n", url); } } rpmSpecSrcIterFree(iter); return 0; } static int printSources(rpmSpec spec) { return printSourceFilenames(spec, RPMBUILD_ISSOURCE); } static int printPatches(rpmSpec spec) { return printSourceFilenames(spec, RPMBUILD_ISPATCH); } static int dumpSpec(rpmSpec spec) { fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE)); return 0; } static int doSpec(poptContext optCon, parsecb cb) { int ec = 0; const char * spath; char *target = rpmExpand("%{_target}", NULL); 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) { ec += cb(spec); rpmSpecFree(spec); } else { ec++; } rpmFreeMacros(NULL); rpmReadConfigFiles(rpmcliRcfile, target); } free(target); return ec; } int main(int argc, char *argv[]) { rpmts ts = NULL; QVA_t qva = &rpmQVKArgs; poptContext optCon; int ec = 0; optCon = rpmcliInit(argc, argv, optionsTable); if (full && (mode != MODE_SOURCES && mode != MODE_PATCHES)) argerror(_("--full is only valid for --sources/--patches operations")); if (rpmcliPipeOutput && initPipe()) exit(EXIT_FAILURE); 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: ec = doSpec(optCon, dumpSpec); break; case MODE_SOURCES: ec = doSpec(optCon, printSources); break; case MODE_PATCHES: ec = doSpec(optCon, printPatches); break; #ifdef HAVE_READLINE case MODE_SHELL: if (poptPeekArg(optCon)) ec = doSpec(optCon, doShell); else ec = doShell(NULL); break; #endif 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); }