コード例 #1
0
ファイル: verify.c プロジェクト: kaltsi/rpm
/**
 * Check file info from header against what's actually installed.
 * @param ts		transaction set
 * @param h		header to verify
 * @param omitMask	bits to disable verify checks
 * @param ghosts	should ghosts be verified?
 * @return		0 no problems, 1 problems found
 */
static int verifyHeader(rpmts ts, Header h, rpmVerifyAttrs omitMask, int ghosts)
{
    rpmVerifyAttrs verifyResult = 0;
    int ec = 0;		/* assume no problems */
    rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_FLAGS_VERIFY);

    rpmfiInit(fi, 0);
    while (rpmfiNext(fi) >= 0) {
	rpmfileAttrs fileAttrs = rpmfiFFlags(fi);
	char *buf = NULL, *attrFormat;
	char ac;
	int rc;

	/* If not verifying %ghost, skip ghost files. */
	if ((fileAttrs & RPMFILE_GHOST) && !ghosts)
	    continue;

	rc = rpmVerifyFile(ts, fi, &verifyResult, omitMask);

	/* Filter out timestamp differences of shared files */
	if (rc == 0 && (verifyResult & RPMVERIFY_MTIME)) {
	    rpmdbMatchIterator mi;
	    mi = rpmtsInitIterator(ts, RPMDBI_BASENAMES, rpmfiFN(fi), 0);
	    if (rpmdbGetIteratorCount(mi) > 1) 
		verifyResult &= ~RPMVERIFY_MTIME;
	    rpmdbFreeIterator(mi);
	}

	attrFormat = rpmFFlagsString(fileAttrs, "");
	ac = rstreq(attrFormat, "") ? ' ' : attrFormat[0];
	if (rc) {
	    if (!(fileAttrs & (RPMFILE_MISSINGOK|RPMFILE_GHOST)) || rpmIsVerbose()) {
		rasprintf(&buf, _("missing   %c %s"), ac, rpmfiFN(fi));
		if ((verifyResult & RPMVERIFY_LSTATFAIL) != 0 &&
		    errno != ENOENT) {
		    char *app;
		    rasprintf(&app, " (%s)", strerror(errno));
		    rstrcat(&buf, app);
		    free(app);
		}
		ec = rc;
	    }
	} else if (verifyResult || rpmIsVerbose()) {
	    char *verifyFormat = rpmVerifyString(verifyResult, ".");
	    rasprintf(&buf, "%s  %c %s", verifyFormat, ac, rpmfiFN(fi));
	    free(verifyFormat);

	    if (verifyResult) ec = 1;
	}
	free(attrFormat);

	if (buf) {
	    rpmlog(RPMLOG_NOTICE, "%s\n", buf);
	    buf = _free(buf);
	}
    }
    rpmfiFree(fi);
	
    return ec;
}
コード例 #2
0
ファイル: tbf.c プロジェクト: avokhmin/RPM5
static unsigned rpmbfWrite(FD_t fd, rpmbf * bfa, size_t npkgs)
{
    const char * fn = xstrdup(fdGetOPath(fd));
    struct stat sb;
    int ix;
    int xx;

    for (ix = 0; ix < (int) npkgs; ix++) {
	rpmbf bf = bfa[ix];
	static const char _bfmagic[] = "BFL3";
	const unsigned char * _bits = (bf ? bf->bits : NULL);
	uint32_t _n = (bf ? htonl(bf->n) : 0);
	uint32_t _m = (bf ? htonl(bf->m) : 0);
	uint32_t _k = (bf ? htonl(bf->k) : 0);

	if (bf && rpmIsVerbose())
	    fprintf(stderr, "\tbf[%d] %p {%u,%u}[%u] %u bytes\n", ix, bf, (unsigned)bf->n, (unsigned)bf->m, (unsigned)bf->k, (unsigned)(16 + (bf->m+7)/8));
	xx = Fwrite(_bfmagic, 1, 2, fd);
	xx = Fwrite(&_n, 1, sizeof(_n), fd);
	xx = Fwrite(&_m, 1, sizeof(_m), fd);
	xx = Fwrite(&_k, 1, sizeof(_m), fd);
	if (bf && bf->m > 0)
	    xx = Fwrite(bf->bits, 1, (bf->m+7)/8, fd);
    }
    xx = Fclose(fd);
    xx = Stat(fn, &sb);
    xx = Unlink(fn);

    return sb.st_size;
}
コード例 #3
0
ファイル: parsePrep.c プロジェクト: cmjonze/rpm5_tarballs
static void prepFetchVerbose(/*@unused@*/ struct Source *sp,
		/*@unused@*/ struct stat *st)
	/*@globals internalState @*/
	/*@modifies internalState @*/
{
    char *buf;
    size_t buf_len;
    int xx;
    int i;

    if (!(rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE)))
        return;
    buf_len = 2*80;
    if ((buf = (char *)malloc(buf_len)) == NULL)
        return;
    xx = snprintf(buf, buf_len, "%s%d:", (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num);
    for (i = (int)strlen(buf); i <= 11; i++)
        buf[i] = ' ';
    xx = snprintf(buf+i, buf_len-i, "%-52.52s", sp->source);
    i = (int)strlen(buf);
    if (st != NULL)
        xx = snprintf(buf+i, buf_len-i, " %9lu Bytes\n", (unsigned long)st->st_size);
    else
        xx = snprintf(buf+i, buf_len-i, "      ...MISSING\n");
    rpmlog(RPMLOG_NOTICE, "%s", buf);
    buf = _free(buf);
    return;
}
コード例 #4
0
ファイル: verify.c プロジェクト: xrg/RPM
int showVerifyPackage(QVA_t qva, rpmts ts, Header h)
{
    int ec = 0;
    int rc;

    if (qva->qva_flags & VERIFY_DEPS) {
	int save_noise = _rpmds_unspecified_epoch_noise;
	if (rpmIsVerbose())
	    _rpmds_unspecified_epoch_noise = 1;
	if ((rc = verifyDependencies(qva, ts, h)) != 0)
	    ec = rc;
	_rpmds_unspecified_epoch_noise = save_noise;
    }
    if (qva->qva_flags & VERIFY_FILES) {
	if ((rc = verifyHeader(qva, ts, h)) != 0)
	    ec = rc;
    }
    if ((qva->qva_flags & VERIFY_SCRIPT)
     && headerIsEntry(h, RPMTAG_VERIFYSCRIPT))
    {
	FD_t fdo = fdDup(STDOUT_FILENO);
	if ((rc = rpmVerifyScript(qva, ts, h, fdo)) != 0)
	    ec = rc;
	if (fdo != NULL)
	    rc = Fclose(fdo);
    }

    return ec;
}
コード例 #5
0
ファイル: rpmlua.c プロジェクト: cobexer/RPM5
static int rpm_verbose(lua_State *L)
/*@globals internalState @*/
/*@modifies L, internalState @*/
{
    lua_pushboolean(L, rpmIsVerbose());
    return 1;
}
コード例 #6
0
ファイル: rpminstall.c プロジェクト: rpm5/rpm
static void setNotifyFlag(struct rpmInstallArguments_s * ia,
			  rpmts ts)
{
    int notifyFlags;

    notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
    rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)notifyFlags));
}
コード例 #7
0
ファイル: verify.c プロジェクト: nforro/rpm
static const char * stateStr(rpmfileState fstate)
{
    switch (fstate) {
    case RPMFILE_STATE_NORMAL:
	return NULL;
    case RPMFILE_STATE_NOTINSTALLED:
	return rpmIsVerbose() ? _("not installed") : NULL;
    case RPMFILE_STATE_NETSHARED:
	return rpmIsVerbose() ? _("net shared") : NULL;
    case RPMFILE_STATE_WRONGCOLOR:
	return rpmIsVerbose() ? _("wrong color") : NULL;
    case RPMFILE_STATE_REPLACED:
	return _("replaced");
    case RPMFILE_STATE_MISSING:
	return _("no state");
    }
    return _("unknown state");
}
コード例 #8
0
ファイル: thkp.c プロジェクト: pombredanne/tools-yocto1-rpm
static rpmRC rpmhkpReadKeys(const char ** keyids)
{
    const char ** kip;
    rpmRC rc;
    int ec = 0;

    for (kip = keyids; *kip; kip++) {
	if (rpmIsVerbose())
	    fprintf(stderr, "=============== %s\n", *kip);
	rc = rpmhkpValidate(NULL, *kip);	/* XXX 0 on success */
	if (!rpmIsVerbose())
	    fprintf(stdout, "%-8s\t%s\n", rc2str(rc), *kip);
	if (rc)
	    ec++;
    }

    return ec;
}
コード例 #9
0
ファイル: rpmqv.c プロジェクト: avokhmin/RPM5
	/*@modifies fileSystem @*/
{
    fprintf(stderr, _("%s: %s\n"), __progname, desc);
    exit(EXIT_FAILURE);
}

#ifdef	DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */
static void printVersion(FILE * fp)
	/*@globals rpmEVR, fileSystem @*/
	/*@modifies *fp, fileSystem @*/
{
    fprintf(fp, "%s (" RPM_NAME ") %s\n", __progname, rpmEVR);
    if (rpmIsVerbose())
	fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n",
	    rpmlibVersion(), rpmlibTimestamp(), rpmlibVendor());
}
コード例 #10
0
ファイル: tagexts.c プロジェクト: Distrotech/rpm
static int verboseTag(Header h, rpmtd td, headerGetFlags hgflags)
{
    if (rpmIsVerbose()) {
	td->type = RPM_INT32_TYPE;
	td->count = 1;
	td->data = &(td->count);
	td->flags = RPMTD_NONE;
	return 1;
    } else {
	return 0;
    }
}
コード例 #11
0
ファイル: rpmqv.c プロジェクト: avokhmin/RPM5
static void printUsage(poptContext con, FILE * fp, int flags)
	/*@globals rpmEVR, fileSystem, internalState @*/
	/*@modifies *fp, fileSystem, internalState @*/
{
    printVersion(fp);
    fprintf(fp, "\n");

    if (rpmIsVerbose())
	poptPrintHelp(con, fp, flags);
    else
	poptPrintUsage(con, fp, flags);
}
コード例 #12
0
ファイル: tdir.c プロジェクト: avokhmin/RPM5
static void printDir(struct dirent * dp, off_t offset, int nentry)
{
    if (rpmIsDebug()) {
	unsigned d_off = 0;
#if !(defined(hpux) || defined(__hpux) || defined(sun) || defined(RPM_OS_AIX)) && \
    !defined(__APPLE__) && !defined(__FreeBSD_kernel__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
	d_off = (unsigned) dp->d_off,
#endif
	fprintf(stderr, "0x%08x %5d (0x%08x,0x%08x) 0x%04x ",
		(unsigned)offset, nentry,
		(unsigned) dp->d_ino, d_off, (unsigned) dp->d_reclen);
    }
    if (rpmIsVerbose()) {
	size_t nb = strlen(dp->d_name);
	if (!rpmIsDebug())
	    fprintf(stderr, "\t");
	fprintf(stderr, "%s%s\n", dp->d_name,
	    (dp->d_type == DT_DIR && dp->d_name[nb-1] != '/' ? "/" : ""));
    }
}
コード例 #13
0
ファイル: rpmchecksig.c プロジェクト: nforro/rpm
static int rpmpkgVerifySigs(rpmKeyring keyring, rpmVSFlags flags,
			   FD_t fd, const char *fn)
{
    int rc;
    if (rpmIsVerbose()) {
	rpmlog(RPMLOG_NOTICE, "%s:\n", fn);
	rc = rpmpkgRead(keyring, flags, fd, formatVerbose, NULL, NULL);
    } else {
	struct vfydata_s vd = { 0, 0 };
	rpmlog(RPMLOG_NOTICE, "%s:", fn);
	rc = rpmpkgRead(keyring, flags, fd, formatDefault, &vd, NULL);
	if (vd.seen & RPMSIG_DIGEST_TYPE) {
	    rpmlog(RPMLOG_NOTICE, " %s", (vd.bad & RPMSIG_DIGEST_TYPE) ?
					_("DIGESTS") : _("digests"));
	}
	if (vd.seen & RPMSIG_SIGNATURE_TYPE) {
	    rpmlog(RPMLOG_NOTICE, " %s", (vd.bad & RPMSIG_SIGNATURE_TYPE) ?
					_("SIGNATURES") : _("signatures"));
	}
	rpmlog(RPMLOG_NOTICE, " %s\n", rc ? _("NOT OK") : _("OK"));
    }
    return rc;
}
コード例 #14
0
ファイル: rpmchecksig.c プロジェクト: PerilousApricot/rpm
/* 
 * Format sigcheck result for output, appending the message spew to buf and
 * bad/missing keyids to keyprob.
 *
 * In verbose mode, just dump it all. Otherwise ok signatures
 * are dumped lowercase, bad sigs uppercase and for PGP/GPG
 * if misssing/untrusted key it's uppercase in parenthesis
 * and stash the key id as <SIGTYPE>#<keyid>. Pfft.
 */
static void formatResult(rpmTagVal sigtag, rpmRC sigres, const char *result,
			 char **keyprob, char **buf)
{
    char *msg = NULL;
    if (rpmIsVerbose()) {
	rasprintf(&msg, "    %s\n", result);
    } else { 
	/* Check for missing / untrusted keys in result. */
	const char *signame = sigtagname(sigtag, (sigres != RPMRC_OK));
	
	if (sigres == RPMRC_NOKEY || sigres == RPMRC_NOTTRUSTED) {
	    const char *tempKey = strstr(result, "ey ID");
	    if (tempKey) {
		char keyid[sizeof(pgpKeyID_t) + 1];
		rstrlcpy(keyid, tempKey + 6, sizeof(keyid));
		rstrscat(keyprob, " ", signame, "#", keyid, NULL);
	    }
	}
	rasprintf(&msg, (*keyprob ? "(%s) " : "%s "), signame);
    }
    rstrcat(buf, msg);
    free(msg);
}
コード例 #15
0
ファイル: tget.c プロジェクト: hahnakane/junkcode
static ssize_t tgetFill(rpmtget tget)
{
    char * b = tget->buf;
    size_t nb = tget->nbuf;
    ssize_t rc;

    if (tget->b != NULL && tget->nb > 0 && tget->b > tget->buf) {
	memmove(tget->buf, tget->b, tget->nb);
	b += tget->nb;
	nb -= tget->nb;
    }

    rc = Fread(b, 1, nb, tget->fd);
    if (Ferror(tget->fd))
	rc = -1;
    else if (rc > 0) {
	tget->nb += rc;
	if (rpmIsVerbose())
	    fwrite(b, 1, rc, stderr);
    }
    tget->b = tget->buf;

    return rc;
}
コード例 #16
0
ファイル: rpminstall.c プロジェクト: rpm5/rpm
int rpmInstallSource(rpmts ts, const char * arg,
		char ** specFilePtr, char ** cookie)
{
    FD_t fd;
    int rc;


    fd = Fopen(arg, "r.ufdio");
    if (fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("cannot open %s: %s\n"), arg, Fstrerror(fd));
	if (fd != NULL) (void) Fclose(fd);
	return 1;
    }

    if (rpmIsVerbose() && specFilePtr != NULL)
	fprintf(stdout, _("Installing %s\n"), arg);

    {
	rpmVSFlags ovsflags =
		rpmtsSetVSFlags(ts, (specFilePtr) ? (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD) : rpmtsVSFlags(ts));
	rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie);
	rc = (rpmrc == RPMRC_OK ? 0 : 1);
	rpmtsSetVSFlags(ts, ovsflags);
    }
    if (rc != 0) {
	rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), arg);
	if (specFilePtr && *specFilePtr)
	    *specFilePtr = _free(*specFilePtr);
	if (cookie && *cookie)
	    *cookie = _free(*cookie);
    }

    (void) Fclose(fd);

    return rc;
}
コード例 #17
0
ファイル: tglob.c プロジェクト: avokhmin/RPM5
static int printGlob(const char * path)
{
    rpmop op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
    glob_t gl = { .gl_pathc = 0, .gl_pathv = NULL, .gl_offs = 0 };
    int rc;
    int xx;

fprintf(stderr, "===== %s\n", path);
    xx = rpmswEnter(op, 0);
    gl.gl_pathc = 0;
    gl.gl_pathv = NULL;
    gl.gl_offs = 0;
    rc = Glob(path, 0, my_Glob_error, &gl);
    if (rc != 0) {
fprintf(stderr, "*** Glob rc %d\n", rc);
    } else
    if (rpmIsVerbose()) {
	int i;
	for (i = 0; i < (int)gl.gl_pathc; i++)
	    fprintf(stderr, "%5d %s\n", i, gl.gl_pathv[i]);
    }
    Globfree(&gl);
    xx = rpmswExit(op, 0);

    if (_rpmsw_stats)
	rpmswPrint("glob:", op, NULL);
    return rc;
}

static struct poptOption optionsTable[] = {
 { "debug", 'd', POPT_ARG_VAL,	&__debug, -1,		NULL, NULL },

 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
	N_("Common options for all rpmio executables:"),
	NULL },

  POPT_AUTOHELP
  POPT_TABLEEND
};

int
main(int argc, char *argv[])
{
    poptContext optCon = rpmioInit(argc, argv, optionsTable);
    ARGV_t av;
    int ac;
    const char * dn;
    int rc = 0;

    if (__debug) {
_av_debug = -1;
_dav_debug = -1;
_ftp_debug = -1;
_url_debug = -1;
_rpmio_debug = -1;
    }

    av = poptGetArgs(optCon);
    ac = argvCount(av);
    if (ac < 1) {
	poptPrintUsage(optCon, stderr, 0);
	goto exit;
    }

    while (rc == 0 && (dn = *av++) != NULL)
	rc = printGlob(dn);

exit:

    optCon = rpmioFini(optCon);

    return rc;
}
コード例 #18
0
ファイル: rpmqv.c プロジェクト: avokhmin/RPM5
int main(int argc, const char ** argv)
#endif
	/*@globals rpmEVR, RPMVERSION,
		rpmGlobalMacroContext, rpmCLIMacroContext,
		h_errno, fileSystem, internalState@*/
	/*@modifies fileSystem, internalState@*/
{
    poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable);

    rpmts ts = NULL;
    enum modes bigMode = MODE_UNKNOWN;

#if defined(IAM_RPMQV)
    QVA_t qva = &rpmQVKArgs;
#endif

#ifdef	IAM_RPMBT
    BTA_t ba = &rpmBTArgs;
#endif

#ifdef	IAM_RPMEIU
    QVA_t ia = &rpmIArgs;
#endif

#if defined(IAM_RPMDB)
    QVA_t da = &rpmDBArgs;
#endif

#if defined(IAM_RPMK)
    QVA_t ka = &rpmQVKArgs;
#endif

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
    char * passPhrase = "";
#endif

    pid_t pipeChild = 0;
    int ec = 0;
    int status;
    int p[2];
#ifdef	IAM_RPMEIU
    int xx;
#endif
	
#if !defined(__GLIBC__) && !defined(__LCLINT__)
    environ = envp;
#else
/* XXX limit the fiddle up to linux for now. */
#if !defined(HAVE_SETPROCTITLE) && defined(__linux__)
    (void) initproctitle(argc, (char **)argv, environ);
#endif
#endif  

    /* Set the major mode based on argv[0] */
    /*@-nullpass@*/
#ifdef	IAM_RPMBT
    if (!strcmp(__progname, "rpmb"))	bigMode = MODE_BUILD;
    if (!strcmp(__progname, "lt-rpmb"))	bigMode = MODE_BUILD;
    if (!strcmp(__progname, "rpmt"))	bigMode = MODE_TARBUILD;
    if (!strcmp(__progname, "rpmbuild"))	bigMode = MODE_BUILD;
#endif
#ifdef	IAM_RPMQV
    if (!strcmp(__progname, "rpmq"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "lt-rpmq"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "rpmv"))	bigMode = MODE_VERIFY;
    if (!strcmp(__progname, "rpmquery"))	bigMode = MODE_QUERY;
    if (!strcmp(__progname, "rpmverify"))	bigMode = MODE_VERIFY;
#endif
#ifdef	RPMEIU
    if (!strcmp(__progname, "rpme"))	bigMode = MODE_ERASE;
    if (!strcmp(__progname, "rpmi"))	bigMode = MODE_INSTALL;
    if (!strcmp(__progname, "lt-rpmi"))	bigMode = MODE_INSTALL;
    if (!strcmp(__progname, "rpmu"))	bigMode = MODE_INSTALL;
#endif
    /*@=nullpass@*/

#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_CHECKSIG:	qva->qva_mode = 'K';	break;
    case MODE_RESIGN:	qva->qva_mode = 'R';	break;
    case MODE_INSTALL:
    case MODE_ERASE:
    case MODE_BUILD:
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    case MODE_TARBUILD:
    case MODE_REBUILDDB:
    case MODE_UNKNOWN:
    default:
	break;
    }
#endif

    rpmcliConfigured();

#ifdef	IAM_RPMBT
    switch (ba->buildMode) {
    case 'b':	bigMode = MODE_BUILD;		break;
    case 't':	bigMode = MODE_TARBUILD;	break;
    case 'B':	bigMode = MODE_REBUILD;		break;
    case 'C':	bigMode = MODE_RECOMPILE;	break;
    }

    if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
	bigMode = MODE_BUILD;

    if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
	bigMode = MODE_BUILD;
#endif	/* IAM_RPMBT */
    
#ifdef	IAM_RPMDB
  if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
    if (da->rebuild) {
	if (bigMode != MODE_UNKNOWN) 
	    argerror(_("only one major mode may be specified"));
	else
	    bigMode = MODE_REBUILDDB;
    }
  }
#endif	/* IAM_RPMDB */

#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 > 2)
	    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 */

#ifdef	IAM_RPMK
  if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
	switch (ka->qva_mode) {
	case RPMSIGN_NONE:
	    ka->sign = 0;
	    break;
	case RPMSIGN_IMPORT_PUBKEY:
	case RPMSIGN_CHK_SIGNATURE:
	    bigMode = MODE_CHECKSIG;
	    ka->sign = 0;
	    break;
	case RPMSIGN_ADD_SIGNATURE:
	case RPMSIGN_NEW_SIGNATURE:
	case RPMSIGN_DEL_SIGNATURE:
	    bigMode = MODE_RESIGN;
	    ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE);
	    break;
	}
  }
#endif	/* IAM_RPMK */

#if defined(IAM_RPMEIU)
    if (!( bigMode == MODE_INSTALL ) &&
(ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
	argerror(_("only installation, upgrading, rmsource and rmspec 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->qva_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->qva_prefix)
	argerror(_("--prefix may only be used when installing new packages"));

    if (ia->qva_prefix && ia->qva_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 ((ia->installInterfaceFlags & INSTALL_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 &&
	(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 &&
	(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 "
		   "building, rebuilding, recompilation, installation, "
		   "erasure, and verification"));

    if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
	argerror(_("--test may only be specified during package installation, "
		 "erasure, and building"));
#endif	/* IAM_RPMEIU */

    if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
	argerror(_("--root (-r) may only be specified during "
		 "installation, erasure, querying, and "
		 "database rebuilds"));

    if (rpmioRootDir) {
	switch (urlIsURL(rpmioRootDir)) {
	default:
	    if (bigMode & MODES_FOR_ROOT)
		break;
	    /*@fallthrough@*/
	case URL_IS_UNKNOWN:
	    if (rpmioRootDir[0] != '/')
		argerror(_("arguments to --root (-r) must begin with a /"));
	    break;
	}
    }

#if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
    integrity_check(__progname, bigMode);
#endif

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
    if (0
#if defined(IAM_RPMBT)
    || ba->sign 
#endif
#if defined(IAM_RPMK)
    || ka->sign
#endif
    )
    /*@-branchstate@*/
    {
        if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
	    bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD)
	{
	    const char ** av;
	    struct stat sb;
	    int errors = 0;

	    if ((av = poptGetArgs(optCon)) == NULL) {
		fprintf(stderr, _("no files to sign\n"));
		errors++;
	    } else
	    while (*av) {
		if (Stat(*av, &sb)) {
		    fprintf(stderr, _("cannot access file %s\n"), *av);
		    errors++;
		}
		av++;
	    }

	    if (errors) {
		ec = errors;
		goto exit;
	    }

	
            if (poptPeekArg(optCon)
#if defined(IAM_RPMBT)
	    && !ba->nopassword 
#endif
#if defined(IAM_RPMK)
	    && !ka->nopassword
#endif
	    )
	    {
		passPhrase = Getpass(_("Enter pass phrase: "));
		if (rpmCheckPassPhrase(passPhrase)) {
		    fprintf(stderr, _("Pass phrase check failed\n"));
		    ec = EXIT_FAILURE;
		    goto exit;
		}
		fprintf(stderr, _("Pass phrase is good.\n"));
		/* XXX Getpass() should realloc instead. */
		passPhrase = xstrdup(passPhrase);
	    }
	}
    }
    /*@=branchstate@*/
#endif	/* IAM_RPMBT || IAM_RPMK */

    if (rpmioPipeOutput) {
	if (pipe(p) < 0) {
	    fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
	    goto exit;
	}

	if (!(pipeChild = fork())) {
	    (void) close(p[1]);
	    (void) dup2(p[0], STDIN_FILENO);
	    (void) close(p[0]);
	    (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL);
	    fprintf(stderr, _("exec failed\n"));
	}

	(void) close(p[0]);
	(void) dup2(p[1], STDOUT_FILENO);
	(void) close(p[1]);
    }
	
    ts = rpmtsCreate();
    (void) rpmtsSetRootDir(ts, rpmioRootDir);
    switch (bigMode) {
#ifdef	IAM_RPMDB
    case MODE_REBUILDDB:
    {   rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
	rpmVSFlags ovsflags;
	if (rpmcliQueryFlags & VERIFY_DIGEST)
	    vsflags |= _RPMVSF_NODIGESTS;
	if (rpmcliQueryFlags & VERIFY_SIGNATURE)
	    vsflags |= _RPMVSF_NOSIGNATURES;
	ovsflags = rpmtsSetVSFlags(ts, vsflags);
	ec = rpmtsRebuildDB(ts);
	vsflags = rpmtsSetVSFlags(ts, ovsflags);
    }	break;
#endif	/* IAM_RPMDB */

#ifdef	IAM_RPMBT
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    {	const char * pkg;
	int nbuilds = 0;

        while (!rpmIsVerbose())
	    rpmIncreaseVerbosity();

	if (!poptPeekArg(optCon))
	    argerror(_("no packages files given for rebuild"));

	ba->buildAmount =
	    RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
	if (bigMode == MODE_REBUILD) {
	    ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
	    ba->buildAmount |= RPMBUILD_RMSOURCE;
	    ba->buildAmount |= RPMBUILD_RMSPEC;
	    ba->buildAmount |= RPMBUILD_CLEAN;
	    ba->buildAmount |= RPMBUILD_RMBUILD;
	}

	while ((pkg = poptGetArg(optCon))) {
	    if (nbuilds++ > 0) {
		rpmFreeMacros(NULL);
		rpmFreeRpmrc();
		(void) rpmReadConfigFiles(NULL, NULL);
	    }
	    ba->specFile = NULL;
	    ba->cookie = NULL;
	    ec = rpmInstallSource(ts, pkg, &ba->specFile, &ba->cookie);
	    if (ec == 0) {
		ba->rootdir = rpmioRootDir;
		ba->passPhrase = passPhrase;
		ec = build(ts, ba, NULL);
	    }
	    ba->cookie = _free(ba->cookie);
	    ba->specFile = _free(ba->specFile);

	    if (ec)
		/*@loopbreak@*/ break;
	}

    }	break;

    case MODE_BUILD:
    case MODE_TARBUILD:
    {	int nbuilds = 0;

#if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */
	if (ba->buildChar != 't' && ba->buildChar != 'f')
#endif
        while (!rpmIsVerbose())
	    rpmIncreaseVerbosity();
       
	switch (ba->buildChar) {
	case 'a':
	    ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
	    /*@fallthrough@*/
	case 'b':
	    ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
	    ba->buildAmount |= RPMBUILD_CLEAN;
#if defined(RPM_VENDOR_MANDRIVA)
	    if ((ba->buildChar == 'a' || ba->buildChar == 'b') && ba->shortCircuit)
#else
	    if ((ba->buildChar == 'b') && ba->shortCircuit)
#endif
		/*@innerbreak@*/ break;
	    /*@fallthrough@*/
	case 'i':
	    ba->buildAmount |= RPMBUILD_INSTALL;
	    ba->buildAmount |= RPMBUILD_CHECK;
	    if ((ba->buildChar == 'i') && ba->shortCircuit)
		/*@innerbreak@*/ break;
	    /*@fallthrough@*/
	case 'c':
	    ba->buildAmount |= RPMBUILD_BUILD;
	    if ((ba->buildChar == 'c') && ba->shortCircuit)
		/*@innerbreak@*/ break;
	    /*@fallthrough@*/
	case 'p':
	    ba->buildAmount |= RPMBUILD_PREP;
	    /*@innerbreak@*/ break;
	    
	case 'l':
	    ba->buildAmount |= RPMBUILD_FILECHECK;
	    /*@innerbreak@*/ break;
	case 's':
	    ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
#if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */
	    /* enforce no dependency checking when rolling a source RPM */
	    ba->noDeps = 1;
#endif
	    /*@innerbreak@*/ break;
	case 't':	/* support extracting the "%track" script/section */
	    ba->buildAmount |= RPMBUILD_TRACK;
	    /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */
	    ba->noDeps = 1;
	    rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE);
	    rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE);
	    rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE);
	    /*@innerbreak@*/ break;
	case 'f':
	    ba->buildAmount |= RPMBUILD_FETCHSOURCE;
	    ba->noDeps = 1;
	    /*@innerbreak@*/ break;
	}

	if (!poptPeekArg(optCon)) {
	    if (bigMode == MODE_BUILD)
		argerror(_("no spec files given for build"));
	    else
		argerror(_("no tar files given for build"));
	}

	while ((ba->specFile = poptGetArg(optCon))) {
	    if (nbuilds++ > 0) {
		rpmFreeMacros(NULL);
		rpmFreeRpmrc();
		(void) rpmReadConfigFiles(NULL, NULL);
	    }
	    ba->rootdir = rpmioRootDir;
	    ba->passPhrase = passPhrase;
	    ba->cookie = NULL;
	    ec = build(ts, ba, NULL);
	    if (ec)
		/*@loopbreak@*/ break;
	}
    }	break;
#endif	/* IAM_RPMBT */

#ifdef	IAM_RPMEIU
    case MODE_ERASE:
	ia->depFlags = global_depFlags;
	if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;

	if (!poptPeekArg(optCon)) {
	    if (ia->rbtid == 0)
		argerror(_("no packages given for erase"));
ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
ia->rbCheck = rpmcliInstallCheck;
ia->rbOrder = rpmcliInstallOrder;
ia->rbRun = rpmcliInstallRun;
	    ec += rpmRollback(ts, ia, NULL);
	} else {
	    ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon));
	}
	break;

    case MODE_INSTALL:

	/* RPMTRANS_FLAG_KEEPOBSOLETE */

	ia->depFlags = global_depFlags;
	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) */
	/*@-branchstate@*/
	if (ia->qva_prefix) {
	    xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
			NULL, ia->qva_prefix);
	    xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
			NULL, NULL);
	} else if (ia->relocations) {
	    xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
			NULL, NULL);
	}
	/*@=branchstate@*/

	if (!poptPeekArg(optCon)) {
	    if (ia->rbtid == 0)
		argerror(_("no packages given for install"));
ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
ia->rbCheck = rpmcliInstallCheck;
ia->rbOrder = rpmcliInstallOrder;
ia->rbRun = rpmcliInstallRun;
/*@i@*/	    ec += rpmRollback(ts, ia, NULL);
	} else {
	    /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */
	    ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon));
	    /*@=compdef =compmempass@*/
	}
	break;

#endif	/* IAM_RPMEIU */

#ifdef	IAM_RPMQV
    case MODE_QUERY:
	if (!poptPeekArg(optCon)
	 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
	    argerror(_("no arguments given for query"));

	qva->depFlags = global_depFlags;
	qva->qva_specQuery = rpmspecQuery;
	ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
	qva->qva_specQuery = NULL;
	break;

    case MODE_VERIFY:
    {	rpmVerifyFlags verifyFlags = VERIFY_ALL;

	qva->depFlags = global_depFlags;
	verifyFlags &= ~qva->qva_flags;
	qva->qva_flags = (rpmQueryFlags) verifyFlags;

	if (!poptPeekArg(optCon)
	 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
	    argerror(_("no arguments given for verify"));
	ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon));
    }	break;
#endif	/* IAM_RPMQV */

#ifdef IAM_RPMK
    case MODE_CHECKSIG:
    {	rpmVerifyFlags verifyFlags =
		(VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE);

	verifyFlags &= ~ka->qva_flags;
	ka->qva_flags = (rpmQueryFlags) verifyFlags;
    }   /*@fallthrough@*/
    case MODE_RESIGN:
	if (!poptPeekArg(optCon))
	    argerror(_("no arguments given"));
	ka->passPhrase = passPhrase;
	ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon));
    	break;
#endif	/* IAM_RPMK */
	
#if !defined(IAM_RPMQV)
    case MODE_QUERY:
    case MODE_VERIFY:
#endif
#if !defined(IAM_RPMK)
    case MODE_CHECKSIG:
    case MODE_RESIGN:
#endif
#if !defined(IAM_RPMDB)
    case MODE_REBUILDDB:
#endif
#if !defined(IAM_RPMBT)
    case MODE_BUILD:
    case MODE_REBUILD:
    case MODE_RECOMPILE:
    case MODE_TARBUILD:
#endif
#if !defined(IAM_RPMEIU)
    case MODE_INSTALL:
    case MODE_ERASE:
#endif
    case MODE_UNKNOWN:
#ifdef	DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */
	if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
	    printUsage(optCon, stderr, 0);
	    ec = argc;
	}
#endif
	break;
    }

#if defined(IAM_RPMBT) || defined(IAM_RPMK)
exit:
#endif	/* IAM_RPMBT || IAM_RPMK */

    (void)rpmtsFree(ts); 
    ts = NULL;

    if (pipeChild) {
	(void) fclose(stdout);
	(void) waitpid(pipeChild, &status, 0);
    }

#ifdef	IAM_RPMQV
    qva->qva_queryFormat = _free(qva->qva_queryFormat);
#endif

#ifdef	IAM_RPMBT
    freeNames();
    /* XXX _specPool/_pkgPool teardown should be done somewhere else. */
    {	extern rpmioPool _pkgPool;
	extern rpmioPool _specPool;
	_pkgPool = rpmioFreePool(_pkgPool);
	_specPool = rpmioFreePool(_specPool);
    }
#endif

#ifdef	IAM_RPMEIU
    ia->relocations = rpmfiFreeRelocations(ia->relocations);
#endif

    optCon = rpmcliFini(optCon);

/* XXX limit the fiddle up to linux for now. */
#if !defined(HAVE_SETPROCTITLE) && defined(__linux__)
    (void) finiproctitle();
#endif

    /* XXX don't overflow single byte exit status */
    /* XXX status 255 is special to xargs(1) */
    if (ec > 254) ec = 254;

     rpmlog(RPMLOG_DEBUG, D_("exit code: %d\n"), ec);

    /*@-globstate@*/
    return ec;
    /*@=globstate@*/
}
コード例 #19
0
ファイル: rpminstall.c プロジェクト: rpm5/rpm
/** @todo Generalize --freshen policies. */
int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
{
    struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu));
    rpmRelocation * relocations;
    char * fileURL = NULL;
    rpmVSFlags vsflags, ovsflags;
    int rc;
    int i;

    vsflags = setvsFlags(ia);
    ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));

    if (fileArgv == NULL) goto exit;

    (void) rpmtsSetFlags(ts, ia->transFlags);

    relocations = ia->relocations;

    setNotifyFlag(ia, ts); 

    if ((eiu->relocations = relocations) != NULL) {
	while (eiu->relocations->oldPath)
	    eiu->relocations++;
	if (eiu->relocations->newPath == NULL)
	    eiu->relocations = NULL;
    }

    /* Build fully globbed list of arguments in argv[argc]. */
    for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
    	ARGV_t av = NULL;
    	int ac = 0;

	if (giFlags & RPMGI_NOGLOB) {
	    rc = rpmNoGlob(*eiu->fnp, &ac, &av);
	} else {
	    char * fn = rpmEscapeSpaces(*eiu->fnp);
	    rc = rpmGlob(fn, &ac, &av);
	    fn = _free(fn);
	}
	if (rc || ac == 0) {
	    if (giFlags & RPMGI_NOGLOB) {
		rpmlog(RPMLOG_ERR, _("File not found: %s\n"), *eiu->fnp);
	    } else {
		rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
	    }
	    eiu->numFailed++;
	    continue;
	}

	argvAppend(&(eiu->argv), av);
	argvFree(av);
	eiu->argc += ac;
    }

restart:
    /* Allocate sufficient storage for next set of args. */
    if (eiu->pkgx >= eiu->numPkgs) {
	eiu->numPkgs = eiu->pkgx + eiu->argc;
	eiu->pkgURL = xrealloc(eiu->pkgURL,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
	memset(eiu->pkgURL + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
	eiu->pkgState = xrealloc(eiu->pkgState,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
	memset(eiu->pkgState + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgState)));
    }

    /* Retrieve next set of args, cache on local storage. */
    for (i = 0; i < eiu->argc; i++) {
	fileURL = _free(fileURL);
	fileURL = eiu->argv[i];
	eiu->argv[i] = NULL;

	switch (urlIsURL(fileURL)) {
	case URL_IS_HTTPS:
	case URL_IS_HTTP:
	case URL_IS_FTP:
	{   char *tfn = NULL;
	    FD_t tfd;

	    if (rpmIsVerbose())
		fprintf(stdout, _("Retrieving %s\n"), fileURL);

	    tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn);
	    if (tfd && tfn) {
		Fclose(tfd);
	    	rc = urlGetFile(fileURL, tfn);
	    } else {
		rc = -1;
	    }

	    if (rc != 0) {
		rpmlog(RPMLOG_ERR,
			_("skipping %s - transfer failed\n"), fileURL);
		eiu->numFailed++;
		eiu->pkgURL[eiu->pkgx] = NULL;
		tfn = _free(tfn);
		break;
	    }
	    eiu->pkgState[eiu->pkgx] = 1;
	    eiu->pkgURL[eiu->pkgx] = tfn;
	    eiu->pkgx++;
	}   break;
	case URL_IS_PATH:
	case URL_IS_DASH:	/* WRONG WRONG WRONG */
	case URL_IS_HKP:	/* WRONG WRONG WRONG */
	default:
	    eiu->pkgURL[eiu->pkgx] = fileURL;
	    fileURL = NULL;
	    eiu->pkgx++;
	    break;
	}
    }
    fileURL = _free(fileURL);

    if (eiu->numFailed) goto exit;

    /* Continue processing file arguments, building transaction set. */
    for (eiu->fnp = eiu->pkgURL+eiu->prevx;
	 *eiu->fnp != NULL;
	 eiu->fnp++, eiu->prevx++)
    {
	Header h = NULL;
	const char * fileName;

	rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp);
	(void) urlPath(*eiu->fnp, &fileName);

	if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL)
	    continue;

	if (eiu->rpmrc == RPMRC_NOTFOUND) {
	    rc = tryReadManifest(eiu);
	    if (rc == RPMRC_OK) {
	        eiu->prevx++;
	        goto restart;
	    }
	}

	if (headerIsSource(h)) {
	    if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
		headerFree(h);
	        continue;
	    }
	    rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n",
		eiu->numSRPMS);
	    eiu->sourceURL = xrealloc(eiu->sourceURL,
				(eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
	    eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
	    *eiu->fnp = NULL;
	    eiu->numSRPMS++;
	    eiu->sourceURL[eiu->numSRPMS] = NULL;
	    continue;
	}

	if (eiu->relocations) {
	    struct rpmtd_s prefixes;

	    headerGet(h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT);
	    if (rpmtdCount(&prefixes) == 1) {
		eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes));
		rpmtdFreeData(&prefixes);
	    } else {
		rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"),
		       headerGetString(h, RPMTAG_NAME));
		eiu->numFailed++;
		goto exit;
	    }
	}

	if (ia->installInterfaceFlags & INSTALL_FRESHEN)
	    if (checkFreshenStatus(ts, h) != 1) {
		headerFree(h);
	        continue;
	    }

	if (ia->installInterfaceFlags & INSTALL_REINSTALL)
	    rc = rpmtsAddReinstallElement(ts, h, (fnpyKey)fileName);
	else
	    rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName,
			(ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
			relocations);

	headerFree(h);
	if (eiu->relocations)
	    eiu->relocations->oldPath = _free(eiu->relocations->oldPath);

	switch (rc) {
	case 0:
	    rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n",
			eiu->numRPMS);
	    break;
	case 1:
	    rpmlog(RPMLOG_ERR,
			    _("error reading from file %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	default:
	    eiu->numFailed++;
	    goto exit;
	    break;
	}

	eiu->numRPMS++;
    }

    rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n",
		eiu->numSRPMS, eiu->numRPMS);

    if (eiu->numFailed) goto exit;

    if (eiu->numRPMS) {
        int rc = rpmcliTransaction(ts, ia, eiu->numPkgs);
        if (rc < 0)
            eiu->numFailed += eiu->numRPMS;
	else if (rc > 0)
            eiu->numFailed += rc;
    }

    if (eiu->numSRPMS && (eiu->sourceURL != NULL)) {
	rpmcliProgressState = 0;
	rpmcliProgressTotal = 0;
	rpmcliProgressCurrent = 0;
	for (i = 0; i < eiu->numSRPMS; i++) {
	    rpmsqPoll();
	    if (eiu->sourceURL[i] != NULL) {
	        rc = RPMRC_OK;
		if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST))
		    rc = rpmInstallSource(ts, eiu->sourceURL[i], NULL, NULL);
		if (rc != 0)
		    eiu->numFailed++;
	    }
	}
    }

exit:
    if (eiu->pkgURL != NULL) {
        for (i = 0; i < eiu->numPkgs; i++) {
	    if (eiu->pkgURL[i] == NULL) continue;
	    if (eiu->pkgState[i] == 1)
	        (void) unlink(eiu->pkgURL[i]);
	    eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
	}
    }
    eiu->pkgState = _free(eiu->pkgState);
    eiu->pkgURL = _free(eiu->pkgURL);
    eiu->argv = _free(eiu->argv);
    rc = eiu->numFailed;
    free(eiu);

    rpmtsEmpty(ts);
    rpmtsSetVSFlags(ts, ovsflags);

    return rc;
}
コード例 #20
0
ファイル: rpminstall.c プロジェクト: xrg/RPM
/** @todo Generalize --freshen policies. */
int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
{
    struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu));
    rpmps ps;
    rpmprobFilterFlags probFilter;
    rpmRelocation * relocations;
    char * fileURL = NULL;
    int stopInstall = 0;
    rpmVSFlags vsflags, ovsflags, tvsflags;
    int rc;
    int xx;
    int i;

    if (fileArgv == NULL) goto exit;

    rpmcliPackagesTotal = 0;

    (void) rpmtsSetFlags(ts, ia->transFlags);

    probFilter = ia->probFilter;
    relocations = ia->relocations;

    if (ia->installInterfaceFlags & INSTALL_UPGRADE)
	vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
    else
	vsflags = rpmExpandNumeric("%{?_vsflags_install}");
    if (ia->qva_flags & VERIFY_DIGEST)
	vsflags |= _RPMVSF_NODIGESTS;
    if (ia->qva_flags & VERIFY_SIGNATURE)
	vsflags |= _RPMVSF_NOSIGNATURES;
    if (ia->qva_flags & VERIFY_HDRCHK)
	vsflags |= RPMVSF_NOHDRCHK;
    ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));

    {	int notifyFlags;
	notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
	xx = rpmtsSetNotifyCallback(ts,
			rpmShowProgress, (void *) ((long)notifyFlags));
    }

    if ((eiu->relocations = relocations) != NULL) {
	while (eiu->relocations->oldPath)
	    eiu->relocations++;
	if (eiu->relocations->newPath == NULL)
	    eiu->relocations = NULL;
    }

    /* Build fully globbed list of arguments in argv[argc]. */
    for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
    	ARGV_t av = NULL;
    	int ac = 0;
	char * fn;

	fn = rpmEscapeSpaces(*eiu->fnp);
	rc = rpmGlob(fn, &ac, &av);
	fn = _free(fn);
	if (rc || ac == 0) {
	    rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    continue;
	}

	argvAppend(&(eiu->argv), av);
	argvFree(av);
	eiu->argc += ac;
    }

restart:
    /* Allocate sufficient storage for next set of args. */
    if (eiu->pkgx >= eiu->numPkgs) {
	eiu->numPkgs = eiu->pkgx + eiu->argc;
	eiu->pkgURL = xrealloc(eiu->pkgURL,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
	memset(eiu->pkgURL + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
	eiu->pkgState = xrealloc(eiu->pkgState,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
	memset(eiu->pkgState + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgState)));
    }

    /* Retrieve next set of args, cache on local storage. */
    for (i = 0; i < eiu->argc; i++) {
	fileURL = _free(fileURL);
	fileURL = eiu->argv[i];
	eiu->argv[i] = NULL;

	switch (urlIsURL(fileURL)) {
	case URL_IS_HTTPS:
	case URL_IS_HTTP:
	case URL_IS_FTP:
	{   char *tfn;
	    FD_t tfd;

	    if (rpmIsVerbose())
		fprintf(stdout, _("Retrieving %s\n"), fileURL);

	    tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn);
	    if (tfd && tfn) {
		Fclose(tfd);
	    	rc = urlGetFile(fileURL, tfn);
	    } else {
		rc = -1;
	    }

	    if (rc != 0) {
		rpmlog(RPMLOG_ERR,
			_("skipping %s - transfer failed\n"), fileURL);
		eiu->numFailed++;
		eiu->pkgURL[eiu->pkgx] = NULL;
		tfn = _free(tfn);
		break;
	    }
	    eiu->pkgState[eiu->pkgx] = 1;
	    eiu->pkgURL[eiu->pkgx] = tfn;
	    eiu->pkgx++;
	}   break;
	case URL_IS_PATH:
	case URL_IS_DASH:	/* WRONG WRONG WRONG */
	case URL_IS_HKP:	/* WRONG WRONG WRONG */
	default:
	    eiu->pkgURL[eiu->pkgx] = fileURL;
	    fileURL = NULL;
	    eiu->pkgx++;
	    break;
	}
    }
    fileURL = _free(fileURL);

    if (eiu->numFailed) goto exit;

    /* Continue processing file arguments, building transaction set. */
    for (eiu->fnp = eiu->pkgURL+eiu->prevx;
	 *eiu->fnp != NULL;
	 eiu->fnp++, eiu->prevx++)
    {
	const char * fileName;

	rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp);
	(void) urlPath(*eiu->fnp, &fileName);

	/* Try to read the header from a package file. */
	eiu->fd = Fopen(*eiu->fnp, "r.ufdio");
	if (eiu->fd == NULL || Ferror(eiu->fd)) {
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp,
			Fstrerror(eiu->fd));
	    if (eiu->fd != NULL) {
		xx = Fclose(eiu->fd);
		eiu->fd = NULL;
	    }
	    eiu->numFailed++; *eiu->fnp = NULL;
	    continue;
	}

	/* Read the header, verifying signatures (if present). */
	tvsflags = rpmtsSetVSFlags(ts, vsflags);
	eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h);
	tvsflags = rpmtsSetVSFlags(ts, tvsflags);
	xx = Fclose(eiu->fd);
	eiu->fd = NULL;

	switch (eiu->rpmrc) {
	case RPMRC_FAIL:
	    rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp);
	    eiu->numFailed++; *eiu->fnp = NULL;
	    continue;
	    break;
	case RPMRC_NOTFOUND:
	    goto maybe_manifest;
	    break;
	case RPMRC_NOTTRUSTED:
	case RPMRC_NOKEY:
	case RPMRC_OK:
	default:
	    break;
	}

	eiu->isSource = headerIsSource(eiu->h);

	if (eiu->isSource) {
	    rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n",
		eiu->numSRPMS);
	    eiu->sourceURL = xrealloc(eiu->sourceURL,
				(eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
	    eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
	    *eiu->fnp = NULL;
	    eiu->numSRPMS++;
	    eiu->sourceURL[eiu->numSRPMS] = NULL;
	    continue;
	}

	if (eiu->relocations) {
	    struct rpmtd_s prefixes;

	    headerGet(eiu->h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT);
	    if (rpmtdCount(&prefixes) == 1) {
		eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes));
		rpmtdFreeData(&prefixes);
	    } else {
		const char * name;
		xx = headerNVR(eiu->h, &name, NULL, NULL);
		rpmlog(RPMLOG_ERR,
			       _("package %s is not relocatable\n"), name);
		eiu->numFailed++;
		goto exit;
	    }
	}

	/* On --freshen, verify package is installed and newer */
	if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
	    rpmdbMatchIterator mi;
	    const char * name;
	    Header oldH;
	    int count;

	    xx = headerNVR(eiu->h, &name, NULL, NULL);
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0);
	    count = rpmdbGetIteratorCount(mi);
	    while ((oldH = rpmdbNextIterator(mi)) != NULL) {
		if (rpmVersionCompare(oldH, eiu->h) < 0)
		    continue;
		/* same or newer package already installed */
		count = 0;
		break;
	    }
	    mi = rpmdbFreeIterator(mi);
	    if (count == 0) {
		eiu->h = headerFree(eiu->h);
		continue;
	    }
	    /* Package is newer than those currently installed. */
	}

	rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName,
			(ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
			relocations);

	/* XXX reference held by transaction set */
	eiu->h = headerFree(eiu->h);
	if (eiu->relocations)
	    eiu->relocations->oldPath = _free(eiu->relocations->oldPath);

	switch(rc) {
	case 0:
	    rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n",
			eiu->numRPMS);
	    break;
	case 1:
	    rpmlog(RPMLOG_ERR,
			    _("error reading from file %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	case 2:
	    rpmlog(RPMLOG_ERR,
			    _("file %s requires a newer version of RPM\n"),
			    *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	default:
	    eiu->numFailed++;
	    goto exit;
	    break;
	}

	eiu->numRPMS++;
	continue;

maybe_manifest:
	/* Try to read a package manifest. */
	eiu->fd = Fopen(*eiu->fnp, "r.fpio");
	if (eiu->fd == NULL || Ferror(eiu->fd)) {
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp,
			Fstrerror(eiu->fd));
	    if (eiu->fd != NULL) {
		xx = Fclose(eiu->fd);
		eiu->fd = NULL;
	    }
	    eiu->numFailed++; *eiu->fnp = NULL;
	    break;
	}

	/* Read list of packages from manifest. */
/* FIX: *eiu->argv can be NULL */
	rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv);
	if (rc != RPMRC_OK)
	    rpmlog(RPMLOG_ERR, _("%s: not an rpm package (or package manifest): %s\n"),
			*eiu->fnp, Fstrerror(eiu->fd));
	xx = Fclose(eiu->fd);
	eiu->fd = NULL;

	/* If successful, restart the query loop. */
	if (rc == RPMRC_OK) {
	    eiu->prevx++;
	    goto restart;
	}

	eiu->numFailed++; *eiu->fnp = NULL;
	break;
    }

    rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n",
		eiu->numSRPMS, eiu->numRPMS);

    if (eiu->numFailed) goto exit;

    if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) {

	if (rpmtsCheck(ts)) {
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}

	ps = rpmtsProblems(ts);
	if (!stopInstall && rpmpsNumProblems(ps) > 0) {
	    rpmlog(RPMLOG_ERR, _("Failed dependencies:\n"));
	    rpmpsPrint(NULL, ps);
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}
	ps = rpmpsFree(ps);
    }

    if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
	if (rpmtsOrder(ts)) {
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}
    }

    if (eiu->numRPMS && !stopInstall) {

	rpmcliPackagesTotal += eiu->numSRPMS;

	rpmlog(RPMLOG_DEBUG, "installing binary packages\n");

	/* Drop added/available package indices and dependency sets. */
	rpmtsClean(ts);

	rc = rpmtsRun(ts, NULL, probFilter);
	ps = rpmtsProblems(ts);

	if (rc < 0) {
	    eiu->numFailed += eiu->numRPMS;
	} else if (rc > 0) {
	    eiu->numFailed += rc;
	    if (rpmpsNumProblems(ps) > 0)
		rpmpsPrint(stderr, ps);
	}
	ps = rpmpsFree(ps);
    }

    if (eiu->numSRPMS && !stopInstall) {
	if (eiu->sourceURL != NULL)
	for (i = 0; i < eiu->numSRPMS; i++) {
	    rpmdbCheckSignals();
	    if (eiu->sourceURL[i] == NULL) continue;
	    eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio");
	    if (eiu->fd == NULL || Ferror(eiu->fd)) {
		rpmlog(RPMLOG_ERR, _("cannot open file %s: %s\n"),
			   eiu->sourceURL[i], Fstrerror(eiu->fd));
		if (eiu->fd != NULL) {
		    xx = Fclose(eiu->fd);
		    eiu->fd = NULL;
		}
		continue;
	    }

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
		eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL);
		if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++;
	    }

	    xx = Fclose(eiu->fd);
	    eiu->fd = NULL;
	}
    }

exit:
    if (eiu->pkgURL != NULL)
    for (i = 0; i < eiu->numPkgs; i++) {
	if (eiu->pkgURL[i] == NULL) continue;
	if (eiu->pkgState[i] == 1)
	    (void) unlink(eiu->pkgURL[i]);
	eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
    }
    eiu->pkgState = _free(eiu->pkgState);
    eiu->pkgURL = _free(eiu->pkgURL);
    eiu->argv = _free(eiu->argv);
    rc = eiu->numFailed;
    free(eiu);

    rpmtsEmpty(ts);

    return rc;
}
コード例 #21
0
ファイル: rpminstall.c プロジェクト: xrg/RPM
int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv)
{
    char * const * arg;
    char *qfmt = NULL;
    int numFailed = 0;
    int stopUninstall = 0;
    int numPackages = 0;
    rpmVSFlags vsflags, ovsflags;
    rpmps ps;

    if (argv == NULL) return 0;

    vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
    if (ia->qva_flags & VERIFY_DIGEST)
	vsflags |= _RPMVSF_NODIGESTS;
    if (ia->qva_flags & VERIFY_SIGNATURE)
	vsflags |= _RPMVSF_NOSIGNATURES;
    if (ia->qva_flags & VERIFY_HDRCHK)
	vsflags |= RPMVSF_NOHDRCHK;
    ovsflags = rpmtsSetVSFlags(ts, vsflags);

    /* XXX suggest mechanism only meaningful when installing */
    ia->transFlags |= RPMTRANS_FLAG_NOSUGGEST;

    (void) rpmtsSetFlags(ts, ia->transFlags);

#ifdef	NOTYET	/* XXX no callbacks on erase yet */
    {	int notifyFlags, xx;
	notifyFlags = ia->eraseInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
	xx = rpmtsSetNotifyCallback(ts,
			rpmShowProgress, (void *) ((long)notifyFlags));
    }
#endif

    qfmt = rpmExpand("%{?_query_all_fmt}\n", NULL);
    for (arg = argv; *arg; arg++) {
	rpmdbMatchIterator mi;
	int matches = 0;
	int erasing = 1;

	/* Iterator count isn't reliable with labels, count manually... */
	mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0);
	while (rpmdbNextIterator(mi) != NULL) {
	    matches++;
	}
	rpmdbFreeIterator(mi);

	if (! matches) {
	    rpmlog(RPMLOG_ERR, _("package %s is not installed\n"), *arg);
	    numFailed++;
	} else {
	    Header h;	/* XXX iterator owns the reference */

	    if (matches > 1 && 
		!(ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES)) {
		rpmlog(RPMLOG_ERR, _("\"%s\" specifies multiple packages:\n"),
			*arg);
		numFailed++;
		erasing = 0;
	    }

	    mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0);
	    while ((h = rpmdbNextIterator(mi)) != NULL) {
		if (erasing) {
		    (void) rpmtsAddEraseElement(ts, h, -1);
		    numPackages++;
		} else {
		    char *nevra = headerFormat(h, qfmt, NULL);
		    rpmlog(RPMLOG_NOTICE, "  %s", nevra);
		    free(nevra);
		}
	    }
	    mi = rpmdbFreeIterator(mi);
	}
    }
    free(qfmt);

    if (numFailed) goto exit;

    if (!(ia->eraseInterfaceFlags & UNINSTALL_NODEPS)) {

	if (rpmtsCheck(ts)) {
	    numFailed = numPackages;
	    stopUninstall = 1;
	}

	ps = rpmtsProblems(ts);
	if (!stopUninstall && rpmpsNumProblems(ps) > 0) {
	    rpmlog(RPMLOG_ERR, _("Failed dependencies:\n"));
	    rpmpsPrint(NULL, ps);
	    numFailed += numPackages;
	    stopUninstall = 1;
	}
	ps = rpmpsFree(ps);
    }

    if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
	if (rpmtsOrder(ts)) {
	    numFailed += numPackages;
	    stopUninstall = 1;
	}
    }

    if (numPackages && !stopUninstall) {
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_REVERSE));

	/* Drop added/available package indices and dependency sets. */
	rpmtsClean(ts);

	numPackages = rpmtsRun(ts, NULL, ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES));
	ps = rpmtsProblems(ts);
	if (rpmpsNumProblems(ps) > 0)
	    rpmpsPrint(NULL, ps);
	numFailed += numPackages;
	stopUninstall = 1;
	ps = rpmpsFree(ps);
    }

exit:
    rpmtsEmpty(ts);

    return numFailed;
}
コード例 #22
0
ファイル: verify.c プロジェクト: avokhmin/RPM5
int showVerifyPackage(QVA_t qva, rpmts ts, Header h)
{
    static int scareMem = 0;
    rpmVerifyAttrs omitMask = ((qva->qva_flags & VERIFY_ATTRS) ^ VERIFY_ATTRS);
    int spew = (qva->qva_mode != 'v');	/* XXX no output w verify(...) probe. */
    int ec = 0;
    int i;
rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
uint32_t fc = rpmfiFC(fi);

  {
    /* Verify header digest/signature. */
    if (qva->qva_flags & (VERIFY_DIGEST | VERIFY_SIGNATURE))
    {
	const char * horigin = headerGetOrigin(h);
	const char * msg = NULL;
	size_t uhlen = 0;
	void * uh = headerUnload(h, &uhlen);
	int lvl = headerCheck(rpmtsDig(ts), uh, uhlen, &msg) == RPMRC_FAIL
		? RPMLOG_ERR : RPMLOG_DEBUG;
	rpmlog(lvl, "%s: %s\n",
		(horigin ? horigin : "verify"), (msg ? msg : ""));
	rpmtsCleanDig(ts);
	uh = _free(uh);
	msg = _free(msg);
    }

    /* Verify file digests. */
    if (fc > 0 && (qva->qva_flags & VERIFY_FILES))
#if defined(_OPENMP)
    #pragma omp parallel for private(i) reduction(+:ec)
#endif
    for (i = 0; i < (int)fc; i++) {
	int fflags = fi->fflags[i];
	rpmvf vf;
	int rc;

	/* If not querying %config, skip config files. */
	if ((qva->qva_fflags & RPMFILE_CONFIG) && (fflags & RPMFILE_CONFIG))
	    continue;

	/* If not querying %doc, skip doc files. */
	if ((qva->qva_fflags & RPMFILE_DOC) && (fflags & RPMFILE_DOC))
	    continue;

	/* If not verifying %ghost, skip ghost files. */
	/* XXX the broken!!! logic disables %ghost queries always. */
	if (!(qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST))
	    continue;

	/* Gather per-file data into a carrier. */
	vf = rpmvfNew(ts, fi, i, omitMask);

	/* Verify per-file metadata. */
	rc = rpmvfVerify(vf, spew);
	if (rc)
	    ec += rc;

	(void) rpmvfFree(vf);
	vf = NULL;
    }

    /* Run verify/sanity scripts (if any). */
    if (qva->qva_flags & VERIFY_SCRIPT)
    {
	int rc;

	if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT) ||
	    headerIsEntry(h, RPMTAG_SANITYCHECK))
	{
	    FD_t fdo = fdDup(STDOUT_FILENO);

	    rc = rpmfiSetHeader(fi, h);
	    if ((rc = rpmVerifyScript(qva, ts, fi, fdo)) != 0)
		ec += rc;
	    if (fdo != NULL)
		rc = Fclose(fdo);
	    rc = rpmfiSetHeader(fi, NULL);
	}
    }

    /* Verify dependency assertions. */
    if (qva->qva_flags & VERIFY_DEPS)
    {
	int save_noise = _rpmds_unspecified_epoch_noise;
	int rc;

/*@-mods@*/
	if (rpmIsVerbose())
	    _rpmds_unspecified_epoch_noise = 1;
	if ((rc = verifyDependencies(qva, ts, h)) != 0)
	    ec += rc;
	_rpmds_unspecified_epoch_noise = save_noise;
/*@=mods@*/
    }
  }

    fi = rpmfiFree(fi);

    return ec;
}
コード例 #23
0
ファイル: verify.c プロジェクト: avokhmin/RPM5
/** \ingroup rpmcli
 * Verify file attributes (including file digest).
 * @param vf		file data to verify
 * #param spew		should verify results be printed?
 * @return		0 on success (or not installed), 1 on error
 */
static int rpmvfVerify(rpmvf vf, int spew)
	/*@globals h_errno, fileSystem, internalState @*/
	/*@modifies vf, fileSystem, internalState @*/
{
    rpmVerifyAttrs res = RPMVERIFY_NONE;
    struct stat sb;
    int ec = 0;

    /* Check to see if the file was installed - if not pretend all is OK. */
    switch (vf->fstate) {
    default:
    case RPMFILE_STATE_NETSHARED:
    case RPMFILE_STATE_REPLACED:
    case RPMFILE_STATE_NOTINSTALLED:
    case RPMFILE_STATE_WRONGCOLOR:
	goto exit;
	/*@notreached@*/ break;
    case RPMFILE_STATE_NORMAL:
	break;
    }

assert(vf->fn != NULL);
    if (vf->fn == NULL || Lstat(vf->fn, &sb) != 0) {
	res |= RPMVERIFY_LSTATFAIL;
	ec = 1;
	goto exit;
    }

    /* Not all attributes of non-regular files can be verified. */
    if (S_ISDIR(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISLNK(sb.st_mode)) {
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
		RPMVERIFY_MODE | RPMVERIFY_HMAC);
#if CHOWN_FOLLOWS_SYMLINK
	vf->vflags &= ~(RPMVERIFY_USER | RPMVERIFY_GROUP);
#endif
    }
    else if (S_ISFIFO(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISCHR(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISBLK(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else
	vf->vflags &= ~(RPMVERIFY_LINKTO);

    if (vf->vflags & (RPMVERIFY_FDIGEST | RPMVERIFY_HMAC)) {
	if (vf->digest == NULL || vf->dlen == 0)
	    res |= RPMVERIFY_FDIGEST;
	else {
	/* XXX If --nofdigest, then prelinked library sizes fail to verify. */
	    unsigned char * fdigest = memset(alloca(vf->dlen), 0, vf->dlen);
	    size_t fsize = 0;
#define	_mask	(RPMVERIFY_FDIGEST|RPMVERIFY_HMAC)
	    unsigned dflags = (vf->vflags & _mask) == RPMVERIFY_HMAC
		? 0x2 : 0x0;
#undef	_mask
	    int rc = dodigest(vf->dalgo, vf->fn, fdigest, dflags, &fsize);
	    sb.st_size = fsize;
	    if (rc)
		res |= (RPMVERIFY_READFAIL|RPMVERIFY_FDIGEST);
	    else
	    if (memcmp(fdigest, vf->digest, vf->dlen))
		res |= RPMVERIFY_FDIGEST;
	}
    }

    if (vf->vflags & RPMVERIFY_LINKTO) {
	char linkto[1024+1];
	int size = 0;

	if ((size = Readlink(vf->fn, linkto, sizeof(linkto)-1)) == -1)
	    res |= (RPMVERIFY_READLINKFAIL|RPMVERIFY_LINKTO);
	else {
	    linkto[size] = '\0';
	    if (vf->flink == NULL || strcmp(linkto, vf->flink))
		res |= RPMVERIFY_LINKTO;
	}
    }

    if (vf->vflags & RPMVERIFY_FILESIZE) {
	if (sb.st_size != vf->sb.st_size)
	    res |= RPMVERIFY_FILESIZE;
    }

    if (vf->vflags & RPMVERIFY_MODE) {
	/* XXX AIX has sizeof(mode_t) > sizeof(unsigned short) */
	unsigned short metamode = (unsigned short)vf->sb.st_mode;
	unsigned short filemode = (unsigned short)sb.st_mode;

	/* Comparing type of %ghost files is meaningless, but perms are OK. */
	if (vf->fflags & RPMFILE_GHOST) {
	    metamode &= ~0xf000;
	    filemode &= ~0xf000;
	}
	if (metamode != filemode)
	    res |= RPMVERIFY_MODE;
    }

    if (vf->vflags & RPMVERIFY_RDEV) {
	if (S_ISCHR(vf->sb.st_mode) != S_ISCHR(sb.st_mode)
	 || S_ISBLK(vf->sb.st_mode) != S_ISBLK(sb.st_mode))
	    res |= RPMVERIFY_RDEV;
	else if (S_ISDEV(vf->sb.st_mode) && S_ISDEV(sb.st_mode)) {
	    rpmuint16_t st_rdev = (rpmuint16_t)(sb.st_rdev & 0xffff);
	    rpmuint16_t frdev = (rpmuint16_t)(vf->sb.st_rdev & 0xffff);
	    if (st_rdev != frdev)
		res |= RPMVERIFY_RDEV;
	}
    }

    if (vf->vflags & RPMVERIFY_MTIME) {
	if (sb.st_mtime != vf->sb.st_mtime)
	    res |= RPMVERIFY_MTIME;
    }

    if (vf->vflags & RPMVERIFY_USER) {
	const char * fuser = uidToUname(sb.st_uid);
	if (fuser == NULL || vf->fuser == NULL || strcmp(fuser, vf->fuser))
	    res |= RPMVERIFY_USER;
    }

    if (vf->vflags & RPMVERIFY_GROUP) {
	const char * fgroup = gidToGname(sb.st_gid);
	if (fgroup == NULL || vf->fgroup == NULL || strcmp(fgroup, vf->fgroup))
	    res |= RPMVERIFY_GROUP;
    }

exit:

    if (spew) {	/* XXX no output w verify(...) probe. */
	char buf[BUFSIZ];
	char * t = buf;
	char * te = t;
	*te = '\0';
	if (ec) {
	    if (!(vf->fflags & (RPMFILE_MISSINGOK|RPMFILE_GHOST))
	     || rpmIsVerbose())
	    {
		sprintf(te, _("missing   %c %s"),
			((vf->fflags & RPMFILE_CONFIG)	? 'c' :
			 (vf->fflags & RPMFILE_DOC)	? 'd' :
			 (vf->fflags & RPMFILE_GHOST)	? 'g' :
			 (vf->fflags & RPMFILE_LICENSE)	? 'l' :
			 (vf->fflags & RPMFILE_PUBKEY)	? 'P' :
			 (vf->fflags & RPMFILE_README)	? 'r' : ' '),
			vf->fn);
                if ((res & RPMVERIFY_LSTATFAIL) != 0 && errno != ENOENT) {
		    te += strlen(te);
                    sprintf(te, " (%s)", strerror(errno));
                }
	    }
	} else if (res || rpmIsVerbose()) {
	    /*@observer@*/ static const char aok[] = ".";
	    /*@observer@*/ static const char unknown[] = "?";

#define	_verify(_RPMVERIFY_F, _C)	\
	((res & _RPMVERIFY_F) ? _C : aok)
#define	_verifylink(_RPMVERIFY_F, _C)	\
	((res & RPMVERIFY_READLINKFAIL) ? unknown : \
	 (res & _RPMVERIFY_F) ? _C : aok)
#define	_verifyfile(_RPMVERIFY_F, _C)	\
	((res & RPMVERIFY_READFAIL) ? unknown : \
	 (res & _RPMVERIFY_F) ? _C : aok)
	
	    const char * digest = _verifyfile(RPMVERIFY_FDIGEST, "5");
	    const char * size = _verify(RPMVERIFY_FILESIZE, "S");
	    const char * link = _verifylink(RPMVERIFY_LINKTO, "L");
	    const char * mtime = _verify(RPMVERIFY_MTIME, "T");
	    const char * rdev = _verify(RPMVERIFY_RDEV, "D");
	    const char * user = _verify(RPMVERIFY_USER, "U");
	    const char * group = _verify(RPMVERIFY_GROUP, "G");
	    const char * mode = _verify(RPMVERIFY_MODE, "M");

#undef _verifyfile
#undef _verifylink
#undef _verify

	    sprintf(te, "%s%s%s%s%s%s%s%s  %c %s",
		    size, mode, digest, rdev, link, user, group, mtime,
			((vf->fflags & RPMFILE_CONFIG)	? 'c' :
			 (vf->fflags & RPMFILE_DOC)	? 'd' :
			 (vf->fflags & RPMFILE_GHOST)	? 'g' :
			 (vf->fflags & RPMFILE_LICENSE)	? 'l' :
			 (vf->fflags & RPMFILE_PUBKEY)	? 'P' :
			 (vf->fflags & RPMFILE_README)	? 'r' : ' '),
			vf->fn);

	}

	if (t && *t)
	    rpmlog(RPMLOG_NOTICE, "%s\n", t);

    }

    return (res != 0);
}
コード例 #24
0
ファイル: macro.c プロジェクト: xrg/RPM
/**
 * Execute macro primitives.
 * @param mb		macro expansion state
 * @param negate	should logic be inverted?
 * @param f		beginning of field f
 * @param fn		length of field f
 * @param g		beginning of field g
 * @param gn		length of field g
 */
static void
doFoo(MacroBuf mb, int negate, const char * f, size_t fn,
		const char * g, size_t gn)
{
    size_t blen = MACROBUFSIZ + fn + gn;
    char *buf = xmalloc(blen);
    char *b = NULL, *be;
    int c;

    buf[0] = '\0';
    if (g != NULL) {
	strncpy(buf, g, gn);
	buf[gn] = '\0';
	(void) expandU(mb, buf, blen);
    }
    if (STREQ("basename", f, fn)) {
	if ((b = strrchr(buf, '/')) == NULL)
	    b = buf;
	else
	    b++;
#if NOTYET
    /* XXX watchout for conflict with %dir */
    } else if (STREQ("dirname", f, fn)) {
	if ((b = strrchr(buf, '/')) != NULL)
	    *b = '\0';
	b = buf;
#endif
    } else if (STREQ("suffix", f, fn)) {
	if ((b = strrchr(buf, '.')) != NULL)
	    b++;
    } else if (STREQ("expand", f, fn)) {
	b = buf;
    } else if (STREQ("verbose", f, fn)) {
	if (negate)
	    b = (rpmIsVerbose() ? NULL : buf);
	else
	    b = (rpmIsVerbose() ? buf : NULL);
    } else if (STREQ("url2path", f, fn) || STREQ("u2p", f, fn)) {
	(void)urlPath(buf, (const char **)&b);
	if (*b == '\0') b = "/";
    } else if (STREQ("uncompress", f, fn)) {
	rpmCompressedMagic compressed = COMPRESSED_OTHER;
	for (b = buf; (c = *b) && isblank(c);)
	    b++;
	for (be = b; (c = *be) && !isblank(c);)
	    be++;
	*be++ = '\0';
	(void) rpmFileIsCompressed(b, &compressed);
	switch(compressed) {
	default:
	case COMPRESSED_NOT:
	    sprintf(be, "%%__cat %s", b);
	    break;
	case COMPRESSED_OTHER:
	    sprintf(be, "%%__gzip -dc %s", b);
	    break;
	case COMPRESSED_BZIP2:
	    sprintf(be, "%%__bzip2 -dc %s", b);
	    break;
	case COMPRESSED_ZIP:
	    sprintf(be, "%%__unzip %s", b);
	    break;
        case COMPRESSED_LZMA:
            sprintf(be, "%%__lzma -dc %s", b);
            break;
	}
	b = be;
    } else if (STREQ("getenv", f, fn)) {
	b = getenv(buf);
    } else if (STREQ("S", f, fn)) {
	for (b = buf; (c = *b) && risdigit(c);)
	    b++;
	if (!c) {	/* digit index */
	    b++;
	    sprintf(b, "%%SOURCE%s", buf);
	} else
	    b = buf;
    } else if (STREQ("P", f, fn)) {
	for (b = buf; (c = *b) && risdigit(c);)
	    b++;
	if (!c) {	/* digit index */
	    b++;
	    sprintf(b, "%%PATCH%s", buf);
	} else
			b = buf;
    } else if (STREQ("F", f, fn)) {
	b = buf + strlen(buf) + 1;
	sprintf(b, "file%s.file", buf);
    }

    if (b) {
	(void) expandT(mb, b, strlen(b));
    }
    free(buf);
}
コード例 #25
0
ファイル: rpmscript.c プロジェクト: pombredanne/rpm-4
/**
 * Run an external script.
 */
static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
                          const char *sname, rpmlogLvl lvl, FD_t scriptFd,
                          ARGV_t * argvp, const char *script, int arg1, int arg2)
{
    FD_t out = NULL;
    char * fn = NULL;
    pid_t pid, reaped;
    int status;
    rpmRC rc = RPMRC_FAIL;

    rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", sname);

    if (script) {
        fn = writeScript(*argvp[0], script);
        if (fn == NULL) {
            rpmlog(RPMLOG_ERR,
                   _("Couldn't create temporary file for %s: %s\n"),
                   sname, strerror(errno));
            goto exit;
        }

        argvAdd(argvp, fn);
        if (arg1 >= 0) {
            argvAddNum(argvp, arg1);
        }
        if (arg2 >= 0) {
            argvAddNum(argvp, arg2);
        }
    }

    if (scriptFd != NULL) {
        if (rpmIsVerbose()) {
            out = fdDup(Fileno(scriptFd));
        } else {
            out = Fopen("/dev/null", "w.fdio");
            if (Ferror(out)) {
                out = fdDup(Fileno(scriptFd));
            }
        }
    } else {
        out = fdDup(STDOUT_FILENO);
    }
    if (out == NULL) {
        rpmlog(RPMLOG_ERR, _("Couldn't duplicate file descriptor: %s: %s\n"),
               sname, strerror(errno));
        goto exit;
    }

    pid = fork();
    if (pid == (pid_t) -1) {
        rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"),
               sname, strerror(errno));
        goto exit;
    } else if (pid == 0) {/* Child */
        rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n",
               sname, *argvp[0], (unsigned)getpid());

        /* Run scriptlet post fork hook for all plugins */
        if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) {
            doScriptExec(*argvp, prefixes, scriptFd, out);
        } else {
            _exit(126); /* exit 126 for compatibility with bash(1) */
        }
    }

    do {
        reaped = waitpid(pid, &status, 0);
    } while (reaped == -1 && errno == EINTR);

    rpmlog(RPMLOG_DEBUG, "%s: waitpid(%d) rc %d status %x\n",
           sname, (unsigned)pid, (unsigned)reaped, status);

    if (reaped < 0) {
        rpmlog(lvl, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"),
               sname, pid, reaped, strerror(errno));
    } else if (!WIFEXITED(status) || WEXITSTATUS(status)) {
        if (WIFSIGNALED(status)) {
            rpmlog(lvl, _("%s scriptlet failed, signal %d\n"),
                   sname, WTERMSIG(status));
        } else {
            rpmlog(lvl, _("%s scriptlet failed, exit status %d\n"),
                   sname, WEXITSTATUS(status));
        }
    } else {
        /* if we get this far we're clear */
        rc = RPMRC_OK;
    }

exit:
    if (out)
        Fclose(out);	/* XXX dup'd STDOUT_FILENO */

    if (fn) {
        if (!rpmIsDebug())
            unlink(fn);
        free(fn);
    }
    return rc;
}
コード例 #26
0
ファイル: depends.c プロジェクト: Distrotech/rpm
/*
 * Check for previously added versions and obsoletions.
 * Return index where to place this element, or -1 to skip.
 * XXX OBSOLETENAME is a bit of a hack, but gives us what
 * we want from rpmal: we're only interested in added package
 * names here, not their provides.
 */
static int findPos(rpmts ts, rpm_color_t tscolor, rpmte te, int upgrade)
{
    tsMembers tsmem = rpmtsMembers(ts);
    int oc = tsmem->orderCount;
    int skip = 0;
    const char * name = rpmteN(te);
    const char * evr = rpmteEVR(te);
    rpmte p;
    rpmstrPool tspool = rpmtsPool(ts);
    rpmds oldChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				   name, evr, (RPMSENSE_LESS));
    rpmds newChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				   name, evr, (RPMSENSE_GREATER));
    rpmds sameChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				    name, evr, (RPMSENSE_EQUAL));
    rpmds obsChk = rpmteDS(te, RPMTAG_OBSOLETENAME);

    /* If obsoleting package has already been added, skip this. */
    if ((p = checkObsoleted(tsmem->addedPackages, rpmteDS(te, RPMTAG_NAME)))) {
	skip = 1;
	goto exit;
    }

    /* If obsoleted package has already been added, replace with this. */
    rpmdsInit(obsChk);
    while (rpmdsNext(obsChk) >= 0) {
	/* XXX Obsoletes are not colored */
	if ((p = checkAdded(tsmem->addedPackages, 0, te, obsChk))) {
	    goto exit;
	}
    }

    /* If same NEVR has already been added, skip this. */
    if ((p = checkAdded(tsmem->addedPackages, tscolor, te, sameChk))) {
	skip = 1;
	goto exit;
    }

    /* On upgrades... */
    if (upgrade) {
	/* ...if newer NEVR has already been added, skip this. */
	if ((p = checkAdded(tsmem->addedPackages, tscolor, te, newChk))) {
	    skip = 1;
	    goto exit;
	}

	/* ...if older NEVR has already been added, replace with this. */
	if ((p = checkAdded(tsmem->addedPackages, tscolor, te, oldChk))) {
	    goto exit;
	}
    }

exit:
    /* If we found a previous element we've something to say */
    if (p != NULL && rpmIsVerbose()) {
	const char *msg = skip ?
		    _("package %s was already added, skipping %s\n") :
		    _("package %s was already added, replacing with %s\n");
	rpmlog(RPMLOG_WARNING, msg, rpmteNEVRA(p), rpmteNEVRA(te));
    }

    /* If replacing a previous element, find out where it is. Pooh. */
    if (!skip && p != NULL) {
	for (oc = 0; oc < tsmem->orderCount; oc++) {
	    if (p == tsmem->order[oc])
		break;
	}
    }

    rpmdsFree(oldChk);
    rpmdsFree(newChk);
    rpmdsFree(sameChk);
    return (skip) ? -1 : oc;
}
コード例 #27
0
ファイル: verify.c プロジェクト: nforro/rpm
/**
 * Check file info from header against what's actually installed.
 * @param ts		transaction set
 * @param h		header to verify
 * @param omitMask	bits to disable verify checks
 * @param incAttr	skip files without these attrs (eg %ghost)
 * @param skipAttr	skip files with these attrs (eg %ghost)
 * @return		0 no problems, 1 problems found
 */
static int verifyHeader(rpmts ts, Header h, rpmVerifyAttrs omitMask,
			rpmfileAttrs incAttrs, rpmfileAttrs skipAttrs)
{
    rpmVerifyAttrs verifyResult = 0;
    rpmVerifyAttrs verifyAll = 0; /* assume no problems */
    rpmfi fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_FLAGS_VERIFY);

    if (fi == NULL)
	return 1;

    rpmfiInit(fi, 0);
    while (rpmfiNext(fi) >= 0) {
	rpmfileAttrs fileAttrs = rpmfiFFlags(fi);
	char *buf = NULL, *attrFormat;
	const char *fstate = NULL;
	char ac;

	/* If filtering by inclusion, skip non-matching (eg --configfiles) */
	if (incAttrs && !(incAttrs & fileAttrs))
	    continue;

	/* Skip on attributes (eg from --noghost) */
	if (skipAttrs & fileAttrs)
	    continue;

	verifyResult = rpmfiVerify(fi, omitMask);

	/* Filter out timestamp differences of shared files */
	if (verifyResult & RPMVERIFY_MTIME) {
	    rpmdbMatchIterator mi;
	    mi = rpmtsInitIterator(ts, RPMDBI_BASENAMES, rpmfiFN(fi), 0);
	    if (rpmdbGetIteratorCount(mi) > 1) 
		verifyResult &= ~RPMVERIFY_MTIME;
	    rpmdbFreeIterator(mi);
	}

	/* State is only meaningful for installed packages */
	if (headerGetInstance(h))
	    fstate = stateStr(rpmfiFState(fi));

	attrFormat = rpmFFlagsString(fileAttrs, "");
	ac = rstreq(attrFormat, "") ? ' ' : attrFormat[0];
	if (verifyResult & RPMVERIFY_LSTATFAIL) {
	    if (!(fileAttrs & (RPMFILE_MISSINGOK|RPMFILE_GHOST)) || rpmIsVerbose()) {
		rasprintf(&buf, _("missing   %c %s"), ac, rpmfiFN(fi));
		if ((verifyResult & RPMVERIFY_LSTATFAIL) != 0 &&
		    errno != ENOENT) {
		    char *app;
		    rasprintf(&app, " (%s)", strerror(errno));
		    rstrcat(&buf, app);
		    free(app);
		}
	    }
	} else if (verifyResult || fstate || rpmIsVerbose()) {
	    char *verifyFormat = rpmVerifyString(verifyResult, ".");
	    rasprintf(&buf, "%s  %c %s", verifyFormat, ac, rpmfiFN(fi));
	    free(verifyFormat);
	}
	free(attrFormat);

	if (buf) {
	    if (fstate)
		buf = rstrscat(&buf, " (", fstate, ")", NULL);
	    rpmlog(RPMLOG_NOTICE, "%s\n", buf);
	    buf = _free(buf);
	}
	verifyAll |= verifyResult;
    }
    rpmfiFree(fi);
	
    return (verifyAll != 0) ? 1 : 0;
}
コード例 #28
0
ファイル: rpmqv.c プロジェクト: soig/rpm
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

    xsetprogname(argv[0]); /* Portability call -- see system.h */

    optCon = rpmcliInit(argc, argv, optionsTable);

    /* Set the major mode based on argv[0] */
#ifdef	IAM_RPMQV
    if (rstreq(xgetprogname(), "rpmquery"))	bigMode = MODE_QUERY;
    if (rstreq(xgetprogname(), "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|INSTALL_REINSTALL));
	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 & MODES_IE) && (ia->installInterfaceFlags & INSTALL_HASH))
	argerror(_("--hash (-h) may only be specified during package "
			"installation and erasure"));

    if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_PERCENT))
	argerror(_("--percent may only be specified during package "
			"installation and erasure"));

    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;
    }

    rpmtsFree(ts);
    if (finishPipe())
	ec = EXIT_FAILURE;

#ifdef	IAM_RPMQV
    free(qva->qva_queryFormat);
#endif

#ifdef	IAM_RPMEIU
    if (ia->relocations != NULL) {
	for (i = 0; i < ia->numRelocations; i++)
	    free(ia->relocations[i].oldPath);
	free(ia->relocations);
    }
#endif

    rpmcliFini(optCon);

    return RETVAL(ec);
}
コード例 #29
0
ファイル: rpmchecksig.c プロジェクト: PerilousApricot/rpm
static int rpmpkgVerifySigs(rpmKeyring keyring, rpmQueryFlags flags,
			   FD_t fd, const char *fn)
{

    char *buf = NULL;
    char *missingKeys = NULL; 
    char *untrustedKeys = NULL;
    struct rpmtd_s sigtd;
    pgpDigParams sig = NULL;
    Header sigh = NULL;
    HeaderIterator hi = NULL;
    char * msg = NULL;
    int res = 1; /* assume failure */
    rpmRC rc;
    int failed = 0;
    int nodigests = !(flags & VERIFY_DIGEST);
    int nosignatures = !(flags & VERIFY_SIGNATURE);
    struct sigtInfo_s sinfo;
    rpmDigestBundle plbundle = rpmDigestBundleNew();
    rpmDigestBundle hdrbundle = rpmDigestBundleNew();

    if ((rc = rpmLeadRead(fd, NULL, NULL, &msg)) != RPMRC_OK) {
	goto exit;
    }

    rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);

    if (rc != RPMRC_OK) {
	goto exit;
    }

    /* Initialize all digests we'll be needing */
    hi = headerInitIterator(sigh);
    for (; headerNext(hi, &sigtd) != 0; rpmtdFreeData(&sigtd)) {
	rc = rpmSigInfoParse(&sigtd, "package", &sinfo, NULL, NULL);

	if (nosignatures && sinfo.type == RPMSIG_SIGNATURE_TYPE)
	    continue;
	if (nodigests && sinfo.type == RPMSIG_DIGEST_TYPE)
	    continue;
	if (rc == RPMRC_OK && sinfo.hashalgo) {
	    rpmDigestBundleAdd(sinfo.payload ? plbundle : hdrbundle,
			       sinfo.hashalgo, RPMDIGEST_NONE);
	}
    }
    hi = headerFreeIterator(hi);

    /* Read the file, generating digest(s) on the fly. */
    fdSetBundle(fd, plbundle);
    if (readFile(fd, fn, plbundle, hdrbundle)) {
	goto exit;
    }

    rasprintf(&buf, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') );

    hi = headerInitIterator(sigh);
    for (; headerNext(hi, &sigtd) != 0; rpmtdFreeData(&sigtd)) {
	char *result = NULL;
	DIGEST_CTX ctx = NULL;
	if (sigtd.data == NULL) /* XXX can't happen */
	    continue;

	/* Clean up parameters from previous sigtag. */
	sig = pgpDigParamsFree(sig);

	/* Note: we permit failures to be ignored via disablers */
	rc = rpmSigInfoParse(&sigtd, "package", &sinfo, &sig, &result);

	if (nosignatures && sinfo.type == RPMSIG_SIGNATURE_TYPE)
	    continue;
	if (nodigests &&  sinfo.type == RPMSIG_DIGEST_TYPE)
	    continue;
	if (sinfo.type == RPMSIG_OTHER_TYPE)
	    continue;

	if (rc == RPMRC_OK) {
	    ctx = rpmDigestBundleDupCtx(sinfo.payload ? plbundle : hdrbundle,
					sinfo.hashalgo);
	    rc = rpmVerifySignature(keyring, &sigtd, sig, ctx, &result);
	    rpmDigestFinal(ctx, NULL, NULL, 0);
	}

	if (result) {
	    formatResult(sigtd.tag, rc, result,
		     (rc == RPMRC_NOKEY ? &missingKeys : &untrustedKeys),
		     &buf);
	    free(result);
	}

	if (rc != RPMRC_OK) {
	    failed = 1;
	}

    }
    res = failed;

    if (rpmIsVerbose()) {
	rpmlog(RPMLOG_NOTICE, "%s", buf);
    } else {
	const char *ok = (failed ? _("NOT OK") : _("OK"));
	rpmlog(RPMLOG_NOTICE, "%s%s%s%s%s%s%s%s\n", buf, ok,
	       missingKeys ? _(" (MISSING KEYS:") : "",
	       missingKeys ? missingKeys : "",
	       missingKeys ? _(") ") : "",
	       untrustedKeys ? _(" (UNTRUSTED KEYS:") : "",
	       untrustedKeys ? untrustedKeys : "",
	       untrustedKeys ? _(")") : "");
    }
    free(missingKeys);
    free(untrustedKeys);

exit:
    if (res && msg != NULL)
	rpmlog(RPMLOG_ERR, "%s: %s\n", fn, msg);
    free(msg);
    free(buf);
    rpmDigestBundleFree(hdrbundle);
    rpmDigestBundleFree(plbundle);
    fdSetBundle(fd, NULL); /* XXX avoid double-free from fd close */
    sigh = rpmFreeSignature(sigh);
    hi = headerFreeIterator(hi);
    pgpDigParamsFree(sig);
    return res;
}
コード例 #30
0
ファイル: rpmspec.c プロジェクト: soig/rpm
int main(int argc, char *argv[])
{
    rpmts ts = NULL;
    QVA_t qva = &rpmQVKArgs;

    poptContext optCon;
    int ec = 0;

    xsetprogname(argv[0]); /* Portability call -- see system.h */

    optCon = rpmcliInit(argc, argv, optionsTable);

    if (rpmcliPipeOutput && initPipe())
	exit(EXIT_FAILURE);

    if (target) {
	rpmFreeMacros(NULL);
	rpmFreeRpmrc();
	rpmReadConfigFiles(rpmcliRcfile, target);
    }
	
    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;
	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 == NULL) {
		ec++;
		continue;
	    }
	    fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE));
	    rpmSpecFree(spec);
	}
	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);
}