示例#1
0
文件: depends.c 项目: Distrotech/rpm
/* Add erase elements for obsoleted packages of same color (if any). */
static int addObsoleteErasures(rpmts ts, rpm_color_t tscolor, rpmte p)
{
    rpmstrPool tspool = rpmtsPool(ts);
    rpmds obsoletes = rpmdsInit(rpmteDS(p, RPMTAG_OBSOLETENAME));
    Header oh;
    int rc = 0;

    while (rpmdsNext(obsoletes) >= 0 && rc == 0) {
	const char * Name;
	rpmdbMatchIterator mi = NULL;

	if ((Name = rpmdsN(obsoletes)) == NULL)
	    continue;	/* XXX can't happen */

	mi = rpmtsPrunedIterator(ts, RPMDBI_NAME, Name, 1);

	while((oh = rpmdbNextIterator(mi)) != NULL) {
	    const char *oarch = headerGetString(oh, RPMTAG_ARCH);
	    int match;

	    /* avoid self-obsoleting packages */
	    if (rstreq(rpmteN(p), Name) && rstreq(rpmteA(p), oarch)) {
		char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA);
		rpmlog(RPMLOG_DEBUG, "  Not obsoleting: %s\n", ohNEVRA);
		free(ohNEVRA);
		continue;
	    }

	    /*
	     * Rpm prior to 3.0.3 does not have versioned obsoletes.
	     * If no obsoletes version info is available, match all names.
	     */
	    match = (rpmdsEVR(obsoletes) == NULL);
	    if (!match)
		match = rpmdsMatches(tspool, oh, -1, obsoletes, 1,
					 _rpmds_nopromote);

	    if (match) {
		char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA);
		rpmlog(RPMLOG_DEBUG, "  Obsoletes: %s\t\terases %s\n",
			rpmdsDNEVR(obsoletes)+2, ohNEVRA);
		free(ohNEVRA);

		if (removePackage(ts, oh, p)) {
		    rc = 1;
		    break;
		}
	    }
	}
	rpmdbFreeIterator(mi);
    }
    return rc;
}
示例#2
0
文件: depends.c 项目: Distrotech/rpm
/**
 * Check for supported payload format in header.
 * @param h		header to check
 * @return		RPMRC_OK if supported, RPMRC_FAIL otherwise
 */
static rpmRC headerCheckPayloadFormat(Header h) {
    rpmRC rc = RPMRC_OK;
    const char *payloadfmt = headerGetString(h, RPMTAG_PAYLOADFORMAT);
    /* 
     * XXX Ugh, rpm 3.x packages don't have payload format tag. Instead
     * of blindly allowing, should check somehow (HDRID existence or... ?)
     */
    if (!payloadfmt) return rc;

    if (!rstreq(payloadfmt, "cpio")) {
        char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
        if (payloadfmt && rstreq(payloadfmt, "drpm")) {
            rpmlog(RPMLOG_ERR,
                     _("%s is a Delta RPM and cannot be directly installed\n"),
                     nevra);
        } else {
            rpmlog(RPMLOG_ERR, 
                     _("Unsupported payload (%s) in package %s\n"),
                     payloadfmt ? payloadfmt : "none", nevra);
        } 
        free(nevra);
	rc = RPMRC_FAIL;
    }
    return rc;
}
示例#3
0
文件: depends.c 项目: Distrotech/rpm
/* Check a given dependency against installed packages */
static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
			  rpmTag depTag, const char *dep)
{
    Header h;
    rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1);
    rpmstrPool pool = rpmtsPool(ts);
    /* require-problems are unsatisfied, others appear "satisfied" */
    int is_problem = (depTag == RPMTAG_REQUIRENAME);

    while ((h = rpmdbNextIterator(mi)) != NULL) {
	char * pkgNEVRA;
	rpmds ds;

	/* Ignore self-obsoletes and self-conflicts */
	if (depTag == RPMTAG_OBSOLETENAME || depTag == RPMTAG_CONFLICTNAME) {
	    unsigned int instance = headerGetInstance(h);
	    if (instance && instance == rpmteDBInstance(te))
		continue;
	}

	pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA);
	ds = rpmdsNewPool(pool, h, depTag, 0);
	rpmdsSetIx(ds, rpmdbGetIteratorFileNum(mi));

	if (unsatisfiedDepend(ts, dcache, ds) == is_problem)
	    rpmteAddDepProblem(te, pkgNEVRA, ds, NULL);

	rpmdsFree(ds);
	free(pkgNEVRA);
    }
    rpmdbFreeIterator(mi);
}
示例#4
0
文件: tagexts.c 项目: Distrotech/rpm
static int getNEVRA(Header h, rpmtd td, nevraFlags flags)
{
    const char *val = NULL;
    char *res = NULL;

    if ((flags & NEVRA_NAME)) {
	val = headerGetString(h, RPMTAG_NAME);
	if (val) rstrscat(&res, val, "-", NULL);
    }
    if ((flags & NEVRA_EPOCH)) {
	char *e = headerGetAsString(h, RPMTAG_EPOCH);
	if (e) rstrscat(&res, e, ":", NULL);
	free(e);
    }
    if ((flags & NEVRA_VERSION)) {
	val = headerGetString(h, RPMTAG_VERSION);
	if (val) rstrscat(&res, val, "-", NULL);
    }
    if ((flags & NEVRA_RELEASE)) {
	val = headerGetString(h, RPMTAG_RELEASE);
	if (val) rstrscat(&res, val, NULL);
    }
    if ((flags & NEVRA_ARCH)) {
	val = headerGetString(h, RPMTAG_ARCH);
	if (headerIsSource(h) && val == NULL) val = "src";
	if (val) rstrscat(&res, ".", val, NULL);
    }

    td->type = RPM_STRING_TYPE;
    td->data = res;
    td->count = 1;
    td->flags = RPMTD_ALLOCED;

    return 1;
}
示例#5
0
文件: policies.c 项目: kaltsi/rpm
rpmRC processBinaryPolicies(rpmSpec spec, int test)
{
    Package pkg;
    rpmRC rc = RPMRC_OK;
    char *nvr;

#if WITH_SELINUX
    for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
	if (pkg->policyList == NULL) {
	    continue;
	}

	nvr = headerGetAsString(pkg->header, RPMTAG_NVRA);
	rpmlog(RPMLOG_NOTICE, _("Processing policies: %s\n"), nvr);
	free(nvr);

	if (processPolicies(spec, pkg, test) != RPMRC_OK) {
	    rc = RPMRC_FAIL;
	    break;
	}
    }
#endif

    return rc;
}
示例#6
0
static rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body,
                              rpmscriptFlags flags)
{
    char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
    rpmScript script = xcalloc(1, sizeof(*script));
    script->tag = tag;
    script->flags = flags;
    script->body = (body != NULL) ? xstrdup(body) : NULL;
    rasprintf(&script->descr, "%s(%s)", tag2sln(tag), nevra);

    /* macros need to be expanded before possible queryformat */
    if (script->body && (script->flags & RPMSCRIPT_FLAG_EXPAND)) {
        char *body = rpmExpand(script->body, NULL);
        free(script->body);
        script->body = body;
    }
    if (script->body && (script->flags & RPMSCRIPT_FLAG_QFORMAT)) {
        /* XXX TODO: handle queryformat errors */
        char *body = headerFormat(h, script->body, NULL);
        free(script->body);
        script->body = body;
    }

    free(nevra);
    return script;
}
示例#7
0
文件: rpmlead.c 项目: Conan-Kudo/rpm
static int rpmLeadFromHeader(Header h, struct rpmlead_s *l)
{
    if (h != NULL) {
	int archnum, osnum;
	char * nevr = headerGetAsString(h, RPMTAG_NEVR);

	/* FIXME: should grab these from header instead (RhBug:717898) */
	rpmGetArchInfo(NULL, &archnum);
	rpmGetOsInfo(NULL, &osnum);

	memset(l, 0, sizeof(*l));
	l->major = 3;
	l->minor = 0;
	l->archnum = archnum;
	l->osnum = osnum;
	l->signature_type = RPMSIGTYPE_HEADERSIG;
	l->type = (headerIsSource(h) ? 1 : 0);

	memcpy(l->magic, lead_magic, sizeof(l->magic));
	rstrlcpy(l->name, nevr, sizeof(l->name));

	free(nevr);
    }

    return (h != NULL);
}
示例#8
0
文件: pack.c 项目: kaltsi/rpm
/*
 * Add extra provides to package.
 */
static void addPackageProvides(Header h)
{
    const char *arch, *name;
    char *evr, *isaprov;
    rpmsenseFlags pflags = RPMSENSE_EQUAL;

    /* <name> = <evr> provide */
    name = headerGetString(h, RPMTAG_NAME);
    arch = headerGetString(h, RPMTAG_ARCH);
    evr = headerGetAsString(h, RPMTAG_EVR);
    headerPutString(h, RPMTAG_PROVIDENAME, name);
    headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
    headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);

    /*
     * <name>(<isa>) = <evr> provide
     * FIXME: noarch needs special casing for now as BuildArch: noarch doesn't
     * cause reading in the noarch macros :-/ 
     */
    isaprov = rpmExpand(name, "%{?_isa}", NULL);
    if (!rstreq(arch, "noarch") && !rstreq(name, isaprov)) {
	headerPutString(h, RPMTAG_PROVIDENAME, isaprov);
	headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
	headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
    }
    free(isaprov);
    free(evr);
}
示例#9
0
文件: rpmds.c 项目: akozumpl/rpm
rpmds rpmdsThis(Header h, rpmTagVal tagN, rpmsenseFlags Flags)
{
    char *evr = headerGetAsString(h, RPMTAG_EVR);
    rpmds ds = singleDS(tagN, headerGetString(h, RPMTAG_NAME),
			evr, Flags, headerGetInstance(h), 0);
    free(evr);
    return ds;
}
示例#10
0
/* XXX only ts->{probs,rpmdb} modified */
static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi,
				   Header otherHeader, rpmfi otherFi,
				   int beingRemoved)
{
    unsigned int fx = rpmfiFX(fi);
    rpmfs fs = rpmteGetFileStates(p);
    int isCfgFile = ((rpmfiFFlags(otherFi) | rpmfiFFlags(fi)) & RPMFILE_CONFIG);

    if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
	return;

    if (rpmfiCompare(otherFi, fi)) {
	rpm_color_t tscolor = rpmtsColor(ts);
	rpm_color_t prefcolor = rpmtsPrefColor(ts);
	rpm_color_t FColor = rpmfiFColor(fi) & tscolor;
	rpm_color_t oFColor = rpmfiFColor(otherFi) & tscolor;
	int rConflicts;
	char rState = RPMFILE_STATE_REPLACED;

	rConflicts = !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES));
	/* Resolve file conflicts to prefer Elf64 (if not forced). */
	if (tscolor != 0 && FColor != 0 && oFColor != 0 && FColor != oFColor) {
	    if (oFColor & prefcolor) {
		rpmfsSetAction(fs, fx, FA_SKIPCOLOR);
		rConflicts = 0;
	    } else if (FColor & prefcolor) {
		rpmfsSetAction(fs, fx, FA_CREATE);
		rConflicts = 0;
		rState = RPMFILE_STATE_WRONGCOLOR;
	    }
	}

	if (rConflicts) {
	    char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
	    rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, rpmfiFN(fi),
			    headerGetInstance(otherHeader));
	    free(altNEVR);
	}

	/* Save file identifier to mark as state REPLACED. */
	if ( !(isCfgFile || XFA_SKIPPING(rpmfsGetAction(fs, fx))) ) {
	    if (!beingRemoved)
		rpmfsAddReplaced(rpmteGetFileStates(p), rpmfiFX(fi), rState,
				 headerGetInstance(otherHeader),
				 rpmfiFX(otherFi));
	}
    }

    /* Determine config file dispostion, skipping missing files (if any). */
    if (isCfgFile) {
	int skipMissing = ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
	rpmFileAction action = rpmfiDecideFate(otherFi, fi, skipMissing);
	rpmfsSetAction(fs, fx, action);
    }
    rpmfiSetFReplacedSize(fi, rpmfiFSize(otherFi));
}
示例#11
0
文件: legacy.c 项目: OlegGirko/rpm
/*
 * Up to rpm 3.0.4, packages implicitly provided their own name-version-release.
 * Retrofit an explicit "Provides: name = epoch:version-release.
 */
static void providePackageNVR(Header h)
{
    const char *name = headerGetString(h, RPMTAG_NAME);
    char *pEVR = headerGetAsString(h, RPMTAG_EVR);
    rpmsenseFlags pFlags = RPMSENSE_EQUAL;
    int bingo = 1;
    struct rpmtd_s pnames;
    rpmds hds, nvrds;

    /* Generate provides for this package name-version-release. */
    if (!(name && pEVR))
	return;

    /*
     * Rpm prior to 3.0.3 does not have versioned provides.
     * If no provides at all are available, we can just add.
     */
    if (!headerGet(h, RPMTAG_PROVIDENAME, &pnames, HEADERGET_MINMEM)) {
	goto exit;
    }

    /*
     * Otherwise, fill in entries on legacy packages.
     */
    if (!headerIsEntry(h, RPMTAG_PROVIDEVERSION)) {
	while (rpmtdNext(&pnames) >= 0) {
	    rpmsenseFlags fdummy = RPMSENSE_ANY;

	    headerPutString(h, RPMTAG_PROVIDEVERSION, "");
	    headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1);
	}
	goto exit;
    }

    /* see if we already have this provide */
    hds = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
    nvrds = rpmdsSingle(RPMTAG_PROVIDENAME, name, pEVR, pFlags);
    if (rpmdsFind(hds, nvrds) >= 0) {
	bingo = 0;
    }
    rpmdsFree(hds);
    rpmdsFree(nvrds);
    

exit:
    if (bingo) {
	headerPutString(h, RPMTAG_PROVIDENAME, name);
	headerPutString(h, RPMTAG_PROVIDEVERSION, pEVR);
	headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pFlags, 1);
    }
    rpmtdFreeData(&pnames);
    free(pEVR);
}
示例#12
0
/**
 * Ensure that current package is newer than installed package.
 * @param p		current transaction element
 * @param h		installed header
 * @param ps		problem set
 */
static void ensureOlder(const rpmte p, const Header h)
{
    rpmsenseFlags reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL);
    rpmds req;

    req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), rpmteEVR(p), reqFlags);
    if (rpmdsNVRMatchesDep(h, req, _rpmds_nopromote) == 0) {
	char * altNEVR = headerGetAsString(h, RPMTAG_NEVRA);
	rpmteAddProblem(p, RPMPROB_OLDPACKAGE, altNEVR, NULL,
			headerGetInstance(h));
	free(altNEVR);
    }
    rpmdsFree(req);
}
示例#13
0
文件: depends.c 项目: OlegGirko/rpm
/* Check a given dependency type against installed packages */
static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
			  rpmTag depTag, const char *dep)
{
    Header h;
    rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1);
    rpmstrPool pool = rpmtsPool(ts);

    while ((h = rpmdbNextIterator(mi)) != NULL) {
	char * pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA);
	rpmds ds = rpmdsNewPool(pool, h, depTag, 0);

	checkDS(ts, dcache, te, pkgNEVRA, ds, dep, 0);

	rpmdsFree(ds);
	free(pkgNEVRA);
    }
    rpmdbFreeIterator(mi);
}
示例#14
0
文件: rpmts.c 项目: OlegGirko/rpm
static int loadKeyringFromDB(rpmts ts)
{
    Header h;
    rpmdbMatchIterator mi;
    int nkeys = 0;

    rpmlog(RPMLOG_DEBUG, "loading keyring from rpmdb\n");
    mi = rpmtsInitIterator(ts, RPMDBI_NAME, "gpg-pubkey", 0);
    while ((h = rpmdbNextIterator(mi)) != NULL) {
	struct rpmtd_s pubkeys;
	const char *key;

	if (!headerGet(h, RPMTAG_PUBKEYS, &pubkeys, HEADERGET_MINMEM))
	   continue;

	while ((key = rpmtdNextString(&pubkeys))) {
	    uint8_t *pkt;
	    size_t pktlen;

	    if (rpmBase64Decode(key, (void **) &pkt, &pktlen) == 0) {
		rpmPubkey key = rpmPubkeyNew(pkt, pktlen);
		if (rpmKeyringAddKey(ts->keyring, key) == 0) {
		    char *nvr = headerGetAsString(h, RPMTAG_NVR);
		    rpmlog(RPMLOG_DEBUG, "added key %s to keyring\n", nvr);
		    free(nvr);
		    nkeys++;
		}
		rpmPubkeyFree(key);
		free(pkt);
	    }
	}
	rpmtdFreeData(&pubkeys);
    }
    rpmdbFreeIterator(mi);

    return nkeys;
}
示例#15
0
文件: psm.c 项目: fingunter/rpm
static int rpmlibDeps(Header h)
{
    rpmds req = rpmdsInit(rpmdsNew(h, RPMTAG_REQUIRENAME, 0));
    rpmds rpmlib = NULL;
    rpmdsRpmlib(&rpmlib, NULL);
    int rc = 1;
    char *nvr = NULL;
    while (rpmdsNext(req) >= 0) {
	if (!(rpmdsFlags(req) & RPMSENSE_RPMLIB))
	    continue;
	if (rpmdsSearch(rpmlib, req) < 0) {
	    if (!nvr) {
		nvr = headerGetAsString(h, RPMTAG_NEVRA);
		rpmlog(RPMLOG_ERR, _("Missing rpmlib features for %s:\n"), nvr);
	    }
	    rpmlog(RPMLOG_ERR, "\t%s\n", rpmdsDNEVR(req)+2);
	    rc = 0;
	}
    }
    rpmdsFree(req);
    rpmdsFree(rpmlib);
    free(nvr);
    return rc;
}
示例#16
0
static char *getNEVRA(Header h, rpmTag tag, const char **np)
{
    if (np) *np = headerGetString(h, RPMTAG_NAME);
    return headerGetAsString(h, tag);
}
示例#17
0
文件: rpminstall.c 项目: rpm5/rpm
void * rpmShowProgress(const void * arg,
			const rpmCallbackType what,
			const rpm_loff_t amount,
			const rpm_loff_t total,
			fnpyKey key,
			void * data)
{
    Header h = (Header) arg;
    int flags = (int) ((long)data);
    void * rc = NULL;
    const char * filename = (const char *)key;
    static FD_t fd = NULL;

    switch (what) {
    case RPMCALLBACK_INST_OPEN_FILE:
	if (filename == NULL || filename[0] == '\0')
	    return NULL;
	fd = Fopen(filename, "r.ufdio");
	/* FIX: still necessary? */
	if (fd == NULL || Ferror(fd)) {
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), filename,
			Fstrerror(fd));
	    if (fd != NULL) {
		Fclose(fd);
		fd = NULL;
	    }
	} else
	    fd = fdLink(fd);
#if defined(POSIX_FADV_WILLNEED)
	(void) Fadvise(fd, 0, 0, POSIX_FADV_WILLNEED);
#endif
	return (void *)fd;
	break;

    case RPMCALLBACK_INST_CLOSE_FILE:
	/* FIX: still necessary? */
	fd = fdFree(fd);
	if (fd != NULL) {
	    Fclose(fd);
	    fd = NULL;
	}
	break;

    case RPMCALLBACK_INST_START:
    case RPMCALLBACK_UNINST_START:
	if (rpmcliProgressState != what) {
	    rpmcliProgressState = what;
	    if (flags & INSTALL_HASH) {
		if (what == RPMCALLBACK_INST_START) {
		    fprintf(stdout, _("Updating / installing...\n"));
		} else {
		    fprintf(stdout, _("Cleaning up / removing...\n"));
		}
		fflush(stdout);
	    }
	}
		
	rpmcliHashesCurrent = 0;
	if (h == NULL || !(flags & INSTALL_LABEL))
	    break;
	if (flags & INSTALL_HASH) {
	    char *s = headerGetAsString(h, RPMTAG_NEVR);
	    if (isatty (STDOUT_FILENO))
		fprintf(stdout, "%4d:%-33.33s", rpmcliProgressCurrent + 1, s);
	    else
		fprintf(stdout, "%-38.38s", s);
	    (void) fflush(stdout);
	    free(s);
	} else {
	    char *s = headerGetAsString(h, RPMTAG_NEVRA);
	    fprintf(stdout, "%s\n", s);
	    (void) fflush(stdout);
	    free(s);
	}
	break;

    case RPMCALLBACK_INST_STOP:
	break;

    case RPMCALLBACK_TRANS_PROGRESS:
    case RPMCALLBACK_INST_PROGRESS:
    case RPMCALLBACK_UNINST_PROGRESS:
	if (flags & INSTALL_PERCENT)
	    fprintf(stdout, "%%%% %f\n", (double) (total
				? ((((float) amount) / total) * 100)
				: 100.0));
	else if (flags & INSTALL_HASH)
	    printHash(amount, total);
	(void) fflush(stdout);
	break;

    case RPMCALLBACK_TRANS_START:
	rpmcliHashesCurrent = 0;
	rpmcliProgressTotal = 1;
	rpmcliProgressCurrent = 0;
	rpmcliPackagesTotal = total;
	rpmcliProgressState = what;
	if (!(flags & INSTALL_LABEL))
	    break;
	if (flags & INSTALL_HASH)
	    fprintf(stdout, "%-38s", _("Preparing..."));
	else
	    fprintf(stdout, "%s\n", _("Preparing packages..."));
	(void) fflush(stdout);
	break;

    case RPMCALLBACK_TRANS_STOP:
	if (flags & INSTALL_HASH)
	    printHash(1, 1);	/* Fixes "preparing..." progress bar */
	rpmcliProgressTotal = rpmcliPackagesTotal;
	rpmcliProgressCurrent = 0;
	break;

    case RPMCALLBACK_UNINST_STOP:
	break;
    case RPMCALLBACK_UNPACK_ERROR:
	break;
    case RPMCALLBACK_CPIO_ERROR:
	break;
    case RPMCALLBACK_SCRIPT_ERROR:
	break;
    case RPMCALLBACK_SCRIPT_START:
	break;
    case RPMCALLBACK_SCRIPT_STOP:
	break;
    case RPMCALLBACK_UNKNOWN:
    default:
	break;
    }

    return rc;
}	
示例#18
0
文件: psm.c 项目: fingunter/rpm
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd,
		char ** specFilePtr, char ** cookie)
{
    Header h = NULL;
    rpmpsm psm = NULL;
    rpmte te = NULL;
    rpmRC rpmrc;
    int specix = -1;

    rpmrc = rpmReadPackageFile(ts, fd, NULL, &h);
    switch (rpmrc) {
    case RPMRC_NOTTRUSTED:
    case RPMRC_NOKEY:
    case RPMRC_OK:
	break;
    default:
	goto exit;
	break;
    }
    if (h == NULL)
	goto exit;

    rpmrc = RPMRC_FAIL; /* assume failure */

    if (!headerIsSource(h)) {
	rpmlog(RPMLOG_ERR, _("source package expected, binary found\n"));
	goto exit;
    }

    /* src.rpm install can require specific rpmlib features, check them */
    if (!rpmlibDeps(h))
	goto exit;

    specix = headerFindSpec(h);

    if (specix < 0) {
	rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n"));
	goto exit;
    };

    if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) {
	goto exit;
    }

    te = rpmtsElement(ts, 0);
    if (te == NULL) {	/* XXX can't happen */
	goto exit;
    }
    rpmteSetFd(te, fd);

    rpmteSetHeader(te, h);

    {
	/* set all files to be installed */
	rpmfs fs = rpmteGetFileStates(te);
	int fc = rpmfsFC(fs);
	for (int i = 0; i < fc; i++)
	    rpmfsSetAction(fs, i, FA_CREATE);
    }

    psm = rpmpsmNew(ts, te, PKG_INSTALL);

    if (rpmpsmUnpack(psm) == RPMRC_OK)
	rpmrc = RPMRC_OK;

    rpmpsmFree(psm);

exit:
    if (rpmrc == RPMRC_OK && specix >= 0) {
	if (cookie)
	    *cookie = headerGetAsString(h, RPMTAG_COOKIE);
	if (specFilePtr) {
	    rpmfiles files = rpmteFiles(te);
	    *specFilePtr = rpmfilesFN(files, specix);
	    rpmfilesFree(files);
	}
    }

    /* XXX nuke the added package(s). */
    headerFree(h);
    rpmtsEmpty(ts);

    return rpmrc;
}
示例#19
0
/* XXX only ts->{probs,rpmdb} modified */
static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfiles fi, int fx,
				   Header otherHeader, rpmfiles otherFi, int ofx,
				   int beingRemoved)
{
    rpmfs fs = rpmteGetFileStates(p);
    int isCfgFile = ((rpmfilesFFlags(otherFi, ofx) | rpmfilesFFlags(fi, fx)) & RPMFILE_CONFIG);

    if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
	return;

    if (rpmfilesCompare(otherFi, ofx, fi, fx)) {
	int rConflicts = 1;
	char rState = RPMFILE_STATE_REPLACED;

	/*
	 * There are some removal conflicts we can't handle. However
	 * if the package has a %pretrans scriptlet, it might be able to
	 * fix the conflict. Let it through on test-transaction to allow
	 * eg yum to get past it, if the conflict is present on the actual
	 * transaction we'll abort. Behaving differently on test is nasty,
	 * but its still better than barfing in middle of large transaction.
	 */
	if (beingRemoved) {
	    rConflicts = handleRemovalConflict(fi, fx, otherFi, ofx);
	    if (rConflicts && rpmteHaveTransScript(p, RPMTAG_PRETRANS)) {
		if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
		    rConflicts = 0;
	    }
	}

	if (rConflicts) {
	    /* If enabled, resolve colored conflicts to preferred type */
	    rConflicts = handleColorConflict(ts, fs, fi, fx,
					     NULL, otherFi, ofx);
	    /* If resolved, we need to adjust in-rpmdb state too */
	    if (rConflicts == 0 && rpmfsGetAction(fs, fx) == FA_CREATE)
		rState = RPMFILE_STATE_WRONGCOLOR;
	}

	/* Somebody used The Force, lets shut up... */
	if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES)
	    rConflicts = 0;

	if (rConflicts) {
	    char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
	    char *fn = rpmfilesFN(fi, fx);
	    rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, fn,
			    headerGetInstance(otherHeader));
	    free(fn);
	    free(altNEVR);
	}

	/* Save file identifier to mark as state REPLACED. */
	if ( !(isCfgFile || XFA_SKIPPING(rpmfsGetAction(fs, fx))) ) {
	    if (!beingRemoved)
		rpmfsAddReplaced(rpmteGetFileStates(p), fx, rState,
				 headerGetInstance(otherHeader), ofx);
	}
    }

    /* Determine config file disposition, skipping missing files (if any). */
    if (isCfgFile) {
	int skipMissing = ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
	rpmFileAction action;
	action = rpmfilesDecideFate(otherFi, ofx, fi, fx, skipMissing);
	rpmfsSetAction(fs, fx, action);
    }
    rpmfilesSetFReplacedSize(fi, fx, rpmfilesFSize(otherFi, ofx));
}