summaryrefslogtreecommitdiffstats
path: root/dpkg-deb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dpkg-deb/Makefile.am25
-rw-r--r--dpkg-deb/Makefile.in744
-rw-r--r--dpkg-deb/build.c682
-rw-r--r--dpkg-deb/dpkg-deb.h87
-rw-r--r--dpkg-deb/extract.c499
-rw-r--r--dpkg-deb/info.c305
-rw-r--r--dpkg-deb/main.c257
7 files changed, 2599 insertions, 0 deletions
diff --git a/dpkg-deb/Makefile.am b/dpkg-deb/Makefile.am
new file mode 100644
index 0000000..02d79ed
--- /dev/null
+++ b/dpkg-deb/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+localedir = $(datadir)/locale
+AM_CPPFLAGS = \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -idirafter $(top_srcdir)/lib/compat \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/lib
+
+
+bin_PROGRAMS = dpkg-deb
+
+dpkg_deb_SOURCES = \
+ dpkg-deb.h \
+ build.c \
+ extract.c \
+ info.c \
+ main.c
+
+dpkg_deb_LDADD = \
+ ../lib/dpkg/libdpkg.la \
+ $(LIBINTL) \
+ $(Z_LIBS) \
+ $(LZMA_LIBS) \
+ $(BZ2_LIBS)
diff --git a/dpkg-deb/Makefile.in b/dpkg-deb/Makefile.in
new file mode 100644
index 0000000..2be0f96
--- /dev/null
+++ b/dpkg-deb/Makefile.in
@@ -0,0 +1,744 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = dpkg-deb$(EXEEXT)
+subdir = dpkg-deb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/dpkg-arch.m4 \
+ $(top_srcdir)/m4/dpkg-build.m4 \
+ $(top_srcdir)/m4/dpkg-compiler.m4 \
+ $(top_srcdir)/m4/dpkg-coverage.m4 \
+ $(top_srcdir)/m4/dpkg-funcs.m4 $(top_srcdir)/m4/dpkg-libs.m4 \
+ $(top_srcdir)/m4/dpkg-linker.m4 $(top_srcdir)/m4/dpkg-progs.m4 \
+ $(top_srcdir)/m4/dpkg-types.m4 \
+ $(top_srcdir)/m4/dpkg-unicode.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_dpkg_deb_OBJECTS = build.$(OBJEXT) extract.$(OBJEXT) info.$(OBJEXT) \
+ main.$(OBJEXT)
+dpkg_deb_OBJECTS = $(am_dpkg_deb_OBJECTS)
+am__DEPENDENCIES_1 =
+dpkg_deb_DEPENDENCIES = ../lib/dpkg/libdpkg.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES =
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/build.Po ./$(DEPDIR)/extract.Po \
+ ./$(DEPDIR)/info.Po ./$(DEPDIR)/main.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(dpkg_deb_SOURCES)
+DIST_SOURCES = $(dpkg_deb_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOM4TE = @AUTOM4TE@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_DEVEL_DOCS = @BUILD_DEVEL_DOCS@
+BZ2_LIBS = @BZ2_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURSES_LIBS = @CURSES_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCOV = @GCOV@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_DOT = @HAVE_DOT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+KVM_LIBS = @KVM_LIBS@
+LCOV = @LCOV@
+LCOV_GENHTML = @LCOV_GENHTML@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZMA_LIBS = @LZMA_LIBS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MD_LIBS = @MD_LIBS@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_BUG_WEB = @PACKAGE_BUG_WEB@
+PACKAGE_COPYRIGHT_HOLDER = @PACKAGE_COPYRIGHT_HOLDER@
+PACKAGE_CPAN_NAME = @PACKAGE_CPAN_NAME@
+PACKAGE_DIST_IS_RELEASE = @PACKAGE_DIST_IS_RELEASE@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_RELEASE_DATE = @PACKAGE_RELEASE_DATE@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VCS_TYPE = @PACKAGE_VCS_TYPE@
+PACKAGE_VCS_URL = @PACKAGE_VCS_URL@
+PACKAGE_VCS_WEB = @PACKAGE_VCS_WEB@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATCH = @PATCH@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PERL_COVER = @PERL_COVER@
+PERL_COVERAGE = @PERL_COVERAGE@
+PERL_LIBDIR = @PERL_LIBDIR@
+PERL_MIN_VERSION = @PERL_MIN_VERSION@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PO4A = @PO4A@
+POD2MAN = @POD2MAN@
+POSUB = @POSUB@
+PS_LIBS = @PS_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
+SELINUX_LIBS = @SELINUX_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TAR = @TAR@
+USE_NLS = @USE_NLS@
+USE_PO4A = @USE_PO4A@
+USE_UNICODE = @USE_UNICODE@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+admindir = @admindir@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+devlibdir = @devlibdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = $(datadir)/locale
+localstatedir = @localstatedir@
+logdir = @logdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgconfdir = @pkgconfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -idirafter $(top_srcdir)/lib/compat \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/lib
+
+dpkg_deb_SOURCES = \
+ dpkg-deb.h \
+ build.c \
+ extract.c \
+ info.c \
+ main.c
+
+dpkg_deb_LDADD = \
+ ../lib/dpkg/libdpkg.la \
+ $(LIBINTL) \
+ $(Z_LIBS) \
+ $(LZMA_LIBS) \
+ $(BZ2_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dpkg-deb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign dpkg-deb/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+dpkg-deb$(EXEEXT): $(dpkg_deb_OBJECTS) $(dpkg_deb_DEPENDENCIES) $(EXTRA_dpkg_deb_DEPENDENCIES)
+ @rm -f dpkg-deb$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(dpkg_deb_OBJECTS) $(dpkg_deb_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/build.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/build.Po
+ -rm -f ./$(DEPDIR)/extract.Po
+ -rm -f ./$(DEPDIR)/info.Po
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/build.Po
+ -rm -f ./$(DEPDIR)/extract.Po
+ -rm -f ./$(DEPDIR)/info.Po
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
new file mode 100644
index 0000000..3317b51
--- /dev/null
+++ b/dpkg-deb/build.c
@@ -0,0 +1,682 @@
+/*
+ * dpkg-deb - construction and deconstruction of *.deb archives
+ * build.c - building archives
+ *
+ * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright © 2000,2001 Wichert Akkerman <wakkerma@debian.org>
+ * Copyright © 2007-2015 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <time.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/i18n.h>
+#include <dpkg/c-ctype.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/path.h>
+#include <dpkg/treewalk.h>
+#include <dpkg/varbuf.h>
+#include <dpkg/fdio.h>
+#include <dpkg/buffer.h>
+#include <dpkg/subproc.h>
+#include <dpkg/command.h>
+#include <dpkg/compress.h>
+#include <dpkg/ar.h>
+#include <dpkg/options.h>
+
+#include "dpkg-deb.h"
+
+static void
+control_treewalk_feed(const char *dir, int fd_out)
+{
+ struct treeroot *tree;
+ struct treenode *node;
+
+ tree = treewalk_open(dir, TREEWALK_NONE, NULL);
+ for (node = treewalk_node(tree); node; node = treewalk_next(tree)) {
+ char *nodename;
+
+ nodename = str_fmt("./%s", treenode_get_virtname(node));
+ if (fd_write(fd_out, nodename, strlen(nodename) + 1) < 0)
+ ohshite(_("failed to write filename to tar pipe (%s)"),
+ _("control member"));
+ free(nodename);
+ }
+ treewalk_close(tree);
+}
+
+/**
+ * Simple structure to store information about a file.
+ */
+struct file_info {
+ struct file_info *next;
+ char *fn;
+};
+
+static struct file_info *
+file_info_new(const char *filename)
+{
+ struct file_info *fi;
+
+ fi = m_malloc(sizeof(*fi));
+ fi->fn = m_strdup(filename);
+ fi->next = NULL;
+
+ return fi;
+}
+
+static void
+file_info_free(struct file_info *fi)
+{
+ free(fi->fn);
+ free(fi);
+}
+
+static struct file_info *
+file_info_find_name(struct file_info *list, const char *filename)
+{
+ struct file_info *node;
+
+ for (node = list; node; node = node->next)
+ if (strcmp(node->fn, filename) == 0)
+ return node;
+
+ return NULL;
+}
+
+/**
+ * Add a new file_info struct to a single linked list of file_info structs.
+ *
+ * We perform a slight optimization to work around a ‘feature’ in tar: tar
+ * always recurses into subdirectories if you list a subdirectory. So if an
+ * entry is added and the previous entry in the list is its subdirectory we
+ * remove the subdirectory.
+ *
+ * After a file_info struct is added to a list it may no longer be freed, we
+ * assume full responsibility for its memory.
+ */
+static void
+file_info_list_append(struct file_info **head, struct file_info **tail,
+ struct file_info *fi)
+{
+ if (*head == NULL)
+ *head = *tail = fi;
+ else
+ *tail = (*tail)->next =fi;
+}
+
+/**
+ * Free the memory for all entries in a list of file_info structs.
+ */
+static void
+file_info_list_free(struct file_info *fi)
+{
+ while (fi) {
+ struct file_info *fl;
+
+ fl=fi; fi=fi->next;
+ file_info_free(fl);
+ }
+}
+
+static void
+file_treewalk_feed(const char *dir, int fd_out)
+{
+ struct treeroot *tree;
+ struct treenode *node;
+ struct file_info *fi;
+ struct file_info *symlist = NULL;
+ struct file_info *symlist_end = NULL;
+
+ tree = treewalk_open(dir, TREEWALK_NONE, NULL);
+ for (node = treewalk_node(tree); node ; node = treewalk_next(tree)) {
+ const char *virtname = treenode_get_virtname(node);
+ char *nodename;
+
+ if (strncmp(virtname, BUILDCONTROLDIR, strlen(BUILDCONTROLDIR)) == 0)
+ continue;
+
+ nodename = str_fmt("./%s", virtname);
+
+ if (!nocheckflag && strchr(nodename, '\n'))
+ ohshit(_("newline not allowed in pathname '%s'"), nodename);
+
+ /* We need to reorder the files so we can make sure that symlinks
+ * will not appear before their target. */
+ if (S_ISLNK(treenode_get_mode(node))) {
+ fi = file_info_new(nodename);
+ file_info_list_append(&symlist, &symlist_end, fi);
+ } else {
+ if (fd_write(fd_out, nodename, strlen(nodename) + 1) < 0)
+ ohshite(_("failed to write filename to tar pipe (%s)"),
+ _("data member"));
+ }
+
+ free(nodename);
+ }
+ treewalk_close(tree);
+
+ for (fi = symlist; fi; fi = fi->next)
+ if (fd_write(fd_out, fi->fn, strlen(fi->fn) + 1) < 0)
+ ohshite(_("failed to write filename to tar pipe (%s)"), _("data member"));
+
+ file_info_list_free(symlist);
+}
+
+static const char *const maintainerscripts[] = {
+ PREINSTFILE,
+ POSTINSTFILE,
+ PRERMFILE,
+ POSTRMFILE,
+ MAINTSCRIPT_FILE_CONFIG,
+ NULL,
+};
+
+/**
+ * Check control directory and file permissions.
+ */
+static void
+check_file_perms(const char *ctrldir)
+{
+ struct varbuf path = VARBUF_INIT;
+ const char *const *mscriptp;
+ struct stat mscriptstab;
+
+ varbuf_printf(&path, "%s/", ctrldir);
+ if (lstat(path.buf, &mscriptstab))
+ ohshite(_("unable to stat control directory"));
+ if (!S_ISDIR(mscriptstab.st_mode))
+ ohshit(_("control directory is not a directory"));
+ if ((mscriptstab.st_mode & 07757) != 0755)
+ ohshit(_("control directory has bad permissions %03lo "
+ "(must be >=0755 and <=0775)"),
+ (unsigned long)(mscriptstab.st_mode & 07777));
+
+ for (mscriptp = maintainerscripts; *mscriptp; mscriptp++) {
+ varbuf_reset(&path);
+ varbuf_printf(&path, "%s/%s", ctrldir, *mscriptp);
+ if (!lstat(path.buf, &mscriptstab)) {
+ if (S_ISLNK(mscriptstab.st_mode))
+ continue;
+ if (!S_ISREG(mscriptstab.st_mode))
+ ohshit(_("maintainer script '%.50s' is not a plain file or symlink"),
+ *mscriptp);
+ if ((mscriptstab.st_mode & 07557) != 0555)
+ ohshit(_("maintainer script '%.50s' has bad permissions %03lo "
+ "(must be >=0555 and <=0775)"),
+ *mscriptp, (unsigned long)(mscriptstab.st_mode & 07777));
+ } else if (errno != ENOENT) {
+ ohshite(_("maintainer script '%.50s' is not stattable"), *mscriptp);
+ }
+ }
+
+ varbuf_destroy(&path);
+}
+
+/**
+ * Check if conffiles contains sane information.
+ */
+static void
+check_conffiles(const char *ctrldir, const char *rootdir)
+{
+ FILE *cf;
+ struct varbuf controlfile = VARBUF_INIT;
+ char conffilename[MAXCONFFILENAME + 1];
+ struct file_info *conffiles_head = NULL;
+ struct file_info *conffiles_tail = NULL;
+
+ varbuf_printf(&controlfile, "%s/%s", ctrldir, CONFFILESFILE);
+
+ cf = fopen(controlfile.buf, "r");
+ if (cf == NULL) {
+ if (errno == ENOENT)
+ return;
+
+ ohshite(_("error opening conffiles file"));
+ }
+
+ while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) {
+ struct stat controlstab;
+ int n;
+
+ n = strlen(conffilename);
+ if (!n)
+ ohshite(_("empty string from fgets reading conffiles"));
+
+ if (conffilename[n - 1] != '\n')
+ ohshit(_("conffile name '%s' is too long, or missing final newline"),
+ conffilename);
+
+ conffilename[n - 1] = '\0';
+ varbuf_reset(&controlfile);
+ varbuf_printf(&controlfile, "%s/%s", rootdir, conffilename);
+ if (lstat(controlfile.buf, &controlstab)) {
+ if (errno == ENOENT) {
+ if ((n > 1) && c_isspace(conffilename[n - 2]))
+ warning(_("conffile filename '%s' contains trailing white spaces"),
+ conffilename);
+ ohshit(_("conffile '%.250s' does not appear in package"), conffilename);
+ } else
+ ohshite(_("conffile '%.250s' is not stattable"), conffilename);
+ } else if (!S_ISREG(controlstab.st_mode)) {
+ warning(_("conffile '%s' is not a plain file"), conffilename);
+ }
+
+ if (file_info_find_name(conffiles_head, conffilename)) {
+ warning(_("conffile name '%s' is duplicated"), conffilename);
+ } else {
+ struct file_info *conffile;
+
+ conffile = file_info_new(conffilename);
+ file_info_list_append(&conffiles_head, &conffiles_tail, conffile);
+ }
+ }
+
+ file_info_list_free(conffiles_head);
+ varbuf_destroy(&controlfile);
+
+ if (ferror(cf))
+ ohshite(_("error reading conffiles file"));
+ fclose(cf);
+}
+
+/**
+ * Check the control file.
+ *
+ * @param ctrldir The directory from where to build the binary package.
+ * @return The pkginfo struct from the parsed control file.
+ */
+static struct pkginfo *
+check_control_file(const char *ctrldir)
+{
+ struct pkginfo *pkg;
+ char *controlfile;
+
+ controlfile = str_fmt("%s/%s", ctrldir, CONTROLFILE);
+ parsedb(controlfile, pdb_parse_binary, &pkg);
+
+ if (strspn(pkg->set->name, "abcdefghijklmnopqrstuvwxyz0123456789+-.") !=
+ strlen(pkg->set->name))
+ ohshit(_("package name has characters that aren't lowercase alphanums or '-+.'"));
+ if (pkg->available.arch->type == DPKG_ARCH_NONE ||
+ pkg->available.arch->type == DPKG_ARCH_EMPTY)
+ ohshit(_("package architecture is missing or empty"));
+ if (pkg->priority == PKG_PRIO_OTHER)
+ warning(_("'%s' contains user-defined Priority value '%s'"),
+ controlfile, pkg->otherpriority);
+
+ free(controlfile);
+
+ return pkg;
+}
+
+/**
+ * Perform some sanity checks on the to-be-built package control area.
+ *
+ * @param ctrldir The directory from where to build the binary package.
+ * @return The pkginfo struct from the parsed control file.
+ */
+static struct pkginfo *
+check_control_area(const char *ctrldir, const char *rootdir)
+{
+ struct pkginfo *pkg;
+ int warns;
+
+ /* Start by reading in the control file so we can check its contents. */
+ pkg = check_control_file(ctrldir);
+ check_file_perms(ctrldir);
+ check_conffiles(ctrldir, rootdir);
+
+ warns = warning_get_count();
+ if (warns)
+ warning(P_("ignoring %d warning about the control file(s)",
+ "ignoring %d warnings about the control file(s)", warns),
+ warns);
+
+ return pkg;
+}
+
+/**
+ * Generate the pathname for the destination binary package.
+ *
+ * If the pathname cannot be computed, because the destination is a directory,
+ * then NULL will be returned.
+ *
+ * @param dir The directory from where to build the binary package.
+ * @param dest The destination name, either a file or directory name.
+ * @return The pathname for the package being built.
+ */
+static char *
+gen_dest_pathname(const char *dir, const char *dest)
+{
+ if (dest) {
+ struct stat dest_stab;
+
+ if (stat(dest, &dest_stab)) {
+ if (errno != ENOENT)
+ ohshite(_("unable to check for existence of archive '%.250s'"), dest);
+ } else if (S_ISDIR(dest_stab.st_mode)) {
+ /* Need to compute the destination name from the package control file. */
+ return NULL;
+ }
+
+ return m_strdup(dest);
+ } else {
+ char *pathname;
+
+ pathname = m_malloc(strlen(dir) + sizeof(DEBEXT));
+ strcpy(pathname, dir);
+ path_trim_slash_slashdot(pathname);
+ strcat(pathname, DEBEXT);
+
+ return pathname;
+ }
+}
+
+/**
+ * Generate the pathname for the destination binary package from control file.
+ *
+ * @return The pathname for the package being built.
+ */
+static char *
+gen_dest_pathname_from_pkg(const char *dir, struct pkginfo *pkg)
+{
+ return str_fmt("%s/%s_%s_%s%s", dir, pkg->set->name,
+ versiondescribe(&pkg->available.version, vdew_never),
+ pkg->available.arch->name, DEBEXT);
+}
+
+typedef void filenames_feed_func(const char *dir, int fd_out);
+
+struct tar_pack_options {
+ time_t timestamp;
+ const char *mode;
+ bool root_owner_group;
+};
+
+/**
+ * Pack the contents of a directory into a tarball.
+ */
+static void
+tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
+ struct tar_pack_options *options,
+ struct compress_params *tar_compress_params, int fd_out)
+{
+ int pipe_filenames[2], pipe_tarball[2];
+ pid_t pid_tar, pid_comp;
+
+ /* Fork off a tar. We will feed it a list of filenames on stdin later. */
+ m_pipe(pipe_filenames);
+ m_pipe(pipe_tarball);
+ pid_tar = subproc_fork();
+ if (pid_tar == 0) {
+ struct command cmd;
+ char mtime[50];
+
+ m_dup2(pipe_filenames[0], 0);
+ close(pipe_filenames[0]);
+ close(pipe_filenames[1]);
+ m_dup2(pipe_tarball[1], 1);
+ close(pipe_tarball[0]);
+ close(pipe_tarball[1]);
+
+ if (chdir(dir))
+ ohshite(_("failed to chdir to '%.255s'"), dir);
+
+ snprintf(mtime, sizeof(mtime), "@%ld", options->timestamp);
+
+ command_init(&cmd, TAR, "tar -cf");
+ command_add_args(&cmd, "tar", "-cf", "-", "--format=gnu",
+ "--mtime", mtime, "--clamp-mtime", NULL);
+ /* Mode might become a positional argument, pass it before -T. */
+ if (options->mode)
+ command_add_args(&cmd, "--mode", options->mode, NULL);
+ if (options->root_owner_group)
+ command_add_args(&cmd, "--owner", "root:0", "--group", "root:0", NULL);
+ command_add_args(&cmd, "--null", "--no-unquote", "--no-recursion",
+ "-T", "-", NULL);
+ command_exec(&cmd);
+ }
+ close(pipe_filenames[0]);
+ close(pipe_tarball[1]);
+
+ /* Of course we should not forget to compress the archive as well. */
+ pid_comp = subproc_fork();
+ if (pid_comp == 0) {
+ close(pipe_filenames[1]);
+ compress_filter(tar_compress_params, pipe_tarball[0], fd_out,
+ _("compressing tar member"));
+ exit(0);
+ }
+ close(pipe_tarball[0]);
+
+ /* All the pipes are set, now lets start feeding filenames to tar. */
+ tar_filenames_feeder(dir, pipe_filenames[1]);
+
+ /* All done, clean up wait for tar and <compress> to finish their job. */
+ close(pipe_filenames[1]);
+ subproc_reap(pid_comp, _("<compress> from tar -cf"), 0);
+ subproc_reap(pid_tar, "tar -cf", 0);
+}
+
+static time_t
+parse_timestamp(const char *value)
+{
+ time_t timestamp;
+ char *end;
+
+ errno = 0;
+ timestamp = strtol(value, &end, 10);
+ if (value == end || *end || errno != 0)
+ ohshite(_("unable to parse timestamp '%.255s'"), value);
+
+ return timestamp;
+}
+
+/**
+ * Overly complex function that builds a .deb file.
+ */
+int
+do_build(const char *const *argv)
+{
+ struct compress_params control_compress_params;
+ struct tar_pack_options tar_options;
+ struct dpkg_error err;
+ struct dpkg_ar *ar;
+ time_t timestamp;
+ const char *timestamp_str;
+ const char *dir, *dest;
+ char *ctrldir;
+ char *debar;
+ char *tfbuf;
+ int gzfd;
+
+ /* Decode our arguments. */
+ dir = *argv++;
+ if (!dir)
+ badusage(_("--%s needs a <directory> argument"), cipaction->olong);
+
+ dest = *argv++;
+ if (dest && *argv)
+ badusage(_("--%s takes at most two arguments"), cipaction->olong);
+
+ debar = gen_dest_pathname(dir, dest);
+ ctrldir = str_fmt("%s/%s", dir, BUILDCONTROLDIR);
+
+ /* Perform some sanity checks on the to-be-build package. */
+ if (nocheckflag) {
+ if (debar == NULL)
+ ohshit(_("target is directory - cannot skip control file check"));
+ warning(_("not checking contents of control area"));
+ info(_("building an unknown package in '%s'."), debar);
+ } else {
+ struct pkginfo *pkg;
+
+ pkg = check_control_area(ctrldir, dir);
+ if (debar == NULL)
+ debar = gen_dest_pathname_from_pkg(dest, pkg);
+ info(_("building package '%s' in '%s'."), pkg->set->name, debar);
+ }
+ m_output(stdout, _("<standard output>"));
+
+ timestamp_str = getenv("SOURCE_DATE_EPOCH");
+ if (timestamp_str)
+ timestamp = parse_timestamp(timestamp_str);
+ else
+ timestamp = time(NULL);
+
+ /* Now that we have verified everything it is time to actually
+ * build something. Let's start by making the ar-wrapper. */
+ ar = dpkg_ar_create(debar, 0644);
+
+ dpkg_ar_set_mtime(ar, timestamp);
+
+ unsetenv("TAR_OPTIONS");
+
+ /* Create a temporary file to store the control data in. Immediately
+ * unlink our temporary file so others can't mess with it. */
+ tfbuf = path_make_temp_template("dpkg-deb");
+ gzfd = mkstemp(tfbuf);
+ if (gzfd == -1)
+ ohshite(_("failed to make temporary file (%s)"), _("control member"));
+ /* Make sure it's gone, the fd will remain until we close it. */
+ if (unlink(tfbuf))
+ ohshit(_("failed to unlink temporary file (%s), %s"), _("control member"),
+ tfbuf);
+ free(tfbuf);
+
+ /* Select the compressor to use for our control archive. */
+ if (opt_uniform_compression) {
+ control_compress_params = compress_params;
+ } else {
+ control_compress_params.type = COMPRESSOR_TYPE_GZIP;
+ control_compress_params.strategy = COMPRESSOR_STRATEGY_NONE;
+ control_compress_params.level = -1;
+ if (!compressor_check_params(&control_compress_params, &err))
+ internerr("invalid control member compressor params: %s", err.str);
+ }
+
+ /* Fork a tar to package the control-section of the package. */
+ tar_options.mode = "u+rw,go=rX";
+ tar_options.timestamp = timestamp;
+ tar_options.root_owner_group = true;
+ tarball_pack(ctrldir, control_treewalk_feed, &tar_options,
+ &control_compress_params, gzfd);
+
+ free(ctrldir);
+
+ if (lseek(gzfd, 0, SEEK_SET))
+ ohshite(_("failed to rewind temporary file (%s)"), _("control member"));
+
+ /* We have our first file for the ar-archive. Write a header for it
+ * to the package and insert it. */
+ if (deb_format.major == 0) {
+ struct stat controlstab;
+ char versionbuf[40];
+
+ if (fstat(gzfd, &controlstab))
+ ohshite(_("failed to stat temporary file (%s)"), _("control member"));
+ sprintf(versionbuf, "%-8s\n%jd\n", OLDARCHIVEVERSION,
+ (intmax_t)controlstab.st_size);
+ if (fd_write(ar->fd, versionbuf, strlen(versionbuf)) < 0)
+ ohshite(_("error writing '%s'"), debar);
+ if (fd_fd_copy(gzfd, ar->fd, -1, &err) < 0)
+ ohshit(_("cannot copy '%s' into archive '%s': %s"), _("control member"),
+ ar->name, err.str);
+ } else if (deb_format.major == 2) {
+ const char deb_magic[] = ARCHIVEVERSION "\n";
+ char adminmember[16 + 1];
+
+ sprintf(adminmember, "%s%s", ADMINMEMBER,
+ compressor_get_extension(control_compress_params.type));
+
+ dpkg_ar_put_magic(ar);
+ dpkg_ar_member_put_mem(ar, DEBMAGIC, deb_magic, strlen(deb_magic));
+ dpkg_ar_member_put_file(ar, adminmember, gzfd, -1);
+ } else {
+ internerr("unknown deb format version %d.%d", deb_format.major, deb_format.minor);
+ }
+
+ close(gzfd);
+
+ /* Control is done, now we need to archive the data. */
+ if (deb_format.major == 0) {
+ /* In old format, the data member is just concatenated after the
+ * control member, so we do not need a temporary file and can use
+ * the compression file descriptor. */
+ gzfd = ar->fd;
+ } else if (deb_format.major == 2) {
+ /* Start by creating a new temporary file. Immediately unlink the
+ * temporary file so others can't mess with it. */
+ tfbuf = path_make_temp_template("dpkg-deb");
+ gzfd = mkstemp(tfbuf);
+ if (gzfd == -1)
+ ohshite(_("failed to make temporary file (%s)"), _("data member"));
+ /* Make sure it's gone, the fd will remain until we close it. */
+ if (unlink(tfbuf))
+ ohshit(_("failed to unlink temporary file (%s), %s"), _("data member"),
+ tfbuf);
+ free(tfbuf);
+ } else {
+ internerr("unknown deb format version %d.%d", deb_format.major, deb_format.minor);
+ }
+
+ /* Pack the directory into a tarball, feeding files from the callback. */
+ tar_options.mode = NULL;
+ tar_options.timestamp = timestamp;
+ tar_options.root_owner_group = opt_root_owner_group;
+ tarball_pack(dir, file_treewalk_feed, &tar_options, &compress_params, gzfd);
+
+ /* Okay, we have data.tar as well now, add it to the ar wrapper. */
+ if (deb_format.major == 2) {
+ char datamember[16 + 1];
+
+ sprintf(datamember, "%s%s", DATAMEMBER,
+ compressor_get_extension(compress_params.type));
+
+ if (lseek(gzfd, 0, SEEK_SET))
+ ohshite(_("failed to rewind temporary file (%s)"), _("data member"));
+
+ dpkg_ar_member_put_file(ar, datamember, gzfd, -1);
+
+ close(gzfd);
+ }
+ if (fsync(ar->fd))
+ ohshite(_("unable to sync file '%s'"), ar->name);
+
+ dpkg_ar_close(ar);
+
+ free(debar);
+
+ return 0;
+}
diff --git a/dpkg-deb/dpkg-deb.h b/dpkg-deb/dpkg-deb.h
new file mode 100644
index 0000000..a5e8d39
--- /dev/null
+++ b/dpkg-deb/dpkg-deb.h
@@ -0,0 +1,87 @@
+/*
+ * dpkg-deb - construction and deconstruction of *.deb archives
+ * dpkg-deb.h - external definitions for this program
+ *
+ * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright © 2006-2012 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DPKG_DEB_H
+#define DPKG_DEB_H
+
+#include <dpkg/deb-version.h>
+
+action_func do_build;
+action_func do_contents;
+action_func do_control;
+action_func do_showinfo;
+action_func do_info;
+action_func do_field;
+action_func do_extract;
+action_func do_vextract;
+action_func do_raw_extract;
+action_func do_ctrltarfile;
+action_func do_fsystarfile;
+
+extern int opt_verbose;
+extern int opt_root_owner_group;
+extern int opt_uniform_compression;
+extern int debugflag, nocheckflag;
+
+extern struct deb_version deb_format;
+
+enum dpkg_tar_options {
+ /** Output the tar file directly, without any processing. */
+ DPKG_TAR_PASSTHROUGH = 0,
+ /** List tar files. */
+ DPKG_TAR_LIST = DPKG_BIT(0),
+ /** Extract tar files. */
+ DPKG_TAR_EXTRACT = DPKG_BIT(1),
+ /** Preserve tar permissions on extract. */
+ DPKG_TAR_PERMS = DPKG_BIT(2),
+ /** Do not set tar mtime on extract. */
+ DPKG_TAR_NOMTIME = DPKG_BIT(3),
+ /** Guarantee extraction into a new directory, abort if it exists. */
+ DPKG_TAR_CREATE_DIR = DPKG_BIT(4),
+};
+
+void extracthalf(const char *debar, const char *dir,
+ enum dpkg_tar_options taroption, int admininfo);
+
+extern const char *showformat;
+extern struct compress_params compress_params;
+
+#define ARCHIVEVERSION "2.0"
+
+#define BUILDCONTROLDIR "DEBIAN"
+#define EXTRACTCONTROLDIR BUILDCONTROLDIR
+
+#define OLDARCHIVEVERSION "0.939000"
+
+#define OLDDEBDIR "DEBIAN"
+#define OLDOLDDEBDIR ".DEBIAN"
+
+#define DEBMAGIC "debian-binary"
+#define ADMINMEMBER "control.tar"
+#define DATAMEMBER "data.tar"
+
+#ifdef PATH_MAX
+# define INTERPRETER_MAX PATH_MAX
+#else
+# define INTERPRETER_MAX 1024
+#endif
+
+#endif /* DPKG_DEB_H */
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
new file mode 100644
index 0000000..ff31ccc
--- /dev/null
+++ b/dpkg-deb/extract.c
@@ -0,0 +1,499 @@
+/*
+ * dpkg-deb - construction and deconstruction of *.deb archives
+ * extract.c - extracting archives
+ *
+ * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright © 2006-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ar.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/i18n.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/fdio.h>
+#include <dpkg/buffer.h>
+#include <dpkg/subproc.h>
+#include <dpkg/command.h>
+#include <dpkg/compress.h>
+#include <dpkg/ar.h>
+#include <dpkg/deb-version.h>
+#include <dpkg/options.h>
+
+#include "dpkg-deb.h"
+
+static void movecontrolfiles(const char *thing) {
+ char buf[200];
+ pid_t pid;
+
+ sprintf(buf, "mv %s/* . && rmdir %s", thing, thing);
+ pid = subproc_fork();
+ if (pid == 0) {
+ command_shell(buf, _("shell command to move files"));
+ }
+ subproc_reap(pid, _("shell command to move files"), 0);
+}
+
+static void DPKG_ATTR_NORET
+read_fail(int rc, const char *filename, const char *what)
+{
+ if (rc >= 0)
+ ohshit(_("unexpected end of file in %s in %.255s"),what,filename);
+ else
+ ohshite(_("error reading %s from file %.255s"), what, filename);
+}
+
+static ssize_t
+read_line(int fd, char *buf, size_t min_size, size_t max_size)
+{
+ ssize_t line_size = 0;
+ size_t n = min_size;
+
+ while (line_size < (ssize_t)max_size) {
+ ssize_t r;
+ char *nl;
+
+ r = fd_read(fd, buf + line_size, n);
+ if (r <= 0)
+ return r;
+
+ nl = memchr(buf + line_size, '\n', r);
+ line_size += r;
+
+ if (nl != NULL) {
+ nl[1] = '\0';
+ return line_size;
+ }
+
+ n = 1;
+ }
+
+ buf[line_size] = '\0';
+ return line_size;
+}
+
+void
+extracthalf(const char *debar, const char *dir,
+ enum dpkg_tar_options taroption, int admininfo)
+{
+ struct dpkg_error err;
+ const char *errstr;
+ struct dpkg_ar *ar;
+ char versionbuf[40];
+ struct deb_version version;
+ off_t ctrllennum, memberlen = 0;
+ ssize_t r;
+ int dummy;
+ pid_t c1=0,c2,c3;
+ int p1[2], p2[2];
+ int p2_out;
+ char nlc;
+ int adminmember = -1;
+ bool header_done;
+ enum compressor_type decompressor = COMPRESSOR_TYPE_GZIP;
+
+ ar = dpkg_ar_open(debar);
+
+ r = read_line(ar->fd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf) - 1);
+ if (r < 0)
+ read_fail(r, debar, _("archive magic version number"));
+
+ if (strcmp(versionbuf, DPKG_AR_MAGIC) == 0) {
+ ctrllennum= 0;
+ header_done = false;
+ for (;;) {
+ struct dpkg_ar_hdr arh;
+
+ r = fd_read(ar->fd, &arh, sizeof(arh));
+ if (r != sizeof(arh))
+ read_fail(r, debar, _("archive member header"));
+
+ if (dpkg_ar_member_is_illegal(&arh))
+ ohshit(_("file '%.250s' is corrupt - bad archive header magic"), debar);
+
+ dpkg_ar_normalize_name(&arh);
+
+ memberlen = dpkg_ar_member_get_size(ar, &arh);
+ if (!header_done) {
+ char *infobuf;
+
+ if (strncmp(arh.ar_name, DEBMAGIC, sizeof(arh.ar_name)) != 0)
+ ohshit(_("file '%.250s' is not a Debian binary archive (try dpkg-split?)"),
+ debar);
+ infobuf= m_malloc(memberlen+1);
+ r = fd_read(ar->fd, infobuf, memberlen + (memberlen & 1));
+ if (r != (memberlen + (memberlen & 1)))
+ read_fail(r, debar, _("archive information header member"));
+ infobuf[memberlen] = '\0';
+
+ if (strchr(infobuf, '\n') == NULL)
+ ohshit(_("archive has no newlines in header"));
+ errstr = deb_version_parse(&version, infobuf);
+ if (errstr)
+ ohshit(_("archive has invalid format version: %s"), errstr);
+ if (version.major != 2)
+ ohshit(_("archive is format version %d.%d; get a newer dpkg-deb"),
+ version.major, version.minor);
+
+ free(infobuf);
+
+ header_done = true;
+ } else if (arh.ar_name[0] == '_') {
+ /* Members with ‘_’ are noncritical, and if we don't understand
+ * them we skip them. */
+ if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
+ ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
+ } else {
+ if (strncmp(arh.ar_name, ADMINMEMBER, strlen(ADMINMEMBER)) == 0) {
+ const char *extension = arh.ar_name + strlen(ADMINMEMBER);
+
+ adminmember = 1;
+ decompressor = compressor_find_by_extension(extension);
+ if (decompressor != COMPRESSOR_TYPE_NONE &&
+ decompressor != COMPRESSOR_TYPE_GZIP &&
+ decompressor != COMPRESSOR_TYPE_XZ)
+ ohshit(_("archive '%s' uses unknown compression for member '%.*s', "
+ "giving up"),
+ debar, (int)sizeof(arh.ar_name), arh.ar_name);
+ } else {
+ if (adminmember != 1)
+ ohshit(_("archive '%s' has premature member '%.*s' before '%s', "
+ "giving up"),
+ debar, (int)sizeof(arh.ar_name), arh.ar_name, ADMINMEMBER);
+
+ if (strncmp(arh.ar_name, DATAMEMBER, strlen(DATAMEMBER)) == 0) {
+ const char *extension = arh.ar_name + strlen(DATAMEMBER);
+
+ adminmember= 0;
+ decompressor = compressor_find_by_extension(extension);
+ if (decompressor == COMPRESSOR_TYPE_UNKNOWN)
+ ohshit(_("archive '%s' uses unknown compression for member '%.*s', "
+ "giving up"),
+ debar, (int)sizeof(arh.ar_name), arh.ar_name);
+ } else {
+ ohshit(_("archive '%s' has premature member '%.*s' before '%s', "
+ "giving up"),
+ debar, (int)sizeof(arh.ar_name), arh.ar_name, DATAMEMBER);
+ }
+ }
+ if (adminmember == 1) {
+ if (ctrllennum != 0)
+ ohshit(_("archive '%.250s' contains two control members, giving up"),
+ debar);
+ ctrllennum= memberlen;
+ }
+ if (!adminmember != !admininfo) {
+ if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
+ ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
+ } else {
+ /* Yes! - found it. */
+ break;
+ }
+ }
+ }
+
+ if (admininfo >= 2) {
+ printf(_(" new Debian package, version %d.%d.\n"
+ " size %jd bytes: control archive=%jd bytes.\n"),
+ version.major, version.minor,
+ (intmax_t)ar->size, (intmax_t)ctrllennum);
+ m_output(stdout, _("<standard output>"));
+ }
+ } else if (strncmp(versionbuf, "0.93", 4) == 0) {
+ char ctrllenbuf[40];
+ int l;
+
+ l = strlen(versionbuf);
+
+ if (strchr(versionbuf, '\n') == NULL)
+ ohshit(_("archive has no newlines in header"));
+ errstr = deb_version_parse(&version, versionbuf);
+ if (errstr)
+ ohshit(_("archive has invalid format version: %s"), errstr);
+
+ r = read_line(ar->fd, ctrllenbuf, 1, sizeof(ctrllenbuf) - 1);
+ if (r < 0)
+ read_fail(r, debar, _("archive control member size"));
+ if (sscanf(ctrllenbuf, "%jd%c%d", (intmax_t *)&ctrllennum, &nlc, &dummy) != 2 ||
+ nlc != '\n')
+ ohshit(_("archive has malformed control member size '%s'"), ctrllenbuf);
+
+ if (admininfo) {
+ memberlen = ctrllennum;
+ } else {
+ memberlen = ar->size - ctrllennum - strlen(ctrllenbuf) - l;
+ if (fd_skip(ar->fd, ctrllennum, &err) < 0)
+ ohshit(_("cannot skip archive control member from '%s': %s"), ar->name,
+ err.str);
+ }
+
+ if (admininfo >= 2) {
+ printf(_(" old Debian package, version %d.%d.\n"
+ " size %jd bytes: control archive=%jd, main archive=%jd.\n"),
+ version.major, version.minor,
+ (intmax_t)ar->size, (intmax_t)ctrllennum,
+ (intmax_t)(ar->size - ctrllennum - strlen(ctrllenbuf) - l));
+ m_output(stdout, _("<standard output>"));
+ }
+ } else {
+ if (strncmp(versionbuf, "!<arch>", 7) == 0) {
+ notice(_("file looks like it might be an archive which has been\n"
+ " corrupted by being downloaded in ASCII mode"));
+ }
+
+ ohshit(_("'%.255s' is not a Debian format archive"), debar);
+ }
+
+ m_pipe(p1);
+ c1 = subproc_fork();
+ if (!c1) {
+ close(p1[0]);
+ if (fd_fd_copy(ar->fd, p1[1], memberlen, &err) < 0)
+ ohshit(_("cannot copy archive member from '%s' to decompressor pipe: %s"),
+ ar->name, err.str);
+ if (close(p1[1]))
+ ohshite(_("cannot close decompressor pipe"));
+ exit(0);
+ }
+ close(p1[1]);
+
+ if (taroption) {
+ m_pipe(p2);
+ p2_out = p2[1];
+ } else {
+ p2_out = 1;
+ }
+
+ c2 = subproc_fork();
+ if (!c2) {
+ if (taroption)
+ close(p2[0]);
+ decompress_filter(decompressor, p1[0], p2_out,
+ _("decompressing archive member"));
+ exit(0);
+ }
+ close(p1[0]);
+ dpkg_ar_close(ar);
+ if (taroption) close(p2[1]);
+
+ if (taroption) {
+ c3 = subproc_fork();
+ if (!c3) {
+ struct command cmd;
+
+ command_init(&cmd, TAR, "tar");
+ command_add_arg(&cmd, "tar");
+
+ if ((taroption & DPKG_TAR_LIST) && (taroption & DPKG_TAR_EXTRACT))
+ command_add_arg(&cmd, "-xv");
+ else if (taroption & DPKG_TAR_EXTRACT)
+ command_add_arg(&cmd, "-x");
+ else if (taroption & DPKG_TAR_LIST)
+ command_add_arg(&cmd, "-tv");
+ else
+ internerr("unknown or missing tar action '%d'", taroption);
+
+ if (taroption & DPKG_TAR_PERMS)
+ command_add_arg(&cmd, "-p");
+ if (taroption & DPKG_TAR_NOMTIME)
+ command_add_arg(&cmd, "-m");
+
+ command_add_arg(&cmd, "-f");
+ command_add_arg(&cmd, "-");
+ command_add_arg(&cmd, "--warning=no-timestamp");
+
+ m_dup2(p2[0],0);
+ close(p2[0]);
+
+ unsetenv("TAR_OPTIONS");
+
+ if (dir) {
+ if (mkdir(dir, 0777) != 0) {
+ if (errno != EEXIST)
+ ohshite(_("failed to create directory"));
+
+ if (taroption & DPKG_TAR_CREATE_DIR)
+ ohshite(_("unexpected pre-existing pathname %s"), dir);
+ }
+ if (chdir(dir) != 0)
+ ohshite(_("failed to chdir to directory"));
+ }
+
+ command_exec(&cmd);
+ }
+ close(p2[0]);
+ subproc_reap(c3, "tar", 0);
+ }
+
+ subproc_reap(c2, _("<decompress>"), SUBPROC_NOPIPE);
+ if (c1 != -1)
+ subproc_reap(c1, _("paste"), 0);
+ if (version.major == 0 && admininfo) {
+ /* Handle the version as a float to preserve the behaviour of old code,
+ * because even if the format is defined to be padded by 0's that might
+ * not have been always true for really ancient versions... */
+ while (version.minor && (version.minor % 10) == 0)
+ version.minor /= 10;
+
+ if (version.minor == 931)
+ movecontrolfiles(OLDOLDDEBDIR);
+ else if (version.minor == 932 || version.minor == 933)
+ movecontrolfiles(OLDDEBDIR);
+ }
+}
+
+int
+do_ctrltarfile(const char *const *argv)
+{
+ const char *debar;
+
+ debar = *argv++;
+ if (debar == NULL)
+ badusage(_("--%s needs a .deb filename argument"), cipaction->olong);
+ if (*argv)
+ badusage(_("--%s takes only one argument (.deb filename)"),
+ cipaction->olong);
+
+ extracthalf(debar, NULL, DPKG_TAR_PASSTHROUGH, 1);
+
+ return 0;
+}
+
+int
+do_fsystarfile(const char *const *argv)
+{
+ const char *debar;
+
+ debar = *argv++;
+ if (debar == NULL)
+ badusage(_("--%s needs a .deb filename argument"),cipaction->olong);
+ if (*argv)
+ badusage(_("--%s takes only one argument (.deb filename)"),cipaction->olong);
+ extracthalf(debar, NULL, DPKG_TAR_PASSTHROUGH, 0);
+
+ return 0;
+}
+
+int
+do_control(const char *const *argv)
+{
+ const char *debar, *dir;
+
+ debar = *argv++;
+ if (debar == NULL)
+ badusage(_("--%s needs a .deb filename argument"), cipaction->olong);
+
+ dir = *argv++;
+ if (dir == NULL)
+ dir = EXTRACTCONTROLDIR;
+ else if (*argv)
+ badusage(_("--%s takes at most two arguments (.deb and directory)"),
+ cipaction->olong);
+
+ extracthalf(debar, dir, DPKG_TAR_EXTRACT, 1);
+
+ return 0;
+}
+
+int
+do_extract(const char *const *argv)
+{
+ const char *debar, *dir;
+ enum dpkg_tar_options options = DPKG_TAR_EXTRACT | DPKG_TAR_PERMS;
+
+ if (opt_verbose)
+ options |= DPKG_TAR_LIST;
+
+ debar = *argv++;
+ if (debar == NULL)
+ badusage(_("--%s needs .deb filename and directory arguments"),
+ cipaction->olong);
+
+ dir = *argv++;
+ if (dir == NULL)
+ badusage(_("--%s needs a target directory.\n"
+ "Perhaps you should be using dpkg --install ?"),
+ cipaction->olong);
+ else if (*argv)
+ badusage(_("--%s takes at most two arguments (.deb and directory)"),
+ cipaction->olong);
+
+ extracthalf(debar, dir, options, 0);
+
+ return 0;
+}
+
+int
+do_vextract(const char *const *argv)
+{
+ /* XXX: Backward compatibility. */
+ opt_verbose = 1;
+ return do_extract(argv);
+}
+
+int
+do_raw_extract(const char *const *argv)
+{
+ enum dpkg_tar_options data_options;
+ const char *debar, *dir;
+ char *control_dir;
+
+ debar = *argv++;
+ if (debar == NULL)
+ badusage(_("--%s needs .deb filename and directory arguments"),
+ cipaction->olong);
+ else if (strcmp(debar, "-") == 0)
+ badusage(_("--%s does not support (yet) reading the .deb from standard input"),
+ cipaction->olong);
+
+ dir = *argv++;
+ if (dir == NULL)
+ badusage(_("--%s needs a target directory.\n"
+ "Perhaps you should be using dpkg --install ?"),
+ cipaction->olong);
+ else if (*argv)
+ badusage(_("--%s takes at most two arguments (.deb and directory)"),
+ cipaction->olong);
+
+ control_dir = str_fmt("%s/%s", dir, EXTRACTCONTROLDIR);
+
+ data_options = DPKG_TAR_EXTRACT | DPKG_TAR_PERMS;
+ if (opt_verbose)
+ data_options |= DPKG_TAR_LIST;
+
+ extracthalf(debar, dir, data_options, 0);
+ extracthalf(debar, control_dir, DPKG_TAR_EXTRACT | DPKG_TAR_CREATE_DIR, 1);
+
+ free(control_dir);
+
+ return 0;
+}
diff --git a/dpkg-deb/info.c b/dpkg-deb/info.c
new file mode 100644
index 0000000..794eeb0
--- /dev/null
+++ b/dpkg-deb/info.c
@@ -0,0 +1,305 @@
+/*
+ * dpkg-deb - construction and deconstruction of *.deb archives
+ * info.c - providing information
+ *
+ * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright © 2001 Wichert Akkerman
+ * Copyright © 2007-2015 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/i18n.h>
+#include <dpkg/c-ctype.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/parsedump.h>
+#include <dpkg/pkg-format.h>
+#include <dpkg/buffer.h>
+#include <dpkg/path.h>
+#include <dpkg/options.h>
+
+#include "dpkg-deb.h"
+
+static void cu_info_prepare(int argc, void **argv) {
+ char *dir;
+
+ dir = argv[0];
+ path_remove_tree(dir);
+ free(dir);
+}
+
+static void info_prepare(const char *const **argvp,
+ const char **debarp,
+ const char **dirp,
+ int admininfo) {
+ char *dbuf;
+
+ *debarp= *(*argvp)++;
+ if (!*debarp) badusage(_("--%s needs a .deb filename argument"),cipaction->olong);
+
+ dbuf = mkdtemp(path_make_temp_template("dpkg-deb"));
+ if (!dbuf)
+ ohshite(_("unable to create temporary directory"));
+ *dirp = dbuf;
+
+ push_cleanup(cu_info_prepare, -1, 1, (void *)dbuf);
+ extracthalf(*debarp, dbuf, DPKG_TAR_EXTRACT | DPKG_TAR_NOMTIME, admininfo);
+}
+
+static int ilist_select(const struct dirent *de) {
+ return strcmp(de->d_name,".") && strcmp(de->d_name,"..");
+}
+
+static void
+info_spew(const char *debar, const char *dir, const char *const *argv)
+{
+ struct dpkg_error err;
+ const char *component;
+ struct varbuf controlfile = VARBUF_INIT;
+ int fd;
+ int re= 0;
+
+ while ((component = *argv++) != NULL) {
+ varbuf_reset(&controlfile);
+ varbuf_printf(&controlfile, "%s/%s", dir, component);
+
+ fd = open(controlfile.buf, O_RDONLY);
+ if (fd >= 0) {
+ if (fd_fd_copy(fd, 1, -1, &err) < 0)
+ ohshit(_("cannot extract control file '%s' from '%s': %s"),
+ controlfile.buf, debar, err.str);
+ close(fd);
+ } else if (errno == ENOENT) {
+ notice(_("'%.255s' contains no control component '%.255s'"),
+ debar, component);
+ re++;
+ } else {
+ ohshite(_("open component '%.255s' (in %.255s) failed in an unexpected way"),
+ component, dir);
+ }
+ }
+ varbuf_destroy(&controlfile);
+
+ if (re > 0)
+ ohshit(P_("%d requested control component is missing",
+ "%d requested control components are missing", re), re);
+}
+
+static void
+info_list(const char *debar, const char *dir)
+{
+ char interpreter[INTERPRETER_MAX+1], *p;
+ int il, lines;
+ struct varbuf controlfile = VARBUF_INIT;
+ struct dirent **cdlist, *cdep;
+ int cdn, n;
+ FILE *cc;
+ struct stat stab;
+ int c;
+
+ cdn = scandir(dir, &cdlist, &ilist_select, alphasort);
+ if (cdn == -1)
+ ohshite(_("cannot scan directory '%.255s'"), dir);
+
+ for (n = 0; n < cdn; n++) {
+ cdep = cdlist[n];
+
+ varbuf_reset(&controlfile);
+ varbuf_printf(&controlfile, "%s/%s", dir, cdep->d_name);
+
+ if (stat(controlfile.buf, &stab))
+ ohshite(_("cannot stat '%.255s' (in '%.255s')"), cdep->d_name, dir);
+ if (S_ISREG(stab.st_mode)) {
+ cc = fopen(controlfile.buf, "r");
+ if (!cc)
+ ohshite(_("cannot open '%.255s' (in '%.255s')"), cdep->d_name, dir);
+ lines = 0;
+ interpreter[0] = '\0';
+ if (getc(cc) == '#') {
+ if (getc(cc) == '!') {
+ while ((c= getc(cc))== ' ');
+ p=interpreter; *p++='#'; *p++='!'; il=2;
+ while (il < INTERPRETER_MAX && !c_isspace(c) && c != EOF) {
+ *p++= c; il++; c= getc(cc);
+ }
+ *p = '\0';
+ if (c=='\n') lines++;
+ }
+ }
+ while ((c= getc(cc))!= EOF) { if (c == '\n') lines++; }
+ if (ferror(cc))
+ ohshite(_("failed to read '%.255s' (in '%.255s')"), cdep->d_name, dir);
+ fclose(cc);
+ printf(_(" %7jd bytes, %5d lines %c %-20.127s %.127s\n"),
+ (intmax_t)stab.st_size, lines,
+ (S_IXUSR & stab.st_mode) ? '*' : ' ',
+ cdep->d_name, interpreter);
+ } else {
+ printf(_(" not a plain file %.255s\n"), cdep->d_name);
+ }
+ free(cdep);
+ }
+ free(cdlist);
+
+ varbuf_reset(&controlfile);
+ varbuf_printf(&controlfile, "%s/%s", dir, CONTROLFILE);
+ cc = fopen(controlfile.buf, "r");
+ if (!cc) {
+ if (errno != ENOENT)
+ ohshite(_("failed to read '%.255s' (in '%.255s')"), CONTROLFILE, dir);
+ warning(_("no 'control' file in control archive!"));
+ } else {
+ lines= 1;
+ while ((c= getc(cc))!= EOF) {
+ if (lines)
+ putc(' ', stdout);
+ putc(c, stdout);
+ lines= c=='\n';
+ }
+ if (!lines)
+ putc('\n', stdout);
+
+ if (ferror(cc))
+ ohshite(_("failed to read '%.255s' (in '%.255s')"), CONTROLFILE, dir);
+ fclose(cc);
+ }
+
+ m_output(stdout, _("<standard output>"));
+ varbuf_destroy(&controlfile);
+}
+
+static void
+info_field(const char *debar, const char *dir, const char *const *fields,
+ enum fwriteflags fieldflags)
+{
+ char *controlfile;
+ struct varbuf str = VARBUF_INIT;
+ struct pkginfo *pkg;
+ int i;
+
+ controlfile = str_fmt("%s/%s", dir, CONTROLFILE);
+ parsedb(controlfile, pdb_parse_binary | pdb_ignore_archives, &pkg);
+ free(controlfile);
+
+ for (i = 0; fields[i]; i++) {
+ const struct fieldinfo *field;
+ const struct arbitraryfield *arbfield;
+
+ varbuf_reset(&str);
+ field = find_field_info(fieldinfos, fields[i]);
+ if (field) {
+ field->wcall(&str, pkg, &pkg->available, fieldflags, field);
+ } else {
+ arbfield = find_arbfield_info(pkg->available.arbs, fields[i]);
+ if (arbfield)
+ varbuf_add_arbfield(&str, arbfield, fieldflags);
+ }
+ varbuf_end_str(&str);
+
+ if (fieldflags & fw_printheader)
+ printf("%s", str.buf);
+ else
+ printf("%s\n", str.buf);
+ }
+
+ m_output(stdout, _("<standard output>"));
+
+ varbuf_destroy(&str);
+}
+
+int
+do_showinfo(const char *const *argv)
+{
+ const char *debar, *dir;
+ char *controlfile;
+ struct dpkg_error err;
+ struct pkginfo *pkg;
+ struct pkg_format_node *fmt;
+
+ fmt = pkg_format_parse(showformat, &err);
+ if (!fmt)
+ ohshit(_("error in show format: %s"), err.str);
+
+ info_prepare(&argv, &debar, &dir, 1);
+
+ controlfile = str_fmt("%s/%s", dir, CONTROLFILE);
+ parsedb(controlfile, pdb_parse_binary | pdb_ignore_archives, &pkg);
+ pkg_format_show(fmt, pkg, &pkg->available);
+ pkg_format_free(fmt);
+ free(controlfile);
+
+ return 0;
+}
+
+int
+do_info(const char *const *argv)
+{
+ const char *debar, *dir;
+
+ if (*argv && argv[1]) {
+ info_prepare(&argv, &debar, &dir, 1);
+ info_spew(debar, dir, argv);
+ } else {
+ info_prepare(&argv, &debar, &dir, 2);
+ info_list(debar, dir);
+ }
+
+ return 0;
+}
+
+int
+do_field(const char *const *argv)
+{
+ const char *debar, *dir;
+
+ info_prepare(&argv, &debar, &dir, 1);
+ if (*argv) {
+ info_field(debar, dir, argv, argv[1] != NULL ? fw_printheader : 0);
+ } else {
+ static const char *const controlonly[] = { CONTROLFILE, NULL };
+ info_spew(debar, dir, controlonly);
+ }
+
+ return 0;
+}
+
+int
+do_contents(const char *const *argv)
+{
+ const char *debar = *argv++;
+
+ if (debar == NULL || *argv)
+ badusage(_("--%s takes exactly one argument"), cipaction->olong);
+ extracthalf(debar, NULL, DPKG_TAR_LIST, 0);
+
+ return 0;
+}
diff --git a/dpkg-deb/main.c b/dpkg-deb/main.c
new file mode 100644
index 0000000..52e9ce6
--- /dev/null
+++ b/dpkg-deb/main.c
@@ -0,0 +1,257 @@
+/*
+ * dpkg-deb - construction and deconstruction of *.deb archives
+ * main.c - main program
+ *
+ * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright © 2006-2014 Guillem Jover <guillem@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <limits.h>
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <dpkg/macros.h>
+#include <dpkg/i18n.h>
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/compress.h>
+#include <dpkg/options.h>
+
+#include "dpkg-deb.h"
+
+const char *showformat = "${Package}\t${Version}\n";
+
+static void DPKG_ATTR_NORET
+printversion(const struct cmdinfo *cip, const char *value)
+{
+ printf(_("Debian '%s' package archive backend version %s.\n"),
+ BACKEND, PACKAGE_RELEASE);
+ printf(_(
+"This is free software; see the GNU General Public License version 2 or\n"
+"later for copying conditions. There is NO warranty.\n"));
+
+ m_output(stdout, _("<standard output>"));
+
+ exit(0);
+}
+
+static void DPKG_ATTR_NORET
+usage(const struct cmdinfo *cip, const char *value)
+{
+ printf(_(
+"Usage: %s [<option> ...] <command>\n"
+"\n"), BACKEND);
+
+ printf(_(
+"Commands:\n"
+" -b|--build <directory> [<deb>] Build an archive.\n"
+" -c|--contents <deb> List contents.\n"
+" -I|--info <deb> [<cfile> ...] Show info to stdout.\n"
+" -W|--show <deb> Show information on package(s)\n"
+" -f|--field <deb> [<cfield> ...] Show field(s) to stdout.\n"
+" -e|--control <deb> [<directory>] Extract control info.\n"
+" -x|--extract <deb> <directory> Extract files.\n"
+" -X|--vextract <deb> <directory> Extract & list files.\n"
+" -R|--raw-extract <deb> <directory>\n"
+" Extract control info and files.\n"
+" --ctrl-tarfile <deb> Output control tarfile.\n"
+" --fsys-tarfile <deb> Output filesystem tarfile.\n"
+"\n"));
+
+ printf(_(
+" -?, --help Show this help message.\n"
+" --version Show the version.\n"
+"\n"));
+
+ printf(_(
+"<deb> is the filename of a Debian format archive.\n"
+"<cfile> is the name of an administrative file component.\n"
+"<cfield> is the name of a field in the main 'control' file.\n"
+"\n"));
+
+ printf(_(
+"Options:\n"
+" -v, --verbose Enable verbose output.\n"
+" -D, --debug Enable debugging output.\n"
+" --showformat=<format> Use alternative format for --show.\n"
+" --deb-format=<format> Select archive format.\n"
+" Allowed values: 0.939000, 2.0 (default).\n"
+" --nocheck Suppress control file check (build bad\n"
+" packages).\n"
+" --root-owner-group Forces the owner and groups to root.\n"
+" --[no-]uniform-compression Use the compression params on all members.\n"
+" -z# Set the compression level when building.\n"
+" -Z<type> Set the compression type used when building.\n"
+" Allowed types: gzip, xz, none.\n"
+" -S<strategy> Set the compression strategy when building.\n"
+" Allowed values: none; extreme (xz);\n"
+" filtered, huffman, rle, fixed (gzip).\n"
+"\n"));
+
+ printf(_(
+"Format syntax:\n"
+" A format is a string that will be output for each package. The format\n"
+" can include the standard escape sequences \\n (newline), \\r (carriage\n"
+" return) or \\\\ (plain backslash). Package information can be included\n"
+" by inserting variable references to package fields using the ${var[;width]}\n"
+" syntax. Fields will be right-aligned unless the width is negative in which\n"
+" case left alignment will be used.\n"));
+
+ printf(_(
+"\n"
+"Use 'dpkg' to install and remove packages from your system, or\n"
+"'apt' or 'aptitude' for user-friendly package management. Packages\n"
+"unpacked using 'dpkg-deb --extract' will be incorrectly installed !\n"));
+
+ m_output(stdout, _("<standard output>"));
+
+ exit(0);
+}
+
+static const char printforhelp[] =
+ N_("Type dpkg-deb --help for help about manipulating *.deb files;\n"
+ "Type dpkg --help for help about installing and deinstalling packages.");
+
+int debugflag = 0;
+int nocheckflag = 0;
+int opt_verbose = 0;
+int opt_root_owner_group = 0;
+int opt_uniform_compression = 1;
+
+struct deb_version deb_format = DEB_VERSION(2, 0);
+
+static void
+set_deb_format(const struct cmdinfo *cip, const char *value)
+{
+ const char *err;
+
+ err = deb_version_parse(&deb_format, value);
+ if (err)
+ badusage(_("invalid deb format version: %s"), err);
+
+ if ((deb_format.major == 2 && deb_format.minor == 0) ||
+ (deb_format.major == 0 && deb_format.minor == 939000))
+ return;
+ else
+ badusage(_("unknown deb format version: %s"), value);
+}
+
+struct compress_params compress_params = {
+ .type = DPKG_DEB_DEFAULT_COMPRESSOR,
+ .strategy = COMPRESSOR_STRATEGY_NONE,
+ .level = -1,
+};
+
+static void
+set_compress_level(const struct cmdinfo *cip, const char *value)
+{
+ long level;
+
+ level = dpkg_options_parse_arg_int(cip, value);
+ if (level < 0 || level > 9)
+ badusage(_("invalid compression level for -%c: %ld"), cip->oshort, level);
+
+ compress_params.level = level;
+}
+
+static void
+set_compress_strategy(const struct cmdinfo *cip, const char *value)
+{
+ compress_params.strategy = compressor_get_strategy(value);
+ if (compress_params.strategy == COMPRESSOR_STRATEGY_UNKNOWN)
+ badusage(_("unknown compression strategy '%s'!"), value);
+}
+
+static void
+set_compress_type(const struct cmdinfo *cip, const char *value)
+{
+ compress_params.type = compressor_find_by_name(value);
+ if (compress_params.type == COMPRESSOR_TYPE_UNKNOWN)
+ badusage(_("unknown compression type '%s'!"), value);
+ if (compress_params.type == COMPRESSOR_TYPE_LZMA)
+ badusage(_("obsolete compression type '%s'; use xz instead"), value);
+ if (compress_params.type == COMPRESSOR_TYPE_BZIP2)
+ badusage(_("obsolete compression type '%s'; use xz or gzip instead"), value);
+}
+
+static const struct cmdinfo cmdinfos[]= {
+ ACTION("build", 'b', 0, do_build),
+ ACTION("contents", 'c', 0, do_contents),
+ ACTION("control", 'e', 0, do_control),
+ ACTION("info", 'I', 0, do_info),
+ ACTION("field", 'f', 0, do_field),
+ ACTION("extract", 'x', 0, do_extract),
+ ACTION("vextract", 'X', 0, do_vextract),
+ ACTION("raw-extract", 'R', 0, do_raw_extract),
+ ACTION("ctrl-tarfile", 0, 0, do_ctrltarfile),
+ ACTION("fsys-tarfile", 0, 0, do_fsystarfile),
+ ACTION("show", 'W', 0, do_showinfo),
+
+ { "deb-format", 0, 1, NULL, NULL, set_deb_format },
+ { "debug", 'D', 0, &debugflag, NULL, NULL, 1 },
+ { "verbose", 'v', 0, &opt_verbose, NULL, NULL, 1 },
+ { "nocheck", 0, 0, &nocheckflag, NULL, NULL, 1 },
+ { "root-owner-group", 0, 0, &opt_root_owner_group, NULL, NULL, 1 },
+ { "uniform-compression", 0, 0, &opt_uniform_compression, NULL, NULL, 1 },
+ { "no-uniform-compression", 0, 0, &opt_uniform_compression, NULL, NULL, 0 },
+ { NULL, 'z', 1, NULL, NULL, set_compress_level },
+ { NULL, 'Z', 1, NULL, NULL, set_compress_type },
+ { NULL, 'S', 1, NULL, NULL, set_compress_strategy },
+ { "showformat", 0, 1, NULL, &showformat, NULL },
+ { "help", '?', 0, NULL, NULL, usage },
+ { "version", 0, 0, NULL, NULL, printversion },
+ { NULL, 0, 0, NULL, NULL, NULL }
+};
+
+int main(int argc, const char *const *argv) {
+ struct dpkg_error err;
+ int ret;
+
+ dpkg_locales_init(PACKAGE);
+ dpkg_program_init(BACKEND);
+ dpkg_options_parse(&argv, cmdinfos, printforhelp);
+
+ if (!cipaction) badusage(_("need an action option"));
+
+ if (!compressor_check_params(&compress_params, &err))
+ badusage(_("invalid compressor parameters: %s"), err.str);
+
+ if (opt_uniform_compression &&
+ (compress_params.type != COMPRESSOR_TYPE_NONE &&
+ compress_params.type != COMPRESSOR_TYPE_GZIP &&
+ compress_params.type != COMPRESSOR_TYPE_XZ))
+ badusage(_("unsupported compression type '%s' with uniform compression"),
+ compressor_get_name(compress_params.type));
+
+ ret = cipaction->action(argv);
+
+ dpkg_program_done();
+
+ return ret;
+}