home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <rpm/rpmlib.h>
- #include <rpm/header.h>
- #include <rpm/rpmerr.h>
-
- #include "hash.h"
-
- #define MAXPKGS 1024
-
- void compareFileList(int availFileCount, char **availFiles,
- int installedFileCount, char **installedFiles,
- struct hash_table *ht)
- {
- int installedX, availX, rc;
-
- availX = 0;
- installedX = 0;
- while (installedX < installedFileCount) {
- if (availX == availFileCount) {
- /* All the rest have moved */
- /* printf("=> %s\n", installedFiles[installedX]); */
- add_to_table(ht, installedFiles[installedX]);
- installedX++;
- } else {
- rc = strcmp(availFiles[availX], installedFiles[installedX]);
- if (rc > 0) {
- /* Avail > Installed -- file has moved */
- /* printf("=> %s\n", installedFiles[installedX]); */
- add_to_table(ht, installedFiles[installedX]);
- installedX++;
- } else if (rc < 0) {
- /* Avail < Installed -- avail has some new files */
- availX++;
- } else {
- /* Files are equal -- file not moved */
- availX++;
- installedX++;
- }
- }
- }
-
- }
-
- void errorFunction(void)
- {
- }
-
- int findUpgradePackages(rpmdb db, int ugdbfd, struct hash_table *ht,
- int *resultArray, int *availPkgs)
- {
- int pkgNum, skipThis;
- Header h, installedHeader;
- char *name, *version, *release;
- dbIndexSet matches;
- int rc, i;
- char **installedFiles, **availFiles;
- int installedFileCount, availFileCount;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
-
- while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
- name = version = release = NULL;
- getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
- getEntry(h, RPMTAG_VERSION, NULL, (void **) &version, NULL);
- getEntry(h, RPMTAG_RELEASE, NULL, (void **) &release, NULL);
- if (! (name && version && release)) {
- /* bum header */
- printf("Failed with bad header\n");
- exit(1);
- }
-
- /* XXX - Need to do serial number stuff someday */
- /*printf("Avail: %s-%s-%s\n", name, version, release);*/
- rc = rpmdbFindPackage(db, name, &matches);
- /*printf("Find returned: %d\n", rc);*/
-
- if (rc == 0) {
- skipThis = 0;
- errSetCallback(errorFunction);
- for (i = 0; i < matches.count; i++) {
- if (rpmEnsureOlder(db, name, version, release,
- matches.recs[i].recOffset)) {
- /* already have a newer version installed */
- /*printf("Already have newer version\n");*/
- skipThis = 1;
- break;
- }
- }
- errSetCallback(NULL);
- if (! skipThis) {
- /* no newer version installed */
- /*printf("No newer version installed\n");*/
- skipThis = 0;
- }
- } else {
- skipThis = 1;
- /*printf("Not installed\n");*/
- }
-
- if (skipThis) {
- /*printf("DO NOT INSTALL\n");*/
- } else {
- /*printf("UPGRADE\n");*/
- resultArray[pkgNum] = 1;
-
- getEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount);
-
- for (i = 0; i < matches.count; i++) {
- /* Compare the file lists */
- installedHeader =
- rpmdbGetRecord(db, matches.recs[i].recOffset);
- getEntry(installedHeader, RPMTAG_FILENAMES, NULL,
- (void **) &installedFiles, &installedFileCount);
-
- compareFileList(availFileCount, availFiles,
- installedFileCount, installedFiles, ht);
-
- free(installedFiles);
- freeHeader(installedHeader);
- }
-
- free(availFiles);
- }
- if (rc == 0) {
- freeDBIndexRecord(matches);
- }
-
- /*printf("\n\n");*/
-
- freeHeader(h);
- pkgNum++;
- }
-
- *availPkgs = pkgNum;
- return 0;
- }
-
- int removeMovedFilesAlreadyHandled(int ugdbfd, struct hash_table *ht,
- int *resultArray)
- {
- int pkgNum;
- char *name;
- int i;
- Header h;
- char **availFiles;
- int availFileCount;
- char *file;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
- while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
- if (resultArray[pkgNum]) {
- name = NULL;
- getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
-
- getEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount);
-
- for (i = 0; i < availFileCount; i++) {
- if ((file = in_table(ht, availFiles[i]))) {
- *file = '\0';
- printf("File already in %s: %s\n", name, availFiles[i]);
- resultArray[pkgNum] = 1;
- break;
- }
- }
-
- free(availFiles);
- }
-
- pkgNum++;
- freeHeader(h);
- }
-
- return 0;
- }
-
- int findPackagesWithRelocatedFiles(int ugdbfd, struct hash_table *ht,
- int *resultArray)
- {
- int pkgNum;
- char *name;
- int i;
- Header h;
- char **availFiles;
- int availFileCount;
- char *file;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
- while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
- if (! resultArray[pkgNum]) {
- name = NULL;
- getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
-
- getEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount);
-
- for (i = 0; i < availFileCount; i++) {
- if ((file = in_table(ht, availFiles[i]))) {
- *file = '\0';
- printf("Found file in %s: %s\n", name, availFiles[i]);
- resultArray[pkgNum] = 1;
- break;
- }
- }
-
- free(availFiles);
- }
-
- pkgNum++;
- freeHeader(h);
- }
-
- return 0;
- }
-
- int main(int argc, char **argv)
- {
- int fd;
- rpmdb db;
- struct hash_table *hashTable;
- int installThisPackage[MAXPKGS];
- int availPkgs, i;
-
- if ((fd = open(argv[1], O_RDONLY)) < 0) {
- perror("open");
- exit(1);
- }
-
- if (rpmdbOpen("/", &db, O_RDONLY, 0644)) {
- fprintf(stderr, "error: cannot open /var/lib/rpm/packages.rpm\n");
- exit(1);
- }
-
- for(i = 0; i < MAXPKGS; i++) {
- installThisPackage[i] = 0;
- }
-
- hashTable = new_table(1103);
-
- findUpgradePackages(db, fd, hashTable, installThisPackage, &availPkgs);
- rpmdbClose(db);
- hash_stats(hashTable);
- removeMovedFilesAlreadyHandled(fd, hashTable, installThisPackage);
- findPackagesWithRelocatedFiles(fd, hashTable, installThisPackage);
-
- close(fd);
-
- return 0;
- }
-