home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / MISC / SRC / UPGRADE / UPGRADE.C < prev   
Encoding:
C/C++ Source or Header  |  1996-07-28  |  5.8 KB  |  260 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <rpm/rpmlib.h>
  6. #include <rpm/header.h>
  7. #include <rpm/rpmerr.h>
  8.  
  9. #include "hash.h"
  10.  
  11. #define MAXPKGS 1024
  12.  
  13. void compareFileList(int availFileCount, char **availFiles,
  14.              int installedFileCount, char **installedFiles,
  15.              struct hash_table *ht)
  16. {
  17.     int installedX, availX, rc;
  18.     
  19.     availX = 0;
  20.     installedX = 0;
  21.     while (installedX < installedFileCount) {
  22.     if (availX == availFileCount) {
  23.         /* All the rest have moved */
  24.         /* printf("=> %s\n", installedFiles[installedX]); */
  25.         add_to_table(ht, installedFiles[installedX]);
  26.         installedX++;
  27.     } else {
  28.         rc = strcmp(availFiles[availX], installedFiles[installedX]);
  29.         if (rc > 0) {
  30.         /* Avail > Installed -- file has moved */
  31.         /* printf("=> %s\n", installedFiles[installedX]); */
  32.         add_to_table(ht, installedFiles[installedX]);
  33.         installedX++;
  34.         } else if (rc < 0) {
  35.         /* Avail < Installed -- avail has some new files */
  36.         availX++;
  37.         } else {
  38.         /* Files are equal -- file not moved */
  39.         availX++;
  40.         installedX++;
  41.         }
  42.     }
  43.     }
  44.         
  45. }
  46.  
  47. void errorFunction(void)
  48. {
  49. }
  50.  
  51. int findUpgradePackages(rpmdb db, int ugdbfd, struct hash_table *ht,
  52.             int *resultArray, int *availPkgs)
  53. {
  54.     int pkgNum, skipThis;
  55.     Header h, installedHeader;
  56.     char *name, *version, *release;
  57.     dbIndexSet matches;
  58.     int rc, i;
  59.     char **installedFiles, **availFiles;
  60.     int installedFileCount, availFileCount;
  61.  
  62.     lseek(ugdbfd, 0, SEEK_SET);
  63.  
  64.     pkgNum = 0;
  65.  
  66.     while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
  67.     name = version = release = NULL;
  68.     getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
  69.     getEntry(h, RPMTAG_VERSION, NULL, (void **) &version, NULL);
  70.     getEntry(h, RPMTAG_RELEASE, NULL, (void **) &release, NULL);
  71.     if (! (name && version && release)) {
  72.         /* bum header */
  73.         printf("Failed with bad header\n");
  74.         exit(1);
  75.     }
  76.  
  77.     /* XXX - Need to do serial number stuff someday */
  78.     /*printf("Avail: %s-%s-%s\n", name, version, release);*/
  79.     rc = rpmdbFindPackage(db, name, &matches);
  80.     /*printf("Find returned: %d\n", rc);*/
  81.         
  82.     if (rc == 0) {
  83.         skipThis = 0;
  84.         errSetCallback(errorFunction);
  85.         for (i = 0; i < matches.count; i++) {
  86.         if (rpmEnsureOlder(db, name, version, release,
  87.                    matches.recs[i].recOffset)) {
  88.             /* already have a newer version installed */
  89.             /*printf("Already have newer version\n");*/
  90.             skipThis = 1;
  91.             break;
  92.         }
  93.         }
  94.         errSetCallback(NULL);
  95.         if (! skipThis) {
  96.         /* no newer version installed */
  97.         /*printf("No newer version installed\n");*/
  98.         skipThis = 0;
  99.         }
  100.     } else {
  101.         skipThis = 1;
  102.         /*printf("Not installed\n");*/
  103.     }
  104.     
  105.     if (skipThis) {
  106.         /*printf("DO NOT INSTALL\n");*/
  107.     } else {
  108.         /*printf("UPGRADE\n");*/
  109.         resultArray[pkgNum] = 1;
  110.  
  111.         getEntry(h, RPMTAG_FILENAMES, NULL,
  112.              (void **) &availFiles, &availFileCount);
  113.  
  114.         for (i = 0; i < matches.count; i++) {
  115.         /* Compare the file lists */
  116.         installedHeader =
  117.             rpmdbGetRecord(db, matches.recs[i].recOffset);
  118.         getEntry(installedHeader, RPMTAG_FILENAMES, NULL,
  119.              (void **) &installedFiles, &installedFileCount);
  120.  
  121.         compareFileList(availFileCount, availFiles,
  122.                 installedFileCount, installedFiles, ht);
  123.  
  124.         free(installedFiles);
  125.         freeHeader(installedHeader);
  126.         }
  127.  
  128.         free(availFiles);
  129.     }
  130.     if (rc == 0) {
  131.         freeDBIndexRecord(matches);
  132.     }
  133.  
  134.     /*printf("\n\n");*/
  135.  
  136.     freeHeader(h);
  137.     pkgNum++;
  138.     }
  139.  
  140.     *availPkgs = pkgNum;
  141.     return 0;
  142. }
  143.  
  144. int removeMovedFilesAlreadyHandled(int ugdbfd, struct hash_table *ht,
  145.                    int *resultArray)
  146. {
  147.     int pkgNum;
  148.     char *name;
  149.     int i;
  150.     Header h;
  151.     char **availFiles;
  152.     int availFileCount;
  153.     char *file;
  154.  
  155.     lseek(ugdbfd, 0, SEEK_SET);
  156.  
  157.     pkgNum = 0;
  158.     while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
  159.     if (resultArray[pkgNum]) {
  160.         name = NULL;
  161.         getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
  162.  
  163.         getEntry(h, RPMTAG_FILENAMES, NULL,
  164.              (void **) &availFiles, &availFileCount);
  165.  
  166.         for (i = 0; i < availFileCount; i++) {
  167.         if ((file = in_table(ht, availFiles[i]))) {
  168.             *file = '\0';
  169.             printf("File already in %s: %s\n", name, availFiles[i]);
  170.             resultArray[pkgNum] = 1;
  171.             break;
  172.         }
  173.         }
  174.         
  175.         free(availFiles);
  176.     }
  177.  
  178.     pkgNum++;
  179.     freeHeader(h);
  180.     }
  181.  
  182.     return 0;
  183. }
  184.  
  185. int findPackagesWithRelocatedFiles(int ugdbfd, struct hash_table *ht,
  186.                    int *resultArray)
  187. {
  188.     int pkgNum;
  189.     char *name;
  190.     int i;
  191.     Header h;
  192.     char **availFiles;
  193.     int availFileCount;
  194.     char *file;
  195.  
  196.     lseek(ugdbfd, 0, SEEK_SET);
  197.  
  198.     pkgNum = 0;
  199.     while ((h = readHeader(ugdbfd, HEADER_MAGIC))) {
  200.     if (! resultArray[pkgNum]) {
  201.         name = NULL;
  202.         getEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL);
  203.  
  204.         getEntry(h, RPMTAG_FILENAMES, NULL,
  205.              (void **) &availFiles, &availFileCount);
  206.  
  207.         for (i = 0; i < availFileCount; i++) {
  208.         if ((file = in_table(ht, availFiles[i]))) {
  209.             *file = '\0';
  210.             printf("Found file in %s: %s\n", name, availFiles[i]);
  211.             resultArray[pkgNum] = 1;
  212.             break;
  213.         }
  214.         }
  215.         
  216.         free(availFiles);
  217.     }
  218.  
  219.     pkgNum++;
  220.     freeHeader(h);
  221.     }
  222.  
  223.     return 0;
  224. }
  225.  
  226. int main(int argc, char **argv)
  227. {
  228.     int fd;
  229.     rpmdb db;
  230.     struct hash_table *hashTable;
  231.     int installThisPackage[MAXPKGS];
  232.     int availPkgs, i;
  233.  
  234.     if ((fd = open(argv[1], O_RDONLY)) < 0) {
  235.     perror("open");
  236.     exit(1);
  237.     }
  238.  
  239.     if (rpmdbOpen("/", &db, O_RDONLY, 0644)) {
  240.     fprintf(stderr, "error: cannot open /var/lib/rpm/packages.rpm\n");
  241.     exit(1);
  242.     }
  243.  
  244.     for(i = 0; i < MAXPKGS; i++) {
  245.     installThisPackage[i] = 0;
  246.     }
  247.  
  248.     hashTable = new_table(1103);
  249.  
  250.     findUpgradePackages(db, fd, hashTable, installThisPackage, &availPkgs);
  251.     rpmdbClose(db);
  252.     hash_stats(hashTable);
  253.     removeMovedFilesAlreadyHandled(fd, hashTable, installThisPackage);
  254.     findPackagesWithRelocatedFiles(fd, hashTable, installThisPackage);
  255.  
  256.     close(fd);
  257.  
  258.     return 0;
  259. }
  260.