Ejemplo n.º 1
0
int headerFindSpec(Header h)
{
    struct rpmtd_s filenames;
    int specix = -1;

    if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_MINMEM)) {
	struct rpmtd_s td;
	const char *str;
	
	/* Try to find spec by file flags */
	if (headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) {
	    rpmfileAttrs *flags;
	    while (specix < 0 && (flags = rpmtdNextUint32(&td))) {
		if (*flags & RPMFILE_SPECFILE)
		    specix = rpmtdGetIndex(&td);
	    }
	    rpmtdFreeData(&td);
	}
	/* Still no spec? Look by filename. */
	while (specix < 0 && (str = rpmtdNextString(&filenames))) {
	    if (rpmFileHasSuffix(str, ".spec")) 
		specix = rpmtdGetIndex(&filenames);
	}
	rpmtdFreeData(&filenames);
    }
    return specix;
}
Ejemplo n.º 2
0
Archivo: psm.c Proyecto: fingunter/rpm
/**
 * Run triggers from this header that are fired by headers in the database.
 * @param psm		package state machine data
 * @param sense		trigger type
 * @return		0 on success
 */
static rpmRC runImmedTriggers(rpmpsm psm, rpmsenseFlags sense)
{
    const rpmts ts = psm->ts;
    unsigned char * triggersRun;
    struct rpmtd_s tnames, tindexes;
    Header h = rpmteHeader(psm->te);
    int nerrors = 0;

    if (!(headerGet(h, RPMTAG_TRIGGERNAME, &tnames, HEADERGET_MINMEM) &&
	  headerGet(h, RPMTAG_TRIGGERINDEX, &tindexes, HEADERGET_MINMEM))) {
	goto exit;
    }

    triggersRun = xcalloc(rpmtdCount(&tindexes), sizeof(*triggersRun));
    {	Header sourceH = NULL;
	const char *trigName;
    	rpm_count_t *triggerIndices = tindexes.data;

	while ((trigName = rpmtdNextString(&tnames))) {
	    rpmdbMatchIterator mi;
	    int i = rpmtdGetIndex(&tnames);

	    if (triggersRun[triggerIndices[i]] != 0) continue;
	
	    mi = rpmtsInitIterator(ts, RPMDBI_NAME, trigName, 0);

	    while((sourceH = rpmdbNextIterator(mi)) != NULL) {
		nerrors += handleOneTrigger(psm->ts, psm->te,
				sense, sourceH, h,
				psm->countCorrection,
				rpmdbGetIteratorCount(mi),
				triggersRun);
	    }

	    rpmdbFreeIterator(mi);
	}
    }
    rpmtdFreeData(&tnames);
    rpmtdFreeData(&tindexes);
    free(triggersRun);

exit:
    headerFree(h);
    return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
}
Ejemplo n.º 3
0
static int haveLangTag(Header h, rpmTagVal tag, const char *lang)
{
    int rc = 0;	/* assume tag not present */
    int langNum = -1;

    if (lang && *lang) {
	/* See if the language is in header i18n table */
	struct rpmtd_s langtd;
	const char *s = NULL;
	headerGet(h, RPMTAG_HEADERI18NTABLE, &langtd, HEADERGET_MINMEM);
	while ((s = rpmtdNextString(&langtd)) != NULL) {
	    if (rstreq(s, lang)) {
		langNum = rpmtdGetIndex(&langtd);
		break;
	    }
	}
	rpmtdFreeData(&langtd);
    } else {
	/* C locale */
	langNum = 0;
    }

    /* If locale is present, check the actual tag content */
    if (langNum >= 0) {
	struct rpmtd_s td;
	headerGet(h, tag, &td, HEADERGET_MINMEM|HEADERGET_RAW);
	if (rpmtdSetIndex(&td, langNum) == langNum) {
	    const char *s = rpmtdGetString(&td);
	    /* non-empty string means a dupe */
	    if (s && *s)
		rc = 1;
	}
	rpmtdFreeData(&td);
    };

    return rc;
}
Ejemplo n.º 4
0
static rpmRC writeModuleToHeader(ModuleRec mod, Package pkg)
{
    rpmRC rc = RPMRC_FAIL;
    ARGV_t av;
    uint32_t count;
    struct rpmtd_s policies;
    struct rpmtd_s policynames;
    struct rpmtd_s policyflags;
    struct rpmtd_s policytypes;
    struct rpmtd_s policytypesidx;
    rpmtdReset(&policies);
    rpmtdReset(&policynames);
    rpmtdReset(&policyflags);
    rpmtdReset(&policytypes);
    rpmtdReset(&policytypesidx);

    if (!mod || !pkg) {
	goto exit;
    }

    /* check for duplicates */
    if (headerIsEntry(pkg->header, RPMTAG_POLICYNAMES)) {
	int typeCount;
	const char *name;
	char *type;
	int i;
	int idx;

	headerGet(pkg->header, RPMTAG_POLICYNAMES, &policynames, HEADERGET_MINMEM);
	headerGet(pkg->header, RPMTAG_POLICYFLAGS, &policyflags, HEADERGET_ARGV | HEADERGET_MINMEM);
	headerGet(pkg->header, RPMTAG_POLICYTYPES, &policytypes, HEADERGET_ARGV | HEADERGET_MINMEM);
	headerGet(pkg->header, RPMTAG_POLICYTYPESINDEXES, &policytypesidx, HEADERGET_ARGV | HEADERGET_MINMEM);
	typeCount = rpmtdCount(&policytypes);

	while ((name = rpmtdNextString(&policynames))) {
	    int overlappingtypes = 0;

	    idx = rpmtdGetIndex(&policynames);

	    for (i = 0; i < typeCount; i++) {
		if (((int *) policytypesidx.data)[i] != idx) {
		    continue;
		}

		type = ((char **) policytypes.data)[i];

		if (rstreq(type, RPMPOL_TYPE_DEFAULT) ||
		    argvSearch(mod->types, type, NULL) ||
		    argvSearch(mod->types, RPMPOL_TYPE_DEFAULT, NULL)) {
		    overlappingtypes = 1;
		    break;
		}
	    }

	    if (!overlappingtypes) {
		continue;
	    }

	    if (rstreq(mod->name, name)) {
		rpmlog(RPMLOG_ERR, _("Policy module '%s' duplicated with overlapping types\n"), name);
		goto exit;
	    }

	    if ((mod->flags && RPMPOL_FLAG_BASE) &&
		(((int *) policyflags.data)[idx] & RPMPOL_FLAG_BASE)) {
		rpmlog(RPMLOG_ERR, _("Base modules '%s' and '%s' have overlapping types\n"), mod->name, name);
		goto exit;
	    }
	}
    }

    if (headerIsEntry(pkg->header, RPMTAG_POLICIES)) {
	if (!headerGet(pkg->header, RPMTAG_POLICIES, &policies, HEADERGET_MINMEM)) {
	    rpmlog(RPMLOG_ERR, _("Failed to get policies from header\n"));
	    goto exit;
	}
	count = rpmtdCount(&policies);
    } else {
	count = 0;
    }

    /* save everything to the header */
    headerPutString(pkg->header, RPMTAG_POLICIES, mod->data);
    headerPutString(pkg->header, RPMTAG_POLICYNAMES, mod->name);
    headerPutUint32(pkg->header, RPMTAG_POLICYFLAGS, &mod->flags, 1);

    for (av = mod->types; av && *av; av++) {
	headerPutString(pkg->header, RPMTAG_POLICYTYPES, *av);
	headerPutUint32(pkg->header, RPMTAG_POLICYTYPESINDEXES, &count, 1);
    }

    rc = RPMRC_OK;

  exit:

    rpmtdFreeData(&policies);
    rpmtdFreeData(&policynames);
    rpmtdFreeData(&policyflags);
    rpmtdFreeData(&policytypes);
    rpmtdFreeData(&policytypesidx);

    return rc;
}
Ejemplo n.º 5
0
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd,
		char ** specFilePtr, char ** cookie)
{
    rpmfi fi = NULL;
    char * specFile = NULL;
    const char *rootdir = rpmtsRootDir(ts);
    Header h = NULL;
    rpmpsm psm = NULL;
    rpmte te = NULL;
    rpmRC rpmrc;
    int specix = -1;
    struct rpmtd_s filenames;

    rpmtdReset(&filenames);
    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;

    if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_ALLOC)) {
	struct rpmtd_s td;
	const char *str;
	const char *_cookie = headerGetString(h, RPMTAG_COOKIE);
	if (cookie && _cookie) *cookie = xstrdup(_cookie);
	
	/* Try to find spec by file flags */
	if (_cookie && headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) {
	    rpmfileAttrs *flags;
	    while (specix < 0 && (flags = rpmtdNextUint32(&td))) {
		if (*flags & RPMFILE_SPECFILE)
		    specix = rpmtdGetIndex(&td);
	    }
	}
	/* Still no spec? Look by filename. */
	while (specix < 0 && (str = rpmtdNextString(&filenames))) {
	    if (rpmFileHasSuffix(str, ".spec")) 
		specix = rpmtdGetIndex(&filenames);
	}
    }

    if (rootdir && rstreq(rootdir, "/"))
	rootdir = NULL;

    /* Macros need to be added before trying to create directories */
    rpmInstallLoadMacros(h);

    if (specix >= 0) {
	const char *bn;

	headerDel(h, RPMTAG_BASENAMES);
	headerDel(h, RPMTAG_DIRNAMES);
	headerDel(h, RPMTAG_DIRINDEXES);

	rpmtdInit(&filenames);
	for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) {
	    int spec = (i == specix);
	    char *fn = rpmGenPath(rpmtsRootDir(ts),
				  spec ? "%{_specdir}" : "%{_sourcedir}", bn);
	    headerPutString(h, RPMTAG_OLDFILENAMES, fn);
	    if (spec) specFile = xstrdup(fn);
	    free(fn);
	}
	headerConvert(h, HEADERCONV_COMPRESSFILELIST);
    } else {
	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);
    fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
    h = headerFree(h);

    if (fi == NULL) {
	goto exit;
    }
    fi->apath = filenames.data; /* Ick */
    rpmteSetFI(te, fi);
    fi = rpmfiFree(fi);

    if (rpmMkdirs(rpmtsRootDir(ts), "%{_topdir}:%{_sourcedir}:%{_specdir}")) {
	goto exit;
    }

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

    psm = rpmpsmNew(ts, te);
    psm->goal = PKG_INSTALL;

   	/* FIX: psm->fi->dnl should be owned. */
    if (rpmpsmStage(psm, PSM_PROCESS) == RPMRC_OK)
	rpmrc = RPMRC_OK;

    (void) rpmpsmStage(psm, PSM_FINI);
    rpmpsmFree(psm);

exit:
    if (specFilePtr && specFile && rpmrc == RPMRC_OK)
	*specFilePtr = specFile;
    else
	free(specFile);

    headerFree(h);
    rpmfiFree(fi);

    /* XXX nuke the added package(s). */
    rpmtsClean(ts);

    return rpmrc;
}
Ejemplo n.º 6
0
Archivo: rpmvs.c Proyecto: junaruga/rpm
static rpmRC rpmsinfoInit(rpmtd td, const char *origin,
		      struct rpmsinfo_s *sinfo, char **msg)
{
    rpmRC rc = RPMRC_FAIL;
    const void *data = NULL;
    const struct vfytag_s *tinfo;
    const struct vfyinfo_s *vinfo;
    rpm_count_t dlen = 0;
    int ix;

    if ((ix = sinfoLookup(td->tag)) == -1) {
	/* anything unknown just falls through for now */
	rc = RPMRC_OK;
	goto exit;
    }
    vinfo = &rpmvfyitems[ix];
    tinfo = &rpmvfytags[ix];
    assert(tinfo->tag == vinfo->tag);

    *sinfo = rpmvfyitems[ix].vi; /* struct assignment */

    if (tinfo->tagtype && tinfo->tagtype != td->type) {
	rasprintf(msg, _("%s tag %u: invalid type %u"),
			origin, td->tag, td->type);
	goto exit;
    }

    if (tinfo->tagcount && tinfo->tagcount != td->count) {
	rasprintf(msg, _("%s: tag %u: invalid count %u"),
			origin, td->tag, td->count);
	goto exit;
    }

    switch (td->type) {
    case RPM_STRING_TYPE:
    case RPM_STRING_ARRAY_TYPE:
	data = rpmtdGetString(td);
	if (data)
	    dlen = strlen(data);
	break;
    case RPM_BIN_TYPE:
	data = td->data;
	dlen = td->count;
	break;
    }

    /* MD5 has data length of 16, everything else is (much) larger */
    if (sinfo->hashalgo && (data == NULL || dlen < 16)) {
	rasprintf(msg, _("%s tag %u: invalid data %p (%u)"),
			origin, td->tag, data, dlen);
	goto exit;
    }

    if (td->type == RPM_STRING_TYPE && td->size == 0)
	td->size = dlen + 1;

    if (tinfo->tagsize && (td->flags & RPMTD_IMMUTABLE) &&
		tinfo->tagsize != td->size) {
	rasprintf(msg, _("%s tag %u: invalid size %u"),
			origin, td->tag, td->size);
	goto exit;
    }

    if (sinfo->type == RPMSIG_SIGNATURE_TYPE) {
	if (pgpPrtParams(data, dlen, PGPTAG_SIGNATURE, &sinfo->sig)) {
	    rasprintf(msg, _("%s tag %u: invalid OpenPGP signature"),
		    origin, td->tag);
	    goto exit;
	}
	sinfo->hashalgo = pgpDigParamsAlgo(sinfo->sig, PGPVAL_HASHALGO);
	sinfo->keyid = pgpGrab(sinfo->sig->signid+4, 4);
    } else if (sinfo->type == RPMSIG_DIGEST_TYPE) {
	if (td->type == RPM_BIN_TYPE) {
	    sinfo->dig = pgpHexStr(data, dlen);
	} else {
	    if (!validHex(data, dlen)) {
		rasprintf(msg, _("%s: tag %u: invalid hex"), origin, td->tag);
		goto exit;
	    }
	    sinfo->dig = xstrdup(data);
	}
    }

    if (sinfo->hashalgo)
	sinfo->id = (td->tag << 16) | rpmtdGetIndex(td);

    rc = RPMRC_OK;

exit:
    return rc;
}