csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
#include "system.h"
2ff057
2ff057
#include <rpm/rpmcli.h>
2ff057
#include <rpm/rpmlib.h>			/* RPMSIGTAG, rpmReadPackageFile .. */
2ff057
#include <rpm/rpmlog.h>
2ff057
#include <rpm/rpmps.h>
2ff057
#include <rpm/rpmts.h>
2ff057
2ff057
#include "cliutils.h"
2ff057
2ff057
#include "debug.h"
2ff057
2ff057
#if defined(IAM_RPMQ) || defined(IAM_RPMV)
2ff057
#define IAM_RPMQV
2ff057
#endif
2ff057
2ff057
enum modes {
2ff057
2ff057
    MODE_QUERY		= (1 <<  0),
2ff057
    MODE_VERIFY		= (1 <<  3),
2ff057
#define	MODES_QV (MODE_QUERY | MODE_VERIFY)
2ff057
2ff057
    MODE_INSTALL	= (1 <<  1),
2ff057
    MODE_ERASE		= (1 <<  2),
2ff057
#define	MODES_IE (MODE_INSTALL | MODE_ERASE)
2ff057
2ff057
    MODE_UNKNOWN	= 0
2ff057
};
2ff057
2ff057
#define	MODES_FOR_NODEPS	(MODES_IE | MODE_VERIFY)
2ff057
#define	MODES_FOR_TEST		(MODES_IE)
2ff057
2ff057
static int quiet;
2ff057
2ff057
/* the structure describing the options we take and the defaults */
2ff057
static struct poptOption optionsTable[] = {
2ff057
2ff057
#ifdef	IAM_RPMQV
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
2ff057
        N_("Query/Verify package selection options:"),
2ff057
        NULL },
2ff057
#endif
2ff057
#ifdef IAM_RPMQ
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
2ff057
	N_("Query options (with -q or --query):"),
2ff057
	NULL },
2ff057
#endif
2ff057
#ifdef IAM_RPMV
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
2ff057
	N_("Verify options (with -V or --verify):"),
2ff057
	NULL },
2ff057
#endif
2ff057
2ff057
#ifdef	IAM_RPMEIU
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
2ff057
	N_("Install/Upgrade/Erase options:"),
2ff057
	NULL },
2ff057
#endif	/* IAM_RPMEIU */
2ff057
2ff057
 { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
2ff057
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
2ff057
	N_("Common options for all rpm modes and executables:"),
2ff057
	NULL },
2ff057
2ff057
   POPT_AUTOALIAS
2ff057
   POPT_AUTOHELP
2ff057
   POPT_TABLEEND
2ff057
};
2ff057
2ff057
int main(int argc, char *argv[])
2ff057
{
2ff057
    rpmts ts = NULL;
2ff057
    enum modes bigMode = MODE_UNKNOWN;
2ff057
2ff057
#if defined(IAM_RPMQV)
2ff057
    QVA_t qva = &rpmQVKArgs;
2ff057
#endif
2ff057
2ff057
#ifdef	IAM_RPMEIU
2ff057
   struct rpmInstallArguments_s * ia = &rpmIArgs;
2ff057
#endif
2ff057
2ff057
    poptContext optCon;
2ff057
    int ec = 0;
2ff057
#ifdef	IAM_RPMEIU
2ff057
    int i;
2ff057
#endif
2ff057
2ff057
    xsetprogname(argv[0]); /* Portability call -- see system.h */
2ff057
2ff057
    optCon = rpmcliInit(argc, argv, optionsTable);
2ff057
2ff057
    /* Set the major mode based on argv[0] */
2ff057
#ifdef	IAM_RPMQV
2ff057
    if (rstreq(xgetprogname(), "rpmquery"))	bigMode = MODE_QUERY;
2ff057
    if (rstreq(xgetprogname(), "rpmverify")) bigMode = MODE_VERIFY;
2ff057
#endif
2ff057
2ff057
#if defined(IAM_RPMQV)
2ff057
    /* Jumpstart option from argv[0] if necessary. */
2ff057
    switch (bigMode) {
2ff057
    case MODE_QUERY:	qva->qva_mode = 'q';	break;
2ff057
    case MODE_VERIFY:	qva->qva_mode = 'V';	break;
2ff057
    case MODE_INSTALL:
2ff057
    case MODE_ERASE:
2ff057
    case MODE_UNKNOWN:
2ff057
    default:
2ff057
	break;
2ff057
    }
2ff057
#endif
2ff057
2ff057
#ifdef	IAM_RPMQV
2ff057
  if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
2ff057
    switch (qva->qva_mode) {
2ff057
    case 'q':	bigMode = MODE_QUERY;		break;
2ff057
    case 'V':	bigMode = MODE_VERIFY;		break;
2ff057
    }
2ff057
2ff057
    if (qva->qva_sourceCount) {
2ff057
	if (qva->qva_sourceCount > 1)
2ff057
	    argerror(_("one type of query/verify may be performed at a "
2ff057
			"time"));
2ff057
    }
2ff057
    if (qva->qva_flags && (bigMode & ~MODES_QV)) 
2ff057
	argerror(_("unexpected query flags"));
2ff057
2ff057
    if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
2ff057
	argerror(_("unexpected query format"));
2ff057
2ff057
    if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
2ff057
	argerror(_("unexpected query source"));
2ff057
  }
2ff057
#endif	/* IAM_RPMQV */
2ff057
2ff057
#ifdef	IAM_RPMEIU
2ff057
  if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
2ff057
    {	int iflags = (ia->installInterfaceFlags &
2ff057
			(INSTALL_UPGRADE|INSTALL_FRESHEN|
2ff057
			 INSTALL_INSTALL|INSTALL_REINSTALL));
2ff057
	int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
2ff057
2ff057
	if (iflags & eflags)
2ff057
	    argerror(_("only one major mode may be specified"));
2ff057
	else if (iflags)
2ff057
	    bigMode = MODE_INSTALL;
2ff057
	else if (eflags)
2ff057
	    bigMode = MODE_ERASE;
2ff057
    }
2ff057
#endif	/* IAM_RPMEIU */
2ff057
2ff057
#if defined(IAM_RPMEIU)
2ff057
    if (!( bigMode == MODE_INSTALL ) &&
2ff057
(ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
2ff057
	argerror(_("only installation and upgrading may be forced"));
2ff057
    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
2ff057
	argerror(_("files may only be relocated during package installation"));
2ff057
2ff057
    if (ia->relocations && ia->prefix)
2ff057
	argerror(_("cannot use --prefix with --relocate or --excludepath"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && ia->relocations)
2ff057
	argerror(_("--relocate and --excludepath may only be used when installing new packages"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && ia->prefix)
2ff057
	argerror(_("--prefix may only be used when installing new packages"));
2ff057
2ff057
    if (ia->prefix && ia->prefix[0] != '/') 
2ff057
	argerror(_("arguments to --prefix must begin with a /"));
2ff057
2ff057
    if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_HASH))
2ff057
	argerror(_("--hash (-h) may only be specified during package "
2ff057
			"installation and erasure"));
2ff057
2ff057
    if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_PERCENT))
2ff057
	argerror(_("--percent may only be specified during package "
2ff057
			"installation and erasure"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
2ff057
	argerror(_("--replacepkgs may only be specified during package "
2ff057
			"installation"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
2ff057
	argerror(_("--excludedocs may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && ia->incldocs)
2ff057
	argerror(_("--includedocs may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
2ff057
	argerror(_("only one of --excludedocs and --includedocs may be "
2ff057
		 "specified"));
2ff057
  
2ff057
    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
2ff057
	argerror(_("--ignorearch may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
2ff057
	argerror(_("--ignoreos may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
2ff057
	(ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
2ff057
	argerror(_("--ignoresize may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
2ff057
	argerror(_("--allmatches may only be specified during package "
2ff057
		   "erasure"));
2ff057
2ff057
    if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
2ff057
	argerror(_("--allfiles may only be specified during package "
2ff057
		   "installation"));
2ff057
2ff057
    if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
2ff057
	bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
2ff057
	argerror(_("--justdb may only be specified during package "
2ff057
		   "installation and erasure"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
2ff057
	(ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
2ff057
	argerror(_("script disabling options may only be specified during "
2ff057
		   "package installation and erasure"));
2ff057
2ff057
    if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
2ff057
	(ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
2ff057
	argerror(_("trigger disabling options may only be specified during "
2ff057
		   "package installation and erasure"));
2ff057
2ff057
    if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
2ff057
	argerror(_("--nodeps may only be specified during package "
2ff057
		   "installation, erasure, and verification"));
2ff057
2ff057
    if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
2ff057
	argerror(_("--test may only be specified during package installation "
2ff057
		 "and erasure"));
2ff057
#endif	/* IAM_RPMEIU */
2ff057
2ff057
    if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
2ff057
	argerror(_("arguments to --root (-r) must begin with a /"));
2ff057
    }
2ff057
2ff057
    if (quiet)
2ff057
	rpmSetVerbosity(RPMLOG_WARNING);
2ff057
2ff057
    if (rpmcliPipeOutput && initPipe())
2ff057
	exit(EXIT_FAILURE);
2ff057
	
2ff057
    ts = rpmtsCreate();
2ff057
    (void) rpmtsSetRootDir(ts, rpmcliRootDir);
2ff057
    switch (bigMode) {
2ff057
#ifdef	IAM_RPMEIU
2ff057
    case MODE_ERASE:
2ff057
	if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
2ff057
2ff057
	if (!poptPeekArg(optCon)) {
2ff057
	    argerror(_("no packages given for erase"));
2ff057
	} else {
2ff057
	    ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
2ff057
	}
2ff057
	break;
2ff057
2ff057
    case MODE_INSTALL:
2ff057
2ff057
	/* RPMTRANS_FLAG_KEEPOBSOLETE */
2ff057
2ff057
	if (!ia->incldocs) {
2ff057
	    if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
2ff057
		;
2ff057
	    } else if (rpmExpandNumeric("%{_excludedocs}"))
2ff057
		ia->transFlags |= RPMTRANS_FLAG_NODOCS;
2ff057
	}
2ff057
2ff057
	if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
2ff057
2ff057
	/* we've already ensured !(!ia->prefix && !ia->relocations) */
2ff057
	if (ia->prefix) {
2ff057
	    ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
2ff057
	    ia->relocations[0].oldPath = NULL;   /* special case magic */
2ff057
	    ia->relocations[0].newPath = ia->prefix;
2ff057
	    ia->relocations[1].oldPath = NULL;
2ff057
	    ia->relocations[1].newPath = NULL;
2ff057
	} else if (ia->relocations) {
2ff057
	    ia->relocations = xrealloc(ia->relocations, 
2ff057
			sizeof(*ia->relocations) * (ia->numRelocations + 1));
2ff057
	    ia->relocations[ia->numRelocations].oldPath = NULL;
2ff057
	    ia->relocations[ia->numRelocations].newPath = NULL;
2ff057
	}
2ff057
2ff057
	if (!poptPeekArg(optCon)) {
2ff057
	    argerror(_("no packages given for install"));
2ff057
	} else {
2ff057
	    /* FIX: ia->relocations[0].newPath undefined */
2ff057
	    ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
2ff057
	}
2ff057
	break;
2ff057
2ff057
#endif	/* IAM_RPMEIU */
2ff057
2ff057
#ifdef	IAM_RPMQV
2ff057
    case MODE_QUERY:
2ff057
	if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
2ff057
	    argerror(_("no arguments given for query"));
2ff057
2ff057
	ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
2ff057
	break;
2ff057
2ff057
    case MODE_VERIFY:
2ff057
    {	rpmVerifyFlags verifyFlags = VERIFY_ALL;
2ff057
2ff057
	verifyFlags &= ~qva->qva_flags;
2ff057
	qva->qva_flags = (rpmQueryFlags) verifyFlags;
2ff057
2ff057
	rpmtsSetFlags(ts, rpmtsFlags(ts) | (ia->transFlags & RPMTRANS_FLAG_NOPLUGINS));
2ff057
2ff057
	if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
2ff057
	    argerror(_("no arguments given for verify"));
2ff057
	ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
2ff057
    }	break;
2ff057
#endif	/* IAM_RPMQV */
2ff057
2ff057
#if !defined(IAM_RPMQV)
2ff057
    case MODE_QUERY:
2ff057
    case MODE_VERIFY:
2ff057
#endif
2ff057
#if !defined(IAM_RPMEIU)
2ff057
    case MODE_INSTALL:
2ff057
    case MODE_ERASE:
2ff057
#endif
2ff057
    case MODE_UNKNOWN:
2ff057
	if (poptPeekArg(optCon) != NULL || argc <= 1) {
2ff057
	    printUsage(optCon, stderr, 0);
2ff057
	    ec = argc;
2ff057
	}
2ff057
	break;
2ff057
    }
2ff057
2ff057
    rpmtsFree(ts);
2ff057
    if (finishPipe())
2ff057
	ec = EXIT_FAILURE;
2ff057
2ff057
#ifdef	IAM_RPMQV
2ff057
    free(qva->qva_queryFormat);
2ff057
#endif
2ff057
2ff057
#ifdef	IAM_RPMEIU
2ff057
    if (ia->relocations != NULL) {
2ff057
	for (i = 0; i < ia->numRelocations; i++)
2ff057
	    free(ia->relocations[i].oldPath);
2ff057
	free(ia->relocations);
2ff057
    }
2ff057
#endif
2ff057
2ff057
    rpmcliFini(optCon);
2ff057
2ff057
    rpmlog(RPMLOG_DEBUG, "Exit status: %d\n", ec);
2ff057
2ff057
    return RETVAL(ec);
2ff057
}