Ejemplo n.º 1
0
static int rpm_slurp(lua_State *L)
/*@globals fileSystem, internalState @*/
/*@modifies L, fileSystem, internalState @*/
{
    rpmiob iob = NULL;
    const char *fn;
    int rc;

    if (lua_isstring(L, 1))
        fn = lua_tostring(L, 1);
    else {
        (void)luaL_argerror(L, 1, "filename");
        return 0;
    }
    /*@-globs@*/
    rc = rpmiobSlurp(fn, &iob);
    /*@=globs@*/
    if (rc || iob == NULL) {
        (void)luaL_error(L, "failed to slurp data");
        return 0;
    }
    lua_pushlstring(L, (const char *)rpmiobStr(iob), rpmiobLen(iob));
    iob = rpmiobFree(iob);
    return 1;
}
Ejemplo n.º 2
0
/**
 * Add expanded build scriptlet to srpm header.
 * @param h		srpm header
 * @param progTag	interpreter tag (0 disables)
 * @param scriptTag	script tag (0 disables)
 * @param iob		script body sting buf (NULL disables)
 * @return		0 always
 */
static int initSourceHeaderScriptlet(Header h,
		rpmTag progTag, rpmTag scriptTag, rpmiob iob)
	/*@modifies h @*/
{
    HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
    int xx;

    if (progTag !=(rpmTag) 0) {
	static const char prog[] = "/bin/sh";	/* XXX FIXME */
	he->tag = progTag;
	he->t = RPM_STRING_TYPE;
	he->p.str = prog;
	he->c = 1;
	xx = headerPut(h, he, 0);
    }

    if (scriptTag != (rpmTag)0 && iob != NULL) {
	he->tag = scriptTag;
	he->t = RPM_STRING_TYPE;
	he->p.str = rpmiobStr(iob);
	he->c = 1;
	xx = headerPut(h, he, 0);
    }
    return 0;
}
Ejemplo n.º 3
0
rpmRC rpmpythonRunFile(rpmpython python, const char * fn, const char ** resultp)
{
    rpmRC rc = RPMRC_FAIL;


if (_rpmpython_debug)
fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, python, fn);

    if (python == NULL) python = rpmpythonI();

    if (fn != NULL) {
#if defined(WITH_PYTHONEMBED)
	const char * pyfn = ((fn == NULL || !strcmp(fn, "-")) ? "<stdin>" : fn);
	FILE * pyfp = (!strcmp(pyfn, "<stdin>") ? stdin : fopen(fn, "rb"));
	int closeit = (pyfp != stdin);
	PyCompilerFlags cf = { .cf_flags = 0 };
	
	if (pyfp != NULL) {
	    PyRun_AnyFileExFlags(pyfp, pyfn, closeit, &cf);
	    rc = RPMRC_OK;
	}
#endif
    }
    return rc;
}

static const char * rpmpythonSlurp(const char * arg)
	/*@*/
{
    rpmiob iob = NULL;
    const char * val = NULL;
    struct stat sb;
    int xx;

    if (!strcmp(arg, "-")) {	/* Macros from stdin arg. */
	xx = rpmiobSlurp(arg, &iob);
    } else
    if ((arg[0] == '/' || strchr(arg, ' ') == NULL)
     && !Stat(arg, &sb)
     && S_ISREG(sb.st_mode)) {	/* Macros from a file arg. */
	xx = rpmiobSlurp(arg, &iob);
    } else {			/* Macros from string arg. */
	iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0);
    }

    val = xstrdup(rpmiobStr(iob));
    iob = rpmiobFree(iob);
    return val;
}
Ejemplo n.º 4
0
rpmRC rpmtclRun(rpmtcl tcl, const char * str, const char ** resultp)
{
    rpmRC rc = RPMRC_FAIL;

if (_rpmtcl_debug)
fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, tcl, str);

    if (tcl == NULL) tcl = rpmtclI();

#if defined(WITH_TCL)
    if (str != NULL && Tcl_Eval((Tcl_Interp *)tcl->I, str) == TCL_OK) {
	rc = RPMRC_OK;
	if (resultp)
	    *resultp = rpmiobStr(tcl->iob);
    }
#endif
    return rc;
}
Ejemplo n.º 5
0
/**
 * Add %changelog section to header.
 * @param h		header
 * @param iob		changelog strings
 * @return		RPMRC_OK on success
 */
static rpmRC addChangelog(Header h, rpmiob iob)
	/*@globals rpmGlobalMacroContext, h_errno, internalState @*/
	/*@modifies h, rpmGlobalMacroContext, internalState @*/
{
    char * s = rpmiobStr(iob);
    char * se;
    char *date, *name, *text;
    int i;
    time_t time;
    time_t lastTime = 0;
    int nentries = 0;
    static time_t last = 0;
    static int oneshot = 0;

    /* Determine changelog truncation criteria. */
    if (!oneshot++) {
	char * t = rpmExpand("%{?_changelog_truncate}", NULL);
	char *te = NULL;
	if (t && *t) {
	    long res = strtol(t, &te, 0);
	    if (res >= 0 && *te == '\0') {
		last = res;		/* truncate to no. of entries. */
	    } else {
/*@-moduncon@*/
		res = (long)get_date (t, NULL);
/*@=moduncon@*/
		/* XXX malformed date string silently ignored. */
		if (res > 0) {
		    last = res;		/* truncate to date. */
		}
	    }
	}
	t = _free(t);
    }

    /* skip space */
    mySKIPSPACE(s);

    while (*s != '\0') {
	if (*s != '*') {
	    rpmlog(RPMLOG_ERR,
			_("%%changelog entries must start with *\n"));
	    return RPMRC_FAIL;
	}

	/* find end of line */
	date = s;
	while(*s && *s != '\n') s++;
	if (! *s) {
	    rpmlog(RPMLOG_ERR, _("incomplete %%changelog entry\n"));
	    return RPMRC_FAIL;
	}
/*@-modobserver@*/
	*s = '\0';
/*@=modobserver@*/
	text = s + 1;
	
	/* 4 fields of date */
	date++;
	s = date;
	for (i = 0; i < 4; i++) {
	    mySKIPSPACE(s);
	    mySKIPNONSPACE(s);
	}
	mySKIPSPACE(date);
	if (dateToTimet(date, &time)) {
	    rpmlog(RPMLOG_ERR, _("bad date in %%changelog: %s\n"), date);
	    return RPMRC_FAIL;
	}
	if (lastTime && lastTime < time) {
	    rpmlog(RPMLOG_ERR,
		     _("%%changelog not in descending chronological order\n"));
	    return RPMRC_FAIL;
	}
	lastTime = time;

	/* skip space to the name */
	mySKIPSPACE(s);
	if (! *s) {
	    rpmlog(RPMLOG_ERR, _("missing name in %%changelog\n"));
	    return RPMRC_FAIL;
	}

	/* name */
	name = s;
	while (*s != '\0') s++;
	while (s > name && isspace(*s))
	    *s-- = '\0';

	if (s == name) {
	    rpmlog(RPMLOG_ERR, _("missing name in %%changelog\n"));
	    return RPMRC_FAIL;
	}

	/* text */
	mySKIPSPACE(text);
	if (! *text) {
	    rpmlog(RPMLOG_ERR, _("no description in %%changelog\n"));
	    return RPMRC_FAIL;
	}
	    
	/* find the next leading '*' (or eos) */
	s = text;
	do {
	   s++;
	} while (*s && (*(s-1) != '\n' || *s != '*'));
	se = s;
	s--;

	/* backup to end of description */
	while ((s > text) && xisspace(*s))
	    *s-- = '\0';
	
	/* Add entry if not truncated. */
	nentries++;

	if (last <= 0
	 || (last < 1000 && nentries < (int)last)
	 || (last > 1000 && time >= last))
	    addChangelogEntry(h, time, name, text);

	s = se;

    }

    return 0;
}
Ejemplo n.º 6
0
/*
 * @todo Single use by %%doc in files.c prevents static.
 */
rpmRC doScript(Spec spec, int what, const char *name, rpmiob iob, int test)
{
    const char * rootURL = spec->rootURL;
    const char * rootDir;
    const char * scriptName = NULL;
    const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
    const char * buildScript;
    const char * buildCmd = NULL;
    const char * buildTemplate = NULL;
    const char * buildPost = NULL;
    const char * mTemplate = NULL;
    const char * mCmd = NULL;
    const char * mPost = NULL;
    int argc = 0;
    const char **argv = NULL;
    FILE * fp = NULL;
    urlinfo u = NULL;
    rpmop op = NULL;
    int ix = -1;

    FD_t fd;
    FD_t xfd;
    int status;
    rpmRC rc;
    size_t i;

    switch (what) {
    case RPMBUILD_PREP:
	name = "%prep";
	iob = spec->prep;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_PREP;
	mTemplate = "%{__spec_prep_template}";
	mPost = "%{__spec_prep_post}";
	mCmd = "%{__spec_prep_cmd}";
	break;
    case RPMBUILD_BUILD:
	name = "%build";
	iob = spec->build;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_BUILD;
	mTemplate = "%{__spec_build_template}";
	mPost = "%{__spec_build_post}";
	mCmd = "%{__spec_build_cmd}";
	break;
    case RPMBUILD_INSTALL:
	name = "%install";
	iob = spec->install;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_INSTALL;
	mTemplate = "%{__spec_install_template}";
	mPost = "%{__spec_install_post}";
	mCmd = "%{__spec_install_cmd}";
	break;
    case RPMBUILD_CHECK:
	name = "%check";
	iob = spec->check;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_CHECK;
	mTemplate = "%{__spec_check_template}";
	mPost = "%{__spec_check_post}";
	mCmd = "%{__spec_check_cmd}";
	break;
    case RPMBUILD_CLEAN:
	name = "%clean";
	iob = spec->clean;
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    case RPMBUILD_RMBUILD:
	name = "--clean";
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    /* support "%track" script/section */
    case RPMBUILD_TRACK:
	name = "%track";
	iob = NULL;
	if (spec->foo)
	for (i = 0; i < spec->nfoo; i++) {
	    if (spec->foo[i].str == NULL || spec->foo[i].iob == NULL)
		continue;
	    if (xstrcasecmp(spec->foo[i].str, "track"))
		continue;
	    iob = spec->foo[i].iob;
	    /*@loopbreak@*/ break;
	}
	mTemplate = "%{__spec_track_template}";
	mPost = "%{__spec_track_post}";
	mCmd = "%{__spec_track_cmd}";
	break;
    case RPMBUILD_STRINGBUF:
    default:
	mTemplate = "%{___build_template}";
	mPost = "%{___build_post}";
	mCmd = "%{___build_cmd}";
	break;
    }

assert(name != NULL);

    if ((what != RPMBUILD_RMBUILD) && iob == NULL) {
	rc = RPMRC_OK;
	goto exit;
    }

    if (rpmTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
	rc = RPMRC_FAIL;
	goto exit;
    }

    if (fdGetFp(fd) == NULL)
	xfd = Fdopen(fd, "w.fpio");
    else
	xfd = fd;

    /*@-type@*/ /* FIX: cast? */
    if ((fp = fdGetFp(xfd)) == NULL) {
	rc = RPMRC_FAIL;
	goto exit;
    }
    /*@=type@*/

    (void) urlPath(rootURL, &rootDir);
    if (*rootDir == '\0') rootDir = "/";

    (void) urlPath(scriptName, &buildScript);

    buildTemplate = rpmExpand(mTemplate, NULL);
    buildPost = rpmExpand(mPost, NULL);

    (void) fputs(buildTemplate, fp);

    /* support "%track" script/section */
    if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir && what != RPMBUILD_TRACK)
	fprintf(fp, "cd '%s'\n", spec->buildSubdir);

    if (what == RPMBUILD_RMBUILD) {
	if (spec->buildSubdir)
	    fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
    } else if (iob != NULL)
	fprintf(fp, "%s", rpmiobStr(iob));

    (void) fputs(buildPost, fp);

    (void) Fclose(xfd);

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

    if (buildDirURL && buildDirURL[0] != '/' &&
	(urlSplit(buildDirURL, &u) != 0)) {
	rc = RPMRC_FAIL;
	goto exit;
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
	addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
	if (strcmp(rootDir, "/"))
	    addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    buildCmd = rpmExpand(mCmd, " ", buildScript, NULL);
    (void) poptParseArgvString(buildCmd, &argc, &argv);

    if (what != RPMBUILD_TRACK)		/* support "%track" script/section */
	rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);

    /* Run the script with a stopwatch. */
    if (op != NULL)
	(void) rpmswEnter(op, 0);

    status = rpmsqExecve(argv);
    if (ix >= 0 && ix < RPMSCRIPT_MAX)
	spec->sstates[ix] =
	    (RPMSCRIPT_STATE_EXEC | RPMSCRIPT_STATE_REAPED) | (status & 0xffff);

    if (!WIFEXITED(status) || WEXITSTATUS(status)) {
	rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
		 scriptName, name);
	rc = RPMRC_FAIL;
    } else
	rc = RPMRC_OK;

    if (op != NULL) {
	static unsigned int scale = 1000;
	(void) rpmswExit(op, 0);
	if (ix >= 0 && ix < RPMSCRIPT_MAX)
	    spec->smetrics[ix] += op->usecs / scale;
    }

exit:
    if (scriptName) {
#if defined(RPM_VENDOR_OPENPKG) /* always-remove-tempfiles */
	/* Unconditionally remove temporary files ("rpm-tmp.XXXXX") which
	   were generated for the executed scripts. In OpenPKG we run the
	   scripts in debug mode ("set -x") anyway, so we never need to
	   see the whole generated script -- not even if it breaks.  Instead
	   we would just have temporary files staying around forever. */
#else
	if (rc == RPMRC_OK)
#endif
	    (void) Unlink(scriptName);
	scriptName = _free(scriptName);
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	delMacro(spec->macros, "_remsh");
	delMacro(spec->macros, "_remhost");
	if (strcmp(rootDir, "/"))
	    delMacro(spec->macros, "_remroot");
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    argv = _free(argv);
    buildCmd = _free(buildCmd);
    buildTemplate = _free(buildTemplate);
    buildPost = _free(buildPost);
    buildDirURL = _free(buildDirURL);
    return rc;
}
Ejemplo n.º 7
0
static void integrity_check(const char *progname, enum modes progmode_num)
{
    rpmts ts = NULL;
    rpmlua lua = NULL;
    char *spec_fn = NULL;
    char *proc_fn = NULL;
    char *pkey_fn = NULL;
    char *spec = NULL;
    char *proc = NULL;
    rpmiob spec_iob = NULL;
    rpmiob proc_iob = NULL;
    const char *result = NULL;
    const char *error = NULL;
    int xx;
    const char *progmode;
    int rc = INTEGRITY_ERROR;

    /* determine paths of integrity checking related files */
    spec_fn = rpmExpand("%{?_integrity_spec_cfg}%{!?_integrity_spec_cfg:scripts/integrity.cfg}", NULL);
    if (spec_fn == NULL || spec_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Configuration Specification file not configured.\n"
            "rpm: HINT: macro %%{_integrity_spec_cfg} not configured correctly.\n");
        goto failure;
    }
    proc_fn = rpmExpand("%{?_integrity_proc_lua}%{!?_integrity_proc_lua:scripts/integrity.lua}", NULL);
    if (proc_fn == NULL || proc_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Validation Processor file not configured.\n"
            "rpm: HINT: macro %%{_integrity_proc_lua} not configured correctly.\n");
        goto failure;
    }
    pkey_fn = rpmExpand("%{?_integrity_pkey_pgp}%{!?_integrity_pkey_pgp:scripts/integrity.pgp}", NULL);
    if (pkey_fn == NULL || pkey_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Autority Public-Key file not configured.\n"
            "rpm: HINT: macro %%{_integrity_pkey_pgp} not configured correctly.\n");
        goto failure;
    }

    /* create RPM transaction environment and open RPM database */
    ts = rpmtsCreate();
    (void)rpmtsOpenDB(ts, O_RDONLY);

    /* check signature on integrity configuration specification file */
    if (rpmnsProbeSignature(ts, spec_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
        integrity_check_message("ERROR: Integrity Configuration Specification file contains invalid signature.\n"
            "rpm: HINT: Check file \"%s\".\n", spec_fn);
        goto failure;
    }

    /* check signature on integrity validation processor file */
    if (rpmnsProbeSignature(ts, proc_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
        integrity_check_message("ERROR: Integrity Validation Processor file contains invalid signature.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }

    /* load integrity configuration specification file */
    xx = rpmiobSlurp(spec_fn, &spec_iob);
    if (!(xx == 0 && spec_iob != NULL)) {
        integrity_check_message("ERROR: Unable to load Integrity Configuration Specification file.\n"
            "rpm: HINT: Check file \"%s\".\n", spec_fn);
        goto failure;
    }
    spec = rpmiobStr(spec_iob);

    /* load integrity validation processor file */
    xx = rpmiobSlurp(proc_fn, &proc_iob);
    if (!(xx == 0 && proc_iob != NULL)) {
        integrity_check_message("ERROR: Unable to load Integrity Validation Processor file.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }
    proc = rpmiobStr(proc_iob);

    /* provision program name and mode */
    if (progname == NULL || progname[0] == '\0')
        progname = "rpm";
    switch (progmode_num) {
        case MODE_QUERY:     progmode = "query";     break;
        case MODE_VERIFY:    progmode = "verify";    break;
        case MODE_CHECKSIG:  progmode = "checksig";  break;
        case MODE_RESIGN:    progmode = "resign";    break;
        case MODE_INSTALL:   progmode = "install";   break;
        case MODE_ERASE:     progmode = "erase";     break;
        case MODE_BUILD:     progmode = "build";     break;
        case MODE_REBUILD:   progmode = "rebuild";   break;
        case MODE_RECOMPILE: progmode = "recompile"; break;
        case MODE_TARBUILD:  progmode = "tarbuild";  break;
        case MODE_REBUILDDB: progmode = "rebuilddb"; break;
        case MODE_UNKNOWN:   progmode = "unknown";   break;
        default:             progmode = "unknown";   break;
    }

    /* execute Integrity Validation Processor via Lua glue code */
    lua = rpmluaNew();
    rpmluaSetPrintBuffer(lua, 1);
    rpmluaextActivate(lua);
    lua_getfield(lua->L, LUA_GLOBALSINDEX, "integrity");
    lua_getfield(lua->L, -1, "processor");
    lua_remove(lua->L, -2);
    lua_pushstring(lua->L, progname);
    lua_pushstring(lua->L, progmode);
    lua_pushstring(lua->L, spec_fn);
    lua_pushstring(lua->L, spec);
    lua_pushstring(lua->L, proc_fn);
    lua_pushstring(lua->L, proc);
#ifdef RPM_INTEGRITY_MV
    lua_pushstring(lua->L, RPM_INTEGRITY_MV);
#else
    lua_pushstring(lua->L, "0");
#endif
    if (lua_pcall(lua->L, 7, 1, 0) != 0) {
        error = lua_isstring(lua->L, -1) ? lua_tostring(lua->L, -1) : "unknown error";
        lua_pop(lua->L, 1);
        integrity_check_message("ERROR: Failed to execute Integrity Validation Processor.\n"
            "rpm: ERROR: Lua: %s.\n"
            "rpm: HINT: Check file \"%s\".\n", error, proc_fn);
        goto failure;
    }

    /* check Integrity Validation Processor results */
    if (!lua_isstring(lua->L, -1)) {
        integrity_check_message("ERROR: Failed to fetch Integrity Validation Processor results.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }
    result = lua_tostring(lua->L, -1);
    if (strcmp(result, "OK") == 0)
        rc = INTEGRITY_OK;
    else if (strncmp(result, "WARNING:", 8) == 0) {
        rc = INTEGRITY_WARNING;
        integrity_check_message("%s\n", result);
    }
    else {
        rc = INTEGRITY_ERROR;
        integrity_check_message("%s\n", result);
    }

    /* cleanup processing */
    failure:
    if (lua != NULL)
	rpmluaFree(lua);
    if (ts != NULL)
	(void)rpmtsFree(ts);
    ts = NULL;
    if (spec_iob != NULL)
	spec_iob = rpmiobFree(spec_iob);
    if (proc_iob != NULL)
	proc_iob = rpmiobFree(proc_iob);

    /* final result handling */
    if (rc != INTEGRITY_OK) {
        if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO))
            sleep(4);
        if (rc == INTEGRITY_ERROR)
            exit(42);
    }
    return;
}
Ejemplo n.º 8
0
int parseDescription(Spec spec)
	/*@globals name, lang @*/
	/*@modifies name, lang @*/
{
    rpmParseState nextPart = (rpmParseState) RPMRC_FAIL; /* assume error */
    rpmiob iob = NULL;
    int flag = PART_SUBNAME;
    Package pkg;
    int rc, argc;
    int arg;
    const char **argv = NULL;
    poptContext optCon = NULL;
    spectag t = NULL;

    {	char * se = strchr(spec->line, '#');
	if (se) {
	    *se = '\0';
	    while (--se >= spec->line && strchr(" \t\n\r", *se) != NULL)
		*se = '\0';
	}
    }

    if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
	rpmlog(RPMLOG_ERR, _("line %d: Error parsing %%description: %s\n"),
		 spec->lineNum, poptStrerror(rc));
	goto exit;
    }

    name = NULL;
    lang = RPMBUILD_DEFAULT_LANG;
    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
    while ((arg = poptGetNextOpt(optCon)) > 0)
	{;}
    if (name != NULL)
	flag = PART_NAME;

    if (arg < -1) {
	rpmlog(RPMLOG_ERR, _("line %d: Bad option %s: %s\n"),
		 spec->lineNum,
		 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
		 spec->line);
	goto exit;
    }

    if (poptPeekArg(optCon)) {
	if (name == NULL)
	    name = poptGetArg(optCon);
	if (poptPeekArg(optCon)) {
	    rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"),
		     spec->lineNum, spec->line);
	    goto exit;
	}
    }

    if (lookupPackage(spec, name, flag, &pkg) != RPMRC_OK) {
	rpmlog(RPMLOG_ERR, _("line %d: Package does not exist: %s\n"),
		 spec->lineNum, spec->line);
	goto exit;
    }

    /* Lose the inheirited %description (if present). */
    if (spec->packages->header != pkg->header) {
	HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
	int xx;
	he->tag = RPMTAG_DESCRIPTION;
	xx = headerGet(pkg->header, he, 0);
	he->p.ptr = _free(he->p.ptr);
	if (xx && he->t == RPM_STRING_TYPE)
	    xx = headerDel(pkg->header, he, 0);
    }
    
    t = stashSt(spec, pkg->header, RPMTAG_DESCRIPTION, lang);
    
    iob = rpmiobNew(0);

    if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
	nextPart = PART_NONE;
	goto exit;
    }
    if (rc < 0) {
	    nextPart = (rpmParseState) RPMRC_FAIL;
	    goto exit;
	}

	while ((nextPart = isPart(spec)) == PART_NONE) {
	    iob = rpmiobAppend(iob, spec->line, 1);
	    if (t) t->t_nlines++;
	if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
		nextPart = PART_NONE;
		break;
	    }
	    if (rc) {
		nextPart = (rpmParseState) RPMRC_FAIL;
		goto exit;
	    }
	}
    
    iob = rpmiobRTrim(iob);
    if (!(noLang && strcmp(lang, RPMBUILD_DEFAULT_LANG))) {
	const char * s = rpmiobStr(iob);
	(void) headerAddI18NString(pkg->header, RPMTAG_DESCRIPTION, s, lang);
    }
    
exit:
    iob = rpmiobFree(iob);
    argv = _free(argv);
    optCon = poptFreeContext(optCon);
    return nextPart;
}
Ejemplo n.º 9
0
int parsePrep(Spec spec, int verify)
{
    rpmParseState nextPart;
    int res, rc;
    rpmiob iob;
    ARGV_t saveLines = NULL;
    ARGV_t lines;
    const char * cp;
    int xx;

    if (spec->prep != NULL) {
	rpmlog(RPMLOG_ERR, _("line %d: second %%prep\n"), spec->lineNum);
	return RPMRC_FAIL;
    }

    spec->prep = rpmiobNew(0);

    /* There are no options to %prep */
    if ((rc = readLine(spec, STRIP_NOTHING)) > 0)
	return PART_NONE;
    if (rc)
	return rc;

    /* Check to make sure that all sources/patches are present. */
    if (verify) {
	rc = prepFetch(spec);
	if (rc)
	    return RPMRC_FAIL;
    }

    iob = rpmiobNew(0);

    while ((nextPart = isPart(spec)) == PART_NONE) {
	/* Need to expand the macros inline.  That way we  */
	/* can give good line number information on error. */
	iob = rpmiobAppend(iob, spec->line, 0);
	if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
	    nextPart = PART_NONE;
	    break;
	}
	if (rc)
	    return rc;
    }

    xx = argvSplit(&saveLines, rpmiobStr(iob), "\n");

/*@-usereleased@*/
    for (lines = saveLines; *lines; lines++) {
	res = 0;
	for (cp = *lines; *cp == ' ' || *cp == '\t'; cp++)
	    {};
	if (!strncmp(cp, "%setup", sizeof("%setup")-1)) {
	    res = doSetupMacro(spec, cp);
#ifndef	DYING
	} else if (! strncmp(cp, "%patch", sizeof("%patch")-1)) {
	    res = doPatchMacro(spec, cp);
#endif
	} else {
	    spec->prep = rpmiobAppend(spec->prep, *lines, 1);
	}
	if (res && !spec->force) {
	    saveLines = argvFree(saveLines);
	    iob = rpmiobFree(iob);
	    return res;
	}
    }
/*@=usereleased@*/

    saveLines = argvFree(saveLines);
    iob = rpmiobFree(iob);

    return nextPart;
}
Ejemplo n.º 10
0
/**
 * Parse %setup macro.
 * @todo FIXME: Option -q broken when not immediately after %setup.
 * @param spec		build info
 * @param line		current line from spec file
 * @return		0 on success
 */
static int doSetupMacro(Spec spec, const char * line)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies spec->buildSubdir, spec->macros, spec->prep,
		spec->packages->header,
		rpmGlobalMacroContext, fileSystem, internalState @*/
{
    char buf[BUFSIZ];
    rpmiob before = NULL;
    rpmiob after = NULL;
    poptContext optCon;
    int argc;
    const char ** argv;
    int arg;
    const char * optArg;
    int rc;
    rpmuint32_t num;
    rpmRC ec = RPMRC_FAIL;	/* XXX assume failure */

    /*@-mods@*/
    leaveDirs = skipDefaultAction = 0;
    createDir = quietly = 0;
    dirName = NULL;
    /*@=mods@*/

    if ((rc = poptParseArgvString(line, &argc, &argv))) {
	rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"),
			poptStrerror(rc));
	goto exit;
    }

    before = rpmiobNew(0);
    after = rpmiobNew(0);

    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
    while ((arg = poptGetNextOpt(optCon)) > 0) {
	optArg = poptGetOptArg(optCon);

	/* We only parse -a and -b here */

	if (parseNum(optArg, &num)) {
	    rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"),
		     spec->lineNum, (optArg ? optArg : "???"));
	    optCon = poptFreeContext(optCon);
	    argv = _free(argv);
	    goto exit;
	}

	{   const char *chptr = doUntar(spec, num, quietly);
	    if (chptr == NULL)
		goto exit;

	    (void) rpmiobAppend((arg == 'a' ? after : before), chptr, 1);
	}
    }

    if (arg < -1) {
	rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"),
		 spec->lineNum,
		 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
		 poptStrerror(arg));
	optCon = poptFreeContext(optCon);
	argv = _free(argv);
	goto exit;
    }

    if (dirName) {
	spec->buildSubdir = xstrdup(dirName);
    } else {
	const char *N, *V;
	(void) headerNEVRA(spec->packages->header, &N, NULL, &V, NULL, NULL);
	(void) snprintf(buf, sizeof(buf), "%s-%s", N, V);
	buf[sizeof(buf)-1] = '\0';
	N = _free(N);
	V = _free(V);
	spec->buildSubdir = xstrdup(buf);
    }
    addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC);

    optCon = poptFreeContext(optCon);
    argv = _free(argv);

    /* cd to the build dir */
    {	const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
	const char *buildDir;

	(void) urlPath(buildDirURL, &buildDir);
	rc = rpmioMkpath(buildDir, 0755, -1, -1);
	sprintf(buf, "cd '%s'", buildDir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
	buildDirURL = _free(buildDirURL);
    }

    /* delete any old sources */
    if (!leaveDirs) {
	sprintf(buf, "rm -rf '%s'", spec->buildSubdir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    /* check if source is a ruby gem */
    {   struct Source *sp;
	for (sp = spec->sources; sp != NULL; sp = sp->next) {
	    if ((sp->flags & RPMFILE_SOURCE) && (sp->num == 0)) {
		break;
	    }
	}
	if (sp != NULL) {
	    char *t = strrchr(sp->source, '.');
	    if(t && !strcasecmp(t, ".gem"))
		createDir = 1;
	}
    }

    /* if necessary, create and cd into the proper dir */
    if (createDir) {
	char *mkdir_p;
	mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL);
	if (!mkdir_p)
	    mkdir_p = xstrdup("mkdir -p");
	sprintf(buf, "%s '%s'\ncd '%s'",
		mkdir_p, spec->buildSubdir, spec->buildSubdir);
	mkdir_p = _free(mkdir_p);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    /* do the default action */
   if (!createDir && !skipDefaultAction) {
	const char *chptr = doUntar(spec, 0, quietly);
	if (chptr == NULL)
	    goto exit;
	spec->prep = rpmiobAppend(spec->prep, chptr, 1);
    }

    spec->prep = rpmiobAppend(spec->prep, rpmiobStr(before), 0);

    if (!createDir) {
	sprintf(buf, "cd '%s'", spec->buildSubdir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    if (createDir && !skipDefaultAction) {
	const char * chptr = doUntar(spec, 0, quietly);
	if (chptr == NULL)
	    goto exit;
	spec->prep = rpmiobAppend(spec->prep, chptr, 1);
    }

    spec->prep = rpmiobAppend(spec->prep, rpmiobStr(after), 0);

    /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */
    /* Fix the owner, group, and permissions of the setup build tree */
    {	/*@observer@*/ static const char *fixmacs[] =
		{ "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL };
	const char ** fm;

	for (fm = fixmacs; *fm; fm++) {
	    const char *fix;
	    fix = rpmExpand(*fm, " .", NULL);
	    if (fix && *fix != '%')
		spec->prep = rpmiobAppend(spec->prep, fix, 1);
	    fix = _free(fix);
	}
    }
    ec = RPMRC_OK;

exit:
    before = rpmiobFree(before);
    after = rpmiobFree(after);
    return ec;
}