summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorjbj <devnull@localhost>1997-01-01 01:30:08 +0000
committerjbj <devnull@localhost>1997-01-01 01:30:08 +0000
commit7dbc73fec627ec4760f8b031df64ee659c6e6a86 (patch)
treea9bc8f0bc62919f08b6c9fb801a37b37ba31b9cf /python
parent931f010d2dcf882b5217be87485758ad82e57164 (diff)
downloadrpm-7dbc73fec627ec4760f8b031df64ee659c6e6a86.tar.gz
rpm-7dbc73fec627ec4760f8b031df64ee659c6e6a86.tar.bz2
rpm-7dbc73fec627ec4760f8b031df64ee659c6e6a86.zip
Merge rpm-4.0.4 changes.
CVS patchset: 1256 CVS date: 1997/01/01 01:30:08
Diffstat (limited to 'python')
-rw-r--r--python/Makefile.am47
-rw-r--r--python/Makefile.in509
-rw-r--r--python/db-py.c499
-rw-r--r--python/db-py.h29
-rw-r--r--python/header-py.c1116
-rw-r--r--python/header-py.h31
-rw-r--r--python/rpmmodule.c1170
7 files changed, 3401 insertions, 0 deletions
diff --git a/python/Makefile.am b/python/Makefile.am
new file mode 100644
index 000000000..45c82d32e
--- /dev/null
+++ b/python/Makefile.am
@@ -0,0 +1,47 @@
+# Makefile for rpm library.
+
+AUTOMAKE_OPTIONS = 1.4 foreign
+
+PYVER= @WITH_PYTHON_VERSION@
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/rpmdb \
+ -I$(top_srcdir)/rpmio \
+ -I$(top_srcdir)/beecrypt \
+ -I$(top_srcdir)/popt \
+ -I/usr/include/python${PYVER} \
+ @INCPATH@
+
+EXTRA_DIST = db-py.h hash.h header-py.h upgrade.h
+
+mylibs= \
+ $(top_builddir)/lib/librpm.la \
+ $(top_builddir)/rpmdb/librpmdb.la \
+ $(top_builddir)/rpmio/librpmio.la \
+ $(top_builddir)/popt/libpopt.la
+
+LDADD =
+
+pythondir = $(prefix)/lib/python${PYVER}/site-packages
+python_PROGRAMS = rpmmodule.so poptmodule.so
+
+rpmmodule_so_SOURCES =
+rpmmodule_so_LDFLAGS = $(mylibs) $(LIBS) -shared -Wl,-soname,rpmmodule.so
+
+poptmodule_so_SOURCES = poptmodule.c
+poptmodule_so_LDFLAGS = $(mylibs) $(LIBS) -shared -Wl,-soname,poptmodule.so
+
+noinst_LTLIBRARIES = librpmmodule.la
+librpmmodule_la_SOURCES = rpmmodule.c hash.c upgrade.c header-py.c db-py.c
+
+rpmmodule.so$(EXEEXT): $(librpmmodule_la_OBJECTS)
+ $(LINK) -o $@ $(librpmmodule_la_OBJECTS) $(rpmmodule_so_LDFLAGS)
+
+poptmodule.so$(EXEEXT): $(poptmodule_so_OBJECTS)
+ $(LINK) -o $@ $(poptmodule_so_OBJECTS) $(poptmodule_so_LDFLAGS)
+
+.PHONY: lclint
+lclint:
+ lclint $(DEFS) $(INCLUDES) $(librpmmodule_la_SOURCES)
diff --git a/python/Makefile.in b/python/Makefile.in
new file mode 100644
index 000000000..e7620161b
--- /dev/null
+++ b/python/Makefile.in
@@ -0,0 +1,509 @@
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for rpm library.
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+BUILD_RPMNLSTOOLS = @BUILD_RPMNLSTOOLS@
+BZIP2BIN = @BZIP2BIN@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
+DBLIBSRCS = @DBLIBSRCS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+FINDPROVIDES = @FINDPROVIDES@
+FINDREQUIRES = @FINDREQUIRES@
+FIXPERMS = @FIXPERMS@
+GENCAT = @GENCAT@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GZIPBIN = @GZIPBIN@
+HAVE_LIB = @HAVE_LIB@
+INCPATH = @INCPATH@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+LDFLAGS_STATIC = @LDFLAGS_STATIC@
+LIB = @LIB@
+LIBDIR = @LIBDIR@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMISC = @LIBMISC@
+LIBOBJS = @LIBOBJS@
+LIBRPMALIAS_FILENAME = @LIBRPMALIAS_FILENAME@
+LIBRPMRC_FILENAME = @LIBRPMRC_FILENAME@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIB = @LTLIB@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+MACROFILES = @MACROFILES@
+MKDIR = @MKDIR@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PGPBIN = @PGPBIN@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+ROOT_GROUP = @ROOT_GROUP@
+RPM = @RPM@
+RPMCANONARCH = @RPMCANONARCH@
+RPMCANONOS = @RPMCANONOS@
+RPMCANONVENDOR = @RPMCANONVENDOR@
+RPMCONFIGDIR = @RPMCONFIGDIR@
+RPMGID = @RPMGID@
+RPMGROUP = @RPMGROUP@
+RPMUID = @RPMUID@
+RPMUSER = @RPMUSER@
+STRIP = @STRIP@
+SYSCONFIGDIR = @SYSCONFIGDIR@
+U = @U@
+UNZIPBIN = @UNZIPBIN@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_APIDOCS = @WITH_APIDOCS@
+WITH_APIDOCS_TARGET = @WITH_APIDOCS_TARGET@
+WITH_BZIP2 = @WITH_BZIP2@
+WITH_DB_SUBDIR = @WITH_DB_SUBDIR@
+WITH_INTERNAL_DB = @WITH_INTERNAL_DB@
+WITH_PYTHON_SUBDIR = @WITH_PYTHON_SUBDIR@
+WITH_PYTHON_SUBPACKAGE = @WITH_PYTHON_SUBPACKAGE@
+WITH_PYTHON_VERSION = @WITH_PYTHON_VERSION@
+WITH_ZLIB_INCLUDE = @WITH_ZLIB_INCLUDE@
+WITH_ZLIB_LIB = @WITH_ZLIB_LIB@
+WITH_ZLIB_SUBDIR = @WITH_ZLIB_SUBDIR@
+__CAT = @__CAT@
+__CHGRP = @__CHGRP@
+__CHGRP_RHF = @__CHGRP_RHF@
+__CHMOD = @__CHMOD@
+__CHOWN = @__CHOWN@
+__CHOWN_RHF = @__CHOWN_RHF@
+__CP = @__CP@
+__CPIO = @__CPIO@
+__DOXYGEN = @__DOXYGEN@
+__FILE = @__FILE@
+__GPG = @__GPG@
+__GREP = @__GREP@
+__ID = @__ID@
+__ID_U = @__ID_U@
+__INSTALL = @__INSTALL@
+__LD = @__LD@
+__MAKE = @__MAKE@
+__MKDIR = @__MKDIR@
+__MV = @__MV@
+__NM = @__NM@
+__OBJCOPY = @__OBJCOPY@
+__OBJDUMP = @__OBJDUMP@
+__PATCH = @__PATCH@
+__PERL = @__PERL@
+__PYTHON = @__PYTHON@
+__RM = @__RM@
+__RSH = @__RSH@
+__SED = @__SED@
+__SSH = @__SSH@
+__STRIP = @__STRIP@
+__TAR = @__TAR@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+libdb3 = @libdb3@
+libdb3a = @libdb3a@
+testdir = @testdir@
+tmpdir = @tmpdir@
+varprefix = @varprefix@
+
+AUTOMAKE_OPTIONS = 1.4 foreign
+
+PYVER = @WITH_PYTHON_VERSION@
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/rpmdb \
+ -I$(top_srcdir)/rpmio \
+ -I$(top_srcdir)/beecrypt \
+ -I$(top_srcdir)/popt \
+ -I/usr/include/python${PYVER} \
+ @INCPATH@
+
+
+EXTRA_DIST = db-py.h hash.h header-py.h upgrade.h
+
+mylibs = \
+ $(top_builddir)/lib/librpm.la \
+ $(top_builddir)/rpmdb/librpmdb.la \
+ $(top_builddir)/rpmio/librpmio.la \
+ $(top_builddir)/popt/libpopt.la
+
+
+LDADD =
+
+pythondir = $(prefix)/lib/python${PYVER}/site-packages
+python_PROGRAMS = rpmmodule.so poptmodule.so
+
+rpmmodule_so_SOURCES =
+rpmmodule_so_LDFLAGS = $(mylibs) $(LIBS) -shared -Wl,-soname,rpmmodule.so
+
+poptmodule_so_SOURCES = poptmodule.c
+poptmodule_so_LDFLAGS = $(mylibs) $(LIBS) -shared -Wl,-soname,poptmodule.so
+
+noinst_LTLIBRARIES = librpmmodule.la
+librpmmodule_la_SOURCES = rpmmodule.c hash.c upgrade.c header-py.c db-py.c
+subdir = python
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+librpmmodule_la_LDFLAGS =
+librpmmodule_la_LIBADD =
+am_librpmmodule_la_OBJECTS = rpmmodule.lo hash.lo upgrade.lo \
+ header-py.lo db-py.lo
+librpmmodule_la_OBJECTS = $(am_librpmmodule_la_OBJECTS)
+python_PROGRAMS = rpmmodule.so$(EXEEXT) poptmodule.so$(EXEEXT)
+PROGRAMS = $(python_PROGRAMS)
+
+am_poptmodule_so_OBJECTS = poptmodule.$(OBJEXT)
+poptmodule_so_OBJECTS = $(am_poptmodule_so_OBJECTS)
+poptmodule_so_LDADD = $(LDADD)
+poptmodule_so_DEPENDENCIES =
+am_rpmmodule_so_OBJECTS =
+rpmmodule_so_OBJECTS = $(am_rpmmodule_so_OBJECTS)
+rpmmodule_so_LDADD = $(LDADD)
+rpmmodule_so_DEPENDENCIES =
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/db-py.Plo $(DEPDIR)/hash.Plo \
+@AMDEP_TRUE@ $(DEPDIR)/header-py.Plo $(DEPDIR)/poptmodule.Po \
+@AMDEP_TRUE@ $(DEPDIR)/rpmmodule.Plo $(DEPDIR)/upgrade.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+ $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+DIST_SOURCES = $(librpmmodule_la_SOURCES) $(poptmodule_so_SOURCES) \
+ $(rpmmodule_so_SOURCES)
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+SOURCES = $(librpmmodule_la_SOURCES) $(poptmodule_so_SOURCES) $(rpmmodule_so_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign python/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && \
+ CONFIG_HEADERS= CONFIG_LINKS= \
+ CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+librpmmodule.la: $(librpmmodule_la_OBJECTS) $(librpmmodule_la_DEPENDENCIES)
+ $(LINK) $(librpmmodule_la_LDFLAGS) $(librpmmodule_la_OBJECTS) $(librpmmodule_la_LIBADD) $(LIBS)
+install-pythonPROGRAMS: $(python_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pythondir)
+ @list='$(python_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pythondir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pythondir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-pythonPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(python_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(pythondir)/$$f"; \
+ rm -f $(DESTDIR)$(pythondir)/$$f; \
+ done
+
+clean-pythonPROGRAMS:
+ -test -z "$(python_PROGRAMS)" || rm -f $(python_PROGRAMS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/db-py.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/header-py.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/poptmodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/rpmmodule.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/upgrade.Plo@am__quote@
+
+distclean-depend:
+ -rm -rf $(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+
+.c.lo:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
+
+GTAGS:
+ here=`CDPATH=: && cd $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
+ if test -d $$d/$$file; then \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(pythondir)
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pythonPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pythonPROGRAMS
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+uninstall-am: uninstall-info-am uninstall-pythonPROGRAMS
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pythonPROGRAMS \
+ distclean distclean-compile distclean-depend distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am info \
+ info-am install install-am install-data install-data-am \
+ install-exec install-exec-am install-info install-info-am \
+ install-man install-pythonPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool tags uninstall \
+ uninstall-am uninstall-info-am uninstall-pythonPROGRAMS
+
+
+rpmmodule.so$(EXEEXT): $(librpmmodule_la_OBJECTS)
+ $(LINK) -o $@ $(librpmmodule_la_OBJECTS) $(rpmmodule_so_LDFLAGS)
+
+poptmodule.so$(EXEEXT): $(poptmodule_so_OBJECTS)
+ $(LINK) -o $@ $(poptmodule_so_OBJECTS) $(poptmodule_so_LDFLAGS)
+
+.PHONY: lclint
+lclint:
+ lclint $(DEFS) $(INCLUDES) $(librpmmodule_la_SOURCES)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/python/db-py.c b/python/db-py.c
new file mode 100644
index 000000000..74aeb9b58
--- /dev/null
+++ b/python/db-py.c
@@ -0,0 +1,499 @@
+/** \ingroup python
+ * \file python/db-py.c
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "Python.h"
+#include "rpmio_internal.h"
+#include "rpmcli.h" /* XXX for rpmCheckSig */
+#include "misc.h"
+#include "header_internal.h"
+#include "upgrade.h"
+
+#include "db-py.h"
+#include "header-py.h"
+
+/** \ingroup python
+ */
+typedef struct rpmdbMIObject_s rpmdbMIObject;
+
+/** \ingroup python
+ * \class rpmdbMatchIterator
+ * \brief A python rpmdbMatchIterator object represents the result of an RPM
+ * database query.
+ */
+
+/** \ingroup python
+ * \name Class: rpmdbMatchIterator
+ */
+/*@{*/
+
+/** \ingroup python
+ */
+struct rpmdbMIObject_s {
+ PyObject_HEAD;
+ rpmdbObject *db;
+ rpmdbMatchIterator mi;
+} ;
+
+/** \ingroup python
+ */
+static PyObject *
+rpmdbMINext(rpmdbMIObject * s, PyObject * args) {
+ /* XXX assume header? */
+ Header h;
+ hdrObject * ho;
+
+ if (!PyArg_ParseTuple (args, "")) return NULL;
+
+ h = rpmdbNextIterator(s->mi);
+ if (!h) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ ho = createHeaderObject(h);
+
+ return (PyObject *) ho;
+}
+
+/** \ingroup python
+ */
+static PyObject *
+rpmdbMIpattern(rpmdbMIObject * s, PyObject * args) {
+ PyObject *index = NULL;
+ int type;
+ char * pattern;
+ int tag;
+
+ if (!PyArg_ParseTuple(args, "Ois", &index, &type, &pattern))
+ return NULL;
+
+ if (index == NULL)
+ tag = 0;
+ else if ((tag = tagNumFromPyObject (index)) == -1) {
+ PyErr_SetString(PyExc_TypeError, "unknown tag type");
+ return NULL;
+ }
+
+ rpmdbSetIteratorRE(s->mi, tag, type, pattern);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+
+}
+
+/** \ingroup python
+ */
+static struct PyMethodDef rpmdbMIMethods[] = {
+ {"next", (PyCFunction) rpmdbMINext, 1 },
+ {"pattern", (PyCFunction) rpmdbMIpattern, 1 },
+ {NULL, NULL} /* sentinel */
+};
+
+/** \ingroup python
+ */
+static PyObject * rpmdbMIGetAttr (rpmdbObject *s, char *name) {
+ return Py_FindMethod (rpmdbMIMethods, (PyObject *) s, name);
+}
+
+/** \ingroup python
+ */
+static void rpmdbMIDealloc(rpmdbMIObject * s) {
+ if (s && s->mi) {
+ rpmdbFreeIterator(s->mi);
+ }
+ Py_DECREF (s->db);
+ PyMem_DEL(s);
+}
+
+/** \ingroup python
+ */
+PyTypeObject rpmdbMIType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "rpmdbMatchIterator", /* tp_name */
+ sizeof(rpmdbMIObject), /* tp_size */
+ 0, /* tp_itemsize */
+ (destructor) rpmdbMIDealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) rpmdbMIGetAttr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+};
+
+/*@}*/
+
+/** \ingroup python
+ * \class rpmdb
+ * \brief A python rpmdb object represents an RPM database.
+ *
+ * Instances of the rpmdb object provide access to the records of a
+ * RPM database. The records are accessed by index number. To
+ * retrieve the header data in the RPM database, the rpmdb object is
+ * subscripted as you would access members of a list.
+ *
+ * The rpmdb class contains the following methods:
+ *
+ * - firstkey() Returns the index of the first record in the database.
+ * @deprecated Legacy, use rpmdbMatchIterator instead.
+ *
+ * - nextkey(index) Returns the index of the next record after "index" in the
+ * database.
+ * @param index current rpmdb location
+ * @deprecated Legacy, use rpmdbMatchIterator instead.
+ *
+ * - findbyfile(file) Returns a list of the indexes to records that own file
+ * "file".
+ * @param file absolute path to file
+ *
+ * - findbyname(name) Returns a list of the indexes to records for packages
+ * named "name".
+ * @param name package name
+ *
+ * - findbyprovides(dep) Returns a list of the indexes to records for packages
+ * that provide "dep".
+ * @param dep provided dependency string
+ *
+ * To obtain a rpmdb object, the opendb function in the rpm module
+ * must be called. The opendb function takes two optional arguments.
+ * The first optional argument is a boolean flag that specifies if the
+ * database is to be opened for read/write access or read-only access.
+ * The second argument specifies an alternate root directory for RPM
+ * to use.
+ *
+ * An example of opening a database and retrieving the first header in
+ * the database, then printing the name of the package that the header
+ * represents:
+ * \code
+ * import rpm
+ * rpmdb = rpm.opendb()
+ * index = rpmdb.firstkey()
+ * header = rpmdb[index]
+ * print header[rpm.RPMTAG_NAME]
+ * \endcode
+ * To print all of the packages in the database that match a package
+ * name, the code will look like this:
+ * \code
+ * import rpm
+ * rpmdb = rpm.opendb()
+ * indexes = rpmdb.findbyname("foo")
+ * for index in indexes:
+ * header = rpmdb[index]
+ * print "%s-%s-%s" % (header[rpm.RPMTAG_NAME],
+ * header[rpm.RPMTAG_VERSION],
+ * header[rpm.RPMTAG_RELEASE])
+ * \endcode
+ */
+
+/** \ingroup python
+ * \name Class: rpmdb
+ */
+/*@{*/
+
+/**
+ */
+static PyObject * rpmdbFirst(rpmdbObject * s, PyObject * args) {
+ int first;
+
+ if (!PyArg_ParseTuple (args, "")) return NULL;
+
+ /* Acquire all offsets in one fell swoop. */
+ if (s->offsets == NULL || s->noffs <= 0) {
+ rpmdbMatchIterator mi;
+ Header h;
+
+ if (s->offsets)
+ free(s->offsets);
+ s->offsets = NULL;
+ s->noffs = 0;
+ mi = rpmdbInitIterator(s->db, RPMDBI_PACKAGES, NULL, 0);
+ while ((h = rpmdbNextIterator(mi)) != NULL) {
+ s->noffs++;
+ s->offsets = realloc(s->offsets, s->noffs * sizeof(s->offsets[0]));
+ s->offsets[s->noffs-1] = rpmdbGetIteratorOffset(mi);
+ }
+ rpmdbFreeIterator(mi);
+ }
+
+ s->offx = 0;
+ if (s->offsets != NULL && s->offx < s->noffs)
+ first = s->offsets[s->offx++];
+ else
+ first = 0;
+
+ if (!first) {
+ PyErr_SetString(pyrpmError, "cannot find first entry in database\n");
+ return NULL;
+ }
+
+ return Py_BuildValue("i", first);
+}
+
+/**
+ */
+static PyObject * rpmdbNext(rpmdbObject * s, PyObject * args) {
+ int where;
+
+ if (!PyArg_ParseTuple (args, "i", &where)) return NULL;
+
+ if (s->offsets == NULL || s->offx >= s->noffs) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ where = s->offsets[s->offx++];
+
+ if (!where) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return Py_BuildValue("i", where);
+}
+
+/**
+ */
+static PyObject * handleDbResult(rpmdbMatchIterator mi) {
+ PyObject * list, *o;
+
+ list = PyList_New(0);
+
+ /* XXX FIXME: unnecessary header mallocs are side effect here */
+ if (mi != NULL) {
+ while (rpmdbNextIterator(mi)) {
+ PyList_Append(list, o=PyInt_FromLong(rpmdbGetIteratorOffset(mi)));
+ Py_DECREF(o);
+ }
+ rpmdbFreeIterator(mi);
+ }
+
+ return list;
+}
+
+/**
+ */
+static PyObject * rpmdbByFile(rpmdbObject * s, PyObject * args) {
+ char * str;
+
+ if (!PyArg_ParseTuple(args, "s", &str)) return NULL;
+
+ return handleDbResult(rpmdbInitIterator(s->db, RPMTAG_BASENAMES, str, 0));
+}
+
+/**
+ */
+static PyObject * rpmdbByName(rpmdbObject * s, PyObject * args) {
+ char * str;
+
+ if (!PyArg_ParseTuple(args, "s", &str)) return NULL;
+
+ return handleDbResult(rpmdbInitIterator(s->db, RPMTAG_NAME, str, 0));
+}
+
+/**
+ */
+static PyObject * rpmdbByProvides(rpmdbObject * s, PyObject * args) {
+ char * str;
+
+ if (!PyArg_ParseTuple(args, "s", &str)) return NULL;
+
+ return handleDbResult(rpmdbInitIterator(s->db, RPMTAG_PROVIDENAME, str, 0));
+}
+
+/**
+ */
+static rpmdbMIObject *
+py_rpmdbInitIterator (rpmdbObject * s, PyObject * args) {
+ PyObject *index = NULL;
+ char *key = NULL;
+ int len = 0, tag = -1;
+ rpmdbMIObject * mio;
+
+ if (!PyArg_ParseTuple(args, "|Ozi", &index, &key, &len))
+ return NULL;
+
+ if (index == NULL)
+ tag = 0;
+ else if ((tag = tagNumFromPyObject (index)) == -1) {
+ PyErr_SetString(PyExc_TypeError, "unknown tag type");
+ return NULL;
+ }
+
+ mio = (rpmdbMIObject *) PyObject_NEW(rpmdbMIObject, &rpmdbMIType);
+ if (mio == NULL) {
+ PyErr_SetString(pyrpmError, "out of memory creating rpmdbMIObject");
+ return NULL;
+ }
+
+ mio->mi = rpmdbInitIterator(s->db, tag, key, len);
+ mio->db = s;
+ Py_INCREF (mio->db);
+
+ return mio;
+}
+
+/**
+ */
+static struct PyMethodDef rpmdbMethods[] = {
+ {"firstkey", (PyCFunction) rpmdbFirst, 1 },
+ {"nextkey", (PyCFunction) rpmdbNext, 1 },
+ {"findbyfile", (PyCFunction) rpmdbByFile, 1 },
+ {"findbyname", (PyCFunction) rpmdbByName, 1 },
+ {"findbyprovides", (PyCFunction) rpmdbByProvides, 1 },
+ {"match", (PyCFunction) py_rpmdbInitIterator, 1 },
+ {NULL, NULL} /* sentinel */
+};
+
+/**
+ */
+static PyObject * rpmdbGetAttr(rpmdbObject * s, char * name) {
+ return Py_FindMethod(rpmdbMethods, (PyObject * ) s, name);
+}
+
+/**
+ */
+static void rpmdbDealloc(rpmdbObject * s) {
+ if (s->offsets) {
+ free(s->offsets);
+ }
+ if (s->db) {
+ rpmdbClose(s->db);
+ }
+ PyMem_DEL(s);
+}
+
+#ifndef DYINGSOON /* XXX OK, when? */
+/**
+ */
+static int
+rpmdbLength(rpmdbObject * s) {
+ int count = 0;
+
+ { rpmdbMatchIterator mi;
+
+ /* RPMDBI_PACKAGES */
+ mi = rpmdbInitIterator(s->db, RPMDBI_PACKAGES, NULL, 0);
+ while (rpmdbNextIterator(mi) != NULL)
+ count++;
+ rpmdbFreeIterator(mi);
+ }
+
+ return count;
+}
+
+/**
+ */
+static hdrObject *
+rpmdbSubscript(rpmdbObject * s, PyObject * key) {
+ int offset;
+ hdrObject * ho;
+ Header h;
+ rpmdbMatchIterator mi;
+
+ if (!PyInt_Check(key)) {
+ PyErr_SetString(PyExc_TypeError, "integer expected");
+ return NULL;
+ }
+
+ offset = (int) PyInt_AsLong(key);
+
+ mi = rpmdbInitIterator(s->db, RPMDBI_PACKAGES, &offset, sizeof(offset));
+ if (!(h = rpmdbNextIterator(mi))) {
+ rpmdbFreeIterator(mi);
+ PyErr_SetString(pyrpmError, "cannot read rpmdb entry");
+ return NULL;
+ }
+
+ ho = createHeaderObject(h);
+ headerFree(h, NULL);
+
+ return ho;
+}
+
+/**
+ */
+static PyMappingMethods rpmdbAsMapping = {
+ (inquiry) rpmdbLength, /* mp_length */
+ (binaryfunc) rpmdbSubscript, /* mp_subscript */
+ (objobjargproc)0, /* mp_ass_subscript */
+};
+#endif
+
+/**
+ */
+PyTypeObject rpmdbType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "rpmdb", /* tp_name */
+ sizeof(rpmdbObject), /* tp_size */
+ 0, /* tp_itemsize */
+ (destructor) rpmdbDealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) rpmdbGetAttr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+#ifndef DYINGSOON
+ &rpmdbAsMapping, /* tp_as_mapping */
+#else
+ 0,
+#endif
+};
+
+rpmdb dbFromDb(rpmdbObject * db) {
+ return db->db;
+}
+
+/**
+ */
+rpmdbObject * rpmOpenDB(PyObject * self, PyObject * args) {
+ rpmdbObject * o;
+ char * root = "";
+ int forWrite = 0;
+
+ if (!PyArg_ParseTuple(args, "|is", &forWrite, &root)) return NULL;
+
+ o = PyObject_NEW(rpmdbObject, &rpmdbType);
+ o->db = NULL;
+ o->offx = 0;
+ o->noffs = 0;
+ o->offsets = NULL;
+
+ if (rpmdbOpen(root, &o->db, forWrite ? O_RDWR | O_CREAT: O_RDONLY, 0644)) {
+ char * errmsg = "cannot open database in %s";
+ char * errstr = NULL;
+ int errsize;
+
+ Py_DECREF(o);
+ /* PyErr_SetString should take varargs... */
+ errsize = strlen(errmsg) + *root == '\0' ? 15 /* "/var/lib/rpm" */ : strlen(root);
+ errstr = alloca(errsize);
+ snprintf(errstr, errsize, errmsg, *root == '\0' ? "/var/lib/rpm" : root);
+ PyErr_SetString(pyrpmError, errstr);
+ return NULL;
+ }
+
+ return o;
+}
+
+/**
+ */
+PyObject * rebuildDB (PyObject * self, PyObject * args) {
+ char * root = "";
+
+ if (!PyArg_ParseTuple(args, "s", &root)) return NULL;
+
+ return Py_BuildValue("i", rpmdbRebuild(root));
+}
+
+/*@}*/
+
diff --git a/python/db-py.h b/python/db-py.h
new file mode 100644
index 000000000..c2265ffc5
--- /dev/null
+++ b/python/db-py.h
@@ -0,0 +1,29 @@
+#ifndef RPMPYTHON_DB
+#define RPMPYTHON_DB
+
+/** \ingroup python
+ * \file python/db-py.h
+ */
+
+/** \ingroup python
+ */
+struct rpmdbObject_s {
+ PyObject_HEAD;
+ rpmdb db;
+ int offx;
+ int noffs;
+ int *offsets;
+} ;
+
+/** \ingroup python
+ */
+typedef struct rpmdbObject_s rpmdbObject;
+
+extern PyTypeObject rpmdbType;
+PyTypeObject rpmdbMIType;
+
+rpmdb dbFromDb(rpmdbObject * db);
+rpmdbObject * rpmOpenDB(PyObject * self, PyObject * args);
+PyObject * rebuildDB (PyObject * self, PyObject * args);
+
+#endif
diff --git a/python/header-py.c b/python/header-py.c
new file mode 100644
index 000000000..49144b71e
--- /dev/null
+++ b/python/header-py.c
@@ -0,0 +1,1116 @@
+/** \ingroup python
+ * \file python/header-py.c
+ */
+
+#include "Python.h"
+#include "rpmio_internal.h"
+#include "rpmcli.h" /* XXX for rpmCheckSig */
+#include "depends.h" /* XXX for ts->rpmdb */
+#include "legacy.h"
+#include "misc.h"
+#include "header_internal.h"
+
+#include "header-py.h"
+
+/** \ingroup python
+ * \class header
+ * \brief A python header object represents an RPM package header.
+ *
+ * All RPM packages have headers that provide metadata for the package.
+ * Header objects can be returned by database queries or loaded from a
+ * binary package on disk.
+ *
+ * The headerFromPackage function loads the package header from a
+ * package on disk. It returns a tuple of a "isSource" flag and the
+ * header object. The "isSource" flag is set to 1 if the package
+ * header was read from a source rpm or to 0 if the package header was
+ * read from a binary rpm.
+ *
+ * For example:
+ * \code
+ * import os, rpm
+ *
+ * fd = os.open("/tmp/foo-1.0-1.i386.rpm", os.O_RDONLY)
+ * (header, isSource) = rpm.headerFromPackage(fd)
+ * fd.close()
+ * \endcode
+ * The Python interface to the header data is quite elegant. It
+ * presents the data in a dictionary form. We'll take the header we
+ * just loaded and access the data within it:
+ * \code
+ * print header[rpm.RPMTAG_NAME]
+ * print header[rpm.RPMTAG_VERSION]
+ * print header[rpm.RPMTAG_RELEASE]
+ * \endcode
+ * in the case of our "foor-1.0-1.i386.rpm" package, this code would
+ * output:
+\verbatim
+ foo
+ 1.0
+ 1
+\endverbatim
+ * You make also access the header data by string name:
+ * \code
+ * print header['name']
+ * \endcode
+ * This method of access is a bit slower because the name must be
+ * translated into the tag number dynamically. You also must make sure
+ * the strings in header lookups don't get translated, or the lookups
+ * will fail.
+ */
+
+/** \ingroup python
+ * \name Class: header
+ */
+/*@{*/
+
+/** \ingroup python
+ */
+struct hdrObject_s {
+ PyObject_HEAD;
+ Header h;
+ char ** md5list;
+ char ** fileList;
+ char ** linkList;
+ int_32 * fileSizes;
+ int_32 * mtimes;
+ int_32 * uids, * gids; /* XXX these tags are not used anymore */
+ unsigned short * rdevs;
+ unsigned short * modes;
+} ;
+
+/*@unused@*/ static inline Header headerAllocated(Header h) {
+ h->flags |= HEADERFLAG_ALLOCATED;
+ return 0;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrKeyList(hdrObject * s, PyObject * args) {
+ PyObject * list, *o;
+ HeaderIterator iter;
+ int tag, type;
+
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+
+ list = PyList_New(0);
+
+ iter = headerInitIterator(s->h);
+ while (headerNextIterator(iter, &tag, &type, NULL, NULL)) {
+ if (tag == HEADER_I18NTABLE) continue;
+
+ switch (type) {
+ case RPM_BIN_TYPE:
+ case RPM_INT32_TYPE:
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ case RPM_INT16_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ case RPM_STRING_TYPE:
+ PyList_Append(list, o=PyInt_FromLong(tag));
+ Py_DECREF(o);
+ }
+ }
+
+ headerFreeIterator(iter);
+
+ return list;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrUnload(hdrObject * s, PyObject * args, PyObject *keywords) {
+ char * buf;
+ PyObject * rc;
+ int len, legacy = 0;
+ Header h;
+ static char *kwlist[] = { "legacyHeader", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywords, "|i", kwlist, &legacy))
+ return NULL;
+
+ h = headerLink(s->h, "hdrUnload h");
+ /* XXX this legacy switch is a hack, needs to be removed. */
+ if (legacy) {
+ h = headerCopy(s->h); /* XXX strip region tags, etc */
+ headerFree(s->h, "hdrUnload s->h");
+ }
+ len = headerSizeof(h, 0);
+ buf = headerUnload(h);
+ h = headerFree(h, "hdrUnload h");
+
+ if (buf == NULL || len == 0) {
+ PyErr_SetString(pyrpmError, "can't unload bad header\n");
+ return NULL;
+ }
+
+ rc = PyString_FromStringAndSize(buf, len);
+ free(buf);
+
+ return rc;
+}
+
+/** \ingroup python
+ * Returns a list of these tuples for each item that failed:
+ * (attr_name, correctValue, currentValue)
+ * It should be passed the file number to verify.
+ */
+static PyObject * hdrVerifyFile(hdrObject * s, PyObject * args) {
+ int fileNumber;
+ rpmVerifyAttrs verifyResult = 0;
+ PyObject * list, * tuple, * attrName;
+ int type, count;
+ struct stat sb;
+ char buf[2048];
+ int i;
+ time_t timeInt;
+ struct tm * timeStruct;
+
+ if (!PyInt_Check(args)) {
+ PyErr_SetString(PyExc_TypeError, "integer expected");
+ return NULL;
+ }
+
+ fileNumber = (int) PyInt_AsLong(args);
+
+ { rpmTransactionSet ts;
+ int scareMem = 1;
+ TFI_t fi;
+ int rc;
+
+ ts = rpmtransCreateSet(NULL, NULL);
+ fi = fiNew(ts, NULL, s->h, RPMTAG_BASENAMES, scareMem);
+ fi = tfiInit(fi, fileNumber);
+ if (fi != NULL && tfiNext(fi) >= 0) {
+ /* XXX this routine might use callbacks intelligently. */
+ rc = rpmVerifyFile(ts, fi, &verifyResult, RPMVERIFY_NONE);
+ } else
+ rc = 1;
+
+ fi = fiFree(fi, 1);
+ rpmtransFree(ts);
+
+ if (rc) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+
+ list = PyList_New(0);
+
+ if (!verifyResult) return list;
+
+ /* XXX Legacy tag needs to go away. */
+ if (!s->fileList) {
+ headerGetEntry(s->h, RPMTAG_OLDFILENAMES, &type, (void **) &s->fileList,
+ &count);
+ }
+
+ lstat(s->fileList[fileNumber], &sb);
+
+ if (verifyResult & RPMVERIFY_MD5) {
+ if (!s->md5list) {
+ headerGetEntry(s->h, RPMTAG_FILEMD5S, &type, (void **) &s->md5list,
+ &count);
+ }
+
+ if (domd5(s->fileList[fileNumber], buf, 1)) {
+ strcpy(buf, "00000000000000000000000000000000");
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("checksum");
+ PyTuple_SetItem(tuple, 0, attrName);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(s->md5list[fileNumber]));
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ if (verifyResult & RPMVERIFY_FILESIZE) {
+ if (!s->fileSizes) {
+ headerGetEntry(s->h, RPMTAG_FILESIZES, &type, (void **) &s->fileSizes,
+ &count);
+
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("size");
+ PyTuple_SetItem(tuple, 0, attrName);
+
+ sprintf(buf, "%d", 100);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+ sprintf(buf, "%ld", (long)sb.st_size);
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ if (verifyResult & RPMVERIFY_LINKTO) {
+ if (!s->linkList) {
+ headerGetEntry(s->h, RPMTAG_FILELINKTOS, &type, (void **) &s->linkList,
+ &count);
+ }
+
+ i = readlink(s->fileList[fileNumber], buf, sizeof(buf));
+ if (i <= 0)
+ strcpy(buf, "(unknown)");
+ else
+ buf[i] = '\0';
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("link");
+ PyTuple_SetItem(tuple, 0, attrName);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(s->linkList[fileNumber]));
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ if (verifyResult & RPMVERIFY_MTIME) {
+ if (!s->mtimes) {
+ headerGetEntry(s->h, RPMTAG_FILEMTIMES, &type, (void **) &s->mtimes,
+ &count);
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("time");
+ PyTuple_SetItem(tuple, 0, attrName);
+
+ timeInt = sb.st_mtime;
+ timeStruct = localtime(&timeInt);
+ strftime(buf, sizeof(buf) - 1, "%c", timeStruct);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+
+ timeInt = s->mtimes[fileNumber];
+ timeStruct = localtime(&timeInt);
+ strftime(buf, sizeof(buf) - 1, "%c", timeStruct);
+
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ if (verifyResult & RPMVERIFY_RDEV) {
+ if (!s->rdevs) {
+ headerGetEntry(s->h, RPMTAG_FILERDEVS, &type, (void **) &s->rdevs,
+ &count);
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("device");
+
+ PyTuple_SetItem(tuple, 0, attrName);
+ sprintf(buf, "0x%-4x", s->rdevs[fileNumber]);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+ sprintf(buf, "0x%-4x", (unsigned int) sb.st_rdev);
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ /*
+ * RPMVERIFY_USER and RPM_VERIFY_GROUP are handled wrong here, but rpmlib.a
+ * doesn't do these correctly either. At least this is consistent.
+ *
+ * XXX Consistent? rpmlib.a verifies user/group quite well, thank you.
+ * XXX The code below does nothing useful. FILEUSERNAME needs to be
+ * XXX retrieved and looked up.
+ */
+ if (verifyResult & RPMVERIFY_USER) {
+ if (!s->uids) {
+ headerGetEntry(s->h, RPMTAG_FILEUIDS, &type, (void **) &s->uids,
+ &count);
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("uid");
+ PyTuple_SetItem(tuple, 0, attrName);
+ sprintf(buf, "%d", s->uids[fileNumber]);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+ sprintf(buf, "%d", sb.st_uid);
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ /*
+ * XXX The code below does nothing useful. FILEGROUPNAME needs to be
+ * XXX retrieved and looked up.
+ */
+ if (verifyResult & RPMVERIFY_GROUP) {
+ if (!s->gids) {
+ headerGetEntry(s->h, RPMTAG_FILEGIDS, &type, (void **) &s->gids,
+ &count);
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("gid");
+ PyTuple_SetItem(tuple, 0, attrName);
+ sprintf(buf, "%d", s->gids[fileNumber]);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+ sprintf(buf, "%d", sb.st_gid);
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ if (verifyResult & RPMVERIFY_MODE) {
+ if (!s->modes) {
+ headerGetEntry(s->h, RPMTAG_FILEMODES, &type, (void **) &s->modes,
+ &count);
+ }
+
+ tuple = PyTuple_New(3);
+ attrName = PyString_FromString("permissions");
+ PyTuple_SetItem(tuple, 0, attrName);
+ sprintf(buf, "0%-4o", s->modes[fileNumber]);
+ PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
+ sprintf(buf, "0%-4o", sb.st_mode);
+ PyTuple_SetItem(tuple, 2, PyString_FromString(buf));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+ }
+
+ return list;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrExpandFilelist(hdrObject * s, PyObject * args) {
+ expandFilelist (s->h);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrCompressFilelist(hdrObject * s, PyObject * args) {
+ compressFilelist (s->h);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* make a header with _all_ the tags we need */
+/** \ingroup python
+ */
+static void mungeFilelist(Header h)
+{
+ const char ** fileNames = NULL;
+ int count = 0;
+
+ if (!headerIsEntry (h, RPMTAG_BASENAMES)
+ || !headerIsEntry (h, RPMTAG_DIRNAMES)
+ || !headerIsEntry (h, RPMTAG_DIRINDEXES))
+ compressFilelist(h);
+
+ rpmBuildFileList(h, &fileNames, &count);
+
+ if (fileNames == NULL || count <= 0)
+ return;
+
+ /* XXX Legacy tag needs to go away. */
+ headerAddEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
+ fileNames, count);
+
+ free((void *)fileNames);
+}
+
+/**
+ */
+static PyObject * rhnUnload(hdrObject * s, PyObject * args) {
+ int len;
+ char * uh;
+ PyObject * rc;
+ Header h;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ h = headerLink(s->h, "rhnUnload h");
+
+ /* Retrofit a RHNPlatform: tag. */
+ if (!headerIsEntry(h, RPMTAG_RHNPLATFORM)) {
+ const char * arch;
+ int_32 at;
+ if (headerGetEntry(h, RPMTAG_ARCH, &at, (void **)&arch, NULL))
+ headerAddEntry(h, RPMTAG_RHNPLATFORM, at, arch, 1);
+ }
+
+ /* Legacy headers are forced into immutable region. */
+ if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
+ Header nh = headerReload(h, RPMTAG_HEADERIMMUTABLE);
+ /* XXX Another unload/load cycle to "seal" the immutable region. */
+ uh = headerUnload(nh);
+ headerFree(nh, "rhnUnload nh");
+ h = headerLoad(uh);
+ headerAllocated(h);
+ }
+
+ /* All headers have SHA1 digest, compute and add if necessary. */
+ if (!headerIsEntry(h, RPMTAG_SHA1HEADER)) {
+ int_32 uht, uhc;
+ const char * digest;
+ size_t digestlen;
+ DIGEST_CTX ctx;
+
+ headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, (void **)&uh, &uhc);
+
+ ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
+ rpmDigestUpdate(ctx, uh, uhc);
+ rpmDigestFinal(ctx, (void **)&digest, &digestlen, 1);
+
+ headerAddEntry(h, RPMTAG_SHA1RHN, RPM_STRING_TYPE, digest, 1);
+
+ uh = headerFreeData(uh, uht);
+ digest = _free(digest);
+ }
+
+ len = headerSizeof(h, 0);
+ uh = headerUnload(h);
+ headerFree(h, "rhnUnload h");
+
+ rc = PyString_FromStringAndSize(uh, len);
+ free(uh);
+
+ return rc;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrFullFilelist(hdrObject * s, PyObject * args) {
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ mungeFilelist (s->h);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrSprintf(hdrObject * s, PyObject * args) {
+ char * fmt;
+ char * r;
+ errmsg_t err;
+ PyObject * result;
+
+ if (!PyArg_ParseTuple(args, "s", &fmt))
+ return NULL;
+
+ r = headerSprintf(s->h, fmt, rpmTagTable, rpmHeaderFormats, &err);
+ if (!r) {
+ PyErr_SetString(pyrpmError, err);
+ return NULL;
+ }
+
+ result = Py_BuildValue("s", r);
+ free(r);
+
+ return result;
+}
+
+
+/** \ingroup python
+ */
+static struct PyMethodDef hdrMethods[] = {
+ {"keys", (PyCFunction) hdrKeyList, 1 },
+ {"unload", (PyCFunction) hdrUnload, METH_VARARGS|METH_KEYWORDS },
+ {"verifyFile", (PyCFunction) hdrVerifyFile, 1 },
+ {"expandFilelist", (PyCFunction) hdrExpandFilelist, 1 },
+ {"compressFilelist", (PyCFunction) hdrCompressFilelist, 1 },
+ {"fullFilelist", (PyCFunction) hdrFullFilelist, 1 },
+ {"rhnUnload", (PyCFunction) rhnUnload, METH_VARARGS },
+ {"sprintf", (PyCFunction) hdrSprintf, METH_VARARGS },
+ {NULL, NULL} /* sentinel */
+};
+
+/** \ingroup python
+ */
+static PyObject * hdrGetAttr(hdrObject * s, char * name) {
+ return Py_FindMethod(hdrMethods, (PyObject * ) s, name);
+}
+
+/** \ingroup python
+ */
+static void hdrDealloc(hdrObject * s) {
+ if (s->h) headerFree(s->h, "hdrDealloc s->h");
+ if (s->md5list) free(s->md5list);
+ if (s->fileList) free(s->fileList);
+ if (s->linkList) free(s->linkList);
+ PyMem_DEL(s);
+}
+
+/** \ingroup python
+ */
+long tagNumFromPyObject (PyObject *item)
+{
+ char * str;
+ int i;
+
+ if (PyInt_Check(item)) {
+ return PyInt_AsLong(item);
+ } else if (PyString_Check(item)) {
+ str = PyString_AsString(item);
+ for (i = 0; i < rpmTagTableSize; i++)
+ if (!xstrcasecmp(rpmTagTable[i].name + 7, str)) break;
+ if (i < rpmTagTableSize) return rpmTagTable[i].val;
+ }
+ return -1;
+}
+
+/** \ingroup python
+ */
+static PyObject * hdrSubscript(hdrObject * s, PyObject * item) {
+ int type, count, i, tag = -1;
+ void * data;
+ PyObject * o, * metao;
+ char ** stringArray;
+ int forceArray = 0;
+ int freeData = 0;
+ char * str;
+ struct headerSprintfExtension_s * ext = NULL;
+ const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
+
+ if (PyCObject_Check (item))
+ ext = PyCObject_AsVoidPtr(item);
+ else
+ tag = tagNumFromPyObject (item);
+ if (tag == -1 && PyString_Check(item)) {
+ /* if we still don't have the tag, go looking for the header
+ extensions */
+ str = PyString_AsString(item);
+ while (extensions->name) {
+ if (extensions->type == HEADER_EXT_TAG
+ && !xstrcasecmp(extensions->name + 7, str)) {
+ (const struct headerSprintfExtension *) ext = extensions;
+ }
+ extensions++;
+ }
+ }
+
+ if (ext) {
+ ext->u.tagFunction(s->h, &type, (const void **) &data, &count, &freeData);
+ } else {
+ if (tag == -1) {
+ PyErr_SetString(PyExc_KeyError, "unknown header tag");
+ return NULL;
+ }
+
+ if (!rpmHeaderGetEntry(s->h, tag, &type, &data, &count)) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+
+ switch (tag) {
+ case RPMTAG_OLDFILENAMES:
+ case RPMTAG_FILESIZES:
+ case RPMTAG_FILESTATES:
+ case RPMTAG_FILEMODES:
+ case RPMTAG_FILEUIDS:
+ case RPMTAG_FILEGIDS:
+ case RPMTAG_FILERDEVS:
+ case RPMTAG_FILEMTIMES:
+ case RPMTAG_FILEMD5S:
+ case RPMTAG_FILELINKTOS:
+ case RPMTAG_FILEFLAGS:
+ case RPMTAG_ROOT:
+ case RPMTAG_FILEUSERNAME:
+ case RPMTAG_FILEGROUPNAME:
+ forceArray = 1;
+ break;
+ case RPMTAG_SUMMARY:
+ case RPMTAG_GROUP:
+ case RPMTAG_DESCRIPTION:
+ freeData = 1;
+ break;
+ default:
+ break;
+ }
+
+ switch (type) {
+ case RPM_BIN_TYPE:
+ o = PyString_FromStringAndSize(data, count);
+ break;
+
+ case RPM_INT32_TYPE:
+ if (count != 1 || forceArray) {
+ metao = PyList_New(0);
+ for (i = 0; i < count; i++) {
+ o = PyInt_FromLong(((int *) data)[i]);
+ PyList_Append(metao, o);
+ Py_DECREF(o);
+ }
+ o = metao;
+ } else {
+ o = PyInt_FromLong(*((int *) data));
+ }
+ break;
+
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ if (count != 1 || forceArray) {
+ metao = PyList_New(0);
+ for (i = 0; i < count; i++) {
+ o = PyInt_FromLong(((char *) data)[i]);
+ PyList_Append(metao, o);
+ Py_DECREF(o);
+ }
+ o = metao;
+ } else {
+ o = PyInt_FromLong(*((char *) data));
+ }
+ break;
+
+ case RPM_INT16_TYPE:
+ if (count != 1 || forceArray) {
+ metao = PyList_New(0);
+ for (i = 0; i < count; i++) {
+ o = PyInt_FromLong(((short *) data)[i]);
+ PyList_Append(metao, o);
+ Py_DECREF(o);
+ }
+ o = metao;
+ } else {
+ o = PyInt_FromLong(*((short *) data));
+ }
+ break;
+
+ case RPM_STRING_ARRAY_TYPE:
+ stringArray = data;
+
+ metao = PyList_New(0);
+ for (i = 0; i < count; i++) {
+ o = PyString_FromString(stringArray[i]);
+ PyList_Append(metao, o);
+ Py_DECREF(o);
+ }
+ free (stringArray);
+ o = metao;
+ break;
+
+ case RPM_STRING_TYPE:
+ if (count != 1 || forceArray) {
+ stringArray = data;
+
+ metao = PyList_New(0);
+ for (i=0; i < count; i++) {
+ o = PyString_FromString(stringArray[i]);
+ PyList_Append(metao, o);
+ Py_DECREF(o);
+ }
+ o = metao;
+ } else {
+ o = PyString_FromString(data);
+ if (freeData)
+ free (data);
+ }
+ break;
+
+ default:
+ PyErr_SetString(PyExc_TypeError, "unsupported type in header");
+ return NULL;
+ }
+
+ return o;
+}
+
+/** \ingroup python
+ */
+static PyMappingMethods hdrAsMapping = {
+ (inquiry) 0, /* mp_length */
+ (binaryfunc) hdrSubscript, /* mp_subscript */
+ (objobjargproc)0, /* mp_ass_subscript */
+};
+
+/** \ingroup python
+ */
+PyTypeObject hdrType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "header", /* tp_name */
+ sizeof(hdrObject), /* tp_size */
+ 0, /* tp_itemsize */
+ (destructor) hdrDealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) hdrGetAttr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ &hdrAsMapping, /* tp_as_mapping */
+};
+
+hdrObject * createHeaderObject(Header h) {
+ hdrObject * ho;
+
+ ho = PyObject_NEW(hdrObject, &hdrType);
+ ho->h = headerLink(h, NULL);
+ ho->fileList = ho->linkList = ho->md5list = NULL;
+ ho->uids = ho->gids = ho->mtimes = ho->fileSizes = NULL;
+ ho->modes = ho->rdevs = NULL;
+
+ return ho;
+}
+
+Header hdrGetHeader(hdrObject * h) {
+ return h->h;
+}
+
+/**
+ */
+PyObject * rpmHeaderFromPackage(PyObject * self, PyObject * args) {
+ hdrObject * h;
+ Header header;
+ FD_t fd;
+ int rawFd;
+ int isSource = 0;
+ rpmRC rc;
+
+ if (!PyArg_ParseTuple(args, "i", &rawFd)) return NULL;
+
+ fd = fdDup(rawFd);
+ { rpmTransactionSet ts;
+ ts = rpmtransCreateSet(NULL, NULL);
+ rc = rpmReadPackageFile(ts, fd, "rpmHeaderFromPackage", &header);
+ rpmtransFree(ts);
+ }
+ Fclose(fd);
+
+ switch (rc) {
+ case RPMRC_BADSIZE:
+ case RPMRC_OK:
+ h = (hdrObject *) PyObject_NEW(PyObject, &hdrType);
+ h->h = header;
+ h->fileList = h->linkList = h->md5list = NULL;
+ h->uids = h->gids = h->mtimes = h->fileSizes = NULL;
+ h->modes = h->rdevs = NULL;
+ isSource = headerIsEntry(header, RPMTAG_SOURCEPACKAGE);
+ break;
+
+ case RPMRC_BADMAGIC:
+ Py_INCREF(Py_None);
+ h = (hdrObject *) Py_None;
+ break;
+
+ case RPMRC_FAIL:
+ case RPMRC_SHORTREAD:
+ default:
+ PyErr_SetString(pyrpmError, "error reading package");
+ return NULL;
+ }
+
+ return Py_BuildValue("(Ni)", h, isSource);
+}
+
+/**
+ */
+PyObject * hdrLoad(PyObject * self, PyObject * args) {
+ char * obj, * copy=NULL;
+ Header hdr;
+ hdrObject * h;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
+
+ /* malloc is needed to avoid surprises from data swab in headerLoad(). */
+ copy = malloc(len);
+ if (copy == NULL) {
+ PyErr_SetString(pyrpmError, "out of memory");
+ return NULL;
+ }
+ memcpy (copy, obj, len);
+
+ hdr = headerLoad(copy);
+ if (!hdr) {
+ PyErr_SetString(pyrpmError, "bad header");
+ return NULL;
+ }
+ headerAllocated(hdr);
+ compressFilelist (hdr);
+ providePackageNVR (hdr);
+
+ h = (hdrObject *) PyObject_NEW(PyObject, &hdrType);
+ h->h = hdr;
+ h->fileList = h->linkList = h->md5list = NULL;
+ h->uids = h->gids = h->mtimes = h->fileSizes = NULL;
+ h->modes = h->rdevs = NULL;
+
+ return (PyObject *) h;
+}
+
+/**
+ */
+PyObject * rhnLoad(PyObject * self, PyObject * args) {
+ char * obj, * copy=NULL;
+ Header hdr;
+ hdrObject * h;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#", &obj, &len)) return NULL;
+
+ /* malloc is needed to avoid surprises from data swab in headerLoad(). */
+ copy = malloc(len);
+ if (copy == NULL) {
+ PyErr_SetString(pyrpmError, "out of memory");
+ return NULL;
+ }
+ memcpy (copy, obj, len);
+
+ hdr = headerLoad(copy);
+ if (!hdr) {
+ PyErr_SetString(pyrpmError, "bad header");
+ return NULL;
+ }
+ headerAllocated(hdr);
+
+ /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
+ if (!headerIsEntry(hdr, RPMTAG_HEADERIMMUTABLE)) {
+ PyErr_SetString(pyrpmError, "bad header, not immutable");
+ headerFree(hdr, "rhnLoad hdr #1");
+ return NULL;
+ }
+
+ /* XXX avoid the false OK's from rpmverifyDigest() with missing tags. */
+ if (!headerIsEntry(hdr, RPMTAG_SHA1HEADER)
+ && !headerIsEntry(hdr, RPMTAG_SHA1RHN)) {
+ PyErr_SetString(pyrpmError, "bad header, no digest");
+ headerFree(hdr, "rhnLoad hdr #2");
+ return NULL;
+ }
+
+ if (rpmVerifyDigest(hdr)) {
+ PyErr_SetString(pyrpmError, "bad header, digest check failed");
+ headerFree(hdr, "rhnLoad hdr #3");
+ return NULL;
+ }
+
+ /* Retrofit a RHNPlatform: tag. */
+ if (!headerIsEntry(hdr, RPMTAG_RHNPLATFORM)) {
+ const char * arch;
+ int_32 at;
+ if (headerGetEntry(hdr, RPMTAG_ARCH, &at, (void **)&arch, NULL))
+ headerAddEntry(hdr, RPMTAG_RHNPLATFORM, at, arch, 1);
+ }
+
+ h = createHeaderObject(hdr);
+
+ return (PyObject *) h;
+}
+
+/**
+ */
+PyObject * rpmReadHeaders (FD_t fd) {
+ PyObject * list;
+ Header header;
+ hdrObject * h;
+
+ if (!fd) {
+ PyErr_SetFromErrno(pyrpmError);
+ return NULL;
+ }
+
+ list = PyList_New(0);
+ Py_BEGIN_ALLOW_THREADS
+ header = headerRead(fd, HEADER_MAGIC_YES);
+
+ Py_END_ALLOW_THREADS
+ while (header) {
+ compressFilelist (header);
+ providePackageNVR (header);
+ h = (hdrObject *) PyObject_NEW(PyObject, &hdrType);
+ h->h = header;
+ h->fileList = h->linkList = h->md5list = NULL;
+ h->uids = h->gids = h->mtimes = h->fileSizes = NULL;
+ h->modes = h->rdevs = NULL;
+ if (PyList_Append(list, (PyObject *) h)) {
+ Py_DECREF(list);
+ Py_DECREF(h);
+ return NULL;
+ }
+
+ Py_DECREF(h);
+
+ Py_BEGIN_ALLOW_THREADS
+ header = headerRead(fd, HEADER_MAGIC_YES);
+ Py_END_ALLOW_THREADS
+ }
+
+ return list;
+}
+
+/**
+ */
+PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args) {
+ FD_t fd;
+ int fileno;
+ PyObject * list;
+
+ if (!PyArg_ParseTuple(args, "i", &fileno)) return NULL;
+ fd = fdDup(fileno);
+
+ list = rpmReadHeaders (fd);
+ Fclose(fd);
+
+ return list;
+}
+
+/**
+ */
+PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args) {
+ char * filespec;
+ FD_t fd;
+ PyObject * list;
+
+ if (!PyArg_ParseTuple(args, "s", &filespec)) return NULL;
+ fd = Fopen(filespec, "r.fdio");
+
+ if (!fd) {
+ PyErr_SetFromErrno(pyrpmError);
+ return NULL;
+ }
+
+ list = rpmReadHeaders (fd);
+ Fclose(fd);
+
+ return list;
+}
+
+/**
+ * This assumes the order of list matches the order of the new headers, and
+ * throws an exception if that isn't true.
+ */
+int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag) {
+ Header newH;
+ HeaderIterator iter;
+ int_32 * newMatch, * oldMatch;
+ hdrObject * ho;
+ int count = 0;
+ int type, c, tag;
+ void * p;
+
+ Py_BEGIN_ALLOW_THREADS
+ newH = headerRead(fd, HEADER_MAGIC_YES);
+
+ Py_END_ALLOW_THREADS
+ while (newH) {
+ if (!headerGetEntry(newH, matchTag, NULL, (void **) &newMatch, NULL)) {
+ PyErr_SetString(pyrpmError, "match tag missing in new header");
+ return 1;
+ }
+
+ ho = (hdrObject *) PyList_GetItem(list, count++);
+ if (!ho) return 1;
+
+ if (!headerGetEntry(ho->h, matchTag, NULL, (void **) &oldMatch, NULL)) {
+ PyErr_SetString(pyrpmError, "match tag missing in new header");
+ return 1;
+ }
+
+ if (*newMatch != *oldMatch) {
+ PyErr_SetString(pyrpmError, "match tag mismatch");
+ return 1;
+ }
+
+ if (ho->md5list) free(ho->md5list);
+ if (ho->fileList) free(ho->fileList);
+ if (ho->linkList) free(ho->linkList);
+
+ ho->md5list = NULL;
+ ho->fileList = NULL;
+ ho->linkList = NULL;
+
+ iter = headerInitIterator(newH);
+
+ while (headerNextIterator(iter, &tag, &type, (void *) &p, &c)) {
+ /* could be dupes */
+ headerRemoveEntry(ho->h, tag);
+ headerAddEntry(ho->h, tag, type, p, c);
+ headerFreeData(p, type);
+ }
+
+ headerFreeIterator(iter);
+
+ Py_BEGIN_ALLOW_THREADS
+ newH = headerRead(fd, HEADER_MAGIC_YES);
+ Py_END_ALLOW_THREADS
+ }
+
+ return 0;
+}
+
+PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args) {
+ FD_t fd;
+ int fileno;
+ PyObject * list;
+ int rc;
+ int matchTag;
+
+ if (!PyArg_ParseTuple(args, "Oii", &list, &fileno, &matchTag)) return NULL;
+
+ if (!PyList_Check(list)) {
+ PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
+ return NULL;
+ }
+
+ fd = fdDup(fileno);
+
+ rc = rpmMergeHeaders (list, fd, matchTag);
+ Fclose(fd);
+
+ if (rc) {
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/**
+ */
+PyObject * versionCompare (PyObject * self, PyObject * args) {
+ hdrObject * h1, * h2;
+
+ if (!PyArg_ParseTuple(args, "O!O!", &hdrType, &h1, &hdrType, &h2)) return NULL;
+
+ return Py_BuildValue("i", rpmVersionCompare(h1->h, h2->h));
+}
+
+/**
+ */
+PyObject * labelCompare (PyObject * self, PyObject * args) {
+ char *v1, *r1, *e1, *v2, *r2, *e2;
+ int rc;
+
+ if (!PyArg_ParseTuple(args, "(zzz)(zzz)",
+ &e1, &v1, &r1,
+ &e2, &v2, &r2)) return NULL;
+
+ if (e1 && !e2)
+ return Py_BuildValue("i", 1);
+ else if (!e1 && e2)
+ return Py_BuildValue("i", -1);
+ else if (e1 && e2) {
+ int ep1, ep2;
+ ep1 = atoi (e1);
+ ep2 = atoi (e2);
+ if (ep1 < ep2)
+ return Py_BuildValue("i", -1);
+ else if (ep1 > ep2)
+ return Py_BuildValue("i", 1);
+ }
+
+ rc = rpmvercmp(v1, v2);
+ if (rc)
+ return Py_BuildValue("i", rc);
+
+ return Py_BuildValue("i", rpmvercmp(r1, r2));
+}
+
+/*@}*/
diff --git a/python/header-py.h b/python/header-py.h
new file mode 100644
index 000000000..c5d3d4ab7
--- /dev/null
+++ b/python/header-py.h
@@ -0,0 +1,31 @@
+#ifndef RPMPYTHON_HEADER
+#define RPMPYTHON_HEADER
+
+/** \ingroup python
+ * \file python/header-py.h
+ */
+
+/** \ingroup python
+ */
+typedef struct hdrObject_s hdrObject;
+extern PyTypeObject hdrType;
+
+/** \ingroup python
+ */
+PyObject * pyrpmError;
+
+hdrObject * createHeaderObject(Header h);
+Header hdrGetHeader(hdrObject * h);
+PyObject * labelCompare (PyObject * self, PyObject * args);
+PyObject * versionCompare (PyObject * self, PyObject * args);
+PyObject * rpmMergeHeadersFromFD(PyObject * self, PyObject * args);
+int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag);
+PyObject * rpmHeaderFromFile(PyObject * self, PyObject * args);
+PyObject * rpmHeaderFromFD(PyObject * self, PyObject * args);
+PyObject * rpmReadHeaders (FD_t fd);
+PyObject * rhnLoad(PyObject * self, PyObject * args);
+PyObject * hdrLoad(PyObject * self, PyObject * args);
+PyObject * rpmHeaderFromPackage(PyObject * self, PyObject * args);
+long tagNumFromPyObject (PyObject *item);
+
+#endif
diff --git a/python/rpmmodule.c b/python/rpmmodule.c
new file mode 100644
index 000000000..c0c1f5fec
--- /dev/null
+++ b/python/rpmmodule.c
@@ -0,0 +1,1170 @@
+/** \ingroup python
+ * \file python/rpmmodule.c
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <glob.h> /* XXX rpmio.h */
+#include <dirent.h> /* XXX rpmio.h */
+#include <locale.h>
+#include <time.h>
+
+#include "Python.h"
+#include "rpmio_internal.h"
+#include "rpmcli.h" /* XXX for rpmCheckSig */
+#include "depends.h" /* XXX for ts->rpmdb */
+#include "legacy.h"
+#include "misc.h"
+#include "header_internal.h"
+#include "upgrade.h"
+
+#include "db-py.h"
+#include "header-py.h"
+
+extern int _rpmio_debug;
+
+/* XXX These names/constants have been removed from the rpmlib API. */
+enum {
+ RPMDEP_SENSE_REQUIRES, /*!< requirement not satisfied. */
+ RPMDEP_SENSE_CONFLICTS /*!< conflict was found. */
+};
+
+#ifdef __LCLINT__
+#undef PyObject_HEAD
+#define PyObject_HEAD int _PyObjectHead
+#endif
+
+void initrpm(void);
+
+/* from lib/misc.c */
+int rpmvercmp(const char * one, const char * two);
+
+/** \ingroup python
+ */
+typedef struct rpmtransObject_s rpmtransObject;
+
+/** \ingroup python
+ * \name Class: rpmtrans
+ * \class rpmtrans
+ * \brief A python rpmtrans object represents an RPM transaction set.
+ *
+ * The transaction set is the workhorse of RPM. It performs the
+ * installation and upgrade of packages. The rpmtrans object is
+ * instantiated by the TransactionSet function in the rpm module.
+ *
+ * The TransactionSet function takes two optional arguments. The first
+ * argument is the root path, the second is an open database to perform
+ * the transaction set upon.
+ *
+ * A rpmtrans object has the following methods:
+ *
+ * - add(header,data,mode) Add a binary package to a transaction set.
+ * @param header the header to be added
+ * @param data user data that will be passed to the transaction callback
+ * during transaction execution
+ * @param mode optional argument that specifies if this package should
+ * be installed ('i'), upgraded ('u'), or if it is just
+ * available to the transaction when computing
+ * dependencies but no action should be performed with it
+ * ('a').
+ *
+ * - remove
+ *
+ * - depcheck() Perform a dependency and conflict check on the
+ * transaction set. After headers have been added to a
+ * transaction set, a dependency check can be performed
+ * to make sure that all package dependencies are
+ * satisfied.
+ * @return None If there are no unresolved dependencies
+ * Otherwise a list of complex tuples is returned, one tuple per
+ * unresolved dependency, with
+ * The format of the dependency tuple is:
+ * ((packageName, packageVersion, packageRelease),
+ * (reqName, reqVersion),
+ * needsFlags,
+ * suggestedPackage,
+ * sense)
+ * packageName, packageVersion, packageRelease are the name,
+ * version, and release of the package that has the unresolved
+ * dependency or conflict.
+ * The reqName and reqVersion are the name and version of the
+ * requirement or conflict.
+ * The needsFlags is a bitfield that describes the versioned
+ * nature of a requirement or conflict. The constants
+ * rpm.RPMSENSE_LESS, rpm.RPMSENSE_GREATER, and
+ * rpm.RPMSENSE_EQUAL can be logical ANDed with the needsFlags
+ * to get versioned dependency information.
+ * suggestedPackage is a tuple if the dependency check was aware
+ * of a package that solves this dependency problem when the
+ * dependency check was run. Packages that are added to the
+ * transaction set as "available" are examined during the
+ * dependency check as possible dependency solvers. The tuple
+ * contains two values, (header, suggestedName). These are set to
+ * the header of the suggested package and its name, respectively.
+ * If there is no known package to solve the dependency problem,
+ * suggestedPackage is None.
+ * The constants rpm.RPMDEP_SENSE_CONFLICTS and
+ * rpm.RPMDEP_SENSE_REQUIRES are set to show a dependency as a
+ * requirement or a conflict.
+ *
+ * - run(flags,problemSetFilter,callback,data) Attempt to execute a
+ * transaction set. After the transaction set has been populated
+ * with install and upgrade actions, it can be executed by invoking
+ * the run() method.
+ * @param flags - modifies the behavior of the transaction set as it is
+ * processed. The following values can be locical ORed
+ * together:
+ * - rpm.RPMTRANS_FLAG_TEST - test mode, do not modify the RPM
+ * database, change any files, or run any package scripts
+ * - rpm.RPMTRANS_FLAG_BUILD_PROBS - only build a list of
+ * problems encountered when attempting to run this transaction
+ * set
+ * - rpm.RPMTRANS_FLAG_NOSCRIPTS - do not execute package scripts
+ * - rpm.RPMTRANS_FLAG_JUSTDB - only make changes to the rpm
+ * database, do not modify files.
+ * - rpm.RPMTRANS_FLAG_NOTRIGGERS - do not run trigger scripts
+ * - rpm.RPMTRANS_FLAG_NODOCS - do not install files marked as %doc
+ * - rpm.RPMTRANS_FLAG_ALLFILES - create all files, even if a
+ * file is marked %config(missingok) and an upgrade is
+ * being performed.
+ * - rpm.RPMTRANS_FLAG_KEEPOBSOLETE - do not remove obsoleted
+ * packages.
+ * @param problemSetFilter - control bit(s) to ignore classes of problems,
+ * any of
+ * - rpm.RPMPROB_FILTER_IGNOREOS -
+ * - rpm.RPMPROB_FILTER_IGNOREARCH -
+ * - rpm.RPMPROB_FILTER_REPLACEPKG -
+ * - rpm.RPMPROB_FILTER_FORCERELOCATE -
+ * - rpm.RPMPROB_FILTER_REPLACENEWFILES -
+ * - rpm.RPMPROB_FILTER_REPLACEOLDFILES -
+ * - rpm.RPMPROB_FILTER_OLDPACKAGE -
+ * - rpm.RPMPROB_FILTER_DISKSPACE -
+ */
+
+/** \ingroup python
+ * \name Class: rpmtrans
+ */
+/*@{*/
+
+/** \ingroup python
+ */
+struct rpmtransObject_s {
+ PyObject_HEAD;
+ rpmdbObject * dbo;
+ rpmTransactionSet ts;
+ PyObject * keyList; /* keeps reference counts correct */
+ FD_t scriptFd;
+} ;
+
+/** \ingroup python
+ */
+static PyObject * rpmtransAdd(rpmtransObject * s, PyObject * args) {
+ hdrObject * h;
+ PyObject * key;
+ char * how = NULL;
+ int isUpgrade = 0;
+ PyObject * hObj;
+
+ if (!PyArg_ParseTuple(args, "OO|s", &h, &key, &how)) return NULL;
+
+ hObj = (PyObject *) h;
+ if (hObj->ob_type != &hdrType) {
+ PyErr_SetString(PyExc_TypeError, "bad type for header argument");
+ return NULL;
+ }
+
+ if (how && strcmp(how, "a") && strcmp(how, "u") && strcmp(how, "i")) {
+ PyErr_SetString(PyExc_TypeError, "how argument must be \"u\", \"a\", or \"i\"");
+ return NULL;
+ } else if (how && !strcmp(how, "u"))
+ isUpgrade = 1;
+
+ if (how && !strcmp(how, "a"))
+ rpmtransAvailablePackage(s->ts, hdrGetHeader(h), key);
+ else
+ rpmtransAddPackage(s->ts, hdrGetHeader(h), key, isUpgrade, NULL);
+
+ /* This should increment the usage count for me */
+ if (key) {
+ PyList_Append(s->keyList, key);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * rpmtransRemove(rpmtransObject * s, PyObject * args) {
+ char * name;
+ int count;
+ rpmdbMatchIterator mi;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ /* XXX: Copied hack from ../lib/rpminstall.c, rpmErase() */
+ mi = rpmdbInitIterator(dbFromDb(s->dbo), RPMDBI_LABEL, name, 0);
+ count = rpmdbGetIteratorCount(mi);
+ if (count <= 0) {
+ PyErr_SetString(pyrpmError, "package not installed");
+ return NULL;
+ } else { /* XXX: Note that we automatically choose to remove all matches */
+ Header h;
+ while ((h = rpmdbNextIterator(mi)) != NULL) {
+ unsigned int recOffset = rpmdbGetIteratorOffset(mi);
+ if (recOffset) {
+ rpmtransRemovePackage(s->ts, h, recOffset);
+ }
+ }
+ }
+ rpmdbFreeIterator(mi);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * rpmtransDepCheck(rpmtransObject * s, PyObject * args) {
+ rpmProblem conflicts, c;
+ int numConflicts;
+ PyObject * list, * cf;
+ int i;
+ int allSuggestions = 0;
+
+ if (!PyArg_ParseTuple(args, "|i", &allSuggestions)) return NULL;
+
+ rpmdepCheck(s->ts, &conflicts, &numConflicts);
+ if (numConflicts) {
+ list = PyList_New(0);
+
+ /* XXX TODO: rpmlib >= 4.0.3 can return multiple suggested keys. */
+ for (i = 0; i < numConflicts; i++) {
+#ifdef DYING
+ cf = Py_BuildValue("((sss)(ss)iOi)", conflicts[i].byName,
+ conflicts[i].byVersion, conflicts[i].byRelease,
+
+ conflicts[i].needsName,
+ conflicts[i].needsVersion,
+
+ conflicts[i].needsFlags,
+ conflicts[i].suggestedPkgs ?
+ conflicts[i].suggestedPkgs[0] : Py_None,
+ conflicts[i].sense);
+#else
+ char * byName, * byVersion, * byRelease;
+ char * needsName, * needsOP, * needsVersion;
+ int needsFlags, sense;
+ fnpyKey key;
+
+ c = conflicts + i;
+
+ byName = c->pkgNEVR;
+ if ((byRelease = strrchr(byName, '-')) != NULL)
+ *byRelease++ = '\0';
+ if ((byVersion = strrchr(byName, '-')) != NULL)
+ *byVersion++ = '\0';
+
+ key = c->key;
+
+ needsName = c->altNEVR;
+ if (needsName[1] == ' ') {
+ sense = (needsName[0] == 'C')
+ ? RPMDEP_SENSE_CONFLICTS : RPMDEP_SENSE_REQUIRES;
+ needsName += 2;
+ } else
+ sense = RPMDEP_SENSE_REQUIRES;
+ if ((needsVersion = strrchr(needsName, ' ')) != NULL)
+ *needsVersion++ = '\0';
+
+ needsFlags = 0;
+ if ((needsOP = strrchr(needsName, ' ')) != NULL) {
+ for (*needsOP++ = '\0'; *needsOP != '\0'; needsOP++) {
+ if (*needsOP == '<') needsFlags |= RPMSENSE_LESS;
+ else if (*needsOP == '>') needsFlags |= RPMSENSE_GREATER;
+ else if (*needsOP == '=') needsFlags |= RPMSENSE_EQUAL;
+ }
+ }
+
+ cf = Py_BuildValue("((sss)(ss)iOi)", byName, byVersion, byRelease,
+ needsName, needsVersion, needsFlags,
+ (key != NULL ? key : Py_None),
+ sense);
+#endif
+ PyList_Append(list, (PyObject *) cf);
+ Py_DECREF(cf);
+ }
+
+ conflicts = rpmdepFreeConflicts(conflicts, numConflicts);
+
+ return list;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * rpmtransOrder(rpmtransObject * s, PyObject * args) {
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+
+ rpmdepOrder(s->ts);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** \ingroup python
+ */
+static PyObject * py_rpmtransGetKeys(rpmtransObject * s, PyObject * args) {
+ const void **data = NULL;
+ int num, i;
+ PyObject *tuple;
+
+ rpmtransGetKeys(s->ts, &data, &num);
+ if (data == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ tuple = PyTuple_New(num);
+
+ for (i = 0; i < num; i++) {
+ PyObject *obj = (PyObject *) data[i];
+ Py_INCREF(obj);
+ PyTuple_SetItem(tuple, i, obj);
+ }
+
+ free (data);
+
+ return tuple;
+}
+
+/** \ingroup python
+ */
+struct tsCallbackType {
+ PyObject * cb;
+ PyObject * data;
+ int pythonError;
+};
+
+/** \ingroup python
+ * @todo Remove, there's no headerLink refcount on the pointer.
+ */
+static Header transactionSetHeader = NULL;
+
+/** \ingroup python
+ */
+static void * tsCallback(const void * hd, const rpmCallbackType what,
+ const unsigned long amount, const unsigned long total,
+ const void * pkgKey, rpmCallbackData data) {
+ struct tsCallbackType * cbInfo = data;
+ PyObject * args, * result;
+ int fd;
+ static FD_t fdt;
+ const Header h = (Header) hd;
+
+ if (cbInfo->pythonError) return NULL;
+ if (cbInfo->cb == Py_None) return NULL;
+
+ if (!pkgKey) pkgKey = Py_None;
+ transactionSetHeader = h;
+
+ args = Py_BuildValue("(illOO)", what, amount, total, pkgKey, cbInfo->data);
+ result = PyEval_CallObject(cbInfo->cb, args);
+ Py_DECREF(args);
+
+ if (!result) {
+ cbInfo->pythonError = 1;
+ return NULL;
+ }
+
+ if (what == RPMCALLBACK_INST_OPEN_FILE) {
+ if (!PyArg_Parse(result, "i", &fd)) {
+ cbInfo->pythonError = 1;
+ return NULL;
+ }
+ fdt = fdDup(fd);
+
+ Py_DECREF(result);
+ return fdt;
+ }
+
+ if (what == RPMCALLBACK_INST_CLOSE_FILE) {
+ Fclose (fdt);
+ }
+
+ Py_DECREF(result);
+
+ return NULL;
+}
+
+/** \ingroup python
+ */
+static PyObject * rpmtransRun(rpmtransObject * s, PyObject * args) {
+ int flags, ignoreSet;
+ int rc, i;
+ PyObject * list, * prob;
+ rpmProblemSet probs;
+ struct tsCallbackType cbInfo;
+
+ if (!PyArg_ParseTuple(args, "iiOO", &flags, &ignoreSet, &cbInfo.cb,
+ &cbInfo.data))
+ return NULL;
+
+ cbInfo.pythonError = 0;
+
+ (void) rpmtsSetNotifyCallback(s->ts, tsCallback, (void *) &cbInfo);
+ (void) rpmtsSetFlags(s->ts, flags);
+
+ rc = rpmRunTransactions(s->ts, NULL, &probs, ignoreSet);
+
+ if (cbInfo.pythonError) {
+ if (rc > 0)
+ rpmProblemSetFree(probs);
+ return NULL;
+ }
+
+ if (rc < 0) {
+ list = PyList_New(0);
+ return list;
+ } else if (!rc) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ list = PyList_New(0);
+ for (i = 0; i < probs->numProblems; i++) {
+ rpmProblem myprob = probs->probs + i;
+ prob = Py_BuildValue("s(isN)", rpmProblemString(myprob),
+ myprob->type,
+ myprob->str1,
+ PyLong_FromLongLong(myprob->ulong1));
+ PyList_Append(list, prob);
+ Py_DECREF(prob);
+ }
+
+ rpmProblemSetFree(probs);
+
+ return list;
+}
+
+/** \ingroup python
+ */
+static struct PyMethodDef rpmtransMethods[] = {
+ {"add", (PyCFunction) rpmtransAdd, 1 },
+ {"remove", (PyCFunction) rpmtransRemove, 1 },
+ {"depcheck", (PyCFunction) rpmtransDepCheck, 1 },
+ {"order", (PyCFunction) rpmtransOrder, 1 },
+ {"getKeys", (PyCFunction) py_rpmtransGetKeys, 1 },
+ {"run", (PyCFunction) rpmtransRun, 1 },
+ {NULL, NULL} /* sentinel */
+};
+
+/** \ingroup python
+ */
+static PyObject * rpmtransGetAttr(rpmtransObject * o, char * name) {
+ return Py_FindMethod(rpmtransMethods, (PyObject *) o, name);
+}
+
+/** \ingroup python
+ */
+static void rpmtransDealloc(PyObject * o) {
+ rpmtransObject * trans = (void *) o;
+
+ trans->ts->rpmdb = NULL; /* XXX HACK: avoid rpmdb close/free */
+ rpmtransFree(trans->ts);
+ if (trans->dbo) {
+ Py_DECREF(trans->dbo);
+ }
+ if (trans->scriptFd) Fclose(trans->scriptFd);
+ /* this will free the keyList, and decrement the ref count of all
+ the items on the list as well :-) */
+ Py_DECREF(trans->keyList);
+ PyMem_DEL(o);
+}
+
+/** \ingroup python
+ */
+static int rpmtransSetAttr(rpmtransObject * o, char * name,
+ PyObject * val) {
+ int i;
+
+ if (!strcmp(name, "scriptFd")) {
+ if (!PyArg_Parse(val, "i", &i)) return 0;
+ if (i < 0) {
+ PyErr_SetString(PyExc_TypeError, "bad file descriptor");
+ return -1;
+ } else {
+ o->scriptFd = fdDup(i);
+ rpmtransSetScriptFd(o->ts, o->scriptFd);
+ }
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+ }
+
+ return 0;
+}
+
+/** \ingroup python
+ */
+static PyTypeObject rpmtransType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "rpmtrans", /* tp_name */
+ sizeof(rpmtransObject), /* tp_size */
+ 0, /* tp_itemsize */
+ (destructor) rpmtransDealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) rpmtransGetAttr, /* tp_getattr */
+ (setattrfunc) rpmtransSetAttr, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+};
+
+/*@}*/
+
+/** \ingroup python
+ * \name Module: rpm
+ */
+/*@{*/
+
+/**
+ */
+static PyObject * rpmtransCreate(PyObject * self, PyObject * args) {
+ rpmtransObject * o;
+ rpmdbObject * db = NULL;
+ char * rootPath = "/";
+
+ if (!PyArg_ParseTuple(args, "|sO", &rootPath, &db)) return NULL;
+ if (db && ((PyObject *) db)->ob_type != &rpmdbType) {
+ PyErr_SetString(PyExc_TypeError, "bad type for database argument");
+ return NULL;
+ }
+
+ o = (void *) PyObject_NEW(rpmtransObject, &rpmtransType);
+
+ Py_XINCREF(db);
+ o->dbo = db;
+ o->scriptFd = NULL;
+ o->ts = rpmtransCreateSet(NULL, rootPath);
+ o->ts->rpmdb = (db ? dbFromDb(db) : NULL);
+ o->keyList = PyList_New(0);
+
+ return (void *) o;
+}
+
+/**
+ */
+static PyObject * doAddMacro(PyObject * self, PyObject * args) {
+ char * name, * val;
+
+ if (!PyArg_ParseTuple(args, "ss", &name, &val))
+ return NULL;
+
+ addMacro(NULL, name, NULL, val, RMIL_DEFAULT);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/**
+ */
+static PyObject * doDelMacro(PyObject * self, PyObject * args) {
+ char * name;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ delMacro(NULL, name);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/**
+ */
+static PyObject * archScore(PyObject * self, PyObject * args) {
+ char * arch;
+ int score;
+
+ if (!PyArg_ParseTuple(args, "s", &arch))
+ return NULL;
+
+ score = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch);
+
+ return Py_BuildValue("i", score);
+}
+
+/**
+ */
+static int psGetArchScore(Header h) {
+ void * pkgArch;
+ int type, count;
+
+ if (!headerGetEntry(h, RPMTAG_ARCH, &type, (void **) &pkgArch, &count) ||
+ type == RPM_INT8_TYPE)
+ return 150;
+ else
+ return rpmMachineScore(RPM_MACHTABLE_INSTARCH, pkgArch);
+}
+
+/**
+ */
+static int pkgCompareVer(void * first, void * second) {
+ struct packageInfo ** a = first;
+ struct packageInfo ** b = second;
+ int ret, score1, score2;
+
+ /* put packages w/o names at the end */
+ if (!(*a)->name) return 1;
+ if (!(*b)->name) return -1;
+
+ ret = xstrcasecmp((*a)->name, (*b)->name);
+ if (ret) return ret;
+ score1 = psGetArchScore((*a)->h);
+ if (!score1) return 1;
+ score2 = psGetArchScore((*b)->h);
+ if (!score2) return -1;
+ if (score1 < score2) return -1;
+ if (score1 > score2) return 1;
+ return rpmVersionCompare((*b)->h, (*a)->h);
+}
+
+/**
+ */
+static void pkgSort(struct pkgSet * psp) {
+ int i;
+ char *name;
+
+ if (psp->numPackages <= 0)
+ return;
+
+ qsort(psp->packages, psp->numPackages, sizeof(*psp->packages),
+ (void *) pkgCompareVer);
+
+ name = psp->packages[0]->name;
+ if (!name) {
+ psp->numPackages = 0;
+ return;
+ }
+ for (i = 1; i < psp->numPackages; i++) {
+ if (!psp->packages[i]->name) break;
+ if (!strcmp(psp->packages[i]->name, name))
+ psp->packages[i]->name = NULL;
+ else
+ name = psp->packages[i]->name;
+ }
+
+ qsort(psp->packages, psp->numPackages, sizeof(*psp->packages),
+ (void *) pkgCompareVer);
+
+ for (i = 0; i < psp->numPackages; i++)
+ if (!psp->packages[i]->name) break;
+ psp->numPackages = i;
+}
+
+/**
+ */
+static PyObject * findUpgradeSet(PyObject * self, PyObject * args) {
+ PyObject * hdrList, * result;
+ char * root = "/";
+ int i;
+ struct pkgSet list;
+ hdrObject * hdr;
+
+ if (!PyArg_ParseTuple(args, "O|s", &hdrList, &root)) return NULL;
+
+ if (!PyList_Check(hdrList)) {
+ PyErr_SetString(PyExc_TypeError, "list of headers expected");
+ return NULL;
+ }
+
+ list.numPackages = PyList_Size(hdrList);
+ list.packages = alloca(sizeof(list.packages) * list.numPackages);
+ for (i = 0; i < list.numPackages; i++) {
+ hdr = (hdrObject *) PyList_GetItem(hdrList, i);
+ if (((PyObject *) hdr)->ob_type != &hdrType) {
+ PyErr_SetString(PyExc_TypeError, "list of headers expected");
+ return NULL;
+ }
+ list.packages[i] = alloca(sizeof(struct packageInfo));
+ list.packages[i]->h = hdrGetHeader(hdr);
+ list.packages[i]->selected = 0;
+ list.packages[i]->data = hdr;
+
+ headerGetEntry(list.packages[i]->h, RPMTAG_NAME, NULL,
+ (void **) &list.packages[i]->name, NULL);
+ }
+
+ pkgSort (&list);
+
+ if (ugFindUpgradePackages(&list, root)) {
+ PyErr_SetString(pyrpmError, "error during upgrade check");
+ return NULL;
+ }
+
+ result = PyList_New(0);
+ for (i = 0; i < list.numPackages; i++) {
+ if (list.packages[i]->selected) {
+ PyList_Append(result, list.packages[i]->data);
+/* Py_DECREF(list.packages[i]->data); */
+ }
+ }
+
+ return result;
+}
+
+/**
+ */
+static PyObject * rpmInitDB(PyObject * self, PyObject * args) {
+ char *root;
+ int forWrite = 0;
+
+ if (!PyArg_ParseTuple(args, "i|s", &forWrite, &root)) return NULL;
+
+ if (rpmdbInit(root, forWrite ? O_RDWR | O_CREAT: O_RDONLY)) {
+ char * errmsg = "cannot initialize database in %s";
+ char * errstr = NULL;
+ int errsize;
+
+ errsize = strlen(errmsg) + strlen(root);
+ errstr = alloca(errsize);
+ snprintf(errstr, errsize, errmsg, root);
+ PyErr_SetString(pyrpmError, errstr);
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return(Py_None);
+}
+
+/**
+ */
+static PyObject * errorCB = NULL, * errorData = NULL;
+
+/**
+ */
+static void errorcb (void)
+{
+ PyObject * result, * args = NULL;
+
+ if (errorData)
+ args = Py_BuildValue("(O)", errorData);
+
+ result = PyEval_CallObject(errorCB, args);
+ Py_XDECREF(args);
+
+ if (result == NULL) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ Py_DECREF (result);
+}
+
+/**
+ */
+static PyObject * errorSetCallback (PyObject * self, PyObject * args) {
+ PyObject *newCB = NULL, *newData = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|O", &newCB, &newData)) return NULL;
+
+ /* if we're getting a void*, set the error callback to this. */
+ /* also, we can possibly decref any python callbacks we had */
+ /* and set them to NULL. */
+ if (PyCObject_Check (newCB)) {
+ rpmErrorSetCallback (PyCObject_AsVoidPtr(newCB));
+
+ Py_XDECREF (errorCB);
+ Py_XDECREF (errorData);
+
+ errorCB = NULL;
+ errorData = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (!PyCallable_Check (newCB)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+ return NULL;
+ }
+
+ Py_XDECREF(errorCB);
+ Py_XDECREF(errorData);
+
+ errorCB = newCB;
+ errorData = newData;
+
+ Py_INCREF (errorCB);
+ Py_XINCREF (errorData);
+
+ return PyCObject_FromVoidPtr(rpmErrorSetCallback (errorcb), NULL);
+}
+
+/**
+ */
+static PyObject * errorString (PyObject * self, PyObject * args) {
+ return PyString_FromString(rpmErrorString ());
+}
+
+/**
+ */
+static PyObject * checkSig (PyObject * self, PyObject * args) {
+ char * filename;
+ int flags;
+ int rc = 255;
+
+ if (PyArg_ParseTuple(args, "si", &filename, &flags)) {
+ rpmTransactionSet ts;
+ const char * av[2];
+ QVA_t ka = memset(alloca(sizeof(*ka)), 0, sizeof(*ka));
+
+ av[0] = filename;
+ av[1] = NULL;
+ ka->qva_mode = 'K';
+ ka->qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
+ ka->sign = 0;
+ ka->passPhrase = NULL;
+ ts = rpmtransCreateSet(NULL, NULL);
+ rc = rpmcliSign(ts, ka, av);
+ rpmtransFree(ts);
+ }
+ return Py_BuildValue("i", rc);
+}
+
+/* hack to get the current header that's in the transaction set */
+/**
+ */
+static PyObject * getTsHeader (PyObject * self, PyObject * args) {
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ if (transactionSetHeader) {
+ return (PyObject *) createHeaderObject(transactionSetHeader);
+ }
+ Py_INCREF(Py_None);
+ return (PyObject *) Py_None;
+}
+
+static PyObject * setVerbosity (PyObject * self, PyObject * args) {
+ int level;
+
+ if (!PyArg_ParseTuple(args, "i", &level))
+ return NULL;
+
+ rpmSetVerbosity(level);
+
+ Py_INCREF(Py_None);
+ return (PyObject *) Py_None;
+}
+
+/**
+ */
+typedef struct FDlist_t FDlist;
+
+/**
+ */
+struct FDlist_t {
+ FILE *f;
+ FD_t fd;
+ char *note;
+ FDlist *next;
+} ;
+
+/**
+ */
+static FDlist *fdhead = NULL;
+
+/**
+ */
+static FDlist *fdtail = NULL;
+
+/**
+ */
+static int closeCallback(FILE * f) {
+ FDlist *node, *last;
+
+ printf ("close callback on %p\n", f);
+
+ node = fdhead;
+ last = NULL;
+ while (node) {
+ if (node->f == f)
+ break;
+ last = node;
+ node = node->next;
+ }
+ if (node) {
+ if (last)
+ last->next = node->next;
+ else
+ fdhead = node->next;
+ printf ("closing %s %p\n", node->note, node->fd);
+ free (node->note);
+ node->fd = fdLink(node->fd, "closeCallback");
+ Fclose (node->fd);
+ while (node->fd)
+ node->fd = fdFree(node->fd, "closeCallback");
+ free (node);
+ }
+ return 0;
+}
+
+/**
+ */
+static PyObject * doFopen(PyObject * self, PyObject * args) {
+ char * path, * mode;
+ FDlist *node;
+
+ if (!PyArg_ParseTuple(args, "ss", &path, &mode))
+ return NULL;
+
+ node = malloc (sizeof(FDlist));
+
+ node->fd = Fopen(path, mode);
+ node->fd = fdLink(node->fd, "doFopen");
+ node->note = strdup (path);
+
+ if (!node->fd) {
+ PyErr_SetFromErrno(pyrpmError);
+ free (node);
+ return NULL;
+ }
+
+ if (Ferror(node->fd)) {
+ const char *err = Fstrerror(node->fd);
+ free(node);
+ if (err) {
+ PyErr_SetString(pyrpmError, err);
+ return NULL;
+ }
+ }
+ node->f = fdGetFp(node->fd);
+ printf ("opening %s fd = %p f = %p\n", node->note, node->fd, node->f);
+ if (!node->f) {
+ PyErr_SetString(pyrpmError, "FD_t has no FILE*");
+ free(node);
+ return NULL;
+ }
+
+ node->next = NULL;
+ if (!fdhead) {
+ fdhead = fdtail = node;
+ } else if (fdtail) {
+ fdtail->next = node;
+ } else {
+ fdhead = node;
+ }
+ fdtail = node;
+
+ return PyFile_FromFile (node->f, path, mode, closeCallback);
+}
+
+/**
+ */
+static PyMethodDef rpmModuleMethods[] = {
+ { "TransactionSet", (PyCFunction) rpmtransCreate, METH_VARARGS, NULL },
+ { "addMacro", (PyCFunction) doAddMacro, METH_VARARGS, NULL },
+ { "delMacro", (PyCFunction) doDelMacro, METH_VARARGS, NULL },
+ { "archscore", (PyCFunction) archScore, METH_VARARGS, NULL },
+ { "findUpgradeSet", (PyCFunction) findUpgradeSet, METH_VARARGS, NULL },
+ { "headerFromPackage", (PyCFunction) rpmHeaderFromPackage, METH_VARARGS, NULL },
+ { "headerLoad", (PyCFunction) hdrLoad, METH_VARARGS, NULL },
+ { "rhnLoad", (PyCFunction) rhnLoad, METH_VARARGS, NULL },
+ { "initdb", (PyCFunction) rpmInitDB, METH_VARARGS, NULL },
+ { "opendb", (PyCFunction) rpmOpenDB, METH_VARARGS, NULL },
+ { "rebuilddb", (PyCFunction) rebuildDB, METH_VARARGS, NULL },
+ { "mergeHeaderListFromFD", (PyCFunction) rpmMergeHeadersFromFD, METH_VARARGS, NULL },
+ { "readHeaderListFromFD", (PyCFunction) rpmHeaderFromFD, METH_VARARGS, NULL },
+ { "readHeaderListFromFile", (PyCFunction) rpmHeaderFromFile, METH_VARARGS, NULL },
+ { "errorSetCallback", (PyCFunction) errorSetCallback, METH_VARARGS, NULL },
+ { "errorString", (PyCFunction) errorString, METH_VARARGS, NULL },
+ { "versionCompare", (PyCFunction) versionCompare, METH_VARARGS, NULL },
+ { "labelCompare", (PyCFunction) labelCompare, METH_VARARGS, NULL },
+ { "checksig", (PyCFunction) checkSig, METH_VARARGS, NULL },
+ { "getTransactionCallbackHeader", (PyCFunction) getTsHeader, METH_VARARGS, NULL },
+ { "Fopen", (PyCFunction) doFopen, METH_VARARGS, NULL },
+ { "setVerbosity", (PyCFunction) setVerbosity, METH_VARARGS, NULL },
+ { NULL }
+} ;
+
+/**
+ */
+void initrpm(void) {
+ PyObject * m, * d, *o, * tag = NULL, * dict;
+ int i;
+ const struct headerSprintfExtension_s * extensions = rpmHeaderFormats;
+ struct headerSprintfExtension_s * ext;
+ m = Py_InitModule("rpm", rpmModuleMethods);
+
+ hdrType.ob_type = &PyType_Type;
+ rpmdbMIType.ob_type = &PyType_Type;
+ rpmdbType.ob_type = &PyType_Type;
+ rpmtransType.ob_type = &PyType_Type;
+
+ if(!m)
+ return;
+
+/* _rpmio_debug = -1; */
+ rpmReadConfigFiles(NULL, NULL);
+
+ d = PyModule_GetDict(m);
+
+ pyrpmError = PyString_FromString("rpm.error");
+ PyDict_SetItemString(d, "error", pyrpmError);
+ Py_DECREF(pyrpmError);
+
+ dict = PyDict_New();
+
+ for (i = 0; i < rpmTagTableSize; i++) {
+ tag = PyInt_FromLong(rpmTagTable[i].val);
+ PyDict_SetItemString(d, (char *) rpmTagTable[i].name, tag);
+ Py_DECREF(tag);
+ PyDict_SetItem(dict, tag, o=PyString_FromString(rpmTagTable[i].name + 7));
+ Py_DECREF(o);
+ }
+
+ while (extensions->name) {
+ if (extensions->type == HEADER_EXT_TAG) {
+ (const struct headerSprintfExtension *) ext = extensions;
+ PyDict_SetItemString(d, (char *) extensions->name, o=PyCObject_FromVoidPtr(ext, NULL));
+ Py_DECREF(o);
+ PyDict_SetItem(dict, tag, o=PyString_FromString(ext->name + 7));
+ Py_DECREF(o);
+ }
+ extensions++;
+ }
+
+ PyDict_SetItemString(d, "tagnames", dict);
+ Py_DECREF(dict);
+
+
+#define REGISTER_ENUM(val) \
+ PyDict_SetItemString(d, #val, o=PyInt_FromLong( val )); \
+ Py_DECREF(o);
+
+ REGISTER_ENUM(RPMFILE_STATE_NORMAL);
+ REGISTER_ENUM(RPMFILE_STATE_REPLACED);
+ REGISTER_ENUM(RPMFILE_STATE_NOTINSTALLED);
+ REGISTER_ENUM(RPMFILE_STATE_NETSHARED);
+
+ REGISTER_ENUM(RPMFILE_CONFIG);
+ REGISTER_ENUM(RPMFILE_DOC);
+ REGISTER_ENUM(RPMFILE_MISSINGOK);
+ REGISTER_ENUM(RPMFILE_NOREPLACE);
+ REGISTER_ENUM(RPMFILE_GHOST);
+ REGISTER_ENUM(RPMFILE_LICENSE);
+ REGISTER_ENUM(RPMFILE_README);
+
+ REGISTER_ENUM(RPMDEP_SENSE_REQUIRES);
+ REGISTER_ENUM(RPMDEP_SENSE_CONFLICTS);
+
+ REGISTER_ENUM(RPMSENSE_SERIAL);
+ REGISTER_ENUM(RPMSENSE_LESS);
+ REGISTER_ENUM(RPMSENSE_GREATER);
+ REGISTER_ENUM(RPMSENSE_EQUAL);
+ REGISTER_ENUM(RPMSENSE_PREREQ);
+ REGISTER_ENUM(RPMSENSE_INTERP);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_PRE);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_POST);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_PREUN);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_POSTUN);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_VERIFY);
+ REGISTER_ENUM(RPMSENSE_FIND_REQUIRES);
+ REGISTER_ENUM(RPMSENSE_FIND_PROVIDES);
+ REGISTER_ENUM(RPMSENSE_TRIGGERIN);
+ REGISTER_ENUM(RPMSENSE_TRIGGERUN);
+ REGISTER_ENUM(RPMSENSE_TRIGGERPOSTUN);
+ REGISTER_ENUM(RPMSENSE_MULTILIB);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_PREP);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_BUILD);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_INSTALL);
+ REGISTER_ENUM(RPMSENSE_SCRIPT_CLEAN);
+ REGISTER_ENUM(RPMSENSE_RPMLIB);
+ REGISTER_ENUM(RPMSENSE_TRIGGERPREIN);
+
+ REGISTER_ENUM(RPMTRANS_FLAG_TEST);
+ REGISTER_ENUM(RPMTRANS_FLAG_BUILD_PROBS);
+ REGISTER_ENUM(RPMTRANS_FLAG_NOSCRIPTS);
+ REGISTER_ENUM(RPMTRANS_FLAG_JUSTDB);
+ REGISTER_ENUM(RPMTRANS_FLAG_NOTRIGGERS);
+ REGISTER_ENUM(RPMTRANS_FLAG_NODOCS);
+ REGISTER_ENUM(RPMTRANS_FLAG_ALLFILES);
+ REGISTER_ENUM(RPMTRANS_FLAG_KEEPOBSOLETE);
+ REGISTER_ENUM(RPMTRANS_FLAG_MULTILIB);
+
+ REGISTER_ENUM(RPMPROB_FILTER_IGNOREOS);
+ REGISTER_ENUM(RPMPROB_FILTER_IGNOREARCH);
+ REGISTER_ENUM(RPMPROB_FILTER_REPLACEPKG);
+ REGISTER_ENUM(RPMPROB_FILTER_FORCERELOCATE);
+ REGISTER_ENUM(RPMPROB_FILTER_REPLACENEWFILES);
+ REGISTER_ENUM(RPMPROB_FILTER_REPLACEOLDFILES);
+ REGISTER_ENUM(RPMPROB_FILTER_OLDPACKAGE);
+ REGISTER_ENUM(RPMPROB_FILTER_DISKSPACE);
+ REGISTER_ENUM(RPMPROB_FILTER_DISKNODES);
+
+ REGISTER_ENUM(RPMCALLBACK_INST_PROGRESS);
+ REGISTER_ENUM(RPMCALLBACK_INST_START);
+ REGISTER_ENUM(RPMCALLBACK_INST_OPEN_FILE);
+ REGISTER_ENUM(RPMCALLBACK_INST_CLOSE_FILE);
+ REGISTER_ENUM(RPMCALLBACK_TRANS_PROGRESS);
+ REGISTER_ENUM(RPMCALLBACK_TRANS_START);
+ REGISTER_ENUM(RPMCALLBACK_TRANS_STOP);
+ REGISTER_ENUM(RPMCALLBACK_UNINST_PROGRESS);
+ REGISTER_ENUM(RPMCALLBACK_UNINST_START);
+ REGISTER_ENUM(RPMCALLBACK_UNINST_STOP);
+ REGISTER_ENUM(RPMCALLBACK_UNPACK_ERROR);
+ REGISTER_ENUM(RPMCALLBACK_CPIO_ERROR);
+
+ REGISTER_ENUM(RPMPROB_BADARCH);
+ REGISTER_ENUM(RPMPROB_BADOS);
+ REGISTER_ENUM(RPMPROB_PKG_INSTALLED);
+ REGISTER_ENUM(RPMPROB_BADRELOCATE);
+ REGISTER_ENUM(RPMPROB_REQUIRES);
+ REGISTER_ENUM(RPMPROB_CONFLICT);
+ REGISTER_ENUM(RPMPROB_NEW_FILE_CONFLICT);
+ REGISTER_ENUM(RPMPROB_FILE_CONFLICT);
+ REGISTER_ENUM(RPMPROB_OLDPACKAGE);
+ REGISTER_ENUM(RPMPROB_DISKSPACE);
+ REGISTER_ENUM(RPMPROB_DISKNODES);
+ REGISTER_ENUM(RPMPROB_BADPRETRANS);
+
+#ifdef DEAD
+ REGISTER_ENUM(CHECKSIG_PGP); /* XXX use VERIFY_SIGNATURE */
+ REGISTER_ENUM(CHECKSIG_GPG); /* XXX use VERIFY_SIGNATURE */
+ REGISTER_ENUM(CHECKSIG_MD5); /* XXX use VERIFY_DIGEST */
+#else
+ REGISTER_ENUM(VERIFY_DIGEST);
+ REGISTER_ENUM(VERIFY_SIGNATURE);
+#endif
+
+ REGISTER_ENUM(RPMLOG_EMERG);
+ REGISTER_ENUM(RPMLOG_ALERT);
+ REGISTER_ENUM(RPMLOG_CRIT);
+ REGISTER_ENUM(RPMLOG_ERR);
+ REGISTER_ENUM(RPMLOG_WARNING);
+ REGISTER_ENUM(RPMLOG_NOTICE);
+ REGISTER_ENUM(RPMLOG_INFO);
+ REGISTER_ENUM(RPMLOG_DEBUG);
+
+ REGISTER_ENUM(RPMMIRE_DEFAULT);
+ REGISTER_ENUM(RPMMIRE_STRCMP);
+ REGISTER_ENUM(RPMMIRE_REGEX);
+ REGISTER_ENUM(RPMMIRE_GLOB);
+
+}
+
+/*@}*/