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; }
/** * 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; }
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; }