Ejemplo n.º 1
0
int addSource(Spec spec, /*@unused@*/ Package pkg,
		const char *field, rpmTag tag)
{
    struct Source *p;
#if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
    struct Source *p_last;
#endif
    int flag = 0;
    const char *name = NULL;
    const char *mdir = NULL;
    const char *fieldp = NULL;
    char buf[BUFSIZ];
    uint32_t num = 0;

    buf[0] = '\0';
    switch (tag) {
    case RPMTAG_SOURCE:
	flag = RPMFILE_SOURCE;
	name = "source";
	fieldp = spec->line + strlen(name);
	break;
    case RPMTAG_PATCH:
	flag = RPMFILE_PATCH;
	name = "patch";
	fieldp = spec->line + strlen(name);
	break;
    case RPMTAG_ICON:
	flag = RPMFILE_ICON;
	name = "icon";
	fieldp = NULL;
	break;
    default:
assert(0);
	/*@notreached@*/ break;
    }
#if !defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    mdir = getSourceDir(flag);
assert(mdir != NULL);
#endif

    /* Get the number */
    if (fieldp != NULL) {
	char * end = NULL;

	num = strtoul(fieldp, &end, 10);
	SKIPSPACE(end);
	if (*end != ':') {
	    rpmlog(RPMLOG_ERR, _("line %d: No ':' terminator: %s\n"),
			 spec->lineNum, spec->line);
	    return RPMRC_FAIL;
	}
    }

    /* Check whether tags of the same number haven't already been defined */
    for (p = spec->sources; p != NULL; p = p->next) {
	if ( p->num != num ) continue;
	if ((tag == RPMTAG_SOURCE && p->flags == RPMFILE_SOURCE) ||
	    (tag == RPMTAG_PATCH  && p->flags == RPMFILE_PATCH)) {
		rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num);
		return RPMRC_FAIL;
	    }
    }

    /* Create the entry and link it in */
    p = xmalloc(sizeof(*p));
    p->num = num;
    p->fullSource = xstrdup(field);
    p->flags = flag;
    p->source = strrchr(p->fullSource, '/');
    if (p->source)
	p->source++;
    else
	p->source = p->fullSource;

#if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
    p->next = NULL;
    p_last = spec->sources;
    while (p_last != NULL && p_last->next != NULL)
        p_last = p_last->next;
    if (p_last != NULL)
        p_last->next = p;
    else
        spec->sources = p;
#else
    p->next = spec->sources;
    spec->sources = p;
#endif

    spec->numSources++;

    /* XXX FIXME: need to add ICON* macros. */
#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    mdir = getSourceDir(flag, p->source);
#endif
    if (tag != RPMTAG_ICON) {
	const char *body = rpmGenPath(NULL, mdir, p->source);

	sprintf(buf, "%s%d",
		(flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
	addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
	sprintf(buf, "%sURL%d",
		(flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
	addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
#ifdef WITH_LUA
	if (!spec->recursing) {
	    rpmlua lua = NULL; /* global state */
	    const char * what = (flag & RPMFILE_PATCH) ? "patches" : "sources";
	    rpmluav var = rpmluavNew();

	    rpmluaPushTable(lua, what);
	    rpmluavSetListMode(var, 1);
	    rpmluavSetValue(var, RPMLUAV_STRING, body);
	    rpmluaSetVar(lua, var);
/*@-moduncon@*/
	    var = (rpmluav) rpmluavFree(var);
/*@=moduncon@*/
	    rpmluaPop(lua);
	}
#endif
	body = _free(body);
    }
    
    return RPMRC_OK;
}
Ejemplo n.º 2
0
/**
 * Run internal Lua script.
 */
static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
                          const char *sname, rpmlogLvl lvl, FD_t scriptFd,
                          ARGV_t * argvp, const char *script, int arg1, int arg2)
{
    rpmRC rc = RPMRC_FAIL;
#ifdef WITH_LUA
    ARGV_t argv = argvp ? *argvp : NULL;
    rpmlua lua = NULL; /* Global state. */
    rpmluav var = rpmluavNew();
    int cwd = -1;

    rpmlog(RPMLOG_DEBUG, "%s: running <lua> scriptlet.\n", sname);

    /* Create arg variable */
    rpmluaPushTable(lua, "arg");
    rpmluavSetListMode(var, 1);
    if (argv) {
        char **p;
        for (p = argv; *p; p++) {
            rpmluavSetValue(var, RPMLUAV_STRING, *p);
            rpmluaSetVar(lua, var);
        }
    }
    if (arg1 >= 0) {
        rpmluavSetValueNum(var, arg1);
        rpmluaSetVar(lua, var);
    }
    if (arg2 >= 0) {
        rpmluavSetValueNum(var, arg2);
        rpmluaSetVar(lua, var);
    }
    rpmluaPop(lua);

    /* Lua scripts can change our cwd and umask, save and restore */
    /* XXX TODO: use cwd from chroot state to save unnecessary open here */
    cwd = open(".", O_RDONLY);
    if (cwd != -1) {
        mode_t oldmask = umask(0);
        umask(oldmask);

        if (chdir("/") == 0 && rpmluaRunScript(lua, script, sname) == 0) {
            rc = RPMRC_OK;
        }
        /* This failing would be fatal, return something different for it... */
        if (fchdir(cwd)) {
            rpmlog(RPMLOG_ERR, _("Unable to restore current directory: %m"));
            rc = RPMRC_NOTFOUND;
        }
        close(cwd);
        umask(oldmask);
    }

    rpmluaDelVar(lua, "arg");
    rpmluavFree(var);

#else
    rpmlog(lvl, _("<lua> scriptlet support not built in\n"));
#endif

    return rc;
}
Ejemplo n.º 3
0
static int addSource(rpmSpec spec, Package pkg, const char *field, rpmTagVal tag)
{
    struct Source *p;
    int flag = 0;
    const char *name = NULL;
    char *nump;
    char *fieldp = NULL;
    char *buf = NULL;
    uint32_t num = 0;

    switch (tag) {
      case RPMTAG_SOURCE:
	flag = RPMBUILD_ISSOURCE;
	name = "source";
	fieldp = spec->line + 6;
	break;
      case RPMTAG_PATCH:
	flag = RPMBUILD_ISPATCH;
	name = "patch";
	fieldp = spec->line + 5;
	break;
      case RPMTAG_ICON:
	flag = RPMBUILD_ISICON;
	fieldp = NULL;
	break;
      default:
	return -1;
	break;
    }

    /* Get the number */
    if (tag != RPMTAG_ICON) {
	/* We already know that a ':' exists, and that there */
	/* are no spaces before it.                          */
	/* This also now allows for spaces and tabs between  */
	/* the number and the ':'                            */
	char ch;
	char *fieldp_backup = fieldp;

	while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
	    fieldp++;
	}
	ch = *fieldp;
	*fieldp = '\0';

	nump = fieldp_backup;
	SKIPSPACE(nump);
	if (nump == NULL || *nump == '\0') {
	    num = flag == RPMBUILD_ISSOURCE ? 0 : INT_MAX;
	} else {
	    if (parseUnsignedNum(fieldp_backup, &num)) {
		rpmlog(RPMLOG_ERR, _("line %d: Bad %s number: %s\n"),
			 spec->lineNum, name, spec->line);
		*fieldp = ch;
		return RPMRC_FAIL;
	    }
	}
	*fieldp = ch;
    }

    /* Check whether tags of the same number haven't already been defined */
    for (p = spec->sources; p != NULL; p = p->next) {
	if ( p->num != num ) continue;
	if ((tag == RPMTAG_SOURCE && p->flags == RPMBUILD_ISSOURCE) ||
	    (tag == RPMTAG_PATCH  && p->flags == RPMBUILD_ISPATCH)) {
		rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num);
		return RPMRC_FAIL;
	    }
    }

    /* Create the entry and link it in */
    p = xmalloc(sizeof(*p));
    p->num = num;
    p->fullSource = xstrdup(field);
    p->flags = flag;
    p->source = strrchr(p->fullSource, '/');
    if (p->source) {
	if ((buf = strrchr(p->source,'='))) p->source = buf;
	p->source++;
    } else {
	p->source = p->fullSource;
    }

    if (tag != RPMTAG_ICON) {
	p->next = spec->sources;
	spec->sources = p;
    } else {
	p->next = pkg->icon;
	pkg->icon = p;
    }

    spec->numSources++;

    if (tag != RPMTAG_ICON) {
	char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
	struct stat st;
	int nofetch = (spec->flags & RPMSPEC_FORCE) ||
		      rpmExpandNumeric("%{_disable_source_fetch}");

	/* try to download source/patch if it's missing */
	if (lstat(body, &st) != 0 && errno == ENOENT && !nofetch) {
	    char *url = NULL;
	    if (urlIsURL(p->fullSource) != URL_IS_UNKNOWN) {
		url = rstrdup(p->fullSource);
	    } else {
		url = rpmExpand("%{_default_source_url}", NULL);
		rstrcat(&url, p->source);
		if (*url == '%') url = _free(url);
	    }
	    if (url) {
		rpmlog(RPMLOG_WARNING, _("Downloading %s to %s\n"), url, body);
		if (urlGetFile(url, body) != 0) {
		    free(url);
		    rpmlog(RPMLOG_ERR, _("Couldn't download %s\n"), p->fullSource);
		    return RPMRC_FAIL;
		}
		free(url);
	    }
	}

	rasprintf(&buf, "%s%d",
		(flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
	rpmPushMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
	free(buf);
	rasprintf(&buf, "%sURL%d",
		(flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
	rpmPushMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
	free(buf);
#ifdef WITH_LUA
	{
	    rpmlua lua = NULL; /* global state */
	    const char * what = (flag & RPMBUILD_ISPATCH) ? "patches" : "sources";
	    rpmluaPushTable(lua, what);
	    rpmluav var = rpmluavNew();
	    rpmluavSetListMode(var, 1);
	    rpmluavSetValue(var, RPMLUAV_STRING, body);
	    rpmluaSetVar(lua, var);
	    rpmluavFree(var);
	    rpmluaPop(lua);
	}
#endif
	free(body);
    }
    
    return 0;
}