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 <string.h>
-
- #include "install.h"
- #include "log.h"
- #include "hash.h"
- #include "pkgs.h"
-
- #define MAXPKGS 1024
-
- #if 0
- static void printMemStats(char *mess)
- {
- char buf[1024];
- printf("%s\n", mess);
- sprintf(buf, "cat /proc/%d/status | grep VmSize", getpid());
- system(buf);
- }
- #endif
-
- static 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]); */
- if (strncmp(installedFiles[installedX], "/etc/rc.d/", 10))
- htAddToTable(ht, installedFiles[installedX]);
- installedX++;
- } else {
- rc = strcmp(availFiles[availX], installedFiles[installedX]);
- if (rc > 0) {
- /* Avail > Installed -- file has moved */
- /* printf("=> %s\n", installedFiles[installedX]); */
- if (strncmp(installedFiles[installedX], "/etc/rc.d/", 10))
- htAddToTable(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++;
- }
- }
- }
- }
-
- static void addLostFiles(struct pkgSet *psp, struct hash_table *ht, rpmdb db)
- {
- int num;
- Header h;
- char *name;
- struct packageInfo **pack;
- struct packageInfo key;
- struct packageInfo *keyaddr = &key;
- char **installedFiles;
- int installedFileCount;
-
- num = rpmdbFirstRecNum(db);
- while (num) {
- h = rpmdbGetRecord(db, num);
- headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
- key.name = name;
-
- pack = bsearch(&keyaddr, psp->packages, psp->numPackages,
- sizeof(*psp->packages), (void *)pkgCompare);
- if (!pack) {
- if (headerGetEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &installedFiles, &installedFileCount)) {
- compareFileList(0, NULL, installedFileCount,
- installedFiles, ht);
- free(installedFiles);
- }
- }
-
- headerFree(h);
- num = rpmdbNextRecNum(db, num);
- }
- }
-
- static void errorFunction(void)
- {
- }
-
- static int findUpgradePackages(rpmdb db, int ugdbfd, struct hash_table *ht,
- char **resultArray, int *availPkgs)
- {
- int pkgNum, skipThis;
- Header h, installedHeader;
- char *name, *version, *release;
- dbiIndexSet matches;
- int rc, i;
- char **installedFiles, **availFiles;
- int installedFileCount, availFileCount;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
-
- while ((h = headerRead(ugdbfd, HEADER_MAGIC_YES))) {
- name = version = release = NULL;
- headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
- headerGetEntry(h, RPMTAG_VERSION, NULL, (void **) &version, NULL);
- headerGetEntry(h, RPMTAG_RELEASE, NULL, (void **) &release, NULL);
- if (! (name && version && release)) {
- /* bum header */
- logMessage("Failed with bad header");
- return(INST_ERROR);
- }
-
- /* XXX - Need to do serial number stuff someday */
- /*printf("Avail: %s-%s-%s\n", name, version, release);*/
- rc = rpmdbFindPackage(db, name, &matches);
-
- if (rc == 0) {
- skipThis = 0;
- rpmErrorSetCallback(errorFunction);
- for (i = 0; i < matches.count; i++) {
- installedHeader =
- rpmdbGetRecord(db, matches.recs[i].recOffset);
- if (rpmVersionCompare(installedHeader, h) > 0) {
- /* already have a newer version installed */
- /*printf("Already have newer version\n");*/
- skipThis = 1;
- break;
- }
- }
- rpmErrorSetCallback(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");*/
- if (!resultArray[pkgNum]) {
- resultArray[pkgNum] = strdup(name);
- }
-
- if (!headerGetEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount)) {
- availFiles = NULL;
- availFileCount = 0;
- }
-
- for (i = 0; i < matches.count; i++) {
- /* Compare the file lists */
- installedHeader =
- rpmdbGetRecord(db, matches.recs[i].recOffset);
- if (!headerGetEntry(installedHeader, RPMTAG_FILENAMES, NULL,
- (void **) &installedFiles,
- &installedFileCount)) {
- installedFiles = NULL;
- installedFileCount = 0;
- }
-
- compareFileList(availFileCount, availFiles,
- installedFileCount, installedFiles, ht);
-
- if (installedFiles) {
- free(installedFiles);
- }
- headerFree(installedHeader);
- }
-
- if (availFiles) {
- free(availFiles);
- }
- }
-
- if (rc == 0) {
- dbiFreeIndexRecord(matches);
- }
-
- /*printf("\n\n");*/
-
-
- headerFree(h);
- pkgNum++;
- }
-
- *availPkgs = pkgNum;
- return 0;
- }
-
- static int removeMovedFilesAlreadyHandled(int ugdbfd, struct hash_table *ht,
- char **resultArray)
- {
- int pkgNum;
- char *name;
- int i;
- Header h;
- char **availFiles;
- int availFileCount;
- char *file;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
- while ((h = headerRead(ugdbfd, HEADER_MAGIC_YES))) {
- if (resultArray[pkgNum]) {
- name = NULL;
- headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
-
- if (!headerGetEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount)) {
- availFiles = NULL;
- availFileCount = 0;
- }
-
- for (i = 0; i < availFileCount; i++) {
- if ((file = htInTable(ht, availFiles[i]))) {
- *file = '\0';
- /*printf("File already in %s: %s\n", name, availFiles[i]);*/
- if (!resultArray[pkgNum]) {
- resultArray[pkgNum] = strdup(name);
- }
- break;
- }
- }
- if (availFiles) {
- free(availFiles);
- }
- }
-
- pkgNum++;
- headerFree(h);
- }
-
- return 0;
- }
-
- static int findPackagesWithRelocatedFiles(int ugdbfd, struct hash_table *ht,
- char **resultArray)
- {
- int pkgNum;
- char *name;
- int i;
- Header h;
- char **availFiles;
- int availFileCount;
- char *file;
-
- lseek(ugdbfd, 0, SEEK_SET);
-
- pkgNum = 0;
- while ((h = headerRead(ugdbfd, HEADER_MAGIC_YES))) {
- if (! resultArray[pkgNum]) {
- name = NULL;
- headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
-
- availFiles = NULL;
- availFileCount = 0;
- if (headerGetEntry(h, RPMTAG_FILENAMES, NULL,
- (void **) &availFiles, &availFileCount)) {
- for (i = 0; i < availFileCount; i++) {
- if ((file = htInTable(ht, availFiles[i]))) {
- *file = '\0';
- /*printf("Found file in %s: %s\n", name,
- availFiles[i]);*/
- if (!resultArray[pkgNum]) {
- resultArray[pkgNum] = strdup(name);
- }
- break;
- }
- }
- free(availFiles);
- }
- }
-
- pkgNum++;
- headerFree(h);
- }
-
- return 0;
- }
-
- int ugFindUpgradePackages(struct pkgSet *psp, char *installRoot,
- char *ugdbName)
- {
- int fd;
- rpmdb db;
- struct hash_table *hashTable;
- char *installThisPackage[MAXPKGS];
- int availPkgs, i, upgradeCount;
- struct packageInfo **pack;
- struct packageInfo key;
- struct packageInfo *keyaddr = &key;
-
- if ((fd = open(ugdbName, O_RDONLY)) < 0) {
- logMessage("failed opening %s", ugdbName);
- return(INST_ERROR);
- }
-
- rpmReadConfigFiles(NULL, NULL, NULL, 0);
- if (rpmdbOpen(installRoot, &db, O_RDWR | O_CREAT, 0644)) {
- close(fd);
- logMessage("failed opening %s/var/lib/rpm/packages.rpm",
- installRoot);
- return(INST_ERROR);
- }
-
- for (i = 0; i < MAXPKGS; i++) {
- installThisPackage[i] = NULL;
- }
-
- hashTable = htNewTable(1103);
-
- addLostFiles(psp, hashTable, db);
-
- if (findUpgradePackages(db, fd, hashTable, \
- installThisPackage, &availPkgs)) {
- close(fd);
- rpmdbClose(db);
- return(INST_ERROR);
- }
- /*hash_stats(hashTable);*/
-
- removeMovedFilesAlreadyHandled(fd, hashTable, installThisPackage);
-
- findPackagesWithRelocatedFiles(fd, hashTable, installThisPackage);
-
- htFreeHashTable(hashTable);
-
- /*printMemStats("Done");*/
-
- rpmdbClose(db);
- close(fd);
-
- upgradeCount = 0;
- for (i = 0; i < MAXPKGS; i++) {
- if (installThisPackage[i]) {
- key.name = installThisPackage[i];
- pack = bsearch(&keyaddr, psp->packages, psp->numPackages,
- sizeof(*psp->packages), (void *)pkgCompare);
- (*pack)->selected = 1;
- free(installThisPackage[i]);
- upgradeCount++;
- }
- }
-
- logMessage("ugFindUpgradePackages() marked %d packages", upgradeCount);
-
- return 0;
- }
-