1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-01-18 00:20:18 +08:00
|
|
|
|
1998-07-31 06:09:42 +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
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
typedef enum fileActions { REMOVE, BACKUP, KEEP } fileActions_t;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
|
|
|
static int sharedFileCmp(const void * one, const void * two);
|
|
|
|
static int handleSharedFiles(rpmdb db, int offset, char ** fileList,
|
|
|
|
char ** fileMd5List, int fileCount,
|
1998-11-17 05:40:28 +08:00
|
|
|
fileActions_t * fileActions);
|
1996-01-09 03:19:53 +08:00
|
|
|
static int removeFile(char * file, char state, unsigned int flags, char * md5,
|
1998-11-17 05:40:28 +08:00
|
|
|
short mode, fileActions_t action,
|
1996-09-01 02:36:28 +08:00
|
|
|
int brokenMd5, int test);
|
1998-03-28 00:46:39 +08:00
|
|
|
static int runScript(Header h, char * root, int progArgc, char ** progArgv,
|
|
|
|
char * script, int arg1, int arg2, int errfd);
|
1996-01-09 03:19:53 +08:00
|
|
|
|
|
|
|
static int sharedFileCmp(const void * one, const void * two) {
|
1996-02-20 08:12:50 +08:00
|
|
|
if (((struct sharedFile *) one)->secRecOffset <
|
|
|
|
((struct sharedFile *) two)->secRecOffset)
|
1996-01-09 03:19:53 +08:00
|
|
|
return -1;
|
1996-02-20 08:12:50 +08:00
|
|
|
else if (((struct sharedFile *) one)->secRecOffset ==
|
|
|
|
((struct sharedFile *) two)->secRecOffset)
|
1996-01-09 03:19:53 +08:00
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int findSharedFiles(rpmdb db, int offset, char ** fileList, int fileCount,
|
|
|
|
struct sharedFile ** listPtr, int * listCountPtr) {
|
|
|
|
int i, j;
|
|
|
|
struct sharedFile * list = NULL;
|
|
|
|
int itemsUsed = 0;
|
|
|
|
int itemsAllocated = 0;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiIndexSet matches;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
|
|
|
itemsAllocated = 5;
|
|
|
|
list = malloc(sizeof(struct sharedFile) * itemsAllocated);
|
|
|
|
|
|
|
|
for (i = 0; i < fileCount; i++) {
|
|
|
|
if (!rpmdbFindByFile(db, fileList[i], &matches)) {
|
|
|
|
for (j = 0; j < matches.count; j++) {
|
|
|
|
if (matches.recs[j].recOffset != offset) {
|
|
|
|
if (itemsUsed == itemsAllocated) {
|
|
|
|
itemsAllocated += 10;
|
|
|
|
list = realloc(list, sizeof(struct sharedFile) *
|
|
|
|
itemsAllocated);
|
|
|
|
}
|
|
|
|
list[itemsUsed].mainFileNumber = i;
|
|
|
|
list[itemsUsed].secRecOffset = matches.recs[j].recOffset;
|
|
|
|
list[itemsUsed].secFileNumber = matches.recs[j].fileNumber;
|
|
|
|
itemsUsed++;
|
|
|
|
}
|
|
|
|
}
|
1996-10-21 09:24:25 +08:00
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-10-21 09:24:25 +08:00
|
|
|
if (itemsUsed) {
|
|
|
|
qsort(list, itemsUsed, sizeof(struct sharedFile), sharedFileCmp);
|
|
|
|
*listPtr = list;
|
|
|
|
*listCountPtr = itemsUsed;
|
|
|
|
} else {
|
|
|
|
free(list);
|
|
|
|
*listPtr = NULL;
|
|
|
|
*listCountPtr = 0;
|
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handleSharedFiles(rpmdb db, int offset, char ** fileList,
|
|
|
|
char ** fileMd5List, int fileCount,
|
1998-11-17 05:40:28 +08:00
|
|
|
fileActions_t * fileActions) {
|
1996-02-20 08:12:50 +08:00
|
|
|
Header sech = NULL;
|
1996-01-09 03:19:53 +08:00
|
|
|
int secOffset = 0;
|
|
|
|
struct sharedFile * sharedList;
|
|
|
|
int sharedCount;
|
|
|
|
char * name, * version, * release;
|
|
|
|
int secFileCount;
|
|
|
|
char ** secFileMd5List, ** secFileList;
|
|
|
|
char * secFileStatesList;
|
|
|
|
int type;
|
|
|
|
int i;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
if (findSharedFiles(db, offset, fileList, fileCount, &sharedList,
|
|
|
|
&sharedCount)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sharedCount) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < sharedCount; i++) {
|
|
|
|
if (secOffset != sharedList[i].secRecOffset) {
|
|
|
|
if (secOffset) {
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(sech);
|
1996-01-09 03:19:53 +08:00
|
|
|
free(secFileMd5List);
|
|
|
|
free(secFileList);
|
|
|
|
}
|
|
|
|
|
|
|
|
secOffset = sharedList[i].secRecOffset;
|
|
|
|
sech = rpmdbGetRecord(db, secOffset);
|
1998-11-17 05:40:28 +08:00
|
|
|
if (sech == NULL) {
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmError(RPMERR_DBCORRUPT,
|
|
|
|
_("cannot read header at %d for uninstall"), offset);
|
1996-01-09 03:19:53 +08:00
|
|
|
rc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(sech, RPMTAG_NAME, &type, (void **) &name,
|
1996-01-09 03:19:53 +08:00
|
|
|
&secFileCount);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(sech, RPMTAG_VERSION, &type, (void **) &version,
|
1996-01-09 03:19:53 +08:00
|
|
|
&secFileCount);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(sech, RPMTAG_RELEASE, &type, (void **) &release,
|
1996-01-09 03:19:53 +08:00
|
|
|
&secFileCount);
|
|
|
|
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
|
|
|
_("package %s-%s-%s contain shared files\n"),
|
|
|
|
name, version, release);
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
if (!headerGetEntry(sech, RPMTAG_FILENAMES, &type,
|
1996-01-09 03:19:53 +08:00
|
|
|
(void **) &secFileList, &secFileCount)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmError(RPMERR_DBCORRUPT, _("package %s contains no files"),
|
1996-01-09 03:19:53 +08:00
|
|
|
name);
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(sech);
|
1996-01-09 03:19:53 +08:00
|
|
|
rc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1998-05-26 21:45:16 +08:00
|
|
|
if (!headerGetEntry(sech, RPMTAG_FILESTATES, &type,
|
|
|
|
(void **) &secFileStatesList, NULL)) {
|
|
|
|
/* This shouldn't happen, but some versions of RPM didn't
|
|
|
|
implement --justdb properly, and chose to leave this stuff
|
|
|
|
out. */
|
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
1998-09-28 06:03:52 +08:00
|
|
|
_("package is missing FILESTATES\n"));
|
1998-05-26 21:45:16 +08:00
|
|
|
secFileStatesList = alloca(secFileCount);
|
|
|
|
memset(secFileStatesList, RPMFILE_STATE_NOTINSTALLED,
|
|
|
|
secFileCount);
|
|
|
|
}
|
|
|
|
|
1996-11-19 02:02:36 +08:00
|
|
|
headerGetEntry(sech, RPMTAG_FILEMD5S, &type,
|
1996-01-09 03:19:53 +08:00
|
|
|
(void **) &secFileMd5List, &secFileCount);
|
|
|
|
}
|
|
|
|
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("file %s is shared\n"),
|
1996-01-09 03:19:53 +08:00
|
|
|
fileList[sharedList[i].mainFileNumber]);
|
|
|
|
|
|
|
|
switch (secFileStatesList[sharedList[i].secFileNumber]) {
|
|
|
|
case RPMFILE_STATE_REPLACED:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file has already been replaced\n"));
|
1996-01-09 03:19:53 +08:00
|
|
|
break;
|
1996-03-30 04:51:20 +08:00
|
|
|
|
|
|
|
case RPMFILE_STATE_NOTINSTALLED:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file was never installed\n"));
|
1996-03-30 04:51:20 +08:00
|
|
|
break;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1996-10-21 10:19:37 +08:00
|
|
|
case RPMFILE_STATE_NETSHARED:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file is netshared (so don't touch it)\n"));
|
1996-10-21 10:19:37 +08:00
|
|
|
fileActions[sharedList[i].mainFileNumber] = KEEP;
|
|
|
|
break;
|
|
|
|
|
1996-01-09 03:19:53 +08:00
|
|
|
case RPMFILE_STATE_NORMAL:
|
|
|
|
if (!strcmp(fileMd5List[sharedList[i].mainFileNumber],
|
|
|
|
secFileMd5List[sharedList[i].secFileNumber])) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file is truely shared - saving\n"));
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
|
|
|
fileActions[sharedList[i].mainFileNumber] = KEEP;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-01-23 05:13:55 +08:00
|
|
|
if (secOffset) {
|
1996-11-19 02:02:36 +08:00
|
|
|
headerFree(sech);
|
1996-01-23 05:13:55 +08:00
|
|
|
free(secFileMd5List);
|
|
|
|
free(secFileList);
|
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
free(sharedList);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1996-06-28 22:37:45 +08:00
|
|
|
int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int flags) {
|
1996-01-06 02:12:55 +08:00
|
|
|
Header h;
|
1998-02-09 01:28:16 +08:00
|
|
|
int i, j;
|
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-01-06 02:12:55 +08:00
|
|
|
char * fileStatesList;
|
1998-11-17 05:40:28 +08:00
|
|
|
fileActions_t * fileActions;
|
1996-06-28 22:37:45 +08:00
|
|
|
int scriptArg;
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1997-07-24 23:15:48 +08:00
|
|
|
if (flags & RPMUNINSTALL_JUSTDB)
|
|
|
|
flags |= RPMUNINSTALL_NOSCRIPTS;
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
scriptArg = matches.count - 1;
|
1996-11-19 02:02:36 +08:00
|
|
|
dbiFreeIndexRecord(matches);
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1998-07-01 02:51:25 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_NOTRIGGERS)) {
|
|
|
|
/* run triggers from this package which are keyed on installed
|
|
|
|
packages */
|
|
|
|
if (runImmedTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1)) {
|
|
|
|
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 */
|
|
|
|
if (runTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1))
|
|
|
|
return 1;
|
|
|
|
}
|
1996-11-01 05:07:30 +08:00
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_TEST)) {
|
|
|
|
if (runInstScript(prefix, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
|
|
|
|
flags & RPMUNINSTALL_NOSCRIPTS, 0)) {
|
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"),
|
1998-02-09 01:28:16 +08:00
|
|
|
flags & RPMUNINSTALL_TEST);
|
1997-07-24 23:15:48 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_JUSTDB) &&
|
|
|
|
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
|
|
|
|
1998-05-26 21:45:16 +08:00
|
|
|
if (!headerGetEntry(h, RPMTAG_FILESTATES, &type,
|
|
|
|
(void **) &fileStatesList, NULL)) {
|
|
|
|
/* This shouldn't happen, but some versions of RPM didn't
|
|
|
|
implement --justdb properly, and chose to leave this stuff
|
|
|
|
out. */
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("package is missing FILESTATES\n"));
|
1998-05-26 21:45:16 +08:00
|
|
|
fileStatesList = alloca(fileCount);
|
|
|
|
memset(fileStatesList, RPMFILE_STATE_NOTINSTALLED,
|
|
|
|
fileCount);
|
|
|
|
}
|
|
|
|
|
1996-03-30 04:51:20 +08:00
|
|
|
fileActions = alloca(sizeof(*fileActions) * fileCount);
|
|
|
|
for (i = 0; i < fileCount; i++)
|
1996-10-21 10:19:37 +08:00
|
|
|
if (fileStatesList[i] == RPMFILE_STATE_NOTINSTALLED ||
|
|
|
|
fileStatesList[i] == RPMFILE_STATE_NETSHARED)
|
1996-03-30 04:51:20 +08:00
|
|
|
fileActions[i] = KEEP;
|
|
|
|
else
|
|
|
|
fileActions[i] = REMOVE;
|
|
|
|
|
1998-02-09 01:28:16 +08:00
|
|
|
if (rpmGetVar(RPMVAR_NETSHAREDPATH)) {
|
|
|
|
char ** netsharedPaths, ** nsp;
|
|
|
|
|
|
|
|
netsharedPaths = splitString(rpmGetVar(RPMVAR_NETSHAREDPATH),
|
|
|
|
strlen(rpmGetVar(RPMVAR_NETSHAREDPATH)), ':');
|
|
|
|
|
|
|
|
for (nsp = netsharedPaths; nsp && *nsp; nsp++) {
|
|
|
|
j = strlen(*nsp);
|
|
|
|
|
|
|
|
for (i = 0; i < fileCount; i++)
|
|
|
|
if (!strncmp(fileList[i], *nsp, j) &&
|
|
|
|
(fileList[i][j] == '\0' || fileList[i][j] == '/')) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%s has a netshared override\n"),
|
1998-02-09 01:28:16 +08:00
|
|
|
fileList[i]);
|
|
|
|
fileActions[i] = KEEP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-10 04:20:17 +08:00
|
|
|
freeSplitString(netsharedPaths);
|
1998-02-09 01:28:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
handleSharedFiles(db, offset, fileList, fileMd5List, fileCount,
|
|
|
|
fileActions);
|
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];
|
|
|
|
}
|
|
|
|
|
1996-01-09 03:19:53 +08:00
|
|
|
removeFile(fnbuffer, fileStatesList[i], fileFlagsList[i],
|
1996-01-09 04:21:22 +08:00
|
|
|
fileMd5List[i], fileModesList[i], fileActions[i],
|
1998-03-28 00:46:39 +08:00
|
|
|
!headerIsEntry(h, RPMTAG_RPMVERSION),
|
1996-11-19 02:02:36 +08:00
|
|
|
flags & RPMUNINSTALL_TEST);
|
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
|
|
|
}
|
|
|
|
|
1998-01-08 23:32:10 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_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,
|
|
|
|
flags & RPMUNINSTALL_NOSCRIPTS, 0);
|
1998-01-08 23:32:10 +08:00
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
|
1998-07-01 02:51:25 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_NOTRIGGERS)) {
|
|
|
|
/* Run postun triggers which are set off by this package's removal */
|
|
|
|
if (runTriggers(prefix, db, RPMSENSE_TRIGGERPOSTUN, h, 0)) {
|
|
|
|
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"));
|
1996-11-19 02:02:36 +08:00
|
|
|
if (!(flags & RPMUNINSTALL_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
|
|
|
}
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
static int runScript(Header h, char * root, int progArgc, char ** progArgv,
|
|
|
|
char * script, int arg1, int arg2, int errfd) {
|
|
|
|
char ** argv;
|
|
|
|
int argc;
|
1998-01-30 03:39:12 +08:00
|
|
|
char ** prefixes = NULL;
|
|
|
|
int numPrefixes;
|
|
|
|
char * oldPrefix;
|
|
|
|
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;
|
|
|
|
char * fn;
|
|
|
|
int fd;
|
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];
|
|
|
|
int out = 1;
|
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 = progArgv;
|
|
|
|
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
|
|
|
|
1998-02-09 01:28:16 +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) {
|
1997-10-18 02:35:53 +08:00
|
|
|
if (makeTempFile(root, &fn, &fd)) {
|
1998-03-28 00:46:39 +08:00
|
|
|
free(argv);
|
|
|
|
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-17 05:40:28 +08:00
|
|
|
(void)write(fd, "set -x\n", 7);
|
1997-07-16 09:41:50 +08:00
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
(void)write(fd, script, strlen(script));
|
1997-07-16 09:41:50 +08:00
|
|
|
close(fd);
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
argv[argc++] = fn + strlen(root);
|
|
|
|
if (arg1 >= 0) {
|
|
|
|
argv[argc] = alloca(20);
|
|
|
|
sprintf(argv[argc++], "%d", arg1);
|
|
|
|
}
|
|
|
|
if (arg2 >= 0) {
|
|
|
|
argv[argc] = alloca(20);
|
|
|
|
sprintf(argv[argc++], "%d", arg2);
|
|
|
|
}
|
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-03-28 00:46:39 +08:00
|
|
|
if (errfd) {
|
1997-10-18 02:35:53 +08:00
|
|
|
if (rpmIsVerbose()) {
|
1998-03-28 00:46:39 +08:00
|
|
|
out = errfd;
|
1997-10-18 02:35:53 +08:00
|
|
|
} else {
|
|
|
|
out = open("/dev/null", O_WRONLY);
|
|
|
|
if (out < 0) {
|
1998-03-28 00:46:39 +08:00
|
|
|
out = errfd;
|
1997-10-18 02:35:53 +08:00
|
|
|
}
|
|
|
|
}
|
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]);
|
|
|
|
dup2(pipes[0], 0);
|
1997-10-18 02:35:53 +08:00
|
|
|
close(pipes[0]);
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
if (errfd) {
|
|
|
|
if (errfd != 2) dup2(errfd, 2);
|
1997-10-18 02:35:53 +08:00
|
|
|
if (out != 1) dup2(out, 1);
|
|
|
|
/* make sure we don't close stdin/stderr/stdout by mistake! */
|
1998-03-28 00:46:39 +08:00
|
|
|
if (errfd > 2) close (errfd);
|
|
|
|
if (out > 2 && out != errfd) close (out);
|
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 */
|
|
|
|
if (!i) {
|
|
|
|
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("/");
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
execv(argv[0], 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-03-28 00:46:39 +08:00
|
|
|
if (errfd) {
|
1997-10-18 02:35:53 +08:00
|
|
|
if (out > 2) close(out);
|
1998-03-28 00:46:39 +08:00
|
|
|
if (errfd > 2) close(errfd);
|
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);
|
1997-09-10 05:00:48 +08:00
|
|
|
free(fn);
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
1998-03-28 00:46:39 +08:00
|
|
|
int runInstScript(char * root, Header h, int scriptTag, int progTag,
|
|
|
|
int arg, int norunScripts, int err) {
|
|
|
|
void ** programArgv;
|
|
|
|
int programArgc;
|
|
|
|
char ** argv;
|
|
|
|
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 *));
|
|
|
|
*argv = (char *) programArgv;
|
|
|
|
} else {
|
|
|
|
argv = (char **) programArgv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = runScript(h, root, programArgc, argv, script, arg, -1, err);
|
|
|
|
if (programType == RPM_STRING_ARRAY_TYPE) free(programArgv);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1996-01-09 03:19:53 +08:00
|
|
|
static int removeFile(char * file, char state, unsigned int flags, char * md5,
|
1998-11-17 05:40:28 +08:00
|
|
|
short mode, fileActions_t action,
|
1996-09-01 02:36:28 +08:00
|
|
|
int brokenMd5, int test) {
|
1996-01-09 04:21:22 +08:00
|
|
|
char currentMd5[40];
|
|
|
|
int rc = 0;
|
|
|
|
char * newfile;
|
1996-01-09 03:19:53 +08:00
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case RPMFILE_STATE_REPLACED:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%s has already been replaced\n"), file);
|
1996-01-09 03:19:53 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RPMFILE_STATE_NORMAL:
|
1998-11-08 06:48:12 +08:00
|
|
|
if(S_ISREG(mode) &&
|
|
|
|
(action == REMOVE) && (flags & RPMFILE_CONFIG)) {
|
1996-01-09 04:21:22 +08:00
|
|
|
/* if it's a config file, we may not want to remove it */
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("finding md5sum of %s\n"), file);
|
1998-11-08 06:48:12 +08:00
|
|
|
|
1996-09-01 02:36:28 +08:00
|
|
|
if (brokenMd5)
|
|
|
|
rc = mdfileBroken(file, currentMd5);
|
|
|
|
else
|
|
|
|
rc = mdfile(file, currentMd5);
|
|
|
|
|
1998-11-09 02:23:16 +08:00
|
|
|
if (rc)
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
1998-09-28 06:03:52 +08:00
|
|
|
_(" failed - assuming file removed\n"));
|
1996-01-09 04:21:22 +08:00
|
|
|
else {
|
|
|
|
if (strcmp(currentMd5, md5)) {
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _(" file changed - will save\n"));
|
1996-01-09 04:21:22 +08:00
|
|
|
action = BACKUP;
|
|
|
|
} else {
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG,
|
1998-09-28 06:03:52 +08:00
|
|
|
_(" file unchanged - will remove\n"));
|
1996-01-09 04:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|
|
|
|
|
1996-01-09 04:21:22 +08:00
|
|
|
switch (action) {
|
|
|
|
|
|
|
|
case KEEP:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("keeping %s\n"), file);
|
1996-02-16 05:08:09 +08:00
|
|
|
break;
|
1996-01-09 04:21:22 +08:00
|
|
|
|
|
|
|
case BACKUP:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("saving %s as %s.rpmsave\n"), file, file);
|
1996-01-09 04:21:22 +08:00
|
|
|
if (!test) {
|
|
|
|
newfile = alloca(strlen(file) + 20);
|
|
|
|
strcpy(newfile, file);
|
|
|
|
strcat(newfile, ".rpmsave");
|
|
|
|
if (rename(file, newfile)) {
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
|
1996-01-09 04:21:22 +08:00
|
|
|
file, newfile, strerror(errno));
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REMOVE:
|
1998-09-28 06:03:52 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("%s - removing\n"), file);
|
1996-01-09 04:21:22 +08:00
|
|
|
if (S_ISDIR(mode)) {
|
|
|
|
if (!test) {
|
|
|
|
if (rmdir(file)) {
|
|
|
|
if (errno == ENOTEMPTY)
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmError(RPMERR_RMDIR,
|
|
|
|
_("cannot remove %s - directory not empty"),
|
|
|
|
file);
|
1996-01-09 04:21:22 +08:00
|
|
|
else
|
1997-05-01 23:15:11 +08:00
|
|
|
rpmError(RPMERR_RMDIR, _("rmdir of %s failed: %s"),
|
1996-01-09 04:21:22 +08:00
|
|
|
file, strerror(errno));
|
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!test) {
|
|
|
|
if (unlink(file)) {
|
1997-10-30 06:13:48 +08:00
|
|
|
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
|
|
|
rc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int handleOneTrigger(char * root, rpmdb db, int sense, Header sourceH,
|
|
|
|
Header triggeredH, int arg1correction, int arg2,
|
|
|
|
char * triggersAlreadyRun) {
|
|
|
|
char ** triggerNames, ** triggerVersions;
|
|
|
|
char ** triggerScripts, ** triggerProgs;
|
|
|
|
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],
|
|
|
|
matches.count + arg1correction, arg2, 0);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
int runTriggers(char * root, rpmdb db, int sense, Header h,
|
|
|
|
int countCorrection) {
|
|
|
|
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);
|
|
|
|
numPackage = otherMatches.count + countCorrection;
|
|
|
|
dbiFreeIndexRecord(otherMatches);
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
for (i = 0; i < matches.count; i++) {
|
1998-11-17 05:40:28 +08:00
|
|
|
if ((triggeredH = rpmdbGetRecord(db, matches.recs[i].recOffset)) == NULL)
|
1998-03-28 00:46:39 +08:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
rc |= handleOneTrigger(root, db, sense, h, triggeredH, 0, numPackage,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
headerFree(triggeredH);
|
|
|
|
}
|
|
|
|
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int runImmedTriggers(char * root, rpmdb db, int sense, Header h,
|
|
|
|
int countCorrection) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < matches.count; j++) {
|
1998-11-17 05:40:28 +08:00
|
|
|
if ((sourceH = rpmdbGetRecord(db, matches.recs[j].recOffset)) == NULL)
|
1998-03-28 00:46:39 +08:00
|
|
|
return 1;
|
|
|
|
rc |= handleOneTrigger(root, db, sense, sourceH, h,
|
|
|
|
countCorrection, matches.count, triggersRun);
|
|
|
|
headerFree(sourceH);
|
|
|
|
if (triggersRun[triggerIndices[i]]) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbiFreeIndexRecord(matches);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
1996-01-09 03:19:53 +08:00
|
|
|
}
|