Blame lib/poptALL.c

2ff057
/** \ingroup rpmcli
2ff057
 * \file lib/poptALL.c
2ff057
 *  Popt tables for all rpm modes.
2ff057
 */
2ff057
2ff057
#include "system.h"
2ff057
2ff057
#include <rpm/rpmcli.h>
2ff057
#include <rpm/rpmlib.h>		/* rpmEVR, rpmReadConfigFiles etc */
2ff057
#include <rpm/rpmlog.h>
2ff057
#include <rpm/rpmstring.h>
2ff057
#include <rpm/rpmfileutil.h>
2ff057
2ff057
#include "debug.h"
2ff057
2ff057
#define POPT_SHOWVERSION	-999
2ff057
#define POPT_SHOWRC		-998
2ff057
#define POPT_QUERYTAGS		-997
2ff057
#define POPT_PREDEFINE		-996
2ff057
#define POPT_DBPATH		-995
2ff057
#define POPT_UNDEFINE		-994
2ff057
#define POPT_PIPE		-993
2ff057
2ff057
static int _debug = 0;
2ff057
2ff057
extern int _rpmds_nopromote;
2ff057
2ff057
extern int _fsm_debug;
2ff057
2ff057
extern int _print_pkts;
2ff057
2ff057
extern int _psm_debug;
2ff057
2ff057
/* XXX avoid -lrpmbuild linkage. */
2ff057
       int _rpmfc_debug;
2ff057
2ff057
extern int _rpmts_stats;
2ff057
2ff057
const char * rpmcliPipeOutput = NULL;
2ff057
2ff057
const char * rpmcliRcfile = NULL;
2ff057
2ff057
const char * rpmcliRootDir = "/";
2ff057
2ff057
rpmQueryFlags rpmcliQueryFlags;
2ff057
2ff057
rpmVSFlags rpmcliVSFlags;
2ff057
2ff057
int rpmcliVfyLevelMask;
2ff057
2ff057
extern int _rpmio_debug;
2ff057
2ff057
static int rpmcliInitialized = -1;
2ff057
2ff057
/**
2ff057
 * Display rpm version.
2ff057
 */
2ff057
static void printVersion(FILE * fp)
2ff057
{
2ff057
    fprintf(fp, _("RPM version %s\n"), rpmEVR);
2ff057
}
2ff057
2ff057
/**
2ff057
 * Make sure that config files have been read.
2ff057
 * @warning Options like --rcfile and --verbose must precede callers option.
2ff057
 */
2ff057
void rpmcliConfigured(void)
2ff057
{
2ff057
2ff057
    if (rpmcliInitialized < 0)
2ff057
	rpmcliInitialized = rpmReadConfigFiles(rpmcliRcfile, NULL);
2ff057
    if (rpmcliInitialized)
2ff057
	exit(EXIT_FAILURE);
2ff057
}
2ff057
2ff057
static int cliDefine(const char *arg, int predefine)
2ff057
{
2ff057
    int rc;
2ff057
    char *s, *t;
2ff057
    /* XXX Convert '-' in macro name to underscore, skip leading %. */
2ff057
    s = t = xstrdup(arg);
2ff057
    while (*t && !risspace(*t)) {
2ff057
	if (*t == '-') *t = '_';
2ff057
	t++;
2ff057
    }
2ff057
    t = s;
2ff057
    if (*t == '%') t++;
2ff057
2ff057
    rc = rpmDefineMacro(NULL, t, RMIL_CMDLINE);
2ff057
    if (!predefine && rc == 0)
2ff057
	(void) rpmDefineMacro(rpmCLIMacroContext, t, RMIL_CMDLINE);
2ff057
2ff057
    free(s);
2ff057
    return rc;
2ff057
}
2ff057
2ff057
/**
2ff057
 */
2ff057
static void rpmcliAllArgCallback( poptContext con,
2ff057
                enum poptCallbackReason reason,
2ff057
                const struct poptOption * opt, const char * arg,
2ff057
                const void * data)
2ff057
{
2ff057
2ff057
    /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
2ff057
    if (opt->arg == NULL)
2ff057
    switch (opt->val) {
2ff057
    case 'q':
2ff057
	rpmSetVerbosity(RPMLOG_WARNING);
2ff057
	break;
2ff057
    case 'v':
2ff057
	rpmIncreaseVerbosity();
2ff057
	break;
2ff057
    case POPT_PREDEFINE:
2ff057
	if (cliDefine(arg, 1))
2ff057
	    exit(EXIT_FAILURE);
2ff057
	break;
2ff057
    case 'D':
2ff057
	rpmcliConfigured();
2ff057
	if (cliDefine(arg, 0))
2ff057
	    exit(EXIT_FAILURE);
2ff057
	break;
2ff057
    case POPT_UNDEFINE:
2ff057
	rpmcliConfigured();
2ff057
	if (*arg == '%')
2ff057
	    arg++;
2ff057
	rpmPopMacro(NULL, arg);
2ff057
	break;
2ff057
    case 'E':
2ff057
	rpmcliConfigured();
2ff057
	{   char *val = NULL;
2ff057
	    if (rpmExpandMacros(NULL, arg, &val, 0) < 0)
2ff057
		exit(EXIT_FAILURE);
2ff057
	    fprintf(stdout, "%s\n", val);
2ff057
	    free(val);
2ff057
	}
2ff057
	break;
2ff057
    case POPT_DBPATH:
2ff057
	rpmcliConfigured();
2ff057
	rpmPushMacro(NULL, "_dbpath", NULL, arg, RMIL_CMDLINE);
2ff057
	break;
2ff057
    case POPT_SHOWVERSION:
2ff057
	printVersion(stdout);
2ff057
	exit(EXIT_SUCCESS);
2ff057
	break;
2ff057
    case POPT_SHOWRC:
2ff057
	rpmcliConfigured();
2ff057
	(void) rpmShowRC(stdout);
2ff057
	exit(EXIT_SUCCESS);
2ff057
	break;
2ff057
    case POPT_QUERYTAGS:
2ff057
	rpmDisplayQueryTags(stdout);
2ff057
	exit(EXIT_SUCCESS);
2ff057
	break;
2ff057
    case POPT_PIPE:
2ff057
	if (rpmcliPipeOutput) {
2ff057
	    fprintf(stderr,
2ff057
		    _("%s: error: more than one --pipe specified "
2ff057
		      "(incompatible popt aliases?)\n"), xgetprogname());
2ff057
	    exit(EXIT_FAILURE);
2ff057
	}
2ff057
	rpmcliPipeOutput = xstrdup(arg);
2ff057
	break;
2ff057
	
2ff057
    case RPMCLI_POPT_NODIGEST:
2ff057
	rpmcliQueryFlags |= VERIFY_DIGEST;
2ff057
	rpmcliVSFlags |= RPMVSF_MASK_NODIGESTS;
2ff057
	rpmcliVfyLevelMask |= RPMSIG_DIGEST_TYPE;
2ff057
	break;
2ff057
2ff057
    case RPMCLI_POPT_NOSIGNATURE:
2ff057
	rpmcliQueryFlags |= VERIFY_SIGNATURE;
2ff057
	rpmcliVSFlags |= RPMVSF_MASK_NOSIGNATURES;
2ff057
	rpmcliVfyLevelMask |= RPMSIG_SIGNATURE_TYPE;
2ff057
	break;
2ff057
2ff057
    case RPMCLI_POPT_NOHDRCHK:
2ff057
	rpmcliQueryFlags |= VERIFY_HDRCHK;
2ff057
	rpmcliVSFlags |= RPMVSF_NOHDRCHK;
2ff057
	break;
2ff057
2ff057
    case RPMCLI_POPT_TARGETPLATFORM:
2ff057
	rpmcliInitialized = rpmReadConfigFiles(rpmcliRcfile, arg);
2ff057
	break;
2ff057
    }
2ff057
}
2ff057
2ff057
struct poptOption rpmcliAllPoptTable[] = {
2ff057
/* FIX: cast? */
2ff057
 { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
2ff057
        rpmcliAllArgCallback, 0, NULL, NULL },
2ff057
2ff057
 { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_debug, -1,
2ff057
        NULL, NULL },
2ff057
2ff057
 { "predefine", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_PREDEFINE,
2ff057
	N_("predefine MACRO with value EXPR"),
2ff057
	N_("'MACRO EXPR'") },
2ff057
 { "define", 'D', POPT_ARG_STRING, 0, 'D',
2ff057
	N_("define MACRO with value EXPR"),
2ff057
	N_("'MACRO EXPR'") },
2ff057
 { "undefine", '\0', POPT_ARG_STRING, 0, POPT_UNDEFINE,
2ff057
	N_("undefine MACRO"),
2ff057
	N_("MACRO") },
2ff057
 { "eval", 'E', POPT_ARG_STRING, 0, 'E',
2ff057
	N_("print macro expansion of EXPR"),
2ff057
	N_("'EXPR'") },
2ff057
 { "target", '\0', POPT_ARG_STRING, NULL,  RPMCLI_POPT_TARGETPLATFORM,
2ff057
        N_("Specify target platform"), N_("CPU-VENDOR-OS") },
2ff057
 { "macros", '\0', POPT_ARG_STRING, &macrofiles, 0,
2ff057
	N_("read <FILE:...> instead of default file(s)"),
2ff057
	N_("<FILE:...>") },
2ff057
2ff057
 /* XXX this is a bit out of place here but kinda unavoidable... */
2ff057
 { "noplugins", '\0', POPT_BIT_SET,
2ff057
	&rpmIArgs.transFlags, RPMTRANS_FLAG_NOPLUGINS,
2ff057
	N_("don't enable any plugins"), NULL },
2ff057
2ff057
 { "nodigest", '\0', 0, 0, RPMCLI_POPT_NODIGEST,
2ff057
        N_("don't verify package digest(s)"), NULL },
2ff057
 { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NOHDRCHK,
2ff057
        N_("don't verify database header(s) when retrieved"), NULL },
2ff057
 { "nosignature", '\0', 0, 0, RPMCLI_POPT_NOSIGNATURE,
2ff057
        N_("don't verify package signature(s)"), NULL },
2ff057
2ff057
 { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_PIPE,
2ff057
	N_("send stdout to CMD"),
2ff057
	N_("CMD") },
2ff057
 { "rcfile", '\0', POPT_ARG_STRING, &rpmcliRcfile, 0,
2ff057
	N_("read <FILE:...> instead of default file(s)"),
2ff057
	N_("<FILE:...>") },
2ff057
 { "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmcliRootDir, 0,
2ff057
	N_("use ROOT as top level directory"),
2ff057
	N_("ROOT") },
2ff057
 { "dbpath", '\0', POPT_ARG_STRING, 0, POPT_DBPATH,
2ff057
	N_("use database in DIRECTORY"),
2ff057
	N_("DIRECTORY") },
2ff057
2ff057
 { "querytags", '\0', 0, 0, POPT_QUERYTAGS,
2ff057
        N_("display known query tags"), NULL },
2ff057
 { "showrc", '\0', 0, NULL, POPT_SHOWRC,
2ff057
	N_("display final rpmrc and macro configuration"), NULL },
2ff057
 { "quiet", '\0', 0, NULL, 'q',
2ff057
	N_("provide less detailed output"), NULL},
2ff057
 { "verbose", 'v', 0, NULL, 'v',
2ff057
	N_("provide more detailed output"), NULL},
2ff057
 { "version", '\0', 0, NULL, POPT_SHOWVERSION,
2ff057
	N_("print the version of rpm being used"), NULL },
2ff057
2ff057
 { "promoteepoch", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_nopromote, 0,
2ff057
	NULL, NULL},
2ff057
2ff057
 { "fsmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_debug, -1,
2ff057
	N_("debug payload file state machine"), NULL},
2ff057
 { "prtpkts", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_print_pkts, -1,
2ff057
	NULL, NULL},
2ff057
 { "rpmfcdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfc_debug, -1,
2ff057
	NULL, NULL},
2ff057
 { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
2ff057
	N_("debug rpmio I/O"), NULL},
2ff057
 { "stats", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_stats, -1,
2ff057
	NULL, NULL},
2ff057
2ff057
   POPT_TABLEEND
2ff057
};
2ff057
2ff057
poptContext
2ff057
rpmcliFini(poptContext optCon)
2ff057
{
2ff057
    poptFreeContext(optCon);
2ff057
    rpmFreeMacros(NULL);
2ff057
    rpmFreeMacros(rpmCLIMacroContext);
2ff057
    rpmFreeRpmrc();
2ff057
    rpmlogClose();
2ff057
    rpmcliInitialized = -1;
2ff057
2ff057
    return NULL;
2ff057
}
2ff057
2ff057
poptContext
2ff057
rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
2ff057
{
2ff057
    poptContext optCon;
2ff057
    int rc;
2ff057
    const char *ctx, *execPath;
2ff057
2ff057
#if defined(ENABLE_NLS)
2ff057
    (void) setlocale(LC_ALL, "" );
2ff057
2ff057
    (void) bindtextdomain(PACKAGE, LOCALEDIR);
2ff057
    (void) textdomain(PACKAGE);
2ff057
#endif
2ff057
2ff057
    rpmSetVerbosity(RPMLOG_NOTICE);
2ff057
2ff057
    if (optionsTable == NULL) {
2ff057
	/* Read rpm configuration (if not already read). */
2ff057
	rpmcliConfigured();
2ff057
	return NULL;
2ff057
    }
2ff057
2ff057
    /* XXX hack to get popt working from build tree wrt lt-foo names */
2ff057
    ctx = rstreqn(xgetprogname(), "lt-", 3) ? xgetprogname() + 3 : xgetprogname();
2ff057
2ff057
    optCon = poptGetContext(ctx, argc, (const char **)argv, optionsTable, 0);
2ff057
    {
2ff057
	char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
2ff057
	(void) poptReadConfigFile(optCon, poptfile);
2ff057
	free(poptfile);
2ff057
    }
2ff057
    (void) poptReadDefaultConfig(optCon, 1);
2ff057
2ff057
    if ((execPath = getenv("RPM_POPTEXEC_PATH")) == NULL)
2ff057
	execPath = LIBRPMALIAS_EXECPATH;
2ff057
    poptSetExecPath(optCon, execPath, 1);
2ff057
2ff057
    /* Process all options, whine if unknown. */
2ff057
    while ((rc = poptGetNextOpt(optCon)) > 0) {
2ff057
	fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
2ff057
		xgetprogname(), rc);
2ff057
	exit(EXIT_FAILURE);
2ff057
    }
2ff057
2ff057
    if (rc < -1) {
2ff057
	fprintf(stderr, "%s: %s: %s\n", xgetprogname(),
2ff057
		poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
2ff057
		poptStrerror(rc));
2ff057
	exit(EXIT_FAILURE);
2ff057
    }
2ff057
2ff057
    /* Read rpm configuration (if not already read). */
2ff057
    rpmcliConfigured();
2ff057
2ff057
    if (_debug) {
2ff057
	rpmIncreaseVerbosity();
2ff057
	rpmIncreaseVerbosity();
2ff057
    }
2ff057
2ff057
    return optCon;
2ff057
}