Esempio n. 1
0
int parseSpec(rpmts ts, const char *specFile, const char *rootDir,
		const char *buildRoot, int recursing, const char *passPhrase,
		const char *cookie, int anyarch, int force)
{
    rpmParseState parsePart = PART_PREAMBLE;
    int initialPackage = 1;
    Package pkg;
    rpmSpec spec;
    
    /* Set up a new Spec structure with no packages. */
    spec = newSpec();

    spec->specFile = rpmGetPath(specFile, NULL);
    spec->fileStack = newOpenFileInfo();
    spec->fileStack->fileName = xstrdup(spec->specFile);
    /* If buildRoot not specified, use default %{buildroot} */
    if (buildRoot) {
	spec->buildRoot = xstrdup(buildRoot);
    } else {
	spec->buildRoot = rpmGetPath("%{?buildroot:%{buildroot}}", NULL);
    }
    addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
    spec->recursing = recursing;
    spec->anyarch = anyarch;
    spec->force = force;

    if (rootDir)
	spec->rootDir = xstrdup(rootDir);
    if (passPhrase)
	spec->passPhrase = xstrdup(passPhrase);
    if (cookie)
	spec->cookie = xstrdup(cookie);

    spec->timeCheck = rpmExpandNumeric("%{_timecheck}");

    /* All the parse*() functions expect to have a line pre-read */
    /* in the spec's line buffer.  Except for parsePreamble(),   */
    /* which handles the initial entry into a spec file.         */
    
    while (parsePart != PART_NONE) {
	int goterror = 0;
	switch (parsePart) {
	/* XXX Trap unexpected RPMRC_FAIL returns for now */
	case RPMRC_FAIL:
	    rpmlog(RPMLOG_ERR, "FIXME: got RPMRC_FAIL from spec parse\n");
	    abort();
	case PART_ERROR: /* fallthrough */
	default:
	    goterror = 1;
	    break;
	case PART_PREAMBLE:
	    parsePart = parsePreamble(spec, initialPackage);
	    initialPackage = 0;
	    break;
	case PART_PREP:
	    parsePart = parsePrep(spec);
	    break;
	case PART_BUILD:
	case PART_INSTALL:
	case PART_CHECK:
	case PART_CLEAN:
	    parsePart = parseBuildInstallClean(spec, parsePart);
	    break;
	case PART_CHANGELOG:
	    parsePart = parseChangelog(spec);
	    break;
	case PART_DESCRIPTION:
	    parsePart = parseDescription(spec);
	    break;

	case PART_PRE:
	case PART_POST:
	case PART_PREUN:
	case PART_POSTUN:
	case PART_PRETRANS:
	case PART_POSTTRANS:
	case PART_VERIFYSCRIPT:
	case PART_TRIGGERPREIN:
	case PART_TRIGGERIN:
	case PART_TRIGGERUN:
	case PART_TRIGGERPOSTUN:
	    parsePart = parseScript(spec, parsePart);
	    break;

	case PART_FILES:
	    parsePart = parseFiles(spec);
	    break;

	case PART_NONE:		/* XXX avoid gcc whining */
	case PART_LAST:
	case PART_BUILDARCHITECTURES:
	    break;
	}

	if (goterror || parsePart >= PART_LAST) {
	    goto errxit;
	}

	if (parsePart == PART_BUILDARCHITECTURES) {
	    int index;
	    int x;

	    closeSpec(spec);

	    spec->BASpecs = xcalloc(spec->BACount, sizeof(*spec->BASpecs));
	    index = 0;
	    if (spec->BANames != NULL)
	    for (x = 0; x < spec->BACount; x++) {

		/* Skip if not arch is not compatible. */
		if (!rpmMachineScore(RPM_MACHTABLE_BUILDARCH, spec->BANames[x]))
		    continue;
		addMacro(NULL, "_target_cpu", NULL, spec->BANames[x], RMIL_RPMRC);
		spec->BASpecs[index] = NULL;
		if (parseSpec(ts, specFile, spec->rootDir, buildRoot, 1,
				  passPhrase, cookie, anyarch, force)
		 || (spec->BASpecs[index] = rpmtsSetSpec(ts, NULL)) == NULL)
		{
			spec->BACount = index;
			goto errxit;
		}
		delMacro(NULL, "_target_cpu");
		index++;
	    }

	    spec->BACount = index;
	    if (! index) {
		rpmlog(RPMLOG_ERR,
			_("No compatible architectures found for build\n"));
		goto errxit;
	    }

	    /*
	     * Return the 1st child's fully parsed Spec structure.
	     * The restart of the parse when encountering BuildArch
	     * causes problems for "rpm -q --specfile". This is
	     * still a hack because there may be more than 1 arch
	     * specified (unlikely but possible.) There's also the
	     * further problem that the macro context, particularly
	     * %{_target_cpu}, disagrees with the info in the header.
	     */
	    if (spec->BACount >= 1) {
		rpmSpec nspec = spec->BASpecs[0];
		spec->BASpecs = _free(spec->BASpecs);
		spec = freeSpec(spec);
		spec = nspec;
	    }

	    (void) rpmtsSetSpec(ts, spec);
	    return 0;
	}
    }

    if (spec->clean == NULL) {
	char *body = rpmExpand("%{?buildroot: %{__rm} -rf %{buildroot}}", NULL);
	spec->clean = newStringBuf();
	appendLineStringBuf(spec->clean, body);
	free(body);
    }

    /* Check for description in each package and add arch and os */
  {
    char *platform = rpmExpand("%{_target_platform}", NULL);
    char *arch = rpmExpand("%{_target_cpu}", NULL);
    char *os = rpmExpand("%{_target_os}", NULL);

    for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
	if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
	    rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
		   headerGetString(pkg->header, RPMTAG_NAME));
	    goto errxit;
	}

	headerPutString(pkg->header, RPMTAG_OS, os);
	/* noarch subpackages already have arch set here, leave it alone */
	if (!headerIsEntry(pkg->header, RPMTAG_ARCH)) {
	    headerPutString(pkg->header, RPMTAG_ARCH, arch);
	}
	headerPutString(pkg->header, RPMTAG_PLATFORM, platform);

	pkg->ds = rpmdsThis(pkg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);

    }

    platform = _free(platform);
    arch = _free(arch);
    os = _free(os);
  }

    closeSpec(spec);
    (void) rpmtsSetSpec(ts, spec);

    return 0;

errxit:
    spec = freeSpec(spec);
    return PART_ERROR;
}
Esempio n. 2
0
static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
                         const char *buildRoot, int recursing)
{
    int parsePart = PART_PREAMBLE;
    int initialPackage = 1;
    rpmSpec spec;

    /* Set up a new Spec structure with no packages. */
    spec = newSpec();

    spec->specFile = rpmGetPath(specFile, NULL);
    pushOFI(spec, spec->specFile);
    /* If buildRoot not specified, use default %{buildroot} */
    if (buildRoot) {
        spec->buildRoot = xstrdup(buildRoot);
    } else {
        spec->buildRoot = rpmGetPath("%{?buildroot:%{buildroot}}", NULL);
    }
    addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
    addMacro(NULL, "_licensedir", NULL, "%{_defaultlicensedir}", RMIL_SPEC);
    spec->recursing = recursing;
    spec->flags = flags;

    /* All the parse*() functions expect to have a line pre-read */
    /* in the spec's line buffer.  Except for parsePreamble(),   */
    /* which handles the initial entry into a spec file.         */

    while (parsePart != PART_NONE) {
        int goterror = 0;
        switch (parsePart) {
        case PART_ERROR: /* fallthrough */
        default:
            goterror = 1;
            break;
        case PART_PREAMBLE:
            parsePart = parsePreamble(spec, initialPackage);
            initialPackage = 0;
            break;
        case PART_PREP:
            parsePart = parsePrep(spec);
            break;
        case PART_BUILD:
        case PART_INSTALL:
        case PART_CHECK:
        case PART_CLEAN:
            parsePart = parseBuildInstallClean(spec, parsePart);
            break;
        case PART_CHANGELOG:
            parsePart = parseChangelog(spec);
            break;
        case PART_DESCRIPTION:
            parsePart = parseDescription(spec);
            break;

        case PART_PRE:
        case PART_POST:
        case PART_PREUN:
        case PART_POSTUN:
        case PART_PRETRANS:
        case PART_POSTTRANS:
        case PART_VERIFYSCRIPT:
        case PART_TRIGGERPREIN:
        case PART_TRIGGERIN:
        case PART_TRIGGERUN:
        case PART_TRIGGERPOSTUN:
        case PART_FILETRIGGERIN:
        case PART_FILETRIGGERUN:
        case PART_FILETRIGGERPOSTUN:
        case PART_TRANSFILETRIGGERIN:
        case PART_TRANSFILETRIGGERUN:
        case PART_TRANSFILETRIGGERPOSTUN:
            parsePart = parseScript(spec, parsePart);
            break;

        case PART_FILES:
            parsePart = parseFiles(spec);
            break;

        case PART_POLICIES:
            parsePart = parsePolicies(spec);
            break;

        case PART_NONE:		/* XXX avoid gcc whining */
        case PART_LAST:
        case PART_BUILDARCHITECTURES:
            break;
        }

        if (goterror || parsePart >= PART_LAST) {
            goto errxit;
        }

        if (parsePart == PART_BUILDARCHITECTURES) {
            int index;
            int x;

            closeSpec(spec);

            spec->BASpecs = xcalloc(spec->BACount, sizeof(*spec->BASpecs));
            index = 0;
            if (spec->BANames != NULL)
                for (x = 0; x < spec->BACount; x++) {

                    /* Skip if not arch is not compatible. */
                    if (!rpmMachineScore(RPM_MACHTABLE_BUILDARCH, spec->BANames[x]))
                        continue;
                    addMacro(NULL, "_target_cpu", NULL, spec->BANames[x], RMIL_RPMRC);
                    spec->BASpecs[index] = parseSpec(specFile, flags, buildRoot, 1);
                    if (spec->BASpecs[index] == NULL) {
                        spec->BACount = index;
                        goto errxit;
                    }
                    delMacro(NULL, "_target_cpu");
                    index++;
                }

            spec->BACount = index;
            if (! index) {
                rpmlog(RPMLOG_ERR,
                       _("No compatible architectures found for build\n"));
                goto errxit;
            }

            /*
             * Return the 1st child's fully parsed Spec structure.
             * The restart of the parse when encountering BuildArch
             * causes problems for "rpm -q --specfile". This is
             * still a hack because there may be more than 1 arch
             * specified (unlikely but possible.) There's also the
             * further problem that the macro context, particularly
             * %{_target_cpu}, disagrees with the info in the header.
             */
            if (spec->BACount >= 1) {
                rpmSpec nspec = spec->BASpecs[0];
                spec->BASpecs = _free(spec->BASpecs);
                rpmSpecFree(spec);
                spec = nspec;
            }

            goto exit;
        }
    }

    if (spec->clean == NULL) {
        char *body = rpmExpand("%{?buildroot: %{__rm} -rf %{buildroot}}", NULL);
        spec->clean = newStringBuf();
        appendLineStringBuf(spec->clean, body);
        free(body);
    }

    /* Check for description in each package */
    for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
        if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
            rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
                   headerGetString(pkg->header, RPMTAG_NAME));
            goto errxit;
        }
    }

    /* Add arch, os and platform, self-provides etc for each package */
    addTargets(spec->packages);

    /* Check for encoding in each package unless disabled */
    if (!(spec->flags & RPMSPEC_NOUTF8)) {
        int badenc = 0;
        for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
            if (checkForEncoding(pkg->header, 0) != RPMRC_OK) {
                badenc = 1;
            }
        }
        if (badenc)
            goto errxit;
    }

    closeSpec(spec);
exit:
    /* Assemble source header from parsed components */
    initSourceHeader(spec);

    return spec;

errxit:
    rpmSpecFree(spec);
    return NULL;
}
Esempio n. 3
0
static void specFini(void * _spec)
	/*@modifies _spec @*/
{
    Spec spec = _spec;
    struct ReadLevelEntry *rl;

    if (spec == NULL) return;	/* XXX assert? */

    spec->lbuf = _free(spec->lbuf);

    spec->sl = freeSl(spec->sl);
    spec->st = freeSt(spec->st);

    spec->prep = rpmiobFree(spec->prep);
    spec->build = rpmiobFree(spec->build);
    spec->install = rpmiobFree(spec->install);
    spec->check = rpmiobFree(spec->check);
    spec->clean = rpmiobFree(spec->clean);
    spec->foo = tagStoreFree(spec->foo, spec->nfoo);
    spec->nfoo = 0;

    spec->buildSubdir = _free(spec->buildSubdir);
    spec->rootURL = _free(spec->rootURL);
    spec->specFile = _free(spec->specFile);

    closeSpec(spec);

    while (spec->readStack) {
	rl = spec->readStack;
	/*@-dependenttrans@*/
	spec->readStack = rl->next;
	/*@=dependenttrans@*/
	rl->next = NULL;
	rl = _free(rl);
    }
    
    spec->sourceRpmName = _free(spec->sourceRpmName);
    spec->sourcePkgId = _free(spec->sourcePkgId);
    spec->sourceHeader = headerFree(spec->sourceHeader);

    if (spec->fi != NULL) {
	rpmfi fi = spec->fi;
	spec->fi = NULL;
	fi = rpmfiFree(fi);
    }
    
    if (!spec->recursing) {
	if (spec->BASpecs != NULL)
	while (spec->BACount--) {
	    /*@-unqualifiedtrans@*/
	    spec->BASpecs[spec->BACount] =
			freeSpec(spec->BASpecs[spec->BACount]);
	    /*@=unqualifiedtrans@*/
	}
	/*@-compdef@*/
	spec->BASpecs = _free(spec->BASpecs);
	/*@=compdef@*/
    }
    spec->BANames = _free(spec->BANames);

    spec->passPhrase = _free(spec->passPhrase);
    spec->cookie = _free(spec->cookie);

#ifdef WITH_LUA
    {	rpmlua lua = NULL; /* global state */
	rpmluaDelVar(lua, "patches");
	rpmluaDelVar(lua, "sources");	
    }
#endif

    spec->sources = freeSources(spec->sources);

    spec->dig = pgpDigFree(spec->dig);
    spec->packages = freePackages(spec->packages);
    
}