public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Fabian Groffen" <grobian@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/, /
Date: Wed, 27 Mar 2019 10:55:53 +0000 (UTC)	[thread overview]
Message-ID: <1553684038.d0a8d231167adddb80a73849d3bc70edbfda3507.grobian@gentoo> (raw)

commit:     d0a8d231167adddb80a73849d3bc70edbfda3507
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 27 10:53:58 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Wed Mar 27 10:53:58 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=d0a8d231

build: compile applets as separate objects

Instead of including everything from a single file, compile each applet
separately.  This standardises things somewhat, and allows for parallel
compilation.

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 Makefile.am            |  20 +-
 Makefile.in            | 283 ++++++++++++++++++++++-
 TODO.md                |   5 +
 applets.h              |  90 +++++++-
 configure              | 108 ---------
 configure.ac           |   3 -
 libq/Makefile.am       |   2 +
 libq/Makefile.in       |  31 ++-
 libq/cache.h           |   2 +
 libq/contents.c        |  92 ++++++++
 libq/contents.h        |  29 +++
 libq/copy_file.c       |  18 ++
 libq/copy_file.h       |   3 +
 libq/human_readable.c  |  15 +-
 libq/md5_sha1_sum.h    |   3 +
 libq/scandirat.c       |   8 +
 libq/scandirat.h       |   1 +
 libq/vdb.c             |  77 +++++++
 libq/vdb.h             |   5 +
 libq/xarray.h          |   1 +
 qxpak.c => libq/xpak.c | 237 +++++++------------
 libq/xpak.h            |  31 +++
 libq/xregex.c          |  17 ++
 libq/xregex.h          |   1 +
 main.c                 | 604 +++----------------------------------------------
 main.h                 |  12 +-
 q.c                    |  43 +++-
 qatom.c                |  14 +-
 qcache.c               |  56 +++--
 qcheck.c               |  20 +-
 qdepends.c             |  18 +-
 qfile.c                |  20 +-
 qgrep.c                |  91 +++++---
 qlist.c                |  42 +++-
 qlop.c                 |  18 +-
 qmerge.c               |  54 ++++-
 qpkg.c                 |  94 +++++---
 qsearch.c              |  83 +++++--
 qsize.c                |  28 ++-
 qtbz2.c                |  89 +++-----
 qtegrity.c             |  16 +-
 quse.c                 |  66 +++---
 qxpak.c                | 374 ++++--------------------------
 43 files changed, 1383 insertions(+), 1441 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index bb1015c..a9eba56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,25 @@ postsyncddir = $(portagedir)/repo.postsync.d
 dist_postsyncd_SCRIPTS = repo.postsync/q-reinit
 
 bin_PROGRAMS = q
-q_SOURCES = main.c
+q_SOURCES = \
+	main.c \
+	q.c \
+	qatom.c \
+	qcache.c \
+	qcheck.c \
+	qdepends.c \
+	qfile.c \
+	qgrep.c \
+	qlist.c \
+	qlop.c \
+	qmerge.c \
+	qpkg.c \
+	qsearch.c \
+	qsize.c \
+	qtbz2.c \
+	qtegrity.c \
+	quse.c \
+	qxpak.c
 q_CPPFLAGS = \
 	-I$(top_srcdir)/libq \
 	-I$(top_builddir)/autotools/gnulib \

diff --git a/Makefile.in b/Makefile.in
index ee65a5d..a014d25 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -248,7 +248,12 @@ CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(postsyncddir)" \
 	"$(DESTDIR)$(man1dir)"
 PROGRAMS = $(bin_PROGRAMS)
-am_q_OBJECTS = q-main.$(OBJEXT)
+am_q_OBJECTS = q-main.$(OBJEXT) q-q.$(OBJEXT) q-qatom.$(OBJEXT) \
+	q-qcache.$(OBJEXT) q-qcheck.$(OBJEXT) q-qdepends.$(OBJEXT) \
+	q-qfile.$(OBJEXT) q-qgrep.$(OBJEXT) q-qlist.$(OBJEXT) \
+	q-qlop.$(OBJEXT) q-qmerge.$(OBJEXT) q-qpkg.$(OBJEXT) \
+	q-qsearch.$(OBJEXT) q-qsize.$(OBJEXT) q-qtbz2.$(OBJEXT) \
+	q-qtegrity.$(OBJEXT) q-quse.$(OBJEXT) q-qxpak.$(OBJEXT)
 q_OBJECTS = $(am_q_OBJECTS)
 am__DEPENDENCIES_1 =
 q_DEPENDENCIES = $(top_builddir)/libq/libq.la \
@@ -1542,7 +1547,26 @@ SUBDIRS = autotools/gnulib libq
 portagedir = $(sysconfdir)/portage
 postsyncddir = $(portagedir)/repo.postsync.d
 dist_postsyncd_SCRIPTS = repo.postsync/q-reinit
-q_SOURCES = main.c
+q_SOURCES = \
+	main.c \
+	q.c \
+	qatom.c \
+	qcache.c \
+	qcheck.c \
+	qdepends.c \
+	qfile.c \
+	qgrep.c \
+	qlist.c \
+	qlop.c \
+	qmerge.c \
+	qpkg.c \
+	qsearch.c \
+	qsize.c \
+	qtbz2.c \
+	qtegrity.c \
+	quse.c \
+	qxpak.c
+
 
 # @@@ GEN START @@@ #
 q_CPPFLAGS = -I$(top_srcdir)/libq -I$(top_builddir)/autotools/gnulib \
@@ -1831,6 +1855,23 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-q.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qatom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qcache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qdepends.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qgrep.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qlist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qlop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qmerge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qpkg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qsearch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qsize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qtbz2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qtegrity.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-quse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/q-qxpak.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1867,6 +1908,244 @@ q-main.obj: main.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
 
+q-q.o: q.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-q.o -MD -MP -MF $(DEPDIR)/q-q.Tpo -c -o q-q.o `test -f 'q.c' || echo '$(srcdir)/'`q.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-q.Tpo $(DEPDIR)/q-q.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='q.c' object='q-q.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-q.o `test -f 'q.c' || echo '$(srcdir)/'`q.c
+
+q-q.obj: q.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-q.obj -MD -MP -MF $(DEPDIR)/q-q.Tpo -c -o q-q.obj `if test -f 'q.c'; then $(CYGPATH_W) 'q.c'; else $(CYGPATH_W) '$(srcdir)/q.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-q.Tpo $(DEPDIR)/q-q.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='q.c' object='q-q.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-q.obj `if test -f 'q.c'; then $(CYGPATH_W) 'q.c'; else $(CYGPATH_W) '$(srcdir)/q.c'; fi`
+
+q-qatom.o: qatom.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qatom.o -MD -MP -MF $(DEPDIR)/q-qatom.Tpo -c -o q-qatom.o `test -f 'qatom.c' || echo '$(srcdir)/'`qatom.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qatom.Tpo $(DEPDIR)/q-qatom.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qatom.c' object='q-qatom.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qatom.o `test -f 'qatom.c' || echo '$(srcdir)/'`qatom.c
+
+q-qatom.obj: qatom.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qatom.obj -MD -MP -MF $(DEPDIR)/q-qatom.Tpo -c -o q-qatom.obj `if test -f 'qatom.c'; then $(CYGPATH_W) 'qatom.c'; else $(CYGPATH_W) '$(srcdir)/qatom.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qatom.Tpo $(DEPDIR)/q-qatom.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qatom.c' object='q-qatom.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qatom.obj `if test -f 'qatom.c'; then $(CYGPATH_W) 'qatom.c'; else $(CYGPATH_W) '$(srcdir)/qatom.c'; fi`
+
+q-qcache.o: qcache.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qcache.o -MD -MP -MF $(DEPDIR)/q-qcache.Tpo -c -o q-qcache.o `test -f 'qcache.c' || echo '$(srcdir)/'`qcache.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qcache.Tpo $(DEPDIR)/q-qcache.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qcache.c' object='q-qcache.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qcache.o `test -f 'qcache.c' || echo '$(srcdir)/'`qcache.c
+
+q-qcache.obj: qcache.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qcache.obj -MD -MP -MF $(DEPDIR)/q-qcache.Tpo -c -o q-qcache.obj `if test -f 'qcache.c'; then $(CYGPATH_W) 'qcache.c'; else $(CYGPATH_W) '$(srcdir)/qcache.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qcache.Tpo $(DEPDIR)/q-qcache.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qcache.c' object='q-qcache.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qcache.obj `if test -f 'qcache.c'; then $(CYGPATH_W) 'qcache.c'; else $(CYGPATH_W) '$(srcdir)/qcache.c'; fi`
+
+q-qcheck.o: qcheck.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qcheck.o -MD -MP -MF $(DEPDIR)/q-qcheck.Tpo -c -o q-qcheck.o `test -f 'qcheck.c' || echo '$(srcdir)/'`qcheck.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qcheck.Tpo $(DEPDIR)/q-qcheck.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qcheck.c' object='q-qcheck.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qcheck.o `test -f 'qcheck.c' || echo '$(srcdir)/'`qcheck.c
+
+q-qcheck.obj: qcheck.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qcheck.obj -MD -MP -MF $(DEPDIR)/q-qcheck.Tpo -c -o q-qcheck.obj `if test -f 'qcheck.c'; then $(CYGPATH_W) 'qcheck.c'; else $(CYGPATH_W) '$(srcdir)/qcheck.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qcheck.Tpo $(DEPDIR)/q-qcheck.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qcheck.c' object='q-qcheck.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qcheck.obj `if test -f 'qcheck.c'; then $(CYGPATH_W) 'qcheck.c'; else $(CYGPATH_W) '$(srcdir)/qcheck.c'; fi`
+
+q-qdepends.o: qdepends.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qdepends.o -MD -MP -MF $(DEPDIR)/q-qdepends.Tpo -c -o q-qdepends.o `test -f 'qdepends.c' || echo '$(srcdir)/'`qdepends.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qdepends.Tpo $(DEPDIR)/q-qdepends.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qdepends.c' object='q-qdepends.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qdepends.o `test -f 'qdepends.c' || echo '$(srcdir)/'`qdepends.c
+
+q-qdepends.obj: qdepends.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qdepends.obj -MD -MP -MF $(DEPDIR)/q-qdepends.Tpo -c -o q-qdepends.obj `if test -f 'qdepends.c'; then $(CYGPATH_W) 'qdepends.c'; else $(CYGPATH_W) '$(srcdir)/qdepends.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qdepends.Tpo $(DEPDIR)/q-qdepends.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qdepends.c' object='q-qdepends.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qdepends.obj `if test -f 'qdepends.c'; then $(CYGPATH_W) 'qdepends.c'; else $(CYGPATH_W) '$(srcdir)/qdepends.c'; fi`
+
+q-qfile.o: qfile.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qfile.o -MD -MP -MF $(DEPDIR)/q-qfile.Tpo -c -o q-qfile.o `test -f 'qfile.c' || echo '$(srcdir)/'`qfile.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qfile.Tpo $(DEPDIR)/q-qfile.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qfile.c' object='q-qfile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qfile.o `test -f 'qfile.c' || echo '$(srcdir)/'`qfile.c
+
+q-qfile.obj: qfile.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qfile.obj -MD -MP -MF $(DEPDIR)/q-qfile.Tpo -c -o q-qfile.obj `if test -f 'qfile.c'; then $(CYGPATH_W) 'qfile.c'; else $(CYGPATH_W) '$(srcdir)/qfile.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qfile.Tpo $(DEPDIR)/q-qfile.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qfile.c' object='q-qfile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qfile.obj `if test -f 'qfile.c'; then $(CYGPATH_W) 'qfile.c'; else $(CYGPATH_W) '$(srcdir)/qfile.c'; fi`
+
+q-qgrep.o: qgrep.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qgrep.o -MD -MP -MF $(DEPDIR)/q-qgrep.Tpo -c -o q-qgrep.o `test -f 'qgrep.c' || echo '$(srcdir)/'`qgrep.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qgrep.Tpo $(DEPDIR)/q-qgrep.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qgrep.c' object='q-qgrep.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qgrep.o `test -f 'qgrep.c' || echo '$(srcdir)/'`qgrep.c
+
+q-qgrep.obj: qgrep.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qgrep.obj -MD -MP -MF $(DEPDIR)/q-qgrep.Tpo -c -o q-qgrep.obj `if test -f 'qgrep.c'; then $(CYGPATH_W) 'qgrep.c'; else $(CYGPATH_W) '$(srcdir)/qgrep.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qgrep.Tpo $(DEPDIR)/q-qgrep.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qgrep.c' object='q-qgrep.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qgrep.obj `if test -f 'qgrep.c'; then $(CYGPATH_W) 'qgrep.c'; else $(CYGPATH_W) '$(srcdir)/qgrep.c'; fi`
+
+q-qlist.o: qlist.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qlist.o -MD -MP -MF $(DEPDIR)/q-qlist.Tpo -c -o q-qlist.o `test -f 'qlist.c' || echo '$(srcdir)/'`qlist.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qlist.Tpo $(DEPDIR)/q-qlist.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qlist.c' object='q-qlist.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qlist.o `test -f 'qlist.c' || echo '$(srcdir)/'`qlist.c
+
+q-qlist.obj: qlist.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qlist.obj -MD -MP -MF $(DEPDIR)/q-qlist.Tpo -c -o q-qlist.obj `if test -f 'qlist.c'; then $(CYGPATH_W) 'qlist.c'; else $(CYGPATH_W) '$(srcdir)/qlist.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qlist.Tpo $(DEPDIR)/q-qlist.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qlist.c' object='q-qlist.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qlist.obj `if test -f 'qlist.c'; then $(CYGPATH_W) 'qlist.c'; else $(CYGPATH_W) '$(srcdir)/qlist.c'; fi`
+
+q-qlop.o: qlop.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qlop.o -MD -MP -MF $(DEPDIR)/q-qlop.Tpo -c -o q-qlop.o `test -f 'qlop.c' || echo '$(srcdir)/'`qlop.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qlop.Tpo $(DEPDIR)/q-qlop.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qlop.c' object='q-qlop.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qlop.o `test -f 'qlop.c' || echo '$(srcdir)/'`qlop.c
+
+q-qlop.obj: qlop.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qlop.obj -MD -MP -MF $(DEPDIR)/q-qlop.Tpo -c -o q-qlop.obj `if test -f 'qlop.c'; then $(CYGPATH_W) 'qlop.c'; else $(CYGPATH_W) '$(srcdir)/qlop.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qlop.Tpo $(DEPDIR)/q-qlop.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qlop.c' object='q-qlop.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qlop.obj `if test -f 'qlop.c'; then $(CYGPATH_W) 'qlop.c'; else $(CYGPATH_W) '$(srcdir)/qlop.c'; fi`
+
+q-qmerge.o: qmerge.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qmerge.o -MD -MP -MF $(DEPDIR)/q-qmerge.Tpo -c -o q-qmerge.o `test -f 'qmerge.c' || echo '$(srcdir)/'`qmerge.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qmerge.Tpo $(DEPDIR)/q-qmerge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qmerge.c' object='q-qmerge.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qmerge.o `test -f 'qmerge.c' || echo '$(srcdir)/'`qmerge.c
+
+q-qmerge.obj: qmerge.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qmerge.obj -MD -MP -MF $(DEPDIR)/q-qmerge.Tpo -c -o q-qmerge.obj `if test -f 'qmerge.c'; then $(CYGPATH_W) 'qmerge.c'; else $(CYGPATH_W) '$(srcdir)/qmerge.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qmerge.Tpo $(DEPDIR)/q-qmerge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qmerge.c' object='q-qmerge.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qmerge.obj `if test -f 'qmerge.c'; then $(CYGPATH_W) 'qmerge.c'; else $(CYGPATH_W) '$(srcdir)/qmerge.c'; fi`
+
+q-qpkg.o: qpkg.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qpkg.o -MD -MP -MF $(DEPDIR)/q-qpkg.Tpo -c -o q-qpkg.o `test -f 'qpkg.c' || echo '$(srcdir)/'`qpkg.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qpkg.Tpo $(DEPDIR)/q-qpkg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qpkg.c' object='q-qpkg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qpkg.o `test -f 'qpkg.c' || echo '$(srcdir)/'`qpkg.c
+
+q-qpkg.obj: qpkg.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qpkg.obj -MD -MP -MF $(DEPDIR)/q-qpkg.Tpo -c -o q-qpkg.obj `if test -f 'qpkg.c'; then $(CYGPATH_W) 'qpkg.c'; else $(CYGPATH_W) '$(srcdir)/qpkg.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qpkg.Tpo $(DEPDIR)/q-qpkg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qpkg.c' object='q-qpkg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qpkg.obj `if test -f 'qpkg.c'; then $(CYGPATH_W) 'qpkg.c'; else $(CYGPATH_W) '$(srcdir)/qpkg.c'; fi`
+
+q-qsearch.o: qsearch.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qsearch.o -MD -MP -MF $(DEPDIR)/q-qsearch.Tpo -c -o q-qsearch.o `test -f 'qsearch.c' || echo '$(srcdir)/'`qsearch.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qsearch.Tpo $(DEPDIR)/q-qsearch.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qsearch.c' object='q-qsearch.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qsearch.o `test -f 'qsearch.c' || echo '$(srcdir)/'`qsearch.c
+
+q-qsearch.obj: qsearch.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qsearch.obj -MD -MP -MF $(DEPDIR)/q-qsearch.Tpo -c -o q-qsearch.obj `if test -f 'qsearch.c'; then $(CYGPATH_W) 'qsearch.c'; else $(CYGPATH_W) '$(srcdir)/qsearch.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qsearch.Tpo $(DEPDIR)/q-qsearch.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qsearch.c' object='q-qsearch.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qsearch.obj `if test -f 'qsearch.c'; then $(CYGPATH_W) 'qsearch.c'; else $(CYGPATH_W) '$(srcdir)/qsearch.c'; fi`
+
+q-qsize.o: qsize.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qsize.o -MD -MP -MF $(DEPDIR)/q-qsize.Tpo -c -o q-qsize.o `test -f 'qsize.c' || echo '$(srcdir)/'`qsize.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qsize.Tpo $(DEPDIR)/q-qsize.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qsize.c' object='q-qsize.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qsize.o `test -f 'qsize.c' || echo '$(srcdir)/'`qsize.c
+
+q-qsize.obj: qsize.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qsize.obj -MD -MP -MF $(DEPDIR)/q-qsize.Tpo -c -o q-qsize.obj `if test -f 'qsize.c'; then $(CYGPATH_W) 'qsize.c'; else $(CYGPATH_W) '$(srcdir)/qsize.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qsize.Tpo $(DEPDIR)/q-qsize.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qsize.c' object='q-qsize.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qsize.obj `if test -f 'qsize.c'; then $(CYGPATH_W) 'qsize.c'; else $(CYGPATH_W) '$(srcdir)/qsize.c'; fi`
+
+q-qtbz2.o: qtbz2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qtbz2.o -MD -MP -MF $(DEPDIR)/q-qtbz2.Tpo -c -o q-qtbz2.o `test -f 'qtbz2.c' || echo '$(srcdir)/'`qtbz2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qtbz2.Tpo $(DEPDIR)/q-qtbz2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qtbz2.c' object='q-qtbz2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qtbz2.o `test -f 'qtbz2.c' || echo '$(srcdir)/'`qtbz2.c
+
+q-qtbz2.obj: qtbz2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qtbz2.obj -MD -MP -MF $(DEPDIR)/q-qtbz2.Tpo -c -o q-qtbz2.obj `if test -f 'qtbz2.c'; then $(CYGPATH_W) 'qtbz2.c'; else $(CYGPATH_W) '$(srcdir)/qtbz2.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qtbz2.Tpo $(DEPDIR)/q-qtbz2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qtbz2.c' object='q-qtbz2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qtbz2.obj `if test -f 'qtbz2.c'; then $(CYGPATH_W) 'qtbz2.c'; else $(CYGPATH_W) '$(srcdir)/qtbz2.c'; fi`
+
+q-qtegrity.o: qtegrity.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qtegrity.o -MD -MP -MF $(DEPDIR)/q-qtegrity.Tpo -c -o q-qtegrity.o `test -f 'qtegrity.c' || echo '$(srcdir)/'`qtegrity.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qtegrity.Tpo $(DEPDIR)/q-qtegrity.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qtegrity.c' object='q-qtegrity.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qtegrity.o `test -f 'qtegrity.c' || echo '$(srcdir)/'`qtegrity.c
+
+q-qtegrity.obj: qtegrity.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qtegrity.obj -MD -MP -MF $(DEPDIR)/q-qtegrity.Tpo -c -o q-qtegrity.obj `if test -f 'qtegrity.c'; then $(CYGPATH_W) 'qtegrity.c'; else $(CYGPATH_W) '$(srcdir)/qtegrity.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qtegrity.Tpo $(DEPDIR)/q-qtegrity.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qtegrity.c' object='q-qtegrity.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qtegrity.obj `if test -f 'qtegrity.c'; then $(CYGPATH_W) 'qtegrity.c'; else $(CYGPATH_W) '$(srcdir)/qtegrity.c'; fi`
+
+q-quse.o: quse.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-quse.o -MD -MP -MF $(DEPDIR)/q-quse.Tpo -c -o q-quse.o `test -f 'quse.c' || echo '$(srcdir)/'`quse.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-quse.Tpo $(DEPDIR)/q-quse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='quse.c' object='q-quse.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-quse.o `test -f 'quse.c' || echo '$(srcdir)/'`quse.c
+
+q-quse.obj: quse.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-quse.obj -MD -MP -MF $(DEPDIR)/q-quse.Tpo -c -o q-quse.obj `if test -f 'quse.c'; then $(CYGPATH_W) 'quse.c'; else $(CYGPATH_W) '$(srcdir)/quse.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-quse.Tpo $(DEPDIR)/q-quse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='quse.c' object='q-quse.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-quse.obj `if test -f 'quse.c'; then $(CYGPATH_W) 'quse.c'; else $(CYGPATH_W) '$(srcdir)/quse.c'; fi`
+
+q-qxpak.o: qxpak.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qxpak.o -MD -MP -MF $(DEPDIR)/q-qxpak.Tpo -c -o q-qxpak.o `test -f 'qxpak.c' || echo '$(srcdir)/'`qxpak.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qxpak.Tpo $(DEPDIR)/q-qxpak.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qxpak.c' object='q-qxpak.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qxpak.o `test -f 'qxpak.c' || echo '$(srcdir)/'`qxpak.c
+
+q-qxpak.obj: qxpak.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT q-qxpak.obj -MD -MP -MF $(DEPDIR)/q-qxpak.Tpo -c -o q-qxpak.obj `if test -f 'qxpak.c'; then $(CYGPATH_W) 'qxpak.c'; else $(CYGPATH_W) '$(srcdir)/qxpak.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/q-qxpak.Tpo $(DEPDIR)/q-qxpak.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='qxpak.c' object='q-qxpak.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(q_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o q-qxpak.obj `if test -f 'qxpak.c'; then $(CYGPATH_W) 'qxpak.c'; else $(CYGPATH_W) '$(srcdir)/qxpak.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 

diff --git a/TODO.md b/TODO.md
index 6e813b8..5ebd9ea 100644
--- a/TODO.md
+++ b/TODO.md
@@ -49,6 +49,7 @@
 - support TTL field in binpkgs file
 - merge duplicate atoms on the CLI (`qmerge -Uq nano nano nano`)
 - unmerging should clean out @world set
+- test should work on local vdb (so TRAVIS can test it too)
 
 # qdepends
 
@@ -66,3 +67,7 @@
 # qsync
 
 - rewrite to use new repos.conf standard
+
+# qgrep
+
+- make it use standard xarray instead of its own buf\_list

diff --git a/applets.h b/applets.h
index 14b0154..e2d487c 100644
--- a/applets.h
+++ b/applets.h
@@ -1,13 +1,36 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
  */
 
-#ifndef _QAPPLETS_H_
-#define _QAPPLETS_H_
+#ifndef _APPLETS_H_
+#define _APPLETS_H_ 1
+
+#if defined(__sun) && defined(__SVR4)
+/* workaround non-const defined name in option struct, such that we
+ * don't get a zillion of warnings */
+#define	no_argument		0
+#define	required_argument	1
+#define	optional_argument	2
+struct option {
+	const char *name;
+	int has_arg;
+	int *flag;
+	int val;
+};
+extern int	getopt_long(int, char * const *, const char *,
+		    const struct option *, int *);
+#else
+# include <getopt.h>
+#endif
+
+#include <stdbool.h>
+#include <dirent.h>
+
+#include "xarray.h"
 
 /* applet prototypes */
 typedef int (*APPLET)(int, char **);
@@ -34,11 +57,6 @@ DECLARE_APPLET(qcache)
 DECLARE_APPLET(qtegrity)
 #undef DECLARE_APPLET
 
-#define DEFINE_APPLET_STUB(applet) \
-	int applet##_main(_q_unused_ int argc, _q_unused_ char **argv) { \
-		err("Sorry, this applet has been disabled"); \
-	}
-
 static const struct applet_t {
 	const char *name;
 	APPLET func;
@@ -92,4 +110,60 @@ static const struct applet_t {
 	{NULL, NULL, NULL, NULL}
 };
 
+/* Common usage for all applets */
+#define COMMON_FLAGS "vqChV"
+#define COMMON_LONG_OPTS \
+	{"root",       a_argument, NULL, 0x1}, \
+	{"verbose",   no_argument, NULL, 'v'}, \
+	{"quiet",     no_argument, NULL, 'q'}, \
+	{"nocolor",   no_argument, NULL, 'C'}, \
+	{"help",      no_argument, NULL, 'h'}, \
+	{"version",   no_argument, NULL, 'V'}, \
+	{NULL,        no_argument, NULL, 0x0}
+#define COMMON_OPTS_HELP \
+	"Set the ROOT env var", \
+	"Make a lot of noise", \
+	"Tighter output; suppress warnings", \
+	"Don't output color", \
+	"Print this help and exit", \
+	"Print version and exit", \
+	NULL
+#define COMMON_GETOPTS_CASES(applet) \
+	case 0x1: portroot = optarg; break; \
+	case 'v': ++verbose; break; \
+	case 'q': setup_quiet(); break; \
+	case 'V': version_barf(); break; \
+	case 'h': applet ## _usage(EXIT_SUCCESS); break; \
+	case 'C': no_colors(); break; \
+	default: applet ## _usage(EXIT_FAILURE); break;
+
+extern char *modpath;
+extern char *portroot;
+extern int verbose;
+extern int quiet;
+extern char pretend;
+extern char *config_protect;
+extern char *config_protect_mask;
+extern char *portvdb;
+extern char *portlogdir;
+extern int portcachedir_type;
+extern char *pkg_install_mask;
+extern char *binhost;
+extern char *pkgdir;
+extern char *port_tmpdir;
+extern char *features;
+extern char *install_mask;
+extern DEFINE_ARRAY(overlays);
+
+void no_colors(void);
+void setup_quiet(void);
+void version_barf(void);
+void usage(int status, const char *flags, struct option const opts[],
+      const char * const help[], const char *desc, int blabber);
+int lookup_applet_idx(const char *);
+APPLET lookup_applet(const char *applet);
+const char *initialize_flat(const char *overlay, int cache_type, bool force);
+void freeargv(int argc, char **argv);
+void makeargv(const char *string, int *argc, char ***argv);
+
 #endif

diff --git a/configure b/configure
index ce1fbde..e538b3e 100755
--- a/configure
+++ b/configure
@@ -34569,42 +34569,6 @@ else
 fi
 
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-missing-prototypes" >&5
-$as_echo_n "checking whether C compiler accepts -Wno-missing-prototypes... " >&6; }
-if ${ax_cv_check_cflags___Wno_missing_prototypes+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-  ax_check_save_flags=$CFLAGS
-  CFLAGS="$CFLAGS  -Wno-missing-prototypes"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ax_cv_check_cflags___Wno_missing_prototypes=yes
-else
-  ax_cv_check_cflags___Wno_missing_prototypes=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CFLAGS=$ax_check_save_flags
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_missing_prototypes" >&5
-$as_echo "$ax_cv_check_cflags___Wno_missing_prototypes" >&6; }
-if test "x$ax_cv_check_cflags___Wno_missing_prototypes" = xyes; then :
-  as_fn_append CFLAGS " -Wno-missing-prototypes"
-else
-  :
-fi
-
-
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wwrite-strings" >&5
 $as_echo_n "checking whether C compiler accepts -Wwrite-strings... " >&6; }
 if ${ax_cv_check_cflags___Wwrite_strings+:} false; then :
@@ -34857,42 +34821,6 @@ else
 fi
 
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-format-nonliteral" >&5
-$as_echo_n "checking whether C compiler accepts -Wno-format-nonliteral... " >&6; }
-if ${ax_cv_check_cflags___Wno_format_nonliteral+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-  ax_check_save_flags=$CFLAGS
-  CFLAGS="$CFLAGS  -Wno-format-nonliteral"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ax_cv_check_cflags___Wno_format_nonliteral=yes
-else
-  ax_cv_check_cflags___Wno_format_nonliteral=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CFLAGS=$ax_check_save_flags
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_format_nonliteral" >&5
-$as_echo "$ax_cv_check_cflags___Wno_format_nonliteral" >&6; }
-if test "x$ax_cv_check_cflags___Wno_format_nonliteral" = xyes; then :
-  as_fn_append CFLAGS " -Wno-format-nonliteral"
-else
-  :
-fi
-
-
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wsequence-point" >&5
 $as_echo_n "checking whether C compiler accepts -Wsequence-point... " >&6; }
 if ${ax_cv_check_cflags___Wsequence_point+:} false; then :
@@ -35001,42 +34929,6 @@ else
 fi
 
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-expansion-to-defined" >&5
-$as_echo_n "checking whether C compiler accepts -Wno-expansion-to-defined... " >&6; }
-if ${ax_cv_check_cflags___Wno_expansion_to_defined+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-  ax_check_save_flags=$CFLAGS
-  CFLAGS="$CFLAGS  -Wno-expansion-to-defined"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ax_cv_check_cflags___Wno_expansion_to_defined=yes
-else
-  ax_cv_check_cflags___Wno_expansion_to_defined=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CFLAGS=$ax_check_save_flags
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_expansion_to_defined" >&5
-$as_echo "$ax_cv_check_cflags___Wno_expansion_to_defined" >&6; }
-if test "x$ax_cv_check_cflags___Wno_expansion_to_defined" = xyes; then :
-  as_fn_append CFLAGS " -Wno-expansion-to-defined"
-else
-  :
-fi
-
-
 
 ac_config_files="$ac_config_files Makefile libq/Makefile autotools/gnulib/Makefile tests/atom_explode/Makefile tests/copy_file/Makefile tests/mkdir/Makefile tests/rmspace/Makefile"
 

diff --git a/configure.ac b/configure.ac
index 55346a8..c7f6e69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,7 +36,6 @@ m4_foreach_w([flag], [
 	-Wshadow
 	-Wformat=2
 	-Wmissing-declarations
-	-Wno-missing-prototypes
 	-Wwrite-strings
 	-Wbad-function-cast
 	-Wnested-externs
@@ -44,11 +43,9 @@ m4_foreach_w([flag], [
 	-Winline
 	-Wchar-subscripts
 	-Wcast-align
-	-Wno-format-nonliteral
 	-Wsequence-point
 	-Wold-style-definition
 	-Wextra
-	-Wno-expansion-to-defined
 ], [
 	AX_CHECK_COMPILE_FLAG(flag, AS_VAR_APPEND([CFLAGS], " flag"))
 ])

diff --git a/libq/Makefile.am b/libq/Makefile.am
index 26647ee..734a78f 100644
--- a/libq/Makefile.am
+++ b/libq/Makefile.am
@@ -5,6 +5,7 @@ QFILES = \
 	busybox.h \
 	cache.c cache.h \
 	colors.c colors.h \
+	contents.c contents.h \
 	copy_file.c copy_file.h \
 	eat_file.c eat_file.h \
 	hash_fd.c hash_fd.h \
@@ -22,6 +23,7 @@ QFILES = \
 	xasprintf.h \
 	xchdir.c xchdir.h \
 	xmkdir.c xmkdir.h \
+	xpak.c xpak.h \
 	xregex.c xregex.h \
 	xsystem.c xsystem.h \
 	$(NULL)

diff --git a/libq/Makefile.in b/libq/Makefile.in
index 6c529c2..ab7012f 100644
--- a/libq/Makefile.in
+++ b/libq/Makefile.in
@@ -242,12 +242,13 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libq_la_LIBADD =
 am__objects_1 = libq_la-atom.lo libq_la-basename.lo libq_la-cache.lo \
-	libq_la-colors.lo libq_la-copy_file.lo libq_la-eat_file.lo \
-	libq_la-hash_fd.lo libq_la-human_readable.lo \
-	libq_la-md5_sha1_sum.lo libq_la-prelink.lo libq_la-profile.lo \
-	libq_la-rmspace.lo libq_la-safe_io.lo libq_la-scandirat.lo \
-	libq_la-set.lo libq_la-vdb.lo libq_la-xarray.lo \
-	libq_la-xchdir.lo libq_la-xmkdir.lo libq_la-xregex.lo \
+	libq_la-colors.lo libq_la-contents.lo libq_la-copy_file.lo \
+	libq_la-eat_file.lo libq_la-hash_fd.lo \
+	libq_la-human_readable.lo libq_la-md5_sha1_sum.lo \
+	libq_la-prelink.lo libq_la-profile.lo libq_la-rmspace.lo \
+	libq_la-safe_io.lo libq_la-scandirat.lo libq_la-set.lo \
+	libq_la-vdb.lo libq_la-xarray.lo libq_la-xchdir.lo \
+	libq_la-xmkdir.lo libq_la-xpak.lo libq_la-xregex.lo \
 	libq_la-xsystem.lo
 am_libq_la_OBJECTS = $(am__objects_1)
 libq_la_OBJECTS = $(am_libq_la_OBJECTS)
@@ -1447,6 +1448,7 @@ QFILES = \
 	busybox.h \
 	cache.c cache.h \
 	colors.c colors.h \
+	contents.c contents.h \
 	copy_file.c copy_file.h \
 	eat_file.c eat_file.h \
 	hash_fd.c hash_fd.h \
@@ -1464,6 +1466,7 @@ QFILES = \
 	xasprintf.h \
 	xchdir.c xchdir.h \
 	xmkdir.c xmkdir.h \
+	xpak.c xpak.h \
 	xregex.c xregex.h \
 	xsystem.c xsystem.h \
 	$(NULL)
@@ -1532,6 +1535,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-basename.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-cache.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-colors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-contents.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-copy_file.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-eat_file.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-hash_fd.Plo@am__quote@
@@ -1547,6 +1551,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xarray.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xchdir.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xmkdir.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xpak.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xregex.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libq_la-xsystem.Plo@am__quote@
 
@@ -1599,6 +1604,13 @@ libq_la-colors.lo: colors.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-colors.lo `test -f 'colors.c' || echo '$(srcdir)/'`colors.c
 
+libq_la-contents.lo: contents.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-contents.lo -MD -MP -MF $(DEPDIR)/libq_la-contents.Tpo -c -o libq_la-contents.lo `test -f 'contents.c' || echo '$(srcdir)/'`contents.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-contents.Tpo $(DEPDIR)/libq_la-contents.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='contents.c' object='libq_la-contents.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-contents.lo `test -f 'contents.c' || echo '$(srcdir)/'`contents.c
+
 libq_la-copy_file.lo: copy_file.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-copy_file.lo -MD -MP -MF $(DEPDIR)/libq_la-copy_file.Tpo -c -o libq_la-copy_file.lo `test -f 'copy_file.c' || echo '$(srcdir)/'`copy_file.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-copy_file.Tpo $(DEPDIR)/libq_la-copy_file.Plo
@@ -1704,6 +1716,13 @@ libq_la-xmkdir.lo: xmkdir.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-xmkdir.lo `test -f 'xmkdir.c' || echo '$(srcdir)/'`xmkdir.c
 
+libq_la-xpak.lo: xpak.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-xpak.lo -MD -MP -MF $(DEPDIR)/libq_la-xpak.Tpo -c -o libq_la-xpak.lo `test -f 'xpak.c' || echo '$(srcdir)/'`xpak.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-xpak.Tpo $(DEPDIR)/libq_la-xpak.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='xpak.c' object='libq_la-xpak.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libq_la-xpak.lo `test -f 'xpak.c' || echo '$(srcdir)/'`xpak.c
+
 libq_la-xregex.lo: xregex.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libq_la-xregex.lo -MD -MP -MF $(DEPDIR)/libq_la-xregex.Tpo -c -o libq_la-xregex.lo `test -f 'xregex.c' || echo '$(srcdir)/'`xregex.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libq_la-xregex.Tpo $(DEPDIR)/libq_la-xregex.Plo

diff --git a/libq/cache.h b/libq/cache.h
index 971417c..93421df 100644
--- a/libq/cache.h
+++ b/libq/cache.h
@@ -10,6 +10,8 @@
 #ifndef _CACHE_H
 #define _CACHE_H 1
 
+#include "atom.h"
+
 typedef struct {
 	char *_data;
 	char *DEPEND;        /* line 1 */

diff --git a/libq/contents.c b/libq/contents.c
new file mode 100644
index 0000000..41929d0
--- /dev/null
+++ b/libq/contents.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2005-2019 Gentoo Foundation
+ * Distributed under the terms of the GNU General Public License v2
+ *
+ * Copyright 2005-2008 Ned Ludd        - <solar@gentoo.org>
+ * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
+ * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
+ */
+
+#include "main.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "contents.h"
+
+/*
+ * Parse a line of CONTENTS file and provide access to the individual fields
+ */
+contents_entry *
+contents_parse_line(char *line)
+{
+	static contents_entry e;
+	char *p;
+
+	if (!line || !*line || *line == '\n')
+		return NULL;
+
+	/* chop trailing newline */
+	if ((p = strrchr(line, '\n')) != NULL)
+		*p = '\0';
+
+	/* ferringb wants to break portage/vdb by using tabs vs spaces
+	 * so filenames can have lame ass spaces in them..
+	 * (I smell Windows near by)
+	 * Anyway we just convert that crap to a space so we can still
+	 * parse quickly */
+	p = line;
+	while ((p = strchr(p, '\t')) != NULL)
+		*p = ' ';
+
+	memset(&e, 0x00, sizeof(e));
+	e._data = line;
+
+	if (!strncmp(e._data, "obj ", 4))
+		e.type = CONTENTS_OBJ;
+	else if (!strncmp(e._data, "dir ", 4))
+		e.type = CONTENTS_DIR;
+	else if (!strncmp(e._data, "sym ", 4))
+		e.type = CONTENTS_SYM;
+	else
+		return NULL;
+
+	e.name = e._data + 4;
+
+	switch (e.type) {
+		/* dir /bin */
+		case CONTENTS_DIR:
+			break;
+
+		/* obj /bin/bash 62ed51c8b23866777552643ec57614b0 1120707577 */
+		case CONTENTS_OBJ:
+			if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
+				return NULL;
+			*e.mtime_str++ = '\0';
+			if ((e.digest = strrchr(e.name, ' ')) == NULL)
+				return NULL;
+			*e.digest++ = '\0';
+			break;
+
+		/* sym /bin/sh -> bash 1120707577 */
+		case CONTENTS_SYM:
+			if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
+				return NULL;
+			*e.mtime_str++ = '\0';
+			if ((e.sym_target = strstr(e.name, " -> ")) == NULL)
+				return NULL;
+			*e.sym_target = '\0';
+			e.sym_target += 4;
+			break;
+	}
+
+	if (e.mtime_str) {
+		e.mtime = strtol(e.mtime_str, NULL, 10);
+		if (e.mtime == LONG_MAX) {
+			e.mtime = 0;
+			e.mtime_str = NULL;
+		}
+	}
+
+	return &e;
+}

diff --git a/libq/contents.h b/libq/contents.h
new file mode 100644
index 0000000..c766827
--- /dev/null
+++ b/libq/contents.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2005-2019 Gentoo Foundation
+ * Distributed under the terms of the GNU General Public License v2
+ *
+ * Copyright 2005-2008 Ned Ludd        - <solar@gentoo.org>
+ * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
+ * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
+ */
+
+#ifndef _CONTENTS_H
+#define _CONTENTS_H 1
+
+typedef enum {
+	CONTENTS_DIR, CONTENTS_OBJ, CONTENTS_SYM
+} contents_type;
+
+typedef struct {
+	contents_type type;
+	char *_data;
+	char *name;
+	char *sym_target;
+	char *digest;
+	char *mtime_str;
+	long mtime;
+} contents_entry;
+
+contents_entry *contents_parse_line(char *line);
+
+#endif

diff --git a/libq/copy_file.c b/libq/copy_file.c
index e013442..e4619ce 100644
--- a/libq/copy_file.c
+++ b/libq/copy_file.c
@@ -26,3 +26,21 @@ int copy_file_fd(int fd_src, int fd_dst)
 			return -1;
 	}
 }
+
+int copy_file(FILE *src, FILE *dst)
+{
+	ssize_t rcnt, wcnt;
+	char buf[64 * 1024];
+
+	while (1) {
+		rcnt = fread(buf, 1, sizeof(buf), src);
+		if (rcnt < 0)
+			return -1;
+		else if (rcnt == 0)
+			return 0;
+
+		wcnt = fwrite(buf, 1, rcnt, dst);
+		if (wcnt == -1 || wcnt != rcnt)
+			return -1;
+	}
+}

diff --git a/libq/copy_file.h b/libq/copy_file.h
index 41da823..080c99e 100644
--- a/libq/copy_file.h
+++ b/libq/copy_file.h
@@ -8,6 +8,9 @@
 #ifndef _COPY_FILE_H
 #define _COPY_FILE_H 1
 
+#include <stdio.h>
+
 int copy_file_fd(int fd_src, int fd_dst);
+int copy_file(FILE *src, FILE *dst);
 
 #endif

diff --git a/libq/human_readable.c b/libq/human_readable.c
index 855ecef..5b8f7a3 100644
--- a/libq/human_readable.c
+++ b/libq/human_readable.c
@@ -38,14 +38,12 @@ make_human_readable_str(unsigned long long val,
 
 	unsigned frac; /* 0..9 - the fractional digit */
 	const char *u;
-	const char *fmt;
 
 	static char str[21];		/* Sufficient for 64 bit unsigned integers. */
 
 	if (val == 0)
 		return "0";
 
-	fmt = "%llu";
 	if (block_size > 1)
 		val *= block_size;
 	frac = 0;
@@ -55,11 +53,11 @@ make_human_readable_str(unsigned long long val,
 		val += display_unit/2;  /* Deal with rounding */
 		val /= display_unit;    /* Don't combine with the line above! */
 		/* will just print it as ulonglong (below) */
+		snprintf(str, sizeof(str), "%llu", val);
 	} else {
 		while ((val >= 1024)
 		 /* && (u < unit_chars + sizeof(unit_chars) - 1) - always true */
 		) {
-			fmt = "%llu.%u%c";
 			u++;
 			frac = (((unsigned)val % 1024) * 10 + 1024/2) / 1024;
 			val /= 1024;
@@ -68,19 +66,18 @@ make_human_readable_str(unsigned long long val,
 			++val;
 			frac = 0;
 		}
-#if 1
 		/* If block_size is 0, dont print fractional part */
 		if (block_size == 0) {
 			if (frac >= 5) {
 				++val;
 			}
-			fmt = "%llu%*c";
-			frac = 1;
+			snprintf(str, sizeof(str), "%llu%c", val, *u);
+		} else if (u == unit_chars) {
+			snprintf(str, sizeof(str), "%llu", val);
+		} else {
+			snprintf(str, sizeof(str), "%llu.%u%c", val, frac, *u);
 		}
-#endif
 	}
 
-	snprintf(str, sizeof(str), fmt, val, frac, *u);
-
 	return str;
 }

diff --git a/libq/md5_sha1_sum.h b/libq/md5_sha1_sum.h
index a4d7b1e..3c682a4 100644
--- a/libq/md5_sha1_sum.h
+++ b/libq/md5_sha1_sum.h
@@ -6,6 +6,9 @@
 #ifndef _MD5_SHA1_SUM_H
 #define _MD5_SHA1_SUM_H 1
 
+/* for HASH_MD5/HASH_SHA1 */
+#include "busybox.h"
+
 /* pass in a fd and get back a fd; filename is for display only */
 typedef int (*hash_cb_t) (int, const char *);
 

diff --git a/libq/scandirat.c b/libq/scandirat.c
index c98ce59..b3d0cfe 100644
--- a/libq/scandirat.c
+++ b/libq/scandirat.c
@@ -84,3 +84,11 @@ scandir_free(struct dirent **de, int cnt)
 		free(de[cnt]);
 	free(de);
 }
+
+int
+filter_hidden(const struct dirent *dentry)
+{
+	if (dentry->d_name[0] == '.')
+		return 0;
+	return 1;
+}

diff --git a/libq/scandirat.h b/libq/scandirat.h
index 10ff256..950cbb1 100644
--- a/libq/scandirat.h
+++ b/libq/scandirat.h
@@ -19,5 +19,6 @@ int scandirat(
 #endif
 
 void scandir_free(struct dirent **de, int cnt);
+int filter_hidden(const struct dirent *dentry);
 
 #endif

diff --git a/libq/vdb.c b/libq/vdb.c
index 9bf6d1d..974986c 100644
--- a/libq/vdb.c
+++ b/libq/vdb.c
@@ -10,6 +10,8 @@
 #include "rmspace.h"
 #include "scandirat.h"
 #include "eat_file.h"
+#include "set.h"
+#include "atom.h"
 #include "vdb.h"
 
 #include <ctype.h>
@@ -345,3 +347,78 @@ next_entry:
 
 	return ret;
 }
+
+set *
+get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv)
+{
+	q_vdb_ctx *ctx;
+
+	int cfd, j;
+	int dfd, i;
+
+	char buf[_Q_PATH_MAX];
+	char slot[_Q_PATH_MAX];
+	char *slotp = slot;
+	size_t slot_len;
+
+	struct dirent **cat;
+	struct dirent **pf;
+
+	depend_atom *atom = NULL;
+	set *cpf = NULL;
+
+	ctx = q_vdb_open(sroot, svdb);
+	if (!ctx)
+		return NULL;
+
+	/* scan the cat first */
+	cfd = scandirat(ctx->vdb_fd, ".", &cat, q_vdb_filter_cat, alphasort);
+	if (cfd < 0)
+		goto fuckit;
+
+	for (j = 0; j < cfd; j++) {
+		dfd = scandirat(ctx->vdb_fd, cat[j]->d_name,
+				&pf, q_vdb_filter_pkg, alphasort);
+		if (dfd < 0)
+			continue;
+		for (i = 0; i < dfd; i++) {
+			int blen = snprintf(buf, sizeof(buf), "%s/%s/SLOT",
+					cat[j]->d_name, pf[i]->d_name);
+			if (blen < 0 || (size_t)blen >= sizeof(buf)) {
+				warnf("unable to parse long package: %s/%s",
+						cat[j]->d_name, pf[i]->d_name);
+				continue;
+			}
+
+			/* Chop the SLOT for the atom parsing. */
+			buf[blen - 5] = '\0';
+			if ((atom = atom_explode(buf)) == NULL)
+				continue;
+			/* Restore the SLOT. */
+			buf[blen - 5] = '/';
+
+			slot_len = sizeof(slot);
+			eat_file_at(ctx->vdb_fd, buf, &slotp, &slot_len);
+			rmspace(slot);
+
+			if (fullcpv) {
+				if (atom->PR_int)
+					snprintf(buf, sizeof(buf), "%s/%s-%s-r%i",
+							atom->CATEGORY, atom->PN, atom->PV, atom->PR_int);
+				else
+					snprintf(buf, sizeof(buf), "%s/%s-%s",
+							atom->CATEGORY, atom->PN, atom->PV);
+			} else {
+				snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN);
+			}
+			atom_implode(atom);
+			cpf = add_set(buf, cpf);
+		}
+		scandir_free(pf, dfd);
+	}
+	scandir_free(cat, cfd);
+
+ fuckit:
+	q_vdb_close(ctx);
+	return cpf;
+}

diff --git a/libq/vdb.h b/libq/vdb.h
index b91d1d1..80c318c 100644
--- a/libq/vdb.h
+++ b/libq/vdb.h
@@ -6,6 +6,10 @@
 #ifndef _VDB_H
 #define _VDB_H 1
 
+#include <dirent.h>
+
+#include "set.h"
+
 /* VDB context */
 typedef struct {
 	int portroot_fd, vdb_fd;
@@ -56,5 +60,6 @@ int q_vdb_foreach_pkg(const char *sroot, const char *svdb,
 int q_vdb_foreach_pkg_sorted(const char *sroot, const char *svdb,
 		q_vdb_pkg_cb callback, void *priv);
 struct dirent *q_vdb_get_next_dir(DIR *dir);
+set *get_vdb_atoms(const char *sroot, const char *svdb, int fullcpv);
 
 #endif

diff --git a/libq/xarray.h b/libq/xarray.h
index 46cd772..22ee47a 100644
--- a/libq/xarray.h
+++ b/libq/xarray.h
@@ -33,6 +33,7 @@ typedef struct {
 #define array_init_decl { .eles = NULL, .num = 0, }
 #define array_cnt(arr) (arr)->num
 #define DECLARE_ARRAY(arr) array_t _##arr = array_init_decl, *arr = &_##arr
+#define DEFINE_ARRAY(arr) array_t *arr;
 #define xarraypush_str(arr, ele) xarraypush(arr, ele, strlen(ele) + 1 /*NUL*/)
 #define xarraypush_struct(arr, ele) xarraypush(arr, ele, sizeof(*(ele)))
 

diff --git a/qxpak.c b/libq/xpak.c
similarity index 57%
copy from qxpak.c
copy to libq/xpak.c
index bdd5294..09b58bd 100644
--- a/qxpak.c
+++ b/libq/xpak.c
@@ -1,12 +1,23 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
  */
 
-#ifdef APPLET_qxpak
+#include "main.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <xalloc.h>
+#include <assert.h>
+
+#include "basename.h"
+#include "copy_file.h"
+#include "safe_io.h"
+#include "scandirat.h"
+#include "xpak.h"
 
 /*
 # The format for a tbz2/xpak:
@@ -28,25 +39,6 @@
 #define XPAK_END_MSG         "XPAKSTOP"
 #define XPAK_END_MSG_LEN     8
 
-#define QXPAK_FLAGS "lxcd:O" COMMON_FLAGS
-static struct option const qxpak_long_opts[] = {
-	{"list",      no_argument, NULL, 'l'},
-	{"extract",   no_argument, NULL, 'x'},
-	{"create",    no_argument, NULL, 'c'},
-	{"dir",        a_argument, NULL, 'd'},
-	{"stdout",    no_argument, NULL, 'O'},
-	COMMON_LONG_OPTS
-};
-static const char * const qxpak_opts_help[] = {
-	"List the contents of an archive",
-	"Extract the contents of an archive",
-	"Create an archive of a directory/files",
-	"Change to specified directory",
-	"Write files to stdout",
-	COMMON_OPTS_HELP
-};
-#define qxpak_usage(ret) usage(ret, QXPAK_FLAGS, qxpak_long_opts, qxpak_opts_help, NULL, lookup_applet_idx("qxpak"))
-
 typedef struct {
 	int dir_fd;
 	FILE *fp;
@@ -55,18 +47,20 @@ typedef struct {
 	char *index, *data;
 } _xpak_archive;
 
-static char xpak_stdout;
-
 typedef void (*xpak_callback_t)(int,char*,int,int,int,char*);
 
-static void _xpak_walk_index(_xpak_archive *x, int argc, char **argv, xpak_callback_t func)
+static void _xpak_walk_index(
+		_xpak_archive *x,
+		int argc,
+		char **argv,
+		xpak_callback_t func)
 {
 	int i, pathname_len, data_offset, data_len;
 	char *p, pathname[100];
 
 	p = x->index;
 	while ((p - x->index) < x->index_len) {
-		pathname_len = tbz2_decode_int((unsigned char*)p);
+		pathname_len = READ_BE_INT32((unsigned char*)p);
 		assert((size_t)pathname_len < sizeof(pathname));
 		p += 4;
 		memcpy(pathname, p, pathname_len);
@@ -74,20 +68,22 @@ static void _xpak_walk_index(_xpak_archive *x, int argc, char **argv, xpak_callb
 		if (strchr(pathname, '/') != NULL || strchr(pathname, '\\') != NULL)
 			err("Index contains a file with a path: '%s'", pathname);
 		p += pathname_len;
-		data_offset = tbz2_decode_int((unsigned char*)p);
+		data_offset = READ_BE_INT32((unsigned char*)p);
 		p += 4;
-		data_len = tbz2_decode_int((unsigned char*)p);
+		data_len = READ_BE_INT32((unsigned char*)p);
 		p += 4;
 		if (argc) {
-			for (i = 0; i < argc; ++i)
+			for (i = 0; i < argc; ++i) {
 				if (argv[i] && !strcmp(pathname, argv[i])) {
 					argv[i] = NULL;
 					break;
 				}
+			}
 			if (i == argc)
 				continue;
 		}
-		(*func)(x->dir_fd, pathname, pathname_len, data_offset, data_len, x->data);
+		(*func)(x->dir_fd, pathname, pathname_len,
+				data_offset, data_len, x->data);
 	}
 
 	if (argc)
@@ -117,8 +113,8 @@ static _xpak_archive *_xpak_open(const char *file)
 	}
 
 	/* calc index and data sizes */
-	ret.index_len = tbz2_decode_int((unsigned char*)buf+XPAK_START_MSG_LEN);
-	ret.data_len = tbz2_decode_int((unsigned char*)buf+XPAK_START_MSG_LEN+4);
+	ret.index_len = READ_BE_INT32((unsigned char*)buf+XPAK_START_MSG_LEN);
+	ret.data_len = READ_BE_INT32((unsigned char*)buf+XPAK_START_MSG_LEN+4);
 	if (!ret.index_len || !ret.data_len) {
 		warn("Skipping empty archive '%s'", file);
 		goto close_and_ret;
@@ -137,20 +133,13 @@ static void _xpak_close(_xpak_archive *x)
 	fclose(x->fp);
 }
 
-static void
-_xpak_list_callback(_q_unused_ int dir_fd, char *pathname, _q_unused_ int pathname_len,
-                    int data_offset, int data_len, _q_unused_ char *data)
-{
-	if (!verbose)
-		puts(pathname);
-	else if (verbose == 1)
-		printf("%s: %i byte%c\n", pathname, data_len, (data_len>1?'s':' '));
-	else
-		printf("%s: %i byte%c @ offset byte %i\n",
-			pathname, data_len, (data_len>1?'s':' '), data_offset);
-}
-static int
-xpak_list(int dir_fd, const char *file, int argc, char **argv)
+int
+xpak_list(
+		int dir_fd,
+		const char *file,
+		int argc,
+		char **argv,
+		xpak_callback_t func)
 {
 	_xpak_archive *x;
 	char buf[BUFSIZE];
@@ -165,41 +154,20 @@ xpak_list(int dir_fd, const char *file, int argc, char **argv)
 	assert((size_t)x->index_len < sizeof(buf));
 	ret = fread(x->index, 1, x->index_len, x->fp);
 	assert(ret == (size_t)x->index_len);
-	_xpak_walk_index(x, argc, argv, &_xpak_list_callback);
+	_xpak_walk_index(x, argc, argv, func);
 
 	_xpak_close(x);
 
 	return 0;
 }
 
-static void
-_xpak_extract_callback(int dir_fd, char *pathname, _q_unused_ int pathname_len,
-                       int data_offset, int data_len, char *data)
-{
-	FILE *out;
-
-	if (verbose == 1)
-		puts(pathname);
-	else if (verbose > 1)
-		printf("%s: %i byte%c\n", pathname, data_len, (data_len>1?'s':' '));
-
-	if (!xpak_stdout) {
-		int fd = openat(dir_fd, pathname, O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC, 0644);
-		if (fd < 0)
-			return;
-		out = fdopen(fd, "w");
-		if (!out)
-			return;
-	} else
-		out = stdout;
-
-	fwrite(data + data_offset, 1, data_len, out);
-
-	if (!xpak_stdout)
-		fclose(out);
-}
-static int
-xpak_extract(int dir_fd, const char *file, int argc, char **argv)
+int
+xpak_extract(
+	int dir_fd,
+	const char *file,
+	int argc,
+	char **argv,
+	xpak_callback_t func)
 {
 	_xpak_archive *x;
 	char buf[BUFSIZE], ext[BUFSIZE*32];
@@ -215,7 +183,8 @@ xpak_extract(int dir_fd, const char *file, int argc, char **argv)
 	assert((size_t)x->index_len < sizeof(buf));
 	in = fread(x->index, 1, x->index_len, x->fp);
 	if ((int)in != x->index_len)
-		err("index chunk: read %i bytes, wanted %i bytes", (int)in, x->index_len);
+		err("index chunk: read %i bytes, wanted %i bytes",
+				(int)in, x->index_len);
 
 	/* the xpak may be large (like when it has CONTENTS) #300744 */
 	x->data = (size_t)x->data_len < sizeof(ext) ? ext : xmalloc(x->data_len);
@@ -223,7 +192,7 @@ xpak_extract(int dir_fd, const char *file, int argc, char **argv)
 	if ((int)in != x->data_len)
 		err("data chunk: read %i bytes, wanted %i bytes", (int)in, x->data_len);
 
-	_xpak_walk_index(x, argc, argv, &_xpak_extract_callback);
+	_xpak_walk_index(x, argc, argv, func);
 
 	_xpak_close(x);
 
@@ -234,20 +203,23 @@ xpak_extract(int dir_fd, const char *file, int argc, char **argv)
 }
 
 static void
-_xpak_add_file(int dir_fd, const char *filename, struct stat *st, FILE *findex,
-               int *index_len, FILE *fdata, int *data_len)
+_xpak_add_file(
+		int dir_fd,
+		const char *filename,
+		struct stat *st,
+		FILE *findex,
+		int *index_len,
+		FILE *fdata,
+		int *data_len,
+		int verbose)
 {
 	FILE *fin;
-	unsigned char *p;
+	unsigned char intbuf[4];
+	unsigned char *p = intbuf;
 	const char *basefile;
 	int fd, in_len;
 
-	if ((basefile = strrchr(filename, '/')) == NULL) {
-		basefile = filename;
-	} else {
-		++basefile;
-		assert(*basefile);
-	}
+	basefile = basename(filename);
 
 	if (verbose == 1)
 		printf("%s\n", basefile);
@@ -256,23 +228,24 @@ _xpak_add_file(int dir_fd, const char *filename, struct stat *st, FILE *findex,
 
 	/* write out the (pathname_len) */
 	in_len = strlen(basefile);
-	p = tbz2_encode_int(in_len);
+	WRITE_BE_INT32(p, in_len);
 	fwrite(p, 1, 4, findex);
 	/* write out the pathname */
 	fwrite(basefile, 1, in_len, findex);
 	/* write out the (data_offset) */
-	p = tbz2_encode_int(*data_len);
+	WRITE_BE_INT32(p, *data_len);
 	fwrite(p, 1, 4, findex);
 
 	*index_len += 4 + in_len + 4 + 4;
 
-	/* now open the file, get (data_len), and append the file to the data file */
+	/* now open the file, get (data_len),
+	 * and append the file to the data file */
 	fd = openat(dir_fd, filename, O_RDONLY|O_CLOEXEC);
 	if (fd < 0) {
  open_fail:
 		warnp("could not open for reading: %s", filename);
  fake_data_len:
-		p = tbz2_encode_int(0);
+		WRITE_BE_INT32(p, 0);
 		fwrite(p, 1, 4, findex);
 		return;
 	}
@@ -289,21 +262,29 @@ _xpak_add_file(int dir_fd, const char *filename, struct stat *st, FILE *findex,
 		fclose(fin);
 		goto fake_data_len;
 	}
-	p = tbz2_encode_int(in_len);
+	WRITE_BE_INT32(p, in_len);
 	fwrite(p, 1, 4, findex);
-	_tbz2_copy_file(fin, fdata);
+	copy_file(fin, fdata);
 	fclose(fin);
 
 	*data_len += in_len;
 }
-static int
-xpak_create(int dir_fd, const char *file, int argc, char **argv)
+
+int
+xpak_create(
+		int dir_fd,
+		const char *file,
+		int argc,
+		char **argv,
+		char append,
+		int verbose)
 {
 	FILE *findex, *fdata, *fout;
 	struct dirent **dir;
 	int i, fidx, numfiles;
 	struct stat st;
 	char path[_Q_PATH_MAX];
+	unsigned char intbuf[4];
 	unsigned char *p;
 	int index_len, data_len;
 
@@ -313,7 +294,7 @@ xpak_create(int dir_fd, const char *file, int argc, char **argv)
 	if (strlen(file) >= sizeof(path)-6)
 		err("Pathname is too long: %s", file);
 
-	if ((fout = fopen(file, "w")) == NULL) {
+	if ((fout = fopen(file, append ? "a" : "w")) == NULL) {
 		warnp("could not open output: %s", file);
 		return 1;
 	}
@@ -338,7 +319,8 @@ xpak_create(int dir_fd, const char *file, int argc, char **argv)
 			continue;
 		}
 		if (S_ISDIR(st.st_mode)) {
-			if ((numfiles = scandir(argv[i], &dir, filter_hidden, alphasort)) < 0)
+			if ((numfiles =
+						scandir(argv[i], &dir, filter_hidden, alphasort)) < 0)
 				warn("Directory '%s' is empty; skipping", argv[i]);
 			for (fidx = 0; fidx < numfiles; ++fidx) {
 				int ret = snprintf(path, sizeof(path), "%s/%s",
@@ -352,11 +334,13 @@ xpak_create(int dir_fd, const char *file, int argc, char **argv)
 					warnp("could not read %s", path);
 					continue;
 				}
-				_xpak_add_file(dir_fd, path, &st, findex, &index_len, fdata, &data_len);
+				_xpak_add_file(dir_fd, path, &st,
+						findex, &index_len, fdata, &data_len, verbose);
 			}
 			scandir_free(dir, numfiles);
 		} else if (S_ISREG(st.st_mode)) {
-			_xpak_add_file(dir_fd, argv[i], &st, findex, &index_len, fdata, &data_len);
+			_xpak_add_file(dir_fd, argv[i], &st,
+					findex, &index_len, fdata, &data_len, verbose);
 		} else
 			warn("Skipping non file/directory '%s'", argv[i]);
 	}
@@ -366,12 +350,13 @@ xpak_create(int dir_fd, const char *file, int argc, char **argv)
 
 	/* "XPAKPACK" + (index_len) + (data_len) + index + data + "XPAKSTOP" */
 	fwrite(XPAK_START_MSG, 1, XPAK_START_MSG_LEN, fout); /* "XPAKPACK" */
-	p = tbz2_encode_int(index_len);
+	p = intbuf;
+	WRITE_BE_INT32(p, index_len);
 	fwrite(p, 1, 4, fout);                               /* (index_len) */
-	p = tbz2_encode_int(data_len);
+	WRITE_BE_INT32(p, data_len);
 	fwrite(p, 1, 4, fout);                               /* (data_len) */
-	_tbz2_copy_file(findex, fout);                       /* index */
-	_tbz2_copy_file(fdata, fout);                        /* data */
+	copy_file(findex, fout);                       /* index */
+	copy_file(fdata, fout);                        /* data */
 	fwrite(XPAK_END_MSG, 1, XPAK_END_MSG_LEN, fout);     /* "XPAKSTOP" */
 
 	strcpy(path, file); strcat(path, ".index"); unlink(path);
@@ -382,53 +367,3 @@ xpak_create(int dir_fd, const char *file, int argc, char **argv)
 
 	return 0;
 }
-
-int qxpak_main(int argc, char **argv)
-{
-	enum { XPAK_ACT_NONE, XPAK_ACT_LIST, XPAK_ACT_EXTRACT, XPAK_ACT_CREATE };
-	int i, ret, dir_fd;
-	char *xpak;
-	char action = XPAK_ACT_NONE;
-
-	dir_fd = AT_FDCWD;
-	xpak_stdout = 0;
-
-	while ((i = GETOPT_LONG(QXPAK, qxpak, "")) != -1) {
-		switch (i) {
-		COMMON_GETOPTS_CASES(qxpak)
-		case 'l': action = XPAK_ACT_LIST; break;
-		case 'x': action = XPAK_ACT_EXTRACT; break;
-		case 'c': action = XPAK_ACT_CREATE; break;
-		case 'O': xpak_stdout = 1; break;
-		case 'd':
-			if (dir_fd != AT_FDCWD)
-				err("Only use -d once");
-			dir_fd = open(optarg, O_RDONLY|O_CLOEXEC|O_PATH);
-			if (dir_fd < 0)
-				errp("Could not open directory %s", optarg);
-			break;
-		}
-	}
-	if (optind == argc || action == XPAK_ACT_NONE)
-		qxpak_usage(EXIT_FAILURE);
-
-	xpak = argv[optind++];
-	argc -= optind;
-	argv += optind;
-
-	switch (action) {
-	case XPAK_ACT_LIST:    ret = xpak_list(dir_fd, xpak, argc, argv); break;
-	case XPAK_ACT_EXTRACT: ret = xpak_extract(dir_fd, xpak, argc, argv); break;
-	case XPAK_ACT_CREATE:  ret = xpak_create(dir_fd, xpak, argc, argv); break;
-	default: ret = EXIT_FAILURE;
-	}
-
-	if (dir_fd != AT_FDCWD)
-		close(dir_fd);
-
-	return ret;
-}
-
-#else
-DEFINE_APPLET_STUB(qxpak)
-#endif

diff --git a/libq/xpak.h b/libq/xpak.h
new file mode 100644
index 0000000..0b318b2
--- /dev/null
+++ b/libq/xpak.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005-2019 Gentoo Foundation
+ * Distributed under the terms of the GNU General Public License v2
+ */
+
+#ifndef _XPAK_H
+#define _XPAK_H 1
+
+typedef void (*xpak_callback_t)(int,char*,int,int,int,char*);
+
+int xpak_list(
+		int dir_fd,
+		const char *file,
+		int argc,
+		char **argv,
+		xpak_callback_t func);
+int xpak_extract(
+	int dir_fd,
+	const char *file,
+	int argc,
+	char **argv,
+	xpak_callback_t func);
+int xpak_create(
+		int dir_fd,
+		const char *file,
+		int argc,
+		char **argv,
+		char append,
+		int v);
+
+#endif

diff --git a/libq/xregex.c b/libq/xregex.c
index d299edd..3151254 100644
--- a/libq/xregex.c
+++ b/libq/xregex.c
@@ -26,3 +26,20 @@ void xregcomp(regex_t *preg, const char *regex, int cflags)
 	if (unlikely(wregcomp(preg, regex, cflags)))
 		exit(EXIT_FAILURE);
 }
+
+int
+rematch(const char *re, const char *match, int cflags)
+{
+	regex_t preg;
+	int ret;
+
+	if ((match == NULL) || (re == NULL))
+		return EXIT_FAILURE;
+
+	if (wregcomp(&preg, re, cflags))
+		return EXIT_FAILURE;
+	ret = regexec(&preg, match, 0, NULL, 0);
+	regfree(&preg);
+
+	return ret;
+}

diff --git a/libq/xregex.h b/libq/xregex.h
index fd75030..59fc51b 100644
--- a/libq/xregex.h
+++ b/libq/xregex.h
@@ -12,5 +12,6 @@
 
 int wregcomp(regex_t *preg, const char *regex, int cflags);
 void xregcomp(regex_t *preg, const char *regex, int cflags);
+int rematch(const char *, const char *, int);
 
 #endif

diff --git a/main.c b/main.c
index 01d358a..1da04fe 100644
--- a/main.c
+++ b/main.c
@@ -8,9 +8,19 @@
  */
 
 #include "main.h"
+#include "applets.h"
+
+#include <iniparser.h>
+#include <xalloc.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <limits.h>
+
 #include "atom.h"
 #include "basename.h"
 #include "busybox.h"
+#include "cache.h"
 #include "colors.h"
 #include "copy_file.h"
 #include "eat_file.h"
@@ -32,34 +42,6 @@
 #include "xregex.h"
 #include "xsystem.h"
 
-#include <iniparser.h>
-#include <xalloc.h>
-#include <assert.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include <limits.h>
-
-#if defined(__sun) && defined(__SVR4)
-/* workaround non-const defined name in option struct, such that we
- * don't get a zillion of warnings */
-#define	no_argument		0
-#define	required_argument	1
-#define	optional_argument	2
-struct option {
-	const char *name;
-	int has_arg;
-	int *flag;
-	int val;
-};
-extern int	getopt_long(int, char * const *, const char *,
-		    const struct option *, int *);
-#else
-# include <getopt.h>
-#endif
-
-/* prototypes and such */
-static int lookup_applet_idx(const char *);
-
 /* variables to control runtime behavior */
 char *module_name = NULL;
 char *modpath = NULL;
@@ -67,29 +49,26 @@ int verbose = 0;
 int quiet = 0;
 int portcachedir_type = 0;
 char pretend = 0;
-static int reinitialize = 0;
-static int reinitialize_metacache = 0;
-static char *portlogdir;
+char *portroot;
+char *config_protect;
+char *config_protect_mask;
+char *portvdb;
+char *portlogdir;
+char *pkg_install_mask;
+char *binhost;
+char *pkgdir;
+char *port_tmpdir;
+char *features;
+char *install_mask;
+DECLARE_ARRAY(overlays);
+
 static char *main_overlay;
 static char *portarch;
-static char *portvdb;
 static char *portedb;
 const char portcachedir_pms[] = "metadata/cache";
 const char portcachedir_md5[] = "metadata/md5-cache";
-static char *portroot;
 static char *eprefix;
-static char *config_protect, *config_protect_mask;
-
-static char *pkgdir;
-static char *port_tmpdir;
-
-static char *binhost;
-static char *features;
 static char *accept_license;
-static char *install_mask;
-static char *pkg_install_mask;
-
-const char err_noapplet[] = "Sorry this applet was disabled at compile time";
 
 /* helper functions for showing errors */
 const char *argv0;
@@ -108,9 +87,7 @@ init_coredumps(void)
 }
 #endif
 
-static DECLARE_ARRAY(overlays);
-
-static void
+void
 no_colors(void)
 {
 	BOLD = NORM = BLUE = DKBLUE = CYAN = GREEN = DKGREEN = \
@@ -118,7 +95,7 @@ no_colors(void)
 	setenv("NOCOLOR", "true", 1);
 }
 
-static void
+void
 setup_quiet(void)
 {
 	/* "e" for FD_CLOEXEC */
@@ -127,38 +104,8 @@ setup_quiet(void)
 	++quiet;
 }
 
-/* include common applet defs */
-#include "applets.h"
-
-/* Common usage for all applets */
-#define COMMON_FLAGS "vqChV"
-#define COMMON_LONG_OPTS \
-	{"root",       a_argument, NULL, 0x1}, \
-	{"verbose",   no_argument, NULL, 'v'}, \
-	{"quiet",     no_argument, NULL, 'q'}, \
-	{"nocolor",   no_argument, NULL, 'C'}, \
-	{"help",      no_argument, NULL, 'h'}, \
-	{"version",   no_argument, NULL, 'V'}, \
-	{NULL,        no_argument, NULL, 0x0}
-#define COMMON_OPTS_HELP \
-	"Set the ROOT env var", \
-	"Make a lot of noise", \
-	"Tighter output; suppress warnings", \
-	"Don't output color", \
-	"Print this help and exit", \
-	"Print version and exit", \
-	NULL
-#define COMMON_GETOPTS_CASES(applet) \
-	case 0x1: portroot = optarg; break; \
-	case 'v': ++verbose; break; \
-	case 'q': setup_quiet(); break; \
-	case 'V': version_barf(); break; \
-	case 'h': applet ## _usage(EXIT_SUCCESS); break; \
-	case 'C': no_colors(); break; \
-	default: applet ## _usage(EXIT_FAILURE); break;
-
 /* display usage and exit */
-static void
+void
 usage(int status, const char *flags, struct option const opts[],
       const char * const help[], const char *desc, int blabber)
 {
@@ -226,7 +173,7 @@ usage(int status, const char *flags, struct option const opts[],
 	exit(status);
 }
 
-static void
+void
 version_barf(void)
 {
 	const char *vcsid = "";
@@ -250,39 +197,7 @@ version_barf(void)
 	exit(EXIT_SUCCESS);
 }
 
-static bool
-prompt(const char *p)
-{
-	printf("%s? [Y/n] ", p);
-	fflush(stdout);
-	switch (getc(stdin)) {
-	case '\n':
-	case 'y':
-	case 'Y':
-		return true;
-	default:
-		return false;
-	}
-}
-
-int
-rematch(const char *re, const char *match, int cflags)
-{
-	regex_t preg;
-	int ret;
-
-	if ((match == NULL) || (re == NULL))
-		return EXIT_FAILURE;
-
-	if (wregcomp(&preg, re, cflags))
-		return EXIT_FAILURE;
-	ret = regexec(&preg, match, 0, NULL, 0);
-	regfree(&preg);
-
-	return ret;
-}
-
-static void
+void
 freeargv(int argc, char **argv)
 {
 	while (argc--)
@@ -290,7 +205,7 @@ freeargv(int argc, char **argv)
 	free(argv);
 }
 
-static void
+void
 makeargv(const char *string, int *argc, char ***argv)
 {
 	int curc = 2;
@@ -320,96 +235,6 @@ makeargv(const char *string, int *argc, char ***argv)
 	free(q);
 }
 
-/*
- * Parse a line of CONTENTS file and provide access to the individual fields
- */
-typedef enum {
-	CONTENTS_DIR, CONTENTS_OBJ, CONTENTS_SYM
-} contents_type;
-typedef struct {
-	contents_type type;
-	char *_data;
-	char *name;
-	char *sym_target;
-	char *digest;
-	char *mtime_str;
-	long mtime;
-} contents_entry;
-
-static contents_entry *
-contents_parse_line(char *line)
-{
-	static contents_entry e;
-	char *p;
-
-	if (!line || !*line || *line == '\n')
-		return NULL;
-
-	/* chop trailing newline */
-	if ((p = strrchr(line, '\n')) != NULL)
-		*p = '\0';
-
-	/* ferringb wants to break portage/vdb by using tabs vs spaces
-	 * so filenames can have lame ass spaces in them..
-	 * (I smell Windows near by)
-	 * Anyway we just convert that crap to a space so we can still
-	 * parse quickly */
-	p = line;
-	while ((p = strchr(p, '\t')) != NULL)
-		*p = ' ';
-
-	memset(&e, 0x00, sizeof(e));
-	e._data = line;
-
-	if (!strncmp(e._data, "obj ", 4))
-		e.type = CONTENTS_OBJ;
-	else if (!strncmp(e._data, "dir ", 4))
-		e.type = CONTENTS_DIR;
-	else if (!strncmp(e._data, "sym ", 4))
-		e.type = CONTENTS_SYM;
-	else
-		return NULL;
-
-	e.name = e._data + 4;
-
-	switch (e.type) {
-		/* dir /bin */
-		case CONTENTS_DIR:
-			break;
-
-		/* obj /bin/bash 62ed51c8b23866777552643ec57614b0 1120707577 */
-		case CONTENTS_OBJ:
-			if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
-				return NULL;
-			*e.mtime_str++ = '\0';
-			if ((e.digest = strrchr(e.name, ' ')) == NULL)
-				return NULL;
-			*e.digest++ = '\0';
-			break;
-
-		/* sym /bin/sh -> bash 1120707577 */
-		case CONTENTS_SYM:
-			if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
-				return NULL;
-			*e.mtime_str++ = '\0';
-			if ((e.sym_target = strstr(e.name, " -> ")) == NULL)
-				return NULL;
-			*e.sym_target = '\0';
-			e.sym_target += 4;
-			break;
-	}
-
-	if (e.mtime_str) {
-		e.mtime = strtol(e.mtime_str, NULL, 10);
-		if (e.mtime == LONG_MAX) {
-			e.mtime = 0;
-			e.mtime_str = NULL;
-		}
-	}
-
-	return &e;
-}
-
 /* Handle a single file in the repos.conf format. */
 static void
 read_one_repos_conf(const char *repos_conf)
@@ -958,22 +783,7 @@ initialize_portage_env(void)
 		color_remap();
 }
 
-enum {
-	CACHE_EBUILD = 1,
-	CACHE_METADATA = 2,
-	CACHE_METADATA_PMS = 10,
-	CACHE_METADATA_MD5 = 11,
-};
-
-static int
-filter_hidden(const struct dirent *dentry)
-{
-	if (dentry->d_name[0] == '.')
-		return 0;
-	return 1;
-}
-
-static const char *
+const char *
 initialize_flat(const char *overlay, int cache_type, bool force)
 {
 	struct dirent **category, **pn, **eb;
@@ -1109,357 +919,6 @@ ret:
 	return cache_file;
 }
 
-static void
-reinitialize_as_needed(void)
-{
-	size_t n;
-	const char *overlay, *ret = ret;
-
-	if (reinitialize)
-		array_for_each(overlays, n, overlay) {
-			ret = initialize_flat(overlay, CACHE_EBUILD, true);
-			if (USE_CLEANUP)
-				free((void *)ret);
-		}
-
-	if (reinitialize_metacache)
-		array_for_each(overlays, n, overlay) {
-			ret = initialize_flat(overlay, CACHE_METADATA, true);
-			if (USE_CLEANUP)
-				free((void *)ret);
-		}
-}
-
-typedef struct {
-	char *_data;
-	char *DEPEND;        /* line 1 */
-	char *RDEPEND;
-	char *SLOT;
-	char *SRC_URI;
-	char *RESTRICT;      /* line 5 */
-	char *HOMEPAGE;
-	char *LICENSE;
-	char *DESCRIPTION;
-	char *KEYWORDS;
-	char *INHERITED;     /* line 10 */
-	char *IUSE;
-	char *CDEPEND;
-	char *PDEPEND;
-	char *PROVIDE;       /* line 14 */
-	char *EAPI;
-	char *PROPERTIES;
-	depend_atom *atom;
-	/* These are MD5-Cache only */
-	char *DEFINED_PHASES;
-	char *REQUIRED_USE;
-	char *_eclasses_;
-	char *_md5_;
-} portage_cache;
-
-static void cache_free(portage_cache *cache);
-static portage_cache *cache_read_file_pms(const char *file);
-static portage_cache *cache_read_file_md5(const char *file);
-
-static portage_cache *
-cache_read_file(const char *file)
-{
-	if (portcachedir_type == CACHE_METADATA_MD5)
-		return(cache_read_file_md5(file));
-	else if (portcachedir_type == CACHE_METADATA_PMS)
-		return(cache_read_file_pms(file));
-	warn("Unknown metadata cache type!");
-	return NULL;
-}
-
-static portage_cache *
-cache_read_file_pms(const char *file)
-{
-	struct stat s;
-	char *ptr;
-	FILE *f;
-	portage_cache *ret = NULL;
-	size_t len;
-
-	if ((f = fopen(file, "r")) == NULL)
-		goto err;
-
-	if (fstat(fileno(f), &s) != 0)
-		goto err;
-	len = sizeof(*ret) + s.st_size + 1;
-	ret = xzalloc(len);
-	ptr = (char*)ret;
-	ret->_data = ptr + sizeof(*ret);
-	if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size)
-		goto err;
-
-	ret->atom = atom_explode(file);
-	ret->DEPEND = ret->_data;
-#define next_line(curr, next) \
-	if ((ptr = strchr(ret->curr, '\n')) == NULL) { \
-		warn("Invalid cache file '%s'", file); \
-		goto err; \
-	} \
-	ret->next = ptr+1; \
-	*ptr = '\0';
-	next_line(DEPEND, RDEPEND)
-	next_line(RDEPEND, SLOT)
-	next_line(SLOT, SRC_URI)
-	next_line(SRC_URI, RESTRICT)
-	next_line(RESTRICT, HOMEPAGE)
-	next_line(HOMEPAGE, LICENSE)
-	next_line(LICENSE, DESCRIPTION)
-	next_line(DESCRIPTION, KEYWORDS)
-	next_line(KEYWORDS, INHERITED)
-	next_line(INHERITED, IUSE)
-	next_line(IUSE, CDEPEND)
-	next_line(CDEPEND, PDEPEND)
-	next_line(PDEPEND, PROVIDE)
-	next_line(PROVIDE, EAPI)
-	next_line(EAPI, PROPERTIES)
-#undef next_line
-	ptr = strchr(ptr+1, '\n');
-	if (ptr == NULL) {
-		warn("Invalid cache file '%s' - could not find end of cache data", file);
-		goto err;
-	}
-	*ptr = '\0';
-
-	fclose(f);
-
-	return ret;
-
-err:
-	if (f) fclose(f);
-	if (ret) cache_free(ret);
-	return NULL;
-}
-
-static portage_cache *
-cache_read_file_md5(const char *file)
-{
-	struct stat s;
-	char *ptr, *endptr;
-	FILE *f;
-	portage_cache *ret = NULL;
-	size_t len;
-
-	if ((f = fopen(file, "r")) == NULL)
-		goto err;
-
-	if (fstat(fileno(f), &s) != 0)
-		goto err;
-	len = sizeof(*ret) + s.st_size + 1;
-	ret = xzalloc(len);
-	ptr = (char*)ret;
-	ret->_data = ptr + sizeof(*ret);
-	if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size)
-		goto err;
-
-	ret->atom = atom_explode(file);
-
-	/* We have a block of key=value\n data.
-	 * KEY=VALUE\n
-	 * Where KEY does NOT contain:
-	 * \0 \n =
-	 * And VALUE does NOT contain:
-	 * \0 \n
-	 * */
-#define assign_var_cmp(keyname, cmpkey) \
-	if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \
-		ret->keyname = valptr; \
-		continue; \
-	}
-#define assign_var(keyname) \
-	assign_var_cmp(keyname, #keyname);
-
-	ptr = ret->_data;
-	endptr = strchr(ptr, '\0');
-	if (endptr == NULL) {
-			warn("Invalid cache file '%s' - could not find end of cache data", file);
-			goto err;
-	}
-
-	while (ptr != NULL && ptr != endptr) {
-		char *keyptr;
-		char *valptr;
-		keyptr = ptr;
-		valptr = strchr(ptr, '=');
-		if (valptr == NULL) {
-			warn("Invalid cache file '%s' val", file);
-			goto err;
-		}
-		*valptr = '\0';
-		valptr++;
-		ptr = strchr(valptr, '\n');
-		if (ptr == NULL) {
-			warn("Invalid cache file '%s' key", file);
-			goto err;
-		}
-		*ptr = '\0';
-		ptr++;
-
-		assign_var(CDEPEND);
-		assign_var(DEPEND);
-		assign_var(DESCRIPTION);
-		assign_var(EAPI);
-		assign_var(HOMEPAGE);
-		assign_var(INHERITED);
-		assign_var(IUSE);
-		assign_var(KEYWORDS);
-		assign_var(LICENSE);
-		assign_var(PDEPEND);
-		assign_var(PROPERTIES);
-		assign_var(PROVIDE);
-		assign_var(RDEPEND);
-		assign_var(RESTRICT);
-		assign_var(SLOT);
-		assign_var(SRC_URI);
-		assign_var(DEFINED_PHASES);
-		assign_var(REQUIRED_USE);
-		assign_var(_eclasses_);
-		assign_var(_md5_);
-		warn("Cache file '%s' with unknown key %s", file, keyptr);
-	}
-#undef assign_var
-#undef assign_var_cmp
-
-	fclose(f);
-
-	return ret;
-
-err:
-	if (f) fclose(f);
-	if (ret) cache_free(ret);
-	return NULL;
-}
-
-#ifdef EBUG
-static void
-cache_dump(portage_cache *cache)
-{
-	if (!cache)
-		errf("Cache is empty !");
-
-	printf("DEPEND     : %s\n", cache->DEPEND);
-	printf("RDEPEND    : %s\n", cache->RDEPEND);
-	printf("SLOT       : %s\n", cache->SLOT);
-	printf("SRC_URI    : %s\n", cache->SRC_URI);
-	printf("RESTRICT   : %s\n", cache->RESTRICT);
-	printf("HOMEPAGE   : %s\n", cache->HOMEPAGE);
-	printf("LICENSE    : %s\n", cache->LICENSE);
-	printf("DESCRIPTION: %s\n", cache->DESCRIPTION);
-	printf("KEYWORDS   : %s\n", cache->KEYWORDS);
-	printf("INHERITED  : %s\n", cache->INHERITED);
-	printf("IUSE       : %s\n", cache->IUSE);
-	printf("CDEPEND    : %s\n", cache->CDEPEND);
-	printf("PDEPEND    : %s\n", cache->PDEPEND);
-	printf("PROVIDE    : %s\n", cache->PROVIDE);
-	printf("EAPI       : %s\n", cache->EAPI);
-	printf("PROPERTIES : %s\n", cache->PROPERTIES);
-	if (!cache->atom) return;
-	printf("CATEGORY   : %s\n", cache->atom->CATEGORY);
-	printf("PN         : %s\n", cache->atom->PN);
-	printf("PV         : %s\n", cache->atom->PV);
-	printf("PVR        : %s\n", cache->atom->PVR);
-}
-#endif
-
-static void
-cache_free(portage_cache *cache)
-{
-	if (!cache)
-		errf("Cache is empty !");
-	atom_implode(cache->atom);
-	free(cache);
-}
-
-static char *
-atom_to_pvr(depend_atom *atom) {
-	return (atom->PR_int == 0 ? atom->P : atom->PVR );
-}
-
-/* TODO: Merge this into libq/vdb.c somehow. */
-static set *
-get_vdb_atoms(int fullcpv)
-{
-	q_vdb_ctx *ctx;
-
-	int cfd, j;
-	int dfd, i;
-
-	char buf[_Q_PATH_MAX];
-	char slot[_Q_PATH_MAX];
-	char *slotp = slot;
-	size_t slot_len;
-
-	struct dirent **cat;
-	struct dirent **pf;
-
-	depend_atom *atom = NULL;
-	set *cpf = NULL;
-
-	ctx = q_vdb_open(portroot, portvdb);
-	if (!ctx)
-		return NULL;
-
-	/* scan the cat first */
-	cfd = scandirat(ctx->vdb_fd, ".", &cat, q_vdb_filter_cat, alphasort);
-	if (cfd < 0)
-		goto fuckit;
-
-	for (j = 0; j < cfd; j++) {
-		dfd = scandirat(ctx->vdb_fd, cat[j]->d_name,
-				&pf, q_vdb_filter_pkg, alphasort);
-		if (dfd < 0)
-			continue;
-		for (i = 0; i < dfd; i++) {
-			int blen = snprintf(buf, sizeof(buf), "%s/%s/SLOT",
-					cat[j]->d_name, pf[i]->d_name);
-			if (blen < 0 || (size_t)blen >= sizeof(buf)) {
-				warnf("unable to parse long package: %s/%s",
-						cat[j]->d_name, pf[i]->d_name);
-				continue;
-			}
-
-			/* Chop the SLOT for the atom parsing. */
-			buf[blen - 5] = '\0';
-			if ((atom = atom_explode(buf)) == NULL)
-				continue;
-			/* Restore the SLOT. */
-			buf[blen - 5] = '/';
-
-			slot_len = sizeof(slot);
-			eat_file_at(ctx->vdb_fd, buf, &slotp, &slot_len);
-			rmspace(slot);
-
-			if (fullcpv) {
-				if (atom->PR_int)
-					snprintf(buf, sizeof(buf), "%s/%s-%s-r%i",
-							atom->CATEGORY, atom->PN, atom->PV, atom->PR_int);
-				else
-					snprintf(buf, sizeof(buf), "%s/%s-%s",
-							atom->CATEGORY, atom->PN, atom->PV);
-			} else {
-				snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN);
-			}
-			atom_implode(atom);
-			cpf = add_set(buf, cpf);
-		}
-		scandir_free(pf, dfd);
-	}
-	scandir_free(cat, cfd);
-
- fuckit:
-	q_vdb_close(ctx);
-	return cpf;
-}
-
-static void
-cleanup(void)
-{
-	reinitialize_as_needed();
-}
-
 int main(int argc, char **argv)
 {
 	struct stat st;
@@ -1478,9 +937,6 @@ int main(int argc, char **argv)
 		no_colors();
 
 	initialize_portage_env();
-	atexit(cleanup);
 	optind = 0;
 	return q_main(argc, argv);
 }
-
-#include "include_applets.h"

diff --git a/main.h b/main.h
index ef98c5d..958efa6 100644
--- a/main.h
+++ b/main.h
@@ -52,6 +52,16 @@ extern const char *argv0;
 # define MAX(x, y) ((x) < (y) ? (y) : (x))
 #endif
 
+#define READ_BE_INT32(P) \
+	(((P)[0] << 24) | ((P)[1] << 16) | ((P)[2] << 8 ) | (P)[3])
+#define WRITE_BE_INT32(P,I) \
+{ \
+	(P)[0] = (I & 0xff000000) >> 24; \
+	(P)[1] = (I & 0x00ff0000) >> 16; \
+	(P)[2] = (I & 0x0000ff00) >> 8; \
+	(P)[3] = (I & 0x000000ff); \
+}
+
 /* Easy enough to glue to older versions */
 #ifndef O_CLOEXEC
 # define O_CLOEXEC 0
@@ -122,6 +132,4 @@ extern FILE *warnout;
 #define errp(fmt, args...) _err(warnp, fmt , ## args)
 #define errfp(fmt, args...) _err(warnfp, fmt, ## args)
 
-int rematch(const char *, const char *, int);
-
 #endif

diff --git a/q.c b/q.c
index e5cc369..a4a943e 100644
--- a/q.c
+++ b/q.c
@@ -7,6 +7,17 @@
  * Copyright 2017-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
+#include "main.h"
+#include "applets.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "atom.h"
+#include "basename.h"
+#include "cache.h"
+
 #define Q_FLAGS "irmM:" COMMON_FLAGS
 static struct option const q_long_opts[] = {
 	{"install",       no_argument, NULL, 'i'},
@@ -24,7 +35,7 @@ static const char * const q_opts_help[] = {
 };
 #define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, NULL, lookup_applet_idx("q"))
 
-static APPLET lookup_applet(const char *applet)
+APPLET lookup_applet(const char *applet)
 {
 	unsigned int i;
 
@@ -34,7 +45,8 @@ static APPLET lookup_applet(const char *applet)
 	for (i = 0; applets[i].name; ++i) {
 		if (strcmp(applets[i].name, applet) == 0) {
 			argv0 = applets[i].name;
-			if (i && applets[i].desc != NULL) ++argv0; /* chop the leading 'q' */
+			if (i && applets[i].desc != NULL)
+				++argv0; /* chop the leading 'q' */
 			return applets[i].func;
 		}
 	}
@@ -60,11 +72,34 @@ int lookup_applet_idx(const char *applet)
 	return 0;
 }
 
+static void
+reinitialize_as_needed(int reinitialize, int reinitialize_metacache)
+{
+	size_t n;
+	const char *overlay, *ret = ret;
+
+	if (reinitialize)
+		array_for_each(overlays, n, overlay) {
+			ret = initialize_flat(overlay, CACHE_EBUILD, true);
+			if (USE_CLEANUP)
+				free((void *)ret);
+		}
+
+	if (reinitialize_metacache)
+		array_for_each(overlays, n, overlay) {
+			ret = initialize_flat(overlay, CACHE_METADATA, true);
+			if (USE_CLEANUP)
+				free((void *)ret);
+		}
+}
+
 int q_main(int argc, char **argv)
 {
 	int i, install;
 	const char *p;
 	APPLET func;
+	int reinitialize_metacache = 0;
+	int reinitialize = 0;
 
 	if (argc == 0)
 		return 1;
@@ -161,8 +196,10 @@ int q_main(int argc, char **argv)
 		return ret;
 	}
 
-	if (reinitialize > 0 || reinitialize_metacache > 0)
+	if (reinitialize > 0 || reinitialize_metacache > 0) {
+		reinitialize_as_needed(reinitialize, reinitialize_metacache);
 		return 0;
+	}
 	if (reinitialize < 0 || reinitialize_metacache < 0) {
 		reinitialize = reinitialize_metacache = 0;
 		return 0;

diff --git a/qatom.c b/qatom.c
index d7782ea..c1af10d 100644
--- a/qatom.c
+++ b/qatom.c
@@ -1,12 +1,18 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2008 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
  */
 
-#ifdef APPLET_qatom
+#include "main.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "atom.h"
+#include "applets.h"
 
 #define QATOM_FORMAT "%{CATEGORY} %{PN} %{PV} %[PR] %[SLOT] %[pfx] %[sfx]"
 
@@ -148,7 +154,3 @@ int qatom_main(int argc, char **argv)
 
 	return EXIT_SUCCESS;
 }
-
-#else
-DEFINE_APPLET_STUB(qatom)
-#endif

diff --git a/qcache.c b/qcache.c
index e4b6a7e..29b10af 100644
--- a/qcache.c
+++ b/qcache.c
@@ -5,7 +5,23 @@
  * Copyright 2006 Thomas A. Cort - <tcort@gentoo.org>
  */
 
-#ifdef APPLET_qcache
+#include "main.h"
+#include "applets.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <xalloc.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "atom.h"
+#include "cache.h"
+#include "scandirat.h"
+#include "rmspace.h"
+#include "set.h"
+#include "xasprintf.h"
 
 /********************************************************************/
 /* Required portage-utils stuff                                     */
@@ -358,7 +374,9 @@ qcache_vercmp(const struct dirent **x, const struct dirent **y)
 static int
 qcache_file_select(const struct dirent *entry)
 {
-	return !(entry->d_name[0] == '.' || (strcmp(entry->d_name, "metadata.xml") == 0) || (strstr(entry->d_name, ".cpickle") != 0));
+	return !(entry->d_name[0] == '.' ||
+			(strcmp(entry->d_name, "metadata.xml") == 0) ||
+			(strstr(entry->d_name, ".cpickle") != 0));
 }
 
 /*
@@ -374,7 +392,8 @@ qcache_file_select(const struct dirent *entry)
 static int
 qcache_ebuild_select(const struct dirent *entry)
 {
-	return ((strlen(entry->d_name) > 7) && !strcmp(entry->d_name+strlen(entry->d_name)-7, ".ebuild"));
+	return ((strlen(entry->d_name) > 7) &&
+			!strcmp(entry->d_name+strlen(entry->d_name)-7, ".ebuild"));
 }
 
 /********************************************************************/
@@ -594,10 +613,13 @@ qcache_not(qcache_data *data)
 		return;
 	}
 
-	if (keywords[qcache_test_arch] == testing || keywords[qcache_test_arch] == stable) {
+	if (keywords[qcache_test_arch] == testing ||
+			keywords[qcache_test_arch] == stable)
+	{
 		qcache_skip = 1;
 	} else if (data->cur == data->num) {
-		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE, data->package, NORM);
+		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
+				data->package, NORM);
 	}
 
 	free(keywords);
@@ -621,9 +643,12 @@ qcache_all(qcache_data *data)
 		return;
 	}
 
-	if (keywords[qcache_test_arch] == stable || keywords[qcache_test_arch] == testing) {
+	if (keywords[qcache_test_arch] == stable ||
+			keywords[qcache_test_arch] == testing)
+	{
 		qcache_skip = 1;
-		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE, data->package, NORM);
+		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
+				data->package, NORM);
 	}
 
 	free(keywords);
@@ -651,11 +676,14 @@ qcache_dropped(qcache_data *data)
 		return;
 	}
 
-	if (keywords[qcache_test_arch] == testing || keywords[qcache_test_arch] == stable) {
+	if (keywords[qcache_test_arch] == testing ||
+			keywords[qcache_test_arch] == stable)
+	{
 		qcache_skip = 1;
 
 		if (possible) {
-			printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE, data->package, NORM);
+			printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
+					data->package, NORM);
 		}
 
 		free(keywords);
@@ -889,7 +917,8 @@ qcache_testing_only(qcache_data *data)
 		possible = 1;
 
 	if (data->cur == data->num && possible) {
-		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE, data->package, NORM);
+		printf("%s%s/%s%s%s\n", BOLD, data->category, BLUE,
+				data->package, NORM);
 	}
 
 	free(keywords);
@@ -972,7 +1001,8 @@ int qcache_main(int argc, char **argv)
 			case 'a':
 			case 'n':
 				if (action)
-					qcache_usage(EXIT_FAILURE); /* trying to use more than 1 action */
+					qcache_usage(EXIT_FAILURE);
+					/* trying to use more than 1 action */
 				action = i;
 				break;
 
@@ -999,7 +1029,3 @@ int qcache_main(int argc, char **argv)
 	qcache_usage(EXIT_FAILURE);
 	return EXIT_FAILURE;
 }
-
-#else
-DEFINE_APPLET_STUB(qcache)
-#endif

diff --git a/qcheck.c b/qcheck.c
index b500dd5..0585396 100644
--- a/qcheck.c
+++ b/qcheck.c
@@ -7,9 +7,23 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qcheck
+#include "main.h"
+#include "applets.h"
 
+#include <sys/types.h>
 #include <inttypes.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "atom.h"
+#include "contents.h"
+#include "md5_sha1_sum.h"
+#include "prelink.h"
+#include "set.h"
+#include "vdb.h"
+#include "xarray.h"
+#include "xasprintf.h"
+#include "xregex.h"
 
 #define QCHECK_FLAGS "s:uABHTPp" COMMON_FLAGS
 static struct option const qcheck_long_opts[] = {
@@ -437,7 +451,3 @@ int qcheck_main(int argc, char **argv)
 	xarrayfree_int(atoms);
 	return ret;
 }
-
-#else
-DEFINE_APPLET_STUB(qcheck)
-#endif

diff --git a/qdepends.c b/qdepends.c
index e19718c..ca82f08 100644
--- a/qdepends.c
+++ b/qdepends.c
@@ -7,7 +7,19 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qdepends
+#include "main.h"
+#include "applets.h"
+
+#include <ctype.h>
+#include <xalloc.h>
+#include <assert.h>
+
+#include "atom.h"
+#include "set.h"
+#include "vdb.h"
+#include "xarray.h"
+#include "xasprintf.h"
+#include "xregex.h"
 
 #define QDEPENDS_FLAGS "drpbafNk:Q:" COMMON_FLAGS
 static struct option const qdepends_long_opts[] = {
@@ -714,7 +726,3 @@ int qdepends_main(int argc, char **argv)
 		warn("no matches found for your query");
 	return ret ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-
-#else
-DEFINE_APPLET_STUB(qdepends)
-#endif

diff --git a/qfile.c b/qfile.c
index 71a3236..19b156e 100644
--- a/qfile.c
+++ b/qfile.c
@@ -1,12 +1,24 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
+ * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qfile
+#include "main.h"
+#include "applets.h"
+
+#include <xalloc.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "atom.h"
+#include "basename.h"
+#include "contents.h"
+#include "rmspace.h"
+#include "vdb.h"
 
 #define QFILE_FLAGS "boRx:S" COMMON_FLAGS
 static struct option const qfile_long_opts[] = {
@@ -499,7 +511,3 @@ int qfile_main(int argc, char **argv)
 
 	return (found ? EXIT_SUCCESS : EXIT_FAILURE);
 }
-
-#else
-DEFINE_APPLET_STUB(qfile)
-#endif

diff --git a/qgrep.c b/qgrep.c
index f018821..da38f40 100644
--- a/qgrep.c
+++ b/qgrep.c
@@ -8,7 +8,22 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qgrep
+#include "main.h"
+#include "applets.h"
+
+#include <stdio.h>
+#include <xalloc.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "atom.h"
+#include "cache.h"
+#include "vdb.h"
+#include "xarray.h"
+#include "xchdir.h"
+#include "xregex.h"
 
 #define QGREP_FLAGS "IiHNclLexJEsS:B:A:" COMMON_FLAGS
 static struct option const qgrep_long_opts[] = {
@@ -314,7 +329,8 @@ int qgrep_main(int argc, char **argv)
 	}
 
 	if (show_name && show_filename) {
-		warn("--with-name and --with-filename are incompatible options. The former wins.");
+		warn("--with-name and --with-filename are incompatible options. "
+				"The former wins.");
 		show_filename = 0;
 	}
 
@@ -341,14 +357,16 @@ int qgrep_main(int argc, char **argv)
 	}
 
 	if (do_installed && do_eclass) {
-		warn("--installed and --eclass are incompatible options. The former wins.");
+		warn("--installed and --eclass are incompatible options. "
+				"The former wins.");
 		do_eclass = 0;
 	}
 
 	/* do we report results once per file or per line ? */
 	per_file_output = do_count || (do_list && (!verbose || invert_list));
 	/* label for prefixing matching lines or listing matching files */
-	label = (show_name ? name : ((verbose || show_filename || do_list) ? ebuild : NULL));
+	label = (show_name ? name :
+			((verbose || show_filename || do_list) ? ebuild : NULL));
 
 	if (argc > (optind + 1)) {
 		include_atoms = xcalloc(sizeof(depend_atom*), (argc - optind - 1));
@@ -392,16 +410,20 @@ int qgrep_main(int argc, char **argv)
 			snprintf(buf, sizeof(buf), "%s/%s", portroot, portvdb);
 			xchdir(buf);
 			if ((vdb_dir = opendir(".")) == NULL)
-				errp("could not opendir(%s/%s) for ROOT/VDB", portroot, portvdb);
+				errp("could not opendir(%s/%s) for ROOT/VDB",
+						portroot, portvdb);
 		}
 
 		/* iteration is either over ebuilds or eclasses */
 		while (do_eclass
 				? ((dentry = readdir(eclass_dir))
-					&& snprintf(ebuild, sizeof(ebuild), "eclass/%s", dentry->d_name))
+					&& snprintf(ebuild, sizeof(ebuild),
+						"eclass/%s", dentry->d_name))
 				: (do_installed
-					? (get_next_installed_ebuild(ebuild, vdb_dir, &dentry, &cat_dir) != NULL)
-					: (fgets(ebuild, sizeof(ebuild), fp) != NULL))) {
+					? (get_next_installed_ebuild(ebuild, vdb_dir,
+							&dentry, &cat_dir) != NULL)
+					: (fgets(ebuild, sizeof(ebuild), fp) != NULL)))
+		{
 			FILE *newfp;
 
 			/* filter badly named files, prepare eclass or package name, etc. */
@@ -451,14 +473,19 @@ int qgrep_main(int argc, char **argv)
 				int lineno = 0;
 				char remaining_after_context = 0;
 				count = 0;
-				/* if there have been some matches already, then a separator will be needed */
-				need_separator = (!status) && (num_lines_before || num_lines_after);
-				/* whatever is in the circular buffers list is no more a valid context */
+				/* if there have been some matches already, then a
+				 * separator will be needed */
+				need_separator =
+					!status && (num_lines_before || num_lines_after);
+				/* whatever is in the circular buffers list is no more a
+				 * valid context */
 				qgrep_buf_list_invalidate(buf_list);
 
-				/* reading a new line always happen in the next buffer of the list */
-				while ((buf_list = buf_list->next)
-						&& (fgets(buf_list->buf, sizeof(buf_list->buf), newfp)) != NULL) {
+				/* reading a new line always happen in the next buffer
+				 * of the list */
+				while ((buf_list = buf_list->next) &&
+						fgets(buf_list->buf, sizeof(buf_list->buf), newfp))
+				{
 					lineno++;
 					buf_list->valid = 1;
 
@@ -477,17 +504,20 @@ int qgrep_main(int argc, char **argv)
 					}
 
 					if (skip_pattern) {
-						/* reject some other lines which match an optional pattern */
+						/* reject some other lines which match an
+						 * optional pattern */
 						if (!do_regex) {
 							if (strfunc(buf_list->buf, skip_pattern) != NULL)
 								goto print_after_context;
 						} else {
-							if (regexec(&skip_preg, buf_list->buf, 0, NULL, 0) == 0)
+							if (regexec(&skip_preg, buf_list->buf,
+										0, NULL, 0) == 0)
 								goto print_after_context;
 						}
 					}
 
-					/* four ways to match a line (with/without inversion and regexp) */
+					/* four ways to match a line (with/without inversion
+					 * and regexp) */
 					if (!invert_match) {
 						if (do_regex == 0) {
 							if (strfunc(buf_list->buf, argv[optind]) == NULL)
@@ -509,7 +539,8 @@ int qgrep_main(int argc, char **argv)
 					count++;
 					status = 0; /* got a match, exit status should be 0 */
 					if (per_file_output)
-						continue; /* matching files are listed out of this loop */
+						continue;
+						/* matching files are listed out of this loop */
 
 					if ((need_separator > 0)
 							&& (num_lines_before || num_lines_after))
@@ -519,7 +550,8 @@ int qgrep_main(int argc, char **argv)
 					need_separator = 0 - num_lines_before;
 					if (!do_list) {
 						/* print the leading context */
-						qgrep_print_before_context(buf_list, num_lines_before, label,
+						qgrep_print_before_context(buf_list,
+								num_lines_before, label,
 								((verbose > 1) ? lineno : -1));
 						/* print matching line */
 						if (invert_match || *RED == '\0')
@@ -530,9 +562,11 @@ int qgrep_main(int argc, char **argv)
 								((verbose > 1) ? lineno : -1), &preg);
 						else
 							qgrep_print_matching_line_strcolor(buf_list, label,
-								((verbose > 1) ? lineno : -1), strfunc, argv[optind]);
+								((verbose > 1) ? lineno : -1), strfunc,
+								argv[optind]);
 					} else {
-						/* in verbose do_list mode, list the file once per match */
+						/* in verbose do_list mode, list the file once
+						 * per match */
 						printf("%s", label);
 						if (verbose > 1)
 							printf(":%d", lineno);
@@ -546,8 +580,9 @@ int qgrep_main(int argc, char **argv)
 					/* print some trailing context lines when needed */
 					if (!remaining_after_context) {
 						if (!status)
-							/* we're getting closer to the need of a separator between
-							 * current match block and the next one */
+							/* we're getting closer to the need of a
+							 * separator between current match block and
+							 * the next one */
 							++need_separator;
 					} else {
 						qgrep_print_context_line(buf_list, label,
@@ -557,7 +592,8 @@ int qgrep_main(int argc, char **argv)
 				}
 				fclose(newfp);
 				if (!per_file_output)
-					continue; /* matches were already displayed, line per line */
+					continue;
+					/* matches were already displayed, line per line */
 				if (do_count && count) {
 					if (label != NULL)
 						/* -c without -v/-N/-H only outputs
@@ -565,7 +601,8 @@ int qgrep_main(int argc, char **argv)
 						printf("%s:", label);
 					printf("%d\n", count);
 				} else if ((count && !invert_list) || (!count && invert_list))
-					printf("%s\n", label); /* do_list == 1, or we wouldn't be here */
+					printf("%s\n", label);
+					/* do_list == 1, or we wouldn't be here */
 			}
 		}
 		if (do_eclass)
@@ -591,7 +628,3 @@ int qgrep_main(int argc, char **argv)
 
 	return status;
 }
-
-#else
-DEFINE_APPLET_STUB(qgrep)
-#endif

diff --git a/qlist.c b/qlist.c
index d98b30e..d46e0a6 100644
--- a/qlist.c
+++ b/qlist.c
@@ -8,7 +8,18 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qlist
+#include "main.h"
+#include "applets.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <xalloc.h>
+
+#include "atom.h"
+#include "contents.h"
+#include "vdb.h"
+#include "xregex.h"
 
 #define QLIST_FLAGS "ISRUcDeados" COMMON_FLAGS
 static struct option const qlist_long_opts[] = {
@@ -163,8 +174,19 @@ umapstr(char display, q_vdb_pkg_ctx *pkg_ctx)
 	return _umapstr_buf;
 }
 
-static bool
-qlist_match(q_vdb_pkg_ctx *pkg_ctx, const char *name, depend_atom **name_atom, bool exact)
+/* forward declaration necessary for misuse from qmerge.c, see HACK there */
+bool
+qlist_match(
+		q_vdb_pkg_ctx *pkg_ctx,
+		const char *name,
+		depend_atom **name_atom,
+		bool exact);
+bool
+qlist_match(
+		q_vdb_pkg_ctx *pkg_ctx,
+		const char *name,
+		depend_atom **name_atom,
+		bool exact)
 {
 	const char *catname = pkg_ctx->cat_ctx->name;
 	const char *pkgname = pkg_ctx->name;
@@ -182,7 +204,8 @@ qlist_match(q_vdb_pkg_ctx *pkg_ctx, const char *name, depend_atom **name_atom, b
 			uslot = NULL;
 		else {
 			if (!pkg_ctx->slot)
-				q_vdb_pkg_eat(pkg_ctx, "SLOT", &pkg_ctx->slot, &pkg_ctx->slot_len);
+				q_vdb_pkg_eat(pkg_ctx, "SLOT", &pkg_ctx->slot,
+						&pkg_ctx->slot_len);
 			uslot_len = strlen(uslot);
 		}
 	}
@@ -190,7 +213,8 @@ qlist_match(q_vdb_pkg_ctx *pkg_ctx, const char *name, depend_atom **name_atom, b
 	urepo = strstr(name, "::");
 	if (urepo) {
 		if (!pkg_ctx->repo)
-			q_vdb_pkg_eat(pkg_ctx, "repository", &pkg_ctx->repo, &pkg_ctx->repo_len);
+			q_vdb_pkg_eat(pkg_ctx, "repository", &pkg_ctx->repo,
+					&pkg_ctx->repo_len);
 		urepo += 2;
 		urepo_len = strlen(urepo);
 
@@ -229,8 +253,8 @@ qlist_match(q_vdb_pkg_ctx *pkg_ctx, const char *name, depend_atom **name_atom, b
 	}
 
 	if (uslot) {
-		/* Require exact match on SLOTs.  If the user didn't include a subslot,
-		 * then ignore it when checking the package's value. */
+		/* Require exact match on SLOTs.  If the user didn't include a
+		 * subslot, then ignore it when checking the package's value. */
 		if (strncmp(pkg_ctx->slot, uslot, uslot_len) != 0 ||
 		    (pkg_ctx->slot[uslot_len] != '\0' &&
 		     pkg_ctx->slot[uslot_len] != '/'))
@@ -474,7 +498,3 @@ int qlist_main(int argc, char **argv)
 	/* The return value is whether we matched anything. */
 	return ret ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-
-#else
-DEFINE_APPLET_STUB(qlist)
-#endif

diff --git a/qlop.c b/qlop.c
index d5c2548..b8038b4 100644
--- a/qlop.c
+++ b/qlop.c
@@ -7,7 +7,19 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qlop
+#include "main.h"
+#include "applets.h"
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "atom.h"
+#include "eat_file.h"
+#include "xarray.h"
+#include "xasprintf.h"
 
 #define QLOP_DEFAULT_LOGFILE "emerge.log"
 
@@ -1009,7 +1021,3 @@ int qlop_main(int argc, char **argv)
 
 	return EXIT_SUCCESS;
 }
-
-#else
-DEFINE_APPLET_STUB(qlop)
-#endif

diff --git a/qmerge.c b/qmerge.c
index 5ebb55e..81da0b1 100644
--- a/qmerge.c
+++ b/qmerge.c
@@ -7,13 +7,35 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qmerge
+#include "main.h"
+#include "applets.h"
 
+#include <stdio.h>
+#include <xalloc.h>
 #include <fnmatch.h>
+#include <dirent.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <assert.h>
 #include "stat-time.h"
 
+#include "atom.h"
+#include "copy_file.h"
+#include "contents.h"
+#include "eat_file.h"
+#include "human_readable.h"
+#include "md5_sha1_sum.h"
+#include "profile.h"
+#include "rmspace.h"
+#include "scandirat.h"
+#include "set.h"
+#include "vdb.h"
+#include "xasprintf.h"
+#include "xchdir.h"
+#include "xmkdir.h"
+#include "xsystem.h"
+
 #ifndef GLOB_BRACE
 # define GLOB_BRACE     (1 << 10)	/* Expand "{a,b}" to "a" "b".  */
 #endif
@@ -100,6 +122,21 @@ static int pkg_unmerge(q_vdb_pkg_ctx *, set *, int, char **, int, char **);
 static struct pkg_t *grab_binpkg_info(const char *);
 static char *find_binpkg(const char *);
 
+static bool
+prompt(const char *p)
+{
+	printf("%s? [Y/n] ", p);
+	fflush(stdout);
+	switch (getc(stdin)) {
+	case '\n':
+	case 'y':
+	case 'Y':
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int run_applet_l(const char *arg, ...)
 {
 	int (*applet)(int, char **);
@@ -251,6 +288,15 @@ qmerge_filter_cat(q_vdb_cat_ctx *cat_ctx, void *priv)
 	return !state->catname || strcmp(cat_ctx->name, state->catname) == 0;
 }
 
+/* HACK: pull this in, knowing that qlist will be in the final link, we
+ * should however figure out how to do what match does here from e.g.
+ * atom */
+extern bool qlist_match(
+		q_vdb_pkg_ctx *pkg_ctx,
+		const char *name,
+		depend_atom **name_atom,
+		bool exact);
+
 static int
 qmerge_best_version_cb(q_vdb_pkg_ctx *pkg_ctx, void *priv)
 {
@@ -2269,7 +2315,7 @@ qmerge_add_set(char *buf, set *q)
 	if (strcmp(buf, "world") == 0)
 		return qmerge_add_set_file("/var/lib/portage", "world", q);
 	else if (strcmp(buf, "all") == 0)
-		return get_vdb_atoms(0);
+		return get_vdb_atoms(portroot, portvdb, 0);
 	else if (strcmp(buf, "system") == 0)
 		return q_profile_walk("packages", qmerge_add_set_system, q);
 	else if (buf[0] == '@')
@@ -2362,7 +2408,3 @@ int qmerge_main(int argc, char **argv)
 	free_set(todo);
 	return ret;
 }
-
-#else
-DEFINE_APPLET_STUB(qmerge)
-#endif

diff --git a/qpkg.c b/qpkg.c
index 4de856a..3ff4507 100644
--- a/qpkg.c
+++ b/qpkg.c
@@ -7,9 +7,30 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qpkg
+#include "main.h"
+#include "applets.h"
 
+#include <stdio.h>
+#include <string.h>
 #include <fnmatch.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "atom.h"
+#include "basename.h"
+#include "cache.h"
+#include "contents.h"
+#include "human_readable.h"
+#include "md5_sha1_sum.h"
+#include "scandirat.h"
+#include "set.h"
+#include "vdb.h"
+#include "xarray.h"
+#include "xasprintf.h"
+#include "xchdir.h"
+#include "xpak.h"
 
 #define QPKG_FLAGS "cEpP:" COMMON_FLAGS
 static struct option const qpkg_long_opts[] = {
@@ -33,6 +54,11 @@ extern char pretend;
 static char *qpkg_bindir = NULL;
 static int eclean = 0;
 
+static char *
+atom_to_pvr(depend_atom *atom) {
+	return (atom->PR_int == 0 ? atom->P : atom->PVR );
+}
+
 /* checks to make sure this is a .tbz2 file. used by scandir() */
 static int
 filter_tbz2(const struct dirent *dentry)
@@ -114,7 +140,7 @@ qpkg_clean(char *dirp)
 	if ((count = scandir(".", &dnames, filter_hidden, alphasort)) < 0)
 		return 1;
 
-	vdb = get_vdb_atoms(1);
+	vdb = get_vdb_atoms(portroot, portvdb, 1);
 
 	if (eclean) {
 		size_t n;
@@ -222,7 +248,6 @@ qpkg_make(depend_atom *atom)
 	FILE *fp, *out;
 	char tmpdir[BUFSIZE];
 	char filelist[BUFSIZE + 32];
-	char xpak[BUFSIZE + 32];
 	char tbz2[BUFSIZE + 32];
 	size_t buflen;
 	char *buf;
@@ -231,7 +256,8 @@ qpkg_make(depend_atom *atom)
 	struct stat st;
 
 	if (pretend) {
-		printf(" %s-%s %s/%s:\n", GREEN, NORM, atom->CATEGORY, atom_to_pvr(atom));
+		printf(" %s-%s %s/%s:\n",
+				GREEN, NORM, atom->CATEGORY, atom_to_pvr(atom));
 		return 0;
 	}
 
@@ -240,20 +266,28 @@ qpkg_make(depend_atom *atom)
 
 	snprintf(buf, buflen, "%s/%s/%s/CONTENTS",
 			portvdb, atom->CATEGORY, atom_to_pvr(atom));
-	if ((fp = fopen(buf, "r")) == NULL)
+	if ((fp = fopen(buf, "r")) == NULL) {
+		free(buf);
 		return -1;
+	}
 
 	snprintf(tmpdir, sizeof(tmpdir), "%s/qpkg.XXXXXX", qpkg_get_bindir());
-	if ((i = mkstemp(tmpdir)) == -1)
+	if ((i = mkstemp(tmpdir)) == -1) {
+		free(buf);
 		return -2;
+	}
 	close(i);
 	unlink(tmpdir);
-	if (mkdir(tmpdir, 0750))
+	if (mkdir(tmpdir, 0750)) {
+		free(buf);
 		return -3;
+	}
 
 	snprintf(filelist, sizeof(filelist), "%s/filelist", tmpdir);
-	if ((out = fopen(filelist, "w")) == NULL)
+	if ((out = fopen(filelist, "w")) == NULL) {
+		free(buf);
 		return -4;
+	}
 
 	while (getline(&buf, &buflen, fp) != -1) {
 		contents_entry *e;
@@ -280,41 +314,38 @@ qpkg_make(depend_atom *atom)
 	printf(" %s-%s %s/%s: ", GREEN, NORM, atom->CATEGORY, atom_to_pvr(atom));
 	fflush(stdout);
 
-	snprintf(tbz2, sizeof(tbz2), "%s/bin.tar.bz2", tmpdir);
+	snprintf(tbz2, sizeof(tbz2), "%s/bin.tbz2", tmpdir);
 	if (snprintf(buf, buflen, "tar jcf '%s' --files-from='%s' "
-			"--no-recursion >/dev/null 2>&1", tbz2, filelist) > (int)buflen)
-		return 2;
-	if ((fp = popen(buf, "r")) == NULL)
+			"--no-recursion >/dev/null 2>&1", tbz2, filelist) > (int)buflen ||
+			(fp = popen(buf, "r")) == NULL)
+	{
+		free(buf);
 		return 2;
+	}
 	pclose(fp);
 
-	snprintf(xpak, sizeof(xpak), "%s/inf.xpak", tmpdir);
 	snprintf(buf, buflen, "%s/%s/%s",
 			portvdb, atom->CATEGORY, atom_to_pvr(atom));
 	xpak_argv[0] = buf;
 	xpak_argv[1] = NULL;
-	xpak_create(AT_FDCWD, xpak, 1, xpak_argv);
-
-	snprintf(buf, buflen, "%s/binpkg.tbz2", tmpdir);
-	tbz2_compose(AT_FDCWD, tbz2, xpak, buf);
+	xpak_create(AT_FDCWD, tbz2, 1, xpak_argv, 1, verbose);
 
 	unlink(filelist);
-	unlink(xpak);
-	unlink(tbz2);
 
-	snprintf(tbz2, sizeof(tbz2), "%s/%s.tbz2",
-			qpkg_get_bindir(), atom_to_pvr(atom));
-	if (rename(buf, tbz2)) {
-		warnp("could not move '%s' to '%s'", buf, tbz2);
+	snprintf(buf, buflen, "%s/%s.tbz2", qpkg_get_bindir(), atom_to_pvr(atom));
+	if (rename(tbz2, buf)) {
+		warnp("could not move '%s' to '%s'", tbz2, buf);
+		free(buf);
 		return 1;
 	}
 
 	rmdir(tmpdir);
 
-	stat(tbz2, &st);
+	stat(buf, &st);
 	printf("%s%s%s kB\n",
 			RED, make_human_readable_str(st.st_size, 1, KILOBYTE), NORM);
 
+	free(buf);
 	return 0;
 }
 
@@ -425,8 +456,12 @@ retry_mkdir:
 			for (i = optind; i < argc; ++i) {
 				if (!argv[i]) continue;
 
-				if (!strcmp(argv[i], atom->PN) || !strcmp(argv[i], atom->P) || !strcmp(argv[i], buf) || !strcmp(argv[i], "world"))
-					if (!qpkg_make(atom)) ++pkgs_made;
+				if (!strcmp(argv[i], atom->PN) ||
+						!strcmp(argv[i], atom->P) ||
+						!strcmp(argv[i], buf) ||
+						!strcmp(argv[i], "world"))
+					if (!qpkg_make(atom))
+						++pkgs_made;
 			}
 			atom_implode(atom);
 
@@ -437,13 +472,10 @@ retry_mkdir:
 
 	s = (argc - optind) - pkgs_made;
 	if (s && !pretend)
-		printf(" %s*%s %i package%s could not be matched :/\n", RED, NORM, (int)s, (s > 1 ? "s" : ""));
+		printf(" %s*%s %i package%s could not be matched :/\n",
+				RED, NORM, (int)s, (s > 1 ? "s" : ""));
 	if (pkgs_made)
 		qprintf(" %s*%s Packages can be found in %s\n", GREEN, NORM, bindir);
 
 	return (pkgs_made ? EXIT_SUCCESS : EXIT_FAILURE);
 }
-
-#else
-DEFINE_APPLET_STUB(qpkg)
-#endif

diff --git a/qsearch.c b/qsearch.c
index b75a4f7..5ae68bc 100644
--- a/qsearch.c
+++ b/qsearch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2018 Gentoo Authors
+ * Copyright 2005-2019 Gentoo Authors
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
@@ -7,7 +7,22 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org
  */
 
-#ifdef APPLET_qsearch
+#include "main.h"
+#include "applets.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <xalloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "atom.h"
+#include "basename.h"
+#include "cache.h"
+#include "rmspace.h"
+#include "xarray.h"
+#include "xregex.h"
 
 #define QSEARCH_FLAGS "acesSNH" COMMON_FLAGS
 static struct option const qsearch_long_opts[] = {
@@ -36,21 +51,32 @@ static const char * const qsearch_opts_help[] = {
 
 /* Search an ebuild's details via the metadata cache. */
 static void
-qsearch_ebuild_metadata(_q_unused_ int overlay_fd, const char *ebuild, const char *search_me, char *last,
-                        bool search_desc, bool search_all, _q_unused_ bool search_name, bool show_name_only, bool show_homepage)
+qsearch_ebuild_metadata(
+		int overlay_fd,
+		const char *ebuild,
+		const char *search_me,
+		char *last,
+		bool search_desc,
+		bool search_all,
+		bool search_name,
+		bool show_name_only,
+		bool show_homepage)
 {
-	portage_cache *pcache = cache_read_file(ebuild);
+	(void)overlay_fd;
+	(void)search_name;
+
+	portage_cache *pcache = cache_read_file(portcachedir_type, ebuild);
 
 	if (pcache == NULL) {
-		if (!reinitialize)
-			warnf("(cache update pending) %s", ebuild);
-		reinitialize = 1;
+		warnf("missing cache, please (re)generate");
 		return;
 	}
 
 	if (strcmp(pcache->atom->PN, last) != 0) {
 		strncpy(last, pcache->atom->PN, LAST_BUF_SIZE);
-		if (search_all || rematch(search_me, (search_desc ? pcache->DESCRIPTION : ebuild), REG_EXTENDED | REG_ICASE) == 0)
+		if (search_all || rematch(search_me,
+					(search_desc ? pcache->DESCRIPTION : ebuild),
+					REG_EXTENDED | REG_ICASE) == 0)
 			printf("%s%s/%s%s%s%s%s\n", BOLD, pcache->atom->CATEGORY, BLUE,
 			       pcache->atom->PN, NORM,
 				   (show_name_only ? "" : " "),
@@ -62,22 +88,37 @@ qsearch_ebuild_metadata(_q_unused_ int overlay_fd, const char *ebuild, const cha
 
 /* Search an ebuild's details via the ebuild cache. */
 static void
-qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me, char *last,
-                      _q_unused_ bool search_desc, bool search_all, bool search_name, bool show_name_only, _q_unused_ bool show_homepage)
+qsearch_ebuild_ebuild(
+		int overlay_fd,
+		const char *ebuild,
+		const char *search_me,
+		char *last,
+		bool search_desc,
+		bool search_all,
+		bool search_name,
+		bool show_name_only,
+		bool show_homepage)
 {
 	const char * const search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" };
 	const char *search_var = search_vars[show_homepage ? 1 : 0];
 	size_t search_len = strlen(search_var);
 	char *p, *q, *str;
-
+	char *buf = NULL;
+	int linelen;
+	size_t buflen;
+	bool show_it = false;
 	FILE *ebuildfp;
+	int fd;
+
 	str = xstrdup(ebuild);
 	p = dirname(str);
 
+	(void)search_desc;
+	(void)show_homepage;
+
 	if (strcmp(p, last) == 0)
 		goto no_cache_ebuild_match;
 
-	bool show_it = false;
 	strncpy(last, p, LAST_BUF_SIZE);
 	if (search_name) {
 		if (rematch(search_me, basename(last), REG_EXTENDED | REG_ICASE) != 0) {
@@ -88,7 +129,7 @@ qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me,
 		}
 	}
 
-	int fd = openat(overlay_fd, ebuild, O_RDONLY|O_CLOEXEC);
+	fd = openat(overlay_fd, ebuild, O_RDONLY|O_CLOEXEC);
 	if (fd != -1) {
 		ebuildfp = fdopen(fd, "r");
 		if (ebuildfp == NULL) {
@@ -96,15 +137,10 @@ qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me,
 			goto no_cache_ebuild_match;
 		}
 	} else {
-		if (!reinitialize)
-			warnfp("(cache update pending) %s", ebuild);
-		reinitialize = 1;
+		warnf("missing cache, please (re)generate");
 		goto no_cache_ebuild_match;
 	}
 
-	char *buf = NULL;
-	int linelen;
-	size_t buflen;
 	while ((linelen = getline(&buf, &buflen, ebuildfp)) >= 0) {
 		if ((size_t)linelen <= search_len)
 			continue;
@@ -115,7 +151,8 @@ qsearch_ebuild_ebuild(int overlay_fd, const char *ebuild, const char *search_me,
 		if (strlen(buf) <= search_len)
 			break;
 		q = buf + search_len + 1;
-		if (!search_all && !search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
+		if (!search_all && !search_name &&
+				rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
 			break;
 		show_it = true;
 		break;
@@ -216,7 +253,3 @@ int qsearch_main(int argc, char **argv)
 
 	return ret;
 }
-
-#else
-DEFINE_APPLET_STUB(qsearch)
-#endif

diff --git a/qsize.c b/qsize.c
index 3566429..80d496c 100644
--- a/qsize.c
+++ b/qsize.c
@@ -1,12 +1,14 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
+ * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_qsize
+#include "main.h"
+#include "applets.h"
 
 /* Solaris */
 #if defined(__sun) && defined(__SVR4)
@@ -41,6 +43,18 @@
 # define S_BLKSIZE 512
 #endif
 
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "atom.h"
+#include "contents.h"
+#include "human_readable.h"
+#include "vdb.h"
+#include "xarray.h"
+#include "xregex.h"
+
 #define QSIZE_FLAGS "fsSmkbi:" COMMON_FLAGS
 static struct option const qsize_long_opts[] = {
 	{"filesystem", no_argument, NULL, 'f'},
@@ -136,8 +150,10 @@ qsize_cb(q_vdb_pkg_ctx *pkg_ctx, void *priv)
 		if (e->type == CONTENTS_OBJ || e->type == CONTENTS_SYM) {
 			struct stat st;
 			++num_files;
-			if (!fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd, e->name + 1, &st, AT_SYMLINK_NOFOLLOW))
-				num_bytes += (state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size);
+			if (!fstatat(pkg_ctx->cat_ctx->ctx->portroot_fd,
+						e->name + 1, &st, AT_SYMLINK_NOFOLLOW))
+				num_bytes +=
+					state->fs_size ? st.st_blocks * S_BLKSIZE : st.st_size;
 		} else
 			++num_nonfiles;
 	}
@@ -235,7 +251,3 @@ int qsize_main(int argc, char **argv)
 
 	return ret;
 }
-
-#else
-DEFINE_APPLET_STUB(qsize)
-#endif

diff --git a/qtbz2.c b/qtbz2.c
index ee8e161..314eecd 100644
--- a/qtbz2.c
+++ b/qtbz2.c
@@ -1,12 +1,25 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
  */
 
-#ifdef APPLET_qtbz2
+#include "main.h"
+#include "applets.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "basename.h"
+#include "copy_file.h"
+#include "human_readable.h"
+#include "safe_io.h"
 
 /*
 # The format for a tbz2/xpak:
@@ -49,40 +62,6 @@ static const char * const qtbz2_opts_help[] = {
 
 static char tbz2_stdout = 0;
 
-static unsigned char *
-tbz2_encode_int(int enc)
-{
-	static unsigned char ret[4];
-	ret[0] = (enc & 0xff000000) >> 24;
-	ret[1] = (enc & 0x00ff0000) >> 16;
-	ret[2] = (enc & 0x0000ff00) >> 8;
-	ret[3] = (enc & 0x000000ff);
-	return ret;
-}
-static int
-tbz2_decode_int(unsigned char *buf)
-{
-	int ret;
-	ret = 0;
-	ret += (buf[0] << 24);
-	ret += (buf[1] << 16);
-	ret += (buf[2] << 8);
-	ret += (buf[3]);
-	return ret;
-}
-
-static void
-_tbz2_copy_file(FILE *src, FILE *dst)
-{
-	int count = 1;
-	unsigned char buffer[BUFSIZE*32];
-	while (count) {
-		count = fread(buffer, 1, sizeof(buffer), src);
-		if (!count) return;
-		fwrite(buffer, 1, count, dst);
-	}
-}
-
 static int
 tbz2_compose(int dir_fd, const char *tarbz2, const char *xpak, const char *tbz2)
 {
@@ -136,14 +115,15 @@ tbz2_compose(int dir_fd, const char *tarbz2, const char *xpak, const char *tbz2)
 	}
 
 	/* save [tarball] */
-	_tbz2_copy_file(in_tarbz2, out);
+	copy_file(in_tarbz2, out);
 	fclose(in_tarbz2);
 	/* save [xpak] */
-	_tbz2_copy_file(in_xpak, out);
+	copy_file(in_xpak, out);
 	fclose(in_xpak);
 
 	/* save tbz2 tail: OOOOSTOP */
-	fwrite(tbz2_encode_int(st.st_size), 1, 4, out);
+	WRITE_BE_INT32(buf, st.st_size);
+	fwrite(buf, 1, 4, out);
 	fwrite(TBZ2_END_MSG, 1, TBZ2_END_MSG_LEN, out);
 
 	fclose(out);
@@ -202,7 +182,8 @@ tbz2_decompose(int dir_fd, const char *tbz2, const char *tarbz2, const char *xpa
 		goto close_in_and_ret;
 
 	if (verbose)
-		printf("input tbz2: %s (%s)\n", tbz2, make_human_readable_str(st.st_size, 1, 0));
+		printf("input tbz2: %s (%s)\n", tbz2,
+				make_human_readable_str(st.st_size, 1, 0));
 
 	/* verify the tail signature */
 	if (fseek(in, -TBZ2_END_LEN, SEEK_END) != 0)
@@ -215,7 +196,7 @@ tbz2_decompose(int dir_fd, const char *tbz2, const char *tarbz2, const char *xpa
 	}
 
 	/* calculate xpak's size */
-	xpak_size = tbz2_decode_int(tbz2_tail);
+	xpak_size = READ_BE_INT32(tbz2_tail);
 	/* calculate tarbz2's size */
 	tarbz2_size = st.st_size - xpak_size - TBZ2_END_LEN;
 
@@ -223,11 +204,13 @@ tbz2_decompose(int dir_fd, const char *tbz2, const char *tarbz2, const char *xpa
 	rewind(in);
 	/* dump the tar.bz2 */
 	if (verbose)
-		printf("output tar.bz2: %s (%s)\n", tarbz2, make_human_readable_str(tarbz2_size, 1, 0));
+		printf("output tar.bz2: %s (%s)\n", tarbz2,
+				make_human_readable_str(tarbz2_size, 1, 0));
 	_tbz2_write_file(in, dir_fd, tarbz2, tarbz2_size);
 	/* dump the xpak */
 	if (verbose)
-		printf("output xpak: %s (%s)\n", xpak, make_human_readable_str(xpak_size, 1, 0));
+		printf("output xpak: %s (%s)\n", xpak,
+				make_human_readable_str(xpak_size, 1, 0));
 	_tbz2_write_file(in, dir_fd, xpak, xpak_size);
 
 	ret = 0;
@@ -266,9 +249,12 @@ int qtbz2_main(int argc, char **argv)
 	}
 	if (optind == argc) {
 		switch (action) {
-		case TBZ2_ACT_JOIN:  err("Join usage: <input tar.bz2> <input xpak> [<output tbz2>]");
-		case TBZ2_ACT_SPLIT: err("Split usage: <input tbz2> [<output tar.bz2> <output xpak>]");
-		default:             qtbz2_usage(EXIT_FAILURE);
+		case TBZ2_ACT_JOIN:
+			err("Join usage: <input tar.bz2> <input xpak> [<output tbz2>]");
+		case TBZ2_ACT_SPLIT:
+			err("Split usage: <input tbz2> [<output tar.bz2> <output xpak>]");
+		default:
+			qtbz2_usage(EXIT_FAILURE);
 		}
 	}
 
@@ -281,8 +267,8 @@ int qtbz2_main(int argc, char **argv)
 		else if (strstr(argv[optind], ".tbz2") != NULL)
 			action = TBZ2_ACT_SPLIT;
 		else
-			err("%s: need to use -j or -s, or file must end in .tar.bz2 or .tbz2 to autodetect",
-				argv[optind]);
+			err("%s: need to use -j or -s, or file must end "
+					"in .tar.bz2 or .tbz2 to autodetect", argv[optind]);
 	}
 
 	/* tbz2tool join .tar.bz2 .xpak .tbz2 */
@@ -357,8 +343,7 @@ int qtbz2_main(int argc, char **argv)
 	}
 
 	/* We have to cleanup all resources as we're used indirectly
-	 * (e.g. via qmerge).
-	 */
+	 * (e.g. via qmerge). */
 	free(heap_tbz2);
 	free(heap_xpak);
 	free(heap_tarbz2);
@@ -367,7 +352,3 @@ int qtbz2_main(int argc, char **argv)
 
 	return EXIT_SUCCESS;
 }
-
-#else
-DEFINE_APPLET_STUB(qtbz2)
-#endif

diff --git a/qtegrity.c b/qtegrity.c
index 7436aa2..2e3b859 100644
--- a/qtegrity.c
+++ b/qtegrity.c
@@ -7,10 +7,13 @@
  * Copyright 2017-2018 Sam Besselink
  */
 
-#ifdef APPLET_qtegrity
+#include "main.h"
+#include "applets.h"
 
+#include <string.h>
 #include <sys/types.h>
 #include <signal.h>
+#include <fcntl.h>
 
 #define QTEGRITY_FLAGS "a:is" COMMON_FLAGS
 static struct option const qtegrity_long_opts[] = {
@@ -56,6 +59,9 @@ struct qtegrity_opt_state {
 
 static void external_check_sha(char * ret_digest, char * filepath, char * algo) {
 	size_t size_digest = 1;
+	char cmd[11];
+	int pipefd[2];
+	pid_t pid;
 
 	if (strcmp(algo, "sha256") == 0) {
 		size_digest = 64;
@@ -67,12 +73,8 @@ static void external_check_sha(char * ret_digest, char * filepath, char * algo)
 		return;
 	}
 
-	char cmd[11];
 	snprintf(cmd, 10, "%ssum", algo);
 
-	int pipefd[2];
-	pid_t pid;
-
 	if (pipe(pipefd) == -1) {
 		perror("Couldn't create pipe to shasum\n");
 		exit(1);
@@ -504,7 +506,3 @@ int qtegrity_main(int argc, char **argv)
 
 	return EXIT_SUCCESS;
 }
-
-#else
-DEFINE_APPLET_STUB(qtegrity)
-#endif

diff --git a/quse.c b/quse.c
index 1fd4f3a..62ae166 100644
--- a/quse.c
+++ b/quse.c
@@ -7,7 +7,22 @@
  * Copyright 2018-     Fabian Groffen  - <grobian@gentoo.org>
  */
 
-#ifdef APPLET_quse
+#include "main.h"
+#include "applets.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <xalloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <assert.h>
+
+#include "cache.h"
+#include "rmspace.h"
+#include "xarray.h"
+#include "xregex.h"
 
 /*
  quse -CKe -- '-*' {'~',-,}{alpha,amd64,hppa,ia64,ppc,ppc64,sparc,x86}
@@ -88,7 +103,11 @@ quse_describe_flag(const char *overlay, unsigned int ind, unsigned int argc, cha
 	char *buf, *p;
 	unsigned int i, f;
 	size_t s;
-	const char * const search_files[] = { "use.desc", "use.local.desc", "arch.list", };
+	const char * const search_files[] = {
+		"use.desc",
+		"use.local.desc",
+		"arch.list"
+	};
 	FILE *fp[NUM_SEARCH_FILES];
 	int dfd, fd;
 	DIR *d;
@@ -218,7 +237,8 @@ quse_describe_flag(const char *overlay, unsigned int ind, unsigned int argc, cha
 
 			for (i = ind; i < argc; i++)
 				if (!strcmp(argv[i], buf))
-					printf(" %s%s%s:%s%s%s: %s\n", BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p);
+					printf(" %s%s%s:%s%s%s: %s\n",
+							BOLD, de->d_name, NORM, BLUE, argv[i], NORM, p);
 		}
 		fclose(fp[0]);
 	}
@@ -243,7 +263,12 @@ int quse_main(int argc, char **argv)
 	char *ebuild;
 
 	const char *search_var = NULL;
-	const char *search_vars[] = { "IUSE=", "KEYWORDS=", "LICENSE=", search_var };
+	const char *search_vars[] = {
+		"IUSE=",
+		"KEYWORDS=",
+		"LICENSE=",
+		search_var
+	};
 	short quse_all = 0;
 	int regexp_matching = 1, i, idx = 0;
 	size_t search_len;
@@ -277,6 +302,8 @@ int quse_main(int argc, char **argv)
 	assert(search_len < sizeof(buf0));
 
 	array_for_each(overlays, n, overlay) {
+		int overlay_fd;
+
 		cache_file = initialize_flat(overlay, CACHE_EBUILD, false);
 
 		if ((fp = fopen(cache_file, "re")) == NULL) {
@@ -284,7 +311,7 @@ int quse_main(int argc, char **argv)
 			continue;
 		}
 
-		int overlay_fd = open(overlay, O_RDONLY|O_CLOEXEC|O_PATH);
+		overlay_fd = open(overlay, O_RDONLY|O_CLOEXEC|O_PATH);
 
 		ebuild = NULL;
 		while ((linelen = getline(&ebuild, &ebuildlen, fp)) >= 0) {
@@ -299,24 +326,12 @@ int quse_main(int argc, char **argv)
 			newfp = fdopen(fd, "r");
 			if (newfp != NULL) {
 				unsigned int lineno = 0;
-				char revision[sizeof(buf0)];
-				char date[sizeof(buf0)];
-				char user[sizeof(buf0)];
 
-				revision[0] = 0;
-				user[0] = 0;
-				date[0] = 0;
 				while (fgets(buf0, sizeof(buf0), newfp) != NULL) {
 					int ok = 0;
 					char warned = 0;
 					lineno++;
 
-					if (*buf0 == '#') {
-						if (strncmp(buf0, "# $Header: /", 12) == 0)
-							sscanf(buf0, "%*s %*s %*s %s %s %*s %s %*s %*s",
-								revision, date, user);
-						continue;
-					}
 					if (strncmp(buf0, search_vars[idx], search_len) != 0)
 						continue;
 
@@ -417,14 +432,9 @@ int quse_main(int argc, char **argv)
 						}
 					}
 					if (ok) {
-						if (verbose > 3)
-							printf("%s %s %s ",
-								*user ? user : "MISSING",
-								*revision ? revision : "MISSING",
-								*date ? date : "MISSING");
-
 						printf("%s%s%s ", CYAN, ebuild, NORM);
-						print_highlighted_use_flags(&buf0[search_len + 1], optind, argc, argv);
+						print_highlighted_use_flags(&buf0[search_len + 1],
+								optind, argc, argv);
 						puts(NORM);
 						if (verbose > 1) {
 							char **ARGV;
@@ -438,9 +448,7 @@ int quse_main(int argc, char **argv)
 				}
 				fclose(newfp);
 			} else {
-				if (!reinitialize)
-					warnfp("(cache update pending) %s", ebuild);
-				reinitialize = 1;
+				warnf("missing cache, please (re)generate");
 			}
 		}
 		fclose(fp);
@@ -449,7 +457,3 @@ int quse_main(int argc, char **argv)
 
 	return EXIT_SUCCESS;
 }
-
-#else
-DEFINE_APPLET_STUB(quse)
-#endif

diff --git a/qxpak.c b/qxpak.c
index bdd5294..eb19cae 100644
--- a/qxpak.c
+++ b/qxpak.c
@@ -1,32 +1,25 @@
 /*
- * Copyright 2005-2018 Gentoo Foundation
+ * Copyright 2005-2019 Gentoo Foundation
  * Distributed under the terms of the GNU General Public License v2
  *
  * Copyright 2005-2010 Ned Ludd        - <solar@gentoo.org>
  * Copyright 2005-2014 Mike Frysinger  - <vapier@gentoo.org>
  */
 
-#ifdef APPLET_qxpak
+#include "main.h"
+#include "applets.h"
 
-/*
-# The format for a tbz2/xpak:
-#
-#  tbz2: tar.bz2 + xpak + (xpak_offset) + "STOP"
-#  xpak: "XPAKPACK" + (index_len) + (data_len) + index + data + "XPAKSTOP"
-# index: (pathname_len) + pathname + (data_offset) + (data_len)
-#        index entries are concatenated end-to-end.
-#  data: concatenated data chunks, end-to-end.
-#
-# [tarball]XPAKPACKIIIIDDDD[index][data]XPAKSTOPOOOOSTOP
-#
-# (integer) == encodeint(integer)  ===> 4 characters (big-endian copy)
-# '+' means concatenate the fields ===> All chunks are strings
-*/
-#define XPAK_START_MSG       "XPAKPACK"
-#define XPAK_START_MSG_LEN   8
-#define XPAK_START_LEN       (8 + 4 + 4)
-#define XPAK_END_MSG         "XPAKSTOP"
-#define XPAK_END_MSG_LEN     8
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "basename.h"
+#include "copy_file.h"
+#include "safe_io.h"
+#include "scandirat.h"
+#include "xpak.h"
 
 #define QXPAK_FLAGS "lxcd:O" COMMON_FLAGS
 static struct option const qxpak_long_opts[] = {
@@ -47,100 +40,21 @@ static const char * const qxpak_opts_help[] = {
 };
 #define qxpak_usage(ret) usage(ret, QXPAK_FLAGS, qxpak_long_opts, qxpak_opts_help, NULL, lookup_applet_idx("qxpak"))
 
-typedef struct {
-	int dir_fd;
-	FILE *fp;
-	int index_len;
-	int data_len;
-	char *index, *data;
-} _xpak_archive;
-
 static char xpak_stdout;
 
-typedef void (*xpak_callback_t)(int,char*,int,int,int,char*);
-
-static void _xpak_walk_index(_xpak_archive *x, int argc, char **argv, xpak_callback_t func)
-{
-	int i, pathname_len, data_offset, data_len;
-	char *p, pathname[100];
-
-	p = x->index;
-	while ((p - x->index) < x->index_len) {
-		pathname_len = tbz2_decode_int((unsigned char*)p);
-		assert((size_t)pathname_len < sizeof(pathname));
-		p += 4;
-		memcpy(pathname, p, pathname_len);
-		pathname[pathname_len] = '\0';
-		if (strchr(pathname, '/') != NULL || strchr(pathname, '\\') != NULL)
-			err("Index contains a file with a path: '%s'", pathname);
-		p += pathname_len;
-		data_offset = tbz2_decode_int((unsigned char*)p);
-		p += 4;
-		data_len = tbz2_decode_int((unsigned char*)p);
-		p += 4;
-		if (argc) {
-			for (i = 0; i < argc; ++i)
-				if (argv[i] && !strcmp(pathname, argv[i])) {
-					argv[i] = NULL;
-					break;
-				}
-			if (i == argc)
-				continue;
-		}
-		(*func)(x->dir_fd, pathname, pathname_len, data_offset, data_len, x->data);
-	}
-
-	if (argc)
-		for (i = 0; i < argc; ++i)
-			if (argv[i])
-				warn("Could not locate '%s' in archive", argv[i]);
-}
-
-static _xpak_archive *_xpak_open(const char *file)
-{
-	static _xpak_archive ret;
-	char buf[XPAK_START_LEN];
-
-	/* init the file */
-	memset(&ret, 0x00, sizeof(ret));
-	if (file[0] == '-' && file[1] == '\0')
-		ret.fp = stdin;
-	else if ((ret.fp = fopen(file, "r")) == NULL)
-		return NULL;
-
-	/* verify this xpak doesnt suck */
-	if (fread(buf, 1, XPAK_START_LEN, ret.fp) != XPAK_START_LEN)
-		goto close_and_ret;
-	if (memcmp(buf, XPAK_START_MSG, XPAK_START_MSG_LEN)) {
-		warn("%s: Invalid xpak", file);
-		goto close_and_ret;
-	}
-
-	/* calc index and data sizes */
-	ret.index_len = tbz2_decode_int((unsigned char*)buf+XPAK_START_MSG_LEN);
-	ret.data_len = tbz2_decode_int((unsigned char*)buf+XPAK_START_MSG_LEN+4);
-	if (!ret.index_len || !ret.data_len) {
-		warn("Skipping empty archive '%s'", file);
-		goto close_and_ret;
-	}
-
-	return &ret;
-
-close_and_ret:
-	if (ret.fp != stdin)
-		fclose(ret.fp);
-	return NULL;
-}
-
-static void _xpak_close(_xpak_archive *x)
-{
-	fclose(x->fp);
-}
-
 static void
-_xpak_list_callback(_q_unused_ int dir_fd, char *pathname, _q_unused_ int pathname_len,
-                    int data_offset, int data_len, _q_unused_ char *data)
+_xpak_list_callback(
+		int dir_fd,
+		char *pathname,
+		int pathname_len,
+		int data_offset,
+		int data_len,
+		char *data)
 {
+	(void)dir_fd;
+	(void)pathname_len;
+	(void)data;
+
 	if (!verbose)
 		puts(pathname);
 	else if (verbose == 1)
@@ -149,34 +63,18 @@ _xpak_list_callback(_q_unused_ int dir_fd, char *pathname, _q_unused_ int pathna
 		printf("%s: %i byte%c @ offset byte %i\n",
 			pathname, data_len, (data_len>1?'s':' '), data_offset);
 }
-static int
-xpak_list(int dir_fd, const char *file, int argc, char **argv)
-{
-	_xpak_archive *x;
-	char buf[BUFSIZE];
-	size_t ret;
-
-	x = _xpak_open(file);
-	if (!x)
-		return 1;
-
-	x->dir_fd = dir_fd;
-	x->index = buf;
-	assert((size_t)x->index_len < sizeof(buf));
-	ret = fread(x->index, 1, x->index_len, x->fp);
-	assert(ret == (size_t)x->index_len);
-	_xpak_walk_index(x, argc, argv, &_xpak_list_callback);
-
-	_xpak_close(x);
-
-	return 0;
-}
 
 static void
-_xpak_extract_callback(int dir_fd, char *pathname, _q_unused_ int pathname_len,
-                       int data_offset, int data_len, char *data)
+_xpak_extract_callback(
+	int dir_fd,
+	char *pathname,
+	int pathname_len,
+	int data_offset,
+	int data_len,
+	char *data)
 {
 	FILE *out;
+	(void)pathname_len;
 
 	if (verbose == 1)
 		puts(pathname);
@@ -184,7 +82,8 @@ _xpak_extract_callback(int dir_fd, char *pathname, _q_unused_ int pathname_len,
 		printf("%s: %i byte%c\n", pathname, data_len, (data_len>1?'s':' '));
 
 	if (!xpak_stdout) {
-		int fd = openat(dir_fd, pathname, O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC, 0644);
+		int fd = openat(dir_fd, pathname,
+				O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC, 0644);
 		if (fd < 0)
 			return;
 		out = fdopen(fd, "w");
@@ -198,190 +97,6 @@ _xpak_extract_callback(int dir_fd, char *pathname, _q_unused_ int pathname_len,
 	if (!xpak_stdout)
 		fclose(out);
 }
-static int
-xpak_extract(int dir_fd, const char *file, int argc, char **argv)
-{
-	_xpak_archive *x;
-	char buf[BUFSIZE], ext[BUFSIZE*32];
-	size_t in;
-
-	x = _xpak_open(file);
-	if (!x)
-		return 1;
-
-	x->dir_fd = dir_fd;
-	x->index = buf;
-
-	assert((size_t)x->index_len < sizeof(buf));
-	in = fread(x->index, 1, x->index_len, x->fp);
-	if ((int)in != x->index_len)
-		err("index chunk: read %i bytes, wanted %i bytes", (int)in, x->index_len);
-
-	/* the xpak may be large (like when it has CONTENTS) #300744 */
-	x->data = (size_t)x->data_len < sizeof(ext) ? ext : xmalloc(x->data_len);
-	in = fread(x->data, 1, x->data_len, x->fp);
-	if ((int)in != x->data_len)
-		err("data chunk: read %i bytes, wanted %i bytes", (int)in, x->data_len);
-
-	_xpak_walk_index(x, argc, argv, &_xpak_extract_callback);
-
-	_xpak_close(x);
-
-	if (x->data != ext)
-		free(x->data);
-
-	return 0;
-}
-
-static void
-_xpak_add_file(int dir_fd, const char *filename, struct stat *st, FILE *findex,
-               int *index_len, FILE *fdata, int *data_len)
-{
-	FILE *fin;
-	unsigned char *p;
-	const char *basefile;
-	int fd, in_len;
-
-	if ((basefile = strrchr(filename, '/')) == NULL) {
-		basefile = filename;
-	} else {
-		++basefile;
-		assert(*basefile);
-	}
-
-	if (verbose == 1)
-		printf("%s\n", basefile);
-	else if (verbose)
-		printf("%s @ offset byte %i\n", basefile, *data_len);
-
-	/* write out the (pathname_len) */
-	in_len = strlen(basefile);
-	p = tbz2_encode_int(in_len);
-	fwrite(p, 1, 4, findex);
-	/* write out the pathname */
-	fwrite(basefile, 1, in_len, findex);
-	/* write out the (data_offset) */
-	p = tbz2_encode_int(*data_len);
-	fwrite(p, 1, 4, findex);
-
-	*index_len += 4 + in_len + 4 + 4;
-
-	/* now open the file, get (data_len), and append the file to the data file */
-	fd = openat(dir_fd, filename, O_RDONLY|O_CLOEXEC);
-	if (fd < 0) {
- open_fail:
-		warnp("could not open for reading: %s", filename);
- fake_data_len:
-		p = tbz2_encode_int(0);
-		fwrite(p, 1, 4, findex);
-		return;
-	}
-	fin = fdopen(fd, "r");
-	if (!fin) {
-		close(fd);
-		goto open_fail;
-	}
-	in_len = st->st_size;
-	/* the xpak format can only store files whose size is a 32bit int
-	 * so we have to make sure we don't store a big file */
-	if (in_len != st->st_size) {
-		warnf("File is too big: %"PRIu64, (uint64_t)st->st_size);
-		fclose(fin);
-		goto fake_data_len;
-	}
-	p = tbz2_encode_int(in_len);
-	fwrite(p, 1, 4, findex);
-	_tbz2_copy_file(fin, fdata);
-	fclose(fin);
-
-	*data_len += in_len;
-}
-static int
-xpak_create(int dir_fd, const char *file, int argc, char **argv)
-{
-	FILE *findex, *fdata, *fout;
-	struct dirent **dir;
-	int i, fidx, numfiles;
-	struct stat st;
-	char path[_Q_PATH_MAX];
-	unsigned char *p;
-	int index_len, data_len;
-
-	if (argc == 0)
-		err("Create usage: <xpak output> <files/dirs to pack>");
-
-	if (strlen(file) >= sizeof(path)-6)
-		err("Pathname is too long: %s", file);
-
-	if ((fout = fopen(file, "w")) == NULL) {
-		warnp("could not open output: %s", file);
-		return 1;
-	}
-	strcpy(path, file); strcat(path, ".index");
-	if ((findex = fopen(path, "w+")) == NULL) {
-		warnp("could not open output: %s", path);
-		fclose(fout);
-		return 1;
-	}
-	strcpy(path, file); strcat(path, ".dat");
-	if ((fdata = fopen(path, "w+")) == NULL) {
-		warnp("could not open output: %s", path);
-		fclose(fout);
-		fclose(findex);
-		return 1;
-	}
-
-	index_len = data_len = 0;
-	for (i = 0; i < argc; ++i) {
-		if (fstatat(dir_fd, argv[i], &st, 0)) {
-			warnp("fstatat(%s) failed", argv[i]);
-			continue;
-		}
-		if (S_ISDIR(st.st_mode)) {
-			if ((numfiles = scandir(argv[i], &dir, filter_hidden, alphasort)) < 0)
-				warn("Directory '%s' is empty; skipping", argv[i]);
-			for (fidx = 0; fidx < numfiles; ++fidx) {
-				int ret = snprintf(path, sizeof(path), "%s/%s",
-						argv[i], dir[fidx]->d_name);
-				if (ret < 0 || (size_t)ret >= sizeof(path)) {
-					warn("skipping path too long: %s/%s",
-							argv[i], dir[fidx]->d_name);
-					continue;
-				}
-				if (stat(path, &st) < 0) {
-					warnp("could not read %s", path);
-					continue;
-				}
-				_xpak_add_file(dir_fd, path, &st, findex, &index_len, fdata, &data_len);
-			}
-			scandir_free(dir, numfiles);
-		} else if (S_ISREG(st.st_mode)) {
-			_xpak_add_file(dir_fd, argv[i], &st, findex, &index_len, fdata, &data_len);
-		} else
-			warn("Skipping non file/directory '%s'", argv[i]);
-	}
-
-	rewind(findex);
-	rewind(fdata);
-
-	/* "XPAKPACK" + (index_len) + (data_len) + index + data + "XPAKSTOP" */
-	fwrite(XPAK_START_MSG, 1, XPAK_START_MSG_LEN, fout); /* "XPAKPACK" */
-	p = tbz2_encode_int(index_len);
-	fwrite(p, 1, 4, fout);                               /* (index_len) */
-	p = tbz2_encode_int(data_len);
-	fwrite(p, 1, 4, fout);                               /* (data_len) */
-	_tbz2_copy_file(findex, fout);                       /* index */
-	_tbz2_copy_file(fdata, fout);                        /* data */
-	fwrite(XPAK_END_MSG, 1, XPAK_END_MSG_LEN, fout);     /* "XPAKSTOP" */
-
-	strcpy(path, file); strcat(path, ".index"); unlink(path);
-	strcpy(path, file); strcat(path, ".dat");   unlink(path);
-	fclose(findex);
-	fclose(fdata);
-	fclose(fout);
-
-	return 0;
-}
 
 int qxpak_main(int argc, char **argv)
 {
@@ -417,10 +132,17 @@ int qxpak_main(int argc, char **argv)
 	argv += optind;
 
 	switch (action) {
-	case XPAK_ACT_LIST:    ret = xpak_list(dir_fd, xpak, argc, argv); break;
-	case XPAK_ACT_EXTRACT: ret = xpak_extract(dir_fd, xpak, argc, argv); break;
-	case XPAK_ACT_CREATE:  ret = xpak_create(dir_fd, xpak, argc, argv); break;
-	default: ret = EXIT_FAILURE;
+	case XPAK_ACT_LIST:
+		ret = xpak_list(dir_fd, xpak, argc, argv, &_xpak_list_callback);
+		break;
+	case XPAK_ACT_EXTRACT:
+		ret = xpak_extract(dir_fd, xpak, argc, argv, &_xpak_extract_callback);
+		break;
+	case XPAK_ACT_CREATE:
+		ret = xpak_create(dir_fd, xpak, argc, argv, 0, verbose);
+		break;
+	default:
+		ret = EXIT_FAILURE;
 	}
 
 	if (dir_fd != AT_FDCWD)
@@ -428,7 +150,3 @@ int qxpak_main(int argc, char **argv)
 
 	return ret;
 }
-
-#else
-DEFINE_APPLET_STUB(qxpak)
-#endif


             reply	other threads:[~2019-03-27 10:56 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-27 10:55 Fabian Groffen [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-06-27 19:19 [gentoo-commits] proj/portage-utils:master commit in: libq/, / Fabian Groffen
2024-03-29 10:57 Fabian Groffen
2024-01-02  7:57 Fabian Groffen
2023-02-07  8:25 Fabian Groffen
2023-02-07  8:10 Fabian Groffen
2021-08-16 13:23 Fabian Groffen
2020-02-21  8:18 Fabian Groffen
2020-01-05 13:28 Fabian Groffen
2020-01-02 11:19 Fabian Groffen
2020-01-01 19:52 Fabian Groffen
2019-12-31  9:05 Fabian Groffen
2019-12-30 17:24 Fabian Groffen
2019-12-29 13:26 Fabian Groffen
2019-12-27 16:57 Fabian Groffen
2019-07-13 10:04 Fabian Groffen
2019-06-19 10:44 Fabian Groffen
2019-06-05  9:15 Fabian Groffen
2019-05-09 20:19 Fabian Groffen
2019-05-05 18:13 Fabian Groffen
2019-04-28 15:20 Fabian Groffen
2019-03-27 20:18 Fabian Groffen
2019-03-22  9:57 Fabian Groffen
2019-03-19 20:32 Fabian Groffen
2019-03-19 20:32 Fabian Groffen
2019-03-09 18:58 Fabian Groffen
2018-03-23 11:56 Fabian Groffen
2016-12-29  2:25 Mike Frysinger
2016-11-26 23:17 Mike Frysinger
2015-11-28  2:44 Mike Frysinger
2015-02-24  1:26 Mike Frysinger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1553684038.d0a8d231167adddb80a73849d3bc70edbfda3507.grobian@gentoo \
    --to=grobian@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox