#include "system.h"
+#include <sys/types.h>
+#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
-#define _RPMSQ_INTERNAL
-#include <rpm/rpmsq.h>
-#include <rpm/rpmts.h>
#include <rpm/rpmfileutil.h>
#include <rpm/rpmmacro.h>
#include <rpm/rpmio.h>
#include <rpm/rpmlog.h>
-#include <rpm/rpmsw.h>
#include <rpm/header.h>
+#include <rpm/rpmds.h>
#include "rpmio/rpmlua.h"
#include "lib/rpmscript.h"
+#include "lib/rpmplugins.h" /* rpm plugins hooks */
+
#include "debug.h"
+struct scriptNextFileFunc_s {
+ char *(*func)(void *); /* function producing input for script */
+ void *param; /* parameter for func */
+};
+
+typedef struct scriptNextFileFunc_s *scriptNextFileFunc;
+
+struct rpmScript_s {
+ rpmscriptTypes type; /* script type */
+ rpmTagVal tag; /* script tag */
+ char **args; /* scriptlet call arguments */
+ char *body; /* script body */
+ char *descr; /* description for logging */
+ rpmscriptFlags flags; /* flags to control operation */
+ struct scriptNextFileFunc_s nextFileFunc; /* input function */
+};
+
+struct scriptInfo_s {
+ rpmscriptTypes type;
+ const char *desc;
+ rpmsenseFlags sense;
+ rpmTagVal tag;
+ rpmTagVal progtag;
+ rpmTagVal flagtag;
+};
+
+static const struct scriptInfo_s scriptInfo[] = {
+ { RPMSCRIPT_PREIN, "%prein", 0,
+ RPMTAG_PREIN, RPMTAG_PREINPROG, RPMTAG_PREINFLAGS },
+ { RPMSCRIPT_PREUN, "%preun", 0,
+ RPMTAG_PREUN, RPMTAG_PREUNPROG, RPMTAG_PREUNFLAGS },
+ { RPMSCRIPT_POSTIN, "%post", 0,
+ RPMTAG_POSTIN, RPMTAG_POSTINPROG, RPMTAG_POSTINFLAGS },
+ { RPMSCRIPT_POSTUN, "%postun", 0,
+ RPMTAG_POSTUN, RPMTAG_POSTUNPROG, RPMTAG_POSTUNFLAGS },
+ { RPMSCRIPT_PRETRANS, "%pretrans", 0,
+ RPMTAG_PRETRANS, RPMTAG_PRETRANSPROG, RPMTAG_PRETRANSFLAGS },
+ { RPMSCRIPT_POSTTRANS, "%posttrans", 0,
+ RPMTAG_POSTTRANS, RPMTAG_POSTTRANSPROG, RPMTAG_POSTTRANSFLAGS },
+ { RPMSCRIPT_TRIGGERPREIN, "%triggerprein", RPMSENSE_TRIGGERPREIN,
+ RPMTAG_TRIGGERPREIN, 0, 0 },
+ { RPMSCRIPT_TRIGGERUN, "%triggerun", RPMSENSE_TRIGGERUN,
+ RPMTAG_TRIGGERUN, 0, 0 },
+ { RPMSCRIPT_TRIGGERIN, "%triggerin", RPMSENSE_TRIGGERIN,
+ RPMTAG_TRIGGERIN, 0, 0 },
+ { RPMSCRIPT_TRIGGERPOSTUN, "%triggerpostun", RPMSENSE_TRIGGERPOSTUN,
+ RPMTAG_TRIGGERPOSTUN, 0, 0 },
+ { RPMSCRIPT_VERIFY, "%verify", 0,
+ RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG, RPMTAG_VERIFYSCRIPTFLAGS},
+ { 0, "unknown", 0,
+ RPMTAG_NOT_FOUND, RPMTAG_NOT_FOUND, RPMTAG_NOT_FOUND }
+};
+
+static const struct scriptInfo_s * findTag(rpmTagVal tag)
+{
+ const struct scriptInfo_s * si = scriptInfo;
+ while (si->type && si->tag != tag)
+ si++;
+ return si;
+}
/**
* Run internal Lua script.
*/
-static rpmRC runLuaScript(rpmts ts, ARGV_const_t prefixes,
- const char *sname, rpmlogLvl lvl,
- ARGV_t * argvp, const char *script, int arg1, int arg2)
+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,
+ scriptNextFileFunc nextFileFunc)
{
rpmRC rc = RPMRC_FAIL;
#ifdef WITH_LUA
- int rootFd = -1;
- int xx;
ARGV_t argv = argvp ? *argvp : NULL;
rpmlua lua = NULL; /* Global state. */
- rpmluav var;
+ rpmluav var = rpmluavNew();
+ int cwd = -1;
rpmlog(RPMLOG_DEBUG, "%s: running <lua> scriptlet.\n", sname);
- if (!rpmtsChrootDone(ts)) {
- const char *rootDir = rpmtsRootDir(ts);
- xx = chdir("/");
- rootFd = open(".", O_RDONLY, 0);
- if (rootFd >= 0) {
- if (rootDir != NULL && !rstreq(rootDir, "/") && *rootDir == '/')
- xx = chroot(rootDir);
- xx = rpmtsSetChrootDone(ts, 1);
- }
- }
/* Create arg variable */
rpmluaPushTable(lua, "arg");
- var = rpmluavNew();
rpmluavSetListMode(var, 1);
+ rpmluaSetNextFileFunc(nextFileFunc->func, nextFileFunc->param);
if (argv) {
char **p;
for (p = argv; *p; p++) {
rpmluavSetValueNum(var, arg2);
rpmluaSetVar(lua, var);
}
- var = rpmluavFree(var);
rpmluaPop(lua);
- if (rpmluaRunScript(lua, script, sname) == 0) {
- rc = RPMRC_OK;
+ /* 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);
+ pid_t pid = getpid();
+
+ if (chdir("/") == 0 && rpmluaRunScript(lua, script, sname) == 0) {
+ rc = RPMRC_OK;
+ }
+ if (pid != getpid()) {
+ /* Terminate child process forked in lua scriptlet */
+ rpmlog(RPMLOG_ERR, _("No exec() called after fork() in lua scriptlet\n"));
+ _exit(EXIT_FAILURE);
+ }
+ /* 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);
- if (rootFd >= 0) {
- const char *rootDir = rpmtsRootDir(ts);
- xx = fchdir(rootFd);
- xx = close(rootFd);
- if (rootDir != NULL && !rstreq(rootDir, "/") && *rootDir == '/')
- xx = chroot(".");
- xx = rpmtsSetChrootDone(ts, 0);
- }
#else
rpmlog(lvl, _("<lua> scriptlet support not built in\n"));
#endif
static const char * const SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";
-static void doScriptExec(rpmts ts, ARGV_const_t argv, ARGV_const_t prefixes,
+static void doScriptExec(ARGV_const_t argv, ARGV_const_t prefixes,
FD_t scriptFd, FD_t out)
{
- const char * rootDir;
- int pipes[2];
int flag;
int fdno;
int xx;
int open_max;
+ /* SIGPIPE is ignored in rpm, reset to default for the scriptlet */
(void) signal(SIGPIPE, SIG_DFL);
- pipes[0] = pipes[1] = 0;
- /* make stdin inaccessible */
- xx = pipe(pipes);
- xx = close(pipes[1]);
- xx = dup2(pipes[0], STDIN_FILENO);
- xx = close(pipes[0]);
/* XXX Force FD_CLOEXEC on all inherited fdno's. */
open_max = sysconf(_SC_OPEN_MAX);
path = ipath;
xx = setenv("PATH", path, 1);
- ipath = _free(ipath);
+ free(ipath);
}
for (ARGV_const_t pf = prefixes; pf && *pf; pf++) {
}
}
- rootDir = rpmtsRootDir(ts);
- if (rootDir != NULL) { /* XXX can't happen */
- if (!rpmtsChrootDone(ts) &&
- !(rootDir[0] == '/' && rootDir[1] == '\0'))
- {
- xx = chroot(rootDir);
- }
- xx = chdir("/");
-
+ if (chdir("/") == 0) {
/* XXX Don't mtrace into children. */
unsetenv("MALLOC_CHECK_");
- /* Permit libselinux to do the scriptlet exec. */
- if (rpmtsSELinuxEnabled(ts) == 1) {
- xx = rpm_execcon(0, argv[0], argv, environ);
- }
-
if (xx == 0) {
xx = execv(argv[0], argv);
}
_exit(127); /* exit 127 for compatibility with bash(1) */
}
+static char * writeScript(const char *cmd, const char *script)
+{
+ char *fn = NULL;
+ size_t slen = strlen(script);
+ int ok = 0;
+ FD_t fd = rpmMkTempFile("/", &fn);
+
+ if (Ferror(fd))
+ goto exit;
+
+ if (rpmIsDebug() && (rstreq(cmd, "/bin/sh") || rstreq(cmd, "/bin/bash"))) {
+ static const char set_x[] = "set -x\n";
+ /* Assume failures will be caught by the write below */
+ Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd);
+ }
+
+ ok = (Fwrite(script, sizeof(script[0]), slen, fd) == slen);
+
+exit:
+ if (!ok) fn = _free(fn);
+ Fclose(fd);
+ return fn;
+}
+
/**
* Run an external script.
*/
-static rpmRC runExtScript(rpmts ts, ARGV_const_t prefixes,
- const char *sname, rpmlogLvl lvl,
- ARGV_t * argvp, const char *script, int arg1, int arg2)
+static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
+ const char *sname, rpmlogLvl lvl, FD_t scriptFd,
+ ARGV_t * argvp, const char *script, int arg1, int arg2,
+ scriptNextFileFunc nextFileFunc)
{
- FD_t scriptFd;
FD_t out = NULL;
char * fn = NULL;
- int xx;
+ pid_t pid, reaped;
+ int status;
+ int inpipe[2];
+ FILE *in = NULL;
+ const char *line;
+ char *mline = NULL;
rpmRC rc = RPMRC_FAIL;
- struct rpmsqElem sq;
-
- memset(&sq, 0, sizeof(sq));
- sq.reaper = 1;
rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", sname);
if (script) {
- const char * rootDir = rpmtsRootDir(ts);
- FD_t fd;
-
- fd = rpmMkTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn);
- if (fd == NULL || Ferror(fd)) {
- rpmlog(RPMLOG_ERR, _("Couldn't create temporary file for %s: %s\n"),
+ fn = writeScript(*argvp[0], script);
+ if (fn == NULL) {
+ rpmlog(RPMLOG_ERR,
+ _("Couldn't create temporary file for %s: %s\n"),
sname, strerror(errno));
goto exit;
}
- if (rpmIsDebug() &&
- (rstreq(*argvp[0], "/bin/sh") || rstreq(*argvp[0], "/bin/bash")))
- {
- static const char set_x[] = "set -x\n";
- xx = Fwrite(set_x, sizeof(set_x[0]), sizeof(set_x)-1, fd);
- }
-
- xx = Fwrite(script, sizeof(script[0]), strlen(script), fd);
- xx = Fclose(fd);
-
- { const char * sn = fn;
- if (!rpmtsChrootDone(ts) && rootDir != NULL &&
- !(rootDir[0] == '/' && rootDir[1] == '\0'))
- {
- sn += strlen(rootDir)-1;
- }
- argvAdd(argvp, sn);
- }
-
+ argvAdd(argvp, fn);
if (arg1 >= 0) {
argvAddNum(argvp, arg1);
}
}
}
- scriptFd = rpmtsScriptFd(ts);
+ if (pipe(inpipe) < 0) {
+ rpmlog(RPMLOG_ERR,
+ ("Couldn't create pipe: %s\n"), strerror(errno));
+ goto exit;
+ }
+ in = fdopen(inpipe[1], "w");
+ inpipe[1] = 0;
+
if (scriptFd != NULL) {
if (rpmIsVerbose()) {
out = fdDup(Fileno(scriptFd));
goto exit;
}
- xx = rpmsqFork(&sq);
- if (sq.child == 0) {
+ pid = fork();
+ if (pid == (pid_t) -1) {
+ rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"),
+ sname, strerror(errno));
+ goto exit;
+ } else if (pid == 0) {/* Child */
rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n",
sname, *argvp[0], (unsigned)getpid());
- doScriptExec(ts, *argvp, prefixes, scriptFd, out);
- }
- if (sq.child == (pid_t)-1) {
- rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"), sname, strerror(errno));
- goto exit;
+ fclose(in);
+ dup2(inpipe[0], STDIN_FILENO);
+
+ /* Run scriptlet post fork hook for all plugins */
+ if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) {
+ doScriptExec(*argvp, prefixes, scriptFd, out);
+ } else {
+ _exit(126); /* exit 126 for compatibility with bash(1) */
+ }
+ }
+ close(inpipe[0]);
+ inpipe[0] = 0;
+
+ if (nextFileFunc->func) {
+ while ((line = nextFileFunc->func(nextFileFunc->param)) != NULL) {
+ size_t size = strlen(line);
+ size_t ret_size;
+ mline = xstrdup(line);
+ mline[size] = '\n';
+
+ ret_size = fwrite(mline, size + 1, 1, in);
+ mline = _free(mline);
+ if (ret_size != 1) {
+ if (errno == EPIPE) {
+ break;
+ } else {
+ rpmlog(RPMLOG_ERR, _("Fwrite failed: %s"), strerror(errno));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ }
+ }
}
+ fclose(in);
+ in = NULL;
- rpmsqWait(&sq);
+ do {
+ reaped = waitpid(pid, &status, 0);
+ } while (reaped == -1 && errno == EINTR);
rpmlog(RPMLOG_DEBUG, "%s: waitpid(%d) rc %d status %x\n",
- sname, (unsigned)sq.child, (unsigned)sq.reaped, sq.status);
+ sname, (unsigned)pid, (unsigned)reaped, status);
- if (sq.reaped < 0) {
+ if (reaped < 0) {
rpmlog(lvl, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"),
- sname, sq.child, sq.reaped, strerror(errno));
- } else if (!WIFEXITED(sq.status) || WEXITSTATUS(sq.status)) {
- if (WIFSIGNALED(sq.status)) {
+ sname, pid, reaped, strerror(errno));
+ } else if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ if (WIFSIGNALED(status)) {
rpmlog(lvl, _("%s scriptlet failed, signal %d\n"),
- sname, WTERMSIG(sq.status));
+ sname, WTERMSIG(status));
} else {
rpmlog(lvl, _("%s scriptlet failed, exit status %d\n"),
- sname, WEXITSTATUS(sq.status));
+ sname, WEXITSTATUS(status));
}
} else {
/* if we get this far we're clear */
}
exit:
+ if (in)
+ fclose(in);
+
+ if (inpipe[0])
+ close(inpipe[0]);
+
if (out)
- xx = Fclose(out); /* XXX dup'd STDOUT_FILENO */
+ Fclose(out); /* XXX dup'd STDOUT_FILENO */
- if (script) {
+ if (fn) {
if (!rpmIsDebug())
- xx = unlink(fn);
- fn = _free(fn);
+ unlink(fn);
+ free(fn);
}
+ free(mline);
+
return rc;
}
-rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2,
- rpmts ts, ARGV_const_t prefixes, int warn_only)
+rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,
+ ARGV_const_t prefixes, int warn_only, rpmPlugins plugins)
{
ARGV_t args = NULL;
rpmlogLvl lvl = warn_only ? RPMLOG_WARNING : RPMLOG_ERR;
rpmRC rc;
+ int script_type = RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC;
if (script == NULL) return RPMRC_OK;
} else {
argvAdd(&args, "/bin/sh");
}
+
+ if (rstreq(args[0], "<lua>"))
+ script_type = RPMSCRIPTLET_NONE;
- rpmswEnter(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
- if (rstreq(args[0], "<lua>")) {
- rc = runLuaScript(ts, prefixes, script->descr, lvl, &args, script->body, arg1, arg2);
- } else {
- rc = runExtScript(ts, prefixes, script->descr, lvl, &args, script->body, arg1, arg2);
+ /* Run scriptlet pre hook for all plugins */
+ rc = rpmpluginsCallScriptletPre(plugins, script->descr, script_type);
+
+ if (rc != RPMRC_FAIL) {
+ if (script_type & RPMSCRIPTLET_EXEC) {
+ rc = runExtScript(plugins, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2, &script->nextFileFunc);
+ } else {
+ rc = runLuaScript(plugins, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2, &script->nextFileFunc);
+ }
}
- rpmswExit(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
+
+ /* Run scriptlet post hook for all plugins */
+ rpmpluginsCallScriptletPost(plugins, script->descr, script_type, rc);
+
argvFree(args);
return rc;
}
-static rpmTag getProgTag(rpmTag scriptTag)
+static rpmscriptTypes getScriptType(rpmTagVal scriptTag)
+{
+ return findTag(scriptTag)->type;
+}
+
+static rpmTagVal getProgTag(rpmTagVal scriptTag)
+{
+ return findTag(scriptTag)->progtag;
+}
+
+static rpmTagVal getFlagTag(rpmTagVal scriptTag)
+{
+ return findTag(scriptTag)->flagtag;
+}
+
+static const char * tag2sln(rpmTagVal tag)
+{
+ return findTag(tag)->desc;
+}
+
+static rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body,
+ rpmscriptFlags flags)
+{
+ char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
+ rpmScript script = xcalloc(1, sizeof(*script));
+ script->tag = tag;
+ script->type = getScriptType(tag);
+ script->flags = flags;
+ script->body = (body != NULL) ? xstrdup(body) : NULL;
+ rasprintf(&script->descr, "%s(%s)", tag2sln(tag), nevra);
+
+ /* macros need to be expanded before possible queryformat */
+ if (script->body && (script->flags & RPMSCRIPT_FLAG_EXPAND)) {
+ char *body = rpmExpand(script->body, NULL);
+ free(script->body);
+ script->body = body;
+ }
+ if (script->body && (script->flags & RPMSCRIPT_FLAG_QFORMAT)) {
+ /* XXX TODO: handle queryformat errors */
+ char *body = headerFormat(h, script->body, NULL);
+ free(script->body);
+ script->body = body;
+ }
+
+ script->nextFileFunc.func = NULL;
+ script->nextFileFunc.param = NULL;
+
+ free(nevra);
+ return script;
+}
+
+void rpmScriptSetNextFileFunc(rpmScript script, char *(*func)(void *),
+ void *param)
{
- switch (scriptTag) {
- case RPMTAG_PREIN: return RPMTAG_PREINPROG;
- case RPMTAG_POSTIN: return RPMTAG_POSTINPROG;
- case RPMTAG_PREUN: return RPMTAG_PREUNPROG;
- case RPMTAG_POSTUN: return RPMTAG_POSTUNPROG;
- case RPMTAG_PRETRANS: return RPMTAG_PRETRANSPROG;
- case RPMTAG_POSTTRANS: return RPMTAG_POSTTRANSPROG;
- case RPMTAG_VERIFYSCRIPT: return RPMTAG_VERIFYSCRIPTPROG;
- default: return RPMTAG_NOT_FOUND;
+ script->nextFileFunc.func = func;
+ script->nextFileFunc.param = param;
+}
+
+rpmTagVal triggerDsTag(rpmscriptTriggerModes tm)
+{
+ rpmTagVal tag = RPMTAG_NOT_FOUND;
+ switch (tm) {
+ case RPMSCRIPT_NORMALTRIGGER:
+ tag = RPMTAG_TRIGGERNAME;
+ break;
+ case RPMSCRIPT_FILETRIGGER:
+ tag = RPMTAG_FILETRIGGERNAME;
+ break;
+ case RPMSCRIPT_TRANSFILETRIGGER:
+ tag = RPMTAG_TRANSFILETRIGGERNAME;
+ break;
+ }
+ return tag;
+}
+
+rpmscriptTriggerModes triggerMode(rpmTagVal tag)
+{
+ rpmscriptTriggerModes tm = 0;
+ switch (tag) {
+ case RPMTAG_TRIGGERNAME:
+ tm = RPMSCRIPT_NORMALTRIGGER;
+ break;
+ case RPMTAG_FILETRIGGERNAME:
+ tm = RPMSCRIPT_FILETRIGGER;
+ break;
+ case RPMTAG_TRANSFILETRIGGERNAME:
+ tm = RPMSCRIPT_TRANSFILETRIGGER;
+ break;
}
+ return tm;
}
-static const char * tag2sln(rpmTag tag)
+rpmTagVal triggertag(rpmsenseFlags sense)
{
- switch ((rpm_tag_t) tag) {
- case RPMTAG_PRETRANS: return "%pretrans";
- case RPMTAG_TRIGGERPREIN: return "%triggerprein";
- case RPMTAG_PREIN: return "%pre";
- case RPMTAG_POSTIN: return "%post";
- case RPMTAG_TRIGGERIN: return "%triggerin";
- case RPMTAG_TRIGGERUN: return "%triggerun";
- case RPMTAG_PREUN: return "%preun";
- case RPMTAG_POSTUN: return "%postun";
- case RPMTAG_POSTTRANS: return "%posttrans";
- case RPMTAG_TRIGGERPOSTUN: return "%triggerpostun";
- case RPMTAG_VERIFYSCRIPT: return "%verify";
- default: break;
+ rpmTagVal tag = RPMTAG_NOT_FOUND;
+ switch (sense) {
+ case RPMSENSE_TRIGGERIN:
+ tag = RPMTAG_TRIGGERIN;
+ break;
+ case RPMSENSE_TRIGGERUN:
+ tag = RPMTAG_TRIGGERUN;
+ break;
+ case RPMSENSE_TRIGGERPOSTUN:
+ tag = RPMTAG_TRIGGERPOSTUN;
+ break;
+ case RPMSENSE_TRIGGERPREIN:
+ tag = RPMTAG_TRIGGERPREIN;
+ break;
+ default:
+ break;
+ }
+ return tag;
+}
+
+rpmScript rpmScriptFromTriggerTag(Header h, rpmTagVal triggerTag,
+ rpmscriptTriggerModes tm, uint32_t ix)
+{
+ rpmScript script = NULL;
+ struct rpmtd_s tscripts, tprogs, tflags;
+ headerGetFlags hgflags = HEADERGET_MINMEM;
+
+ switch (tm) {
+ case RPMSCRIPT_NORMALTRIGGER:
+ headerGet(h, RPMTAG_TRIGGERSCRIPTS, &tscripts, hgflags);
+ headerGet(h, RPMTAG_TRIGGERSCRIPTPROG, &tprogs, hgflags);
+ headerGet(h, RPMTAG_TRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ break;
+ case RPMSCRIPT_FILETRIGGER:
+ headerGet(h, RPMTAG_FILETRIGGERSCRIPTS, &tscripts, hgflags);
+ headerGet(h, RPMTAG_FILETRIGGERSCRIPTPROG, &tprogs, hgflags);
+ headerGet(h, RPMTAG_FILETRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ break;
+ case RPMSCRIPT_TRANSFILETRIGGER:
+ headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTS, &tscripts, hgflags);
+ headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTPROG, &tprogs, hgflags);
+ headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ break;
+ }
+
+ if (rpmtdSetIndex(&tscripts, ix) >= 0 && rpmtdSetIndex(&tprogs, ix) >= 0) {
+ rpmscriptFlags sflags = 0;
+ const char *prog = rpmtdGetString(&tprogs);
+
+ if (rpmtdSetIndex(&tflags, ix) >= 0)
+ sflags = rpmtdGetNumber(&tflags);
+
+ script = rpmScriptNew(h, triggerTag, rpmtdGetString(&tscripts), sflags);
+
+ /* hack up a hge-style NULL-terminated array */
+ script->args = xmalloc(2 * sizeof(*script->args) + strlen(prog) + 1);
+ script->args[0] = (char *)(script->args + 2);
+ script->args[1] = NULL;
+ strcpy(script->args[0], prog);
}
- return "%unknownscript";
+
+ rpmtdFreeData(&tscripts);
+ rpmtdFreeData(&tprogs);
+ rpmtdFreeData(&tflags);
+
+ return script;
}
-rpmScript rpmScriptFromTag(Header h, rpmTag scriptTag)
+rpmScript rpmScriptFromTag(Header h, rpmTagVal scriptTag)
{
rpmScript script = NULL;
- rpmTag progTag = getProgTag(scriptTag);
+ rpmTagVal progTag = getProgTag(scriptTag);
if (headerIsEntry(h, scriptTag) || headerIsEntry(h, progTag)) {
struct rpmtd_s prog;
- char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
- script = xcalloc(1, sizeof(*script));
- script->tag = scriptTag;
- script->body = headerGetAsString(h, scriptTag);
- rasprintf(&script->descr, "%s(%s)", tag2sln(scriptTag), nevra);
+ script = rpmScriptNew(h, scriptTag,
+ headerGetString(h, scriptTag),
+ headerGetNumber(h, getFlagTag(scriptTag)));
if (headerGet(h, progTag, &prog, (HEADERGET_ALLOC|HEADERGET_ARGV))) {
script->args = prog.data;
}
- free(nevra);
}
return script;
}
}
return NULL;
}
+
+rpmTagVal rpmScriptTag(rpmScript script)
+{
+ return (script != NULL) ? script->tag : RPMTAG_NOT_FOUND;
+}
+
+rpmscriptTypes rpmScriptType(rpmScript script)
+{
+ return (script != NULL) ? script->type : 0;
+}