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

  1. #include "config.h"
  2.  
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <sys/stat.h>    /* for mkdir(2) !?! */
  8. #include <unistd.h>
  9.  
  10. #if HAVE_ALLOCA_H
  11. #include <alloca.h>
  12. #endif
  13.  
  14. #include "messages.h"
  15. #include "rpmdb.h"
  16. #include "rpmlib.h"
  17.  
  18. int rpmdbRebuild(char * rootdir) {
  19.     rpmdb olddb, newdb;
  20.     char * dbpath, * newdbpath;
  21.     int recnum; 
  22.     Header h;
  23.     int failed = 0;
  24.  
  25.     rpmMessage(RPMMESS_DEBUG, "rebuilding database in rootdir %s\n", rootdir);
  26.  
  27.     dbpath = rpmGetVar(RPMVAR_DBPATH);
  28.     if (!dbpath) {
  29.     rpmMessage(RPMMESS_DEBUG, "no dbpath has been set");
  30.     return 1;
  31.     }
  32.  
  33.     newdbpath = alloca(strlen(dbpath) + 50 + strlen(rootdir));
  34.     sprintf(newdbpath, "%s/%s/rebuilddb.%d", rootdir, dbpath, (int) getpid());
  35.  
  36.     if (!access(newdbpath, F_OK)) {
  37.     rpmError(RPMERR_MKDIR, "temporary database %s already exists",
  38.           newdbpath);
  39.     }
  40.  
  41.     rpmMessage(RPMMESS_DEBUG, "creating directory: %s\n", newdbpath);
  42.     if (mkdir(newdbpath, 0755)) {
  43.     rpmError(RPMERR_MKDIR, "error creating directory %s: %s",
  44.           newdbpath, strerror(errno));
  45.     }
  46.  
  47.     sprintf(newdbpath, "%s/rebuilddb.%d", dbpath, (int) getpid());
  48.  
  49.     rpmMessage(RPMMESS_DEBUG, "opening old database\n");
  50.     if (openDatabase(rootdir, dbpath, &olddb, O_RDONLY, 0644, 0)) {
  51.     return 1;
  52.     }
  53.  
  54.     rpmMessage(RPMMESS_DEBUG, "opening new database\n");
  55.     if (openDatabase(rootdir, newdbpath, &newdb, O_RDWR | O_CREAT, 0644, 0)) {
  56.     return 1;
  57.     }
  58.  
  59.     recnum = rpmdbFirstRecNum(olddb);
  60.     while (recnum > 0) {
  61.     if (!(h = rpmdbGetRecord(olddb, recnum))) {
  62.         rpmError(RPMERR_INTERNAL, "cannot read database record at %d", recnum);
  63.         failed = 1;
  64.         break;
  65.     }
  66.  
  67.     /* let's sanity check this record a bit, otherwise just skip it */
  68.     if (headerIsEntry(h, RPMTAG_NAME) &&
  69.         headerIsEntry(h, RPMTAG_VERSION) &&
  70.         headerIsEntry(h, RPMTAG_RELEASE) &&
  71.         headerIsEntry(h, RPMTAG_RELEASE) &&
  72.         headerIsEntry(h, RPMTAG_BUILDTIME)) {
  73.         if (rpmdbAdd(newdb, h)) {
  74.         rpmError(RPMERR_INTERNAL, "cannot add record originally at %d", 
  75.               recnum);
  76.         failed = 1;
  77.         break;
  78.         }
  79.     } else {
  80.         rpmError(RPMERR_INTERNAL, "record number %d in database is bad "
  81.             "-- skipping it", recnum);
  82.     }
  83.     recnum = rpmdbNextRecNum(olddb, recnum);
  84.     }
  85.  
  86.     rpmdbClose(olddb);
  87.     rpmdbClose(newdb);
  88.  
  89.     if (failed) {
  90.     rpmMessage(RPMMESS_NORMAL, "failed to rebuild database; original database "
  91.         "remains in place\n");
  92.  
  93.     rpmdbRemoveDatabase(rootdir, newdbpath);
  94.     return 1;
  95.     } else {
  96.     if (rpmdbMoveDatabase(rootdir, newdbpath, dbpath)) {
  97.         rpmMessage(RPMMESS_ERROR, "failed to replace old database with new "
  98.             "database!\n");
  99.         rpmMessage(RPMMESS_ERROR, "replaces files in %s with files from %s "
  100.             "to recover", dbpath, newdbpath);
  101.         return 1;
  102.     }
  103.     rmdir(newdbpath);
  104.     }
  105.  
  106.  
  107.     return 0;
  108. }
  109.