summaryrefslogtreecommitdiff
path: root/rpmqv.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpmqv.c')
-rw-r--r--rpmqv.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/rpmqv.c b/rpmqv.c
new file mode 100644
index 0000000..989e95a
--- /dev/null
+++ b/rpmqv.c
@@ -0,0 +1,352 @@
+#include "system.h"
+const char *__progname;
+
+#include <rpm/rpmcli.h>
+#include <rpm/rpmlib.h> /* RPMSIGTAG, rpmReadPackageFile .. */
+#include <rpm/rpmlog.h>
+#include <rpm/rpmps.h>
+#include <rpm/rpmts.h>
+
+#include "cliutils.h"
+
+#include "debug.h"
+
+#if defined(IAM_RPMQ) || defined(IAM_RPMV)
+#define IAM_RPMQV
+#endif
+
+enum modes {
+
+ MODE_QUERY = (1 << 0),
+ MODE_VERIFY = (1 << 3),
+#define MODES_QV (MODE_QUERY | MODE_VERIFY)
+
+ MODE_INSTALL = (1 << 1),
+ MODE_ERASE = (1 << 2),
+#define MODES_IE (MODE_INSTALL | MODE_ERASE)
+
+ MODE_UNKNOWN = 0
+};
+
+#define MODES_FOR_NODEPS (MODES_IE | MODE_VERIFY)
+#define MODES_FOR_TEST (MODES_IE)
+
+static int quiet;
+
+/* the structure describing the options we take and the defaults */
+static struct poptOption optionsTable[] = {
+
+#ifdef IAM_RPMQV
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
+ N_("Query/Verify package selection options:"),
+ NULL },
+#endif
+#ifdef IAM_RPMQ
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
+ N_("Query options (with -q or --query):"),
+ NULL },
+#endif
+#ifdef IAM_RPMV
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
+ N_("Verify options (with -V or --verify):"),
+ NULL },
+#endif
+
+#ifdef IAM_RPMEIU
+ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
+ N_("Install/Upgrade/Erase options:"),
+ NULL },
+#endif /* IAM_RPMEIU */
+
+ { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, 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;
+ enum modes bigMode = MODE_UNKNOWN;
+
+#if defined(IAM_RPMQV)
+ QVA_t qva = &rpmQVKArgs;
+#endif
+
+#ifdef IAM_RPMEIU
+ struct rpmInstallArguments_s * ia = &rpmIArgs;
+#endif
+
+ poptContext optCon;
+ int ec = 0;
+#ifdef IAM_RPMEIU
+ int i;
+#endif
+
+ optCon = rpmcliInit(argc, argv, optionsTable);
+
+ /* Set the major mode based on argv[0] */
+#ifdef IAM_RPMQV
+ if (rstreq(__progname, "rpmquery")) bigMode = MODE_QUERY;
+ if (rstreq(__progname, "rpmverify")) bigMode = MODE_VERIFY;
+#endif
+
+#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_INSTALL:
+ case MODE_ERASE:
+ case MODE_UNKNOWN:
+ default:
+ break;
+ }
+#endif
+
+#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 > 1)
+ 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 */
+
+#if defined(IAM_RPMEIU)
+ if (!( bigMode == MODE_INSTALL ) &&
+(ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
+ argerror(_("only installation and upgrading 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->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->prefix)
+ argerror(_("--prefix may only be used when installing new packages"));
+
+ if (ia->prefix && ia->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 (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
+ (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
+ argerror(_("--ignoresize may only be specified during package "
+ "installation"));
+
+ if ((ia->installInterfaceFlags & UNINSTALL_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 && bigMode != MODE_VERIFY &&
+ (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 && bigMode != MODE_VERIFY &&
+ (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 "
+ "installation, erasure, and verification"));
+
+ if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
+ argerror(_("--test may only be specified during package installation "
+ "and erasure"));
+#endif /* IAM_RPMEIU */
+
+ if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
+ argerror(_("arguments to --root (-r) must begin with a /"));
+ }
+
+ if (quiet)
+ rpmSetVerbosity(RPMLOG_WARNING);
+
+ if (rpmcliPipeOutput && initPipe())
+ exit(EXIT_FAILURE);
+
+ ts = rpmtsCreate();
+ (void) rpmtsSetRootDir(ts, rpmcliRootDir);
+ switch (bigMode) {
+#ifdef IAM_RPMEIU
+ case MODE_ERASE:
+ if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
+
+ if (!poptPeekArg(optCon)) {
+ argerror(_("no packages given for erase"));
+ } else {
+ ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
+ }
+ break;
+
+ case MODE_INSTALL:
+
+ /* RPMTRANS_FLAG_KEEPOBSOLETE */
+
+ 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) */
+ if (ia->prefix) {
+ ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
+ ia->relocations[0].oldPath = NULL; /* special case magic */
+ ia->relocations[0].newPath = ia->prefix;
+ ia->relocations[1].oldPath = NULL;
+ ia->relocations[1].newPath = NULL;
+ } else if (ia->relocations) {
+ ia->relocations = xrealloc(ia->relocations,
+ sizeof(*ia->relocations) * (ia->numRelocations + 1));
+ ia->relocations[ia->numRelocations].oldPath = NULL;
+ ia->relocations[ia->numRelocations].newPath = NULL;
+ }
+
+ if (!poptPeekArg(optCon)) {
+ argerror(_("no packages given for install"));
+ } else {
+ /* FIX: ia->relocations[0].newPath undefined */
+ ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
+ }
+ break;
+
+#endif /* IAM_RPMEIU */
+
+#ifdef IAM_RPMQV
+ case MODE_QUERY:
+ if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
+ argerror(_("no arguments given for query"));
+
+ ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
+ break;
+
+ case MODE_VERIFY:
+ { rpmVerifyFlags verifyFlags = VERIFY_ALL;
+
+ verifyFlags &= ~qva->qva_flags;
+ qva->qva_flags = (rpmQueryFlags) verifyFlags;
+
+ if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
+ argerror(_("no arguments given for verify"));
+ ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
+ } break;
+#endif /* IAM_RPMQV */
+
+#if !defined(IAM_RPMQV)
+ case MODE_QUERY:
+ case MODE_VERIFY:
+#endif
+#if !defined(IAM_RPMEIU)
+ case MODE_INSTALL:
+ case MODE_ERASE:
+#endif
+ case MODE_UNKNOWN:
+ if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
+ printUsage(optCon, stderr, 0);
+ ec = argc;
+ }
+ break;
+ }
+
+ ts = rpmtsFree(ts);
+ finishPipe();
+
+#ifdef IAM_RPMQV
+ qva->qva_queryFormat = _free(qva->qva_queryFormat);
+#endif
+
+#ifdef IAM_RPMEIU
+ if (ia->relocations != NULL)
+ for (i = 0; i < ia->numRelocations; i++)
+ ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
+ ia->relocations = _free(ia->relocations);
+#endif
+
+ rpmcliFini(optCon);
+
+ return RETVAL(ec);
+}