home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / verify.c < prev    next >
C/C++ Source or Header  |  1997-09-17  |  6KB  |  253 lines

  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6.  
  7. #include "lib/messages.h"
  8. #include "install.h"
  9. #include "intl.h"
  10. #include "query.h"
  11. #include "rpmlib.h"
  12. #include "url.h"
  13. #include "verify.h"
  14.  
  15. static void verifyHeader(char * prefix, Header h, int verifyFlags);
  16. static void verifyMatches(char * prefix, rpmdb db, dbiIndexSet matches,
  17.               int verifyFlags);
  18. static void verifyDependencies(rpmdb db, Header h);
  19.  
  20. static void verifyHeader(char * prefix, Header h, int verifyFlags) {
  21.     char ** fileList;
  22.     int count, type;
  23.     int verifyResult;
  24.     int i;
  25.     char * size, * md5, * link, * mtime, * mode;
  26.     char * group, * user, * rdev;
  27.     int_32 * fileFlagsList;
  28.     int omitMask = 0;
  29.  
  30.     if (!(verifyFlags & VERIFY_MD5)) omitMask = RPMVERIFY_MD5;
  31.  
  32.     headerGetEntry(h, RPMTAG_FILEFLAGS, NULL, (void **) &fileFlagsList, NULL);
  33.  
  34.     if (headerGetEntry(h, RPMTAG_FILENAMES, &type, (void **) &fileList, 
  35.             &count)) {
  36.     for (i = 0; i < count; i++) {
  37.         if (rpmVerifyFile(prefix, h, i, &verifyResult, omitMask))
  38.         printf("missing    %s\n", fileList[i]);
  39.         else {
  40.         size = md5 = link = mtime = mode = ".";
  41.         user = group = rdev = ".";
  42.  
  43.         if (!verifyResult) continue;
  44.         
  45.         if (verifyResult & RPMVERIFY_MD5)
  46.             md5 = "5";
  47.         if (verifyResult & RPMVERIFY_FILESIZE)
  48.             size = "S";
  49.         if (verifyResult & RPMVERIFY_LINKTO)
  50.             link = "L";
  51.         if (verifyResult & RPMVERIFY_MTIME)
  52.             mtime = "T";
  53.         if (verifyResult & RPMVERIFY_RDEV)
  54.             rdev = "D";
  55.         if (verifyResult & RPMVERIFY_USER)
  56.             user = "U";
  57.         if (verifyResult & RPMVERIFY_GROUP)
  58.             group = "G";
  59.         if (verifyResult & RPMVERIFY_MODE)
  60.             mode = "M";
  61.  
  62.         printf("%s%s%s%s%s%s%s%s %c %s\n",
  63.                size, mode, md5, rdev, link, user, group, mtime, 
  64.                fileFlagsList[i] & RPMFILE_CONFIG ? 'c' : ' ', 
  65.                fileList[i]);
  66.         }
  67.     }
  68.     
  69.     free(fileList);
  70.     }
  71. }
  72.  
  73. static void verifyDependencies(rpmdb db, Header h) {
  74.     rpmDependencies rpmdep;
  75.     struct rpmDependencyConflict * conflicts;
  76.     int numConflicts;
  77.     char * name, * version, * release;
  78.     int type, count, i;
  79.  
  80.     rpmdep = rpmdepDependencies(db);
  81.     rpmdepAddPackage(rpmdep, h, NULL);
  82.  
  83.     rpmdepCheck(rpmdep, &conflicts, &numConflicts);
  84.     rpmdepDone(rpmdep);
  85.  
  86.     if (numConflicts) {
  87.     headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
  88.     headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
  89.     headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
  90.     printf(_("Unsatisfied dependencies for %s-%s-%s: "), name, version, 
  91.         release);
  92.     for (i = 0; i < numConflicts; i++) {
  93.         if (i) printf(", ");
  94.         printf("%s", conflicts[i].needsName);
  95.         if (conflicts[i].needsFlags) {
  96.         printDepFlags(stdout, conflicts[i].needsVersion, 
  97.                   conflicts[i].needsFlags);
  98.         }
  99.     }
  100.     printf("\n");
  101.     rpmdepFreeConflicts(conflicts, numConflicts);
  102.     }
  103. }
  104.  
  105. static void verifyPackage(char * root, rpmdb db, Header h, int verifyFlags) {
  106.     if (verifyFlags & VERIFY_DEPS)
  107.     verifyDependencies(db, h);
  108.     if (verifyFlags & VERIFY_FILES)
  109.     verifyHeader(root, h, verifyFlags);
  110.     if (verifyFlags & VERIFY_SCRIPT) {
  111.     rpmVerifyScript(root, h, 1);
  112.     }
  113. }
  114.  
  115. static void verifyMatches(char * prefix, rpmdb db, dbiIndexSet matches,
  116.               int verifyFlags) {
  117.     int i;
  118.     Header h;
  119.  
  120.     for (i = 0; i < matches.count; i++) {
  121.     if (matches.recs[i].recOffset) {
  122.         rpmMessage(RPMMESS_DEBUG, "verifying record number %d\n",
  123.             matches.recs[i].recOffset);
  124.         
  125.         h = rpmdbGetRecord(db, matches.recs[i].recOffset);
  126.         if (!h) {
  127.         fprintf(stderr, _("error: could not read database record\n"));
  128.         } else {
  129.         verifyPackage(prefix, db, h, verifyFlags);
  130.         headerFree(h);
  131.         }
  132.     }
  133.     }
  134. }
  135.  
  136. void doVerify(char * prefix, enum verifysources source, char ** argv,
  137.           int verifyFlags) {
  138.     Header h;
  139.     int offset;
  140.     int fd;
  141.     int rc;
  142.     int isSource;
  143.     rpmdb db;
  144.     dbiIndexSet matches;
  145.     struct urlContext context;
  146.     char * arg;
  147.     int isUrl;
  148.     char path[255];
  149.  
  150.     if (source == VERIFY_RPM && !(verifyFlags & VERIFY_DEPS)) {
  151.     db = NULL;
  152.     } else {
  153.     if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
  154.         exit(1);
  155.     }
  156.     }
  157.  
  158.     if (source == VERIFY_EVERY) {
  159.     offset = rpmdbFirstRecNum(db);
  160.     while (offset) {
  161.         h = rpmdbGetRecord(db, offset);
  162.         if (!h) {
  163.         fprintf(stderr, _("could not read database record!\n"));
  164.         exit(1);
  165.         }
  166.         verifyPackage(prefix, db, h, verifyFlags);
  167.         headerFree(h);
  168.         offset = rpmdbNextRecNum(db, offset);
  169.     }
  170.     } else {
  171.     while (*argv) {
  172.         arg = *argv++;
  173.  
  174.         switch (source) {
  175.           case VERIFY_RPM:
  176.         if (urlIsURL(arg)) {
  177.             isUrl = 1;
  178.             if ((fd = urlGetFd(arg, &context)) < 0) {
  179.             fprintf(stderr, _("open of %s failed: %s\n"), arg, 
  180.                 ftpStrerror(fd));
  181.             }
  182.         } else if (!strcmp(arg, "-")) {
  183.             fd = 0;
  184.         } else {
  185.             if ((fd = open(arg, O_RDONLY)) < 0) {
  186.             fprintf(stderr, _("open of %s failed: %s\n"), arg, 
  187.                 strerror(errno));
  188.             }
  189.         }
  190.  
  191.         if (fd >= 0) {
  192.             rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
  193.             close(fd);
  194.             switch (rc) {
  195.             case 0:
  196.                 verifyPackage(prefix, db, h, verifyFlags);
  197.                 headerFree(h);
  198.                 break;
  199.             case 1:
  200.                 fprintf(stderr, "%s is not an RPM\n", arg);
  201.             }
  202.         }
  203.             
  204.         break;
  205.  
  206.           case VERIFY_GRP:
  207.         if (rpmdbFindByGroup(db, arg, &matches)) {
  208.             fprintf(stderr, 
  209.                 _("group %s does not contain any packages\n"), 
  210.                 arg);
  211.         } else {
  212.             verifyMatches(prefix, db, matches, verifyFlags);
  213.             dbiFreeIndexRecord(matches);
  214.         }
  215.         break;
  216.  
  217.           case VERIFY_PATH:
  218.         if (*arg != '/') {
  219.             if (realpath(arg, path) != NULL)
  220.             arg = path;
  221.         }
  222.         if (rpmdbFindByFile(db, arg, &matches)) {
  223.             fprintf(stderr, _("file %s is not owned by any package\n"), 
  224.                 arg);
  225.         } else {
  226.             verifyMatches(prefix, db, matches, verifyFlags);
  227.             dbiFreeIndexRecord(matches);
  228.         }
  229.         break;
  230.  
  231.           case VERIFY_PACKAGE:
  232.         rc = rpmdbFindByLabel(db, arg, &matches);
  233.         if (rc == 1) 
  234.             fprintf(stderr, _("package %s is not installed\n"), arg);
  235.         else if (rc == 2) {
  236.             fprintf(stderr, _("error looking for package %s\n"), arg);
  237.         } else {
  238.             verifyMatches(prefix, db, matches, verifyFlags);
  239.             dbiFreeIndexRecord(matches);
  240.         }
  241.         break;
  242.  
  243.         case VERIFY_EVERY:
  244.             ; /* nop */
  245.         }
  246.     }
  247.     }
  248.    
  249.     if (source != VERIFY_RPM) {
  250.     rpmdbClose(db);
  251.     }
  252. }
  253.