rpm/rpmspec.c

120 lines
3.0 KiB
C
Raw Normal View History

#include "system.h"
#include <rpm/rpmcli.h>
#include <rpm/rpmbuild.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmts.h>
#include "cliutils.h"
#include "debug.h"
enum modes {
MODE_UNKNOWN = 0,
MODE_QUERY = (1 << 0),
MODE_PARSE = (1 << 1),
};
static int mode = MODE_UNKNOWN;
static int source = RPMQV_SPECRPMS;
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 },
{ "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 rpms that would be built from spec"), NULL },
{ "srpm", 0, POPT_ARG_VAL, &source, RPMQV_SPECSRPM,
N_("operate on source rpm 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
};
int main(int argc, char *argv[])
{
rpmts ts = NULL;
QVA_t qva = &rpmQVKArgs;
poptContext optCon;
int ec = 0;
Reimplement setprogname() and getprogname() to be generic and portable The RPM code contains setprogname()/getprogname() support implemented through compatiblity layer with very old GLIBC (internals supported back to '95 and earlier), before stabilization of the GNU C library. This compatiblity layer (__progname, __assert_progname, setprogname()) is supposed to support well archaic GLIBC, but on the other hand it pollutes the library namespace and introduces unpredicable compillation errors on BSD systems. The functions setprogname() and getprogname() are natively supported in NetBSD and work the same way as __progname from the GNU C library (they are even implemented in the same way - but with a slightly changed logic). The support for very old (20 years and older) GNU C Library is obfuscating the code, because it uses defines over defines without a word of explaination why to do so. It's important to note that the setprogname()/getprogname() was inconstiently implemented in the codebase, duplicating the code and/or functionality. Add new generic functions getprogname() and setprogname() and bind it to: - the current and for two decades stable GNU LIB C implementation, - the current NetBSD implementation (introduces to NetBSD in 2002), - fallback reimplementation functions of the setprogname() and getprogname() functionality for other systems. Don't support anymore old GNU Lib C internals and don't support older NetBSD systems, as they aren't supported for many years. Add to the codebase comments explaining the relevant codeparts.
2013-08-18 03:50:41 +08:00
xsetprogname(argv[0]); /* Portability call -- see system.h */
optCon = rpmcliInit(argc, argv, optionsTable);
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: {
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) {
fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE));
rpmSpecFree(spec);
} else {
ec++;
}
rpmFreeMacros(NULL);
rpmReadConfigFiles(rpmcliRcfile, target);
}
free(target);
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);
}