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