added trigger support

CVS patchset: 2049
CVS date: 1998/03/27 16:46:39
This commit is contained in:
ewt 1998-03-27 16:46:39 +00:00
parent 319ff94132
commit 7b8522b57e
14 changed files with 575 additions and 269 deletions

View File

@ -5,6 +5,9 @@
- respect LINGUAS when install package files
- added trigger support to build code
- got rid of annoying mwftw() type warning
- fixed many command line options which got broke by changes
for non-gcc compilers
- added trigger support in install code
2.4.103 -> 2.4.104:
- fixed popt/Makefile.in to use CPP from configure

View File

@ -557,6 +557,7 @@ AC_SUBST(MISCDIR)
AC_SUBST(LIBMISC)
AC_SUBST(MISCPATH)
AC_SUBST(RPMCONFIGDIR)
AC_SUBST(MKDIR_P)
if test -d newbuild ; then
NBMAKEFILE=newbuild/Makefile

View File

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include "depends.h"
#include "intl.h"
#include "misc.h"
#include "rpmlib.h"
@ -72,7 +73,6 @@ static int checkPackageDeps(rpmDependencies rpmdep, struct problemsSet * psp,
Header h, const char * requirement);
static int dbrecMatchesDepFlags(rpmDependencies rpmdep, int recOffset,
char * reqVersion, int reqFlags);
static int headerMatchesDepFlags(Header h, char * reqVersion, int reqFlags);
struct availablePackage * alSatisfiesDepend(struct availableList * al,
char * reqName, char * reqVersion,
int reqFlags);
@ -709,7 +709,7 @@ static int checkPackageDeps(rpmDependencies rpmdep, struct problemsSet * psp,
return ourrc;
}
static int headerMatchesDepFlags(Header h, char * reqInfo, int reqFlags) {
int headerMatchesDepFlags(Header h, char * reqInfo, int reqFlags) {
char * name, * version, * release, * chptr;
char * reqVersion = reqInfo;
char * reqRelease = NULL;

View File

@ -13,6 +13,8 @@ static char * permsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element);
static char * depflagsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element);
static char * triggertypeFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element);
static char * fflagsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element);
static int fsnamesTag(Header h, int_32 * type, void ** data, int_32 * count,
@ -21,16 +23,23 @@ static int fssizesTag(Header h, int_32 * type, void ** data, int_32 * count,
int * freeData);
static int instprefixTag(Header h, int_32 * type, void ** data, int_32 * count,
int * freeData);
static int triggercondsTag(Header h, int_32 * type, void ** data,
int_32 * count, int * freeData);
static int triggertypeTag(Header h, int_32 * type, void ** data,
int_32 * count, int * freeData);
static char * permsString(int mode);
const struct headerSprintfExtension rpmHeaderFormats[] = {
{ HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
{ HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
{ HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
{ HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
{ HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
{ HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
{ HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
{ HEADER_EXT_FORMAT, "perms", { permsFormat } },
{ HEADER_EXT_FORMAT, "permissions", { permsFormat } },
{ HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
{ HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
} ;
@ -85,6 +94,23 @@ static char * permsString(int mode) {
return perms;
}
static char * triggertypeFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element) {
const int_32 * item = data;
char * val;
if (type != RPM_INT32_TYPE) {
val = malloc(20);
strcpy(val, _("(not a number)"));
} else if (*item & RPMSENSE_TRIGGERIN) {
val = strdup("in");
} else {
val = strdup("un");
}
return val;
}
static char * permsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element) {
char * val;
@ -140,7 +166,7 @@ static char * depflagsFormat(int_32 type, const void * data,
char * formatPrefix, int padding, int element) {
char * val;
char buf[10];
int anint = *((int_32 *) data);
int anint = *(((int_32 *) data) + element);
if (type != RPM_INT32_TYPE) {
val = malloc(20);
@ -223,3 +249,101 @@ static int fssizesTag(Header h, int_32 * type, void ** data, int_32 * count,
return 0;
}
static int triggercondsTag(Header h, int_32 * type, void ** data,
int_32 * count, int * freeData) {
int_32 * indices, * flags;
char ** names, ** versions;
int numNames, numScripts;
char ** conds, ** s;
char * item, * flagsStr;
char * chptr;
int i, j;
char buf[5];
if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names,
&numNames)) {
*freeData = 0;
return 0;
}
headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
free(s);
*freeData = 1;
*data = conds = malloc(sizeof(char * ) * numScripts);
*count = numScripts;
*type = RPM_STRING_ARRAY_TYPE;
for (i = 0; i < numScripts; i++) {
chptr = malloc(1);
*chptr = '\0';
for (j = 0; j < numNames; j++) {
if (indices[j] != i) continue;
item = malloc(strlen(names[j]) + strlen(versions[j]) + 20);
if (flags[j] & RPMSENSE_SENSEMASK) {
buf[0] = '%', buf[1] = '\0';
flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
0, j);
sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
free(flagsStr);
} else {
strcpy(item, names[j]);
}
chptr = realloc(chptr, strlen(chptr) + strlen(item) + 5);
if (*chptr) strcat(chptr, ", ");
strcat(chptr, item);
free(item);
}
conds[i] = chptr;
}
free(names);
free(versions);
return 0;
}
static int triggertypeTag(Header h, int_32 * type, void ** data,
int_32 * count, int * freeData) {
int_32 * indices, * flags;
char ** conds, ** s;
int i, j;
char buf[5];
int numScripts, numNames;
if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices,
&numNames)) {
*freeData = 0;
return 1;
}
headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
free(s);
*freeData = 1;
*data = conds = malloc(sizeof(char * ) * numScripts);
*count = numScripts;
*type = RPM_STRING_ARRAY_TYPE;
for (i = 0; i < numScripts; i++) {
for (j = 0; j < numNames; j++) {
if (indices[j] != i) continue;
if (flags[j] & RPMSENSE_TRIGGERIN)
conds[i] = strdup("in");
else
conds[i] = strdup("un");
break;
}
}
return 0;
}

View File

@ -752,7 +752,7 @@ int rpmInstallPackage(char * rootdir, rpmdb db, int fd,
}
rpmMessage(RPMMESS_DEBUG, "running preinstall script (if any)\n");
if (runScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg,
if (runInstScript("/", h, RPMTAG_PREIN, RPMTAG_PREINPROG, scriptArg,
flags & RPMINSTALL_NOSCRIPTS, 0)) {
if (replacedList) free(replacedList);
if (freeFileMem) freeFileMemory(fileMem);
@ -914,11 +914,22 @@ int rpmInstallPackage(char * rootdir, rpmdb db, int fd,
rpmMessage(RPMMESS_DEBUG, "running postinstall script (if any)\n");
if (runScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
if (runInstScript(rootdir, h, RPMTAG_POSTIN, RPMTAG_POSTINPROG, scriptArg,
flags & RPMINSTALL_NOSCRIPTS, 0)) {
return 2;
}
/* Run triggers this package sets off */
if (runTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0)) {
return 2;
}
/* Run triggers in this package which are set off by other things in
the database. */
if (runImmedTriggers(rootdir, db, RPMSENSE_TRIGGERIN, h, 0)) {
return 2;
}
if (toRemove && flags & RPMINSTALL_UPGRADE) {
rpmMessage(RPMMESS_DEBUG, "removing old versions of package\n");
intptr = toRemove;

View File

@ -12,7 +12,14 @@ struct sharedFile {
int findSharedFiles(rpmdb db, int offset, char ** fileList, int fileCount,
struct sharedFile ** listPtr, int * listCountPtr);
int runScript(char * prefix, Header h, int scriptTag, int progTag,
int runInstScript(char * prefix, Header h, int scriptTag, int progTag,
int arg, int norunScripts, int err);
/* this looks for triggers in the database which h would set off */
int runTriggers(char * root, rpmdb db, int sense, Header h,
int countCorrection);
/* while this looks for triggers in h which are set off by things in the db
database to calculate arguments to the trigger */
int runImmedTriggers(char * root, rpmdb db, int sense, Header h,
int countCorrection);
#endif

View File

@ -35,7 +35,7 @@
struct rpmdb_s {
faFile pkgs;
dbiIndex * nameIndex, * fileIndex, * groupIndex, * providesIndex;
dbiIndex * requiredbyIndex, * conflictsIndex;
dbiIndex * requiredbyIndex, * conflictsIndex, * triggerIndex;
};
static void removeIndexEntry(dbiIndex * dbi, char * name, dbiIndexRecord rec,
@ -72,11 +72,32 @@ int rpmdbInit (char * prefix, int perms) {
return openDatabase(prefix, dbpath, &db, O_CREAT | O_RDWR, perms, 1);
}
static int openDbFile(char * prefix, char * dbpath, char * shortName,
int justCheck, int perms, dbiIndex ** db){
char * filename = alloca(strlen(prefix) + strlen(dbpath) +
strlen(shortName) + 20);
if (!prefix) prefix="";
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, shortName);
if (!justCheck || !exists(filename)) {
*db = dbiOpenIndex(filename, perms, 0644);
if (!*db) {
return 1;
}
}
return 0;
}
int openDatabase(char * prefix, char * dbpath, rpmdb *rpmdbp, int mode,
int perms, int justcheck) {
char * filename;
struct rpmdb_s db;
int i;
int i, rc;
struct flock lockinfo;
/* we should accept NULL as a valid prefix */
@ -135,92 +156,38 @@ int openDatabase(char * prefix, char * dbpath, rpmdb *rpmdbp, int mode,
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "nameindex.rpm");
rc = openDbFile(prefix, dbpath, "nameindex.rpm", justcheck, mode,
&db.nameIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "fileindex.rpm", justcheck, mode,
&db.fileIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "providesindex.rpm", justcheck, mode,
&db.providesIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "requiredby.rpm", justcheck, mode,
&db.requiredbyIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "conflictsindex.rpm", justcheck, mode,
&db.conflictsIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "groupindex.rpm", justcheck, mode,
&db.groupIndex);
if (!rc)
rc = openDbFile(prefix, dbpath, "triggerindex.rpm", justcheck, mode,
&db.triggerIndex);
if (!justcheck || !exists(filename)) {
db.nameIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.nameIndex) {
if (rc) {
faClose(db.pkgs);
if (db.nameIndex) dbiCloseIndex(db.nameIndex);
if (db.fileIndex) dbiCloseIndex(db.fileIndex);
if (db.providesIndex) dbiCloseIndex(db.providesIndex);
if (db.requiredbyIndex) dbiCloseIndex(db.requiredbyIndex);
if (db.conflictsIndex) dbiCloseIndex(db.conflictsIndex);
if (db.groupIndex) dbiCloseIndex(db.groupIndex);
if (db.triggerIndex) dbiCloseIndex(db.triggerIndex);
return 1;
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "fileindex.rpm");
if (!justcheck || !exists(filename)) {
db.fileIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.fileIndex) {
faClose(db.pkgs);
dbiCloseIndex(db.nameIndex);
return 1;
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "groupindex.rpm");
if (!justcheck || !exists(filename)) {
db.groupIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.groupIndex) {
faClose(db.pkgs);
dbiCloseIndex(db.nameIndex);
dbiCloseIndex(db.fileIndex);
return 1;
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "providesindex.rpm");
if (!justcheck || !exists(filename)) {
db.providesIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.providesIndex) {
faClose(db.pkgs);
dbiCloseIndex(db.fileIndex);
dbiCloseIndex(db.nameIndex);
dbiCloseIndex(db.groupIndex);
return 1;
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "requiredby.rpm");
if (!justcheck || !exists(filename)) {
db.requiredbyIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.requiredbyIndex) {
faClose(db.pkgs);
dbiCloseIndex(db.fileIndex);
dbiCloseIndex(db.nameIndex);
dbiCloseIndex(db.groupIndex);
dbiCloseIndex(db.providesIndex);
return 1;
}
}
strcpy(filename, prefix);
strcat(filename, dbpath);
strcat(filename, "conflictsindex.rpm");
if (!justcheck || !exists(filename)) {
db.conflictsIndex = dbiOpenIndex(filename, mode, 0644);
if (!db.conflictsIndex) {
faClose(db.pkgs);
dbiCloseIndex(db.fileIndex);
dbiCloseIndex(db.nameIndex);
dbiCloseIndex(db.groupIndex);
dbiCloseIndex(db.providesIndex);
dbiCloseIndex(db.requiredbyIndex);
return 1;
}
}
*rpmdbp = malloc(sizeof(struct rpmdb_s));
**rpmdbp = db;
@ -240,6 +207,7 @@ void rpmdbClose (rpmdb db) {
if (db->providesIndex) dbiCloseIndex(db->providesIndex);
if (db->requiredbyIndex) dbiCloseIndex(db->requiredbyIndex);
if (db->conflictsIndex) dbiCloseIndex(db->conflictsIndex);
if (db->triggerIndex) dbiCloseIndex(db->triggerIndex);
free(db);
}
@ -294,6 +262,10 @@ int rpmdbFindByConflicts(rpmdb db, char * filespec, dbiIndexSet * matches) {
return dbiSearchIndex(db->conflictsIndex, filespec, matches);
}
int rpmdbFindByTriggeredBy(rpmdb db, char * filespec, dbiIndexSet * matches) {
return dbiSearchIndex(db->triggerIndex, filespec, matches);
}
int rpmdbFindByGroup(rpmdb db, char * group, dbiIndexSet * matches) {
return dbiSearchIndex(db->groupIndex, group, matches);
}
@ -337,7 +309,7 @@ int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant) {
unsigned int count;
dbiIndexRecord rec;
char ** fileList, ** providesList, ** requiredbyList;
char ** conflictList;
char ** conflictList, ** triggerList;
int i;
rec.recOffset = offset;
@ -392,6 +364,18 @@ int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant) {
free(requiredbyList);
}
if (headerGetEntry(h, RPMTAG_TRIGGERNAME, &type, (void **) &triggerList,
&count)) {
/* triggerList often contains duplicates */
for (i = 0; i < count; i++) {
rpmMessage(RPMMESS_DEBUG, "removing trigger index for %s\n",
triggerList[i]);
removeIndexEntry(db->triggerIndex, triggerList[i], rec,
1, "trigger index");
}
free(triggerList);
}
if (headerGetEntry(h, RPMTAG_CONFLICTNAME, &type, (void **) &conflictList,
&count)) {
for (i = 0; i < count; i++) {
@ -453,13 +437,15 @@ static int addIndexEntry(dbiIndex * idx, char * index, unsigned int offset,
int rpmdbAdd(rpmdb db, Header dbentry) {
unsigned int dboffset;
unsigned int i;
unsigned int i, j;
char ** fileList;
char ** providesList;
char ** requiredbyList;
char ** conflictList;
char ** triggerList;
char * name, * group;
int count, providesCount, requiredbyCount, conflictCount;
int count = 0, providesCount = 0, requiredbyCount = 0, conflictCount = 0;
int triggerCount = 0;
int type;
int rc = 0;
@ -468,25 +454,16 @@ int rpmdbAdd(rpmdb db, Header dbentry) {
if (!group) group = "Unknown";
if (!headerGetEntry(dbentry, RPMTAG_FILENAMES, &type, (void **) &fileList,
&count)) {
count = 0;
}
if (!headerGetEntry(dbentry, RPMTAG_PROVIDES, &type, (void **) &providesList,
&providesCount)) {
providesCount = 0;
}
if (!headerGetEntry(dbentry, RPMTAG_REQUIRENAME, &type,
(void **) &requiredbyList, &requiredbyCount)) {
requiredbyCount = 0;
}
if (!headerGetEntry(dbentry, RPMTAG_CONFLICTNAME, &type,
(void **) &conflictList, &conflictCount)) {
conflictCount = 0;
}
headerGetEntry(dbentry, RPMTAG_FILENAMES, &type, (void **) &fileList,
&count);
headerGetEntry(dbentry, RPMTAG_PROVIDES, &type, (void **) &providesList,
&providesCount);
headerGetEntry(dbentry, RPMTAG_REQUIRENAME, &type,
(void **) &requiredbyList, &requiredbyCount);
headerGetEntry(dbentry, RPMTAG_CONFLICTNAME, &type,
(void **) &conflictList, &conflictCount);
headerGetEntry(dbentry, RPMTAG_TRIGGERNAME, &type,
(void **) &triggerList, &triggerCount);
blockSignals();
@ -496,6 +473,8 @@ int rpmdbAdd(rpmdb db, Header dbentry) {
unblockSignals();
if (providesCount) free(providesList);
if (requiredbyCount) free(requiredbyList);
if (conflictCount) free(conflictList);
if (triggerCount) free(triggerList);
if (count) free(fileList);
return 1;
}
@ -509,36 +488,40 @@ int rpmdbAdd(rpmdb db, Header dbentry) {
if (addIndexEntry(db->groupIndex, group, dboffset, 0))
rc = 1;
for (i = 0; i < conflictCount; i++) {
if (addIndexEntry(db->conflictsIndex, conflictList[i], dboffset, 0))
rc = 1;
for (i = 0; i < triggerCount; i++) {
/* don't add duplicates */
for (j = 0; j < i; j++)
if (!strcmp(triggerList[i], triggerList[j])) break;
if (j == i)
rc += addIndexEntry(db->triggerIndex, triggerList[i], dboffset, 0);
}
for (i = 0; i < requiredbyCount; i++) {
if (addIndexEntry(db->requiredbyIndex, requiredbyList[i], dboffset, 0))
rc = 1;
}
for (i = 0; i < conflictCount; i++)
rc += addIndexEntry(db->conflictsIndex, conflictList[i], dboffset, 0);
for (i = 0; i < providesCount; i++) {
if (addIndexEntry(db->providesIndex, providesList[i], dboffset, 0))
rc = 1;
}
for (i = 0; i < requiredbyCount; i++)
rc += addIndexEntry(db->requiredbyIndex, requiredbyList[i],
dboffset, 0);
for (i = 0; i < count; i++) {
if (addIndexEntry(db->fileIndex, fileList[i], dboffset, i))
rc = 1;
}
for (i = 0; i < providesCount; i++)
rc += addIndexEntry(db->providesIndex, providesList[i], dboffset, 0);
for (i = 0; i < count; i++)
rc += addIndexEntry(db->fileIndex, fileList[i], dboffset, i);
dbiSyncIndex(db->nameIndex);
dbiSyncIndex(db->groupIndex);
dbiSyncIndex(db->fileIndex);
dbiSyncIndex(db->providesIndex);
dbiSyncIndex(db->requiredbyIndex);
dbiSyncIndex(db->triggerIndex);
unblockSignals();
if (requiredbyCount) free(requiredbyList);
if (providesCount) free(providesList);
if (conflictCount) free(conflictList);
if (triggerCount) free(triggerList);
if (count) free(fileList);
return rc;

View File

@ -112,7 +112,7 @@ extern const struct headerSprintfExtension rpmHeaderFormats[];
#define RPMTAG_BUILDARCHS 1089
#define RPMTAG_OBSOLETES 1090
#define RPMTAG_VERIFYSCRIPTPROG 1091
#define RPMTAG_TRIGGERSCRIPTPROGS 1092
#define RPMTAG_TRIGGERSCRIPTPROG 1092
#define RPMTAG_DOCDIR 1093 /* internal */
#define RPMTAG_COOKIE 1094
#define RPMTAG_FILEDEVICES 1095
@ -120,9 +120,8 @@ extern const struct headerSprintfExtension rpmHeaderFormats[];
#define RPMTAG_FILELANGS 1097
#define RPMTAG_PREFIXES 1098
#define RPMTAG_INSTPREFIXES 1099
#define RPMTAG_TRIGGERSCRIPTPROG 1100
#define RPMTAG_TRIGGERIN 1101 /* internal */
#define RPMTAG_TRIGGERUN 1102 /* internal */
#define RPMTAG_TRIGGERIN 1100 /* internal */
#define RPMTAG_TRIGGERUN 1101 /* internal */
#define RPMTAG_EXTERNAL_TAG 1000000
@ -282,6 +281,7 @@ int rpmdbFindPackage(rpmdb db, char * name, dbiIndexSet * matches);
int rpmdbFindByProvides(rpmdb db, char * provides, dbiIndexSet * matches);
int rpmdbFindByRequiredBy(rpmdb db, char * requires, dbiIndexSet * matches);
int rpmdbFindByConflicts(rpmdb db, char * conflicts, dbiIndexSet * matches);
int rpmdbFindByTriggeredBy(rpmdb db, char * package, dbiIndexSet * matches);
/* these are just convience functions */
int rpmdbFindByLabel(rpmdb db, char * label, dbiIndexSet * matches);

View File

@ -16,6 +16,8 @@
#include <sys/wait.h>
#include <unistd.h>
#include "dbindex.h"
#include "depends.h"
#include "install.h"
#include "intl.h"
#include "messages.h"
@ -34,8 +36,10 @@ static int handleSharedFiles(rpmdb db, int offset, char ** fileList,
char ** fileMd5List, int fileCount,
enum fileActions * fileActions);
static int removeFile(char * file, char state, unsigned int flags, char * md5,
short mode, enum fileActions action, char * rmmess,
short mode, enum fileActions action,
int brokenMd5, int test);
static int runScript(Header h, char * root, int progArgc, char ** progArgv,
char * script, int arg1, int arg2, int errfd);
static int sharedFileCmp(const void * one, const void * two) {
if (((struct sharedFile *) one)->secRecOffset <
@ -200,7 +204,7 @@ int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int flags) {
Header h;
int i, j;
int fileCount;
char * rmmess, * name, * version, * release;
char * name, * version, * release;
char * fnbuffer = NULL;
dbiIndexSet matches;
int fnbuffersize = 0;
@ -237,23 +241,24 @@ int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int flags) {
scriptArg = matches.count - 1;
dbiFreeIndexRecord(matches);
if (flags & RPMUNINSTALL_TEST) {
rmmess = "would remove";
} else {
rmmess = "removing";
/* run triggers from this package which are keyed on installed packages */
if (runImmedTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1)) {
return 2;
}
if (!(flags & RPMUNINSTALL_TEST)) {
rpmMessage(RPMMESS_DEBUG, "running preuninstall script (if any)\n");
/* run triggers which are set off by the removal of this package */
if (runTriggers(prefix, db, RPMSENSE_TRIGGERUN, h, -1))
return 1;
if (runScript(prefix, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
if (!(flags & RPMUNINSTALL_TEST)) {
if (runInstScript(prefix, h, RPMTAG_PREUN, RPMTAG_PREUNPROG, scriptArg,
flags & RPMUNINSTALL_NOSCRIPTS, 0)) {
headerFree(h);
return 1;
}
}
rpmMessage(RPMMESS_DEBUG, "%s files test = %d\n", rmmess,
rpmMessage(RPMMESS_DEBUG, "will remove files test = %d\n",
flags & RPMUNINSTALL_TEST);
if (!(flags & RPMUNINSTALL_JUSTDB) &&
headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList,
@ -321,7 +326,7 @@ int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int flags) {
removeFile(fnbuffer, fileStatesList[i], fileFlagsList[i],
fileMd5List[i], fileModesList[i], fileActions[i],
rmmess, !headerIsEntry(h, RPMTAG_RPMVERSION),
!headerIsEntry(h, RPMTAG_RPMVERSION),
flags & RPMUNINSTALL_TEST);
}
@ -331,68 +336,49 @@ int rpmRemovePackage(char * prefix, rpmdb db, unsigned int offset, int flags) {
if (!(flags & RPMUNINSTALL_TEST)) {
rpmMessage(RPMMESS_DEBUG, "running postuninstall script (if any)\n");
runScript(prefix, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG, scriptArg,
runInstScript(prefix, h, RPMTAG_POSTUN, RPMTAG_POSTUNPROG, scriptArg,
flags & RPMUNINSTALL_NOSCRIPTS, 0);
}
headerFree(h);
rpmMessage(RPMMESS_DEBUG, "%s database entry\n", rmmess);
rpmMessage(RPMMESS_DEBUG, "removing database entry\n");
if (!(flags & RPMUNINSTALL_TEST))
rpmdbRemove(db, offset, 0);
return 0;
}
int runScript(char * root, Header h, int scriptTag, int progTag,
int arg, int norunScripts, int err) {
char * script;
char * fn;
int fd = -1;
int isdebug = rpmIsDebug();
int child;
int status;
char upgradeArg[20];
static int runScript(Header h, char * root, int progArgc, char ** progArgv,
char * script, int arg1, int arg2, int errfd) {
char ** argv;
int argc;
char ** prefixes = NULL;
int numPrefixes;
char * oldPrefix;
char * program;
char ** programArgv;
char ** argv = NULL;
int programArgc;
int programType = 0;
int pipes[2];
int out = 0;
int freePrefixes = 0;
int maxPrefixLength;
int len;
char * prefixBuf;
pid_t child;
int status;
char * fn;
int fd;
int i;
int freePrefixes;
int pipes[2];
int out = 1;
if (norunScripts) return 0;
sprintf(upgradeArg, "%d", arg);
/* 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 && !script)
if (!progArgv && !script)
return 0;
else if (!programArgv) {
programArgv = malloc(4 * sizeof(char *));
programArgv[0] = "/bin/sh";
programArgc = 1;
} else if (programType == RPM_STRING_TYPE) {
program = (char *) programArgv;
programArgv = malloc(4 * sizeof(char *));
programArgv[0] = program;
programArgc = 1;
else if (!progArgv) {
argv = alloca(5 * sizeof(char *));
argv[0] = "/bin/sh";
argc = 1;
} else {
argv = programArgv;
programArgv = malloc((programArgc + 3) * sizeof(char *));
memcpy(programArgv, argv, programArgc * sizeof(char *));
argv = progArgv;
argv = alloca((progArgc + 4) * sizeof(char *));
memcpy(argv, progArgv, progArgc * sizeof(char *));
argc = progArgc;
}
if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void *) &prefixes,
@ -409,42 +395,45 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
maxPrefixLength = 0;
for (i = 0; i < numPrefixes; i++) {
child = strlen(prefixes[i]);
if (child > maxPrefixLength) maxPrefixLength = child;
len = strlen(prefixes[i]);
if (len > maxPrefixLength) maxPrefixLength = len;
}
prefixBuf = alloca(maxPrefixLength + 50);
rpmMessage(RPMMESS_DEBUG, "running inst helper %s\n", programArgv[0]);
if (script) {
if (makeTempFile(root, &fn, &fd)) {
free(programArgv);
if (argv)
free(argv);
if (freePrefixes) free(prefixes);
return 1;
}
if (isdebug &&
(!strcmp(programArgv[0], "/bin/sh") ||
!strcmp(programArgv[0], "/bin/bash")))
if (rpmIsDebug() &&
(!strcmp(argv[0], "/bin/sh") || !strcmp(argv[0], "/bin/bash")))
write(fd, "set -x\n", 7);
write(fd, script, strlen(script));
close(fd);
programArgv[programArgc++] = fn + strlen(root);
programArgv[programArgc++] = upgradeArg;
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);
}
}
programArgv[programArgc] = NULL;
argv[argc] = NULL;
if (err) {
if (errfd) {
if (rpmIsVerbose()) {
out = err;
out = errfd;
} else {
out = open("/dev/null", O_WRONLY);
if (out < 0) {
out = err;
out = errfd;
}
}
}
@ -456,12 +445,12 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
dup2(pipes[0], 0);
close(pipes[0]);
if (err) {
if (err != 2) dup2(err, 2);
if (errfd) {
if (errfd != 2) dup2(errfd, 2);
if (out != 1) dup2(out, 1);
/* make sure we don't close stdin/stderr/stdout by mistake! */
/* if (err > 2) close (err);
if (out > 2 && out != err) close (out); */
if (errfd > 2) close (errfd);
if (out > 2 && out != errfd) close (out);
}
doputenv(SCRIPT_PATH);
@ -478,13 +467,12 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
}
if (strcmp(root, "/")) {
rpmMessage(RPMMESS_DEBUG, "performing chroot(%s)\n", root);
chroot(root);
}
chdir("/");
execv(programArgv[0], programArgv);
execv(argv[0], argv);
_exit(-1);
}
@ -492,18 +480,13 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
if (freePrefixes) free(prefixes);
if (err) {
if (errfd) {
if (out > 2) close(out);
if (err > 2) close(err);
if (!rpmIsVerbose()) close(out);
if (errfd > 2) close(errfd);
}
free(programArgv);
if (argv)
free(argv);
if (script) {
if (!isdebug) unlink(fn);
if (!rpmIsDebug()) unlink(fn);
free(fn);
}
@ -515,8 +498,37 @@ int runScript(char * root, Header h, int scriptTag, int progTag,
return 0;
}
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;
}
static int removeFile(char * file, char state, unsigned int flags, char * md5,
short mode, enum fileActions action, char * rmmess,
short mode, enum fileActions action,
int brokenMd5, int test) {
char currentMd5[40];
int rc = 0;
@ -571,7 +583,7 @@ static int removeFile(char * file, char state, unsigned int flags, char * md5,
break;
case REMOVE:
rpmMessage(RPMMESS_DEBUG, "%s - %s\n", file, rmmess);
rpmMessage(RPMMESS_DEBUG, "%s - removing\n", file);
if (S_ISDIR(mode)) {
if (!test) {
if (rmdir(file)) {
@ -603,3 +615,147 @@ static int removeFile(char * file, char state, unsigned int flags, char * md5,
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;
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;
if (!headerMatchesDepFlags(sourceH, triggerVersions[i],
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;
int i, j;
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++) {
if (!(triggeredH = rpmdbGetRecord(db, matches.recs[i].recOffset)))
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++) {
if (!(sourceH = rpmdbGetRecord(db, matches.recs[j].recOffset)))
return 1;
rc |= handleOneTrigger(root, db, sense, sourceH, h,
countCorrection, matches.count, triggersRun);
headerFree(sourceH);
if (triggersRun[triggerIndices[i]]) break;
}
dbiFreeIndexRecord(matches);
}
return rc;
}

View File

@ -210,6 +210,6 @@ int rpmVerifyFile(char * prefix, Header h, int filenum, int * result,
}
int rpmVerifyScript(char * root, Header h, int err) {
return runScript(root, h, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG,
return runInstScript(root, h, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG,
0, 0, err);
}

10
query.c
View File

@ -442,6 +442,16 @@ int doQuery(char * prefix, enum querysources source, int queryFlags,
}
break;
case QUERY_TRIGGEREDBY:
if (rpmdbFindByTriggeredBy(db, arg, &matches)) {
fprintf(stderr, _("no package triggers %s\n"), arg);
retcode = 1;
} else {
showMatches(db, matches, queryFlags, queryFormat);
dbiFreeIndexRecord(matches);
}
break;
case QUERY_WHATREQUIRES:
if (rpmdbFindByRequiredBy(db, arg, &matches)) {
fprintf(stderr, _("no package requires %s\n"), arg);

View File

@ -5,7 +5,7 @@
enum querysources { QUERY_PATH, QUERY_PACKAGE, QUERY_ALL, QUERY_RPM,
QUERY_GROUP, QUERY_WHATPROVIDES, QUERY_WHATREQUIRES,
QUERY_DBOFFSET };
QUERY_DBOFFSET, QUERY_TRIGGEREDBY };
#define QUERY_FOR_LIST (1 << 1)
#define QUERY_FOR_STATE (1 << 2)

15
rpm.c
View File

@ -45,6 +45,7 @@
#define GETOPT_INSTALL 1014
#define GETOPT_RMSOURCE 1015
#define GETOPT_RELOCATE 1016
#define GETOPT_TRIGGEREDBY 1017
char * version = VERSION;
@ -158,6 +159,7 @@ static struct poptOption optionsTable[] = {
{ "tarball", 't', POPT_ARG_STRING, 0, 't' },
{ "test", '\0', 0, &test, 0 },
{ "timecheck", '\0', POPT_ARG_STRING, 0, GETOPT_TIMECHECK },
{ "triggeredby", '\0', 0, 0, GETOPT_TRIGGEREDBY },
{ "upgrade", 'U', 0, 0, 'U' },
{ "uninstall", 'u', 0, 0, 'u' },
{ "verbose", 'v', 0, 0, 'v' },
@ -503,10 +505,9 @@ int main(int argc, char ** argv) {
int queryFor = 0;
int installFlags = 0, uninstallFlags = 0, interfaceFlags = 0;
int buildAmount = 0;
int shortCircuit = 0, queryTags = 0, excldocs = 0;
int showrc = 0;
int gotDbpath = 0, building = 0, verifyFlags;
int noMd5 = 0, allFiles = 0, justdb = 0, rmsource = 0;
int noMd5 = 0, rmsource = 0;
int checksigFlags = 0;
int timeCheck = 0;
int addSign = NEW_SIGNATURE;
@ -532,7 +533,6 @@ int main(int argc, char ** argv) {
struct rpmRelocation * relocations = NULL;
int numRelocations = 0;
/* set the defaults for the various command line options */
allFiles = 0;
allMatches = 0;
@ -570,7 +570,6 @@ int main(int argc, char ** argv) {
test = 0;
rpm_version = 0;
/* set up the correct locale */
setlocale(LC_ALL, "" );
@ -787,6 +786,14 @@ int main(int argc, char ** argv) {
querySource = QUERY_WHATPROVIDES;
break;
case GETOPT_TRIGGEREDBY:
if (querySource != QUERY_PACKAGE &&
querySource != QUERY_TRIGGEREDBY)
argerror(_("one type of query/verify may be performed at a "
"time"));
querySource = QUERY_TRIGGEREDBY;
break;
case GETOPT_REBUILD:
if (bigMode != MODE_UNKNOWN && bigMode != MODE_REBUILD)
argerror(_("only one major mode may be specified"));

View File

@ -49,3 +49,7 @@ Summary : %{SUMMARY}\n\
Description :\n%{DESCRIPTION}\n'
rpm alias --changelog --qf '[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n\n%{CHANGELOGTEXT}\n\n]'
rpm alias --triggerscripts --qf '\
[trigger%{TRIGGERTYPE} script (through %{TRIGGERSCRIPTPROG}) -- %{TRIGGERCONDS}\n\
%{TRIGGERSCRIPTS}\n]'