1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-01-18 00:20:18 +08:00
|
|
|
|
1999-07-14 05:37:57 +08:00
|
|
|
#include <rpmlib.h>
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
#include "depends.h"
|
1996-01-09 03:19:53 +08:00
|
|
|
#include "install.h"
|
1996-01-09 04:21:22 +08:00
|
|
|
#include "md5.h"
|
1996-01-09 03:19:53 +08:00
|
|
|
#include "misc.h"
|
1996-09-17 06:28:56 +08:00
|
|
|
#include "rpmdb.h"
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1996-05-23 03:30:04 +08:00
|
|
|
static char * SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:"
|
1997-10-18 02:35:53 +08:00
|
|
|
"/usr/X11R6/bin";
|
1996-03-01 09:59:03 +08:00
|
|
|
|
1999-01-05 00:44:05 +08:00
|
|
|
static int removeFile(char * file, unsigned int flags, short mode,
|
|
|
|
enum fileActions action);
|
1999-01-07 01:33:50 +08:00
|
|
|
static int runScript(Header h, const char * root, int progArgc, const char ** progArgv,
|
|
|
|
const char * script, int arg1, int arg2, FD_t errfd);
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1998-12-17 05:58:53 +08:00
|
|
|
int removeBinaryPackage(char * prefix, rpmdb db, unsigned int offset,
|
1999-02-08 05:20:04 +08:00
|
|
|
int flags, enum fileActions * actions, FD_t scriptFd) {
|
1996-01-06 02:12:55 +08:00
|
|
|
Header h;
|
1999-01-05 00:44:05 +08:00
|
|
|
int i;
|
1996-01-09 03:19:53 +08:00
|
|
|
int fileCount;
|
1998-03-28 00:46:39 +08:00
|
|
|
char * name, * version, * release;
|
1996-01-06 02:12:55 +08:00
|
|
|
char * fnbuffer = NULL;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiIndexSet matches;
|
1996-01-06 02:12:55 +08:00
|
|
|
int fnbuffersize = 0;
|
|
|
|
int prefixLength = strlen(prefix);
|
1996-01-09 03:19:53 +08:00
|
|
|
char ** fileList, ** fileMd5List;
|
1996-06-28 22:37:45 +08:00
|
|
|
int type, count;
|
1996-01-09 03:19:53 +08:00
|
|
|
uint_32 * fileFlagsList;
|
1996-01-09 04:21:22 +08:00
|
|
|
int_16 * fileModesList;
|
1996-06-28 22:37:45 +08:00
|
|
|
int scriptArg;
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (flags & RPMTRANS_FLAG_JUSTDB)
|
|
|
|
flags |= RPMTRANS_FLAG_NOSCRIPTS;
|
1997-07-24 23:15:48 +08:00
|
|
|
|
1996-01-06 02:12:55 +08:00
|
|
|
h = rpmdbGetRecord(db, offset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (h == NULL) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_DBCORRUPT, _("cannot read header at %d for uninstall"),
|
1996-01-06 02:12:55 +08:00
|
|
|
offset);
|
1996-01-09 03:19:53 +08:00
|
|
|
return 1;
|
1996-01-06 02:12:55 +08:00
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
|
|
|
|
headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
|
|
|
|
headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
|
1996-06-28 22:37:45 +08:00
|
|
|
/* when we run scripts, we pass an argument which is the number of
|
|
|
|
versions of this package that will be installed when we are finished */
|
|
|
|
if (rpmdbFindPackage(db, name, &matches)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_DBCORRUPT, _("cannot read packages named %s for uninstall"),
|
1996-06-28 22:37:45 +08:00
|
|
|
name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1998-11-20 02:10:28 +08:00
|
|
|
scriptArg = dbiIndexSetCount(matches) - 1;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_NOTRIGGERS)) {
|
1998-07-01 02:51:25 +08:00
|
|
|
/* run triggers from this package which are keyed on installed
|
|
|
|
packages */
|
1999-02-08 05:20:04 +08:00
|
|
|
if (runImmedTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1, scriptFd)) {
|
1998-07-01 02:51:25 +08:00
|
|
|
return 2;
|
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1998-07-01 02:51:25 +08:00
|
|
|
/* run triggers which are set off by the removal of this package */
|
1999-02-08 05:20:04 +08:00
|
|
|
if (runTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1, scriptFd))
|
1998-07-01 02:51:25 +08:00
|
|
|
return 1;
|
|
|
|
}
|
1996-11-01 05:07:30 +08:00
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_TEST)) {
|
1998-03-28 00:46:39 +08:00
|
|
|
if (runInstScript(prefix, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
|
1999-02-17 11:42:57 +08:00
|
|
|
flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd)) {
|
1998-01-08 23:32:10 +08:00
|
|
|
headerFree(h);
|
|
|
|
return 1;
|
|
|
|
}
|
1996-11-01 05:07:30 +08:00
|
|
|
}
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("will remove files test = %d\n"),
|
1999-02-17 11:42:57 +08:00
|
|
|
flags & RPMTRANS_FLAG_TEST);
|
|
|
|
if (!(flags & RPMTRANS_FLAG_JUSTDB) &&
|
1997-07-24 23:15:48 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList,
|
|
|
|
&fileCount)) {
|
1996-01-06 02:12:55 +08:00
|
|
|
if (prefix[0]) {
|
|
|
|
fnbuffersize = 1024;
|
|
|
|
fnbuffer = alloca(fnbuffersize);
|
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEMD5S, &type, (void **) &fileMd5List,
|
1996-01-09 03:19:53 +08:00
|
|
|
&fileCount);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEFLAGS, &type, (void **) &fileFlagsList,
|
1996-01-09 03:19:53 +08:00
|
|
|
&fileCount);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(h, RPMTAG_FILEMODES, &type, (void **) &fileModesList,
|
1996-01-09 04:21:22 +08:00
|
|
|
&fileCount);
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1996-01-30 03:37:28 +08:00
|
|
|
/* go through the filelist backwards to help insure that rmdir()
|
|
|
|
will work */
|
|
|
|
for (i = fileCount - 1; i >= 0; i--) {
|
1996-01-09 05:28:20 +08:00
|
|
|
if (strcmp(prefix, "/")) {
|
1996-01-06 02:12:55 +08:00
|
|
|
if ((strlen(fileList[i]) + prefixLength + 1) > fnbuffersize) {
|
|
|
|
fnbuffersize = (strlen(fileList[i]) + prefixLength) * 2;
|
|
|
|
fnbuffer = alloca(fnbuffersize);
|
|
|
|
}
|
1996-01-09 05:28:20 +08:00
|
|
|
strcpy(fnbuffer, prefix);
|
1996-01-06 02:12:55 +08:00
|
|
|
strcat(fnbuffer, "/");
|
1996-01-09 05:28:20 +08:00
|
|
|
strcat(fnbuffer, fileList[i]);
|
1996-01-06 02:12:55 +08:00
|
|
|
} else {
|
|
|
|
fnbuffer = fileList[i];
|
|
|
|
}
|
|
|
|
|
1999-01-05 00:44:05 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file: %s action: %s\n"),
|
|
|
|
fnbuffer, fileActionString(actions[i]));
|
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_TEST))
|
1999-01-05 00:44:05 +08:00
|
|
|
removeFile(fnbuffer, fileFlagsList[i], fileModesList[i],
|
|
|
|
actions[i]);
|
1996-01-06 02:12:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
free(fileList);
|
1996-01-09 03:19:53 +08:00
|
|
|
free(fileMd5List);
|
1996-01-06 02:12:55 +08:00
|
|
|
}
|
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_TEST)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("running postuninstall script (if any)\n"));
|
1998-03-28 00:46:39 +08:00
|
|
|
runInstScript(prefix, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG, scriptArg,
|
1999-02-17 11:42:57 +08:00
|
|
|
flags & RPMTRANS_FLAG_NOSCRIPTS, scriptFd);
|
1998-01-08 23:32:10 +08:00
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_NOTRIGGERS)) {
|
1998-07-01 02:51:25 +08:00
|
|
|
/* Run postun triggers which are set off by this package's removal */
|
1999-04-23 00:00:43 +08:00
|
|
|
if (runTriggers(prefix, db, RPMSENSE_TRIGGERPOSTUN, h, -1, scriptFd)) {
|
1998-07-01 02:51:25 +08:00
|
|
|
return 2;
|
|
|
|
}
|
1998-04-06 01:22:28 +08:00
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(h);
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("removing database entry\n"));
|
1999-02-17 11:42:57 +08:00
|
|
|
if (!(flags & RPMTRANS_FLAG_TEST))
|
1996-01-06 02:12:55 +08:00
|
|
|
rpmdbRemove(db, offset, 0);
|
|
|
|
|
1996-01-09 03:19:53 +08:00
|
|
|
return 0;
|
1996-01-06 02:12:55 +08:00
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
static int runScript(Header h, const char * root, int progArgc, const char ** progArgv,
|
|
|
|
const char * script, int arg1, int arg2, FD_t errfd) {
|
|
|
|
const char ** argv;
|
1998-03-28 00:46:39 +08:00
|
|
|
int argc;
|
1999-01-07 01:33:50 +08:00
|
|
|
const char ** prefixes = NULL;
|
1998-01-30 03:39:12 +08:00
|
|
|
int numPrefixes;
|
1999-01-07 01:33:50 +08:00
|
|
|
const char * oldPrefix;
|
1998-01-30 03:39:12 +08:00
|
|
|
int maxPrefixLength;
|
1998-03-28 00:46:39 +08:00
|
|
|
int len;
|
1998-01-30 03:39:12 +08:00
|
|
|
char * prefixBuf;
|
1998-03-28 00:46:39 +08:00
|
|
|
pid_t child;
|
|
|
|
int status;
|
1999-01-07 01:33:50 +08:00
|
|
|
const char * fn;
|
1998-01-30 03:39:12 +08:00
|
|
|
int i;
|
1998-04-20 22:44:07 +08:00
|
|
|
int freePrefixes = 0;
|
1998-03-28 00:46:39 +08:00
|
|
|
int pipes[2];
|
1998-11-20 02:10:28 +08:00
|
|
|
FD_t out;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
if (!progArgv && !script)
|
1997-07-16 09:41:50 +08:00
|
|
|
return 0;
|
1998-03-28 00:46:39 +08:00
|
|
|
else if (!progArgv) {
|
|
|
|
argv = alloca(5 * sizeof(char *));
|
|
|
|
argv[0] = "/bin/sh";
|
|
|
|
argc = 1;
|
1997-10-18 02:35:53 +08:00
|
|
|
} else {
|
1998-03-28 00:46:39 +08:00
|
|
|
argv = alloca((progArgc + 4) * sizeof(char *));
|
|
|
|
memcpy(argv, progArgv, progArgc * sizeof(char *));
|
|
|
|
argc = progArgc;
|
1997-10-18 02:35:53 +08:00
|
|
|
}
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1999-04-14 20:35:08 +08:00
|
|
|
if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &prefixes,
|
1998-01-30 03:39:12 +08:00
|
|
|
&numPrefixes)) {
|
|
|
|
freePrefixes = 1;
|
|
|
|
} else if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, NULL,
|
|
|
|
(void **) &oldPrefix,
|
1997-07-16 09:41:50 +08:00
|
|
|
NULL)) {
|
1998-01-30 03:39:12 +08:00
|
|
|
prefixes = &oldPrefix;
|
|
|
|
numPrefixes = 1;
|
|
|
|
} else {
|
|
|
|
numPrefixes = 0;
|
1997-07-16 09:41:50 +08:00
|
|
|
}
|
|
|
|
|
1998-01-30 03:39:12 +08:00
|
|
|
maxPrefixLength = 0;
|
|
|
|
for (i = 0; i < numPrefixes; i++) {
|
1998-03-28 00:46:39 +08:00
|
|
|
len = strlen(prefixes[i]);
|
|
|
|
if (len > maxPrefixLength) maxPrefixLength = len;
|
1998-01-30 03:39:12 +08:00
|
|
|
}
|
|
|
|
prefixBuf = alloca(maxPrefixLength + 50);
|
|
|
|
|
1997-07-16 09:41:50 +08:00
|
|
|
if (script) {
|
1998-11-19 05:41:05 +08:00
|
|
|
FD_t fd;
|
1997-10-18 02:35:53 +08:00
|
|
|
if (makeTempFile(root, &fn, &fd)) {
|
1998-03-28 00:46:39 +08:00
|
|
|
if (freePrefixes) free(prefixes);
|
1996-01-09 03:19:53 +08:00
|
|
|
return 1;
|
1997-10-18 02:35:53 +08:00
|
|
|
}
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
if (rpmIsDebug() &&
|
|
|
|
(!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
|
1998-11-19 05:41:05 +08:00
|
|
|
(void)fdWrite(fd, "set -x\n", 7);
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1998-11-19 05:41:05 +08:00
|
|
|
(void)fdWrite(fd, script, strlen(script));
|
|
|
|
fdClose(fd);
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
argv[argc++] = fn + strlen(root);
|
|
|
|
if (arg1 >= 0) {
|
1999-01-07 01:33:50 +08:00
|
|
|
char *av = alloca(20);
|
|
|
|
sprintf(av, "%d", arg1);
|
|
|
|
argv[argc++] = av;
|
1998-03-28 00:46:39 +08:00
|
|
|
}
|
|
|
|
if (arg2 >= 0) {
|
1999-01-07 01:33:50 +08:00
|
|
|
char *av = alloca(20);
|
|
|
|
sprintf(av, "%d", arg2);
|
|
|
|
argv[argc++] = av;
|
1998-03-28 00:46:39 +08:00
|
|
|
}
|
1997-07-16 09:41:50 +08:00
|
|
|
}
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
argv[argc] = NULL;
|
1997-10-18 02:35:53 +08:00
|
|
|
|
1998-11-19 05:41:05 +08:00
|
|
|
if (errfd != NULL) {
|
1997-10-18 02:35:53 +08:00
|
|
|
if (rpmIsVerbose()) {
|
1999-01-14 02:30:31 +08:00
|
|
|
out = fdDup(fdFileno(errfd));
|
1997-10-18 02:35:53 +08:00
|
|
|
} else {
|
1998-11-20 02:10:28 +08:00
|
|
|
out = fdOpen("/dev/null", O_WRONLY, 0);
|
1999-01-14 02:30:31 +08:00
|
|
|
if (fdFileno(out) < 0)
|
|
|
|
out = fdDup(fdFileno(errfd));
|
1997-10-18 02:35:53 +08:00
|
|
|
}
|
1998-11-20 02:10:28 +08:00
|
|
|
} else {
|
|
|
|
out = fdDup(STDOUT_FILENO);
|
1997-07-16 09:41:50 +08:00
|
|
|
}
|
1997-10-18 02:35:53 +08:00
|
|
|
|
1997-07-16 09:41:50 +08:00
|
|
|
if (!(child = fork())) {
|
|
|
|
/* make stdin inaccessible */
|
|
|
|
pipe(pipes);
|
|
|
|
close(pipes[1]);
|
1998-11-20 02:10:28 +08:00
|
|
|
dup2(pipes[0], STDIN_FILENO);
|
1997-10-18 02:35:53 +08:00
|
|
|
close(pipes[0]);
|
|
|
|
|
1998-11-19 05:41:05 +08:00
|
|
|
if (errfd != NULL) {
|
1998-11-20 03:10:23 +08:00
|
|
|
if (fdFileno(errfd) != STDERR_FILENO)
|
|
|
|
dup2(fdFileno(errfd), STDERR_FILENO);
|
|
|
|
if (fdFileno(out) != STDOUT_FILENO)
|
|
|
|
dup2(fdFileno(out), STDOUT_FILENO);
|
1997-10-18 02:35:53 +08:00
|
|
|
/* make sure we don't close stdin/stderr/stdout by mistake! */
|
1998-11-25 08:42:36 +08:00
|
|
|
if (fdFileno(out) > STDERR_FILENO && fdFileno(out) != fdFileno(errfd))
|
|
|
|
fdClose (out);
|
1998-11-20 03:10:23 +08:00
|
|
|
if (fdFileno(errfd) > STDERR_FILENO)
|
|
|
|
fdClose (errfd);
|
1997-10-18 02:35:53 +08:00
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1997-10-18 02:35:53 +08:00
|
|
|
doputenv(SCRIPT_PATH);
|
1998-01-30 03:39:12 +08:00
|
|
|
|
|
|
|
for (i = 0; i < numPrefixes; i++) {
|
|
|
|
sprintf(prefixBuf, "RPM_INSTALL_PREFIX%d=%s", i, prefixes[i]);
|
|
|
|
doputenv(prefixBuf);
|
|
|
|
|
|
|
|
/* backwards compatibility */
|
1998-11-20 03:10:23 +08:00
|
|
|
if (i == 0) {
|
1998-01-30 03:39:12 +08:00
|
|
|
sprintf(prefixBuf, "RPM_INSTALL_PREFIX=%s", prefixes[i]);
|
|
|
|
doputenv(prefixBuf);
|
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
|
|
|
|
1997-10-18 02:35:53 +08:00
|
|
|
if (strcmp(root, "/")) {
|
|
|
|
chroot(root);
|
|
|
|
}
|
|
|
|
|
|
|
|
chdir("/");
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
execv(argv[0], (char *const *)argv);
|
1997-10-18 02:35:53 +08:00
|
|
|
_exit(-1);
|
1997-07-16 09:41:50 +08:00
|
|
|
}
|
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
(void)waitpid(child, &status, 0);
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1998-01-30 03:39:12 +08:00
|
|
|
if (freePrefixes) free(prefixes);
|
|
|
|
|
1998-11-20 02:10:28 +08:00
|
|
|
fdClose(out); /* XXX dup'd STDOUT_FILENO */
|
1997-10-18 02:35:53 +08:00
|
|
|
|
1997-09-10 05:00:48 +08:00
|
|
|
if (script) {
|
1998-03-28 00:46:39 +08:00
|
|
|
if (!rpmIsDebug()) unlink(fn);
|
1999-01-07 01:33:50 +08:00
|
|
|
xfree(fn);
|
1997-09-10 05:00:48 +08:00
|
|
|
}
|
1997-07-16 09:41:50 +08:00
|
|
|
|
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
|
|
|
rpmError(RPMERR_SCRIPT, _("execution of script failed"));
|
|
|
|
return 1;
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
int runInstScript(const char * root, Header h, int scriptTag, int progTag,
|
1998-11-19 05:41:05 +08:00
|
|
|
int arg, int norunScripts, FD_t err) {
|
1998-03-28 00:46:39 +08:00
|
|
|
void ** programArgv;
|
|
|
|
int programArgc;
|
1999-01-07 01:33:50 +08:00
|
|
|
const char ** argv;
|
1998-03-28 00:46:39 +08:00
|
|
|
int programType;
|
|
|
|
char * script;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (norunScripts) return 0;
|
|
|
|
|
|
|
|
/* headerGetEntry() sets the data pointer to NULL if the entry does
|
|
|
|
not exist */
|
|
|
|
headerGetEntry(h, progTag, &programType, (void **) &programArgv,
|
|
|
|
&programArgc);
|
|
|
|
headerGetEntry(h, scriptTag, NULL, (void **) &script, NULL);
|
|
|
|
|
|
|
|
if (programArgv && programType == RPM_STRING_TYPE) {
|
|
|
|
argv = alloca(sizeof(char *));
|
1999-01-07 01:33:50 +08:00
|
|
|
*argv = (const char *) programArgv;
|
1998-03-28 00:46:39 +08:00
|
|
|
} else {
|
1999-01-07 01:33:50 +08:00
|
|
|
argv = (const char **) programArgv;
|
1998-03-28 00:46:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
rc = runScript(h, root, programArgc, argv, script, arg, -1, err);
|
|
|
|
if (programType == RPM_STRING_ARRAY_TYPE) free(programArgv);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1999-01-05 00:44:05 +08:00
|
|
|
static int removeFile(char * file, unsigned int flags, short mode,
|
|
|
|
enum fileActions action) {
|
1996-01-09 04:21:22 +08:00
|
|
|
int rc = 0;
|
|
|
|
char * newfile;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1999-01-05 00:44:05 +08:00
|
|
|
switch (action) {
|
|
|
|
|
1999-02-21 11:32:56 +08:00
|
|
|
case FA_BACKUP:
|
1999-01-05 00:44:05 +08:00
|
|
|
newfile = alloca(strlen(file) + 20);
|
|
|
|
strcpy(newfile, file);
|
|
|
|
strcat(newfile, ".rpmsave");
|
|
|
|
if (rename(file, newfile)) {
|
|
|
|
rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
|
|
|
|
file, newfile, strerror(errno));
|
|
|
|
rc = 1;
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
1999-01-05 00:44:05 +08:00
|
|
|
break;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1999-02-21 11:32:56 +08:00
|
|
|
case FA_REMOVE:
|
1999-01-05 00:44:05 +08:00
|
|
|
if (S_ISDIR(mode)) {
|
|
|
|
if (rmdir(file)) {
|
|
|
|
if (errno == ENOTEMPTY)
|
|
|
|
rpmError(RPMERR_RMDIR,
|
|
|
|
_("cannot remove %s - directory not empty"),
|
|
|
|
file);
|
|
|
|
else
|
|
|
|
rpmError(RPMERR_RMDIR, _("rmdir of %s failed: %s"),
|
|
|
|
file, strerror(errno));
|
|
|
|
rc = 1;
|
1996-01-09 04:21:22 +08:00
|
|
|
}
|
1999-01-05 00:44:05 +08:00
|
|
|
} else {
|
|
|
|
if (unlink(file)) {
|
|
|
|
if (errno != ENOENT || !(flags & RPMFILE_MISSINGOK)) {
|
|
|
|
rpmError(RPMERR_UNLINK,
|
|
|
|
_("removal of %s failed: %s"),
|
|
|
|
file, strerror(errno));
|
1996-01-09 04:21:22 +08:00
|
|
|
}
|
1999-01-05 00:44:05 +08:00
|
|
|
rc = 1;
|
1996-01-09 04:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
1999-01-06 07:13:56 +08:00
|
|
|
break;
|
1999-02-21 11:32:56 +08:00
|
|
|
case FA_UNKNOWN:
|
|
|
|
case FA_CREATE:
|
|
|
|
case FA_SAVE:
|
|
|
|
case FA_SKIP:
|
|
|
|
case FA_SKIPNSTATE:
|
|
|
|
case FA_ALTNAME:
|
1999-01-06 07:13:56 +08:00
|
|
|
break;
|
1998-03-28 00:46:39 +08:00
|
|
|
}
|
1996-01-09 04:21:22 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourceH,
|
1998-03-28 00:46:39 +08:00
|
|
|
Header triggeredH, int arg1correction, int arg2,
|
1999-02-08 05:20:04 +08:00
|
|
|
char * triggersAlreadyRun, FD_t scriptFd) {
|
1999-01-07 01:33:50 +08:00
|
|
|
const char ** triggerNames;
|
|
|
|
const char ** triggerVersions;
|
|
|
|
const char ** triggerScripts;
|
|
|
|
const char ** triggerProgs;
|
1998-03-28 00:46:39 +08:00
|
|
|
int_32 * triggerFlags, * triggerIndices;
|
|
|
|
char * triggerPackageName, * sourceName;
|
|
|
|
int numTriggers;
|
|
|
|
int rc = 0;
|
|
|
|
int i;
|
|
|
|
int index;
|
|
|
|
dbiIndexSet matches;
|
1998-07-01 02:51:25 +08:00
|
|
|
int skip;
|
1998-03-28 00:46:39 +08:00
|
|
|
|
|
|
|
if (!headerGetEntry(triggeredH, RPMTAG_TRIGGERNAME, NULL,
|
|
|
|
(void **) &triggerNames, &numTriggers)) {
|
|
|
|
headerFree(triggeredH);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
headerGetEntry(sourceH, RPMTAG_NAME, NULL, (void **) &sourceName, NULL);
|
|
|
|
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_TRIGGERFLAGS, NULL,
|
|
|
|
(void **) &triggerFlags, NULL);
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_TRIGGERVERSION, NULL,
|
|
|
|
(void **) &triggerVersions, NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < numTriggers; i++) {
|
|
|
|
if (!(triggerFlags[i] & sense)) continue;
|
|
|
|
if (strcmp(triggerNames[i], sourceName)) continue;
|
1998-07-01 02:51:25 +08:00
|
|
|
|
|
|
|
/* For some reason, the TRIGGERVERSION stuff includes the name
|
|
|
|
of the package which the trigger is based on. We need to skip
|
|
|
|
over that here. I suspect that we'll change our minds on this
|
|
|
|
and remove that, so I'm going to just 'do the right thing'. */
|
|
|
|
skip = strlen(triggerNames[i]);
|
|
|
|
if (!strncmp(triggerVersions[i], triggerNames[i], skip) &&
|
|
|
|
(triggerVersions[i][skip] == '-'))
|
|
|
|
skip++;
|
|
|
|
else
|
|
|
|
skip = 0;
|
|
|
|
|
|
|
|
if (!headerMatchesDepFlags(sourceH, triggerVersions[i] + skip,
|
1998-03-28 00:46:39 +08:00
|
|
|
triggerFlags[i])) continue;
|
|
|
|
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_TRIGGERINDEX, NULL,
|
|
|
|
(void **) &triggerIndices, NULL);
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_TRIGGERSCRIPTS, NULL,
|
|
|
|
(void **) &triggerScripts, NULL);
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_TRIGGERSCRIPTPROG, NULL,
|
|
|
|
(void **) &triggerProgs, NULL);
|
|
|
|
|
|
|
|
headerGetEntry(triggeredH, RPMTAG_NAME, NULL,
|
|
|
|
(void **) &triggerPackageName, NULL);
|
|
|
|
rpmdbFindPackage(db, triggerPackageName, &matches);
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
|
|
|
|
index = triggerIndices[i];
|
|
|
|
if (!triggersAlreadyRun || !triggersAlreadyRun[index]) {
|
|
|
|
rc = runScript(triggeredH, root, 1, triggerProgs + index,
|
|
|
|
triggerScripts[index],
|
1999-02-08 05:20:04 +08:00
|
|
|
dbiIndexSetCount(matches) + arg1correction, arg2,
|
|
|
|
scriptFd);
|
1998-03-28 00:46:39 +08:00
|
|
|
if (triggersAlreadyRun) triggersAlreadyRun[index] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(triggerScripts);
|
|
|
|
free(triggerProgs);
|
|
|
|
|
|
|
|
/* each target/source header pair can only result in a single
|
|
|
|
script being run */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(triggerNames);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
int runTriggers(const char * root, rpmdb db, int sense, Header h,
|
1999-02-08 05:20:04 +08:00
|
|
|
int countCorrection, FD_t scriptFd) {
|
1998-03-28 00:46:39 +08:00
|
|
|
char * packageName;
|
|
|
|
dbiIndexSet matches, otherMatches;
|
|
|
|
Header triggeredH;
|
|
|
|
int numPackage;
|
|
|
|
int rc;
|
1998-07-26 05:00:26 +08:00
|
|
|
int i;
|
1998-03-28 00:46:39 +08:00
|
|
|
|
|
|
|
headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &packageName, NULL);
|
|
|
|
|
|
|
|
if ((rc = rpmdbFindByTriggeredBy(db, packageName, &matches)) < 0)
|
|
|
|
return 1;
|
|
|
|
else if (rc)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
rpmdbFindPackage(db, packageName, &otherMatches);
|
1998-11-20 02:10:28 +08:00
|
|
|
numPackage = dbiIndexSetCount(otherMatches) + countCorrection;
|
1998-03-28 00:46:39 +08:00
|
|
|
dbiFreeIndexRecord(otherMatches);
|
|
|
|
|
|
|
|
rc = 0;
|
1998-11-20 02:10:28 +08:00
|
|
|
for (i = 0; i < dbiIndexSetCount(matches); i++) {
|
|
|
|
unsigned int recOffset = dbiIndexRecordOffset(matches, i);
|
|
|
|
if ((triggeredH = rpmdbGetRecord(db, recOffset)) == NULL)
|
1998-03-28 00:46:39 +08:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
rc |= handleOneTrigger(root, db, sense, h, triggeredH, 0, numPackage,
|
1999-02-08 05:20:04 +08:00
|
|
|
NULL, scriptFd);
|
1998-03-28 00:46:39 +08:00
|
|
|
|
|
|
|
headerFree(triggeredH);
|
|
|
|
}
|
|
|
|
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
int runImmedTriggers(const char * root, rpmdb db, int sense, Header h,
|
1999-02-08 05:20:04 +08:00
|
|
|
int countCorrection, FD_t scriptFd) {
|
1998-03-28 00:46:39 +08:00
|
|
|
int rc = 0;
|
|
|
|
dbiIndexSet matches;
|
|
|
|
char ** triggerNames;
|
|
|
|
int numTriggers;
|
|
|
|
int i, j;
|
|
|
|
int_32 * triggerIndices;
|
|
|
|
char * triggersRun;
|
|
|
|
Header sourceH;
|
|
|
|
|
|
|
|
if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &triggerNames,
|
|
|
|
&numTriggers))
|
|
|
|
return 0;
|
|
|
|
headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &triggerIndices,
|
|
|
|
&i);
|
|
|
|
triggersRun = alloca(sizeof(*triggersRun) * i);
|
|
|
|
memset(triggersRun, 0, sizeof(*triggersRun) * i);
|
|
|
|
|
|
|
|
for (i = 0; i < numTriggers; i++) {
|
|
|
|
if (triggersRun[triggerIndices[i]]) continue;
|
|
|
|
|
|
|
|
if ((j = rpmdbFindPackage(db, triggerNames[i], &matches))) {
|
|
|
|
if (j < 0) rc |= 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
1998-11-20 02:10:28 +08:00
|
|
|
for (j = 0; j < dbiIndexSetCount(matches); j++) {
|
|
|
|
unsigned int recOffset = dbiIndexRecordOffset(matches, j);
|
|
|
|
if ((sourceH = rpmdbGetRecord(db, recOffset)) == NULL)
|
1998-03-28 00:46:39 +08:00
|
|
|
return 1;
|
|
|
|
rc |= handleOneTrigger(root, db, sense, sourceH, h,
|
1999-02-08 05:20:04 +08:00
|
|
|
countCorrection, dbiIndexSetCount(matches),
|
|
|
|
triggersRun, scriptFd);
|
1998-03-28 00:46:39 +08:00
|
|
|
headerFree(sourceH);
|
|
|
|
if (triggersRun[triggerIndices[i]]) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|