From e2ac5f5dacae0ed3809f4c57089e661889657fda Mon Sep 17 00:00:00 2001
From: Assaf Gordon <assafgordon@gmail.com>
Date: Fri, 2 Aug 2019 20:22:33 -0600
Subject: [PATCH] contrib: document how to build older versions on newer
 systems

Based on https://lists.gnu.org/r/coreutils/2019-08/msg00011.html .

* contrib/build-older-versions/README.older-versions: Documentation
* contrib/build-older-versions/build-older-versions.sh: Helper script.
* contrib/build-older-versions/.gitignore: Ignore build directory.
* contrib/build-older-versions/coreutils-5.0-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-5.97-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-6.10-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-6.11-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-6.12-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-7.2-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-8.13-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-8.17-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-8.18-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-8.24-on-glibc-2.28.patch,
contrib/build-older-versions/coreutils-8.4-on-glibc-2.28.patch: Patches.
---
 contrib/build-older-versions/.gitignore       |   1 +
 .../README.older-versions                     | 169 ++++++++++++++++++
 .../build-older-versions.sh                   | 107 +++++++++++
 .../coreutils-5.0-on-glibc-2.28.patch         |  75 ++++++++
 .../coreutils-5.97-on-glibc-2.28.patch        |  51 ++++++
 .../coreutils-6.10-on-glibc-2.28.patch        |  24 +++
 .../coreutils-6.11-on-glibc-2.28.patch        |  34 ++++
 .../coreutils-6.12-on-glibc-2.28.patch        |  64 +++++++
 .../coreutils-7.2-on-glibc-2.28.patch         |  76 ++++++++
 .../coreutils-8.13-on-glibc-2.28.patch        |  88 +++++++++
 .../coreutils-8.17-on-glibc-2.28.patch        |  88 +++++++++
 .../coreutils-8.18-on-glibc-2.28.patch        |  88 +++++++++
 .../coreutils-8.24-on-glibc-2.28.patch        |  87 +++++++++
 .../coreutils-8.4-on-glibc-2.28.patch         |  88 +++++++++
 14 files changed, 1040 insertions(+)
 create mode 100644 contrib/build-older-versions/.gitignore
 create mode 100644 contrib/build-older-versions/README.older-versions
 create mode 100755 contrib/build-older-versions/build-older-versions.sh
 create mode 100644 contrib/build-older-versions/coreutils-5.0-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-5.97-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-6.10-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-6.11-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-6.12-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-7.2-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-8.13-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-8.17-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-8.18-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-8.24-on-glibc-2.28.patch
 create mode 100644 contrib/build-older-versions/coreutils-8.4-on-glibc-2.28.patch

diff --git a/contrib/build-older-versions/.gitignore b/contrib/build-older-versions/.gitignore
new file mode 100644
index 000000000..567609b12
--- /dev/null
+++ b/contrib/build-older-versions/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/contrib/build-older-versions/README.older-versions b/contrib/build-older-versions/README.older-versions
new file mode 100644
index 000000000..abbc812f1
--- /dev/null
+++ b/contrib/build-older-versions/README.older-versions
@@ -0,0 +1,169 @@
+Building older GNU coreutils versions on newer systems
+======================================================
+
+Overview
+--------
+
+Some older GNU coreutils fail to build on newer GNU/Linux systems.
+
+This happens with Coreutils version 8.29 and earlier, on systems
+using GlibC version 2.28 or newer, Such as Debian 10, CentOS 8, Fedora 29.
+
+A typical error is:
+
+    $ wget https://ftp.gnu.org/gnu/coreutils/coreutils-7.6.tar.xz
+    $ tar -xf coreutils-7.6.tar.xz
+    $ cd coreutils-7.6
+    $ ./configure
+    $ make
+    [...]
+    freadahead.c: In function 'freadahead':
+    freadahead.c:83:3: error: #error "Please port gnulib freadahead.c to
+                              your platform! Look at the definition of fflush,
+                              fread, ungetc on your system, then report this
+                              to bug-gnulib."
+    [...]
+    make[4]: *** [Makefile:1700: freadahead.o] Error 1
+
+Other similar errors mention 'freadptr', 'freadseek','fseterr'.
+Older version (pre 7.2) mention 'tee','eaccess','futimens'.
+
+
+Details
+-------
+
+GLibC version 2.28 removed non-standed headre file (libio.h) and some
+internal symbols which were used by gnulib (a core component of GNU coreutils).
+
+These were announced as 'deprecated' in vesion 2.27 [1], and removed in
+version 2.28. Gnulib code was adjusted shortly after [2],
+but the code changes obviously can't be retroactively made to
+previously-released coreutils versions.
+
+[1] https://sourceware.org/ml/libc-announce/2018/msg00000.html
+[2] https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html
+
+Older coreutils versions defined functions that were later picked-up
+by glibc ('tee','eaccess','futimens') resulting in conflicts.
+
+See the patches for the exact code changes.
+
+
+Supplied patches
+----------------
+
+The patch files in this directory change the source code of older
+coreutils versions, enabling successful build on newer systems.
+
+Some versions require different patches.
+
+Coreutils Versions             Patch file
+5.0                            coreutils-5.0-on-glibc-2.28.patch
+5.97 to 6.9                    coreutils-5.97-on-glibc-2.28.patch
+6.10                           coreutils-6.10-on-glibc-2.28.patch
+6.11                           coreutils-6.11-on-glibc-2.28.patch
+6.12                           coreutils-6.12-on-glibc-2.28.patch
+7.2  to 8.3                    coreutils-7.2-on-glibc-2.28.patch
+8.4  to 8.12                   coreutils-8.4-on-glibc-2.28.patch
+8.13 to 8.16                   coreutils-8.13-on-glibc-2.28.patch
+8.17                           coreutils-8.17-on-glibc-2.28.patch
+8.18 to 8.23                   coreutils-8.18-on-glibc-2.28.patch
+8.24 to 8.29                   coreutils-8.24-on-glibc-2.28.patch
+8.30 and newer                 [builds without patching]
+
+
+Manual build
+------------
+
+1. Download the desired version from https://ftp.gnu.org/gnu/coreutils .
+2. Patch using the corresponding patch file (see table above).
+3. Configure the build, optionally adding the version number
+   to the executables, to ensure they will not conflict with existing
+   (newer) executables
+4. Build with 'make'
+5. Optionally install with 'sudo make install'
+
+Example:
+
+    wget https://ftp.gnu.org/gnu/coreutils/coreutils-5.97.tar.gz
+    tar -xf coreutils-5.97.tar.gz
+    cd coreutils-5.97
+    patch -p1 < ../coreutils-5.97-on-glibc-2.28.patch
+    ./configure --program-suffix=-5.97
+    make
+    sudo make install
+
+This will install the programs (e.g. 'sort', 'head) in
+/usr/local/bin, with "-5.97" added to each program name (e.g. 'sort-5.97',
+'head-5.97').
+
+NOTE:
+With very old versions (5.X and 6.X), running "./configure" will
+hang for a long time at the following step:
+   "checking for mktime..."
+But will eventually continue successfully.
+
+
+Automated build
+---------------
+
+The script 'build-older-versions.sh' automatically performs the manual steps
+listed above. It will also install the programs into '$HOME/old-coreutils/bin' .
+
+Example, running the following commands
+
+    ./build-older-versions.sh 5.0
+    ./build-older-versions.sh 5.97
+    ./build-older-versions.sh 6.12
+    ./build-older-versions.sh 7.6
+
+Will download, patch, build and install the programs for GNU coreutils
+versions 5.0,5.97,6.12,7.6 in $HOME/old-coreutils/bin :
+
+    $ ls $HOME/old-coreutils/bin
+    [-5.97          id-5.0          sha224sum-7.6
+    [-6.12          id-5.97         sha256sum-6.12
+    [-7.6           id-6.12         sha256sum-7.6
+    base64-6.12     id-7.6          sha384sum-6.12
+    base64-7.6      install-5.0     sha384sum-7.6
+    basename-5.0    install-5.97    sha512sum-6.12
+    basename-5.97   install-6.12    sha512sum-7.6
+    basename-6.12   install-7.6     shred-5.0
+    basename-7.6    join-5.0        shred-5.97
+    cat-5.0         join-5.97       shred-6.12
+    cat-5.97        join-6.12       shred-7.6
+    cat-6.12        join-7.6        shuf-6.12
+    cat-7.6         kill-5.0        shuf-7.6
+    chcon-6.12      kill-5.97       sleep-5.0
+    chcon-7.6       kill-6.12       sleep-5.97
+    chgrp-5.0       kill-7.6        sleep-6.12
+    chgrp-5.97      link-5.0        sleep-7.6
+    chgrp-6.12      link-5.97       sort-5.0
+    chgrp-7.6       link-6.12       sort-5.97
+    chmod-5.0       link-7.6        sort-6.12
+    chmod-5.97      ln-5.0          sort-7.6
+    chmod-6.12      ln-5.97         split-5.0
+    chmod-7.6       ln-6.12         split-5.97
+    chown-5.0       ln-7.6          split-6.12
+    [... many more files ...]
+
+By adding the directory to your $PATH, older versions can be easily used:
+
+    export PATH=$PATH:$HOME/old-coreutils/bin
+
+
+
+
+
+
+========================================================================
+
+Copyright (C) 2019 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts.  A copy of the license is included in the "GNU Free
+Documentation License" file as part of this distribution.
+
diff --git a/contrib/build-older-versions/build-older-versions.sh b/contrib/build-older-versions/build-older-versions.sh
new file mode 100755
index 000000000..081299766
--- /dev/null
+++ b/contrib/build-older-versions/build-older-versions.sh
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+${PREFIX:=$HOME/old-coreutils/}
+
+die()
+{
+  base=$(basename "$0")
+  echo "$base: $*" >&2
+  exit 1
+}
+
+get_patch_file()
+{
+  case "$1" in
+    5.0)  echo coreutils-5.0-on-glibc-2.28.patch ;;
+    5.97|6.[345679]) echo coreutils-5.97-on-glibc-2.28.patch ;;
+    6.10) echo coreutils-6.10-on-glibc-2.28.patch ;;
+    6.11) echo coreutils-6.11-on-glibc-2.28.patch ;;
+    6.12) echo coreutils-6.12-on-glibc-2.28.patch ;;
+    7.[23456]|8.[123]) echo coreutils-7.2-on-glibc-2.28.patch ;;
+    8.[456789]|8.1[012]) echo coreutils-8.4-on-glibc-2.28.patch ;;
+    8.1[3456]) echo coreutils-8.13-on-glibc-2.28.patch ;;
+    8.17) echo coreutils-8.17-on-glibc-2.28.patch ;;
+    8.1[89]|8.2[0123]) echo coreutils-8.18-on-glibc-2.28.patch ;;
+    8.2[456789]) echo coreutils-8.24-on-glibc-2.28.patch ;;
+    8.3[01]) die "not needed" ;;
+    5.[12]*|5.9*)  die "version '$1' does not have a patch (yet) " \
+                       "use versions 5.0 or 5.97" ;;
+    7.1)  die "version '$1' does not have a patch (yet)" \
+                       "use versions 6.12 or 7.2" ;;
+    5*|6*|7*|8*) die "non-existing version" ;;
+    *) die "unknown version" ;;
+  esac
+}
+
+get_url()
+{
+  _base_url="https://ftp.gnu.org/gnu/coreutils/coreutils-$1.tar"
+  case "$1" in
+    5.*|6.*|7.*) echo "$_base_url.gz" ;;
+    8.*)         echo "$_base_url.xz" ;;
+    *) die "unknown version" ;;
+  esac
+}
+
+##
+## Setup
+##
+
+patch_file=$(get_patch_file "$1")
+test -e "$patch_file" \
+   || die "internal error: patch file '$patch_file' does not exist"
+
+url=$(get_url "$1")
+tarball=$(basename "$url")
+
+mkdir -p build
+cd build
+
+##
+## Download tarball (if needed)
+##
+if ! test -e "$tarball" ; then
+   wget -O "$tarball.t" "$url" \
+        && mv "$tarball.t" "$tarball" \
+        || die "failed to download '$url'"
+fi
+
+##
+## Extract tarball (if needed)
+##
+srcdir=${tarball%.tar.*}
+if ! test -d "$srcdir" ; then
+    tar -xvf "$tarball" || die "failed to extract '$tarball'"
+fi
+
+##
+## Patch (if needed)
+##
+cd "$srcdir"
+
+# Patch will fail if it was already applied (using "--forward" turns
+# that into a no-op). So don't check for failure.
+# Is there a way to differentiate between 'already applied' and
+# 'failed to apply' ?
+patch --batch --forward -p1 < "../../$patch_file"
+
+##
+## Configure
+##
+version=${srcdir#coreutils} # note:  this keeps the '-' in '$version'
+if ! test -e "Makefile" ; then
+  ./configure --program-suffix="$version" --prefix="$PREFIX" \
+    || die "failed to run configure in 'build/$srcdir/'"
+fi
+
+##
+## Build
+##
+make \
+  || die "build failed in 'build/$srcdir'"
+
+##
+## Install
+##
+make install \
+  || die "make-install failed in 'build/$srcdir' (to '$PREFIX')"
diff --git a/contrib/build-older-versions/coreutils-5.0-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-5.0-on-glibc-2.28.patch
new file mode 100644
index 000000000..fb276ae5b
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-5.0-on-glibc-2.28.patch
@@ -0,0 +1,75 @@
+diff -r -U3 coreutils-5.0/src/Makefile.in coreutils-5.0-patched/src/Makefile.in
+--- coreutils-5.0/src/Makefile.in	2003-04-02 07:46:19.000000000 -0700
++++ coreutils-5.0-patched/src/Makefile.in	2019-08-01 19:38:07.440997426 -0600
+@@ -209,7 +209,7 @@
+ printf_LDADD = $(LDADD) @POW_LIB@ @LIBICONV@
+ 
+ # If necessary, add -lm to resolve use of floor, rint, modf.
+-seq_LDADD = $(LDADD) @SEQ_LIBM@
++seq_LDADD = $(LDADD) @SEQ_LIBM@ -lm
+ 
+ # If necessary, add -lm to resolve the `pow' reference in lib/strtod.c
+ # or for the fesetround reference in programs using nanosec.c.
+diff -r -U3 coreutils-5.0/src/tee.c coreutils-5.0-patched/src/tee.c
+--- coreutils-5.0/src/tee.c	2002-12-15 07:21:45.000000000 -0700
++++ coreutils-5.0-patched/src/tee.c	2019-08-01 19:34:32.374301325 -0600
+@@ -32,7 +32,7 @@
+ 
+ #define AUTHORS N_ ("Mike Parker, Richard M. Stallman, and David MacKenzie")
+ 
+-static int tee (int nfiles, const char **files);
++static int tee_FOO (int nfiles, const char **files);
+ 
+ /* If nonzero, append to output files rather than truncating them. */
+ static int append;
+@@ -146,7 +146,7 @@
+   /* Do *not* warn if tee is given no file arguments.
+      POSIX requires that it work when given no arguments.  */
+ 
+-  errs = tee (argc - optind, (const char **) &argv[optind]);
++  errs = tee_FOO (argc - optind, (const char **) &argv[optind]);
+   if (close (STDIN_FILENO) != 0)
+     error (EXIT_FAILURE, errno, _("standard input"));
+ 
+@@ -158,7 +158,7 @@
+    Return 0 if successful, 1 if any errors occur. */
+ 
+ static int
+-tee (int nfiles, const char **files)
++tee_FOO (int nfiles, const char **files)
+ {
+   FILE **descriptors;
+   char buffer[BUFSIZ];
+diff -r -U3 coreutils-5.0/src/test.c coreutils-5.0-patched/src/test.c
+--- coreutils-5.0/src/test.c	2003-02-10 02:19:09.000000000 -0700
++++ coreutils-5.0-patched/src/test.c	2019-08-01 19:35:52.871307966 -0600
+@@ -139,7 +139,7 @@
+ /* Do the same thing access(2) does, but use the effective uid and gid.  */
+ 
+ static int
+-eaccess (char const *file, int mode)
++eaccess_FOO (char const *file, int mode)
+ {
+   static int have_ids;
+   static uid_t uid, euid;
+@@ -635,17 +635,17 @@
+ 
+     case 'r':			/* file is readable? */
+       unary_advance ();
+-      value = -1 != eaccess (argv[pos - 1], R_OK);
++      value = -1 != eaccess_FOO (argv[pos - 1], R_OK);
+       return (TRUE == value);
+ 
+     case 'w':			/* File is writable? */
+       unary_advance ();
+-      value = -1 != eaccess (argv[pos - 1], W_OK);
++      value = -1 != eaccess_FOO (argv[pos - 1], W_OK);
+       return (TRUE == value);
+ 
+     case 'x':			/* File is executable? */
+       unary_advance ();
+-      value = -1 != eaccess (argv[pos - 1], X_OK);
++      value = -1 != eaccess_FOO (argv[pos - 1], X_OK);
+       return (TRUE == value);
+ 
+     case 'O':			/* File is owned by you? */
diff --git a/contrib/build-older-versions/coreutils-5.97-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-5.97-on-glibc-2.28.patch
new file mode 100644
index 000000000..e167dca4f
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-5.97-on-glibc-2.28.patch
@@ -0,0 +1,51 @@
+diff -r -U3 coreutils-6.4/lib/utimens.c coreutils-6.4-patched/lib/utimens.c
+--- coreutils-6.4/lib/utimens.c	2006-09-14 03:53:59.000000000 -0600
++++ coreutils-6.4-patched/lib/utimens.c	2019-08-01 19:09:08.228883163 -0600
+@@ -73,7 +73,7 @@
+    Return 0 on success, -1 (setting errno) on failure.  */
+ 
+ int
+-futimens (int fd ATTRIBUTE_UNUSED,
++futimens_FOO (int fd ATTRIBUTE_UNUSED,
+ 	  char const *file, struct timespec const timespec[2])
+ {
+   /* There's currently no interface to set file timestamps with
+@@ -166,5 +166,5 @@
+ int
+ utimens (char const *file, struct timespec const timespec[2])
+ {
+-  return futimens (-1, file, timespec);
++  return futimens_FOO (-1, file, timespec);
+ }
+diff -r -U3 coreutils-6.4/lib/utimens.h coreutils-6.4-patched/lib/utimens.h
+--- coreutils-6.4/lib/utimens.h	2004-11-23 14:39:48.000000000 -0700
++++ coreutils-6.4-patched/lib/utimens.h	2019-08-01 19:08:25.656313704 -0600
+@@ -1,3 +1,3 @@
+ #include "timespec.h"
+-int futimens (int, char const *, struct timespec const [2]);
++int futimens_FOO (int, char const *, struct timespec const [2]);
+ int utimens (char const *, struct timespec const [2]);
+diff -r -U3 coreutils-6.4/src/copy.c coreutils-6.4-patched/src/copy.c
+--- coreutils-6.4/src/copy.c	2006-10-22 10:54:15.000000000 -0600
++++ coreutils-6.4-patched/src/copy.c	2019-08-01 19:09:42.421340384 -0600
+@@ -487,7 +487,7 @@
+       timespec[0] = get_stat_atime (src_sb);
+       timespec[1] = get_stat_mtime (src_sb);
+ 
+-      if (futimens (dest_desc, dst_name, timespec) != 0)
++      if (futimens_FOO (dest_desc, dst_name, timespec) != 0)
+ 	{
+ 	  error (0, errno, _("preserving times for %s"), quote (dst_name));
+ 	  if (x->require_preserve)
+diff -r -U3 coreutils-6.4/src/touch.c coreutils-6.4-patched/src/touch.c
+--- coreutils-6.4/src/touch.c	2006-10-22 10:54:15.000000000 -0600
++++ coreutils-6.4-patched/src/touch.c	2019-08-01 19:09:34.685236947 -0600
+@@ -182,7 +182,7 @@
+       t = timespec;
+     }
+ 
+-  ok = (futimens (fd, (fd == STDOUT_FILENO ? NULL : file), t) == 0);
++  ok = (futimens_FOO (fd, (fd == STDOUT_FILENO ? NULL : file), t) == 0);
+ 
+   if (fd == STDIN_FILENO)
+     {
diff --git a/contrib/build-older-versions/coreutils-6.10-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-6.10-on-glibc-2.28.patch
new file mode 100644
index 000000000..4f76ed9a2
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-6.10-on-glibc-2.28.patch
@@ -0,0 +1,24 @@
+diff -r -U3 coreutils-6.10/lib/freadahead.c coreutils-6.10-patched/lib/freadahead.c
+--- coreutils-6.10/lib/freadahead.c	2007-11-08 00:32:20.000000000 -0700
++++ coreutils-6.10-patched/lib/freadahead.c	2019-08-01 20:09:03.731243826 -0600
+@@ -22,7 +22,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ferror_unlocked     /* GNU libc, BeOS */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked     /* GNU libc, BeOS */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-6.10/lib/fseterr.c coreutils-6.10-patched/lib/fseterr.c
+--- coreutils-6.10/lib/fseterr.c	2007-11-08 00:32:20.000000000 -0700
++++ coreutils-6.10-patched/lib/fseterr.c	2019-08-01 20:09:16.407416594 -0600
+@@ -27,7 +27,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ferror_unlocked     /* GNU libc, BeOS */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked     /* GNU libc, BeOS */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror             /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
+   fp->_flags |= __SERR;
diff --git a/contrib/build-older-versions/coreutils-6.11-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-6.11-on-glibc-2.28.patch
new file mode 100644
index 000000000..6caab832e
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-6.11-on-glibc-2.28.patch
@@ -0,0 +1,34 @@
+diff -r -U3 coreutils-6.11/lib/freadahead.c coreutils-6.11-patched/lib/freadahead.c
+--- coreutils-6.11/lib/freadahead.c	2008-04-17 03:59:17.000000000 -0600
++++ coreutils-6.11-patched/lib/freadahead.c	2019-08-01 20:20:12.712193242 -0600
+@@ -19,10 +19,17 @@
+ /* Specification.  */
+ #include "freadahead.h"
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
++
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-6.11/lib/fseterr.c coreutils-6.11-patched/lib/fseterr.c
+--- coreutils-6.11/lib/fseterr.c	2008-04-17 03:59:17.000000000 -0600
++++ coreutils-6.11-patched/lib/fseterr.c	2019-08-01 20:20:37.868480486 -0600
+@@ -27,7 +27,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror             /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
+   fp->_flags |= __SERR;
diff --git a/contrib/build-older-versions/coreutils-6.12-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-6.12-on-glibc-2.28.patch
new file mode 100644
index 000000000..885a4dd04
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-6.12-on-glibc-2.28.patch
@@ -0,0 +1,64 @@
+diff -r -U3 coreutils-6.12/lib/freadahead.c coreutils-6.12-patched/lib/freadahead.c
+--- coreutils-6.12/lib/freadahead.c	2008-05-14 06:53:25.000000000 -0600
++++ coreutils-6.12-patched/lib/freadahead.c	2019-08-01 17:50:52.731658318 -0600
+@@ -24,7 +24,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-6.12/lib/freadptr.c coreutils-6.12-patched/lib/freadptr.c
+--- coreutils-6.12/lib/freadptr.c	2008-05-14 06:53:25.000000000 -0600
++++ coreutils-6.12-patched/lib/freadptr.c	2019-08-01 17:51:06.867856472 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-6.12/lib/freadseek.c coreutils-6.12-patched/lib/freadseek.c
+--- coreutils-6.12/lib/freadseek.c	2008-05-14 06:53:25.000000000 -0600
++++ coreutils-6.12-patched/lib/freadseek.c	2019-08-01 17:51:21.264058094 -0600
+@@ -34,7 +34,7 @@
+ freadptrinc (FILE *fp, size_t increment)
+ {
+   /* Keep this code in sync with freadptr!  */
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-6.12/lib/fseterr.c coreutils-6.12-patched/lib/fseterr.c
+--- coreutils-6.12/lib/fseterr.c	2008-05-14 06:53:25.000000000 -0600
++++ coreutils-6.12-patched/lib/fseterr.c	2019-08-01 17:51:36.668273645 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-6.12/lib/stdio-impl.h coreutils-6.12-patched/lib/stdio-impl.h
+--- coreutils-6.12/lib/stdio-impl.h	2008-05-14 06:53:25.000000000 -0600
++++ coreutils-6.12-patched/lib/stdio-impl.h	2019-08-01 17:49:51.518798189 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
diff --git a/contrib/build-older-versions/coreutils-7.2-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-7.2-on-glibc-2.28.patch
new file mode 100644
index 000000000..cdf857a63
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-7.2-on-glibc-2.28.patch
@@ -0,0 +1,76 @@
+diff -r -U3 coreutils-7.6/lib/freadahead.c coreutils-7.6-patched/lib/freadahead.c
+--- coreutils-7.6/lib/freadahead.c	2009-05-03 23:46:33.000000000 -0600
++++ coreutils-7.6-patched/lib/freadahead.c	2019-08-01 17:30:54.589238442 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-7.6/lib/freadptr.c coreutils-7.6-patched/lib/freadptr.c
+--- coreutils-7.6/lib/freadptr.c	2009-05-03 23:46:33.000000000 -0600
++++ coreutils-7.6-patched/lib/freadptr.c	2019-08-01 17:34:10.692659598 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-7.6/lib/freadseek.c coreutils-7.6-patched/lib/freadseek.c
+--- coreutils-7.6/lib/freadseek.c	2009-05-03 23:46:33.000000000 -0600
++++ coreutils-7.6-patched/lib/freadseek.c	2019-08-01 17:34:41.013164702 -0600
+@@ -34,7 +34,7 @@
+ freadptrinc (FILE *fp, size_t increment)
+ {
+   /* Keep this code in sync with freadptr!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-7.6/lib/fseeko.c coreutils-7.6-patched/lib/fseeko.c
+--- coreutils-7.6/lib/fseeko.c	2009-08-09 10:16:11.000000000 -0600
++++ coreutils-7.6-patched/lib/fseeko.c	2019-08-01 17:36:11.030633785 -0600
+@@ -44,7 +44,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-7.6/lib/fseterr.c coreutils-7.6-patched/lib/fseterr.c
+--- coreutils-7.6/lib/fseterr.c	2009-05-03 23:46:33.000000000 -0600
++++ coreutils-7.6-patched/lib/fseterr.c	2019-08-01 17:34:57.285433551 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-7.6/lib/stdio-impl.h coreutils-7.6-patched/lib/stdio-impl.h
+--- coreutils-7.6/lib/stdio-impl.h	2009-05-03 23:46:34.000000000 -0600
++++ coreutils-7.6-patched/lib/stdio-impl.h	2019-08-01 17:32:36.431051254 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
diff --git a/contrib/build-older-versions/coreutils-8.13-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-8.13-on-glibc-2.28.patch
new file mode 100644
index 000000000..d907900f1
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-8.13-on-glibc-2.28.patch
@@ -0,0 +1,88 @@
+diff -r -U3 coreutils-8.13/lib/freadahead.c coreutils-8.13-patched/lib/freadahead.c
+--- coreutils-8.13/lib/freadahead.c	2011-08-19 10:09:37.000000000 -0600
++++ coreutils-8.13-patched/lib/freadahead.c	2019-08-01 19:02:30.847557265 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-8.13/lib/freadptr.c coreutils-8.13-patched/lib/freadptr.c
+--- coreutils-8.13/lib/freadptr.c	2011-08-19 10:09:37.000000000 -0600
++++ coreutils-8.13-patched/lib/freadptr.c	2019-08-01 19:02:30.851557318 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-8.13/lib/freadseek.c coreutils-8.13-patched/lib/freadseek.c
+--- coreutils-8.13/lib/freadseek.c	2011-08-19 10:09:37.000000000 -0600
++++ coreutils-8.13-patched/lib/freadseek.c	2019-08-01 19:02:30.851557318 -0600
+@@ -34,7 +34,7 @@
+ freadptrinc (FILE *fp, size_t increment)
+ {
+   /* Keep this code in sync with freadptr!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-8.13/lib/fseeko.c coreutils-8.13-patched/lib/fseeko.c
+--- coreutils-8.13/lib/fseeko.c	2011-08-12 02:05:46.000000000 -0600
++++ coreutils-8.13-patched/lib/fseeko.c	2019-08-01 19:02:30.851557318 -0600
+@@ -42,7 +42,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-8.13/lib/fseterr.c coreutils-8.13-patched/lib/fseterr.c
+--- coreutils-8.13/lib/fseterr.c	2011-08-19 10:09:37.000000000 -0600
++++ coreutils-8.13-patched/lib/fseterr.c	2019-08-01 19:02:30.851557318 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-8.13/lib/stdio-impl.h coreutils-8.13-patched/lib/stdio-impl.h
+--- coreutils-8.13/lib/stdio-impl.h	2011-04-24 11:21:45.000000000 -0600
++++ coreutils-8.13-patched/lib/stdio-impl.h	2019-08-01 19:02:30.851557318 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
+diff -r -U3 coreutils-8.13/lib/stdio.in.h coreutils-8.13-patched/lib/stdio.in.h
+--- coreutils-8.13/lib/stdio.in.h	2011-06-17 02:06:20.000000000 -0600
++++ coreutils-8.13-patched/lib/stdio.in.h	2019-08-01 19:03:47.484586570 -0600
+@@ -697,7 +697,7 @@
+ /* It is very rare that the developer ever has full control of stdin,
+    so any use of gets warrants an unconditional warning.  Assume it is
+    always declared, since it is required by C89.  */
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
++/* _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); */
+ #endif
+ 
+ 
diff --git a/contrib/build-older-versions/coreutils-8.17-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-8.17-on-glibc-2.28.patch
new file mode 100644
index 000000000..79336b449
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-8.17-on-glibc-2.28.patch
@@ -0,0 +1,88 @@
+diff -r -U3 coreutils-8.17/lib/freadahead.c coreutils-8.17-patched/lib/freadahead.c
+--- coreutils-8.17/lib/freadahead.c	2012-02-11 02:43:22.000000000 -0700
++++ coreutils-8.17-patched/lib/freadahead.c	2019-08-01 19:19:11.975280339 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-8.17/lib/freadptr.c coreutils-8.17-patched/lib/freadptr.c
+--- coreutils-8.17/lib/freadptr.c	2012-02-11 02:43:22.000000000 -0700
++++ coreutils-8.17-patched/lib/freadptr.c	2019-08-01 19:19:11.975280339 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-8.17/lib/freadseek.c coreutils-8.17-patched/lib/freadseek.c
+--- coreutils-8.17/lib/freadseek.c	2012-02-11 02:43:22.000000000 -0700
++++ coreutils-8.17-patched/lib/freadseek.c	2019-08-01 19:19:11.975280339 -0600
+@@ -34,7 +34,7 @@
+ freadptrinc (FILE *fp, size_t increment)
+ {
+   /* Keep this code in sync with freadptr!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-8.17/lib/fseeko.c coreutils-8.17-patched/lib/fseeko.c
+--- coreutils-8.17/lib/fseeko.c	2012-05-04 03:04:45.000000000 -0600
++++ coreutils-8.17-patched/lib/fseeko.c	2019-08-01 19:19:11.975280339 -0600
+@@ -47,7 +47,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-8.17/lib/fseterr.c coreutils-8.17-patched/lib/fseterr.c
+--- coreutils-8.17/lib/fseterr.c	2012-02-11 02:43:22.000000000 -0700
++++ coreutils-8.17-patched/lib/fseterr.c	2019-08-01 19:19:11.975280339 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-8.17/lib/stdio-impl.h coreutils-8.17-patched/lib/stdio-impl.h
+--- coreutils-8.17/lib/stdio-impl.h	2012-02-11 02:43:22.000000000 -0700
++++ coreutils-8.17-patched/lib/stdio-impl.h	2019-08-01 19:19:11.975280339 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
+diff -r -U3 coreutils-8.17/lib/stdio.in.h coreutils-8.17-patched/lib/stdio.in.h
+--- coreutils-8.17/lib/stdio.in.h	2012-05-04 03:04:48.000000000 -0600
++++ coreutils-8.17-patched/lib/stdio.in.h	2019-08-01 19:19:37.183560130 -0600
+@@ -704,7 +704,7 @@
+    removed it.  */
+ #undef gets
+ #if HAVE_RAW_DECL_GETS
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
++/*_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");*/
+ #endif
+ 
+ 
diff --git a/contrib/build-older-versions/coreutils-8.18-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-8.18-on-glibc-2.28.patch
new file mode 100644
index 000000000..f1e19d7a0
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-8.18-on-glibc-2.28.patch
@@ -0,0 +1,88 @@
+diff -r -U3 coreutils-8.18/lib/freadahead.c coreutils-8.18-patched/lib/freadahead.c
+--- coreutils-8.18/lib/freadahead.c	2012-07-15 06:26:12.000000000 -0600
++++ coreutils-8.18-patched/lib/freadahead.c	2019-08-01 19:22:13.169332844 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-8.18/lib/freadptr.c coreutils-8.18-patched/lib/freadptr.c
+--- coreutils-8.18/lib/freadptr.c	2012-07-15 06:26:12.000000000 -0600
++++ coreutils-8.18-patched/lib/freadptr.c	2019-08-01 19:22:13.169332844 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-8.18/lib/freadseek.c coreutils-8.18-patched/lib/freadseek.c
+--- coreutils-8.18/lib/freadseek.c	2012-07-15 06:26:12.000000000 -0600
++++ coreutils-8.18-patched/lib/freadseek.c	2019-08-01 19:23:20.070111747 -0600
+@@ -36,7 +36,7 @@
+   /* Keep this code in sync with freadptr!  */
+ #if HAVE___FREADPTRINC              /* musl libc */
+   __freadptrinc (fp, increment);
+-#elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#elif defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-8.18/lib/fseeko.c coreutils-8.18-patched/lib/fseeko.c
+--- coreutils-8.18/lib/fseeko.c	2012-07-13 08:18:33.000000000 -0600
++++ coreutils-8.18-patched/lib/fseeko.c	2019-08-01 19:22:13.169332844 -0600
+@@ -47,7 +47,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-8.18/lib/fseterr.c coreutils-8.18-patched/lib/fseterr.c
+--- coreutils-8.18/lib/fseterr.c	2012-07-15 06:26:12.000000000 -0600
++++ coreutils-8.18-patched/lib/fseterr.c	2019-08-01 19:22:13.169332844 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-8.18/lib/stdio-impl.h coreutils-8.18-patched/lib/stdio-impl.h
+--- coreutils-8.18/lib/stdio-impl.h	2012-07-15 06:26:12.000000000 -0600
++++ coreutils-8.18-patched/lib/stdio-impl.h	2019-08-01 19:22:13.169332844 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
+diff -r -U3 coreutils-8.18/lib/stdio.in.h coreutils-8.18-patched/lib/stdio.in.h
+--- coreutils-8.18/lib/stdio.in.h	2012-06-12 14:43:46.000000000 -0600
++++ coreutils-8.18-patched/lib/stdio.in.h	2019-08-01 19:22:13.169332844 -0600
+@@ -704,7 +704,7 @@
+    removed it.  */
+ #undef gets
+ #if HAVE_RAW_DECL_GETS
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
++/*_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");*/
+ #endif
+ 
+ 
diff --git a/contrib/build-older-versions/coreutils-8.24-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-8.24-on-glibc-2.28.patch
new file mode 100644
index 000000000..f83e5340d
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-8.24-on-glibc-2.28.patch
@@ -0,0 +1,87 @@
+diff -r -U3 coreutils-8.24/lib/freadahead.c coreutils-8.24-patched/lib/freadahead.c
+--- coreutils-8.24/lib/freadahead.c	2015-06-15 23:00:37.000000000 -0600
++++ coreutils-8.24-patched/lib/freadahead.c	2019-08-01 19:47:31.412646436 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-8.24/lib/freadptr.c coreutils-8.24-patched/lib/freadptr.c
+--- coreutils-8.24/lib/freadptr.c	2015-06-15 23:00:37.000000000 -0600
++++ coreutils-8.24-patched/lib/freadptr.c	2019-08-01 19:47:31.416646500 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-8.24/lib/freadseek.c coreutils-8.24-patched/lib/freadseek.c
+--- coreutils-8.24/lib/freadseek.c	2015-06-15 23:00:37.000000000 -0600
++++ coreutils-8.24-patched/lib/freadseek.c	2019-08-01 19:47:31.416646500 -0600
+@@ -36,7 +36,7 @@
+   /* Keep this code in sync with freadptr!  */
+ #if HAVE___FREADPTRINC              /* musl libc */
+   __freadptrinc (fp, increment);
+-#elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#elif defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+diff -r -U3 coreutils-8.24/lib/fseeko.c coreutils-8.24-patched/lib/fseeko.c
+--- coreutils-8.24/lib/fseeko.c	2015-06-15 23:04:31.000000000 -0600
++++ coreutils-8.24-patched/lib/fseeko.c	2019-08-01 19:47:31.416646500 -0600
+@@ -47,7 +47,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-8.24/lib/fseterr.c coreutils-8.24-patched/lib/fseterr.c
+--- coreutils-8.24/lib/fseterr.c	2015-06-15 23:00:37.000000000 -0600
++++ coreutils-8.24-patched/lib/fseterr.c	2019-08-01 19:47:31.416646500 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+diff -r -U3 coreutils-8.24/lib/mountlist.c coreutils-8.24-patched/lib/mountlist.c
+--- coreutils-8.24/lib/mountlist.c	2015-07-01 09:08:30.000000000 -0600
++++ coreutils-8.24-patched/lib/mountlist.c	2019-08-01 19:49:22.354401380 -0600
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdint.h>
++#include <sys/sysmacros.h>
+ 
+ #include "xalloc.h"
+ 
+diff -r -U3 coreutils-8.24/lib/stdio-impl.h coreutils-8.24-patched/lib/stdio-impl.h
+--- coreutils-8.24/lib/stdio-impl.h	2015-06-15 23:00:37.000000000 -0600
++++ coreutils-8.24-patched/lib/stdio-impl.h	2019-08-01 19:47:31.416646500 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
diff --git a/contrib/build-older-versions/coreutils-8.4-on-glibc-2.28.patch b/contrib/build-older-versions/coreutils-8.4-on-glibc-2.28.patch
new file mode 100644
index 000000000..ce79b17a7
--- /dev/null
+++ b/contrib/build-older-versions/coreutils-8.4-on-glibc-2.28.patch
@@ -0,0 +1,88 @@
+diff -r -U3 coreutils-8.5/lib/freadahead.c coreutils-8.5-patched/lib/freadahead.c
+--- coreutils-8.5/lib/freadahead.c	2010-04-23 07:44:00.000000000 -0600
++++ coreutils-8.5-patched/lib/freadahead.c	2019-08-01 18:35:31.580843463 -0600
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return 0;
+   return (fp->_IO_read_end - fp->_IO_read_ptr)
+diff -r -U3 coreutils-8.5/lib/freadptr.c coreutils-8.5-patched/lib/freadptr.c
+--- coreutils-8.5/lib/freadptr.c	2010-04-23 07:44:00.000000000 -0600
++++ coreutils-8.5-patched/lib/freadptr.c	2019-08-01 18:35:31.580843463 -0600
+@@ -29,7 +29,7 @@
+   size_t size;
+ 
+   /* Keep this code in sync with freadahead!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_write_ptr > fp->_IO_write_base)
+     return NULL;
+   size = fp->_IO_read_end - fp->_IO_read_ptr;
+diff -r -U3 coreutils-8.5/lib/freadseek.c coreutils-8.5-patched/lib/freadseek.c
+--- coreutils-8.5/lib/freadseek.c	2010-04-23 07:44:00.000000000 -0600
++++ coreutils-8.5-patched/lib/freadseek.c	2019-08-01 18:35:31.580843463 -0600
+@@ -34,7 +34,7 @@
+ freadptrinc (FILE *fp, size_t increment)
+ {
+   /* Keep this code in sync with freadptr!  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_IO_read_ptr += increment;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_p += increment;
+diff -r -U3 coreutils-8.5/lib/fseeko.c coreutils-8.5-patched/lib/fseeko.c
+--- coreutils-8.5/lib/fseeko.c	2010-04-21 12:11:48.000000000 -0600
++++ coreutils-8.5-patched/lib/fseeko.c	2019-08-01 18:35:31.580843463 -0600
+@@ -42,7 +42,7 @@
+ #endif
+ 
+   /* These tests are based on fpurge.c.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   if (fp->_IO_read_end == fp->_IO_read_ptr
+       && fp->_IO_write_ptr == fp->_IO_write_base
+       && fp->_IO_save_base == NULL)
+diff -r -U3 coreutils-8.5/lib/fseterr.c coreutils-8.5-patched/lib/fseterr.c
+--- coreutils-8.5/lib/fseterr.c	2010-04-23 07:44:00.000000000 -0600
++++ coreutils-8.5-patched/lib/fseterr.c	2019-08-01 18:35:31.584843515 -0600
+@@ -29,7 +29,7 @@
+   /* Most systems provide FILE as a struct and the necessary bitmask in
+      <stdio.h>, because they need it for implementing getc() and putc() as
+      fast macros.  */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+   fp->_flags |= _IO_ERR_SEEN;
+ #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+   fp_->_flags |= __SERR;
+diff -r -U3 coreutils-8.5/lib/stdio-impl.h coreutils-8.5-patched/lib/stdio-impl.h
+--- coreutils-8.5/lib/stdio-impl.h	2010-04-23 07:44:01.000000000 -0600
++++ coreutils-8.5-patched/lib/stdio-impl.h	2019-08-01 18:35:31.584843515 -0600
+@@ -18,6 +18,12 @@
+    the same implementation of stdio extension API, except that some fields
+    have different naming conventions, or their access requires some casts.  */
+ 
++/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
++ *    problem by defining it ourselves.  FIXME: Do not rely on glibc
++ *       internals.  */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+ 
+ /* BSD stdio derived implementations.  */
+ 
+diff -r -U3 coreutils-8.5/lib/stdio.in.h coreutils-8.5-patched/lib/stdio.in.h
+--- coreutils-8.5/lib/stdio.in.h	2010-04-21 12:11:57.000000000 -0600
++++ coreutils-8.5-patched/lib/stdio.in.h	2019-08-01 18:26:34.113941755 -0600
+@@ -139,7 +139,7 @@
+    so any use of gets warrants an unconditional warning.  Assume it is
+    always declared, since it is required by C89.  */
+ #undef gets
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
++/*_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");*/
+ 
+ #if @GNULIB_FOPEN@
+ # if @REPLACE_FOPEN@
-- 
2.20.1

