rpm/verify.c

237 lines
5.9 KiB
C
Raw Normal View History

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lib/messages.h"
#include "install.h"
#include "query.h"
#include "rpmlib.h"
#include "verify.h"
static void verifyHeader(char * prefix, Header h, int verifyFlags);
static void verifyMatches(char * prefix, rpmdb db, dbiIndexSet matches,
int verifyFlags);
static void verifyDependencies(rpmdb db, Header h);
static void verifyHeader(char * prefix, Header h, int verifyFlags) {
char ** fileList;
int count, type;
int verifyResult;
int i;
char * size, * md5, * link, * mtime, * mode;
char * group, * user, * rdev;
int_32 * fileFlagsList;
int omitMask = 0;
if (!(verifyFlags & VERIFY_MD5)) omitMask = RPMVERIFY_MD5;
headerGetEntry(h, RPMTAG_FILEFLAGS, NULL, (void **) &fileFlagsList, NULL);
if (headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList,
&count)) {
for (i = 0; i < count; i++) {
if (rpmVerifyFile(prefix, h, i, &verifyResult, omitMask))
printf("missing %s\n", fileList[i]);
else {
size = md5 = link = mtime = mode = ".";
user = group = rdev = ".";
if (!verifyResult) continue;
if (verifyResult & RPMVERIFY_MD5)
md5 = "5";
if (verifyResult & RPMVERIFY_FILESIZE)
size = "S";
if (verifyResult & RPMVERIFY_LINKTO)
link = "L";
if (verifyResult & RPMVERIFY_MTIME)
mtime = "T";
if (verifyResult & RPMVERIFY_RDEV)
rdev = "D";
if (verifyResult & RPMVERIFY_USER)
user = "U";
if (verifyResult & RPMVERIFY_GROUP)
group = "G";
if (verifyResult & RPMVERIFY_MODE)
mode = "M";
printf("%s%s%s%s%s%s%s%s %c %s\n",
size, mode, md5, rdev, link, user, group, mtime,
fileFlagsList[i] & RPMFILE_CONFIG ? 'c' : ' ',
fileList[i]);
}
}
free(fileList);
}
}
static void verifyDependencies(rpmdb db, Header h) {
rpmDependencies rpmdep;
struct rpmDependencyConflict * conflicts;
int numConflicts;
char * name, * version, * release;
int type, count, i;
rpmdep = rpmdepDependencies(db);
rpmdepAddPackage(rpmdep, h);
rpmdepCheck(rpmdep, &conflicts, &numConflicts);
rpmdepDone(rpmdep);
if (numConflicts) {
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
printf("Unsatisfied dependencies for %s-%s-%s: ", name, version,
release);
for (i = 0; i < numConflicts; i++) {
if (i) printf(", ");
printf("%s", conflicts[i].needsName);
if (conflicts[i].needsFlags) {
printDepFlags(stdout, conflicts[i].needsVersion,
conflicts[i].needsFlags);
}
}
printf("\n");
rpmdepFreeConflicts(conflicts, numConflicts);
}
}
static void verifyPackage(char * root, rpmdb db, Header h, int verifyFlags) {
if (verifyFlags & VERIFY_DEPS)
verifyDependencies(db, h);
if (verifyFlags & VERIFY_FILES)
verifyHeader(root, h, verifyFlags);
if (verifyFlags & VERIFY_SCRIPT) {
rpmVerifyScript(root, h, 1);
}
}
static void verifyMatches(char * prefix, rpmdb db, dbiIndexSet matches,
int verifyFlags) {
int i;
Header h;
for (i = 0; i < matches.count; i++) {
if (matches.recs[i].recOffset) {
rpmMessage(RPMMESS_DEBUG, "verifying record number %d\n",
matches.recs[i].recOffset);
h = rpmdbGetRecord(db, matches.recs[i].recOffset);
if (!h) {
fprintf(stderr, "error: could not read database record\n");
} else {
verifyPackage(prefix, db, h, verifyFlags);
headerFree(h);
}
}
}
}
void doVerify(char * prefix, enum verifysources source, char ** argv,
int verifyFlags) {
Header h;
int offset;
int fd;
int rc;
int isSource;
rpmdb db;
dbiIndexSet matches;
char * arg;
if ((source == VERIFY_SRPM || source == VERIFY_RPM) &&
!(verifyFlags & VERIFY_DEPS)) {
db = NULL;
} else {
if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
exit(1);
}
}
if (source == VERIFY_EVERY) {
offset = rpmdbFirstRecNum(db);
while (offset) {
h = rpmdbGetRecord(db, offset);
if (!h) {
fprintf(stderr, "could not read database record!\n");
exit(1);
}
verifyPackage(prefix, db, h, verifyFlags);
headerFree(h);
offset = rpmdbNextRecNum(db, offset);
}
} else {
while (*argv) {
arg = *argv++;
switch (source) {
case VERIFY_SRPM:
case VERIFY_RPM:
fd = open(arg, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "open of %s failed: %s\n", arg,
strerror(errno));
} else {
rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
close(fd);
switch (rc) {
case 0:
verifyPackage(prefix, db, h, verifyFlags);
headerFree(h);
break;
case 1:
fprintf(stderr, "%s is not an RPM\n", arg);
}
}
break;
case VERIFY_SGROUP:
case VERIFY_GRP:
if (rpmdbFindByGroup(db, arg, &matches)) {
fprintf(stderr, "group %s does not contain any pacakges\n",
arg);
} else {
verifyMatches(prefix, db, matches, verifyFlags);
dbiFreeIndexRecord(matches);
}
break;
case VERIFY_SPATH:
case VERIFY_PATH:
if (rpmdbFindByFile(db, arg, &matches)) {
fprintf(stderr, "file %s is not owned by any package\n",
arg);
} else {
verifyMatches(prefix, db, matches, verifyFlags);
dbiFreeIndexRecord(matches);
}
break;
case VERIFY_SPACKAGE:
case VERIFY_PACKAGE:
rc = findPackageByLabel(db, arg, &matches);
if (rc == 1)
fprintf(stderr, "package %s is not installed\n", arg);
else if (rc == 2) {
fprintf(stderr, "error looking for package %s\n", arg);
} else {
verifyMatches(prefix, db, matches, verifyFlags);
dbiFreeIndexRecord(matches);
}
break;
case VERIFY_EVERY:
; /* nop */
}
}
}
if (source != VERIFY_SRPM && source != VERIFY_RPM) {
rpmdbClose(db);
}
}