- popt: return POPT_ERROR_ERRNO on config open/read/close failure.
- fix: popt exec doesn't add '--', --target et al no longer need '='.
- fix: popt consume-next-arg "!#:+" w/o side effect (#41956).
+ - fix: for busted db1, attempt chain reconnection to following record.
4.0 -> 4.0.[12]
- add doxygen and lclint annotations most everywhere.
if (!gotDefaults) {
rc = uname(&un);
- if (rc) return;
+ if (rc < 0) return;
#if !defined(__linux__)
#ifdef SNI
# XXX linked binaries like /bin/rpm.
%ifnarch ia64
Requires: glibc >= 2.1.92
-# XXX needed to avoid libdb.so.2 satisfied by compat/libc5 provides.
-Requires: db1 = 1.85
%endif
%endif
%build
%ifos linux
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} --sysconfdir=/etc --localstatedir=/var --infodir='${prefix}%{__share}/info' --mandir='${prefix}%{__share}/man' # --enable-db1
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} --sysconfdir=/etc --localstatedir=/var --infodir='${prefix}%{__share}/info' --mandir='${prefix}%{__share}/man'
%else
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} # --enable-db1
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix}
%endif
make
install -m 755 scripts/rpm.log ${RPM_BUILD_ROOT}/etc/logrotate.d/rpm
mkdir -p $RPM_BUILD_ROOT/etc/rpm
-#cat << E_O_F > $RPM_BUILD_ROOT/etc/rpm/macros.db1
-#%%_dbapi 1
-#E_O_F
+cat << E_O_F > $RPM_BUILD_ROOT/etc/rpm/macros.db1
+%%_dbapi 1
+E_O_F
+
+mkdir -p $RPM_BUILD_ROOT/var/lib/rpm
+for dbi in \
+ Basenames Conflictname Dirnames Group Installtid Name Providename \
+ Provideversion Removetid Requirename Requireversion Triggername
+do
+ touch $RPM_BUILD_ROOT/var/lib/rpm/dbi
+done
%endif
%pre
%ifos linux
-if [ -f /var/lib/rpm/packages.rpm ]; then
+if [ -f /var/lib/rpm/Packages -a -f /var/lib/rpm/packages.rpm ]; then
echo "
-
-This version of rpm does not have db1 support, install rpm-4.0.2 and
-do rpm --rebuilddb to convert your database from db1 to db3 format.
-
+You have both
+ /var/lib/rpm/packages.rpm db1 format installed package headers
+ /var/lib/rpm/Packages db3 format installed package headers
+Please remove (or at least rename) one of those files, and re-install.
"
exit 1
fi
-/usr/sbin/groupadd -g 37 rpm
-/usr/sbin/useradd -d /var/lib/rpm -u 37 -g 37 rpm
+/usr/sbin/groupadd -g 37 @RPMGROUP@ > /dev/null 2>&1
+/usr/sbin/useradd -d /var/lib/rpm -u 37 -g 37 @RPMUSER@ > /dev/null 2>&1
%endif
exit 0
%post
%ifos linux
/sbin/ldconfig
+if [ -f /var/lib/rpm/packages.rpm ]; then
+ : # do nothing
+elif [ -f /var/lib/rpm/Packages ]; then
+ # undo db1 configuration
+ rm -f /etc/rpm/macros.db1
+else
+ # initialize db3 database
+ rm -f /etc/rpm/macros.db1
+ /bin/rpm --initdb
+fi
+/bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]* /var/lib/rpm/*.rpm
%endif
-# initialize db3 database
-/bin/rpm --initdb
-/bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]*
+exit 0
%ifos linux
%postun
%config(missingok) /etc/cron.daily/rpm
%config(missingok) /etc/logrotate.d/rpm
%dir /etc/rpm
-#%config(missingok) /etc/rpm/macros.db1
+%config(missingok) /etc/rpm/macros.db1
+%attr(0755, @RPMUSER@, @RPMGROUP@) %dir /var/lib/rpm
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Basenames
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Conflictname
+#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/__db.001
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Dirnames
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Group
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Installtid
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Name
+#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Packages
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Providename
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Provideversion
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Removetid
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requirename
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requireversion
+%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Triggername
%endif
%attr(0755, @RPMUSER@, @RPMGROUP@) %{__prefix}/bin/rpm2cpio
%attr(0644, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/rpmpopt*
%attr(0644, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/rpmrc
-%attr(0755, @RPMUSER@, @RPMGROUP@) %dir /var/lib/rpm
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Basenames
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Conflictname
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/__db.001
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Dirnames
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Group
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Installtid
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Name
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Packages
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Providename
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Provideversion
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Removetid
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requirename
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requireversion
-#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Triggername
-
%ifarch i386 i486 i586 i686 athlon
%attr(-, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/i[3456]86*
%endif
librpmdb_la_SOURCES = $(DBLIBSRCS) dbconfig.c fprint.c rpmhash.c rpmdb.c
librpmdb_la_LDFLAGS = @libdb3@
librpmdb_la_LIBADD = $(DBLIBOBJS) $(DB3LOBJS)
-librpmdb_la_DEPENDENCIES = $(DBLIBOBJS) createlinks
+librpmdb_la_DEPENDENCIES = $(DBLIBOBJS) .created
# XXX Add internal libtool dependence
install-data-local:
falloc.lo: falloc.c $(top_srcdir)/system.h $(top_srcdir)/rpmio/rpmio.h falloc.h
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
-.PHONY: createlinks
-createlinks:
+.created:
for lo in $(DB3LOBJS); do \
[ -f $$lo ] || $(LN_S) $(top_builddir)/$(WITH_DB_SUBDIR)/$$lo $$lo ; \
done
+ touch $@
clean-local:
rm -f $(DB3LOBJS)
.PHONY: lclint
lclint:
lclint $(DEFS) $(INCLUDES) $(librpmdb_la_SOURCES)
+
+tfalloc: librpmdb.la tfalloc.o
+ $(LINK) -all-static $@.o $< $(mylibpaths) $(mylibs) $(LIBS)
return rc;
}
-/*@null@*/ static void * doGetRecord(FD_t pkgs, unsigned int offset)
+/*@null@*/ static void * doGetRecord(dbiIndex dbi, unsigned int offset)
{
+ FD_t pkgs = dbi->dbi_db;
void * uh = NULL;
Header h = NULL;
const char ** fileNames;
int fileCount = 0;
+ int lasto = 0;
int i;
+retry:
if (offset >= fadGetFileSize(pkgs))
goto exit;
h = headerRead(pkgs, HEADER_MAGIC_NO);
/* let's sanity check this record a bit, otherwise just skip it */
- if (!( headerIsEntry(h, RPMTAG_NAME) &&
+ if (h != NULL &&
+ !( headerIsEntry(h, RPMTAG_NAME) &&
headerIsEntry(h, RPMTAG_VERSION) &&
headerIsEntry(h, RPMTAG_RELEASE) &&
headerIsEntry(h, RPMTAG_BUILDTIME)))
h = headerFree(h);
}
- if (h == NULL)
+ if (h == NULL) {
+ /* XXX HACK: try to reconnect broken chain. */
+ if (lasto == 0) {
+ rpmMessage(RPMMESS_WARNING,
+ _("Broken package chain at offset %d(0x%08x), attempting to reconnect ...\n"),
+ (int) offset, offset);
+ lasto = (offset ? offset : -1);
+ offset = fadNextOffset(pkgs, offset);
+ if (offset > 0)
+ goto retry;
+ }
goto exit;
+ }
+
+ if (lasto) {
+ rpmMessage(RPMMESS_WARNING,
+ _("Reconnecting broken chain at offset %d(0x%08x).\n"),
+ (int) offset, offset);
+ dbi->dbi_lastoffset = offset;
+ }
/* Retrofit "Provide: name = EVR" for binary packages. */
providePackageNVR(h);
* list.
*/
if (!headerGetEntryMinMemory(h, RPMTAG_OLDFILENAMES, NULL,
- (const void **) &fileNames, &fileCount)) goto exit;
+ (const void **) &fileNames, &fileCount))
+ goto exit;
for (i = 0; i < fileCount; i++)
if (*fileNames[i] != '/') break;
memcpy(data.data, &offset, sizeof(offset));
data.size = sizeof(offset);
} else { /* XXX simulated retrieval */
- data.data = doGetRecord(pkgs, offset);
+ data.data = doGetRecord(dbi, offset);
data.size = 0; /* XXX WRONG */
- if (data.data == NULL) {
-if (keyp) *keyp = key.data;
-if (keylen) *keylen = key.size;
- rc = EFAULT;
- }
}
}
#ifdef DYING
#include "system.h"
#include <rpmio_internal.h>
+#include <rpmmessages.h>
#include <rpmerr.h>
#include "falloc.h"
#include "debug.h"
}
}
+static int insane = 0;
+
+static int fadSanity(FD_t fd, int offset, struct faHeader * fh)
+{
+ int rc = 0;
+
+ if (fh->size <= 0 || fh->size > 0x00200000 || (fh->size & 0x3f) != 0)
+ rc |= 0x1;
+
+ if (fh->freeNext &&
+ !( fh->freeNext > sizeof(struct faFileHeader) &&
+ fh->freeNext < fadGetFileSize(fd) &&
+ (fh->freeNext & 0x3f) == sizeof(struct faFileHeader)) )
+ rc |= 0x2;
+
+ if (fh->freePrev &&
+ !( fh->freePrev > sizeof(struct faFileHeader) &&
+ fh->freePrev < fadGetFileSize(fd) &&
+ (fh->freePrev & 0x3f) == sizeof(struct faFileHeader)) )
+ rc |= 0x4;
+
+ if (fh->isFree & ~1)
+ rc |= 0x8;
+
+ if (!insane && rc) {
+ rpmMessage(RPMMESS_DEBUG,
+ "offset %d(0x%08x) rc %d: size 0x%08x next %d(0x%08x) prev %d(0x%08x) isFree 0x%08x\n",
+ offset, (unsigned) offset, rc,
+ (unsigned) fh->size,
+ (int) fh->freeNext, fh->freeNext,
+ (int) fh->freePrev, fh->freePrev,
+ (unsigned) fh->isFree);
+ }
+ return rc;
+}
+
int fadFirstOffset(FD_t fd)
{
return fadNextOffset(fd, 0);
{
struct faHeader header;
int offset;
+ int rc;
offset = (lastOffset)
? (lastOffset - sizeof(header))
if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
return 0;
- if (!lastOffset && !header.isFree)
+ if (!lastOffset && header.isFree == 0)
return (offset + sizeof(header));
+ /*
+ * XXX Try to reconnect at next record found. This isn't perfect
+ * XXX but handles many common db1 corruption problems.
+ */
+ rc = fadSanity(fd, offset, &header);
+ if (rc) {
+ struct faHeader myheader;
+ int o = offset + sizeof(header);
+
+ memset(&myheader, 0, sizeof(myheader));
+ insane = 1;
+ for ( o = offset + 0x40;
+ o < fadGetFileSize(fd);
+ o += 0x40)
+ {
+ rc = Pread(fd, &myheader, sizeof(myheader), o);
+ if (rc != sizeof(header))
+ return 0;
+ rc = fadSanity(fd, o, &myheader);
+ if (rc == 0)
+ break;
+ }
+ insane = 0;
+ if (o >= fadGetFileSize(fd))
+ return 0;
+ return (o + sizeof(header));
+ }
+
do {
offset += header.size;
if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
return 0;
- if (!header.isFree) break;
- } while (offset < fadGetFileSize(fd) && header.isFree);
+ if (header.isFree == 0) break;
+ } while (offset < fadGetFileSize(fd) && header.isFree == 1);
if (offset < fadGetFileSize(fd)) {
/* Sanity check this to make sure we're not going in loops */
--- /dev/null
+#include "system.h"
+#include <rpmlib.h>
+#include "rpmio_internal.h"
+#include "falloc.h"
+#include "debug.h"
+
+#define RPMDBFN "/var/lib/rpm/packages.rpm"
+static const char * rpmdbfn = RPMDBFN;
+
+int main(int argc, const char ** argv)
+{
+ int lasto = 0;
+ FD_t fd;
+
+
+ fd = fadOpen(rpmdbfn, O_RDONLY, 0644);
+ if (fd == NULL) {
+ fprintf(stderr, "fadOpen(%s) failed\n", rpmdbfn);
+ exit(1);
+ }
+fprintf(stderr, "%s: size %d(0x%08x)\n", rpmdbfn, fadGetFileSize(fd), (unsigned) fadGetFileSize(fd));
+
+ while ((lasto = fadNextOffset(fd, lasto)) > 0) {
+fprintf(stderr, "%10d\n", lasto);
+ }
+
+ (void) Fclose(fd);
+
+ return 0;
+}