Initial revision
authorewt <devnull@localhost>
Mon, 16 Sep 1996 22:28:47 +0000 (22:28 +0000)
committerewt <devnull@localhost>
Mon, 16 Sep 1996 22:28:47 +0000 (22:28 +0000)
CVS patchset: 1020
CVS date: 1996/09/16 22:28:47

lib/rebuilddb.c [new file with mode: 0644]
lib/rpmdb.h [new file with mode: 0644]

diff --git a/lib/rebuilddb.c b/lib/rebuilddb.c
new file mode 100644 (file)
index 0000000..5253a4a
--- /dev/null
@@ -0,0 +1,92 @@
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>  /* for mkdir(2) !?! */
+#include <unistd.h>
+
+#include "messages.h"
+#include "rpmdb.h"
+#include "rpmerr.h"
+#include "rpmlib.h"
+
+int rpmdbRebuild(char * rootdir) {
+    rpmdb olddb, newdb;
+    char * dbpath, * newdbpath;
+    unsigned int recnum; 
+    Header h;
+    int failed = 0;
+
+    message(MESS_DEBUG, "rebuilding database in rootdir %s\n", rootdir);
+
+    dbpath = getVar(RPMVAR_DBPATH);
+    if (!dbpath) {
+       message(MESS_DEBUG, "no dbpath has been set");
+       return 1;
+    }
+
+    newdbpath = alloca(strlen(dbpath) + 50 + strlen(rootdir));
+    sprintf(newdbpath, "%s/%s/rebuilddb.%d", rootdir, dbpath, getpid());
+
+    if (!access(newdbpath, F_OK)) {
+       error(RPMERR_MKDIR, "temporary database %s already exists",
+             newdbpath);
+    }
+
+    message(MESS_DEBUG, "creating directory: %s\n", newdbpath);
+    if (mkdir(newdbpath, 0755)) {
+       error(RPMERR_MKDIR, "error creating directory %s: %s",
+             newdbpath, strerror(errno));
+    }
+
+    sprintf(newdbpath, "%s/rebuilddb.%d", dbpath, getpid());
+
+    message(MESS_DEBUG, "opening old database\n");
+    if (openDatabase(rootdir, dbpath, &olddb, O_RDONLY, 0644, 0)) {
+       return 1;
+    }
+
+    message(MESS_DEBUG, "opening new database\n");
+    if (openDatabase(rootdir, newdbpath, &newdb, O_RDWR | O_CREAT, 0644, 0)) {
+       return 1;
+    }
+
+    recnum = rpmdbFirstRecNum(olddb);
+    while (recnum) {
+       if (!(h = rpmdbGetRecord(olddb, recnum))) {
+           error(RPMERR_INTERNAL, "cannot read database record at %d", recnum);
+           failed = 1;
+           break;
+       }
+       if (rpmdbAdd(newdb, h)) {
+           error(RPMERR_INTERNAL, "cannot add record originally at %d", 
+                 recnum);
+           failed = 1;
+           break;
+       }
+       recnum = rpmdbNextRecNum(olddb, recnum);
+    }
+
+    rpmdbClose(olddb);
+    rpmdbClose(newdb);
+
+    if (failed) {
+       message(MESS_NORMAL, "failed to rebuild database; original database "
+               "remains in place\n");
+
+       rpmdbRemoveDatabase(rootdir, newdbpath);
+       return 1;
+    } else {
+       if (rpmdbMoveDatabase(rootdir, newdbpath, dbpath)) {
+           message(MESS_ERROR, "failed to replace old database with new "
+                       "database!\n");
+           message(MESS_ERROR, "replaces files in %s with files from %s "
+                       "to recover", dbpath, newdbpath);
+           return 1;
+       }
+       rmdir(newdbpath);
+    }
+
+
+    return 0;
+}
diff --git a/lib/rpmdb.h b/lib/rpmdb.h
new file mode 100644 (file)
index 0000000..396717b
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef H_RPMDB
+#define H_RPMDB
+
+#include "rpmlib.h"
+
+/* for RPM's internal use only */
+
+int openDatabase(char * prefix, char * dbpath, rpmdb *rpmdbp, int mode, 
+                int perms, int justcheck);
+int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant);
+int rpmdbAdd(rpmdb db, Header dbentry);
+int rpmdbUpdateRecord(rpmdb db, int secOffset, Header secHeader);
+void rpmdbRemoveDatabase(char * rootdir, char * dbpath);
+int rpmdbMoveDatabase(char * rootdir, char * olddbpath, char * newdbpath);
+
+#endif