Browse Source

Merge branch 'portability/freebsd'

Julian Andres Klode 7 years ago
parent
commit
6a68315e93
44 changed files with 370 additions and 119 deletions
  1. 14 3
      CMake/FindBerkeleyDB.cmake
  2. 20 0
      CMake/FindIconv.cmake
  3. 25 0
      CMake/FindLZ4.cmake
  4. 25 0
      CMake/FindLZMA.cmake
  5. 18 0
      CMake/config.h.in
  6. 9 0
      CMake/endian.h.in
  7. 79 20
      CMakeLists.txt
  8. 1 1
      apt-inst/deb/debfile.cc
  9. 8 3
      apt-pkg/CMakeLists.txt
  10. 5 4
      apt-pkg/acquire-item.cc
  11. 2 2
      apt-pkg/acquire-worker.cc
  12. 3 3
      apt-pkg/acquire.cc
  13. 1 1
      apt-pkg/contrib/gpgv.cc
  14. 3 2
      apt-pkg/contrib/strutl.cc
  15. 1 0
      apt-pkg/deb/debindexfile.cc
  16. 4 4
      apt-pkg/deb/debsystem.cc
  17. 2 0
      apt-pkg/deb/dpkgpm.cc
  18. 2 0
      apt-pkg/edsp/edsplistparser.cc
  19. 3 3
      apt-pkg/indexcopy.cc
  20. 6 6
      apt-pkg/init.cc
  21. 2 2
      apt-pkg/install-progress.cc
  22. 7 0
      apt-private/private-download.cc
  23. 1 0
      apt-private/private-show.cc
  24. 1 0
      cmdline/apt-helper.cc
  25. 1 1
      cmdline/apt-key.in
  26. 1 0
      cmdline/apt-sortpkgs.cc
  27. 1 1
      debian/apt.auto-removal.sh
  28. 1 0
      ftparchive/CMakeLists.txt
  29. 1 1
      methods/CMakeLists.txt
  30. 2 0
      methods/connect.cc
  31. 83 39
      test/integration/framework
  32. 5 1
      test/integration/run-tests
  33. 1 1
      test/integration/test-apt-config
  34. 8 3
      test/integration/test-apt-ftparchive-cachedb-lp1274466
  35. 3 3
      test/integration/test-apt-get-changelog
  36. 1 1
      test/integration/test-authentication-basic
  37. 1 1
      test/integration/test-bug-661537-build-profiles-support
  38. 1 1
      test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch
  39. 6 6
      test/integration/test-bug-769609-triggers-still-pending-after-run
  40. 2 2
      test/integration/test-external-dependency-solver-protocol
  41. 2 2
      test/integration/test-kernel-helper-autoremove
  42. 6 1
      test/integration/test-no-fds-leaked-to-maintainer-scripts
  43. 1 0
      test/interactive-helper/test_fileutl.cc
  44. 1 1
      vendor/getinfo

+ 14 - 3
CMake/FindBerkeleyDB.cmake

@@ -33,14 +33,25 @@
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
+# We need NO_DEFAULT_PATH here, otherwise CMake helpfully picks up the wrong
+# db.h on BSD systems instead of the Berkeley DB one.
 find_path(BERKELEY_DB_INCLUDE_DIRS db.h
-  /usr/include/db5
+  ${CMAKE_INSTALL_FULL_INCLUDEDIR}/db5
   /usr/local/include/db5
-  /usr/include/db4
+  /usr/include/db5
+
+  ${CMAKE_INSTALL_FULL_INCLUDEDIR}/db4
   /usr/local/include/db4
+  /usr/include/db4
+
+  ${CMAKE_INSTALL_FULL_INCLUDEDIR}
+  /usr/local/include
+  /usr/include
+
+  NO_DEFAULT_PATH
 )
 
-find_library(BERKELEY_DB_LIBRARIES NAMES db )
+find_library(BERKELEY_DB_LIBRARIES NAMES db db-5)
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Berkeley "Could not find Berkeley DB >= 4.1" BERKELEY_DB_INCLUDE_DIRS BERKELEY_DB_LIBRARIES)

+ 20 - 0
CMake/FindIconv.cmake

@@ -0,0 +1,20 @@
+find_path(ICONV_INCLUDE_DIR NAMES iconv.h)
+
+find_library(ICONV_LIBRARY NAMES iconv)
+if (ICONV_LIBRARY)
+    set(ICONV_SYMBOL_FOUND "${ICONV_LIBRARY}")
+else()
+    check_function_exists(iconv_open ICONV_SYMBOL_FOUND)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Iconv DEFAULT_MESSAGE ICONV_INCLUDE_DIR ICONV_SYMBOL_FOUND)
+
+if(ICONV_LIBRARY)
+    set(ICONV_LIBRARIES "${ICONV_LIBRARY}")
+else()
+    set(ICONV_LIBRARIES)
+endif()
+set(ICONV_INCLUDE_DIRS "${ICONV_INCLUDE_DIR}")
+
+mark_as_advanced(ICONV_LIBRARY ICONV_INCLUDE_DIR)

+ 25 - 0
CMake/FindLZ4.cmake

@@ -0,0 +1,25 @@
+# - Try to find LZ4
+# Once done, this will define
+#
+#  LZ4_FOUND - system has LZ4
+#  LZ4_INCLUDE_DIRS - the LZ4 include directories
+#  LZ4_LIBRARIES - the LZ4 library
+find_package(PkgConfig)
+
+pkg_check_modules(LZ4_PKGCONF liblz4)
+
+find_path(LZ4_INCLUDE_DIRS
+  NAMES lz4frame.h
+  PATHS ${LZ4_PKGCONF_INCLUDE_DIRS}
+)
+
+
+find_library(LZ4_LIBRARIES
+  NAMES lz4
+  PATHS ${LZ4_PKGCONF_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LZ4 DEFAULT_MSG LZ4_INCLUDE_DIRS LZ4_LIBRARIES)
+
+mark_as_advanced(LZ4_INCLUDE_DIRS LZ4_LIBRARIES)

+ 25 - 0
CMake/FindLZMA.cmake

@@ -0,0 +1,25 @@
+# - Try to find LZMA
+# Once done, this will define
+#
+#  LZMA_FOUND - system has LZMA
+#  LZMA_INCLUDE_DIRS - the LZMA include directories
+#  LZMA_LIBRARIES - the LZMA library
+find_package(PkgConfig)
+
+pkg_check_modules(LZMA_PKGCONF liblzma)
+
+find_path(LZMA_INCLUDE_DIRS
+  NAMES lzma.h
+  PATHS ${LZMA_PKGCONF_INCLUDE_DIRS}
+)
+
+
+find_library(LZMA_LIBRARIES
+  NAMES lzma
+  PATHS ${LZMA_PKGCONF_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LZMA DEFAULT_MSG LZMA_INCLUDE_DIRS LZMA_LIBRARIES)
+
+mark_as_advanced(LZMA_INCLUDE_DIRS LZMA_LIBRARIES)

+ 18 - 0
CMake/config.h.in

@@ -25,6 +25,12 @@
 /* Define if we have sys/mount.h */
 #cmakedefine HAVE_MOUNT_H
 
+/* Define if we have sys/endian.h */
+#cmakedefine HAVE_SYS_ENDIAN_H
+
+/* Define if we have machine/endian.h */
+#cmakedefine HAVE_MACHINE_ENDIAN_H
+
 /* Define if we have enabled pthread support */
 #cmakedefine HAVE_PTHREAD
 
@@ -49,6 +55,18 @@
 /* The mail address to reach upstream */
 #define PACKAGE_MAIL "${PACKAGE_MAIL}"
 
+/* Various directories */
+#cmakedefine CMAKE_INSTALL_FULL_BINDIR "${CMAKE_INSTALL_FULL_BINDIR}"
+#cmakedefine STATE_DIR "${STATE_DIR}"
+#cmakedefine CACHE_DIR "${CACHE_DIR}"
+#cmakedefine LOG_DIR "${LOG_DIR}"
+#cmakedefine CONF_DIR "${CONF_DIR}"
+#cmakedefine LIBEXEC_DIR "${LIBEXEC_DIR}"
+#cmakedefine BIN_DIR "${BIN_DIR}"
+
+/* Group of the root user */
+#cmakedefine ROOT_GROUP "${ROOT_GROUP}"
+
 #define APT_8_CLEANER_HEADERS
 #define APT_9_CLEANER_HEADERS
 #define APT_10_CLEANER_HEADERS

+ 9 - 0
CMake/endian.h.in

@@ -0,0 +1,9 @@
+#include <config.h>
+
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/types.h>
+#include <sys/endian.h>
+#endif

+ 79 - 20
CMakeLists.txt

@@ -4,6 +4,9 @@
 # set minimum version
 project(apt)
 cmake_minimum_required(VERSION 3.4.0)
+# Generic header locations
+include_directories(${PROJECT_BINARY_DIR}/include)
+
 
 enable_testing()
 
@@ -25,8 +28,14 @@ include(CheckStructHasMember)
 include(GNUInstallDirs)
 include(TestBigEndian)
 find_package(Threads)
-find_package(PkgConfig)
 find_package(LFS REQUIRED)
+find_package(Iconv REQUIRED)
+
+if(USE_NLS)
+  find_package(Intl REQUIRED)
+  link_libraries(${Intl_LIBRARIES})
+  include_directories(${Intl_INCLUDE_DIRS})
+endif()
 
 # Add large file support
 add_compile_options(${LFS_COMPILE_OPTIONS})
@@ -78,25 +87,27 @@ if (BZIP2_FOUND)
   set(HAVE_BZ2 1)
 endif()
 
-pkg_check_modules(LZMA liblzma)
+find_package(LZMA)
 if (LZMA_FOUND)
   set(HAVE_LZMA 1)
 endif()
 
-pkg_check_modules(LZ4 liblz4)
+
+find_package(LZ4)
 if (LZ4_FOUND)
   set(HAVE_LZ4 1)
 endif()
 
 # Mount()ing and stat()ing and friends
+check_symbol_exists(statfs sys/vfs.h HAVE_VFS_H)
+check_include_files(sys/params.h HAVE_PARAMS_H)
+check_symbol_exists(statfs sys/mount.h HAVE_MOUNT_H)
+if (NOT HAVE_VFS_H AND NOT HAVE_MOUNT_H)
+  message(FATAL_ERROR "Can find neither statvfs() nor statfs()")
+endif()
 
 check_function_exists(statvfs HAVE_STATVFS)
 if (NOT HAVE_STATVFS)
-  check_symbol_exists(statfs sys/vfs.h HAVE_VFS_H)
-  check_symbol_exists(statfs sys/mount.h HAVE_MOUNT_H)
-  if (NOT HAVE_VFS_H AND NOT HAVE_MOUNT_H)
-    message(FATAL_ERROR "Can find neither statvfs() nor statfs()")
-  endif()
   configure_file(CMake/statvfs.h.in ${PROJECT_BINARY_DIR}/include/statvfs.h COPYONLY)
 endif()
 
@@ -111,10 +122,46 @@ check_function_exists(ptsname_r HAVE_PTSNAME_R)
 check_function_exists(timegm HAVE_TIMEGM)
 test_big_endian(WORDS_BIGENDIAN)
 
+# FreeBSD
+add_definitions(-D_WITH_GETLINE=1)
+
 if (CMAKE_USE_PTHREADS_INIT)
   set(HAVE_PTHREAD 1)
 endif()
 
+CHECK_INCLUDE_FILES(machine/endian.h HAVE_MACHINE_ENDIAN_H)
+CHECK_INCLUDE_FILES(sys/endian.h HAVE_SYS_ENDIAN_H)
+CHECK_INCLUDE_FILES(endian.h HAVE_ENDIAN_H)
+if (NOT HAVE_ENDIAN_H)
+  if (HAVE_MACHINE_ENDIAN_H OR HAVE_SYS_ENDIAN_H)
+    configure_file(CMake/endian.h.in ${PROJECT_BINARY_DIR}/include/endian.h)
+  else()
+    message(FATAL_ERROR "Cannot find endian.h")
+  endif()
+endif()
+
+
+include(CheckTypeSize)
+set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
+check_type_size("sig_t" SIG_T LANGUAGE "CXX")
+check_type_size("sighandler_t" SIGHANDLER_T LANGUAGE "CXX")
+set(CMAKE_EXTRA_INCLUDE_FILES)
+if (NOT HAVE_SIGHANDLER_T)
+  if (HAVE_SIG_T)
+    add_definitions(-Dsighandler_t=sig_t)
+  else()
+    message(FATAL_ERROR "Platform defines neither sig_t nor sighandler_t")
+  endif()
+endif()
+
+# Handle resolving
+check_function_exists(res_init HAVE_LIBC_RESOLV)
+if(HAVE_LIBC_RESOLV)
+    set(RESOLV_LIBRARIES)
+else()
+    set(RESOLV_LIBRARIES -lresolv)
+endif()
+
 # Configure some variables like package, version and architecture.
 set(PACKAGE ${PROJECT_NAME})
 set(PACKAGE_MAIL "APT Development Team <deity@lists.debian.org>")
@@ -124,14 +171,26 @@ if (NOT DEFINED COMMON_ARCH)
   execute_process(COMMAND dpkg-architecture -qDEB_HOST_ARCH
                   OUTPUT_VARIABLE COMMON_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
 endif()
+if (NOT DEFINED ROOT_GROUP)
+  execute_process(COMMAND id -gn root
+                  OUTPUT_VARIABLE ROOT_GROUP OUTPUT_STRIP_TRAILING_WHITESPACE)
+  message(STATUS "Found root group: ${ROOT_GROUP}")
+endif()
+set(ROOT_GROUP "${ROOT_GROUP}" CACHE STRING "Group of root (e.g.: wheel or root)")
+
+# Set various directories
+set(STATE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/apt" CACHE PATH "Your /var/lib/apt")
+set(CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/apt" CACHE PATH "Your /var/cache/apt")
+set(LOG_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/apt" CACHE PATH "Your /var/log/apt")
+set(CONF_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/apt" CACHE PATH "Your /etc/apt")
+set(LIBEXEC_DIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/apt" CACHE PATH "Your /usr/libexec/apt")
+set(BIN_DIR "${CMAKE_INSTALL_FULL_BINDIR}")
+
 
 # Configure our configuration headers (config.h and apti18n.h)
 configure_file(CMake/config.h.in ${PROJECT_BINARY_DIR}/include/config.h)
 configure_file(CMake/apti18n.h.in ${PROJECT_BINARY_DIR}/include/apti18n.h)
 
-# Generic header locations
-include_directories(${PROJECT_BINARY_DIR}/include)
-
 # Add our subdirectories
 add_subdirectory(vendor)
 add_subdirectory(apt-pkg)
@@ -154,13 +213,13 @@ endif()
 
 # Create our directories.
 install_empty_directories(
-  ${CMAKE_INSTALL_FULL_SYSCONFDIR}/apt/apt.conf.d
-  ${CMAKE_INSTALL_FULL_SYSCONFDIR}/apt/preferences.d
-  ${CMAKE_INSTALL_FULL_SYSCONFDIR}/apt/sources.list.d
-  ${CMAKE_INSTALL_FULL_SYSCONFDIR}/apt/trusted.gpg.d
-  ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/apt/archives/partial
-  ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/apt/lists/partial
-  ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/apt/mirrors/partial
-  ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/apt/periodic
-  ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/apt
+  ${CONF_DIR}/apt.conf.d
+  ${CONF_DIR}/preferences.d
+  ${CONF_DIR}/sources.list.d
+  ${CONF_DIR}/trusted.gpg.d
+  ${CACHE_DIR}/archives/partial
+  ${STATE_DIR}/lists/partial
+  ${STATE_DIR}/mirrors/partial
+  ${STATE_DIR}/periodic
+  ${LOG_DIR}
 )

+ 1 - 1
apt-inst/deb/debfile.cc

@@ -113,7 +113,7 @@ bool debDebFile::ExtractTarMember(pkgDirStream &Stream,const char *Name)
       Member = AR.FindMember(std::string(Name).append(c->Extension).c_str());
       if (Member == NULL)
 	 continue;
-      Compressor = c->Binary;
+      Compressor = c->Name;
       break;
    }
 

+ 8 - 3
apt-pkg/CMakeLists.txt

@@ -28,14 +28,19 @@ target_include_directories(apt-pkg
                            PRIVATE ${ZLIB_INCLUDE_DIRS}
                                    ${BZIP2_INCLUDE_DIR}
                                    ${LZMA_INCLUDE_DIRS}
-                                   ${LZ4_INCLUDE_DIRS})
+                                   ${LZ4_INCLUDE_DIRS}
+                                   ${ICONV_DIRECTORIES}
+)
+
 target_link_libraries(apt-pkg
-                      PRIVATE -lutil -ldl -lresolv
+                      PRIVATE -lutil ${CMAKE_DL_LIBS} ${RESOLV_LIBRARIES}
                              ${CMAKE_THREAD_LIBS_INIT}
                              ${ZLIB_LIBRARIES}
                              ${BZIP2_LIBRARIES}
                              ${LZMA_LIBRARIES}
-                             ${LZ4_LIBRARIES})
+                             ${LZ4_LIBRARIES}
+                             ${ICONV_LIBRARIES}
+)
 set_target_properties(apt-pkg PROPERTIES VERSION ${MAJOR}.${MINOR})
 set_target_properties(apt-pkg PROPERTIES SOVERSION ${MAJOR})
 add_version_script(apt-pkg)

+ 5 - 4
apt-pkg/acquire-item.cc

@@ -145,7 +145,7 @@ static void ReportMirrorFailureToCentral(pkgAcquire::Item const &I, std::string
 	     << FailCode << std::endl;
 #endif
    string const report = _config->Find("Methods::Mirror::ProblemReporting",
-				 "/usr/lib/apt/apt-report-mirror-failure");
+				 LIBEXEC_DIR "/apt-report-mirror-failure");
    if(!FileExists(report))
       return;
 
@@ -2047,7 +2047,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile)	/*{{{*/
    HashStringList ServerHashes;
    unsigned long long ServerSize = 0;
 
-   auto const &posix = std::locale("C.UTF-8");
+   auto const &posix = std::locale::classic();
    for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
    {
       std::string tagname = *type;
@@ -3439,7 +3439,7 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
    TemporaryDirectory = tmpname;
 
    ChangeOwnerAndPermissionOfFile("Item::QueueURI", TemporaryDirectory.c_str(),
-	 SandboxUser.c_str(), "root", 0700);
+	 SandboxUser.c_str(), ROOT_GROUP, 0700);
 
    DestFile = flCombine(TemporaryDirectory, DestFileName);
    if (DestDir.empty() == false)
@@ -3487,7 +3487,8 @@ std::string pkgAcqChangelog::URI(pkgCache::VerIterator const &Ver)	/*{{{*/
       pkgCache::PkgIterator const Pkg = Ver.ParentPkg();
       if (Pkg->CurrentVer != 0 && Pkg.CurrentVer() == Ver)
       {
-	 std::string const basename = std::string("/usr/share/doc/") + Pkg.Name() + "/changelog";
+	 std::string const root = _config->FindDir("Dir");
+	 std::string const basename = root + std::string("usr/share/doc/") + Pkg.Name() + "/changelog";
 	 std::string const debianname = basename + ".Debian";
 	 if (FileExists(debianname))
 	    return "copy://" + debianname;

+ 2 - 2
apt-pkg/acquire-worker.cc

@@ -692,7 +692,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    {
       std::string const SandboxUser = _config->Find("APT::Sandbox::User");
       ChangeOwnerAndPermissionOfFile("Item::QueueURI", Item->Owner->DestFile.c_str(),
-                                     SandboxUser.c_str(), "root", 0600);
+                                     SandboxUser.c_str(), ROOT_GROUP, 0600);
    }
 
    if (Debug == true)
@@ -788,7 +788,7 @@ void pkgAcquire::Worker::PrepareFiles(char const * const caller, pkgAcquire::Que
 {
    if (RealFileExists(Itm->Owner->DestFile))
    {
-      ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", "root", 0644);
+      ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", ROOT_GROUP, 0644);
       std::string const filename = Itm->Owner->DestFile;
       for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
       {

+ 3 - 3
apt-pkg/acquire.cc

@@ -80,7 +80,7 @@ void pkgAcquire::Initialize()
    if (getuid() == 0 && SandboxUser.empty() == false && SandboxUser != "root") // if we aren't root, we can't chown, so don't try it
    {
       struct passwd const * const pw = getpwnam(SandboxUser.c_str());
-      struct group const * const gr = getgrnam("root");
+      struct group const * const gr = getgrnam(ROOT_GROUP);
       if (pw != NULL && gr != NULL)
       {
 	 std::string const AuthConf = _config->FindFile("Dir::Etc::netrc");
@@ -106,7 +106,7 @@ static bool SetupAPTPartialDirectory(std::string const &grand, std::string const
    if (getuid() == 0 && SandboxUser.empty() == false && SandboxUser != "root") // if we aren't root, we can't chown, so don't try it
    {
       struct passwd const * const pw = getpwnam(SandboxUser.c_str());
-      struct group const * const gr = getgrnam("root");
+      struct group const * const gr = getgrnam(ROOT_GROUP);
       if (pw != NULL && gr != NULL)
       {
          // chown the partial dir
@@ -1312,7 +1312,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
 
       // build the status str
       std::ostringstream str;
-      str.imbue(std::locale("C.UTF-8"));
+      str.imbue(std::locale::classic());
       str.precision(4);
       str << "dlstatus" << ':' << std::fixed << i << ':' << Percent << ':' << msg << '\n';
       auto const dlstatus = str.str();

+ 1 - 1
apt-pkg/contrib/gpgv.cc

@@ -48,7 +48,7 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
              int const &statusfd, int fd[2], std::string const &key)
 {
    #define EINTERNAL 111
-   std::string const aptkey = _config->Find("Dir::Bin::apt-key", "/usr/bin/apt-key");
+   std::string const aptkey = _config->Find("Dir::Bin::apt-key", CMAKE_INSTALL_FULL_BINDIR "/apt-key");
 
    bool const Debug = _config->FindB("Debug::Acquire::gpgv", false);
    struct exiter {

+ 3 - 2
apt-pkg/contrib/strutl.cc

@@ -21,6 +21,7 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/error.h>
 
+#include <array>
 #include <algorithm>
 #include <iomanip>
 #include <locale>
@@ -758,7 +759,7 @@ string TimeRFC1123(time_t Date, bool const NumericTimezone)
    if (gmtime_r(&Date, &Conv) == NULL)
       return "";
 
-   auto const posix = std::locale("C.UTF-8");
+   auto const posix = std::locale::classic();
    std::ostringstream datestr;
    datestr.imbue(posix);
    APT::StringView const fmt("%a, %d %b %Y %H:%M:%S");
@@ -945,7 +946,7 @@ bool RFC1123StrToTime(const char* const str,time_t &time)
    signed int year = 0; // yes, Y23K problem – we gonna worry then…
    std::string weekday, month, datespec, timespec, zone;
    std::istringstream ss(str);
-   auto const &posix = std::locale("C.UTF-8");
+   auto const &posix = std::locale::classic();
    ss.imbue(posix);
    ss >> weekday;
    // we only superficially check weekday, mostly to avoid accepting localized

+ 1 - 0
apt-pkg/deb/debindexfile.cc

@@ -30,6 +30,7 @@
 #include <sstream>
 
 #include <sys/stat.h>
+#include <unistd.h>
 									/*}}}*/
 
 // Sources Index							/*{{{*/

+ 4 - 4
apt-pkg/deb/debsystem.cc

@@ -188,7 +188,7 @@ static std::string getDpkgStatusLocation(Configuration const &Cnf) {
    Configuration PathCnf;
    PathCnf.Set("Dir", Cnf.Find("Dir", "/"));
    PathCnf.Set("Dir::State::status", "status");
-   auto const cnfstatedir = Cnf.Find("Dir::State", "var/lib/apt/");
+   auto const cnfstatedir = Cnf.Find("Dir::State", STATE_DIR + 1);
    // if the state dir ends in apt, replace it with dpkg -
    // for the default this gives us the same as the fallback below.
    // This can't be a ../dpkg as that would play bad with symlinks
@@ -211,7 +211,7 @@ bool debSystem::Initialize(Configuration &Cnf)
    Cnf.CndSet("Dir::State::extended_states", "extended_states");
    if (Cnf.Exists("Dir::State::status") == false)
       Cnf.Set("Dir::State::status", getDpkgStatusLocation(Cnf));
-   Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg");
+   Cnf.CndSet("Dir::Bin::dpkg",BIN_DIR"/dpkg");
 
    if (d->StatusFile) {
      delete d->StatusFile;
@@ -239,9 +239,9 @@ APT_PURE bool debSystem::ArchiveSupported(const char *Type)
 signed debSystem::Score(Configuration const &Cnf)
 {
    signed Score = 0;
-   if (FileExists(Cnf.FindFile("Dir::State::status","/var/lib/dpkg/status")) == true)
+   if (FileExists(Cnf.FindFile("Dir::State::status",getDpkgStatusLocation(Cnf).c_str())) == true)
        Score += 10;
-   if (FileExists(Cnf.Find("Dir::Bin::dpkg","/usr/bin/dpkg")) == true)
+   if (FileExists(Cnf.Find("Dir::Bin::dpkg",BIN_DIR"/dpkg")) == true)
       Score += 10;
    if (FileExists("/etc/debian_version") == true)
       Score += 10;

+ 2 - 0
apt-pkg/deb/dpkgpm.cc

@@ -61,6 +61,8 @@
 #include <apti18n.h>
 									/*}}}*/
 
+extern char **environ;
+
 using namespace std;
 
 APT_PURE static string AptHistoryRequestingUser()			/*{{{*/

+ 2 - 0
apt-pkg/edsp/edsplistparser.cc

@@ -21,6 +21,8 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/pkgsystem.h>
 
+#include <array>
+
 									/*}}}*/
 
 // ListParser::edspListParser - Constructor				/*{{{*/

+ 3 - 3
apt-pkg/indexcopy.cc

@@ -207,7 +207,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
 	 FinalF += URItoFileName(S);
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	    return _error->Errno("rename","Failed to rename");
-	 ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", "root", 0644);
+	 ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", ROOT_GROUP, 0644);
       }
 
       /* Mangle the source to be in the proper notation with
@@ -531,7 +531,7 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName,		/*{{{*/
       Rel.Open(prefix + file,FileFd::ReadOnly);
       if (CopyFile(Rel,Target) == false || Target.Close() == false)
 	 return _error->Error("Copying of '%s' for '%s' from '%s' failed", file.c_str(), CDName.c_str(), prefix.c_str());
-      ChangeOwnerAndPermissionOfFile("CopyPackages", TargetF.c_str(), "root", "root", 0644);
+      ChangeOwnerAndPermissionOfFile("CopyPackages", TargetF.c_str(), "root", ROOT_GROUP, 0644);
 
       return true;
 }
@@ -738,7 +738,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,	/*{{{*/
 	 FinalF += URItoFileName(S);
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	    return _error->Errno("rename","Failed to rename");
-	 ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", "root", 0644);
+	 ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", ROOT_GROUP, 0644);
       }
 
       CurrentSize += FileSize;

+ 6 - 6
apt-pkg/init.cc

@@ -47,19 +47,19 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.CndSet("Dir","/");
    
    // State
-   Cnf.CndSet("Dir::State","var/lib/apt/");
+   Cnf.CndSet("Dir::State", STATE_DIR + 1);
    Cnf.CndSet("Dir::State::lists","lists/");
    Cnf.CndSet("Dir::State::cdroms","cdroms.list");
    Cnf.CndSet("Dir::State::mirrors","mirrors/");
 
    // Cache
-   Cnf.CndSet("Dir::Cache","var/cache/apt/");
+   Cnf.CndSet("Dir::Cache", CACHE_DIR + 1);
    Cnf.CndSet("Dir::Cache::archives","archives/");
    Cnf.CndSet("Dir::Cache::srcpkgcache","srcpkgcache.bin");
    Cnf.CndSet("Dir::Cache::pkgcache","pkgcache.bin");
 
    // Configuration
-   Cnf.CndSet("Dir::Etc","etc/apt/");
+   Cnf.CndSet("Dir::Etc", CONF_DIR + 1);
    Cnf.CndSet("Dir::Etc::sourcelist","sources.list");
    Cnf.CndSet("Dir::Etc::sourceparts","sources.list.d");
    Cnf.CndSet("Dir::Etc::main","apt.conf");
@@ -69,12 +69,12 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.CndSet("Dir::Etc::preferencesparts","preferences.d");
    Cnf.CndSet("Dir::Etc::trusted", "trusted.gpg");
    Cnf.CndSet("Dir::Etc::trustedparts","trusted.gpg.d");
-   Cnf.CndSet("Dir::Bin::methods","/usr/lib/apt/methods");
-   Cnf.CndSet("Dir::Bin::solvers::","/usr/lib/apt/solvers");
+   Cnf.CndSet("Dir::Bin::methods", LIBEXEC_DIR "/methods");
+   Cnf.CndSet("Dir::Bin::solvers::",LIBEXEC_DIR  "/apt/solvers");
    Cnf.CndSet("Dir::Media::MountPath","/media/apt");
 
    // State
-   Cnf.CndSet("Dir::Log","var/log/apt");
+   Cnf.CndSet("Dir::Log", LOG_DIR + 1);
    Cnf.CndSet("Dir::Log::Terminal","term.log");
    Cnf.CndSet("Dir::Log::History","history.log");
    Cnf.CndSet("Dir::Log::Planner","eipp.log.xz");

+ 2 - 2
apt-pkg/install-progress.cc

@@ -84,7 +84,7 @@ static std::string GetProgressFdString(char const * const status,
 {
    float const progress{Done / static_cast<float>(Total) * 100};
    std::ostringstream str;
-   str.imbue(std::locale("C.UTF-8"));
+   str.imbue(std::locale::classic());
    str.precision(4);
    str << status << ':' << pkg << ':' << std::fixed << progress << ':' << msg << '\n';
    return str.str();
@@ -165,7 +165,7 @@ static std::string GetProgressDeb822String(char const * const status,
 {
    float const progress{Done / static_cast<float>(Total) * 100};
    std::ostringstream str;
-   str.imbue(std::locale("C.UTF-8"));
+   str.imbue(std::locale::classic());
    str.precision(4);
    str << "Status: " << status << '\n';
    if (pkg != nullptr)

+ 7 - 0
apt-private/private-download.cc

@@ -25,7 +25,14 @@
 #include <sys/types.h>
 #include <pwd.h>
 #include <fcntl.h>
+#ifdef HAVE_VFS_H
 #include <sys/vfs.h>
+#else
+#ifdef HAVE_PARAMS_H
+#include <sys/params.h>
+#endif
+#include <sys/mount.h>
+#endif
 #include <sys/statvfs.h>
 #include <sys/stat.h>
 #include <errno.h>

+ 1 - 0
apt-private/private-show.cc

@@ -24,6 +24,7 @@
 #include <apt-private/private-show.h>
 
 #include <stdio.h>
+#include <unistd.h>
 #include <ostream>
 #include <string>
 

+ 1 - 0
cmdline/apt-helper.cc

@@ -29,6 +29,7 @@
 #include <string>
 #include <vector>
 
+#include <unistd.h>
 #include <stdlib.h>
 
 #include <apti18n.h>

+ 1 - 1
cmdline/apt-key.in

@@ -321,7 +321,7 @@ merge_all_trusted_keyrings_into_pubring() {
     # does the same as:
     # foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
     # but without using gpg, just cat and find
-    local PUBRING="$(readlink -f "${GPGHOMEDIR}/pubring.gpg")"
+    local PUBRING="$(readlink -f "${GPGHOMEDIR}")/pubring.gpg"
     rm -f "$PUBRING"
     touch "$PUBRING"
     foreach_keyring_do 'catfile' "$PUBRING"

+ 1 - 0
cmdline/apt-sortpkgs.cc

@@ -29,6 +29,7 @@
 #include <vector>
 #include <algorithm>
 #include <stdio.h>
+#include <unistd.h>
 #include <iostream>
 #include <string>
 #include <memory>

+ 1 - 1
debian/apt.auto-removal.sh

@@ -25,7 +25,7 @@ debverlist="$(echo "$list" | cut -d' ' -f 2 | sort --unique --reverse --version-
 if [ -n "$1" ]; then
 	installed_version="$(echo "$list" | awk "\$1 == \"$1\" { print \$2;exit; }")"
 fi
-unamer="$(uname -r)"
+unamer="$(uname -r | tr '[A-Z]' '[a-z]')"
 if [ -n "$unamer" ]; then
 	running_version="$(echo "$list" | awk "\$1 == \"$unamer\" { print \$2;exit; }")"
 fi

+ 1 - 0
ftparchive/CMakeLists.txt

@@ -1,3 +1,4 @@
+include_directories(${BERKELEY_DB_INCLUDE_DIRS})
 # Create the executable tasks
 file(GLOB_RECURSE source "*.cc")
 add_executable(apt-ftparchive ${source})

+ 1 - 1
methods/CMakeLists.txt

@@ -21,7 +21,7 @@ target_link_libraries(store apt-pkg)
 target_link_libraries(gpgv apt-pkg)
 target_link_libraries(cdrom apt-pkg)
 target_link_libraries(http apt-pkg)
-target_link_libraries(mirror apt-pkg -lresolv)
+target_link_libraries(mirror apt-pkg ${RESOLV_LIBRARIES})
 target_link_libraries(https apt-pkg ${CURL_LIBRARIES})
 target_link_libraries(ftp apt-pkg)
 target_link_libraries(rred apt-pkg)

+ 2 - 0
methods/connect.cc

@@ -180,8 +180,10 @@ static bool ConnectToHostname(std::string const &Host, int const Port,
       memset(&Hints,0,sizeof(Hints));
       Hints.ai_socktype = SOCK_STREAM;
       Hints.ai_flags = 0;
+#ifdef AI_IDN
       if (_config->FindB("Acquire::Connect::IDN", true) == true)
 	 Hints.ai_flags |= AI_IDN;
+#endif
       // see getaddrinfo(3): only return address if system has such a address configured
       // useful if system is ipv4 only, to not get ipv6, but that fails if the system has
       // no address configured: e.g. offline and trying to connect to localhost.

+ 83 - 39
test/integration/framework

@@ -31,7 +31,6 @@ if [ "${MSGCOLOR:-YES}" = 'YES' ]; then
 	fi
 fi
 
-
 if [ "$MSGCOLOR" != 'NO' ]; then
 	CERROR="\033[1;31m" # red
 	CWARNING="\033[1;33m" # yellow
@@ -196,6 +195,9 @@ aptinternalplanner() { runapt "${APTINTERNALPLANNER}" "$@"; }
 dpkg() {
 	"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "$@"
 }
+dpkg_version() {
+	command perl -MDpkg -E 'say $Dpkg::PROGVERSION'
+}
 dpkgcheckbuilddeps() {
 	command dpkg-checkbuilddeps --admindir="${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg" "$@"
 }
@@ -276,8 +278,13 @@ find_project_binary_dir() {
 	fi
 }
 setupenvironment() {
+	# Next check needs a gnu stat, let's figure that out early.
+	stat=stat
+	if command -v gnustat >/dev/null 2>&1; then
+		stat=gnustat
+	fi
 	# privilege dropping and testing doesn't work if /tmp isn't world-writeable (as e.g. with libpam-tmpdir)
-	if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$(stat --format '%a' "$TMPDIR")" != '1777' ]; then
+	if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$($stat --format '%a' "$TMPDIR")" != '1777' ]; then
 		unset TMPDIR
 	fi
 	TMPWORKINGDIRECTORY="$(mktemp -d)"
@@ -290,12 +297,24 @@ setupenvironment() {
 	fi
 	msgninfo "Preparing environment for ${0##*/} in ${TMPWORKINGDIRECTORY}…"
 
+	# Setup coreutils on BSD systems
+	mkdir "${TMPWORKINGDIRECTORY}/bin"
+	for prefix in gnu g; do
+			for command in stat touch sed cp tr sha1sum sha256sum md5sum sha512sum grep date wc chmod head readlink tar expr base64; do
+					if command -v $prefix$command 2>/dev/null >/dev/null; then
+							[ -e "${TMPWORKINGDIRECTORY}/bin/$command" ] || ln -sf $(command -v $prefix$command)  "${TMPWORKINGDIRECTORY}/bin/$command"
+					fi
+			done
+	done
+	export PATH="${TMPWORKINGDIRECTORY}/bin/:$PATH"
+
+
 	mkdir -m 700 "${TMPWORKINGDIRECTORY}/downloaded"
 	if [ "$(id -u)" = '0' ]; then
 		# relax permissions so that running as root with user switching works
 		umask 022
 		chmod 711 "$TMPWORKINGDIRECTORY"
-		chown _apt:root "${TMPWORKINGDIRECTORY}/downloaded"
+		chown _apt:$(id -gn) "${TMPWORKINGDIRECTORY}/downloaded"
 	fi
 
 	TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
@@ -352,6 +371,11 @@ setupenvironment() {
 	ln -s "${TMPWORKINGDIRECTORY}/keys/joesixpack.pub" rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 
 	echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf
+	echo "Dir::Etc \"etc\";" >> aptconfig.conf
+	echo "Dir::State \"var/lib/apt\";" >> aptconfig.conf
+	echo "Dir::Cache \"var/cache/apt\";" >> aptconfig.conf
+	echo "Dir::Etc \"etc/apt\";" >> aptconfig.conf
+	echo "Dir::Log \"var/log/apt\";" >> aptconfig.conf
 	echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf
 	echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf
 	# either store apt-key were we can access it, even if we run it as a different user
@@ -386,11 +410,13 @@ EOF
 	cp "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg"
 	cat >> "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" <<EOF
 exec fakeroot '${DPKG:-dpkg}' --root='${TMPWORKINGDIRECTORY}/rootdir' \\
+	--admindir="${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg" \\
 	--log='${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log' \\
 	--force-not-root --force-bad-path "\$@"
 EOF
 	cat >> "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg" <<EOF
 exec fakeroot gdb --quiet -ex run '${DPKG:-dpkg}' --args '${DPKG:-dpkg}' --root='${TMPWORKINGDIRECTORY}/rootdir' \\
+	--admindir="${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg" \\
 	--log='${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log' \\
 	--force-not-root --force-bad-path "\$@"
 EOF
@@ -416,7 +442,7 @@ EOF
 
 	cp "${TESTDIRECTORY}/apt.pem" "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem"
 	if [ "$(id -u)" = '0' ]; then
-		chown _apt:root "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem"
+		chown _apt:$(id -gn) "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem"
 	fi
 	echo "Acquire::https::CaInfo \"${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem\";" > rootdir/etc/apt/apt.conf.d/99https
 	echo "Apt::Cmd::Disable-Script-Warning \"1\";" > rootdir/etc/apt/apt.conf.d/apt-binary
@@ -428,16 +454,13 @@ EOF
 
 	# create some files in /tmp and look at user/group to get what this means
 	TEST_DEFAULT_USER="$(id -un)"
-	if [ "$(uname)" = 'GNU/kFreeBSD' ]; then
-		TEST_DEFAULT_GROUP='root'
-	else
-		TEST_DEFAULT_GROUP="$(id -gn)"
-	fi
+	touch "${TMPWORKINGDIRECTORY}/test-file"
+	TEST_DEFAULT_GROUP=$(stat --format '%G'  "${TMPWORKINGDIRECTORY}/test-file")
 
 	# cleanup the environment a bit
 	# prefer our apt binaries over the system apt binaries
 	export PATH="${BUILDDIRECTORY}:${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
-	export LC_ALL=C.UTF-8
+	export LC_ALL=C
 	unset LANGUAGE APT_CONFIG
 	unset GREP_OPTIONS DEB_BUILD_PROFILES
 	unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy
@@ -500,7 +523,15 @@ configdpkg() {
 		fi
 	fi
 	rm -f rootdir/etc/apt/apt.conf.d/00foreigndpkg
-	if command dpkg --assert-multi-arch >/dev/null 2>&1 ; then
+	# if multi-arch make sure dpkg can detect itself as capable of it
+	if getarchitectures | grep -E -q '[^ ]+ [^ ]+'; then
+		if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then
+			# dpkg doesn't really check the version as long as it is fully installed,
+			# but just to be sure we choose one above the required version
+			insertinstalledpackage 'dpkg' "all" '1.16.2+fake'
+		fi
+	fi
+	if dpkg --assert-multi-arch >/dev/null 2>&1 ; then
 		local ARCHS="$(getarchitectures)"
 		local DPKGARCH="$(dpkg --print-architecture)"
 		# this ensures that even if multi-arch isn't active in the view
@@ -515,14 +546,6 @@ configdpkg() {
 				fi
 			fi
 		done
-		# if multi-arch make sure dpkg can detect itself as capable of it
-		if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
-			if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then
-				# dpkg doesn't really check the version as long as it is fully installed,
-				# but just to be sure we choose one above the required version
-				insertinstalledpackage 'dpkg' "all" '1.16.2+fake'
-			fi
-		fi
 	fi
 }
 
@@ -568,7 +591,11 @@ int execvp(const char *file, char *const argv[]) {
 	return func_execvp(newfile, argv);
 }
 EOF
-	testempty --nomsg gcc -Wall -Wextra -fPIC -shared -o noopchroot.so noopchroot.c -ldl
+	if cc -ldl 2>&1 | grep -q dl; then
+		testempty --nomsg cc -Wall -Wextra -fPIC -shared -o noopchroot.so noopchroot.c
+	else
+		testempty --nomsg cc -Wall -Wextra -fPIC -shared -o noopchroot.so noopchroot.c -ldl
+	fi
 }
 configcompression() {
 	if [ "$1" = 'ALL' ]; then
@@ -626,10 +653,10 @@ _setupsimplenativepackage() {
 	local VERSION="$3"
 	local RELEASE="${4:-unstable}"
 	local DEPENDENCIES="$5"
-	local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
+	local DESCRIPTION="${6:-an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
  If you find such a package installed on your system,
  something went horribly wrong! They are autogenerated
- und used only by testcases and serve no other purpose…"}"
+ und used only by testcases and serve no other purpose…}"
 
 	local SECTION="${7:-others}"
 	local PRIORITY="${8:-optional}"
@@ -662,7 +689,7 @@ Standards-Version: 3.9.3"
 		if [ "$SECTION" != '<none>' ]; then
 			echo "Section: $SECTION"
 		fi
-		local BUILDDEPS="$(echo "$DEPENDENCIES" | grep '^Build-')"
+		local BUILDDEPS="$(printf "%b\n" "$DEPENDENCIES" | grep '^Build-')"
 		test -z "$BUILDDEPS" || echo "$BUILDDEPS"
 		echo "
 Package: $NAME"
@@ -672,21 +699,33 @@ Package: $NAME"
 		else
 			echo "Architecture: any"
 		fi
-		local DEPS="$(echo "$DEPENDENCIES" | grep -v '^Build-')"
+		local DEPS="$(printf "%b\n" "$DEPENDENCIES" | grep -v '^Build-')"
 		test -z "$DEPS" || echo "$DEPS"
-		echo "Description: $DESCRIPTION"
+		printf "%b\n" "Description: $DESCRIPTION"
 	} > "${BUILDDIR}/debian/control"
 
 	echo '3.0 (native)' > "${BUILDDIR}/debian/source/format"
 }
 
+make_tiny_rules() {
+	local OUT="$1"
+	if command -v gmake >/dev/null 2>&1; then
+		[ -e ${TMPWORKINGDIRECTORY}/bin/make ] || ln -s $(command -v gmake) ${TMPWORKINGDIRECTORY}/bin/make
+		echo "#!${TMPWORKINGDIRECTORY}/bin/make -f" > "$OUT"
+	else
+		echo '#!/usr/bin/make -f' > "$OUT"
+	fi
+	echo '%:' >> "$OUT"
+	echo '	dh $@' >> "$OUT"
+}
+
 setupsimplenativepackage() {
 	_setupsimplenativepackage "$@"
 	local NAME="$1"
 	local VERSION="$3"
 	local BUILDDIR="${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION}"
 	test -e "${BUILDDIR}/debian/compat" || echo '7' > "${BUILDDIR}/debian/compat"
-	test -e  "${BUILDDIR}/debian/rules" || cp /usr/share/doc/debhelper/examples/rules.tiny "${BUILDDIR}/debian/rules"
+	test -e  "${BUILDDIR}/debian/rules" || make_tiny_rules "${BUILDDIR}/debian/rules"
 }
 
 buildsimplenativepackage() {
@@ -844,10 +883,10 @@ insertpackage() {
 	local VERSION="$4"
 	local DEPENDENCIES="$5"
 	local PRIORITY="${6:-optional}"
-	local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASES}
+	local DESCRIPTION="${7:-an autogenerated dummy ${NAME}=${VERSION}/${RELEASES}
  If you find such a package installed on your system,
  something went horribly wrong! They are autogenerated
- und used only by testcases and serve no other purpose…"}"
+ und used only by testcases and serve no other purpose…}"
 	local ARCHS=""
 	for RELEASE in $(printf '%s' "$RELEASES" | tr ',' '\n'); do
 		if [ "$RELEASE" = 'installed' ]; then
@@ -872,7 +911,7 @@ Maintainer: Joe Sixpack <joe@example.org>"
 					test "$arch" = 'none' || echo "Architecture: $arch"
 					echo "Version: $VERSION
 Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb"
-					test -z "$DEPENDENCIES" || echo "$DEPENDENCIES"
+					test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES"
 					echo "Description: $(printf '%s' "$DESCRIPTION" | head -n 1)"
 					echo "Description-md5: $(printf '%s' "$DESCRIPTION" | md5sum | cut -d' ' -f 1)"
 					echo "SHA256: 0000000000000000000000000000000000000000000000000000000000000000"
@@ -908,7 +947,7 @@ Binary: $BINARY
 Version: $VERSION
 Maintainer: Joe Sixpack <joe@example.org>
 Architecture: $ARCH" >> $FILE
-		test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> "$FILE"
+		test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES" >> "$FILE"
 		echo "Files:
  $(echo -n "$DSCFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$DSCFILE" | wc -c) "$DSCFILE"
  $(echo -n "$TARFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$TARFILE" | wc -c) "$TARFILE"
@@ -926,10 +965,10 @@ insertinstalledpackage() {
 	local DEPENDENCIES="$4"
 	local PRIORITY="${5:-optional}"
 	local STATUS="${6:-install ok installed}"
-	local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/installed
+	local DESCRIPTION="${7:-an autogenerated dummy ${NAME}=${VERSION}/installed
  If you find such a package installed on your system,
  something went horribly wrong! They are autogenerated
- und used only by testcases and serve no other purpose…"}"
+ und used only by testcases and serve no other purpose…}"
 
 	local FILE='rootdir/var/lib/dpkg/status'
 	local INFO='rootdir/var/lib/dpkg/info'
@@ -942,8 +981,8 @@ Installed-Size: 42
 Maintainer: Joe Sixpack <joe@example.org>
 Version: $VERSION" >> "$FILE"
 		test "$arch" = 'none' || echo "Architecture: $arch" >> "$FILE"
-		test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> "$FILE"
-		echo "Description: $DESCRIPTION" >> "$FILE"
+		test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES" >> "$FILE"
+		printf "%b\n" "Description: $DESCRIPTION" >> "$FILE"
 		echo >> "$FILE"
 		if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then
 			echo -n > "${INFO}/${NAME}:${arch}.list"
@@ -1276,7 +1315,12 @@ changetowebserver() {
 }
 
 changetohttpswebserver() {
-	if ! command -v stunnel4 >/dev/null 2>&1; then
+	local stunnel4
+	if command -v stunnel4 >/dev/null 2>&1; then
+		stunnel4=stunnel4
+	elif command -v stunnel >/dev/null 2>&1; then
+		stunnel4=stunnel
+	else
 		msgdie 'You need to install stunnel4 for https testcases'
 	fi
 	if [ ! -e "${TMPWORKINGDIRECTORY}/aptarchive/aptwebserver.pid" ]; then
@@ -1290,14 +1334,14 @@ output = /dev/null
 accept = 0
 connect = $APTHTTPPORT
 " > "${TMPWORKINGDIRECTORY}/stunnel.conf"
-	stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf"
+	$stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf"
         waitforpidfile "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid"
 	local PID="$(cat "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid")"
         if [ -z "$PID" ]; then
-		msgdie 'Could not fork stunnel4 successfully'
+		msgdie 'Could not fork $stunnel4 successfully'
 	fi
 	addtrap 'prefix' "kill ${PID};"
-	APTHTTPSPORT="$(lsof -i -n | awk "/^stunnel4 / && \$2 == \"${PID}\" {print \$9; exit; }" | cut -d':' -f 2)"
+	APTHTTPSPORT="$(lsof -i -n | awk "/^$stunnel4 / && \$2 == \"${PID}\" {print \$9; exit; }" | cut -d':' -f 2)"
 	webserverconfig 'aptwebserver::port::https' "$APTHTTPSPORT" "https://localhost:${APTHTTPSPORT}"
 	rewritesourceslist "https://localhost:${APTHTTPSPORT}/"
 }
@@ -1917,7 +1961,7 @@ mkdir() {
 		command mkdir -m 700 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial"
 		touch "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/lock"
 		if [ "$(id -u)" = '0' ]; then
-			chown _apt:root "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial"
+			chown _apt:$(id -gn) "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial"
 		fi
 	else
 		command mkdir "$@"

+ 5 - 1
test/integration/run-tests

@@ -89,7 +89,11 @@ if [ -n "$APT_TEST_JOBS" ]; then
 	if [ "$MSGCOLOR" != 'NO' ]; then
 		export MSGCOLOR='ALWAYS'
 	fi
-	exec parallel -j "$APT_TEST_JOBS" "./$(basename "$0")" -- $(echo "$TESTLIST")
+	parallel=parallel
+	if command -v moreutils-parallel >/dev/null 2>&1; then
+		parallel=moreutils-parallel
+	fi
+	exec $parallel -j "$APT_TEST_JOBS" "./$(basename "$0")" -- $(echo "$TESTLIST")
 fi
 TOTAL="$(echo "$TESTLIST" | wc -l)"
 for testcase in $TESTLIST; do

+ 1 - 1
test/integration/test-apt-config

@@ -24,7 +24,7 @@ testsuccessequal "ARCH='amd64'" aptconfig shell ARCH APT::Architecture
 ROOTDIR="$(readlink -f rootdir)"
 testsuccessequal "CONFIG='apt.conf'" aptconfig shell CONFIG Dir::Etc::main
 testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/apt.conf'" aptconfig shell CONFIG Dir::Etc::main/f
-testsuccessequal "CONFIG='etc/apt/'" aptconfig shell CONFIG Dir::Etc
+testsuccessequal "CONFIG='etc/apt'" aptconfig shell CONFIG Dir::Etc
 testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/ # old style
 testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/d
 

+ 8 - 3
test/integration/test-apt-ftparchive-cachedb-lp1274466

@@ -11,14 +11,19 @@ setupenvironment
 configarchitecture "i386"
 confighashes 'MD5' 'SHA1' 'SHA256' 'SHA512'
 
+db_dump=db_dump
+if command -v db_dump-5 >/dev/null 2>&1; then
+    db_dump=db_dump-5
+fi
+
 # gather the db and the deb, ensure mtime is not modfied as its saved in the DB
 cp -p "$TESTDIR/deb-lp1274466-cachedb.deb" foo_1_i386.deb
 cp -p "$TESTDIR/cachedb-lp1274466-old-format.db" old-format.db
 
 # verify that the format is different
 testsuccess aptftparchive --db new-format.db packages .
-db_dump new-format.db > new-format.dump
-db_dump old-format.db > old-format.dump
+$db_dump new-format.db > new-format.dump
+$db_dump old-format.db > old-format.dump
 testfailure diff -u old-format.dump new-format.dump
 
 # ensure the new format as the sha512
@@ -47,7 +52,7 @@ Description: an autogenerated dummy foo=1/test
 " aptftparchive  --db old-format.db packages .
 
 # ensure that the db is updated and contains the new sha512
-db_dump old-format.db > old-format.dump
+$db_dump old-format.db > old-format.dump
 
 testsuccess grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc12a0e7cadb4b66764235c56e1009dbfe8a9a566fb1eedf47a992d1fff2cc3332c old-format.dump
 

+ 3 - 3
test/integration/test-apt-get-changelog

@@ -122,13 +122,13 @@ testsuccess apt install dpkg -y
 # at this moment, we still have the Releasefile claim to be origin:ubuntu
 echo 'Acquire::Changelogs::AlwaysOnline::Origin::Ubuntu "false";' >> rootdir/etc/apt/apt.conf.d/nooriginchangelogs
 testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/d/dpkg/dpkg_42/changelog' dpkg.changelog" apt changelog dpkg --print-uris
-testsuccessequal "'gzip:///usr/share/doc/dpkg/changelog.Debian.gz' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false
+testsuccessequal "'copy://${TMPWORKINGDIRECTORY}/rootdir/usr/share/doc/dpkg/changelog' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false
 testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/d/dpkg/dpkg_42/changelog' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=true
 testsuccessequal "'http://localhost:${APTHTTPPORT}/pool/main/d/dpkg/dpkg_42/changelog' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false -o Acquire::Changelogs::AlwaysOnline::Origin::Ubuntu=true
-testsuccessequal "'gzip:///usr/share/doc/dpkg/changelog.Debian.gz' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false -o Acquire::Changelogs::AlwaysOnline::Origin::Debian=true
+testsuccessequal "'copy://${TMPWORKINGDIRECTORY}/rootdir/usr/share/doc/dpkg/changelog' dpkg.changelog" apt changelog dpkg --print-uris -o Acquire::Changelogs::AlwaysOnline=false -o Acquire::Changelogs::AlwaysOnline::Origin::Debian=true
 
 testsuccess apt changelog dpkg -d
 testfilestats 'dpkg.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
 head -n 3 dpkg.changelog > dpkg.change
-testfileequal 'dpkg.change' "$(apthelper cat-file '/usr/share/doc/dpkg/changelog.Debian.gz' | head -n 3)"
+testfileequal 'dpkg.change' "$(apthelper cat-file 'rootdir/usr/share/doc/dpkg/changelog' | head -n 3)"
 rm -f dpkg.change dpkg.changelog

+ 1 - 1
test/integration/test-authentication-basic

@@ -30,7 +30,7 @@ testauthsuccess() {
 	# lets see if got/retains acceptable permissions
 	if [ -n "$AUTHCONF" ]; then
 		if [ "$(id -u)" = '0' ]; then
-			testfilestats "$AUTHCONF" '%U:%G:%a' '=' "_apt:root:600"
+			testfilestats "$AUTHCONF" '%U:%G:%a' '=' "_apt:$(id -gn):600"
 		else
 			testfilestats "$AUTHCONF" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:600"
 		fi

+ 1 - 1
test/integration/test-bug-661537-build-profiles-support

@@ -76,7 +76,7 @@ Building dependency tree...
 }
 
 msgtest 'Check if version of installed dpkg is high enough for' 'build profiles support'
-if dpkg --compare-versions "$(command dpkg-query --showformat='${Version}' --show dpkg)" 'ge' '1.17.14'; then
+if dpkg --compare-versions "$(dpkg_version)" 'ge' '1.17.14'; then
 	msgpass
 	testwithdpkg() {
 		msgtest "Test with" "dpkg-checkbuilddeps -d '$1' -P '$2'"

+ 1 - 1
test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch

@@ -32,7 +32,7 @@ if [ -n \"${2}\" ]; then
 	FD=\$APT_HOOK_INFO_FD
 	if [ "\$FD" != \"${2}\" ]; then echo \"ERROR: Information is not on requested FD: \$FD != ${2}\" >> ${hook}-v${1}.list; fi
 fi
-while read </proc/\$\$/fd/\$FD line; do
+while read </dev/fd/\$FD line; do
 	if echo \"\$line\" | grep -Fq '**'; then
 		echo \"\$line\"
 	fi

+ 6 - 6
test/integration/test-bug-769609-triggers-still-pending-after-run

@@ -8,7 +8,7 @@ setupenvironment
 configarchitecture 'amd64'
 
 msgtest 'Check if installed dpkg supports' 'noawait trigger'
-if dpkg-checkbuilddeps -d 'dpkg (>= 1.16.1)' /dev/null; then
+if dpkg --compare-versions "$(dpkg_version)" 'ge' '1.16.1'; then
 	msgpass
 else
 	msgskip 'dpkg version too old'
@@ -23,7 +23,7 @@ buildtriggerpackages() {
 	cat >"${BUILDDIR}/debian/postinst" <<EOF
 #!/bin/sh
 if [ "\$1" = 'triggered' ]; then
-	ls -l /proc/self/fd/
+	echo "TRIGGER IS RUNNING"
 fi
 EOF
 	echo "$TYPE /usr/share/doc" > "${BUILDDIR}/debian/triggers"
@@ -49,26 +49,26 @@ runtests() {
 	testsuccess aptget install trigdepends-$TYPE -y --reinstall
 	cp rootdir/tmp/testsuccess.output terminal.output
 	testsuccess grep '^REWRITE ' terminal.output
-	testsuccess grep ' root root ' terminal.output
+	testsuccess grep 'TRIGGER IS RUNNING' terminal.output
 	testdpkginstalled triggerable-$TYPE trigdepends-$TYPE
 
 	testsuccess aptget install trigstuff -y
 	cp rootdir/tmp/testsuccess.output terminal.output
 	testsuccess grep '^REWRITE ' terminal.output
-	testsuccess grep ' root root ' terminal.output
+	testsuccess grep 'TRIGGER IS RUNNING' terminal.output
 	testdpkginstalled triggerable-$TYPE trigdepends-$TYPE trigstuff
 
 	testsuccess aptget purge trigstuff -y
 	cp rootdir/tmp/testsuccess.output terminal.output
 	testsuccess grep '^REWRITE ' terminal.output
-	testsuccess grep ' root root ' terminal.output
+	testsuccess grep 'TRIGGER IS RUNNING' terminal.output
 	testdpkginstalled triggerable-$TYPE trigdepends-$TYPE
 	testdpkgnotinstalled trigstuff
 
 	testsuccess aptget purge trigdepends-$TYPE -y
 	cp rootdir/tmp/testsuccess.output terminal.output
 	testfailure grep '^REWRITE ' terminal.output
-	testfailure grep ' root root ' terminal.output
+	testfailure grep 'TRIGGER IS RUNNING' terminal.output
 	testdpkgnotinstalled triggerable-$TYPE trigdepends-$TYPE
 }
 #runtests 'interest'

+ 2 - 2
test/integration/test-external-dependency-solver-protocol

@@ -26,7 +26,7 @@ insertpackage 'experimental' 'coolstuff' 'i386,amd64' '3' 'Depends: cool, stuff'
 setupaptarchive
 
 testsuccess aptget install --solver apt coolstuff -s
-testempty find -name 'edsp.last.*'
+testempty find . -name 'edsp.last.*'
 echo 'Dir::Log::Solver "edsp.last.xz";' > rootdir/etc/apt/apt.conf.d/log-edsp.conf
 
 testfailure aptget install --solver dump coolstuff -s
@@ -152,7 +152,7 @@ testsuccess grep 'ERR_UNSOLVABLE' rootdir/tmp/testfailure.output
 configarchitecture 'armel'
 testfailure aptget install --solver apt awesomecoolstuff:i386 -s
 msgtest 'An invalid EDSP file generates a' 'hard error'
-if echo "Request: This is a test\nFoo: bar\n\n" | aptinternalsolver > solver.result 2>&1; then
+if printf "%b\n" "Request: This is a test\nFoo: bar\n\n" | aptinternalsolver > solver.result 2>&1; then
 	cat solver.result
 	msgfail
 else

+ 2 - 2
test/integration/test-kernel-helper-autoremove

@@ -6,7 +6,7 @@ TESTDIR="$(readlink -f "$(dirname "$0")")"
 setupenvironment
 configarchitecture 'amd64'
 
-CURRENTKERNEL="linux-image-$(uname -r)"
+CURRENTKERNEL="linux-image-$(uname -r | tr '[A-Z]' '[a-z]')"
 insertinstalledpackage "$CURRENTKERNEL" 'amd64' '5-1'
 # debug packages do not need our protection
 insertinstalledpackage "${CURRENTKERNEL}-dbg" 'amd64' '5-1'
@@ -49,7 +49,7 @@ testprotected() {
 	testsuccess --nomsg grep '^\^linux-image-100\\\.0\\\.0-1-generic\$$' protected.list
 
 	msgtest 'Check kernel autoremoval protection list includes' 'running kernel'
-	testsuccess --nomsg grep "^\\^linux-image-$(uname -r | sed -e 's#\.#\\\\.#g')\\\$\$" protected.list
+	testsuccess --nomsg grep "^\\^linux-image-$(uname -r | tr '[A-Z]' '[a-z]' | sed -e 's#\.#\\\\.#g')\\\$\$" protected.list
 
 	msgtest 'Check kernel autoremoval protection list does not include' 'metapackages'
 	testfailure --nomsg grep -e '^\^linux-image-amd64\$$' -e '^\^linux-image-686-pae\$$' -e ':i386' protected.list

+ 6 - 1
test/integration/test-no-fds-leaked-to-maintainer-scripts

@@ -8,6 +8,11 @@ setupenvironment
 configarchitecture 'amd64' 'i386'
 configdpkgnoopchroot
 
+if [ ! -e /proc/self/fd ]; then
+	msgskip "needs /proc/self/fd"
+    exit 0
+fi
+
 setupsimplenativepackage "fdleaks" 'all' '1.0' 'unstable'
 BUILDDIR="incoming/fdleaks-1.0"
 for script in 'preinst' 'postinst' 'prerm' 'postrm'; do
@@ -24,7 +29,7 @@ buildpackage "$BUILDDIR" 'unstable' 'main' 'native'
 rm -rf "$BUILDDIR"
 
 PKGNAME='fdleaks:all'
-if ! dpkg-checkbuilddeps -d 'dpkg (>= 1.16.2)' /dev/null >/dev/null 2>&1; then
+if dpkg --compare-versions "$(dpkg_version)" 'lt' '1.16.2'; then
 	PKGNAME='fdleaks'
 fi
 

+ 1 - 0
test/interactive-helper/test_fileutl.cc

@@ -4,6 +4,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <fcntl.h>

+ 1 - 1
vendor/getinfo

@@ -6,7 +6,7 @@ BASEDIR="$(readlink -f "$(dirname $0)")"
 getcurrent() {
 	# search for an exact match to use the correct sources.list example
 	cd $BASEDIR
-	DISTROS="$(find -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f 2)"
+	DISTROS="$(find . -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f 2)"
 	for DISTRO in $DISTROS; do
 		if dpkg-vendor --is $DISTRO; then
 			echo $DISTRO