diff --git a/.gitignore b/.gitignore
index b8a1c39..46d0f92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,2 @@
-/coreutils-8.10.tar.xz
-/coreutils-8.11.tar.xz
-/coreutils-8.12.tar.xz
-/coreutils-8.13.tar.xz
-/coreutils-8.14.tar.xz
-/coreutils-8.15.tar.xz
+/coreutils-[0-9.]*.tar.xz
+/coreutils-[0-9.]*.tar.xz.sig
diff --git a/STAGE1-coreutils b/STAGE1-coreutils
new file mode 100644
index 0000000..bfe73b5
--- /dev/null
+++ b/STAGE1-coreutils
@@ -0,0 +1,7 @@
+srpm coreutils
+mcd $BUILDDIR/$1
+(cd $SRC/${1}-*/ ; autoreconf -vif)
+$SRC/${1}-*/configure $TCONFIGARGS --disable-pam
+notparallel
+make $J man1_MANS= V=1
+make $J man1_MANS= install DESTDIR=${ROOTFS}
diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch
deleted file mode 100644
index 25dec6c..0000000
--- a/coreutils-4.5.3-langinfo.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- coreutils-5.92/src/date.c.langinfo 2005-09-16 09:06:57.000000000 +0100
-+++ coreutils-5.92/src/date.c 2005-10-24 18:09:16.000000000 +0100
-@@ -451,14 +451,7 @@
- format = DATE_FMT_LANGINFO ();
- if (! *format)
- {
-- /* Do not wrap the following literal format string with _(...).
-- For example, suppose LC_ALL is unset, LC_TIME=POSIX,
-- and LANG="ko_KR". In that case, POSIX says that LC_TIME
-- determines the format and contents of date and time strings
-- written by date, which means "date" must generate output
-- using the POSIX locale; but adding _() would cause "date"
-- to use a Korean translation of the format. */
-- format = "%a %b %e %H:%M:%S %Z %Y";
-+ format = dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME);
- }
- }
-
diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch
deleted file mode 100644
index 1e3be91..0000000
--- a/coreutils-6.10-configuration.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-tests/gnulib.mk
---- coreutils-8.13-orig/gnulib-tests/gnulib.mk 2011-09-08 17:09:08.000000000 +0200
-+++ coreutils-8.13/gnulib-tests/gnulib.mk 2011-09-09 10:14:18.714689661 +0200
-@@ -235,9 +235,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch
-
- ## begin gnulib module cloexec-tests
-
--TESTS += test-cloexec
--check_PROGRAMS += test-cloexec
--EXTRA_DIST += test-cloexec.c macros.h
-+#TESTS += test-cloexec
-+#check_PROGRAMS += test-cloexec
-+#EXTRA_DIST += test-cloexec.c macros.h
-
- ## end gnulib module cloexec-tests
-
-@@ -321,9 +321,9 @@ EXTRA_DIST += test-dirname.c
-
- ## begin gnulib module dup2-tests
-
--TESTS += test-dup2
--check_PROGRAMS += test-dup2
--EXTRA_DIST += test-dup2.c signature.h macros.h
-+#TESTS += test-dup2
-+#check_PROGRAMS += test-dup2
-+#EXTRA_DIST += test-dup2.c signature.h macros.h
-
- ## end gnulib module dup2-tests
-
-@@ -373,10 +373,10 @@ EXTRA_DIST += test-fadvise.c
-
- ## begin gnulib module fchdir-tests
-
--TESTS += test-fchdir
--check_PROGRAMS += test-fchdir
--test_fchdir_LDADD = $(LDADD) $(LIBINTL)
--EXTRA_DIST += test-fchdir.c signature.h macros.h
-+#TESTS += test-fchdir
-+#check_PROGRAMS += test-fchdir
-+#test_fchdir_LDADD = $(LDADD) $(LIBINTL)
-+#EXTRA_DIST += test-fchdir.c signature.h macros.h
-
- ## end gnulib module fchdir-tests
-
-@@ -918,10 +918,10 @@ EXTRA_DIST += test-link.h test-link.c si
-
- ## begin gnulib module linkat-tests
-
--TESTS += test-linkat
--check_PROGRAMS += test-linkat
--test_linkat_LDADD = $(LDADD) @LIBINTL@
--EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h
-+#TESTS += test-linkat
-+#check_PROGRAMS += test-linkat
-+#test_linkat_LDADD = $(LDADD) @LIBINTL@
-+#EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h
-
- ## end gnulib module linkat-tests
-
-@@ -1284,9 +1284,9 @@ EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h
-
- ## begin gnulib module memrchr-tests
-
--TESTS += test-memrchr
--check_PROGRAMS += test-memrchr
--EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h
-+#TESTS += test-memrchr
-+#check_PROGRAMS += test-memrchr
-+#EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h
-
- ## end gnulib module memrchr-tests
-
-@@ -1824,9 +1824,9 @@
-
- ## begin gnulib module stdalign-tests
-
--TESTS += test-stdalign
--check_PROGRAMS += test-stdalign
--EXTRA_DIST += test-stdalign.c macros.h
-+#TESTS += test-stdalign
-+#check_PROGRAMS += test-stdalign
-+#EXTRA_DIST += test-stdalign.c macros.h
-
- ## end gnulib module stdalign-tests
-
-@@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m
-
- ## begin gnulib module unistd-safer-tests
-
--TESTS += test-dup-safer
--check_PROGRAMS += test-dup-safer
--EXTRA_DIST += test-dup-safer.c macros.h
-+#TESTS += test-dup-safer
-+#check_PROGRAMS += test-dup-safer
-+#EXTRA_DIST += test-dup-safer.c macros.h
-
- ## end gnulib module unistd-safer-tests
-
-@@ -1997,10 +1997,10 @@ EXTRA_DIST += test-usleep.c signature.h
-
- ## begin gnulib module utimens-tests
-
--TESTS += test-utimens
--check_PROGRAMS += test-utimens
--test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
--EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h
-+#TESTS += test-utimens
-+#check_PROGRAMS += test-utimens
-+#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-+#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h
-
- ## end gnulib module utimens-tests
-
-diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.am
---- coreutils-8.13-orig/tests/Makefile.am 2011-09-02 14:08:40.000000000 +0200
-+++ coreutils-8.13/tests/Makefile.am 2011-09-09 10:12:56.364814725 +0200
-@@ -86,7 +86,6 @@ TESTS = \
- rm/ext3-perf \
- rm/cycle \
- cp/link-heap \
-- tail-2/inotify-hash-abuse \
- tail-2/inotify-hash-abuse2 \
- tail-2/F-vs-missing \
- tail-2/F-vs-rename \
-diff -urNp coreutils-8.13-orig/tests/touch/no-dereference coreutils-8.13/tests/touch/no-dereference
---- coreutils-8.13-orig/tests/touch/no-dereference 2011-08-08 09:42:16.000000000 +0200
-+++ coreutils-8.13/tests/touch/no-dereference 2011-09-09 10:15:21.167060702 +0200
-@@ -42,6 +42,8 @@ test -f nowhere && fail=1
- grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null ||
- grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null ||
- skip_ 'this system lacks the utimensat function'
-+grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null ||
-+ skip_ 'rest of the test disabled due to koji lack of utimensat function'
-
- # Changing time of dangling symlink is okay.
- # Skip the test if this fails, but the error text corresponds to
diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch
deleted file mode 100644
index 2c663f9..0000000
--- a/coreutils-6.10-manpages.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c
---- coreutils-6.12-orig/src/md5sum.c 2008-05-26 08:40:33.000000000 +0200
-+++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200
-@@ -175,6 +175,9 @@ With no FILE, or when FILE is -, read st
- fputs (_("\
- -t, --text read in text mode (default)\n\
- "), stdout);
-+ fputs (_("\
-+ Note: There is no difference between binary and text mode option on GNU system.\n\
-+"), stdout);
- fputs (_("\
- \n\
- The following three options are useful only when verifying checksums:\n\
diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch
deleted file mode 100644
index fe83798..0000000
--- a/coreutils-7.4-sttytcsadrain.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -urNp coreutils-8.13-orig/src/stty.c coreutils-8.13/src/stty.c
---- coreutils-8.13-orig/src/stty.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/stty.c 2011-09-09 10:18:57.526687209 +0200
-@@ -1005,7 +1005,7 @@ main (int argc, char **argv)
- spurious difference in an uninitialized portion of the structure. */
- struct termios new_mode = { 0, };
-
-- if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode))
-+ if (tcsetattr (STDIN_FILENO, TCSANOW, &mode))
- error (EXIT_FAILURE, errno, "%s", device_name);
-
- /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
diff --git a/coreutils-8.15-cp-attribute-truncate.patch b/coreutils-8.15-cp-attribute-truncate.patch
deleted file mode 100644
index b7d27ef..0000000
--- a/coreutils-8.15-cp-attribute-truncate.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 3d53e7fe1c31aa440cc9708c7c51db6b78c07653 Mon Sep 17 00:00:00 2001
-From: =?utf8?q?P=C3=A1draig=20Brady?=
-Date: Thu, 12 Apr 2012 12:47:30 +0100
-Subject: [PATCH 1/1] cp: change --attributes-only to not truncate existing files
-
-* src/copy.c (copy_reg): Don't truncate an existing file,
-to support copying attributes between existing files.
-The original use case only considered creating new files,
-and it would be a very unusual use case to be relying
-on the truncating behavior.
-* doc/coreutils.texi (cp invocation): Mention the non
-truncating behavior.
-* tests/cp/attr-existing: A new test to ensure O_TRUNC skipped.
-* tests/Makefile.am: Reference the new test.
----
- doc/coreutils.texi | 6 +++---
- src/copy.c | 4 +++-
- tests/Makefile.am | 1 +
- tests/cp/attr-existing | 29 +++++++++++++++++++++++++++++
- 4 files changed, 36 insertions(+), 4 deletions(-)
- create mode 100755 tests/cp/attr-existing
-
-diff --git a/doc/coreutils.texi b/doc/coreutils.texi
-index 510abb9..1fbf051 100644
---- a/doc/coreutils.texi
-+++ b/doc/coreutils.texi
-@@ -7649,9 +7649,9 @@ Equivalent to @option{-dR --preserve=all} with the reduced diagnostics.
-
- @itemx --attributes-only
- @opindex --attributes-only
--Preserve the specified attributes of the original files in the copy,
--but do not copy any data. See the @option{--preserve} option for
--controlling which attributes to copy.
-+Copy only the specified attributes of the source file to the destination.
-+If the destination already exists, do not alter its contents.
-+See the @option{--preserve} option for controlling which attributes to copy.
-
- @item -b
- @itemx @w{@kbd{--backup}[=@var{method}]}
-diff --git a/src/copy.c b/src/copy.c
-index f63a726..414fbe0 100644
---- a/src/copy.c
-+++ b/src/copy.c
-@@ -826,7 +826,9 @@ copy_reg (char const *src_name, char const *dst_name,
- by the specs for both cp and mv. */
- if (! *new_dst)
- {
-- dest_desc = open (dst_name, O_WRONLY | O_TRUNC | O_BINARY);
-+ int open_flags =
-+ O_WRONLY | O_BINARY | (x->data_copy_required ? O_TRUNC : 0);
-+ dest_desc = open (dst_name, open_flags);
- dest_errno = errno;
-
- /* When using cp --preserve=context to copy to an existing destination,
-diff --git a/tests/Makefile.am b/tests/Makefile.am
-index 011051a..4d73a92 100644
---- a/tests/Makefile.am
-+++ b/tests/Makefile.am
-@@ -320,6 +320,7 @@ TESTS = \
- chown/separator \
- cp/abuse \
- cp/acl \
-+ cp/attr-existing \
- cp/backup-1 \
- cp/backup-dir \
- cp/backup-is-src \
-diff --git a/tests/cp/attr-existing b/tests/cp/attr-existing
-new file mode 100755
-index 0000000..9cf0ffc
---- /dev/null
-+++ b/tests/cp/attr-existing
-@@ -0,0 +1,29 @@
-+#!/bin/sh
-+# Make sure cp --attributes-only doesn't truncate existing data
-+
-+# Copyright 2012 Free Software Foundation, Inc.
-+
-+# This program is free software: you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation, either version 3 of the License, or
-+# (at your option) any later version.
-+
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see .
-+
-+. "${srcdir=.}/init.sh"; path_prepend_ ../src
-+print_ver_ cp
-+
-+printf '1' > file1
-+printf '2' > file2
-+printf '2' > file2.exp
-+
-+cp --attributes-only file1 file2 || fail=1
-+cmp file2 file2.exp || fail=1
-+
-+Exit $fail
---
-1.7.2.5
diff --git a/coreutils-8.15-du-x-nondir.patch b/coreutils-8.15-du-x-nondir.patch
deleted file mode 100644
index 02d120e..0000000
--- a/coreutils-8.15-du-x-nondir.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff --git a/src/du.c b/src/du.c
-index e4e36df..41c9535 100644
---- a/src/du.c
-+++ b/src/du.c
-@@ -443,7 +443,14 @@ process_file (FTS *fts, FTSENT *ent)
- return false;
- }
-
-- if (fts->fts_options & FTS_XDEV && fts->fts_dev != sb->st_dev)
-+ /* The --one-file-system (-x) option cannot exclude anything
-+ specified on the command-line. By definition, it can exclude
-+ a file or directory only when its device number is different
-+ from that of its just-processed parent directory, and du does
-+ not process the parent of a command-line argument. */
-+ if (fts->fts_options & FTS_XDEV
-+ && FTS_ROOTLEVEL < ent->fts_level
-+ && fts->fts_dev != sb->st_dev)
- excluded = true;
- }
-
-diff --git a/tests/du/one-file-system b/tests/du/one-file-system
-index f0d264a..110080f 100755
---- a/tests/du/one-file-system
-+++ b/tests/du/one-file-system
-@@ -43,7 +43,15 @@ compare exp out || fail=1
- du -xL d > u || fail=1
- sed 's/^[0-9][0-9]* //' u > out1
- echo d > exp1 || fail=1
--
- compare exp1 out1 || fail=1
-
-+# With coreutils-8.15, "du -xs FILE" would print no output.
-+touch f
-+for opt in -x -xs; do
-+ du $opt f > u || fail=1
-+ sed 's/^[0-9][0-9]* //' u > out2
-+ echo f > exp2 || fail=1
-+ compare exp2 out2 || fail=1
-+done
-+
- Exit $fail
---
-cgit v0.9.0.2
diff --git a/coreutils-8.17-cp-freememoryread.patch b/coreutils-8.17-cp-freememoryread.patch
deleted file mode 100644
index be4a429..0000000
--- a/coreutils-8.17-cp-freememoryread.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff -urNp coreutils-8.17-orig/src/extent-scan.c coreutils-8.17/src/extent-scan.c
---- coreutils-8.17-orig/src/extent-scan.c 2012-05-02 10:31:47.000000000 +0200
-+++ coreutils-8.17/src/extent-scan.c 2012-11-05 12:05:36.732370966 +0100
-@@ -89,7 +89,7 @@ extern bool
- extent_scan_read (struct extent_scan *scan)
- {
- unsigned int si = 0;
-- struct extent_info *last_ei IF_LINT ( = scan->ext_info);
-+ struct extent_info *last_ei = scan->ext_info;
-
- while (true)
- {
-@@ -127,8 +127,14 @@ extent_scan_read (struct extent_scan *sc
-
- assert (scan->ei_count <= SIZE_MAX - fiemap->fm_mapped_extents);
- scan->ei_count += fiemap->fm_mapped_extents;
-- scan->ext_info = xnrealloc (scan->ext_info, scan->ei_count,
-- sizeof (struct extent_info));
-+ {
-+ /* last_ei points into a buffer that may be freed via xnrealloc.
-+ Record its offset and adjust after allocation. */
-+ size_t prev_idx = last_ei - scan->ext_info;
-+ scan->ext_info = xnrealloc (scan->ext_info, scan->ei_count,
-+ sizeof (struct extent_info));
-+ last_ei = scan->ext_info + prev_idx;
-+ }
-
- unsigned int i = 0;
- for (i = 0; i < fiemap->fm_mapped_extents; i++)
diff --git a/coreutils-8.17-df-duplicates.patch b/coreutils-8.17-df-duplicates.patch
deleted file mode 100644
index 06983ad..0000000
--- a/coreutils-8.17-df-duplicates.patch
+++ /dev/null
@@ -1,264 +0,0 @@
-diff -urNp coreutils-8.17-orig/doc/coreutils.texi coreutils-8.17/doc/coreutils.texi
---- coreutils-8.17-orig/doc/coreutils.texi 2012-05-10 09:14:30.000000000 +0200
-+++ coreutils-8.17/doc/coreutils.texi 2012-12-11 11:30:38.730760947 +0100
-@@ -10561,6 +10561,14 @@ Normally the disk space is printed in un
- 1024 bytes, but this can be overridden (@pxref{Block size}).
- Non-integer quantities are rounded up to the next higher unit.
-
-+For bind mounts and without arguments, @command{df} only outputs the statistics
-+for the first occurence of that device in the list of file systems (@var{mtab}),
-+i.e., it hides duplicate entries, unless the @option{-a} option is specified.
-+
-+By default, @command{df} omits the early-boot pseudo file system type
-+@samp{rootfs}, unless the @option{-a} option is specified or that file system
-+type is explicitly to be included by using the @option{-t} option.
-+
- @cindex disk device file
- @cindex device file, disk
- If an argument @var{file} is a disk device file containing a mounted
-diff -urNp coreutils-8.17-orig/src/df.c coreutils-8.17/src/df.c
---- coreutils-8.17-orig/src/df.c 2012-05-01 22:55:08.000000000 +0200
-+++ coreutils-8.17/src/df.c 2012-12-11 11:30:38.803069545 +0100
-@@ -46,6 +46,17 @@
- /* If true, show inode information. */
- static bool inode_format;
-
-+/* Filled with device numbers of examined file systems to avoid
-+ duplicities in output. */
-+struct devlist
-+{
-+ dev_t dev_num;
-+ struct devlist *next;
-+};
-+
-+/* Store of already-processed device numbers. */
-+static struct devlist *devlist_head;
-+
- /* If true, show even file systems with zero size or
- uninteresting types. */
- static bool show_all_fs;
-@@ -57,6 +68,12 @@ static bool show_local_fs;
- command line argument -- even if it's a dummy (automounter) entry. */
- static bool show_listed_fs;
-
-+/* If true, include rootfs in the output. */
-+static bool show_rootfs;
-+
-+/* The literal name of the initial root file system. */
-+static char const *ROOTFS = "rootfs";
-+
- /* Human-readable options for output. */
- static int human_output_opts;
-
-@@ -350,6 +367,29 @@ excluded_fstype (const char *fstype)
- return false;
- }
-
-+/* Check if the device was already examined. */
-+
-+static bool
-+dev_examined (char const *mount_dir, char const *devname)
-+{
-+ struct stat buf;
-+ if (-1 == stat (mount_dir, &buf))
-+ return false;
-+
-+ struct devlist *devlist = devlist_head;
-+ for ( ; devlist; devlist = devlist->next)
-+ if (devlist->dev_num == buf.st_dev)
-+ return true;
-+
-+ /* Add the device number to the global list devlist. */
-+ devlist = xmalloc (sizeof *devlist);
-+ devlist->dev_num = buf.st_dev;
-+ devlist->next = devlist_head;
-+ devlist_head = devlist;
-+
-+ return false;
-+}
-+
- /* Return true if N is a known integer value. On many file systems,
- UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1
- represents unknown. Use a rule that works on AIX file systems, and
-@@ -474,6 +514,15 @@ get_dev (char const *disk, char const *m
- if (!selected_fstype (fstype) || excluded_fstype (fstype))
- return;
-
-+ if (process_all && !show_all_fs && !show_listed_fs)
-+ {
-+ /* No arguments nor "df -a", then check if df has to ... */
-+ if (!show_rootfs && STREQ (disk, ROOTFS))
-+ return; /* ... skip rootfs: (unless -trootfs is given. */
-+ if (dev_examined (mount_point, disk))
-+ return; /* ... skip duplicate entries (bind mounts). */
-+ }
-+
- /* If MOUNT_POINT is NULL, then the file system is not mounted, and this
- program reports on the file system that the special file is on.
- It would be better to report on the unmounted file system,
-@@ -972,6 +1021,7 @@ main (int argc, char **argv)
- /* Accept -F as a synonym for -t for compatibility with Solaris. */
- case 't':
- add_fs_type (optarg);
-+ show_rootfs = selected_fstype (ROOTFS);
- break;
-
- case 'v': /* For SysV compatibility. */
-@@ -1105,6 +1155,14 @@ main (int argc, char **argv)
-
- if (! file_systems_processed)
- error (EXIT_FAILURE, 0, _("no file systems processed"));
-+ IF_LINT (
-+ while (devlist_head)
-+ {
-+ struct devlist *devlist = devlist_head->next;
-+ free (devlist_head);
-+ devlist_head = devlist;
-+ }
-+ );
-
- exit (exit_status);
- }
-diff -urNp coreutils-8.17-orig/tests/df/skip-duplicates coreutils-8.17/tests/df/skip-duplicates
---- coreutils-8.17-orig/tests/df/skip-duplicates 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.17/tests/df/skip-duplicates 2012-12-11 11:30:38.820762450 +0100
-@@ -0,0 +1,77 @@
-+#!/bin/sh
-+# Test df's behavior when the mount list contains duplicate entries.
-+# This test is skipped on systems that lack LD_PRELOAD support; that's fine.
-+
-+# Copyright (C) 2012 Free Software Foundation, Inc.
-+
-+# This program is free software: you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation, either version 3 of the License, or
-+# (at your option) any later version.
-+
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see .
-+
-+. "${srcdir=.}/init.sh"; path_prepend_ ../src
-+print_ver_ df
-+
-+df || skip_ "df fails"
-+
-+# Simulate an mtab file with two entries of the same device number.
-+cat > k.c <<'EOF' || framework_failure_
-+#include
-+#include
-+
-+struct mntent *getmntent (FILE *fp)
-+{
-+ /* Prove that LD_PRELOAD works. */
-+ static int done = 0;
-+ if (!done)
-+ {
-+ fclose (fopen ("x", "w"));
-+ ++done;
-+ }
-+
-+ static struct mntent mntent;
-+
-+ while (done++ < 3)
-+ {
-+ mntent.mnt_fsname = "fsname";
-+ mntent.mnt_dir = "/";
-+ mntent.mnt_type = "-";
-+
-+ return &mntent;
-+ }
-+ return NULL;
-+}
-+EOF
-+
-+# Then compile/link it:
-+gcc --std=gnu99 -shared -fPIC -ldl -O2 k.c -o k.so \
-+ || skip_ "getmntent hack does not work on this platform"
-+
-+# Test if LD_PRELOAD works:
-+LD_PRELOAD=./k.so df
-+test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?"
-+
-+# The fake mtab file should only contain 2 entries, both
-+# having the same device number; thus the output should
-+# consist of a header and one entry.
-+LD_PRELOAD=./k.so df >out || fail=1
-+test $(wc -l out || fail=1
-+test $(wc -l out || fail=1
-+test $(wc -l .
-+
-+. "${srcdir=.}/init.sh"; path_prepend_ ../src
-+print_ver_ df
-+
-+df || skip_ "df fails"
-+
-+# Verify that rootfs is in mtab (and shown when the -a option is specified).
-+df -a >out || fail=1
-+grep '^rootfs' out || skip_ "no rootfs in mtab"
-+
-+# Ensure that rootfs is supressed when no options is specified.
-+df >out || fail=1
-+grep '^rootfs' out && { fail=1; cat out; }
-+
-+# Ensure that the rootfs is shown when explicitly specifying "-t rootfs".
-+df -t rootfs >out || fail=1
-+grep '^rootfs' out || { fail=1; cat out; }
-+
-+# Ensure that the rootfs is shown when explicitly specifying "-t rootfs",
-+# even when the -a option is specified.
-+df -t rootfs -a >out || fail=1
-+grep '^rootfs' out || { fail=1; cat out; }
-+
-+# Ensure that the rootfs is omitted in all_fs mode when it is explicitly
-+# black-listed.
-+df -a -x rootfs >out || fail=1
-+grep '^rootfs' out && { fail=1; cat out; }
-+
-+Exit $fail
-diff -urNp coreutils-8.17-orig/tests/Makefile.am coreutils-8.17/tests/Makefile.am
---- coreutils-8.17-orig/tests/Makefile.am 2012-05-10 16:36:42.000000000 +0200
-+++ coreutils-8.17/tests/Makefile.am 2012-12-11 11:32:23.021760237 +0100
-@@ -373,6 +373,8 @@ TESTS = \
- cp/symlink-slash \
- cp/thru-dangling \
- df/unreadable \
-+ df/skip-duplicates \
-+ df/skip-rootfs \
- dd/direct \
- dd/misc \
- dd/nocache \
diff --git a/coreutils-8.17-sort-uniq-fmr.patch b/coreutils-8.17-sort-uniq-fmr.patch
deleted file mode 100644
index 91873c7..0000000
--- a/coreutils-8.17-sort-uniq-fmr.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c
---- coreutils-8.17-orig/src/sort.c 2012-08-20 13:15:39.703470009 +0200
-+++ coreutils-8.17/src/sort.c 2012-08-20 13:29:47.177468563 +0200
-@@ -292,6 +292,9 @@ struct merge_node_queue
- when popping. */
- };
-
-+/* Used to implement --unique (-u). */
-+static struct line saved_line;
-+
- /* FIXME: None of these tables work with multibyte character sets.
- Also, there are many other bugs when handling multibyte characters.
- One way to fix this is to rewrite `sort' to use wide characters
-@@ -3943,13 +3946,12 @@ queue_pop (struct merge_node_queue *queu
- static void
- write_unique (struct line const *line, FILE *tfp, char const *temp_output)
- {
-- static struct line saved;
-
- if (unique)
- {
-- if (saved.text && ! compare (line, &saved))
-+ if (saved_line.text && ! compare (line, &saved_line))
- return;
-- saved = *line;
-+ saved_line = *line;
- }
-
- write_line (line, tfp, temp_output);
-@@ -4451,6 +4453,7 @@ sort (char *const *files, size_t nfiles,
- break;
- }
-
-+ saved_line.text = NULL;
- line = buffer_linelim (&buf);
- if (buf.eof && !nfiles && !ntemps && !buf.left)
- {
-diff -urNp coreutils-8.17-orig/tests/misc/sort coreutils-8.17/tests/misc/sort
---- coreutils-8.17-orig/tests/misc/sort 2012-02-03 10:22:06.000000000 +0100
-+++ coreutils-8.17/tests/misc/sort 2012-08-20 13:31:38.685565488 +0200
-@@ -226,6 +226,10 @@ my @Tests =
- ["15c", '-i -u', {IN=>"a\1\na\n"}, {OUT=>"a\1\n"}],
- ["15d", '-i -u', {IN=>"\1a\na\n"}, {OUT=>"\1a\n"}],
- ["15e", '-i -u', {IN=>"a\n\1\1\1\1\1a\1\1\1\1\n"}, {OUT=>"a\n"}],
-+# Before 8.19, this would trigger a free-memory read.
-+["unique-free-mem-read", '-u --p=1 -S32b',
-+ {IN=>"a\n"."b"x900 ."\n"},
-+ {OUT=>"a\n"."b"x900 ."\n"}],
-
- # From Erick Branderhorst -- fixed around 1.19e
- ["16a", '-f',
diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch
deleted file mode 100644
index 4c83df8..0000000
--- a/coreutils-8.2-uname-processortype.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c
---- coreutils-8.2-orig/src/uname.c 2009-09-23 10:25:44.000000000 +0200
-+++ coreutils-8.2/src/uname.c 2009-12-19 09:09:11.663607110 +0100
-@@ -301,7 +301,7 @@ main (int argc, char **argv)
-
- if (toprint & PRINT_PROCESSOR)
- {
-- char const *element = unknown;
-+ char *element = unknown;
- #if HAVE_SYSINFO && defined SI_ARCHITECTURE
- {
- static char processor[257];
-@@ -308,6 +308,12 @@ main (int argc, char **argv)
- if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
- element = processor;
- }
-+#else
-+ {
-+ static struct utsname u;
-+ uname(&u);
-+ element = u.machine;
-+ }
- #endif
- #ifdef UNAME_PROCESSOR
- if (element == unknown)
-@@ -351,7 +357,7 @@ main (int argc, char **argv)
-
- if (toprint & PRINT_HARDWARE_PLATFORM)
- {
-- char const *element = unknown;
-+ char *element = unknown;
- #if HAVE_SYSINFO && defined SI_PLATFORM
- {
- static char hardware_platform[257];
-@@ -353,6 +359,14 @@ main (int argc, char **argv)
- hardware_platform, sizeof hardware_platform))
- element = hardware_platform;
- }
-+#else
-+ {
-+ static struct utsname u;
-+ uname(&u);
-+ element = u.machine;
-+ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6')
-+ element[1]='3';
-+ }
- #endif
- #ifdef UNAME_HARDWARE_PLATFORM
- if (element == unknown)
diff --git a/coreutils-8.26-selinuxenable.patch b/coreutils-8.26-selinuxenable.patch
new file mode 100644
index 0000000..d9b625a
--- /dev/null
+++ b/coreutils-8.26-selinuxenable.patch
@@ -0,0 +1,26 @@
+From 6880c3dc9098b3337612850d1500b474aeb944ca Mon Sep 17 00:00:00 2001
+From: Kamil Dudka
+Date: Tue, 29 Aug 2017 17:33:51 +0200
+Subject: [PATCH] require_selinux_(): use selinuxenabled(8) if available
+
+---
+ init.cfg | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/init.cfg b/init.cfg
+index af6b581..f887b3a 100644
+--- a/init.cfg
++++ b/init.cfg
+@@ -114,6 +114,9 @@ require_selinux_()
+ grep 'selinuxfs$' /proc/filesystems > /dev/null \
+ || skip_ "this system lacks SELinux support"
+
++ # use the 'selinuxenabled' utility if available
++ selinuxenabled; [ $? = 1 ] && skip_ "SELinux is disabled"
++
+ # Independent of whether SELinux is enabled system-wide,
+ # the current file system may lack SELinux support.
+ # Also the current build may have SELinux support disabled.
+--
+2.9.5
+
diff --git a/coreutils-8.26-test-lock.patch b/coreutils-8.26-test-lock.patch
new file mode 100644
index 0000000..d66928c
--- /dev/null
+++ b/coreutils-8.26-test-lock.patch
@@ -0,0 +1,29 @@
+From 0d04ee8ddedb2bf33d64f148f246a3b7ec4fef21 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka
+Date: Mon, 23 Jan 2017 12:35:41 +0100
+Subject: [PATCH] test-lock: disable the rwlock test
+
+It hangs indefinitely if the system rwlock implementation does not
+prevent writer starvation (and glibc does not implement it).
+
+Bug: http://www.mail-archive.com/bug-gnulib@gnu.org/msg33017.html
+---
+ gnulib-tests/test-lock.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gnulib-tests/test-lock.c b/gnulib-tests/test-lock.c
+index aa6de27..5af0a6c 100644
+--- a/gnulib-tests/test-lock.c
++++ b/gnulib-tests/test-lock.c
+@@ -42,7 +42,7 @@
+ Uncomment some of these, to verify that all tests crash if no locking
+ is enabled. */
+ #define DO_TEST_LOCK 1
+-#define DO_TEST_RWLOCK 1
++#define DO_TEST_RWLOCK 0
+ #define DO_TEST_RECURSIVE_LOCK 1
+ #define DO_TEST_ONCE 1
+
+--
+2.7.4
+
diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch
new file mode 100644
index 0000000..37ce3e6
--- /dev/null
+++ b/coreutils-8.32-DIR_COLORS.patch
@@ -0,0 +1,100 @@
+From bca11e30e8a6281a8cbddc9fb196dd86ab09c955 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka
+Date: Fri, 17 Jun 2016 16:58:18 +0200
+Subject: [PATCH] downstream changes to default DIR_COLORS
+
+---
+ DIR_COLORS | 9 ++++++++-
+ DIR_COLORS.lightbgcolor | 21 +++++++++++++++------
+ 2 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/DIR_COLORS b/DIR_COLORS
+index 540f6cd..b4785b6 100644
+--- a/DIR_COLORS
++++ b/DIR_COLORS
+@@ -1,3 +1,7 @@
++# This file goes in the /etc directory, and must be world readable.
++# You can override the system defaults by making a copy of this file
++# as ~/.dir_colors
++
+ # Configuration file for dircolors, a utility to help you set the
+ # LS_COLORS environment variable used by GNU ls with the --color option.
+
+@@ -11,6 +15,9 @@
+
+ # Global config options can be specified before TERM or COLORTERM entries
+
++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to
++# disable colorization. See https://bugzilla.redhat.com/1349579 for details.
++
+ # ===================================================================
+ # Terminal filters
+ # ===================================================================
+@@ -70,7 +77,7 @@ DOOR 01;35 # door
+ BLK 40;33;01 # block device driver
+ CHR 40;33;01 # character device driver
+ ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ...
+-MISSING 00 # ... and the files they point to
++MISSING 01;37;41 # ... and the files they point to
+ SETUID 37;41 # regular file that is setuid (u+s)
+ SETGID 30;43 # regular file that is setgid (g+s)
+ CAPABILITY 00 # regular file with capability (very expensive to lookup)
+diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor
+index e3b0ec3..39a0a4c 100644
+--- a/DIR_COLORS.lightbgcolor
++++ b/DIR_COLORS.lightbgcolor
+@@ -1,3 +1,9 @@
++# Configuration file for the color ls utility - modified for lighter backgrounds
++
++# This file goes in the /etc directory, and must be world readable.
++# You can override the system defaults by making a copy of this file
++# as ~/.dir_colors
++
+ # Configuration file for dircolors, a utility to help you set the
+ # LS_COLORS environment variable used by GNU ls with the --color option.
+
+@@ -11,6 +17,9 @@
+
+ # Global config options can be specified before TERM or COLORTERM entries
+
++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to
++# disable colorization. See https://bugzilla.redhat.com/1349579 for details.
++
+ # ===================================================================
+ # Terminal filters
+ # ===================================================================
+@@ -60,17 +69,17 @@ TERM xterm*
+ #NORMAL 00 # no color code at all
+ #FILE 00 # regular file: use no color at all
+ RESET 0 # reset to "normal" color
+-DIR 01;34 # directory
+-LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
++DIR 00;34 # directory
++LINK 00;36 # symbolic link. (If you set this to 'target' instead of a
+ # numerical value, the color is as for the file pointed to.)
+ MULTIHARDLINK 00 # regular file with more than one link
+ FIFO 40;33 # pipe
+-SOCK 01;35 # socket
+-DOOR 01;35 # door
++SOCK 00;35 # socket
++DOOR 00;35 # door
+ BLK 40;33;01 # block device driver
+ CHR 40;33;01 # character device driver
+ ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ...
+-MISSING 00 # ... and the files they point to
++MISSING 01;37;41 # ... and the files they point to
+ SETUID 37;41 # regular file that is setuid (u+s)
+ SETGID 30;43 # regular file that is setgid (g+s)
+ CAPABILITY 00 # regular file with capability (very expensive to lookup)
+@@ -79,7 +88,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
+ STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
+
+ # This is for regular files with execute permission:
+-EXEC 01;32
++EXEC 00;32
+
+ # ===================================================================
+ # File extension attributes
+--
+2.49.0
+
diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch
deleted file mode 100644
index 3576ec6..0000000
--- a/coreutils-8.4-mkdir-modenote.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi
---- coreutils-8.4-orig/doc/coreutils.texi 2011-01-07 15:01:18.575654333 +0100
-+++ coreutils-8.4/doc/coreutils.texi 2011-01-07 15:05:38.791655243 +0100
-@@ -9058,6 +9058,8 @@ incorrect. @xref{Directory Setuid and S
- set-user-ID and set-group-ID bits of directories are inherited unless
- overridden in this way.
-
-+Note: The @option{--mode},@option{-m} option only applies to the right-most directories listed on the command line. When combined with @option{--parents}, @option{-p} option, any parent directories are created with @samp{u+wx} modified by umask.
-+
- @item -p
- @itemx --parents
- @opindex -p
diff --git a/coreutils-8.4-su-pie.patch b/coreutils-8.4-su-pie.patch
deleted file mode 100644
index b3fcaaf..0000000
--- a/coreutils-8.4-su-pie.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am
---- coreutils-8.4-orig/src/Makefile.am 2010-09-03 17:34:43.399747649 +0200
-+++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200
-@@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP)
-
- # for crypt and pam
- su_LDADD += $(LIB_CRYPT) $(PAM_LIBS)
-+su_LDFLAGS = -pie -Wl,-z,relro,-z,now
-
- # for various ACL functions
- copy_LDADD += $(LIB_ACL)
diff --git a/coreutils-8.5-dircolors.patch b/coreutils-8.5-dircolors.patch
deleted file mode 100644
index 8707c0a..0000000
--- a/coreutils-8.5-dircolors.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -urNp coreutils-8.5-orig/src/dircolors.hin coreutils-8.5/src/dircolors.hin
---- coreutils-8.5-orig/src/dircolors.hin 2010-04-20 21:52:04.000000000 +0200
-+++ coreutils-8.5/src/dircolors.hin 2010-07-22 16:18:41.978036926 +0200
-@@ -127,6 +127,9 @@ EXEC 01;32
- .deb 01;31
- .rpm 01;31
- .jar 01;31
-+.war 01;31
-+.ear 01;31
-+.sar 01;31
- .rar 01;31
- .ace 01;31
- .zoo 01;31
diff --git a/coreutils-8.5-pam.patch b/coreutils-8.5-pam.patch
deleted file mode 100644
index 8a924b2..0000000
--- a/coreutils-8.5-pam.patch
+++ /dev/null
@@ -1,438 +0,0 @@
-From ea2d050b1952feb99f86c98255280beb6e589d8c Mon Sep 17 00:00:00 2001
-From: Ludwig Nussel
-Date: Tue, 17 Aug 2010 13:21:44 +0200
-Subject: [PATCH 1/7] pam support for su
-
----
- configure.ac | 14 +++
- src/Makefile.am | 4 +-
- src/su.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 278 insertions(+), 6 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index b07a52b..1fb5839 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -128,6 +128,20 @@ fi
-
- AC_FUNC_FORK
-
-+AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
-+ [Disable PAM support in su (default=auto)]), , [enable_pam=yes])
-+if test "x$enable_pam" != xno; then
-+ AC_CHECK_LIB([pam], [pam_start], [enable_pam=yes], [enable_pam=no])
-+ AC_CHECK_LIB([pam_misc], [misc_conv], [:], [enable_pam=no])
-+ if test "x$enable_pam" != xno; then
-+ AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM])
-+ PAM_LIBS="-lpam -lpam_misc"
-+ AC_SUBST(PAM_LIBS)
-+ fi
-+fi
-+AC_MSG_CHECKING([whether to enable PAM support in su])
-+AC_MSG_RESULT([$enable_pam])
-+
- optional_bin_progs=
- AC_CHECK_FUNCS([chroot],
- gl_ADD_PROG([optional_bin_progs], [chroot]))
-diff --git a/src/Makefile.am b/src/Makefile.am
-index db5359b..154a5ed 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -363,8 +363,8 @@ factor_LDADD += $(LIB_GMP)
- # for getloadavg
- uptime_LDADD += $(GETLOADAVG_LIBS)
-
--# for crypt
--su_LDADD += $(LIB_CRYPT)
-+# for crypt and pam
-+su_LDADD += $(LIB_CRYPT) $(PAM_LIBS)
-
- # for various ACL functions
- copy_LDADD += $(LIB_ACL)
-diff --git a/src/su.c b/src/su.c
-index f8f5b61..811aad7 100644
---- a/src/su.c
-+++ b/src/su.c
-@@ -37,6 +37,16 @@
- restricts who can su to UID 0 accounts. RMS considers that to
- be fascist.
-
-+#ifdef USE_PAM
-+
-+ Actually, with PAM, su has nothing to do with whether or not a
-+ wheel group is enforced by su. RMS tries to restrict your access
-+ to a su which implements the wheel group, but PAM considers that
-+ to be fascist, and gives the user/sysadmin the opportunity to
-+ enforce a wheel group by proper editing of /etc/pam.d/su
-+
-+#endif
-+
- Compile-time options:
- -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog.
- -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog.
-@@ -52,6 +62,13 @@
- #include
- #include
- #include
-+#ifdef USE_PAM
-+#include
-+#include
-+#include
-+#include
-+#include
-+#endif
-
- #include "system.h"
- #include "getpass.h"
-@@ -111,7 +128,9 @@
- /* The user to become if none is specified. */
- #define DEFAULT_USER "root"
-
-+#ifndef USE_PAM
- char *crypt (char const *key, char const *salt);
-+#endif
-
- static void run_shell (char const *, char const *, char **, size_t)
- ATTRIBUTE_NORETURN;
-@@ -125,6 +144,11 @@ static bool simulate_login;
- /* If true, change some environment vars to indicate the user su'd to. */
- static bool change_environment;
-
-+#ifdef USE_PAM
-+static bool _pam_session_opened;
-+static bool _pam_cred_established;
-+#endif
-+
- static struct option const longopts[] =
- {
- {"command", required_argument, NULL, 'c'},
-@@ -200,7 +224,174 @@ log_su (struct passwd const *pw, bool successful)
- }
- #endif
-
-+#ifdef USE_PAM
-+#define PAM_SERVICE_NAME PROGRAM_NAME
-+#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l"
-+static sig_atomic_t volatile caught_signal = false;
-+static pam_handle_t *pamh = NULL;
-+static int retval;
-+static struct pam_conv conv =
-+{
-+ misc_conv,
-+ NULL
-+};
-+
-+#define PAM_BAIL_P(a) \
-+ if (retval) \
-+ { \
-+ pam_end (pamh, retval); \
-+ a; \
-+ }
-+
-+static void
-+cleanup_pam (int retcode)
-+{
-+ if (_pam_session_opened)
-+ pam_close_session (pamh, 0);
-+
-+ if (_pam_cred_established)
-+ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT);
-+
-+ pam_end(pamh, retcode);
-+}
-+
-+/* Signal handler for parent process. */
-+static void
-+su_catch_sig (int sig)
-+{
-+ caught_signal = true;
-+}
-+
-+/* Export env variables declared by PAM modules. */
-+static void
-+export_pamenv (void)
-+{
-+ char **env;
-+
-+ /* This is a copy but don't care to free as we exec later anyways. */
-+ env = pam_getenvlist (pamh);
-+ while (env && *env)
-+ {
-+ if (putenv (*env) != 0)
-+ xalloc_die ();
-+ env++;
-+ }
-+}
-+
-+static void
-+create_watching_parent (void)
-+{
-+ pid_t child;
-+ sigset_t ourset, blockset;
-+ int status = 0;
-+
-+ retval = pam_open_session (pamh, 0);
-+ if (retval != PAM_SUCCESS)
-+ {
-+ cleanup_pam (retval);
-+ error (EXIT_FAILURE, 0, _("cannot not open session: %s"),
-+ pam_strerror (pamh, retval));
-+ }
-+ else
-+ _pam_session_opened = 1;
-+
-+ child = fork ();
-+ if (child == (pid_t) -1)
-+ {
-+ cleanup_pam (PAM_ABORT);
-+ error (EXIT_FAILURE, errno, _("cannot create child process"));
-+ }
-+
-+ /* the child proceeds to run the shell */
-+ if (child == 0)
-+ return;
-+
-+ /* In the parent watch the child. */
-+
-+ /* su without pam support does not have a helper that keeps
-+ sitting on any directory so let's go to /. */
-+ if (chdir ("/") != 0)
-+ error (0, errno, _("warning: cannot change directory to %s"), "/");
-+
-+ sigfillset (&ourset);
-+ if (sigprocmask (SIG_BLOCK, &ourset, NULL))
-+ {
-+ error (0, errno, _("cannot block signals"));
-+ caught_signal = true;
-+ }
-+ if (!caught_signal)
-+ {
-+ struct sigaction action;
-+ action.sa_handler = su_catch_sig;
-+ sigemptyset (&action.sa_mask);
-+ action.sa_flags = 0;
-+ sigemptyset (&ourset);
-+ if (sigaddset (&ourset, SIGTERM)
-+ || sigaddset (&ourset, SIGALRM)
-+ || sigaction (SIGTERM, &action, NULL)
-+ || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
-+ {
-+ error (0, errno, _("cannot set signal handler"));
-+ caught_signal = true;
-+ }
-+ }
-+ if (!caught_signal)
-+ {
-+ pid_t pid;
-+ for (;;)
-+ {
-+ pid = waitpid (child, &status, WUNTRACED);
-+
-+ if (pid != (pid_t)-1 && WIFSTOPPED (status))
-+ {
-+ /* tcsh sends SIGTSTP to the process group, and so is already pending */
-+ kill (getpid (), SIGSTOP);
-+ if (WSTOPSIG(status) != SIGSTOP) {
-+ sigemptyset(&blockset);
-+ if (sigaddset(&blockset, WSTOPSIG(status)) ||
-+ sigprocmask(SIG_UNBLOCK, &blockset, &ourset) ||
-+ sigprocmask(SIG_SETMASK, &ourset, NULL))
-+ {
-+ error (0, errno, _("cannot set signal handler"));
-+ }
-+ }
-+ /* once we get here, we must have resumed */
-+ kill (pid, SIGCONT);
-+ }
-+ else
-+ break;
-+ }
-+ if (pid != (pid_t)-1)
-+ if (WIFSIGNALED (status))
-+ status = WTERMSIG (status) + 128;
-+ else
-+ status = WEXITSTATUS (status);
-+ else
-+ status = 1;
-+ }
-+ else
-+ status = 1;
-+
-+ if (caught_signal)
-+ {
-+ fprintf (stderr, _("\nSession terminated, killing shell..."));
-+ kill (child, SIGTERM);
-+ }
-+
-+ cleanup_pam (PAM_SUCCESS);
-+
-+ if (caught_signal)
-+ {
-+ sleep (2);
-+ kill (child, SIGKILL);
-+ fprintf (stderr, _(" ...killed.\n"));
-+ }
-+ exit (status);
-+}
-+#endif
-+
- /* Ask the user for a password.
-+ If PAM is in use, let PAM ask for the password if necessary.
- Return true if the user gives the correct password for entry PW,
- false if not. Return true without asking for a password if run by UID 0
- or if PW has an empty password. */
-@@ -208,10 +399,52 @@ log_su (struct passwd const *pw, bool successful)
- static bool
- correct_password (const struct passwd *pw)
- {
-+#ifdef USE_PAM
-+ const struct passwd *lpw;
-+ const char *cp;
-+
-+ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME,
-+ pw->pw_name, &conv, &pamh);
-+ PAM_BAIL_P (return false);
-+
-+ if (isatty (0) && (cp = ttyname (0)) != NULL)
-+ {
-+ const char *tty;
-+
-+ if (strncmp (cp, "/dev/", 5) == 0)
-+ tty = cp + 5;
-+ else
-+ tty = cp;
-+ retval = pam_set_item (pamh, PAM_TTY, tty);
-+ PAM_BAIL_P (return false);
-+ }
-+#if 0 /* Manpage discourages use of getlogin. */
-+ cp = getlogin ();
-+ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ()))
-+#endif
-+ lpw = getpwuid (getuid ());
-+ if (lpw && lpw->pw_name)
-+ {
-+ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name);
-+ PAM_BAIL_P (return false);
-+ }
-+ retval = pam_authenticate (pamh, 0);
-+ PAM_BAIL_P (return false);
-+ retval = pam_acct_mgmt (pamh, 0);
-+ if (retval == PAM_NEW_AUTHTOK_REQD)
-+ {
-+ /* Password has expired. Offer option to change it. */
-+ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
-+ PAM_BAIL_P (return false);
-+ }
-+ PAM_BAIL_P (return false);
-+ /* Must be authenticated if this point was reached. */
-+ return true;
-+#else /* !USE_PAM */
- char *unencrypted, *encrypted, *correct;
- #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
- /* Shadow passwd stuff for SVR3 and maybe other systems. */
-- struct spwd *sp = getspnam (pw->pw_name);
-+ const struct spwd *sp = getspnam (pw->pw_name);
-
- endspent ();
- if (sp)
-@@ -232,6 +465,7 @@ correct_password (const struct passwd *pw)
- encrypted = crypt (unencrypted, correct);
- memset (unencrypted, 0, strlen (unencrypted));
- return STREQ (encrypted, correct);
-+#endif /* !USE_PAM */
- }
-
- /* Update `environ' for the new shell based on PW, with SHELL being
-@@ -274,19 +508,41 @@ modify_environment (const struct passwd *pw, const char *shell)
- }
- }
- }
-+
-+#ifdef USE_PAM
-+ export_pamenv ();
-+#endif
- }
-
- /* Become the user and group(s) specified by PW. */
-
- static void
--change_identity (const struct passwd *pw)
-+init_groups (const struct passwd *pw)
- {
- #ifdef HAVE_INITGROUPS
- errno = 0;
- if (initgroups (pw->pw_name, pw->pw_gid) == -1)
-- error (EXIT_CANCELED, errno, _("cannot set groups"));
-+ {
-+#ifdef USE_PAM
-+ cleanup_pam (PAM_ABORT);
-+#endif
-+ error (EXIT_FAILURE, errno, _("cannot set groups"));
-+ }
- endgrent ();
- #endif
-+
-+#ifdef USE_PAM
-+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED);
-+ if (retval != PAM_SUCCESS)
-+ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval));
-+ else
-+ _pam_cred_established = 1;
-+#endif
-+}
-+
-+static void
-+change_identity (const struct passwd *pw)
-+{
- if (setgid (pw->pw_gid))
- error (EXIT_CANCELED, errno, _("cannot set group id"));
- if (setuid (pw->pw_uid))
-@@ -500,9 +756,21 @@ main (int argc, char **argv)
- shell = NULL;
- }
- shell = xstrdup (shell ? shell : pw->pw_shell);
-- modify_environment (pw, shell);
-+
-+ init_groups (pw);
-+
-+#ifdef USE_PAM
-+ create_watching_parent ();
-+ /* Now we're in the child. */
-+#endif
-
- change_identity (pw);
-+
-+ /* Set environment after pam_open_session, which may put KRB5CCNAME
-+ into the pam_env, etc. */
-+
-+ modify_environment (pw, shell);
-+
- if (simulate_login && chdir (pw->pw_dir) != 0)
- error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
-
---
-1.7.1
-diff -urNp coreutils-8.7-orig/doc/coreutils.texi coreutils-8.7/doc/coreutils.texi
---- coreutils-8.7-orig/doc/coreutils.texi 2010-11-15 12:47:03.529922880 +0100
-+++ coreutils-8.7/doc/coreutils.texi 2010-11-15 12:49:55.945171380 +0100
-@@ -15180,7 +15180,9 @@ the exit status of @var{command} otherwi
-
- @command{su} allows one user to temporarily become another user. It runs a
- command (often an interactive shell) with the real and effective user
--ID, group ID, and supplemental groups of a given @var{user}. Synopsis:
-+ID, group ID, and supplemental groups of a given @var{user}. When the -l
-+option is given, the su-l PAM file is used instead of the default su PAM file.
-+Synopsis:
-
- @example
- su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}]
-@@ -15259,7 +15261,8 @@ environment variables except @env{TERM},
- (which are set, even for the super-user, as described above), and set
- @env{PATH} to a compiled-in default value. Change to @var{user}'s home
- directory. Prepend @samp{-} to the shell's name, intended to make it
--read its login startup file(s).
-+read its login startup file(s). When this option is given, /etc/pam.d/su-l
-+PAM file is used instead of the default one.
-
- @item -m
- @itemx -p
diff --git a/coreutils-8.7-runuser.patch b/coreutils-8.7-runuser.patch
deleted file mode 100644
index c68da7c..0000000
--- a/coreutils-8.7-runuser.patch
+++ /dev/null
@@ -1,338 +0,0 @@
-diff -urNp coreutils-8.7-orig/AUTHORS coreutils-8.7/AUTHORS
---- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100
-@@ -65,6 +65,7 @@ readlink: Dmitry V. Levin
- rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
- rmdir: David MacKenzie
- runcon: Russell Coker
-+runuser: David MacKenzie, Dan Walsh
- seq: Ulrich Drepper
- sha1sum: Ulrich Drepper, Scott Miller, David Madore
- sha224sum: Ulrich Drepper, Scott Miller, David Madore
-diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man
---- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100
-@@ -555,6 +555,9 @@ while (length)
- $include{$sect} .= $content;
- }
-
-+# There is no info documentation for runuser (shared with su).
-+$opt_no_info = 1 if $program eq 'runuser';
-+
- # Refer to the real documentation.
- unless ($opt_no_info)
- {
-diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am
---- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100
-@@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read
- rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
- rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
- runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
-+runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c
- seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
- sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
- sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
-diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x
---- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +0100
-@@ -0,0 +1,12 @@
-+[NAME]
-+runuser \- run a shell with substitute user and group IDs
-+[DESCRIPTION]
-+.\" Add any additional description here
-+[SEE ALSO]
-+.TP
-+More detailed Texinfo documentation could be found by command
-+.TP
-+\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t
-+.TP
-+since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR.
-+.br
-diff -urNp coreutils-8.7-orig/README coreutils-8.7/README
---- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100
-@@ -11,8 +11,8 @@ The programs that can be built with this
- factor false fmt fold groups head hostid hostname id install join kill
- link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
- nproc od paste pathchk pinky pr printenv printf ptx pwd readlink realpath
-- rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred
-- shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
-+ rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum
-+ shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
- timeout touch tr true truncate tsort tty uname unexpand uniq unlink
- uptime users vdir wc who whoami yes
-
-diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am
---- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100
-+++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100
-@@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \
- rm \
- rmdir \
- runcon \
-+ runuser \
- seq \
- sha1sum \
- sha224sum \
-@@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD)
- ginstall_LDADD += $(copy_LDADD)
- mv_LDADD += $(copy_LDADD)
-
-+runuser_SOURCES = su.c
-+runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\""
-+runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS)
-+
- remove_LDADD =
- mv_LDADD += $(remove_LDADD)
- rm_LDADD += $(remove_LDADD)
-@@ -395,7 +400,7 @@ RELEASE_YEAR = \
- `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \
- $(top_srcdir)/lib/version-etc.c`
-
--all-local: su$(EXEEXT)
-+all-local: su$(EXEEXT) runuser
-
- installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
-
-diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c
---- coreutils-8.7-orig/src/su.c 2010-11-15 10:07:07.372933288 +0100
-+++ coreutils-8.7/src/su.c 2010-11-15 10:42:12.569159230 +0100
-@@ -100,9 +100,15 @@
- #include "error.h"
-
- /* The official name of this program (e.g., no `g' prefix). */
-+#ifndef RUNUSER
- #define PROGRAM_NAME "su"
-+#else
-+#define PROGRAM_NAME "runuser"
-+#endif
-
-+#ifndef AUTHORS
- #define AUTHORS proper_name ("David MacKenzie")
-+#endif
-
- #if HAVE_PATHS_H
- # include
-@@ -140,6 +146,9 @@
- #ifndef USE_PAM
- char *crypt (char const *key, char const *salt);
- #endif
-+#ifndef CHECKPASSWD
-+#define CHECKPASSWD 1
-+#endif
-
- static void run_shell (char const *, char const *, char **, size_t)
- ATTRIBUTE_NORETURN;
-@@ -169,6 +178,10 @@ static struct option const longopts[] =
- {"login", no_argument, NULL, 'l'},
- {"preserve-environment", no_argument, NULL, 'p'},
- {"shell", required_argument, NULL, 's'},
-+#ifdef RUNUSER
-+ {"group", required_argument, NULL, 'g'},
-+ {"supp-group", required_argument, NULL, 'G'},
-+#endif
- {GETOPT_HELP_OPTION_DECL},
- {GETOPT_VERSION_OPTION_DECL},
- {NULL, 0, NULL, 0}
-@@ -444,6 +457,11 @@ correct_password (const struct passwd *p
- retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name);
- PAM_BAIL_P (return false);
- }
-+#ifdef RUNUSER
-+ if (getuid() != geteuid())
-+ /* safety net: deny operation if we are suid by accident */
-+ error(EXIT_FAILURE, 1, "runuser may not be setuid");
-+#else
- retval = pam_authenticate (pamh, 0);
- PAM_BAIL_P (return false);
- retval = pam_acct_mgmt (pamh, 0);
-@@ -454,6 +472,7 @@ correct_password (const struct passwd *p
- PAM_BAIL_P (return false);
- }
- PAM_BAIL_P (return false);
-+#endif
- /* Must be authenticated if this point was reached. */
- return true;
- #else /* !USE_PAM */
-@@ -533,11 +552,22 @@ modify_environment (const struct passwd
- /* Become the user and group(s) specified by PW. */
-
- static void
--init_groups (const struct passwd *pw)
-+init_groups (const struct passwd *pw
-+#ifdef RUNUSER
-+ , gid_t *groups, int num_groups
-+#endif
-+ )
- {
- #ifdef HAVE_INITGROUPS
-+ int rc = 0;
- errno = 0;
-- if (initgroups (pw->pw_name, pw->pw_gid) == -1)
-+#ifdef RUNUSER
-+ if (num_groups)
-+ rc = setgroups(num_groups, groups);
-+ else
-+#endif
-+ rc = initgroups(pw->pw_name, pw->pw_gid);
-+ if (rc == -1)
- {
- #ifdef USE_PAM
- cleanup_pam (PAM_ABORT);
-@@ -639,6 +669,28 @@ usage (int status)
- else
- {
- printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
-+#ifdef RUNUSER
-+ printf (_("\
-+Change the effective user id and group id to that of USER. Only session PAM\n\
-+hooks are run, and there is no password prompt. This command is useful only\n\
-+when run as the root user. If run as a non-root user without privilege\n\
-+to set user ID, the command will fail as the binary is not setuid.\n\
-+As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\
-+than su.\n\
-+\n\
-+ -, -l, --login make the shell a login shell, uses runuser-l\n\
-+ PAM file instead of default one\n\
-+ -g --group=group specify the primary group\n\
-+ -G --supp-group=group specify a supplemental group\n\
-+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
-+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
-+ and do not create a new session\n\
-+ -f, --fast pass -f to the shell (for csh or tcsh)\n\
-+ -m, --preserve-environment do not reset environment variables\n\
-+ -p same as -m\n\
-+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
-+"), program_name);
-+#else
- fputs (_("\
- Change the effective user id and group id to that of USER.\n\
- \n\
-@@ -651,6 +703,7 @@ Change the effective user id and group i
- -p same as -m\n\
- -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
- "), stdout);
-+#endif
- fputs (HELP_OPTION_DESCRIPTION, stdout);
- fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-@@ -672,6 +725,12 @@ main (int argc, char **argv)
- char *shell = NULL;
- struct passwd *pw;
- struct passwd pw_copy;
-+#ifdef RUNUSER
-+ struct group *gr;
-+ gid_t groups[NGROUPS_MAX];
-+ int num_supp_groups = 0;
-+ int use_gid = 0;
-+#endif
-
- initialize_main (&argc, &argv);
- set_program_name (argv[0]);
-@@ -686,7 +745,11 @@ main (int argc, char **argv)
- simulate_login = false;
- change_environment = true;
-
-- while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
-+ while ((optc = getopt_long (argc, argv, "c:flmps:"
-+#ifdef RUNUSER
-+ "g:G:"
-+#endif
-+ , longopts, NULL)) != -1)
- {
- switch (optc)
- {
-@@ -716,6 +779,28 @@ main (int argc, char **argv)
- shell = optarg;
- break;
-
-+#ifdef RUNUSER
-+ case 'g':
-+ gr = getgrnam(optarg);
-+ if (!gr)
-+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
-+ use_gid = 1;
-+ groups[0] = gr->gr_gid;
-+ break;
-+
-+ case 'G':
-+ num_supp_groups++;
-+ if (num_supp_groups >= NGROUPS_MAX)
-+ error (EXIT_FAILURE, 0,
-+ _("Can't specify more than %d supplemental groups"),
-+ NGROUPS_MAX - 1);
-+ gr = getgrnam(optarg);
-+ if (!gr)
-+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
-+ groups[num_supp_groups] = gr->gr_gid;
-+ break;
-+#endif
-+
- case_GETOPT_HELP_CHAR;
-
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
-@@ -754,7 +839,20 @@ main (int argc, char **argv)
- : DEFAULT_SHELL);
- endpwent ();
-
-- if (!correct_password (pw))
-+#ifdef RUNUSER
-+ if (num_supp_groups && !use_gid)
-+ {
-+ pw->pw_gid = groups[1];
-+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
-+ }
-+ else if (use_gid)
-+ {
-+ pw->pw_gid = groups[0];
-+ num_supp_groups++;
-+ }
-+#endif
-+
-+ if (CHECKPASSWD && !correct_password (pw))
- {
- #ifdef SYSLOG_FAILURE
- log_su (pw, false);
-@@ -784,7 +882,11 @@ main (int argc, char **argv)
- }
- shell = xstrdup (shell ? shell : pw->pw_shell);
-
-- init_groups (pw);
-+ init_groups (pw
-+#ifdef RUNUSER
-+ , groups, num_supp_groups
-+#endif
-+ );
-
- #ifdef USE_PAM
- create_watching_parent ();
-diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version
---- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100
-@@ -32,6 +32,7 @@ expected_failure_status_nohup=125
- expected_failure_status_stdbuf=125
- expected_failure_status_su=125
- expected_failure_status_timeout=125
-+expected_failure_status_runuser=125
- expected_failure_status_printenv=2
- expected_failure_status_tty=3
- expected_failure_status_sort=2
-@@ -209,6 +210,7 @@ seq_setup () { args=10; }
- sleep_setup () { args=0; }
- su_setup () { args=--version; }
- stdbuf_setup () { args="-oL true"; }
-+runuser_setup () { args=--version; }
- timeout_setup () { args=--version; }
-
- # I'd rather not run sync, since it spins up disks that I've
-diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt
---- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200
-+++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100
-@@ -37,6 +37,7 @@ my %exit_status =
- sort => 2,
- stdbuf => 125,
- su => 125,
-+ runuser => 125,
- test => 0,
- timeout => 125,
- true => 0,
diff --git a/coreutils-9.9-fix-cut-test-aarch64.patch b/coreutils-9.9-fix-cut-test-aarch64.patch
new file mode 100644
index 0000000..600f87b
--- /dev/null
+++ b/coreutils-9.9-fix-cut-test-aarch64.patch
@@ -0,0 +1,28 @@
+From 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?=
+Date: Mon, 22 Dec 2025 17:12:48 +0000
+Subject: [PATCH] tests: avoid false failure due to ulimit on aarch64
+
+* tests/cut/cut-huge-range.sh: Add an extra 1MiB headroom,
+which was seen with aarch64.
+Reported at https://bugzilla.redhat.com/2424302
+
+Cherry-picked-by: Lukáš Zaoral
+Upstream-commit: 95044cb5eaea83d02f768feb5ab79fcf5e6ad782
+---
+ tests/cut/cut-huge-range.sh | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tests/cut/cut-huge-range.sh b/tests/cut/cut-huge-range.sh
+index 4bd1b129d8..98d7e8f0b9 100755
+--- a/tests/cut/cut-huge-range.sh
++++ b/tests/cut/cut-huge-range.sh
+@@ -22,6 +22,7 @@ getlimits_
+
+ vm=$(get_min_ulimit_v_ returns_ 0 cut -b1 /dev/null) \
+ || skip_ 'shell lacks ulimit, or ASAN enabled'
++vm=$(($vm+1000)) # https://bugzilla.redhat.com/2424302
+
+ # Ensure we can cut up to our sentinel value.
+ # Don't use expr to subtract one,
+
diff --git a/coreutils-9.9-gnulib-c23.patch b/coreutils-9.9-gnulib-c23.patch
new file mode 100644
index 0000000..82e3899
--- /dev/null
+++ b/coreutils-9.9-gnulib-c23.patch
@@ -0,0 +1,169 @@
+From 891761bca1aa78336e5b18c121075b6e4696c5d4 Mon Sep 17 00:00:00 2001
+From: Paul Eggert
+Date: Sun, 23 Nov 2025 00:50:40 -0800
+Subject: [PATCH] Port to C23 qualifier-generic fns like strchr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This ports Gnulib to strict C23 platforms that reject code
+like ‘char *q = strchr (P, 'x');’ when P is a pointer to const,
+because in C23 strchr is a qualifier-generic function so
+strchr (P, 'x') returns char const *.
+This patch does not attempt to do the following two things,
+which might be useful in the future:
+1. When compiling on non-C23 platforms, check user code for
+portability to platforms that define qualifier-generic functions.
+2. Port Gnulib to platforms that have qualifier-generic functions
+not listed in the C23 standard, e.g., strchrnul. I don’t know
+of any such platforms.
+* lib/mbschr.c (mbschr):
+* lib/memchr2.c (memchr2):
+Port to C23, where functions like strchr are qualifier-generic.
+* lib/c++defs.h (_GL_FUNCDECL_SYS_NAME): New macro.
+* lib/c++defs.h (_GL_FUNCDECL_SYS):
+* lib/stdlib.in.h (bsearch):
+Use it, to prevent C23 names like strchr from acting like macros.
+* lib/string.in.h (memchr, strchr, strpbrk, strrchr):
+Do not #undef when GNULIB_POSIXCHECK is defined, as this could
+cause conforming C23 code to fail to conform. It’s not clear why
+_GL_WARN_ON_USE_CXX; perhaps it was needed but isn’t any more?
+But for now, limit the removal of #undef to these four functions
+where #undeffing is clearly undesirable in C23.
+* lib/wchar.in.h (wmemchr): Parenthesize function name in decl,
+to prevent it from acting like a macro.
+
+Cherry-picked-by: Lukáš Zaoral
+Upstream-commit: df17f4f37ed3ca373d23ad42eae51122bdb96626
+---
+ lib/c++defs.h | 12 +++++++++++-
+ lib/mbschr.c | 2 +-
+ lib/memchr2.c | 2 +-
+ lib/stdlib.in.h | 6 +++---
+ lib/string.in.h | 4 ----
+ lib/wchar.in.h | 2 +-
+ 6 files changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/lib/c++defs.h b/lib/c++defs.h
+index b77979a..7384457 100644
+--- a/lib/c++defs.h
++++ b/lib/c++defs.h
+@@ -127,6 +127,16 @@
+ #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \
+ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters
+
++/* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to
++ parenthsized func otherwise. Parenthesization is needed in C23 if
++ the function is like strchr and so is a qualifier-generic macro
++ that expands to something more complicated. */
++#ifdef __cplusplus
++# define _GL_FUNCDECL_SYS_NAME(func) func
++#else
++# define _GL_FUNCDECL_SYS_NAME(func) (func)
++#endif
++
+ /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]);
+ declares the system function, named func, with the given prototype,
+ consisting of return type, parameters, and attributes.
+@@ -139,7 +149,7 @@
+ _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD);
+ */
+ #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \
+- _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters
++ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters
+
+ /* _GL_CXXALIAS_RPL (func, rettype, parameters);
+ declares a C++ alias called GNULIB_NAMESPACE::func
+diff --git a/lib/mbschr.c b/lib/mbschr.c
+index c9e14b5..6582134 100644
+--- a/lib/mbschr.c
++++ b/lib/mbschr.c
+@@ -65,5 +65,5 @@ mbschr (const char *string, int c)
+ return NULL;
+ }
+ else
+- return strchr (string, c);
++ return (char *) strchr (string, c);
+ }
+diff --git a/lib/memchr2.c b/lib/memchr2.c
+index 7493823..d7724ae 100644
+--- a/lib/memchr2.c
++++ b/lib/memchr2.c
+@@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n)
+ c2 = (unsigned char) c2_in;
+
+ if (c1 == c2)
+- return memchr (s, c1, n);
++ return (void *) memchr (s, c1, n);
+
+ /* Handle the first few bytes by reading one byte at a time.
+ Do this until VOID_PTR is aligned on a longword boundary. */
+diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
+index bef0aaa..fd0e1e0 100644
+--- a/lib/stdlib.in.h
++++ b/lib/stdlib.in.h
+@@ -224,9 +224,9 @@ _GL_INLINE_HEADER_BEGIN
+
+ /* Declarations for ISO C N3322. */
+ #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__
+-_GL_EXTERN_C void *bsearch (const void *__key,
+- const void *__base, size_t __nmemb, size_t __size,
+- int (*__compare) (const void *, const void *))
++_GL_EXTERN_C void *_GL_FUNCDECL_SYS_NAME (bsearch)
++ (const void *__key, const void *__base, size_t __nmemb, size_t __size,
++ int (*__compare) (const void *, const void *))
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5));
+ _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size,
+ int (*__compare) (const void *, const void *))
+diff --git a/lib/string.in.h b/lib/string.in.h
+index fdcdd21..8b56acf 100644
+--- a/lib/string.in.h
++++ b/lib/string.in.h
+@@ -409,7 +409,6 @@ _GL_CXXALIASWARN1 (memchr, void const *,
+ _GL_CXXALIASWARN (memchr);
+ # endif
+ #elif defined GNULIB_POSIXCHECK
+-# undef memchr
+ /* Assume memchr is always declared. */
+ _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
+ "use gnulib module memchr for portability" );
+@@ -674,7 +673,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - "
+ #if defined GNULIB_POSIXCHECK
+ /* strchr() does not work with multibyte strings if the locale encoding is
+ GB18030 and the character to be searched is a digit. */
+-# undef strchr
+ /* Assume strchr is always declared. */
+ _GL_WARN_ON_USE_CXX (strchr,
+ const char *, char *, (const char *, int),
+@@ -981,7 +979,6 @@ _GL_CXXALIASWARN (strpbrk);
+ Even in this simple case, it does not work with multibyte strings if the
+ locale encoding is GB18030 and one of the characters to be searched is a
+ digit. */
+-# undef strpbrk
+ _GL_WARN_ON_USE_CXX (strpbrk,
+ const char *, char *, (const char *, const char *),
+ "strpbrk cannot work correctly on character strings "
+@@ -1011,7 +1008,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings "
+ #if defined GNULIB_POSIXCHECK
+ /* strrchr() does not work with multibyte strings if the locale encoding is
+ GB18030 and the character to be searched is a digit. */
+-# undef strrchr
+ /* Assume strrchr is always declared. */
+ _GL_WARN_ON_USE_CXX (strrchr,
+ const char *, char *, (const char *, int),
+diff --git a/lib/wchar.in.h b/lib/wchar.in.h
+index ab602a2..6be4515 100644
+--- a/lib/wchar.in.h
++++ b/lib/wchar.in.h
+@@ -301,7 +301,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
+ # ifndef __cplusplus
+-_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n)
++_GL_EXTERN_C wchar_t *(wmemchr) (const wchar_t *__s, wchar_t __wc, size_t __n)
+ _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
+ # endif
+ _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n)
+--
+2.52.0
+
diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS
deleted file mode 100644
index 9c182c8..0000000
--- a/coreutils-DIR_COLORS
+++ /dev/null
@@ -1,246 +0,0 @@
-# Configuration file for the color ls utility
-# Synchronized with coreutils 8.5 dircolors
-# This file goes in the /etc directory, and must be world readable.
-# You can copy this file to .dir_colors in your $HOME directory to override
-# the system defaults.
-
-# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not
-# pipes. 'all' adds color characters to all output. 'none' shuts colorization
-# off.
-COLOR tty
-
-# Extra command line options for ls go here.
-# Basically these ones are:
-# -F = show '/' for dirs, '*' for executables, etc.
-# -T 0 = don't trust tab spacing when formatting ls output.
-OPTIONS -F -T 0
-
-# Below, there should be one TERM entry for each termtype that is colorizable
-TERM Eterm
-TERM ansi
-TERM color-xterm
-TERM con132x25
-TERM con132x30
-TERM con132x43
-TERM con132x60
-TERM con80x25
-TERM con80x28
-TERM con80x30
-TERM con80x43
-TERM con80x50
-TERM con80x60
-TERM cons25
-TERM console
-TERM cygwin
-TERM dtterm
-TERM eterm-color
-TERM gnome
-TERM gnome-256color
-TERM jfbterm
-TERM konsole
-TERM kterm
-TERM linux
-TERM linux-c
-TERM mach-color
-TERM mlterm
-TERM putty
-TERM rxvt
-TERM rxvt-256color
-TERM rxvt-cygwin
-TERM rxvt-cygwin-native
-TERM rxvt-unicode
-TERM rxvt-unicode-256color
-TERM rxvt-unicode256
-TERM screen
-TERM screen-256color
-TERM screen-256color-bce
-TERM screen-bce
-TERM screen-w
-TERM screen.rxvt
-TERM screen.linux
-TERM terminator
-TERM vt100
-TERM xterm
-TERM xterm-16color
-TERM xterm-256color
-TERM xterm-88color
-TERM xterm-color
-TERM xterm-debian
-
-# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output)
-EIGHTBIT 1
-
-# Below are the color init strings for the basic file types. A color init
-# string consists of one or more of the following numeric codes:
-# Attribute codes:
-# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
-# Text color codes:
-# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
-# Background color codes:
-# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
-#NORMAL 00 # no color code at all
-#FILE 00 # normal file, use no color at all
-RESET 0 # reset to "normal" color
-DIR 01;34 # directory
-LINK 01;36 # symbolic link (If you set this to 'target' instead of a
- # numerical value, the color is as for the file pointed to.)
-MULTIHARDLINK 00 # regular file with more than one link
-FIFO 40;33 # pipe
-SOCK 01;35 # socket
-DOOR 01;35 # door
-BLK 40;33;01 # block device driver
-CHR 40;33;01 # character device driver
-ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file
-MISSING 01;05;37;41 # ... and the files they point to
-SETUID 37;41 # file that is setuid (u+s)
-SETGID 30;43 # file that is setgid (g+s)
-CAPABILITY 30;41 # file with capability
-STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w)
-OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
-STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
-
-# This is for files with execute permission:
-EXEC 01;32
-
-# List any file extensions like '.gz' or '.tar' that you would like ls
-# to colorize below. Put the extension, a space, and the color init string.
-# (and any comments you want to add after a '#')
-# executables (bright green)
-#.cmd 01;32
-#.exe 01;32
-#.com 01;32
-#.btm 01;32
-#.bat 01;32
-#.sh 01;32
-#.csh 01;32
- # archives or compressed (bright red)
-.tar 01;31
-.tgz 01;31
-.arj 01;31
-.taz 01;31
-.lzh 01;31
-.lzma 01;31
-.tlz 01;31
-.txz 01;31
-.zip 01;31
-.z 01;31
-.Z 01;31
-.dz 01;31
-.gz 01;31
-.lz 01;31
-.xz 01;31
-.bz2 01;31
-.tbz 01;31
-.tbz2 01;31
-.bz 01;31
-.tz 01;31
-.deb 01;31
-.rpm 01;31
-.jar 01;31
-.war 01;31
-.ear 01;31
-.sar 01;31
-.rar 01;31
-.ace 01;31
-.zoo 01;31
-.cpio 01;31
-.7z 01;31
-.rz 01;31
-
-# image formats (magenta)
-.jpg 01;35
-.jpeg 01;35
-.gif 01;35
-.bmp 01;35
-.pbm 01;35
-.pgm 01;35
-.ppm 01;35
-.tga 01;35
-.xbm 01;35
-.xpm 01;35
-.tif 01;35
-.tiff 01;35
-.png 01;35
-.svg 01;35
-.svgz 01;35
-.mng 01;35
-.pcx 01;35
-.mov 01;35
-.mpg 01;35
-.mpeg 01;35
-.m2v 01;35
-.mkv 01;35
-.ogm 01;35
-.mp4 01;35
-.m4v 01;35
-.mp4v 01;35
-.vob 01;35
-.qt 01;35
-.nuv 01;35
-.wmv 01;35
-.asf 01;35
-.rm 01;35
-.rmvb 01;35
-.flc 01;35
-.avi 01;35
-.fli 01;35
-.flv 01;35
-.gl 01;35
-.dl 01;35
-.xcf 01;35
-.xwd 01;35
-.yuv 01;35
-.cgm 01;35
-.emf 01;35
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axv 01;35
-.anx 01;35
-.ogv 01;35
-.ogx 01;35
-
-# audio formats (cyan)
-.aac 01;36
-.au 01;36
-.flac 01;36
-.mid 01;36
-.midi 01;36
-.mka 01;36
-.mp3 01;36
-.mpc 01;36
-.ogg 01;36
-.ra 01;36
-.wav 01;36
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axa 01;36
-.oga 01;36
-.spx 01;36
-.xspf 01;36
-
-# colorize basic documents (brown)
-.pdf 00;33
-.ps 00;33
-.ps.gz 00;33
-.txt 00;33
-.patch 00;33
-.diff 00;33
-.log 00;33
-.tex 00;33
-.xls 00;33
-.xlsx 00;33
-.ppt 00;33
-.pptx 00;33
-.rtf 00;33
-.doc 00;33
-.docx 00;33
-.odt 00;33
-.ods 00;33
-.odp 00;33
-.xml 00;33
-.epub 00;33
-.abw 00;33
-.htm 00;33
-.html 00;33
-.shtml 00;33
-.wpd 00;33
diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color
deleted file mode 100644
index 1037dd5..0000000
--- a/coreutils-DIR_COLORS.256color
+++ /dev/null
@@ -1,219 +0,0 @@
-# Configuration file for the 256color ls utility
-# This file goes in the /etc directory, and must be world readable.
-# Synchronized with coreutils 8.5 dircolors
-# You can copy this file to .dir_colors in your $HOME directory to override
-# the system defaults.
-# In the case that you are not satisfied with supplied colors, please
-# submit your color configuration or attach your file with colors readable
-# on ALL color background schemas (white,gray,black) to RedHat Bugzilla
-# ticket on https://bugzilla.redhat.com/show_bug.cgi?id=429121 . TIA.
-# Please just keep ls color conventions from 8 color scheme.
-
-# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not
-# pipes. 'all' adds color characters to all output. 'none' shuts colorization
-# off.
-COLOR tty
-
-# Extra command line options for ls go here.
-# Basically these ones are:
-# -F = show '/' for dirs, '*' for executables, etc.
-# -T 0 = don't trust tab spacing when formatting ls output.
-OPTIONS -F -T 0
-
-# Below, there should be one TERM entry for each termtype that is colorizable
-TERM putty-256color
-TERM rxvt-256color
-TERM rxvt-unicode-256color
-TERM rxvt-unicode256
-TERM screen-256color
-TERM xterm-256color
-TERM gnome-256color
-
-# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output)
-EIGHTBIT 1
-
-# Below are the color init strings for the basic file types. A color init
-# string consists of one or more of the following numeric codes:
-# Attribute codes:
-# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
-# Text color(8 colors mode) codes:
-# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
-# Background color(8 colors mode) codes:
-# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
-# Text color(256 colors mode) codes:
-# Valid syntax for text 256color is 38;5; , where color number
-# is number between 0 and 255.
-# You may find following command useful to search the best one for you:
-# for ((x=0; x<=255; x++));do echo -e "${x}:\033[38;5;${x}mcolor\033[000m";done
-# Background color(256 colors mode) codes:
-# Valid syntax for background 256color is 48;5; , where
-# color number is number between 0 and 255.
-# You may find following command useful to search the best one for you:
-# for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done
-
-#NORMAL 00 # global default, no color code at all
-#FILE 00 # normal file, use no color at all
-RESET 0 # reset to "normal" color
-DIR 38;5;27 # directory
-LINK 38;5;51 # symbolic link (If you set this to 'target' instead of a
- # numerical value, the color is as for the file pointed to.)
-MULTIHARDLINK 44;38;5;15 # regular file with more than one link
-FIFO 40;38;5;11 # pipe
-SOCK 38;5;13 # socket
-DOOR 38;5;5 # door
-BLK 48;5;232;38;5;11 # block device driver
-CHR 48;5;232;38;5;3 # character device driver
-ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file
-MISSING 05;48;5;232;38;5;15 # ... and the files they point to
-SETUID 48;5;196;38;5;15 # file that is setuid (u+s)
-SETGID 48;5;11;38;5;16 # file that is setgid (g+s)
-CAPABILITY 48;5;196;38;5;226 # file with capability
-STICKY_OTHER_WRITABLE 48;5;10;38;5;16 # dir that is sticky and other-writable (+t,o+w)
-OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky
-STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable
-
-# This is for files with execute permission:
-EXEC 38;5;34
-
-# List any file extensions like '.gz' or '.tar' that you would like ls
-# to colorize below. Put the extension, a space, and the color init string.
-# (and any comments you want to add after a '#')
-# executables (bright green)
-#.cmd 38;5;34
-#.exe 38;5;34
-#.com 38;5;34
-#.btm 38;5;34
-#.bat 38;5;34
-#.sh 38;5;34
-#.csh 38;5;34
- # archives or compressed (bright red)
-.tar 38;5;9
-.tgz 38;5;9
-.arj 38;5;9
-.taz 38;5;9
-.lzh 38;5;9
-.lzma 38;5;9
-.tlz 38;5;9
-.txz 38;5;9
-.zip 38;5;9
-.z 38;5;9
-.Z 38;5;9
-.dz 38;5;9
-.gz 38;5;9
-.lz 38;5;9
-.xz 38;5;9
-.bz2 38;5;9
-.tbz 38;5;9
-.tbz2 38;5;9
-.bz 38;5;9
-.tz 38;5;9
-.deb 38;5;9
-.rpm 38;5;9
-.jar 38;5;9
-.war 38;5;9
-.ear 38;5;9
-.sar 38;5;9
-.rar 38;5;9
-.ace 38;5;9
-.zoo 38;5;9
-.cpio 38;5;9
-.7z 38;5;9
-.rz 38;5;9
-
-# image formats (magenta)
-.jpg 38;5;13
-.jpeg 38;5;13
-.gif 38;5;13
-.bmp 38;5;13
-.pbm 38;5;13
-.pgm 38;5;13
-.ppm 38;5;13
-.tga 38;5;13
-.xbm 38;5;13
-.xpm 38;5;13
-.tif 38;5;13
-.tiff 38;5;13
-.png 38;5;13
-.svg 38;5;13
-.svgz 38;5;13
-.mng 38;5;13
-.pcx 38;5;13
-.mov 38;5;13
-.mpg 38;5;13
-.mpeg 38;5;13
-.m2v 38;5;13
-.mkv 38;5;13
-.ogm 38;5;13
-.mp4 38;5;13
-.m4v 38;5;13
-.mp4v 38;5;13
-.vob 38;5;13
-.qt 38;5;13
-.nuv 38;5;13
-.wmv 38;5;13
-.asf 38;5;13
-.rm 38;5;13
-.rmvb 38;5;13
-.flc 38;5;13
-.avi 38;5;13
-.fli 38;5;13
-.flv 38;5;13
-.gl 38;5;13
-.dl 38;5;13
-.xcf 38;5;13
-.xwd 38;5;13
-.yuv 38;5;13
-.cgm 38;5;13
-.emf 38;5;13
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axv 38;5;13
-.anx 38;5;13
-.ogv 38;5;13
-.ogx 38;5;13
-
-# audio formats (cyan)
-.aac 38;5;45
-.au 38;5;45
-.flac 38;5;45
-.mid 38;5;45
-.midi 38;5;45
-.mka 38;5;45
-.mp3 38;5;45
-.mpc 38;5;45
-.ogg 38;5;45
-.ra 38;5;45
-.wav 38;5;45
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axa 38;5;45
-.oga 38;5;45
-.spx 38;5;45
-.xspf 38;5;45
-
-# colorize basic documents as well (brown)
-.pdf 00;33
-.ps 00;33
-.ps.gz 00;33
-.txt 00;33
-.patch 00;33
-.diff 00;33
-.log 00;33
-.tex 00;33
-.xls 00;33
-.xlsx 00;33
-.ppt 00;33
-.pptx 00;33
-.rtf 00;33
-.doc 00;33
-.docx 00;33
-.odt 00;33
-.ods 00;33
-.odp 00;33
-.xml 00;33
-.epub 00;33
-.abw 00;33
-.htm 00;33
-.html 00;33
-.shtml 00;33
-.wpd 00;33
diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor
deleted file mode 100644
index 4456a8c..0000000
--- a/coreutils-DIR_COLORS.lightbgcolor
+++ /dev/null
@@ -1,222 +0,0 @@
-# Configuration file for the color ls utility - modified for gray backgrounds
-# Synchronized with coreutils 8.5 dircolors
-# This file goes in the /etc directory, and must be world readable.
-# You can copy this file to .dir_colors in your $HOME directory to override
-# the system defaults.
-
-# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not
-# pipes. 'all' adds color characters to all output. 'none' shuts colorization
-# off.
-COLOR tty
-
-# Extra command line options for ls go here.
-# Basically these ones are:
-# -F = show '/' for dirs, '*' for executables, etc.
-# -T 0 = don't trust tab spacing when formatting ls output.
-OPTIONS -F -T 0
-
-# Below, there should be one TERM entry for each termtype that is colorizable
-TERM linux
-TERM console
-TERM con132x25
-TERM con132x30
-TERM con132x43
-TERM con132x60
-TERM con80x25
-TERM con80x28
-TERM con80x30
-TERM con80x43
-TERM con80x50
-TERM con80x60
-TERM cons25
-TERM xterm
-TERM xterm-16color
-TERM xterm-88color
-TERM xterm-256color
-TERM rxvt
-TERM rxvt-256color
-TERM rxvt-unicode
-TERM rxvt-unicode-256color
-TERM rxvt-unicode256
-TERM xterm-color
-TERM color-xterm
-TERM vt100
-TERM dtterm
-TERM color_xterm
-
-# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output)
-EIGHTBIT 1
-
-# Below are the color init strings for the basic file types. A color init
-# string consists of one or more of the following numeric codes:
-# Attribute codes:
-# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
-# Text color codes:
-# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
-# Background color codes:
-# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
-#NORMAL 00 # no color code at all
-#FILE 00 # normal file, use no color at all
-RESET 0
-DIR 00;34 # directory
-LINK 00;36 # symbolic link (If you set this to 'target' instead of a
- # numerical value, the color is as for the file pointed to.)
-MULTIHARDLINK 00 # regular file with more than one link
-FIFO 40;33 # pipe
-SOCK 00;35 # socket
-DOOR 00;35 # door
-BLK 40;33;01 # block device driver
-CHR 40;33;01 # character device driver
-ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file
-MISSING 01;05;37;41 # ... and the files they point to
-SETUID 37;41 # file that is setuid (u+s)
-SETGID 30;43 # file that is setgid (g+s)
-CAPABILITY 30;41 # file with capability
-STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w)
-OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
-STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
-
-
-# This is for files with execute permission:
-EXEC 00;32
-
-# List any file extensions like '.gz' or '.tar' that you would like ls
-# to colorize below. Put the extension, a space, and the color init string.
-# (and any comments you want to add after a '#')
-#.cmd 00;32 # executables (green)
-#.exe 00;32
-#.com 00;32
-#.btm 00;32
-#.bat 00;32
-#.sh 00;32
-#.csh 00;32
- # archives or compressed (red)
-.tar 00;31
-.tgz 00;31
-.arj 00;31
-.taz 00;31
-.lzh 00;31
-.lzma 00;31
-.tlz 00;31
-.txz 00;31
-.zip 00;31
-.z 00;31
-.Z 00;31
-.dz 00;31
-.gz 00;31
-.lz 00;31
-.xz 00;31
-.bz2 00;31
-.tbz 00;31
-.tbz2 00;31
-.bz 00;31
-.tz 00;31
-.deb 00;31
-.rpm 00;31
-.jar 00;31
-.war 00;31
-.ear 00;31
-.sar 00;31
-.rar 00;31
-.ace 00;31
-.zoo 00;31
-.cpio 00;31
-.7z 00;31
-.rz 00;31
-# image formats (magenta)
-.jpg 00;35
-.jpeg 00;35
-.gif 00;35
-.bmp 00;35
-.pbm 00;35
-.pgm 00;35
-.ppm 00;35
-.tga 00;35
-.xbm 00;35
-.xpm 00;35
-.tif 00;35
-.tiff 00;35
-.png 00;35
-.svg 00;35
-.svgz 00;35
-.mng 00;35
-.pcx 00;35
-.mov 00;35
-.mpg 00;35
-.mpeg 00;35
-.m2v 00;35
-.mkv 00;35
-.ogm 00;35
-.mp4 00;35
-.m4v 00;35
-.mp4v 00;35
-.vob 00;35
-.qt 00;35
-.nuv 00;35
-.wmv 00;35
-.asf 00;35
-.rm 00;35
-.rmvb 00;35
-.flc 00;35
-.avi 00;35
-.fli 00;35
-.flv 00;35
-.gl 00;35
-.dl 00;35
-.xcf 00;35
-.xwd 00;35
-.yuv 00;35
-.cgm 00;35
-.emf 00;35
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axv 00;35
-.anx 00;35
-.ogv 00;35
-.ogx 00;35
-
-# audio formats (cyan)
-.aac 00;36
-.au 00;36
-.flac 00;36
-.mid 00;36
-.midi 00;36
-.mka 00;36
-.mp3 00;36
-.mpc 00;36
-.ogg 00;36
-.ra 00;36
-.wav 00;36
-
-# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
-.axa 00;36
-.oga 00;36
-.spx 00;36
-.xspf 00;36
-
-# colorize basic documents (brown)
-.pdf 00;33
-.ps 00;33
-.ps.gz 00;33
-.txt 00;33
-.patch 00;33
-.diff 00;33
-.log 00;33
-.tex 00;33
-.xls 00;33
-.xlsx 00;33
-.ppt 00;33
-.pptx 00;33
-.rtf 00;33
-.doc 00;33
-.docx 00;33
-.odt 00;33
-.ods 00;33
-.odp 00;33
-.xml 00;33
-.epub 00;33
-.abw 00;33
-.htm 00;33
-.html 00;33
-.shtml 00;33
-.wpd 00;33
diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh
index e244afb..66ec2fa 100755
--- a/coreutils-colorls.csh
+++ b/coreutils-colorls.csh
@@ -1,3 +1,6 @@
+# skip everything for non-interactive shells
+if (! $?prompt) exit
+
# color-ls initialization
if ( $?USER_LS_COLORS ) then
if ( "$USER_LS_COLORS" != "" ) then
@@ -10,15 +13,11 @@ endif
alias ll 'ls -l'
alias l. 'ls -d .*'
set COLORS=/etc/DIR_COLORS
+
if ($?TERM) then
if ( -e "/etc/DIR_COLORS.$TERM" ) then
set COLORS="/etc/DIR_COLORS.$TERM"
endif
- if ( -e "/etc/DIR_COLORS.256color" ) then
- if ( "`tput colors`" == "256" ) then
- set COLORS=/etc/DIR_COLORS.256color
- endif
- endif
endif
if ( -f ~/.dircolors ) set COLORS=~/.dircolors
if ( -f ~/.dir_colors ) set COLORS=~/.dir_colors
@@ -26,18 +25,37 @@ if ($?TERM) then
if ( -f ~/.dircolors."$TERM" ) set COLORS=~/.dircolors."$TERM"
if ( -f ~/.dir_colors."$TERM" ) set COLORS=~/.dir_colors."$TERM"
endif
+set INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`"
if ( ! -e "$COLORS" ) exit
-eval "`dircolors -c $COLORS`"
+set _tmp="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`"
+#if mktemp fails, exit when include was active, otherwise use $COLORS file
+if ( "$_tmp" == '' ) then
+ if ( "$INCLUDE" == '' ) then
+ eval "`/usr/bin/dircolors -c $COLORS`"
+ endif
+ goto cleanup
+endif
+
+if ( "$INCLUDE" != '' ) /usr/bin/cat "$INCLUDE" >> $_tmp
+/usr/bin/grep -v '^INCLUDE' "$COLORS" >> $_tmp
+
+eval "`/usr/bin/dircolors -c $_tmp`"
+
+/usr/bin/rm -f $_tmp
if ( "$LS_COLORS" == '' ) exit
-set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS`
+cleanup:
+set color_none=`/usr/bin/sed -n '/^COLOR.*none/Ip' < $COLORS`
if ( "$color_none" != '' ) then
unset color_none
exit
endif
unset color_none
+unset _tmp
+unset INCLUDE
+unset COLORS
finish:
alias ll 'ls -l --color=auto'
diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh
index dc5c223..5162f1e 100755
--- a/coreutils-colorls.sh
+++ b/coreutils-colorls.sh
@@ -1,40 +1,53 @@
# color-ls initialization
+# Skip all for noninteractive shells.
+[ ! -t 0 ] && return
+
#when USER_LS_COLORS defined do not override user LS_COLORS, but use them.
if [ -z "$USER_LS_COLORS" ]; then
alias ll='ls -l' 2>/dev/null
alias l.='ls -d .*' 2>/dev/null
-
- # Skip the rest for noninteractive shells.
- [ -z "$PS1" ] && return
-
+ INCLUDE=
COLORS=
for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \
"$HOME/.dir_colors" "$HOME/.dircolors"; do
- [ -e "$colors" ] && COLORS="$colors" && break
+ [ -e "$colors" ] && COLORS="$colors" && \
+ INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`" && \
+ break
done
- [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \
- [ "x`tty -s && tput colors 2>/dev/null`" = "x256" ] && \
- COLORS="/etc/DIR_COLORS.256color"
+ [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \
+ COLORS="/etc/DIR_COLORS.$TERM"
- if [ -z "$COLORS" ]; then
- for colors in "/etc/DIR_COLORS.$TERM" "/etc/DIR_COLORS" ; do
- [ -e "$colors" ] && COLORS="$colors" && break
- done
- fi
+ [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \
+ COLORS="/etc/DIR_COLORS"
# Existence of $COLORS already checked above.
[ -n "$COLORS" ] || return
- eval "`dircolors --sh "$COLORS" 2>/dev/null`"
+ if [ -e "$INCLUDE" ];
+ then
+ TMP="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`"
+ [ -z "$TMP" ] && return
+
+ /usr/bin/cat "$INCLUDE" >> $TMP
+ /usr/bin/grep -v '^INCLUDE' "$COLORS" >> $TMP
+
+ eval "`/usr/bin/dircolors --sh $TMP 2>/dev/null`"
+ /usr/bin/rm -f $TMP
+ else
+ eval "`/usr/bin/dircolors --sh $COLORS 2>/dev/null`"
+ fi
+
[ -z "$LS_COLORS" ] && return
- grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return
+ /usr/bin/grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return
fi
+unset TMP COLORS INCLUDE
+
alias ll='ls -l --color=auto' 2>/dev/null
alias l.='ls -d .* --color=auto' 2>/dev/null
alias ls='ls --color=auto' 2>/dev/null
diff --git a/coreutils-cpZ-deprecate.patch b/coreutils-cpZ-deprecate.patch
deleted file mode 100644
index 713b7c5..0000000
--- a/coreutils-cpZ-deprecate.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff -urNp coreutils-8.12-orig/src/copy.c coreutils-8.12/src/copy.c
---- coreutils-8.12-orig/src/copy.c 2011-08-11 16:05:15.432485738 +0200
-+++ coreutils-8.12/src/copy.c 2011-08-11 16:14:28.660360607 +0200
-@@ -850,7 +850,7 @@ copy_reg (char const *src_name, char con
- 1) the src context may prohibit writing, and
- 2) because it's more consistent to use the same context
- that is used when the destination file doesn't already exist. */
-- if (x->preserve_security_context && 0 <= dest_desc)
-+ if ((x->set_security_context || x->preserve_security_context) && 0 <= dest_desc)
- {
- bool all_errors = (!x->data_copy_required
- || x->require_preserve_context);
-diff -urNp coreutils-8.12-orig/src/cp.c coreutils-8.12/src/cp.c
---- coreutils-8.12-orig/src/cp.c 2011-08-11 16:05:15.435486976 +0200
-+++ coreutils-8.12/src/cp.c 2011-08-11 16:16:56.408644526 +0200
-@@ -1119,6 +1119,7 @@ main (int argc, char **argv)
- exit( 1 );
- }
- x.set_security_context = true;
-+ (void) fprintf(stderr, _("Warning, -Z/--context option is deprecated and will be removed soon!\nPlease use 'install' utility instead of cp for this functionality.\n"));
- /* if there's a security_context given set new path
- components to that context, too */
- if ( setfscreatecon(optarg) < 0 ) {
diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch
index 1bc8c40..341ee2c 100644
--- a/coreutils-df-direct.patch
+++ b/coreutils-df-direct.patch
@@ -1,64 +1,77 @@
-diff -urNp coreutils-8.11-orig/doc/coreutils.texi coreutils-8.11/doc/coreutils.texi
---- coreutils-8.11-orig/doc/coreutils.texi 2011-04-12 12:07:43.000000000 +0200
-+++ coreutils-8.11/doc/coreutils.texi 2011-04-14 09:53:43.764309420 +0200
-@@ -10409,6 +10409,13 @@ pseudo-file-systems, such as automounter
- Scale sizes by @var{size} before printing them (@pxref{Block size}).
- For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes.
+From 91be1a584108a6a3d96f64382bbf206c4213b3db Mon Sep 17 00:00:00 2001
+From: Kamil Dudka
+Date: Mon, 29 Mar 2010 17:20:34 +0000
+Subject: [PATCH] coreutils-df-direct.patch
+
+---
+ doc/coreutils.texi | 7 ++++++
+ src/df.c | 34 ++++++++++++++++++++++++++--
+ tests/df/direct.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 94 insertions(+), 2 deletions(-)
+ create mode 100755 tests/df/direct.sh
+
+diff --git a/doc/coreutils.texi b/doc/coreutils.texi
+index b420606..0ccb368 100644
+--- a/doc/coreutils.texi
++++ b/doc/coreutils.texi
+@@ -12597,6 +12597,13 @@ some systems (notably Solaris), doing this yields more up to date results,
+ but in general this option makes @command{df} much slower, especially when
+ there are many or very busy file systems.
-+@itemx --direct
++@item --direct
+@opindex --direct
+@cindex direct statfs for a file
+Do not resolve mount point and show statistics directly for a file. It can be
+especially useful for NFS mount points if there is a boundary between two
+storage policies behind the mount point.
+
- @itemx --total
+ @item --total
@opindex --total
- @cindex grand total of disk size, usage and available space
-diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c
---- coreutils-8.11-orig/src/df.c 2011-04-12 12:07:43.000000000 +0200
-+++ coreutils-8.11/src/df.c 2011-04-14 10:37:44.208308771 +0200
-@@ -112,6 +112,9 @@ static bool print_type;
+ @cindex grand total of file system size, usage and available space
+diff --git a/src/df.c b/src/df.c
+index 75e638c..ef9f0a7 100644
+--- a/src/df.c
++++ b/src/df.c
+@@ -121,6 +121,9 @@ static bool print_type;
/* If true, print a grand total at the end. */
static bool print_grand_total;
+/* If true, show statistics for a file instead of mount point. */
+static bool direct_statfs;
+
- /* Grand total data. */
+ /* Grand total data. */
static struct fs_usage grand_fsu;
-@@ -166,13 +169,15 @@ static size_t nrows;
- enum
- {
+@@ -248,13 +251,15 @@ enum
NO_SYNC_OPTION = CHAR_MAX + 1,
-- SYNC_OPTION
-+ SYNC_OPTION,
+ SYNC_OPTION,
+ TOTAL_OPTION,
+- OUTPUT_OPTION
++ OUTPUT_OPTION,
+ DIRECT_OPTION
};
static struct option const long_options[] =
{
- {"all", no_argument, NULL, 'a'},
- {"block-size", required_argument, NULL, 'B'},
-+ {"direct", no_argument, NULL, DIRECT_OPTION},
- {"inodes", no_argument, NULL, 'i'},
- {"human-readable", no_argument, NULL, 'h'},
- {"si", no_argument, NULL, 'H'},
-@@ -259,7 +264,11 @@ get_header (void)
- }
+ {"all", no_argument, nullptr, 'a'},
+ {"block-size", required_argument, nullptr, 'B'},
++ {"direct", no_argument, nullptr, DIRECT_OPTION},
+ {"inodes", no_argument, nullptr, 'i'},
+ {"human-readable", no_argument, nullptr, 'h'},
+ {"si", no_argument, nullptr, 'H'},
+@@ -571,7 +576,10 @@ get_header (void)
+ for (idx_t col = 0; col < ncolumns; col++)
+ {
+ char *cell;
+- char const *header = _(columns[col]->caption);
++ char const *header = (columns[col]->field == TARGET_FIELD
++ && direct_statfs)?
++ _("File") :
++ _(columns[col]->caption);
- char *cell = NULL;
-- char const *header = _(headers[field][header_mode]);
-+
-+ char const *header = (field == MNT_FIELD && direct_statfs)?
-+ _("File") :
-+ _(headers[field][header_mode]);
-+
- if (!header)
- header = _(headers[field][DEFAULT_MODE]);
-
-@@ -757,6 +766,17 @@ get_point (const char *point, const stru
+ if (columns[col]->field == SIZE_FIELD
+ && (header_mode == DEFAULT_MODE
+@@ -1446,6 +1454,17 @@ get_point (char const *point, const struct stat *statp)
static void
get_entry (char const *name, struct stat const *statp)
{
@@ -66,25 +79,25 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c
+ {
+ char *resolved = canonicalize_file_name (name);
+ if (resolved)
-+ {
-+ get_dev (NULL, resolved, NULL, NULL, false, false, NULL, false);
-+ free (resolved);
-+ return;
-+ }
++ {
++ get_dev (NULL, resolved, name, NULL, NULL, false, false, NULL, false);
++ free (resolved);
++ return;
++ }
+ }
+
if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode))
- && get_disk (name))
+ && get_device (name))
return;
-@@ -825,6 +845,7 @@ Mandatory arguments to long options are
- -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\
- `-BM' prints sizes in units of 1,048,576 bytes.\n\
- See SIZE format below.\n\
+@@ -1516,6 +1535,7 @@ or all file systems by default.\n\
+ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\
+ '-BM' prints sizes in units of 1,048,576 bytes;\n\
+ see SIZE format below\n\
+ --direct show statistics for a file instead of mount point\n\
- --total produce a grand total\n\
- -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\
- \n\
-@@ -901,6 +922,9 @@ main (int argc, char **argv)
+ -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\
+ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\
+ "), stdout);
+@@ -1610,6 +1630,9 @@ main (int argc, char **argv)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
break;
@@ -92,25 +105,27 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c
+ direct_statfs = true;
+ break;
case 'i':
- inode_format = true;
- break;
-@@ -961,6 +985,13 @@ main (int argc, char **argv)
+ if (header_mode == OUTPUT_MODE)
+ {
+@@ -1706,6 +1729,13 @@ main (int argc, char **argv)
}
}
+ if (direct_statfs && show_local_fs)
+ {
+ error (0, 0, _("options --direct and --local (-l) are mutually "
-+ "exclusive"));
++ "exclusive"));
+ usage (EXIT_FAILURE);
+ }
+
if (human_output_opts == -1)
{
if (posix_format)
-diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct
---- coreutils-8.11-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.11/tests/df/direct 2011-04-14 09:53:43.767400034 +0200
+diff --git a/tests/df/direct.sh b/tests/df/direct.sh
+new file mode 100755
+index 0000000..8e4cfb8
+--- /dev/null
++++ b/tests/df/direct.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+# Ensure "df --direct" works as documented
@@ -167,14 +182,6 @@ diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct
+compare file_out file_exp || fail=1
+
+Exit $fail
-diff -urNp coreutils-8.11-orig/tests/Makefile.am coreutils-8.11/tests/Makefile.am
---- coreutils-8.11-orig/tests/Makefile.am 2011-04-14 09:53:13.666324768 +0200
-+++ coreutils-8.11/tests/Makefile.am 2011-04-14 09:53:43.768432620 +0200
-@@ -362,6 +362,7 @@ TESTS = \
- dd/stderr \
- dd/unblock \
- dd/unblock-sync \
-+ df/direct \
- df/total-verify \
- du/2g \
- du/8gb \
+--
+2.52.0
+
diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch
deleted file mode 100644
index 86bbcef..0000000
--- a/coreutils-getgrouplist.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-diff --git a/lib/getugroups.c b/lib/getugroups.c
-index 299bae6..8ece29b 100644
---- a/lib/getugroups.c
-+++ b/lib/getugroups.c
-@@ -19,6 +19,9 @@
-
- #include
-
-+/* We do not need this code if getgrouplist(3) is available. */
-+#ifndef HAVE_GETGROUPLIST
-+
- #include "getugroups.h"
-
- #include
-@@ -123,3 +126,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username,
- }
-
- #endif /* HAVE_GRP_H */
-+#endif /* have getgrouplist */
-diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
-index 76474c2..0a9d221 100644
---- a/lib/mgetgroups.c
-+++ b/lib/mgetgroups.c
-@@ -115,9 +115,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
- /* else no username, so fall through and use getgroups. */
- #endif
-
-- max_n_groups = (username
-- ? getugroups (0, NULL, username, gid)
-- : getgroups (0, NULL));
-+ if (!username)
-+ max_n_groups = getgroups(0, NULL);
-+ else
-+ {
-+#ifdef HAVE_GETGROUPLIST
-+ max_n_groups = 0;
-+ getgrouplist (username, gid, NULL, &max_n_groups);
-+#else
-+ max_n_groups = getugroups (0, NULL, username, gid);
-+#endif
-+ }
-
- /* If we failed to count groups because there is no supplemental
- group support, then return an array containing just GID.
-@@ -139,10 +147,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
- if (g == NULL)
- return -1;
-
-- ng = (username
-- ? getugroups (max_n_groups, g, username, gid)
-- : getgroups (max_n_groups - (gid != (gid_t) -1),
-- g + (gid != (gid_t) -1)));
-+ if (!username)
-+ ng = getgroups (max_n_groups - (gid != (gid_t)-1), g + (gid != (gid_t)-1));
-+ else
-+ {
-+#ifdef HAVE_GETGROUPLIST
-+ int e;
-+ ng = max_n_groups;
-+ while ((e = getgrouplist (username, gid, g, &ng)) == -1
-+ && ng > max_n_groups)
-+ {
-+ max_n_groups = ng;
-+ g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T));
-+ }
-+ if (e == -1)
-+ ng = -1;
-+#else
-+ ng = getugroups (max_n_groups, g, username, gid);
-+#endif
-+ }
-
- if (ng < 0)
- {
-diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
-index 62777c7..5180243 100644
---- a/m4/jm-macros.m4
-+++ b/m4/jm-macros.m4
-@@ -78,6 +78,7 @@
- fchown
- fchmod
- ftruncate
-+ getgrouplist
- iswspace
- mkfifo
- mbrlen
diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch
index 55f12e7..83579e9 100644
--- a/coreutils-i18n.patch
+++ b/coreutils-i18n.patch
@@ -1,9 +1,80 @@
-diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h
---- coreutils-8.15-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100
-+++ coreutils-8.15/lib/linebuffer.h 2013-01-30 13:40:37.339145671 +0100
-@@ -21,6 +21,11 @@
+From a81b096084524e9aeef5e8b81fc829eb9efec581 Mon Sep 17 00:00:00 2001
+From: rpm-build
+Date: Wed, 30 Aug 2023 17:19:58 +0200
+Subject: [PATCH] coreutils-i18n.patch
+
+---
+ bootstrap.conf | 2 +
+ configure.ac | 6 +
+ lib/linebuffer.h | 8 +
+ lib/mbfile.c | 20 +
+ lib/mbfile.h | 283 +++++++++++++
+ m4/mbfile.m4 | 16 +
+ src/cut.c | 508 +++++++++++++++++++++--
+ src/expand-common.c | 114 ++++++
+ src/expand-common.h | 12 +
+ src/expand.c | 90 +++-
+ src/local.mk | 4 +-
+ src/pr.c | 443 ++++++++++++++++++--
+ src/sort.c | 791 +++++++++++++++++++++++++++++++++---
+ src/unexpand.c | 101 ++++-
+ tests/Coreutils.pm | 3 +
+ tests/expand/mb.sh | 183 +++++++++
+ tests/i18n/sort.sh | 29 ++
+ tests/local.mk | 4 +
+ tests/misc/expand.pl | 42 ++
+ tests/misc/sort-mb-tests.sh | 45 ++
+ tests/misc/unexpand.pl | 39 ++
+ tests/pr/pr-tests.pl | 49 +++
+ tests/sort/sort-merge.pl | 42 ++
+ tests/sort/sort.pl | 40 +-
+ tests/unexpand/mb.sh | 172 ++++++++
+ 25 files changed, 2879 insertions(+), 167 deletions(-)
+ create mode 100644 lib/mbfile.c
+ create mode 100644 lib/mbfile.h
+ create mode 100644 m4/mbfile.m4
+ create mode 100644 tests/expand/mb.sh
+ create mode 100644 tests/i18n/sort.sh
+ create mode 100644 tests/misc/sort-mb-tests.sh
+ create mode 100644 tests/unexpand/mb.sh
+
+diff --git a/bootstrap.conf b/bootstrap.conf
+index ec68ac8..ec2fbbe 100644
+--- a/bootstrap.conf
++++ b/bootstrap.conf
+@@ -171,6 +171,8 @@ gnulib_modules="
+ malloc-gnu
+ manywarnings
+ mbbuf
++ mbchar
++ mbfile
+ mbrlen
+ mbrtoc32
+ mbrtowc
+diff --git a/configure.ac b/configure.ac
+index 5e99ef3..ac07577 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -465,6 +465,12 @@ fi
+ # I'm leaving it here for now. This whole thing needs to be modernized...
+ gl_WINSIZE_IN_PTEM
+
++gl_MBFILE
++dnl Do not use gl_MODULE_INDICATOR([mbfile]) here: we don't want 'struct mbchar'
++dnl to have a different size in lib/ than in tests/.
++AC_DEFINE([GNULIB_MBFILE], [1],
++ [Define to 1 if the gnulib module 'mbfile' is in use.])
++
+ gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H
+
+ if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \
+diff --git a/lib/linebuffer.h b/lib/linebuffer.h
+index ca56f80..509b7e6 100644
+--- a/lib/linebuffer.h
++++ b/lib/linebuffer.h
+@@ -27,6 +27,11 @@ extern "C" {
+ #endif
- # include
+/* Get mbstate_t. */
+# if HAVE_WCHAR_H
@@ -13,9 +84,9 @@ diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h
/* A 'struct linebuffer' holds a line of text. */
struct linebuffer
-@@ -28,6 +33,9 @@ struct linebuffer
- size_t size; /* Allocated. */
- size_t length; /* Used. */
+@@ -34,6 +39,9 @@ struct linebuffer
+ idx_t size; /* Allocated. */
+ idx_t length; /* Used. */
char *buffer;
+# if HAVE_WCHAR_H
+ mbstate_t state;
@@ -23,11 +94,349 @@ diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h
};
/* Initialize linebuffer LINEBUFFER for use. */
-diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
---- coreutils-8.15-orig/src/cut.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/cut.c 2013-01-30 13:40:37.341145459 +0100
-@@ -28,6 +28,11 @@
- #include
+diff --git a/lib/mbfile.c b/lib/mbfile.c
+new file mode 100644
+index 0000000..f4e3e77
+--- /dev/null
++++ b/lib/mbfile.c
+@@ -0,0 +1,20 @@
++/* Multibyte character I/O: macros for multi-byte encodings.
++ Copyright (C) 2012-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation, either version 3 of the
++ License, or (at your option) any later version.
++
++ This file is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see . */
++
++#include
++
++#define MBFILE_INLINE _GL_EXTERN_INLINE
++#include "mbfile.h"
+diff --git a/lib/mbfile.h b/lib/mbfile.h
+new file mode 100644
+index 0000000..c852f31
+--- /dev/null
++++ b/lib/mbfile.h
+@@ -0,0 +1,283 @@
++/* Multibyte character I/O: macros for multi-byte encodings.
++ Copyright (C) 2001, 2005, 2009-2025 Free Software Foundation, Inc.
++
++ This file is free software: you can redistribute it and/or modify
++ it under the terms of the GNU Lesser General Public License as
++ published by the Free Software Foundation, either version 3 of the
++ License, or (at your option) any later version.
++
++ This file is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with this program. If not, see . */
++
++/* Written by Mitsuru Chinen
++ and Bruno Haible . */
++
++/* The macros in this file implement multi-byte character input from a
++ stream.
++
++ mb_file_t
++ is the type for multibyte character input stream, usable for variable
++ declarations.
++
++ mbf_char_t
++ is the type for multibyte character or EOF, usable for variable
++ declarations.
++
++ mbf_init (mbf, stream)
++ initializes the MB_FILE for reading from stream.
++
++ mbf_getc (mbc, mbf)
++ reads the next multibyte character from mbf and stores it in mbc.
++
++ mb_iseof (mbc)
++ returns true if mbc represents the EOF value.
++
++ Here are the function prototypes of the macros.
++
++ extern void mbf_init (mb_file_t mbf, FILE *stream);
++ extern void mbf_getc (mbf_char_t mbc, mb_file_t mbf);
++ extern bool mb_iseof (const mbf_char_t mbc);
++ */
++
++#ifndef _MBFILE_H
++#define _MBFILE_H 1
++
++/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */
++#if !_GL_CONFIG_H_INCLUDED
++ #error "Please include config.h first."
++#endif
++
++#include
++#include
++#include
++#include
++#include
++
++#include "mbchar.h"
++
++_GL_INLINE_HEADER_BEGIN
++#ifndef MBFILE_INLINE
++# define MBFILE_INLINE _GL_INLINE
++#endif
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++/* Guarantee two characters of pushback. */
++#define MBFILE_MAX_PUSHBACK 2
++
++struct mbfile_multi {
++ FILE *fp;
++ bool eof_seen;
++ unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */
++ mbstate_t state;
++ unsigned int bufcount;
++ char buf[MBCHAR_BUF_SIZE];
++ struct mbchar pushback[MBFILE_MAX_PUSHBACK];
++};
++
++MBFILE_INLINE void
++mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf)
++{
++ unsigned int new_bufcount;
++ size_t bytes;
++
++ /* Return character pushed back, if there is one. */
++ if (mbf->pushback_count > 0)
++ {
++ mb_copy (mbc, &mbf->pushback[mbf->pushback_count - 1]);
++ mbf->pushback_count--;
++ return;
++ }
++
++ /* If EOF has already been seen, don't use getc. This matters if
++ mbf->fp is connected to an interactive tty. */
++ if (mbf->eof_seen)
++ goto eof;
++
++ new_bufcount = mbf->bufcount;
++
++ /* If mbf->state is not in an initial state, some more 32-bit wide character
++ may be hiding in the state. We need to call mbrtoc32 again. */
++ #if GNULIB_MBRTOC32_REGULAR
++ assert (mbsinit (&mbf->state));
++ #else
++ if (mbsinit (&mbf->state))
++ #endif
++ {
++ /* Before using mbrtoc32, we need at least one byte. */
++ if (new_bufcount == 0)
++ {
++ int c = getc (mbf->fp);
++ if (c == EOF)
++ {
++ mbf->eof_seen = true;
++ goto eof;
++ }
++ mbf->buf[0] = (unsigned char) c;
++ new_bufcount++;
++ }
++
++ /* Handle most ASCII characters quickly, without calling mbrtoc32(). */
++ if (new_bufcount == 1 && is_basic (mbf->buf[0]))
++ {
++ /* These characters are part of the POSIX portable character set.
++ For most of them, namely those in the ISO C basic character set,
++ ISO C 99 guarantees that their wide character code is identical to
++ their char code. For the few other ones, this is the case as well,
++ in all locale encodings that are in use. The 32-bit wide character
++ code is the same as well. */
++ mbc->wc = mbc->buf[0] = mbf->buf[0];
++ mbc->wc_valid = true;
++ mbc->ptr = &mbc->buf[0];
++ mbc->bytes = 1;
++ mbf->bufcount = 0;
++ return;
++ }
++ }
++
++ /* Use mbrtoc32 on an increasing number of bytes. Read only as many bytes
++ from mbf->fp as needed. This is needed to give reasonable interactive
++ behaviour when mbf->fp is connected to an interactive tty. */
++ for (;;)
++ {
++ /* Feed the bytes one by one into mbrtoc32. */
++ bytes = mbrtoc32 (&mbc->wc, &mbf->buf[mbf->bufcount], new_bufcount - mbf->bufcount, &mbf->state);
++
++ if (bytes == (size_t) -1)
++ {
++ /* An invalid multibyte sequence was encountered. */
++ mbf->bufcount = new_bufcount;
++ /* Return a single byte. */
++ bytes = 1;
++ mbc->wc_valid = false;
++ /* Allow the next invocation to continue from a sane state. */
++ mbszero (&mbf->state);
++ break;
++ }
++ else if (bytes == (size_t) -2)
++ {
++ /* An incomplete multibyte character. */
++ mbf->bufcount = new_bufcount;
++ if (mbf->bufcount == MBCHAR_BUF_SIZE)
++ {
++ /* An overlong incomplete multibyte sequence was encountered. */
++ /* Return a single byte. */
++ bytes = 1;
++ mbc->wc_valid = false;
++ break;
++ }
++ else
++ {
++ /* Read one more byte and retry mbrtoc32. */
++ int c = getc (mbf->fp);
++ if (c == EOF)
++ {
++ /* An incomplete multibyte character at the end. */
++ mbf->eof_seen = true;
++ bytes = new_bufcount;
++ mbc->wc_valid = false;
++ break;
++ }
++ mbf->buf[new_bufcount] = (unsigned char) c;
++ new_bufcount++;
++ }
++ }
++ else
++ {
++ #if !GNULIB_MBRTOC32_REGULAR
++ if (bytes == (size_t) -3)
++ {
++ /* The previous multibyte sequence produced an additional 32-bit
++ wide character. */
++ mbf->bufcount = new_bufcount;
++ bytes = 0;
++ }
++ else
++ #endif
++ {
++ bytes = mbf->bufcount + bytes;
++ mbf->bufcount = new_bufcount;
++ if (bytes == 0)
++ {
++ /* A null 32-bit wide character was encountered. */
++ bytes = 1;
++ assert (mbf->buf[0] == '\0');
++ assert (mbc->wc == 0);
++ }
++ }
++ mbc->wc_valid = true;
++ break;
++ }
++ }
++
++ /* Return the multibyte sequence mbf->buf[0..bytes-1]. */
++ mbc->ptr = &mbc->buf[0];
++ memcpy (&mbc->buf[0], &mbf->buf[0], bytes);
++ mbc->bytes = bytes;
++
++ mbf->bufcount -= bytes;
++ if (mbf->bufcount > 0)
++ {
++ /* It's not worth calling memmove() for so few bytes. */
++ unsigned int count = mbf->bufcount;
++ char *p = &mbf->buf[0];
++
++ do
++ {
++ *p = *(p + bytes);
++ p++;
++ }
++ while (--count > 0);
++ }
++ return;
++
++eof:
++ /* An mbchar_t with bytes == 0 is used to indicate EOF. */
++ mbc->ptr = NULL;
++ mbc->bytes = 0;
++ mbc->wc_valid = false;
++ return;
++}
++
++MBFILE_INLINE void
++mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf)
++{
++ if (mbf->pushback_count == MBFILE_MAX_PUSHBACK)
++ abort ();
++ mb_copy (&mbf->pushback[mbf->pushback_count], mbc);
++ mbf->pushback_count++;
++}
++
++typedef struct mbfile_multi mb_file_t;
++
++typedef mbchar_t mbf_char_t;
++
++#define mbf_init(mbf, stream) \
++ ((mbf).fp = (stream), \
++ (mbf).eof_seen = false, \
++ (mbf).pushback_count = 0, \
++ mbszero (&(mbf).state), \
++ (mbf).bufcount = 0)
++
++#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf))
++
++#define mbf_ungetc(mbc, mbf) mbfile_multi_ungetc (&(mbc), &(mbf))
++
++#define mb_iseof(mbc) ((mbc).bytes == 0)
++
++
++#ifdef __cplusplus
++}
++#endif
++
++_GL_INLINE_HEADER_END
++
++#endif /* _MBFILE_H */
+diff --git a/m4/mbfile.m4 b/m4/mbfile.m4
+new file mode 100644
+index 0000000..1d126e0
+--- /dev/null
++++ b/m4/mbfile.m4
+@@ -0,0 +1,16 @@
++# mbfile.m4
++# serial 7
++dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc.
++dnl This file is free software; the Free Software Foundation
++dnl gives unlimited permission to copy and/or distribute it,
++dnl with or without modifications, as long as this notice is preserved.
++dnl This file is offered as-is, without any warranty.
++
++dnl autoconf tests required for use of mbfile.h
++dnl From Bruno Haible.
++
++AC_DEFUN([gl_MBFILE],
++[
++ AC_REQUIRE([AC_TYPE_MBSTATE_T])
++ :
++])
+diff --git a/src/cut.c b/src/cut.c
+index f0effb9..36479d6 100644
+--- a/src/cut.c
++++ b/src/cut.c
+@@ -27,6 +27,11 @@
+ #include
#include
#include
+
@@ -37,10 +446,10 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+#endif
#include "system.h"
- #include "error.h"
-@@ -37,6 +42,18 @@
- #include "quote.h"
- #include "xstrndup.h"
+ #include "assure.h"
+@@ -35,6 +40,18 @@
+
+ #include "set-fields.h"
+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
+ installation; work around this configuration error. */
@@ -54,11 +463,11 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
+#endif
+
- /* The official name of this program (e.g., no `g' prefix). */
+ /* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "cut"
-@@ -72,6 +89,52 @@
- } \
+@@ -51,6 +68,52 @@
+ } \
while (0)
+/* Refill the buffer BUF to get a multibyte character. */
@@ -75,7 +484,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ while (0)
+
+/* Get wide character on BUFPOS. BUFPOS is not included after that.
-+ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */
++ If byte sequence is not valid as a character, CONVFAIL is true. Otherwise false. */
+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \
+ do \
+ { \
@@ -88,7 +497,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ } \
+ \
+ /* Get a wide character. */ \
-+ CONVFAIL = 0; \
++ CONVFAIL = false; \
+ state_bak = STATE; \
+ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \
+ \
@@ -96,7 +505,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ { \
+ case (size_t)-1: \
+ case (size_t)-2: \
-+ CONVFAIL++; \
++ CONVFAIL = true; \
+ STATE = state_bak; \
+ /* Fall througn. */ \
+ \
@@ -107,49 +516,39 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ } \
+ while (0)
+
- struct range_pair
- {
- size_t lo;
-@@ -90,7 +153,7 @@ static char *field_1_buffer;
+
+ /* Pointer inside RP. When checking if a byte or field is selected
+ by a finite range, we check if it is between CURRENT_RP.LO
+@@ -58,6 +121,9 @@
+ CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
+ static struct field_range_pair *current_rp;
+
++/* Length of the delimiter given as argument to -d. */
++size_t delimlen;
++
+ /* This buffer is used to support the semantics of the -s option
+ (or lack of same) when the specified field list includes (does
+ not include) the first field. In both of those cases, the entire
+@@ -70,6 +136,29 @@ static char *field_1_buffer;
/* The number of bytes allocated for FIELD_1_BUFFER. */
static size_t field_1_bufsize;
--/* The largest field or byte index used as an endpoint of a closed
-+/* The largest byte, character or field index used as an endpoint of a closed
- or degenerate range specification; this doesn't include the starting
- index of right-open-ended ranges. For example, with either range spec
- `2-5,9-', `2-3,5,9-' this variable would be set to 5. */
-@@ -102,10 +165,11 @@ static size_t eol_range_start;
-
- /* This is a bit vector.
- In byte mode, which bytes to output.
-+ In character mode, which characters to output.
- In field mode, which DELIM-separated fields to output.
-- Both bytes and fields are numbered starting with 1,
-+ Bytes, characters and fields are numbered starting with 1,
- so the zeroth bit of this array is unused.
-- A field or byte K has been selected if
-+ A byte, character or field K has been selected if
- (K <= MAX_RANGE_ENDPOINT and is_printable_field(K))
- || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */
- static unsigned char *printable_field;
-@@ -114,15 +178,25 @@ enum operating_mode
- {
- undefined_mode,
-
-- /* Output characters that are in the given bytes. */
++enum operating_mode
++ {
++ undefined_mode,
++
+ /* Output bytes that are at the given positions. */
- byte_mode,
-
++ byte_mode,
++
+ /* Output characters that are at the given positions. */
+ character_mode,
+
- /* Output the given delimeter-separated fields. */
- field_mode
- };
-
- static enum operating_mode operating_mode;
-
++ /* Output the given delimiter-separated fields. */
++ field_mode
++ };
++
++static enum operating_mode operating_mode;
++
+/* If nonzero, when in byte mode, don't split multibyte characters. */
+static int byte_mode_character_aware;
+
@@ -157,20 +556,37 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ if this program runs on multibyte locale. */
+static int force_singlebyte_mode;
+
- /* If true do not output lines containing no delimeter characters.
+ /* If true, do not output lines containing no delimiter characters.
Otherwise, all such lines are printed. This option is valid only
with field mode. */
-@@ -134,6 +208,9 @@ static bool complement;
+@@ -81,10 +170,16 @@ static bool complement;
- /* The delimeter character for field mode. */
+ /* The delimiter character for field mode. */
static unsigned char delim;
+#if HAVE_WCHAR_H
+static wchar_t wcdelim;
+#endif
- /* True if the --output-delimiter=STRING option was specified. */
- static bool output_delimiter_specified;
-@@ -207,7 +284,7 @@ Mandatory arguments to long options are
+ /* The delimiter for each line/record. */
+ static unsigned char line_delim = '\n';
+
++/* True if the --output-delimiter=STRING option was specified. */
++static bool output_delimiter_specified;
++
+ /* The length of output_delimiter_string. */
+ static size_t output_delimiter_length;
+
+@@ -92,9 +187,6 @@ static size_t output_delimiter_length;
+ string consisting of the input delimiter. */
+ static char *output_delimiter_string;
+
+-/* The output delimiter string contents, if the default. */
+-static char output_delimiter_default[1];
+-
+ /* True if we have ever read standard input. */
+ static bool have_read_stdin;
+
+@@ -148,7 +240,7 @@ Print selected parts of lines from each FILE to standard output.\n\
-f, --fields=LIST select only these fields; also print any line\n\
that contains no delimiter character, unless\n\
the -s option is specified\n\
@@ -179,54 +595,16 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
"), stdout);
fputs (_("\
--complement complement the set of selected bytes, characters\n\
-@@ -366,7 +443,7 @@ set_fields (const char *fieldstr)
- in_digits = false;
- /* Starting a range. */
- if (dash_found)
-- FATAL_ERROR (_("invalid byte or field list"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
- dash_found = true;
- fieldstr++;
-
-@@ -390,14 +467,16 @@ set_fields (const char *fieldstr)
- if (!rhs_specified)
+@@ -252,7 +344,7 @@ cut_bytes (FILE *stream)
+ next_item (&byte_idx);
+ if (print_kth (byte_idx))
+ {
+- if (output_delimiter_string != output_delimiter_default)
++ if (output_delimiter_specified)
{
- /* `n-'. From `initial' to end of line. */
-- eol_range_start = initial;
-+ if (eol_range_start == 0 ||
-+ (eol_range_start != 0 && eol_range_start > initial))
-+ eol_range_start = initial;
- field_found = true;
- }
- else
- {
- /* `m-n' or `-n' (1-n). */
- if (value < initial)
-- FATAL_ERROR (_("invalid decreasing range"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
-
- /* Is there already a range going to end of line? */
- if (eol_range_start != 0)
-@@ -477,6 +556,9 @@ set_fields (const char *fieldstr)
- if (operating_mode == byte_mode)
- error (0, 0,
- _("byte offset %s is too large"), quote (bad_num));
-+ else if (operating_mode == character_mode)
-+ error (0, 0,
-+ _("character offset %s is too large"), quote (bad_num));
- else
- error (0, 0,
- _("field number %s is too large"), quote (bad_num));
-@@ -487,7 +569,7 @@ set_fields (const char *fieldstr)
- fieldstr++;
- }
- else
-- FATAL_ERROR (_("invalid byte or field list"));
-+ FATAL_ERROR (_("invalid byte, character or field list"));
- }
-
- max_range_endpoint = 0;
-@@ -582,6 +664,77 @@ cut_bytes (FILE *stream)
+ if (print_delimiter && is_range_start_index (byte_idx))
+ {
+@@ -271,6 +363,82 @@ cut_bytes (FILE *stream)
}
}
@@ -242,7 +620,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+static void
+cut_characters_or_cut_bytes_no_split (FILE *stream)
+{
-+ int idx; /* number of bytes or characters in the line so far. */
++ uintmax_t idx; /* number of bytes or characters in the line so far. */
+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */
+ char *bufpos; /* Next read position of BUF. */
+ size_t buflen; /* The length of the byte sequence in buf. */
@@ -250,7 +628,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ size_t mblength; /* The byte size of a multibyte character which shows
+ as same character as WC. */
+ mbstate_t state; /* State of the stream. */
-+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */
++ bool convfail = false; /* true, when conversion failed. Otherwise false. */
+ /* Whether to begin printing delimiters between ranges for the current line.
+ Set after we've begun printing data corresponding to the first range. */
+ bool print_delimiter = false;
@@ -260,37 +638,42 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ bufpos = buf;
+ memset (&state, '\0', sizeof(mbstate_t));
+
++ current_rp = frp;
++
+ while (1)
+ {
+ REFILL_BUFFER (buf, bufpos, buflen, stream);
+
+ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail);
++ (void) convfail; /* ignore unused */
+
+ if (wc == WEOF)
+ {
+ if (idx > 0)
-+ putchar ('\n');
++ putchar (line_delim);
+ break;
+ }
-+ else if (wc == L'\n')
++ else if (wc == line_delim)
+ {
-+ putchar ('\n');
++ putchar (line_delim);
+ idx = 0;
+ print_delimiter = false;
++ current_rp = frp;
+ }
+ else
+ {
-+ bool range_start;
-+ bool *rs = output_delimiter_specified ? &range_start : NULL;
-+ idx += (operating_mode == byte_mode) ? mblength : 1;
-+ if (print_kth (idx, rs))
++ next_item (&idx);
++ if (print_kth (idx))
+ {
-+ if (rs && *rs && print_delimiter)
++ if (output_delimiter_specified)
+ {
-+ fwrite (output_delimiter_string, sizeof (char),
-+ output_delimiter_length, stdout);
-+ }
-+ print_delimiter = true;
++ if (print_delimiter && is_range_start_index (idx))
++ {
++ fwrite (output_delimiter_string, sizeof (char),
++ output_delimiter_length, stdout);
++ }
++ print_delimiter = true;
++ }
+ fwrite (bufpos, mblength, sizeof(char), stdout);
+ }
+ }
@@ -304,16 +687,17 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
/* Read from stream STREAM, printing to standard output any selected fields. */
static void
-@@ -704,13 +857,195 @@ cut_fields (FILE *stream)
+@@ -433,11 +601,218 @@ cut_fields (FILE *stream)
}
}
+-/* Process file FILE to standard output, using CUT_STREAM.
+#if HAVE_MBRTOWC
+static void
+cut_fields_mb (FILE *stream)
+{
+ int c;
-+ unsigned int field_idx;
++ uintmax_t field_idx;
+ int found_any_selected_field;
+ int buffer_first_field;
+ int empty_input;
@@ -324,7 +708,9 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ size_t mblength; /* The byte size of a multibyte character which shows
+ as same character as WC. */
+ mbstate_t state; /* State of the stream. */
-+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */
++ bool convfail = false; /* true, when conversion failed. Otherwise false. */
++
++ current_rp = frp;
+
+ found_any_selected_field = 0;
+ field_idx = 1;
@@ -348,7 +734,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ and the first field has been selected, or if non-delimited lines
+ must be suppressed and the first field has *not* been selected.
+ That is because a non-delimited line has exactly one field. */
-+ buffer_first_field = (suppress_non_delimited ^ !print_kth (1, NULL));
++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1));
+
+ while (1)
+ {
@@ -372,11 +758,11 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ buflen -= mblength;
+ bufpos += mblength;
+
-+ if (!convfail && (wc == L'\n' || wc == wcdelim))
++ if (!convfail && (wc == line_delim || wc == wcdelim))
+ break;
+ }
+
-+ if (len<=0 && wc == WEOF)
++ if (len <= 0 && wc == WEOF)
+ break;
+
+ /* If the first field extends to the end of line (it is not
@@ -392,24 +778,24 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ {
+ fwrite (field_1_buffer, sizeof (char), len, stdout);
+ /* Make sure the output line is newline terminated. */
-+ if (convfail || (!convfail && wc != L'\n'))
-+ putchar ('\n');
++ if (convfail || (!convfail && wc != line_delim))
++ putchar (line_delim);
+ }
+ continue;
+ }
+
-+ if (print_kth (1, NULL))
++ if (print_kth (1))
+ {
+ /* Print the field, but not the trailing delimiter. */
+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout);
+ found_any_selected_field = 1;
+ }
-+ ++field_idx;
++ next_item (&field_idx);
+ }
+
+ if (wc != WEOF)
+ {
-+ if (print_kth (field_idx, NULL))
++ if (print_kth (field_idx))
+ {
+ if (found_any_selected_field)
+ {
@@ -428,14 +814,14 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+
+ if (wc == WEOF)
+ break;
-+ else if (!convfail && (wc == wcdelim || wc == L'\n'))
++ else if (!convfail && (wc == wcdelim || wc == line_delim))
+ {
+ buflen -= mblength;
+ bufpos += mblength;
+ break;
+ }
+
-+ if (print_kth (field_idx, NULL))
++ if (print_kth (field_idx))
+ fwrite (bufpos, mblength, sizeof(char), stdout);
+
+ buflen -= mblength;
@@ -443,30 +829,29 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ }
+ }
+
-+ if ((!convfail || wc == L'\n') && buflen < 1)
++ if ((!convfail || wc == line_delim) && buflen < 1)
+ wc = WEOF;
+
+ if (!convfail && wc == wcdelim)
-+ ++field_idx;
-+ else if (wc == WEOF || (!convfail && wc == L'\n'))
++ next_item (&field_idx);
++ else if (wc == WEOF || (!convfail && wc == line_delim))
+ {
+ if (found_any_selected_field
+ || (!empty_input && !(suppress_non_delimited && field_idx == 1)))
-+ putchar ('\n');
++ putchar (line_delim);
+ if (wc == WEOF)
+ break;
+ field_idx = 1;
++ current_rp = frp;
+ found_any_selected_field = 0;
+ }
+ }
+}
+#endif
+
- static void
- cut_stream (FILE *stream)
- {
-- if (operating_mode == byte_mode)
-- cut_bytes (stream);
++static void
++cut_stream (FILE *stream)
++{
+#if HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
+ {
@@ -484,6 +869,19 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ break;
+
+ case field_mode:
++ if (delimlen == 1)
++ {
++ /* Check if we have utf8 multibyte locale, so we can use this
++ optimization because of uniqueness of characters, which is
++ not true for e.g. SJIS */
++ char * loc = setlocale(LC_CTYPE, NULL);
++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") ||
++ strstr (loc, "UTF8") || strstr (loc, "utf8")))
++ {
++ cut_fields (stream);
++ break;
++ }
++ }
+ cut_fields_mb (stream);
+ break;
+
@@ -491,8 +889,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ abort ();
+ }
+ }
- else
-- cut_fields (stream);
++ else
+#endif
+ {
+ if (operating_mode == field_mode)
@@ -500,32 +897,53 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ else
+ cut_bytes (stream);
+ }
- }
++}
++
++/* Process file FILE to standard output.
+ Return true if successful. */
- /* Process file FILE to standard output.
-@@ -762,6 +1097,8 @@ main (int argc, char **argv)
+ static bool
+-cut_file (char const *file, void (*cut_stream) (FILE *))
++cut_file (char const *file)
+ {
+ FILE *stream;
+
+@@ -482,8 +857,8 @@ main (int argc, char **argv)
+ int optc;
bool ok;
bool delim_specified = false;
- char *spec_list_string IF_LINT ( = NULL);
+- bool byte_mode = false;
+- char *spec_list_string = nullptr;
++ char *spec_list_string IF_LINT ( = nullptr);
+ char mbdelim[MB_LEN_MAX + 1];
-+ size_t delimlen = 0;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
-@@ -784,7 +1121,6 @@ main (int argc, char **argv)
+@@ -493,6 +868,8 @@ main (int argc, char **argv)
+
+ atexit (close_stdout);
+
++ operating_mode = undefined_mode;
++
+ /* By default, all non-delimited lines are printed. */
+ suppress_non_delimited = false;
+
+@@ -505,35 +882,77 @@ main (int argc, char **argv)
switch (optc)
{
case 'b':
- case 'c':
- /* Build the byte list. */
- if (operating_mode != undefined_mode)
- FATAL_ERROR (_("only one type of list may be specified"));
-@@ -792,6 +1128,14 @@ main (int argc, char **argv)
- spec_list_string = optarg;
- break;
-
+ /* Build the byte list. */
+- byte_mode = true;
+- FALLTHROUGH;
++ if (operating_mode != undefined_mode)
++ FATAL_ERROR (_("only one type of list may be specified"));
++ operating_mode = byte_mode;
++ spec_list_string = optarg;
++ break;
++
+ case 'c':
-+ /* Build the character list. */
++ /* Build the character list. */
+ if (operating_mode != undefined_mode)
+ FATAL_ERROR (_("only one type of list may be specified"));
+ operating_mode = character_mode;
@@ -533,12 +951,18 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ break;
+
case 'f':
- /* Build the field list. */
- if (operating_mode != undefined_mode)
-@@ -803,10 +1147,35 @@ main (int argc, char **argv)
+ /* Build the field list. */
+- if (spec_list_string)
+- FATAL_ERROR (_("only one list may be specified"));
++ if (operating_mode != undefined_mode)
++ FATAL_ERROR (_("only one type of list may be specified"));
++ operating_mode = field_mode;
+ spec_list_string = optarg;
+ break;
+
case 'd':
- /* New delimiter. */
- /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */
+ /* New delimiter. */
+ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
- if (optarg[0] != '\0' && optarg[1] != '\0')
- FATAL_ERROR (_("the delimiter must be a single character"));
- delim = optarg[0];
@@ -560,6 +984,9 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0')
+ FATAL_ERROR (_("the delimiter must be a single character"));
+ memcpy (mbdelim, optarg, delimlen);
++ mbdelim[delimlen] = '\0';
++ if (delimlen == 1)
++ delim = *optarg;
+ }
+ }
+
@@ -575,7 +1002,13 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
break;
case OUTPUT_DELIMITER_OPTION:
-@@ -819,6 +1188,7 @@ main (int argc, char **argv)
++ output_delimiter_specified = true;
+ /* Interpret --output-delimiter='' to mean
+ 'use the NUL byte as the delimiter.' */
+ output_delimiter_length = (optarg[0] == '\0'
+ ? 1 : strlen (optarg));
+- output_delimiter_string = optarg;
++ output_delimiter_string = xstrdup (optarg);
break;
case 'n':
@@ -583,17 +1016,34 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
break;
case 's':
-@@ -841,7 +1211,7 @@ main (int argc, char **argv)
- if (operating_mode == undefined_mode)
+@@ -555,40 +974,57 @@ main (int argc, char **argv)
+ }
+ }
+
+- if (!spec_list_string)
++ if (operating_mode == undefined_mode)
FATAL_ERROR (_("you must specify a list of bytes, characters, or fields"));
-- if (delim != '\0' && operating_mode != field_mode)
+- if (byte_mode)
+- {
+- if (delim_specified)
+- FATAL_ERROR (_("an input delimiter may be specified only\
+ if (delim_specified && operating_mode != field_mode)
- FATAL_ERROR (_("an input delimiter may be specified only\
++ FATAL_ERROR (_("an input delimiter may be specified only\
when operating on fields"));
-@@ -868,15 +1238,34 @@ main (int argc, char **argv)
- }
+- if (suppress_non_delimited)
+- FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\
++ if (suppress_non_delimited && operating_mode != field_mode)
++ FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\
+ \tonly when operating on fields"));
+- }
+
+ set_fields (spec_list_string,
+- ((byte_mode ? SETFLD_ERRMSG_USE_POS : 0)
+- | (complement ? SETFLD_COMPLEMENT : 0)));
++ ( (operating_mode == field_mode) ? 0 : SETFLD_ERRMSG_USE_POS)
++ | (complement ? SETFLD_COMPLEMENT : 0) );
if (!delim_specified)
- delim = '\t';
@@ -607,12 +1057,10 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+#endif
+ }
- if (output_delimiter_string == NULL)
+ if (output_delimiter_string == nullptr)
{
-- static char dummy[2];
-- dummy[0] = delim;
-- dummy[1] = '\0';
-- output_delimiter_string = dummy;
+- output_delimiter_default[0] = delim;
+- output_delimiter_string = output_delimiter_default;
- output_delimiter_length = 1;
+#ifdef HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1 && !force_singlebyte_mode)
@@ -632,1094 +1080,348 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c
+ }
}
+- void (*cut_stream) (FILE *) = byte_mode ? cut_bytes : cut_fields;
if (optind == argc)
-diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c
---- coreutils-8.15-orig/src/expand.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/expand.c 2013-01-30 13:40:37.343145830 +0100
-@@ -38,12 +38,29 @@
+- ok = cut_file ("-", cut_stream);
++ ok = cut_file ("-");
+ else
+ for (ok = true; optind < argc; optind++)
+- ok &= cut_file (argv[optind], cut_stream);
++ ok &= cut_file (argv[optind]);
+
+
+ if (have_read_stdin && fclose (stdin) == EOF)
+diff --git a/src/expand-common.c b/src/expand-common.c
+index 14dd804..0d8eaaa 100644
+--- a/src/expand-common.c
++++ b/src/expand-common.c
+@@ -19,6 +19,7 @@
+ #include
+ #include
+ #include
++#include
+ #include "system.h"
+ #include "c-ctype.h"
+ #include "fadvise.h"
+@@ -132,6 +133,119 @@ set_increment_size (colno tabval)
+ return ok;
+ }
+
++extern int
++set_utf_locale (void)
++{
++ /*try using some predefined locale */
++ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"};
++
++ const int predef_locales_count=3;
++ for (int i=0;ibufcount=0;
++ if (c == 0xEF)
++ {
++ c=fgetc(fp);
++ }
++ else
++ {
++ if (c != EOF)
++ {
++ ungetc(c,fp);
++ }
++ return false;
++ }
++
++ if (c == 0xBB)
++ {
++ c=fgetc(fp);
++ }
++ else
++ {
++ if ( c!= EOF )
++ {
++ mbf->buf[0]=(unsigned char) 0xEF;
++ mbf->bufcount=1;
++ ungetc(c,fp);
++ return false;
++ }
++ else
++ {
++ ungetc(0xEF,fp);
++ return false;
++ }
++ }
++ if (c == 0xBF)
++ {
++ mbf->bufcount=0;
++ return true;
++ }
++ else
++ {
++ if (c != EOF)
++ {
++ mbf->buf[0]=(unsigned char) 0xEF;
++ mbf->buf[1]=(unsigned char) 0xBB;
++ mbf->bufcount=2;
++ ungetc(c,fp);
++ return false;
++ }
++ else
++ {
++ mbf->buf[0]=(unsigned char) 0xEF;
++ mbf->bufcount=1;
++ ungetc(0xBB,fp);
++ return false;
++ }
++ }
++ return false;
++}
++
++extern void
++print_bom(void)
++{
++ putc (0xEF, stdout);
++ putc (0xBB, stdout);
++ putc (0xBF, stdout);
++}
++
+ /* Add the comma or blank separated list of tab stops STOPS
+ to the list of tab stops. */
+ extern void
+diff --git a/src/expand-common.h b/src/expand-common.h
+index 46ef4e3..e19469b 100644
+--- a/src/expand-common.h
++++ b/src/expand-common.h
+@@ -29,6 +29,18 @@ extern idx_t max_column_width;
+ /* The desired exit status. */
+ extern int exit_status;
+
++extern int
++set_utf_locale (void);
++
++extern bool
++check_utf_locale(void);
++
++extern bool
++check_bom(FILE* fp, mb_file_t *mbf);
++
++extern void
++print_bom(void);
++
+ /* Add tab stop TABVAL to the end of 'tab_list'. */
+ extern void
+ add_tab_stop (colno tabval);
+diff --git a/src/expand.c b/src/expand.c
+index 5ec7ce9..65ac315 100644
+--- a/src/expand.c
++++ b/src/expand.c
+@@ -38,6 +38,9 @@
#include
#include
#include
+
-+/* Get mbstate_t, mbrtowc(), wcwidth(). */
-+#if HAVE_WCHAR_H
-+# include
-+#endif
++#include
+
#include "system.h"
- #include "error.h"
- #include "fadvise.h"
- #include "quote.h"
- #include "xstrndup.h"
+ #include "expand-common.h"
-+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
-+ installation; work around this configuration error. */
-+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
-+# define MB_LEN_MAX 16
-+#endif
-+
-+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-+#if HAVE_MBRTOWC && defined mbstate_t
-+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-+#endif
-+
- /* The official name of this program (e.g., no `g' prefix). */
- #define PROGRAM_NAME "expand"
-
-@@ -360,6 +377,142 @@ expand (void)
- }
- }
-
-+#if HAVE_MBRTOWC
-+static void
-+expand_multibyte (void)
-+{
-+ FILE *fp; /* Input strem. */
-+ mbstate_t i_state; /* Current shift state of the input stream. */
-+ mbstate_t i_state_bak; /* Back up the I_STATE. */
-+ mbstate_t o_state; /* Current shift state of the output stream. */
-+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */
-+ char *bufpos = buf; /* Next read position of BUF. */
-+ size_t buflen = 0; /* The length of the byte sequence in buf. */
-+ wchar_t wc; /* A gotten wide character. */
-+ size_t mblength; /* The byte size of a multibyte character
-+ which shows as same character as WC. */
-+ int tab_index = 0; /* Index in `tab_list' of next tabstop. */
-+ int column = 0; /* Column on screen of the next char. */
-+ int next_tab_column; /* Column the next tab stop is on. */
-+ int convert = 1; /* If nonzero, perform translations. */
-+
-+ fp = next_file ((FILE *) NULL);
-+ if (fp == NULL)
-+ return;
-+
-+ memset (&o_state, '\0', sizeof(mbstate_t));
-+ memset (&i_state, '\0', sizeof(mbstate_t));
-+
-+ for (;;)
-+ {
-+ /* Refill the buffer BUF. */
-+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
-+ {
-+ memmove (buf, bufpos, buflen);
-+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
-+ bufpos = buf;
-+ }
-+
-+ /* No character is left in BUF. */
-+ if (buflen < 1)
-+ {
-+ fp = next_file (fp);
-+
-+ if (fp == NULL)
-+ break; /* No more files. */
-+ else
-+ {
-+ memset (&i_state, '\0', sizeof(mbstate_t));
-+ continue;
-+ }
-+ }
-+
-+ /* Get a wide character. */
-+ i_state_bak = i_state;
-+ mblength = mbrtowc (&wc, bufpos, buflen, &i_state);
-+
-+ switch (mblength)
-+ {
-+ case (size_t)-1: /* illegal byte sequence. */
-+ case (size_t)-2:
-+ mblength = 1;
-+ i_state = i_state_bak;
-+ if (convert)
-+ {
-+ ++column;
-+ if (convert_entire_line == 0 && !isblank(*bufpos))
-+ convert = 0;
-+ }
-+ putchar (*bufpos);
-+ break;
-+
-+ case 0: /* null. */
-+ mblength = 1;
-+ if (convert && convert_entire_line == 0)
-+ convert = 0;
-+ putchar ('\0');
-+ break;
-+
-+ default:
-+ if (wc == L'\n') /* LF. */
-+ {
-+ tab_index = 0;
-+ column = 0;
-+ convert = 1;
-+ putchar ('\n');
-+ }
-+ else if (wc == L'\t' && convert) /* Tab. */
-+ {
-+ if (tab_size == 0)
-+ {
-+ /* Do not let tab_index == first_free_tab;
-+ stop when it is 1 less. */
-+ while (tab_index < first_free_tab - 1
-+ && column >= tab_list[tab_index])
-+ tab_index++;
-+ next_tab_column = tab_list[tab_index];
-+ if (tab_index < first_free_tab - 1)
-+ tab_index++;
-+ if (column >= next_tab_column)
-+ next_tab_column = column + 1;
-+ }
-+ else
-+ next_tab_column = column + tab_size - column % tab_size;
-+
-+ while (column < next_tab_column)
-+ {
-+ putchar (' ');
-+ ++column;
-+ }
-+ }
-+ else /* Others. */
-+ {
-+ if (convert)
-+ {
-+ if (wc == L'\b')
-+ {
-+ if (column > 0)
-+ --column;
-+ }
-+ else
-+ {
-+ int width; /* The width of WC. */
-+
-+ width = wcwidth (wc);
-+ column += (width > 0) ? width : 0;
-+ if (convert_entire_line == 0 && !iswblank(wc))
-+ convert = 0;
-+ }
-+ }
-+ fwrite (bufpos, sizeof(char), mblength, stdout);
-+ }
-+ }
-+ buflen -= mblength;
-+ bufpos += mblength;
-+ }
-+}
-+#endif
-+
- int
- main (int argc, char **argv)
+@@ -96,19 +99,41 @@ expand (void)
{
-@@ -424,7 +577,12 @@ main (int argc, char **argv)
+ /* Input stream. */
+ FILE *fp = next_file (nullptr);
++ mb_file_t mbf;
++ mbf_char_t c;
++ /* True if the starting locale is utf8. */
++ bool using_utf_locale;
++
++ /* True if the first file contains BOM header. */
++ bool found_bom;
++ using_utf_locale=check_utf_locale();
- file_list = (optind < argc ? &argv[optind] : stdin_argv);
-
-- expand ();
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ expand_multibyte ();
-+ else
-+#endif
-+ expand ();
-
- if (have_read_stdin && fclose (stdin) != 0)
- error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c
---- coreutils-8.15-orig/src/fold.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/fold.c 2013-01-30 13:40:37.344145705 +0100
-@@ -22,12 +22,34 @@
- #include
- #include
-
-+/* Get mbstate_t, mbrtowc(), wcwidth(). */
-+#if HAVE_WCHAR_H
-+# include
-+#endif
-+
-+/* Get iswprint(), iswblank(), wcwidth(). */
-+#if HAVE_WCTYPE_H
-+# include
-+#endif
-+
- #include "system.h"
- #include "error.h"
- #include "fadvise.h"
- #include "quote.h"
- #include "xstrtol.h"
-
-+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
-+ installation; work around this configuration error. */
-+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
-+# undef MB_LEN_MAX
-+# define MB_LEN_MAX 16
-+#endif
-+
-+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-+#if HAVE_MBRTOWC && defined mbstate_t
-+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-+#endif
-+
- #define TAB_WIDTH 8
-
- /* The official name of this program (e.g., no `g' prefix). */
-@@ -35,20 +57,41 @@
-
- #define AUTHORS proper_name ("David MacKenzie")
-
-+#define FATAL_ERROR(Message) \
-+ do \
-+ { \
-+ error (0, 0, (Message)); \
-+ usage (2); \
-+ } \
-+ while (0)
-+
-+enum operating_mode
-+{
-+ /* Fold texts by columns that are at the given positions. */
-+ column_mode,
-+
-+ /* Fold texts by bytes that are at the given positions. */
-+ byte_mode,
-+
-+ /* Fold texts by characters that are at the given positions. */
-+ character_mode,
-+};
-+
-+/* The argument shows current mode. (Default: column_mode) */
-+static enum operating_mode operating_mode;
-+
- /* If nonzero, try to break on whitespace. */
- static bool break_spaces;
-
--/* If nonzero, count bytes, not column positions. */
--static bool count_bytes;
--
- /* If nonzero, at least one of the files we read was standard input. */
- static bool have_read_stdin;
-
--static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
-+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::";
-
- static struct option const longopts[] =
- {
- {"bytes", no_argument, NULL, 'b'},
-+ {"characters", no_argument, NULL, 'c'},
- {"spaces", no_argument, NULL, 's'},
- {"width", required_argument, NULL, 'w'},
- {GETOPT_HELP_OPTION_DECL},
-@@ -78,6 +121,7 @@ Mandatory arguments to long options are
- "), stdout);
- fputs (_("\
- -b, --bytes count bytes rather than columns\n\
-+ -c, --characters count characters rather than columns\n\
- -s, --spaces break at spaces\n\
- -w, --width=WIDTH use WIDTH columns instead of 80\n\
- "), stdout);
-@@ -95,7 +139,7 @@ Mandatory arguments to long options are
- static size_t
- adjust_column (size_t column, char c)
- {
-- if (!count_bytes)
-+ if (operating_mode != byte_mode)
- {
- if (c == '\b')
- {
-@@ -118,30 +162,14 @@ adjust_column (size_t column, char c)
- to stdout, with maximum line length WIDTH.
- Return true if successful. */
-
--static bool
--fold_file (char const *filename, size_t width)
-+static void
-+fold_text (FILE *istream, size_t width, int *saved_errno)
- {
-- FILE *istream;
- int c;
- size_t column = 0; /* Screen column where next char will go. */
- size_t offset_out = 0; /* Index in `line_out' for next char. */
- static char *line_out = NULL;
- static size_t allocated_out = 0;
-- int saved_errno;
--
-- if (STREQ (filename, "-"))
-- {
-- istream = stdin;
-- have_read_stdin = true;
-- }
-- else
-- istream = fopen (filename, "r");
--
-- if (istream == NULL)
-- {
-- error (0, errno, "%s", filename);
-- return false;
-- }
-
- fadvise (istream, FADVISE_SEQUENTIAL);
-
-@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t
- bool found_blank = false;
- size_t logical_end = offset_out;
-
-+ /* If LINE_OUT has no wide character,
-+ put a new wide character in LINE_OUT
-+ if column is bigger than width. */
-+ if (offset_out == 0)
-+ {
-+ line_out[offset_out++] = c;
-+ continue;
-+ }
-+
- /* Look for the last blank. */
- while (logical_end)
- {
-@@ -217,11 +254,221 @@ fold_file (char const *filename, size_t
- line_out[offset_out++] = c;
- }
-
-- saved_errno = errno;
-+ *saved_errno = errno;
-
- if (offset_out)
- fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
-
-+}
-+
-+#if HAVE_MBRTOWC
-+static void
-+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno)
-+{
-+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */
-+ size_t buflen = 0; /* The length of the byte sequence in buf. */
-+ char *bufpos = buf; /* Next read position of BUF. */
-+ wint_t wc; /* A gotten wide character. */
-+ size_t mblength; /* The byte size of a multibyte character which shows
-+ as same character as WC. */
-+ mbstate_t state, state_bak; /* State of the stream. */
-+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */
-+
-+ static char *line_out = NULL;
-+ size_t offset_out = 0; /* Index in `line_out' for next char. */
-+ static size_t allocated_out = 0;
-+
-+ int increment;
-+ size_t column = 0;
-+
-+ size_t last_blank_pos;
-+ size_t last_blank_column;
-+ int is_blank_seen;
-+ int last_blank_increment = 0;
-+ int is_bs_following_last_blank;
-+ size_t bs_following_last_blank_num;
-+ int is_cr_after_last_blank;
-+
-+#define CLEAR_FLAGS \
-+ do \
-+ { \
-+ last_blank_pos = 0; \
-+ last_blank_column = 0; \
-+ is_blank_seen = 0; \
-+ is_bs_following_last_blank = 0; \
-+ bs_following_last_blank_num = 0; \
-+ is_cr_after_last_blank = 0; \
-+ } \
-+ while (0)
-+
-+#define START_NEW_LINE \
-+ do \
-+ { \
-+ putchar ('\n'); \
-+ column = 0; \
-+ offset_out = 0; \
-+ CLEAR_FLAGS; \
-+ } \
-+ while (0)
-+
-+ CLEAR_FLAGS;
-+ memset (&state, '\0', sizeof(mbstate_t));
-+
-+ for (;; bufpos += mblength, buflen -= mblength)
-+ {
-+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream))
-+ {
-+ memmove (buf, bufpos, buflen);
-+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream);
-+ bufpos = buf;
-+ }
-+
-+ if (buflen < 1)
-+ break;
-+
-+ /* Get a wide character. */
-+ state_bak = state;
-+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state);
-+
-+ switch (mblength)
-+ {
-+ case (size_t)-1:
-+ case (size_t)-2:
-+ convfail++;
-+ state = state_bak;
-+ /* Fall through. */
-+
-+ case 0:
-+ mblength = 1;
-+ break;
-+ }
-+
-+rescan:
-+ if (operating_mode == byte_mode) /* byte mode */
-+ increment = mblength;
-+ else if (operating_mode == character_mode) /* character mode */
-+ increment = 1;
-+ else /* column mode */
-+ {
-+ if (convfail)
-+ increment = 1;
-+ else
-+ {
-+ switch (wc)
-+ {
-+ case L'\n':
-+ fwrite (line_out, sizeof(char), offset_out, stdout);
-+ START_NEW_LINE;
-+ continue;
-+
-+ case L'\b':
-+ increment = (column > 0) ? -1 : 0;
-+ break;
-+
-+ case L'\r':
-+ increment = -1 * column;
-+ break;
-+
-+ case L'\t':
-+ increment = 8 - column % 8;
-+ break;
-+
-+ default:
-+ increment = wcwidth (wc);
-+ increment = (increment < 0) ? 0 : increment;
-+ }
-+ }
-+ }
-+
-+ if (column + increment > width && break_spaces && last_blank_pos)
-+ {
-+ fwrite (line_out, sizeof(char), last_blank_pos, stdout);
-+ putchar ('\n');
-+
-+ offset_out = offset_out - last_blank_pos;
-+ column = column - last_blank_column + ((is_cr_after_last_blank)
-+ ? last_blank_increment : bs_following_last_blank_num);
-+ memmove (line_out, line_out + last_blank_pos, offset_out);
-+ CLEAR_FLAGS;
-+ goto rescan;
-+ }
-+
-+ if (column + increment > width && column != 0)
-+ {
-+ fwrite (line_out, sizeof(char), offset_out, stdout);
-+ START_NEW_LINE;
-+ goto rescan;
-+ }
-+
-+ if (allocated_out < offset_out + mblength)
-+ {
-+ line_out = X2REALLOC (line_out, &allocated_out);
-+ }
-+
-+ memcpy (line_out + offset_out, bufpos, mblength);
-+ offset_out += mblength;
-+ column += increment;
-+
-+ if (is_blank_seen && !convfail && wc == L'\r')
-+ is_cr_after_last_blank = 1;
-+
-+ if (is_bs_following_last_blank && !convfail && wc == L'\b')
-+ ++bs_following_last_blank_num;
-+ else
-+ is_bs_following_last_blank = 0;
-+
-+ if (break_spaces && !convfail && iswblank (wc))
-+ {
-+ last_blank_pos = offset_out;
-+ last_blank_column = column;
-+ is_blank_seen = 1;
-+ last_blank_increment = increment;
-+ is_bs_following_last_blank = 1;
-+ bs_following_last_blank_num = 0;
-+ is_cr_after_last_blank = 0;
-+ }
-+ }
-+
-+ *saved_errno = errno;
-+
-+ if (offset_out)
-+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
-+
-+}
-+#endif
-+
-+/* Fold file FILENAME, or standard input if FILENAME is "-",
-+ to stdout, with maximum line length WIDTH.
-+ Return 0 if successful, 1 if an error occurs. */
-+
-+static bool
-+fold_file (char *filename, size_t width)
-+{
-+ FILE *istream;
-+ int saved_errno;
-+
-+ if (STREQ (filename, "-"))
-+ {
-+ istream = stdin;
-+ have_read_stdin = 1;
-+ }
-+ else
-+ istream = fopen (filename, "r");
-+
-+ if (istream == NULL)
-+ {
-+ error (0, errno, "%s", filename);
-+ return 1;
-+ }
-+
-+ /* Define how ISTREAM is being folded. */
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ fold_multibyte_text (istream, width, &saved_errno);
-+ else
-+#endif
-+ fold_text (istream, width, &saved_errno);
-+
- if (ferror (istream))
- {
- error (0, saved_errno, "%s", filename);
-@@ -254,7 +501,8 @@ main (int argc, char **argv)
-
- atexit (close_stdout);
-
-- break_spaces = count_bytes = have_read_stdin = false;
-+ operating_mode = column_mode;
-+ break_spaces = have_read_stdin = false;
-
- while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
- {
-@@ -263,7 +511,15 @@ main (int argc, char **argv)
- switch (optc)
- {
- case 'b': /* Count bytes rather than columns. */
-- count_bytes = true;
-+ if (operating_mode != column_mode)
-+ FATAL_ERROR (_("only one way of folding may be specified"));
-+ operating_mode = byte_mode;
-+ break;
-+
-+ case 'c':
-+ if (operating_mode != column_mode)
-+ FATAL_ERROR (_("only one way of folding may be specified"));
-+ operating_mode = character_mode;
- break;
-
- case 's': /* Break at word boundaries. */
-diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c
---- coreutils-8.15-orig/src/join.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/join.c 2013-01-30 15:59:19.544250392 +0100
-@@ -22,18 +22,32 @@
- #include
- #include
-
-+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */
-+#if HAVE_WCHAR_H
-+# include
-+#endif
-+
-+/* Get iswblank(), towupper. */
-+#if HAVE_WCTYPE_H
-+# include
-+#endif
-+
- #include "system.h"
- #include "error.h"
- #include "fadvise.h"
- #include "hard-locale.h"
- #include "linebuffer.h"
--#include "memcasecmp.h"
- #include "quote.h"
- #include "stdio--.h"
- #include "xmemcoll.h"
- #include "xstrtol.h"
- #include "argmatch.h"
-
-+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-+#if HAVE_MBRTOWC && defined mbstate_t
-+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-+#endif
-+
- /* The official name of this program (e.g., no `g' prefix). */
- #define PROGRAM_NAME "join"
-
-@@ -135,10 +149,12 @@ static struct outlist outlist_head;
- /* Last element in `outlist', where a new element can be added. */
- static struct outlist *outlist_end = &outlist_head;
-
--/* Tab character separating fields. If negative, fields are separated
-- by any nonempty string of blanks, otherwise by exactly one
-- tab character whose value (when cast to unsigned char) equals TAB. */
--static int tab = -1;
-+/* Tab character separating fields. If NULL, fields are separated
-+ by any nonempty string of blanks. */
-+static char *tab = NULL;
-+
-+/* The number of bytes used for tab. */
-+static size_t tablen = 0;
-
- /* If nonzero, check that the input is correctly ordered. */
- static enum
-@@ -263,13 +279,14 @@ xfields (struct line *line)
- if (ptr == lim)
+ if (!fp)
return;
++ mbf_init (mbf, fp);
++ found_bom=check_bom(fp,&mbf);
-- if (0 <= tab && tab != '\n')
-+ if (tab != NULL)
+- while (true)
++ if (using_utf_locale == false && found_bom == true)
++ {
++ /*try using some predefined locale */
++
++ if (set_utf_locale () != 0)
{
-+ unsigned char t = tab[0];
- char *sep;
-- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
-+ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1)
- extract_field (line, ptr, sep - ptr);
- }
-- else if (tab < 0)
-+ else
- {
- /* Skip leading blanks before the first field. */
- while (isblank (to_uchar (*ptr)))
-@@ -293,6 +310,148 @@ xfields (struct line *line)
- extract_field (line, ptr, lim - ptr);
- }
+- /* Input character, or EOF. */
+- int c;
++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
++ }
++ }
++
++
++ if (found_bom == true)
++ {
++ print_bom();
++ }
-+#if HAVE_MBRTOWC
-+static void
-+xfields_multibyte (struct line *line)
-+{
-+ char *ptr = line->buf.buffer;
-+ char const *lim = ptr + line->buf.length - 1;
-+ wchar_t wc = 0;
-+ size_t mblength = 1;
-+ mbstate_t state, state_bak;
-+
-+ memset (&state, 0, sizeof (mbstate_t));
-+
-+ if (ptr >= lim)
-+ return;
-+
-+ if (tab != NULL)
++ while (true)
+ {
-+ unsigned char t = tab[0];
-+ char *sep = ptr;
-+ for (; ptr < lim; ptr = sep + mblength)
-+ {
-+ sep = ptr;
-+ while (sep < lim)
-+ {
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
-+
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ if (mblength == tablen && !memcmp (sep, tab, mblength))
-+ break;
-+ else
-+ {
-+ sep += mblength;
-+ continue;
-+ }
-+ }
-+
-+ if (sep >= lim)
-+ break;
-+
-+ extract_field (line, ptr, sep - ptr);
-+ }
-+ }
-+ else
-+ {
-+ /* Skip leading blanks before the first field. */
-+ while(ptr < lim)
-+ {
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
-+
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ break;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ if (!iswblank(wc))
-+ break;
-+ ptr += mblength;
-+ }
-+
-+ do
-+ {
-+ char *sep;
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ break;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ sep = ptr + mblength;
-+ while (sep < lim)
-+ {
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ break;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ if (iswblank (wc))
-+ break;
-+
-+ sep += mblength;
-+ }
-+
-+ extract_field (line, ptr, sep - ptr);
-+ if (sep >= lim)
-+ return;
-+
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state);
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ break;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ ptr = sep + mblength;
-+ while (ptr < lim)
-+ {
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state);
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ mblength = 1;
-+ state = state_bak;
-+ break;
-+ }
-+ mblength = (mblength < 1) ? 1 : mblength;
-+
-+ if (!iswblank (wc))
-+ break;
-+
-+ ptr += mblength;
-+ }
-+ }
-+ while (ptr < lim);
-+ }
-+
-+ extract_field (line, ptr, lim - ptr);
-+}
-+#endif
-+
- static void
- freeline (struct line *line)
- {
-@@ -314,56 +473,129 @@ keycmp (struct line const *line1, struct
- size_t jf_1, size_t jf_2)
- {
- /* Start of field to compare in each file. */
-- char *beg1;
-- char *beg2;
+ /* If true, perform translations. */
+ bool convert = true;
+
-
-- size_t len1;
-- size_t len2; /* Length of fields to compare. */
-+ char *beg[2];
-+ char *copy[2];
-+ size_t len[2]; /* Length of fields to compare. */
- int diff;
-+ int i, j;
-+ int mallocd = 0;
+ /* The following variables have valid values only when CONVERT
+ is true: */
- if (jf_1 < line1->nfields)
- {
-- beg1 = line1->fields[jf_1].beg;
-- len1 = line1->fields[jf_1].len;
-+ beg[0] = line1->fields[jf_1].beg;
-+ len[0] = line1->fields[jf_1].len;
- }
- else
- {
-- beg1 = NULL;
-- len1 = 0;
-+ beg[0] = NULL;
-+ len[0] = 0;
- }
+@@ -118,17 +143,48 @@ expand (void)
+ /* Index in TAB_LIST of next tab stop to examine. */
+ idx_t tab_index = 0;
- if (jf_2 < line2->nfields)
- {
-- beg2 = line2->fields[jf_2].beg;
-- len2 = line2->fields[jf_2].len;
-+ beg[1] = line2->fields[jf_2].beg;
-+ len[1] = line2->fields[jf_2].len;
- }
- else
- {
-- beg2 = NULL;
-- len2 = 0;
-+ beg[1] = NULL;
-+ len[1] = 0;
- }
+-
+ /* Convert a line of text. */
-- if (len1 == 0)
-- return len2 == 0 ? 0 : -1;
-- if (len2 == 0)
-+ if (len[0] == 0)
-+ return len[1] == 0 ? 0 : -1;
-+ if (len[1] == 0)
- return 1;
-
- if (ignore_case)
- {
-- /* FIXME: ignore_case does not work with NLS (in particular,
-- with multibyte chars). */
-- diff = memcasecmp (beg1, beg2, MIN (len1, len2));
-+#ifdef HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ {
-+ size_t mblength;
-+ wchar_t wc, uwc;
-+ mbstate_t state, state_bak;
-+
-+ memset (&state, '\0', sizeof (mbstate_t));
-+
-+ for (i = 0; i < 2; i++)
-+ {
-+ copy[i] = xmalloc (len[i] + 1);
-+ mallocd = 1;
-+
-+ for (j = 0; j < MIN (len[0], len[1]);)
+ do
+ {
+- while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
+- continue;
++ while (true) {
++ mbf_getc (c, mbf);
++ if ((mb_iseof (c)) && (fp = next_file (fp)))
+ {
-+ state_bak = state;
-+ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state);
-+
-+ switch (mblength)
++ mbf_init (mbf, fp);
++ if (fp!=NULL)
++ {
++ if (check_bom(fp,&mbf)==true)
+ {
-+ case (size_t) -1:
-+ case (size_t) -2:
-+ state = state_bak;
-+ /* Fall through */
-+ case 0:
-+ mblength = 1;
-+ break;
-+
-+ default:
-+ uwc = towupper (wc);
-+
-+ if (uwc != wc)
-+ {
-+ mbstate_t state_wc;
-+
-+ memset (&state_wc, '\0', sizeof (mbstate_t));
-+ wcrtomb (copy[i] + j, uwc, &state_wc);
-+ }
-+ else
-+ memcpy (copy[i] + j, beg[i] + j, mblength);
++ /*Not the first file - check BOM header*/
++ if (using_utf_locale==false && found_bom==false)
++ {
++ /*BOM header in subsequent file but not in the first one. */
++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
++ }
+ }
-+ j += mblength;
-+ }
-+ copy[i][j] = '\0';
-+ }
-+ }
-+ else
-+#endif
-+ {
-+ for (i = 0; i < 2; i++)
-+ {
-+ copy[i] = xmalloc (len[i] + 1);
-+ mallocd = 1;
-+
-+ for (j = 0; j < MIN (len[0], len[1]); j++)
-+ copy[i][j] = toupper (beg[i][j]);
-+
-+ copy[i][j] = '\0';
-+ }
-+ }
- }
- else
- {
-- if (hard_LC_COLLATE)
-- return xmemcoll (beg1, len1, beg2, len2);
-- diff = memcmp (beg1, beg2, MIN (len1, len2));
-+ copy[0] = (unsigned char *) beg[0];
-+ copy[1] = (unsigned char *) beg[1];
-+ }
-+
-+ if (hard_LC_COLLATE)
-+ {
-+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
-+
-+ if (mallocd)
-+ for (i = 0; i < 2; i++)
-+ free (copy[i]);
-+
-+ return diff;
- }
-+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
-+
-+ if (mallocd)
-+ for (i = 0; i < 2; i++)
-+ free (copy[i]);
-
- if (diff)
- return diff;
-- return len1 < len2 ? -1 : len1 != len2;
-+ return len[0] - len[1];
- }
-
- /* Check that successive input lines PREV and CURRENT from input file
-@@ -455,6 +687,11 @@ get_line (FILE *fp, struct line **linep,
- }
- ++line_no[which - 1];
-
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ xfields_multibyte (line);
-+ else
-+#endif
- xfields (line);
-
- if (prevline[which - 1])
-@@ -554,21 +791,28 @@ prfield (size_t n, struct line const *li
-
- /* Output all the fields in line, other than the join field. */
-
-+#define PUT_TAB_CHAR \
-+ do \
-+ { \
-+ (tab != NULL) ? \
-+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \
-+ } \
-+ while (0)
-+
- static void
- prfields (struct line const *line, size_t join_field, size_t autocount)
- {
- size_t i;
- size_t nfields = autoformat ? autocount : line->nfields;
-- char output_separator = tab < 0 ? ' ' : tab;
-
- for (i = 0; i < join_field && i < nfields; ++i)
- {
-- putchar (output_separator);
-+ PUT_TAB_CHAR;
- prfield (i, line);
- }
- for (i = join_field + 1; i < nfields; ++i)
- {
-- putchar (output_separator);
-+ PUT_TAB_CHAR;
- prfield (i, line);
- }
- }
-@@ -579,7 +823,6 @@ static void
- prjoin (struct line const *line1, struct line const *line2)
- {
- const struct outlist *outlist;
-- char output_separator = tab < 0 ? ' ' : tab;
- size_t field;
- struct line const *line;
-
-@@ -613,7 +856,7 @@ prjoin (struct line const *line1, struct
- o = o->next;
- if (o == NULL)
- break;
-- putchar (output_separator);
-+ PUT_TAB_CHAR;
- }
- putchar ('\n');
- }
-@@ -1091,21 +1334,46 @@ main (int argc, char **argv)
-
- case 't':
- {
-- unsigned char newtab = optarg[0];
-+ char *newtab = NULL;
-+ size_t newtablen;
-+ newtab = xstrdup (optarg);
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ {
-+ mbstate_t state;
-+
-+ memset (&state, 0, sizeof (mbstate_t));
-+ newtablen = mbrtowc (NULL, newtab,
-+ strnlen (newtab, MB_LEN_MAX),
-+ &state);
-+ if (newtablen == (size_t) 0
-+ || newtablen == (size_t) -1
-+ || newtablen == (size_t) -2)
-+ newtablen = 1;
++ else
++ {
++ if(using_utf_locale==false && found_bom==true)
++ {
++ /*First file conatined BOM header - locale was switched to UTF
++ *all subsequent files should contain BOM. */
++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
++ }
++ }
++ }
++ continue;
+ }
+ else
-+#endif
-+ newtablen = 1;
- if (! newtab)
-- newtab = '\n'; /* '' => process the whole line. */
-+ {
-+ newtab = "\n"; /* '' => process the whole line. */
-+ }
- else if (optarg[1])
- {
-- if (STREQ (optarg, "\\0"))
-- newtab = '\0';
-- else
-- error (EXIT_FAILURE, 0, _("multi-character tab %s"),
-- quote (optarg));
-+ if (newtablen == 1 && newtab[1])
-+ {
-+ if (STREQ (newtab, "\\0"))
-+ newtab[0] = '\0';
-+ }
-+ }
-+ if (tab != NULL && strcmp (tab, newtab))
+ {
-+ free (newtab);
-+ error (EXIT_FAILURE, 0, _("incompatible tabs"));
- }
-- if (0 <= tab && tab != newtab)
-- error (EXIT_FAILURE, 0, _("incompatible tabs"));
- tab = newtab;
-- }
-+ tablen = newtablen;
-+ }
- break;
++ break;
++ }
++ }
++
- case NOCHECK_ORDER_OPTION:
-diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
---- coreutils-8.15-orig/src/pr.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/pr.c 2013-01-30 13:40:37.350146206 +0100
-@@ -312,6 +312,32 @@
+ if (convert)
+ {
+- if (c == '\t')
++ if (mb_iseq (c, '\t'))
+ {
+ /* Column the next input tab stop is on. */
+ bool last_tab;
+@@ -139,31 +195,33 @@ expand (void)
+ if (putchar (' ') < 0)
+ write_error ();
+- c = ' ';
++ mb_setascii (&c, ' ');
+ }
+- else if (c == '\b')
++ else if (mb_iseq (c, '\b'))
+ {
+ /* Go back one column, and force recalculation of the
+ next tab stop. */
+ column -= !!column;
+ tab_index -= !!tab_index;
+ }
+- else
++ /* A leading control character could make us trip over. */
++ else if (!mb_iscntrl (c))
+ {
+- if (ckd_add (&column, column, 1))
++ if (ckd_add (&column, column, mb_width (c)))
+ error (EXIT_FAILURE, 0, _("input line is too long"));
+ }
+
+- convert &= convert_entire_line || !! isblank (c);
++ convert &= convert_entire_line || !! mb_isblank (c);
+ }
+
+- if (c < 0)
++ if (mb_iseof (c))
+ return;
+
+- if (putchar (c) < 0)
++ mb_putc (c, stdout);
++ if (ferror (stdout))
+ write_error ();
+ }
+- while (c != '\n');
++ while (!mb_iseq (c, '\n'));
+ }
+ }
+
+diff --git a/src/local.mk b/src/local.mk
+index a8ad6b4..b0e61ec 100644
+--- a/src/local.mk
++++ b/src/local.mk
+@@ -490,8 +490,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS)
+ src_basenc_SOURCES = src/basenc.c
+ src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS)
+
+-src_expand_SOURCES = src/expand.c src/expand-common.c
+-src_unexpand_SOURCES = src/unexpand.c src/expand-common.c
++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c lib/mbchar.c
++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c
+
+ src_wc_SOURCES = src/wc.c
+ if USE_AVX512_WC_LINECOUNT
+diff --git a/src/pr.c b/src/pr.c
+index 10b8c52..079c86c 100644
+--- a/src/pr.c
++++ b/src/pr.c
+@@ -312,6 +312,24 @@
+ #include
#include
#include
+
@@ -1739,21 +1441,13 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
+#if HAVE_WCHAR_H
+# include
+#endif
-+
-+/* Get iswprint(). -- for wcwidth(). */
-+#if HAVE_WCTYPE_H
-+# include
-+#endif
-+#if !defined iswprint && !HAVE_ISWPRINT
-+# define iswprint(wc) 1
-+#endif
+
#include "system.h"
- #include "error.h"
+ #include "c-ctype.h"
#include "fadvise.h"
-@@ -323,6 +349,18 @@
- #include "strftime.h"
- #include "xstrtol.h"
+@@ -325,6 +343,18 @@
+ #include "xstrtol-error.h"
+ #include "xdectoint.h"
+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
+#if HAVE_MBRTOWC && defined mbstate_t
@@ -1767,10 +1461,10 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
+extern int wcwidth ();
+#endif
+
- /* The official name of this program (e.g., no `g' prefix). */
+ /* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "pr"
-@@ -415,7 +453,20 @@ struct COLUMN
+@@ -417,7 +447,20 @@ struct COLUMN
typedef struct COLUMN COLUMN;
@@ -1792,23 +1486,23 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
static bool read_line (COLUMN *p);
static bool print_page (void);
static bool print_stored (COLUMN *p);
-@@ -425,6 +476,7 @@ static void print_header (void);
- static void pad_across_to (int position);
+@@ -428,6 +471,7 @@ static void pad_across_to (int position);
static void add_line_number (COLUMN *p);
+ static int getoptnum (char const *n_str, int min, char const *errfmt);
static void getoptarg (char *arg, char switch_char, char *character,
+ int *character_length, int *character_width,
int *number);
static void print_files (int number_of_files, char **av);
static void init_parameters (int number_of_files);
-@@ -438,7 +490,6 @@ static void store_char (char c);
- static void pad_down (int lines);
+@@ -441,7 +485,6 @@ static void store_char (char c);
+ static void pad_down (unsigned int lines);
static void read_rest_of_line (COLUMN *p);
static void skip_read (COLUMN *p, int column_number);
-static void print_char (char c);
static void cleanup (void);
static void print_sep_string (void);
- static void separator_string (const char *optarg_S);
-@@ -450,7 +501,7 @@ static COLUMN *column_vector;
+ static void separator_string (char const *optarg_S);
+@@ -453,7 +496,7 @@ static COLUMN *column_vector;
we store the leftmost columns contiguously in buff.
To print a line from buff, get the index of the first character
from line_vector[i], and print up to line_vector[i + 1]. */
@@ -1817,7 +1511,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* Index of the position in buff where the next character
will be stored. */
-@@ -554,7 +605,7 @@ static int chars_per_column;
+@@ -557,7 +600,7 @@ static int chars_per_column;
static bool untabify_input = false;
/* (-e) The input tab character. */
@@ -1826,7 +1520,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
where the leftmost column is 1. */
-@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8;
+@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8;
static bool tabify_output = false;
/* (-i) The output tab character. */
@@ -1838,7 +1532,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* (-i) The width of the output tab. */
static int chars_per_output_tab = 8;
-@@ -638,7 +692,13 @@ static int power_10;
+@@ -637,7 +683,13 @@ static int line_number;
static bool numbered_lines = false;
/* (-n) Character which follows each line number. */
@@ -1853,18 +1547,18 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* (-n) line counting starts with 1st line of input file (not with 1st
line of 1st page printed). */
-@@ -691,6 +751,7 @@ static bool use_col_separator = false;
- -a|COLUMN|-m is a `space' and with the -J option a `tab'. */
- static char *col_sep_string = (char *) "";
+@@ -690,6 +742,7 @@ static bool use_col_separator = false;
+ -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
+ static char const *col_sep_string = "";
static int col_sep_length = 0;
+static int col_sep_width = 0;
static char *column_separator = (char *) " ";
static char *line_separator = (char *) "\t";
-@@ -847,6 +908,13 @@ separator_string (const char *optarg_S)
- col_sep_length = (int) strlen (optarg_S);
- col_sep_string = xmalloc (col_sep_length + 1);
- strcpy (col_sep_string, optarg_S);
+@@ -852,6 +905,13 @@ separator_string (char const *optarg_S)
+ integer_overflow ();
+ col_sep_length = len;
+ col_sep_string = optarg_S;
+
+#if HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1)
@@ -1875,7 +1569,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
}
int
-@@ -871,6 +939,21 @@ main (int argc, char **argv)
+@@ -876,6 +936,21 @@ main (int argc, char **argv)
atexit (close_stdout);
@@ -1896,8 +1590,8 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
+
n_files = 0;
file_names = (argc > 1
- ? xmalloc ((argc - 1) * sizeof (char *))
-@@ -947,8 +1030,12 @@ main (int argc, char **argv)
+ ? xnmalloc (argc - 1, sizeof (char *))
+@@ -952,8 +1027,12 @@ main (int argc, char **argv)
break;
case 'e':
if (optarg)
@@ -1912,7 +1606,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* Could check tab width > 0. */
untabify_input = true;
break;
-@@ -961,8 +1048,12 @@ main (int argc, char **argv)
+@@ -966,8 +1045,12 @@ main (int argc, char **argv)
break;
case 'i':
if (optarg)
@@ -1927,7 +1621,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* Could check tab width > 0. */
tabify_output = true;
break;
-@@ -989,8 +1080,8 @@ main (int argc, char **argv)
+@@ -986,8 +1069,8 @@ main (int argc, char **argv)
case 'n':
numbered_lines = true;
if (optarg)
@@ -1938,16 +1632,15 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
break;
case 'N':
skip_count = false;
-@@ -1029,7 +1120,7 @@ main (int argc, char **argv)
- old_s = false;
+@@ -1013,6 +1096,7 @@ main (int argc, char **argv)
/* Reset an additional input of -s, -S dominates -s */
- col_sep_string = bad_cast ("");
-- col_sep_length = 0;
-+ col_sep_length = col_sep_width = 0;
+ col_sep_string = "";
+ col_sep_length = 0;
++ col_sep_width = 0;
use_col_separator = true;
if (optarg)
separator_string (optarg);
-@@ -1186,10 +1277,45 @@ main (int argc, char **argv)
+@@ -1168,7 +1252,8 @@ getoptnum (char const *n_str, int min, char const *err)
a number. */
static void
@@ -1955,7 +1648,12 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
+getoptarg (char *arg, char switch_char, char *character, int *character_length,
+ int *character_width, int *number)
{
- if (!ISDIGIT (*arg))
+ if (!*arg)
+ {
+@@ -1177,7 +1262,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number)
+ }
+
+ if (!c_isdigit (*arg))
- *character = *arg++;
+ {
+#ifdef HAVE_MBRTOWC
@@ -1995,7 +1693,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
if (*arg)
{
long int tmp_long;
-@@ -1211,6 +1337,11 @@ static void
+@@ -1206,6 +1325,11 @@ static void
init_parameters (int number_of_files)
{
int chars_used_by_number = 0;
@@ -2007,7 +1705,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
if (lines_per_body <= 0)
-@@ -1248,7 +1379,7 @@ init_parameters (int number_of_files)
+@@ -1243,7 +1367,7 @@ init_parameters (int number_of_files)
else
col_sep_string = column_separator;
@@ -2016,39 +1714,39 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
use_col_separator = true;
}
/* It's rather pointless to define a TAB separator with column
-@@ -1279,11 +1410,11 @@ init_parameters (int number_of_files)
- TAB_WIDTH (chars_per_input_tab, chars_per_number); */
+@@ -1275,11 +1399,11 @@ init_parameters (int number_of_files)
+ + TAB_WIDTH (chars_per_input_tab, chars_per_number); */
/* Estimate chars_per_text without any margin and keep it constant. */
- if (number_separator == '\t')
+ if (number_separator[0] == '\t')
- number_width = chars_per_number +
- TAB_WIDTH (chars_per_default_tab, chars_per_number);
+ number_width = (chars_per_number
+ + TAB_WIDTH (chars_per_default_tab, chars_per_number));
else
- number_width = chars_per_number + 1;
+ number_width = chars_per_number + number_separator_width;
/* The number is part of the column width unless we are
printing files in parallel. */
-@@ -1298,7 +1429,7 @@ init_parameters (int number_of_files)
+@@ -1288,7 +1412,7 @@ init_parameters (int number_of_files)
}
- chars_per_column = (chars_per_line - chars_used_by_number -
-- (columns - 1) * col_sep_length) / columns;
-+ (columns - 1) * col_sep_width) / columns;
-
- if (chars_per_column < 1)
- error (EXIT_FAILURE, 0, _("page width too narrow"));
-@@ -1315,7 +1446,7 @@ init_parameters (int number_of_files)
+ int sep_chars, useful_chars;
+- if (ckd_mul (&sep_chars, columns - 1, col_sep_length))
++ if (ckd_mul (&sep_chars, columns - 1, col_sep_width))
+ sep_chars = INT_MAX;
+ if (ckd_sub (&useful_chars, chars_per_line - chars_used_by_number,
+ sep_chars))
+@@ -1311,7 +1435,7 @@ init_parameters (int number_of_files)
We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
to expand a tab which is not an input_tab-char. */
free (clump_buff);
- clump_buff = xmalloc (MAX (8, chars_per_input_tab));
+ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
}
-
+
/* Open the necessary files,
-@@ -1423,7 +1554,7 @@ init_funcs (void)
+@@ -1417,7 +1541,7 @@ init_funcs (void)
/* Enlarge p->start_position of first column to use the same form of
padding_not_printed with all columns. */
@@ -2057,7 +1755,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* This loop takes care of all but the rightmost column. */
-@@ -1457,7 +1588,7 @@ init_funcs (void)
+@@ -1451,7 +1575,7 @@ init_funcs (void)
}
else
{
@@ -2066,21 +1764,21 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
h_next = h + chars_per_column;
}
}
-@@ -1748,9 +1879,9 @@ static void
+@@ -1751,9 +1875,9 @@ static void
align_column (COLUMN *p)
{
padding_not_printed = p->start_position;
-- if (padding_not_printed - col_sep_length > 0)
-+ if (padding_not_printed - col_sep_width > 0)
+- if (col_sep_length < padding_not_printed)
++ if (col_sep_width < padding_not_printed)
{
- pad_across_to (padding_not_printed - col_sep_length);
+ pad_across_to (padding_not_printed - col_sep_width);
padding_not_printed = ANYWHERE;
}
-@@ -2021,13 +2152,13 @@ store_char (char c)
+@@ -2030,13 +2154,13 @@ store_char (char c)
/* May be too generous. */
- buff = X2REALLOC (buff, &buff_allocated);
+ buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff);
}
- buff[buff_current++] = c;
+ buff[buff_current++] = (unsigned char) c;
@@ -2092,11 +1790,11 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
- int i;
+ int i, j;
char *s;
- int left_cut;
+ int num_width;
-@@ -2050,22 +2181,24 @@ add_line_number (COLUMN *p)
+@@ -2053,22 +2177,24 @@ add_line_number (COLUMN *p)
/* Tabification is assumed for multiple columns, also for n-separators,
- but `default n-separator = TAB' hasn't been given priority over
+ but 'default n-separator = TAB' hasn't been given priority over
equal column_width also specified by POSIX. */
- if (number_separator == '\t')
+ if (number_separator[0] == '\t')
@@ -2123,7 +1821,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
output_position = POS_AFTER_TAB (chars_per_output_tab,
output_position);
}
-@@ -2226,7 +2359,7 @@ print_white_space (void)
+@@ -2227,7 +2353,7 @@ print_white_space (void)
while (goal - h_old > 1
&& (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
{
@@ -2132,15 +1830,15 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
h_old = h_new;
}
while (++h_old <= goal)
-@@ -2246,6 +2379,7 @@ print_sep_string (void)
+@@ -2247,6 +2373,7 @@ print_sep_string (void)
{
- char *s;
+ char const *s = col_sep_string;
int l = col_sep_length;
+ int not_space_flag;
- s = col_sep_string;
-
-@@ -2259,6 +2393,7 @@ print_sep_string (void)
+ if (separators_not_printed <= 0)
+ {
+@@ -2258,6 +2385,7 @@ print_sep_string (void)
{
for (; separators_not_printed > 0; --separators_not_printed)
{
@@ -2148,7 +1846,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
while (l-- > 0)
{
/* 3 types of sep_strings: spaces only, spaces and chars,
-@@ -2272,12 +2407,15 @@ print_sep_string (void)
+@@ -2271,12 +2399,15 @@ print_sep_string (void)
}
else
{
@@ -2165,7 +1863,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* sep_string ends with some spaces */
if (spaces_not_printed > 0)
print_white_space ();
-@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clu
+@@ -2307,7 +2438,7 @@ print_clump (COLUMN *p, int n, char *clump)
required number of tabs and spaces. */
static void
@@ -2174,7 +1872,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
{
if (tabify_output)
{
-@@ -2329,6 +2467,74 @@ print_char (char c)
+@@ -2331,6 +2462,74 @@ print_char (char c)
putchar (c);
}
@@ -2249,31 +1947,49 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* Skip to page PAGE before printing.
PAGE may be larger than total number of pages. */
-@@ -2508,9 +2714,9 @@ read_line (COLUMN *p)
+@@ -2507,9 +2706,9 @@ read_line (COLUMN *p)
align_empty_cols = false;
}
-- if (padding_not_printed - col_sep_length > 0)
-+ if (padding_not_printed - col_sep_width > 0)
+- if (col_sep_length < padding_not_printed)
++ if (col_sep_width < padding_not_printed)
{
- pad_across_to (padding_not_printed - col_sep_length);
+ pad_across_to (padding_not_printed - col_sep_width);
padding_not_printed = ANYWHERE;
}
-@@ -2611,9 +2817,9 @@ print_stored (COLUMN *p)
+@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p)
+ COLUMN *q;
+
+ int line = p->current_line++;
+- char *first = &buff[line_vector[line]];
++ unsigned char *first = &buff[line_vector[line]];
+ /* FIXME
+ UMR: Uninitialized memory read:
+ * This is occurring while in:
+@@ -2590,7 +2789,7 @@ print_stored (COLUMN *p)
+ xmalloc [xmalloc.c:94]
+ init_store_cols [pr.c:1648]
+ */
+- char *last = &buff[line_vector[line + 1]];
++ unsigned char *last = &buff[line_vector[line + 1]];
+
+ pad_vertically = true;
+
+@@ -2610,9 +2809,9 @@ print_stored (COLUMN *p)
}
}
-- if (padding_not_printed - col_sep_length > 0)
-+ if (padding_not_printed - col_sep_width > 0)
+- if (col_sep_length < padding_not_printed)
++ if (col_sep_width < padding_not_printed)
{
- pad_across_to (padding_not_printed - col_sep_length);
+ pad_across_to (padding_not_printed - col_sep_width);
padding_not_printed = ANYWHERE;
}
-@@ -2626,8 +2832,8 @@ print_stored (COLUMN *p)
+@@ -2625,8 +2824,8 @@ print_stored (COLUMN *p)
if (spaces_not_printed == 0)
{
output_position = p->start_position + end_vector[line];
@@ -2284,7 +2000,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
}
return true;
-@@ -2646,7 +2852,7 @@ print_stored (COLUMN *p)
+@@ -2645,7 +2844,7 @@ print_stored (COLUMN *p)
number of characters is 1.) */
static int
@@ -2293,7 +2009,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
{
unsigned char uc = c;
char *s = clump_buff;
-@@ -2656,10 +2862,10 @@ char_to_clump (char c)
+@@ -2655,10 +2854,10 @@ char_to_clump (char c)
int chars;
int chars_per_c = 8;
@@ -2306,7 +2022,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
{
width = TAB_WIDTH (chars_per_c, input_position);
-@@ -2740,6 +2946,154 @@ char_to_clump (char c)
+@@ -2739,6 +2938,164 @@ char_to_clump (char c)
return chars;
}
@@ -2453,7 +2169,17 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
+ mbc_pos -= mblength;
+ }
+
-+ input_position += width;
++ /* Too many backspaces must put us in position 0 -- never negative. */
++ if (width < 0 && input_position == 0)
++ {
++ chars = 0;
++ input_position = 0;
++ }
++ else if (width < 0 && input_position <= -width)
++ input_position = 0;
++ else
++ input_position += width;
++
+ return chars;
+}
+#endif
@@ -2461,19 +2187,15 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c
/* We've just printed some files and need to clean up things before
looking for more options and printing the next batch of files.
-diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
---- coreutils-8.15-orig/src/sort.c 2013-01-30 13:39:59.892046631 +0100
-+++ coreutils-8.15/src/sort.c 2013-01-30 15:56:48.675032507 +0100
-@@ -22,11 +22,20 @@
-
- #include
-
-+#include
- #include
- #include
- #include
+diff --git a/src/sort.c b/src/sort.c
+index 05d00cc..eb51f20 100644
+--- a/src/sort.c
++++ b/src/sort.c
+@@ -30,6 +30,15 @@
#include
#include
+ #include
++
+#if HAVE_WCHAR_H
+# include
+#endif
@@ -2484,9 +2206,14 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+
#include "system.h"
#include "argmatch.h"
- #include "error.h"
-@@ -167,12 +176,34 @@ static int thousands_sep;
+ #include "assure.h"
+@@ -160,14 +169,39 @@ static int thousands_sep;
+ /* We currently ignore multi-byte grouping chars. */
+ static bool thousands_sep_ignored;
++/* True if -f is specified. */
++static bool folding;
++
/* Nonzero if the corresponding locales are hard. */
static bool hard_LC_COLLATE;
-#if HAVE_NL_LANGINFO
@@ -2521,9 +2248,9 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* The kind of blanks for '-b' to skip in various options. */
enum blanktype { bl_start, bl_end, bl_both };
-@@ -346,13 +377,11 @@ static bool reverse;
- they were read if all keys compare equal. */
- static bool stable;
+@@ -344,13 +378,11 @@ static bool stable;
+ /* An int value outside char range. */
+ enum { NON_CHAR = CHAR_MAX + 1 };
-/* If TAB has this value, blanks separate fields. */
-enum { TAB_DEFAULT = CHAR_MAX + 1 };
@@ -2538,9 +2265,9 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* Flag to remove consecutive duplicate lines from the output.
Only the last of a sequence of equal lines will be output. */
-@@ -786,6 +815,46 @@ reap_all (void)
- reap (-1);
- }
+@@ -386,6 +418,46 @@ struct tempnode
+ static struct tempnode *volatile temphead;
+ static struct tempnode *volatile *temptail = &temphead;
+/* Function pointers. */
+static void
@@ -2578,14 +2305,14 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ }
+
+ *length = (mblength < 1) ? 1 : mblength;
-+ return iswblank (wc);
++ return iswblank (wc) || wc == '\n';
+}
+#endif
+
/* Clean up any remaining temporary files. */
static void
-@@ -1218,7 +1287,7 @@ zaptemp (char const *name)
+@@ -1343,7 +1415,7 @@ zaptemp (char const *name)
free (node);
}
@@ -2594,7 +2321,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
static int
struct_month_cmp (void const *m1, void const *m2)
-@@ -1233,7 +1302,7 @@ struct_month_cmp (void const *m1, void c
+@@ -1358,7 +1430,7 @@ struct_month_cmp (void const *m1, void const *m2)
/* Initialize the character class tables. */
static void
@@ -2603,7 +2330,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
{
size_t i;
-@@ -1245,7 +1314,7 @@ inittables (void)
+@@ -1370,7 +1442,7 @@ inittables (void)
fold_toupper[i] = toupper (i);
}
@@ -2612,7 +2339,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* If we're not in the "C" locale, read different names for months. */
if (hard_LC_TIME)
{
-@@ -1327,6 +1396,84 @@ specify_nmerge (int oi, char c, char con
+@@ -1450,6 +1522,84 @@ specify_nmerge (int oi, char c, char const *s)
xstrtol_fatal (e, oi, c, long_options, s);
}
@@ -2697,7 +2424,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* Specify the amount of main memory to use when sorting. */
static void
specify_sort_size (int oi, char c, char const *s)
-@@ -1555,7 +1702,7 @@ buffer_linelim (struct buffer const *buf
+@@ -1676,7 +1826,7 @@ buffer_linelim (struct buffer const *buf)
by KEY in LINE. */
static char *
@@ -2706,7 +2433,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t sword = key->sword;
-@@ -1564,10 +1711,10 @@ begfield (struct line const *line, struc
+@@ -1685,10 +1835,10 @@ begfield (struct line const *line, struct keyfield const *key)
/* The leading field separator itself is included in a field when -t
is absent. */
@@ -2719,7 +2446,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
++ptr;
if (ptr < lim)
++ptr;
-@@ -1593,11 +1740,70 @@ begfield (struct line const *line, struc
+@@ -1718,12 +1868,71 @@ begfield (struct line const *line, struct keyfield const *key)
return ptr;
}
@@ -2785,15 +2512,16 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* Return the limit of (a pointer to the first character after) the field
in LINE specified by KEY. */
+ ATTRIBUTE_PURE
static char *
-limfield (struct line const *line, struct keyfield const *key)
-+limfield_uni (const struct line *line, const struct keyfield *key)
++limfield_uni (struct line const *line, struct keyfield const *key)
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t eword = key->eword, echar = key->echar;
-@@ -1612,10 +1818,10 @@ limfield (struct line const *line, struc
- `beginning' is the first character following the delimiting TAB.
- Otherwise, leave PTR pointing at the first `blank' character after
+@@ -1738,10 +1947,10 @@ limfield (struct line const *line, struct keyfield const *key)
+ 'beginning' is the first character following the delimiting TAB.
+ Otherwise, leave PTR pointing at the first 'blank' character after
the preceding field. */
- if (tab != TAB_DEFAULT)
+ if (tab_length)
@@ -2804,7 +2532,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
++ptr;
if (ptr < lim && (eword || echar))
++ptr;
-@@ -1661,10 +1867,10 @@ limfield (struct line const *line, struc
+@@ -1787,10 +1996,10 @@ limfield (struct line const *line, struct keyfield const *key)
*/
/* Make LIM point to the end of (one byte past) the current field. */
@@ -2817,12 +2545,12 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
if (newlim)
lim = newlim;
}
-@@ -1695,6 +1901,130 @@ limfield (struct line const *line, struc
+@@ -1825,6 +2034,130 @@ limfield (struct line const *line, struct keyfield const *key)
return ptr;
}
+#if HAVE_MBRTOWC
-+static char *
++static char * _GL_ATTRIBUTE_PURE
+limfield_mb (const struct line *line, const struct keyfield *key)
+{
+ char *ptr = line->text, *lim = ptr + line->length - 1;
@@ -2906,7 +2634,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ {
+ /* If we're skipping leading blanks, don't start counting characters
+ * until after skipping past any leading blanks. */
-+ if (key->skipsblanks)
++ if (key->skipeblanks)
+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+
@@ -2948,7 +2676,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
/* Fill BUF reading from FP, moving buf->left bytes from the end
of buf->buf to the beginning first. If EOF is reached and the
file wasn't terminated by a newline, supply one. Set up BUF's line
-@@ -1781,8 +2111,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
+@@ -1911,8 +2244,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
else
{
if (key->skipsblanks)
@@ -2973,16 +2701,32 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
line->keybeg = line_start;
}
}
-@@ -1903,7 +2247,7 @@ human_numcompare (char const *a, char co
- hideously fast. */
+@@ -2050,12 +2397,10 @@ find_unit_order (char const *number)
+ ATTRIBUTE_PURE
+ static int
+-human_numcompare (char const *a, char const *b)
++human_numcompare (char *a, char *b)
+ {
+- while (blanks[to_uchar (*a)])
+- a++;
+- while (blanks[to_uchar (*b)])
+- b++;
++ skipblanks(&a, a + strlen(a));
++ skipblanks(&b, b + strlen(b));
+
+ int diff = find_unit_order (a) - find_unit_order (b);
+ return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep));
+@@ -2067,7 +2412,7 @@ human_numcompare (char const *a, char const *b)
+
+ ATTRIBUTE_PURE
static int
-numcompare (char const *a, char const *b)
+numcompare_uni (const char *a, const char *b)
{
while (blanks[to_uchar (*a)])
a++;
-@@ -1913,6 +2257,25 @@ numcompare (char const *a, char const *b
+@@ -2077,6 +2422,25 @@ numcompare (char const *a, char const *b)
return strnumcmp (a, b, decimal_point, thousands_sep);
}
@@ -3005,10 +2749,10 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+}
+#endif /* HAV_EMBRTOWC */
+
- /* Work around a problem whereby the long double value returned by glibc's
- strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
- A and B before calling strtold. FIXME: remove this function once
-@@ -1963,7 +2326,7 @@ general_numcompare (char const *sa, char
+ static int
+ nan_compare (long double a, long double b)
+ {
+@@ -2118,7 +2482,7 @@ general_numcompare (char const *sa, char const *sb)
Return 0 if the name in S is not recognized. */
static int
@@ -3017,7 +2761,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
{
size_t lo = 0;
size_t hi = MONTHS_PER_YEAR;
-@@ -2238,15 +2601,14 @@ debug_key (struct line const *line, stru
+@@ -2457,15 +2821,14 @@ debug_key (struct line const *line, struct keyfield const *key)
char saved = *lim;
*lim = '\0';
@@ -3035,17 +2779,67 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
else if (key->general_numeric)
ignore_value (strtold (beg, &tighter_lim));
else if (key->numeric || key->human_numeric)
-@@ -2390,7 +2752,7 @@ key_warnings (struct keyfield const *gke
- bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
- && !(key->schar || key->echar);
+@@ -2611,7 +2974,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
+ /* Warn about significant leading blanks. */
+ bool implicit_skip = key_numeric (key) || key->month;
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
-- if (!gkey_only && tab == TAB_DEFAULT && !line_offset
-+ if (!gkey_only && !tab_length && !line_offset
- && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
+- if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset
++ if (!zero_width && !gkey_only && !tab_length && !line_offset
+ && ((!key->skipsblanks && !implicit_skip)
|| (!key->skipsblanks && key->schar)
|| (!key->skipeblanks && key->echar)))
-@@ -2448,11 +2810,87 @@ key_warnings (struct keyfield const *gke
- error (0, 0, _("option `-r' only applies to last-resort comparison"));
+@@ -2659,9 +3022,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
+ bool number_locale_warned = false;
+ if (basic_numeric_field_span)
+ {
+- if (tab == TAB_DEFAULT
+- ? thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep)))
+- : tab == thousands_sep)
++ if (tab_length
++ ? tab[0] == thousands_sep
++ : thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep))))
+ {
+ error (0, 0,
+ _("field separator %s is treated as a "
+@@ -2672,9 +3035,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
+ }
+ if (basic_numeric_field_span || general_numeric_field_span)
+ {
+- if (tab == TAB_DEFAULT
+- ? thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point)))
+- : tab == decimal_point)
++ if (tab_length
++ ? tab[0] == decimal_point
++ : thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point))))
+ {
+ error (0, 0,
+ _("field separator %s is treated as a "
+@@ -2682,19 +3045,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
+ quote (((char []) {decimal_point, 0})));
+ number_locale_warned = true;
+ }
+- else if (tab == '-')
++ else if (tab_length && tab[0] == '-')
+ {
+ error (0, 0,
+ _("field separator %s is treated as a "
+ "minus sign in numbers"),
+- quote (((char []) {tab, 0})));
++ quote (((char []) {tab[0], 0})));
+ }
+- else if (general_numeric_field_span && tab == '+')
++ else if (general_numeric_field_span && tab_length && tab[0] == '+')
+ {
+ error (0, 0,
+ _("field separator %s is treated as a "
+ "plus sign in numbers"),
+- quote (((char []) {tab, 0})));
++ quote (((char []) {tab[0], 0})));
+ }
+ }
+
+@@ -2746,11 +3109,87 @@ diff_reversed (int diff, bool reversed)
+ return reversed ? _GL_CMP (0, diff) : diff;
}
+#if HAVE_MBRTOWC
@@ -3057,8 +2851,8 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ register int lo = 0, hi = MONTHS_PER_YEAR, result;
+ char *tmp;
+ size_t wclength, mblength;
-+ const char **pp;
-+ const wchar_t **wpp;
++ const char *pp;
++ const wchar_t *wpp;
+ wchar_t *month_wcs;
+ mbstate_t state;
+
@@ -3071,17 +2865,19 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ if (len == 0)
+ return 0;
+
-+ month = (char *) xmalloc (len + 1);
++ if (SIZE_MAX - len < 1)
++ xalloc_die ();
+
-+ tmp = (char *) xmalloc (len + 1);
++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX);
++
++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX);
+ memcpy (tmp, s, len);
+ tmp[len] = '\0';
-+ pp = (const char **)&tmp;
-+ month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t));
-+ memset (&state, '\0', sizeof(mbstate_t));
++ wpp = month_wcs = (wchar_t *) xnmalloc (len + 1, sizeof (wchar_t));
++ memset (&state, '\0', sizeof (mbstate_t));
+
-+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
-+ if (wclength == (size_t)-1 || *pp != NULL)
++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state);
++ if (wclength == (size_t)-1 || pp != NULL)
+ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
+
+ for (i = 0; i < wclength; i++)
@@ -3094,10 +2890,8 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ }
+ }
+
-+ wpp = (const wchar_t **)&month_wcs;
-+
-+ mblength = wcsrtombs (month, wpp, len + 1, &state);
-+ assert (mblength != (-1) && *wpp == NULL);
++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state);
++ assert (mblength != (-1) && wpp == NULL);
+
+ do
+ {
@@ -3114,7 +2908,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ ? monthtab[lo].val : 0);
+
+ if (ea && result)
-+ *ea = s + strlen (monthtab[lo].name);
++ *ea = (char*) s + strlen (monthtab[lo].name);
+
+ free (month);
+ free (tmp);
@@ -3133,17 +2927,17 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
{
struct keyfield *key = keylist;
-@@ -2537,7 +2975,7 @@ keycompare (struct line const *a, struct
+@@ -2831,7 +3270,7 @@ keycompare (struct line const *a, struct line const *b)
else if (key->human_numeric)
diff = human_numcompare (ta, tb);
else if (key->month)
-- diff = getmonth (ta, NULL) - getmonth (tb, NULL);
-+ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL);
+- diff = getmonth (ta, nullptr) - getmonth (tb, nullptr);
++ diff = getmonth (ta, tlena, nullptr) - getmonth (tb, tlenb, nullptr);
else if (key->random)
diff = compare_random (ta, tlena, tb, tlenb);
else if (key->version)
-@@ -2653,6 +3091,181 @@ keycompare (struct line const *a, struct
- return key->reverse ? -diff : diff;
+@@ -2941,6 +3380,211 @@ keycompare (struct line const *a, struct line const *b)
+ return diff_reversed (diff, key->reverse);
}
+#if HAVE_MBRTOWC
@@ -3163,45 +2957,14 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ wchar_t wc_a, wc_b;
+ mbstate_t state_a, state_b;
+
-+ int diff;
++ int diff = 0;
+
+ memset (&state_a, '\0', sizeof(mbstate_t));
+ memset (&state_b, '\0', sizeof(mbstate_t));
++ /* Ignore keys with start after end. */
++ if (a->keybeg - a->keylim > 0)
++ return 0;
+
-+ for (;;)
-+ {
-+ char const *translate = key->translate;
-+ bool const *ignore = key->ignore;
-+
-+ /* Find the lengths. */
-+ size_t lena = lima <= texta ? 0 : lima - texta;
-+ size_t lenb = limb <= textb ? 0 : limb - textb;
-+
-+ /* Actually compare the fields. */
-+ if (key->random)
-+ diff = compare_random (texta, lena, textb, lenb);
-+ else if (key->numeric | key->general_numeric | key->human_numeric)
-+ {
-+ char savea = *lima, saveb = *limb;
-+
-+ *lima = *limb = '\0';
-+ diff = (key->numeric ? numcompare (texta, textb)
-+ : key->general_numeric ? general_numcompare (texta, textb)
-+ : human_numcompare (texta, textb));
-+ *lima = savea, *limb = saveb;
-+ }
-+ else if (key->version)
-+ diff = filevercmp (texta, textb);
-+ else if (key->month)
-+ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL);
-+ else
-+ {
-+ if (ignore || translate)
-+ {
-+ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1);
-+ char *copy_b = copy_a + lena + 1;
-+ size_t new_len_a, new_len_b;
-+ size_t i, j;
+
+ /* Ignore and/or translate chars before comparing. */
+# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \
@@ -3269,19 +3032,81 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ COPY[NEW_LEN] = '\0'; \
+ } \
+ while (0)
-+ IGNORE_CHARS (new_len_a, lena, texta, copy_a,
-+ wc_a, mblength_a, state_a);
-+ IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
-+ wc_b, mblength_b, state_b);
-+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
-+ free(copy_a);
-+ }
-+ else if (lena == 0)
-+ diff = - NONZERO (lenb);
-+ else if (lenb == 0)
-+ goto greater;
-+ else
-+ diff = xmemcoll (texta, lena, textb, lenb);
++
++ /* Actually compare the fields. */
++
++ for (;;)
++ {
++ /* Find the lengths. */
++ size_t lena = lima <= texta ? 0 : lima - texta;
++ size_t lenb = limb <= textb ? 0 : limb - textb;
++
++ char enda IF_LINT (= 0);
++ char endb IF_LINT (= 0);
++
++ char const *translate = key->translate;
++ bool const *ignore = key->ignore;
++
++ if (ignore || translate)
++ {
++ if (SIZE_MAX - lenb - 2 < lena)
++ xalloc_die ();
++ char *copy_a = (char *) xnmalloc (lena + lenb + 2, MB_CUR_MAX);
++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1;
++ size_t new_len_a, new_len_b;
++ size_t i, j;
++
++ IGNORE_CHARS (new_len_a, lena, texta, copy_a,
++ wc_a, mblength_a, state_a);
++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
++ wc_b, mblength_b, state_b);
++ texta = copy_a; textb = copy_b;
++ lena = new_len_a; lenb = new_len_b;
++ }
++ else
++ {
++ /* Use the keys in-place, temporarily null-terminated. */
++ enda = texta[lena]; texta[lena] = '\0';
++ endb = textb[lenb]; textb[lenb] = '\0';
++ }
++
++ if (key->random)
++ diff = compare_random (texta, lena, textb, lenb);
++ else if (key->numeric | key->general_numeric | key->human_numeric)
++ {
++ char savea = *lima, saveb = *limb;
++
++ *lima = *limb = '\0';
++ diff = (key->numeric ? numcompare (texta, textb)
++ : key->general_numeric ? general_numcompare (texta, textb)
++ : human_numcompare (texta, textb));
++ *lima = savea, *limb = saveb;
++ }
++ else if (key->version)
++ diff = filevercmp (texta, textb);
++ else if (key->month)
++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL);
++ else if (lena == 0)
++ diff = - NONZERO (lenb);
++ else if (lenb == 0)
++ diff = 1;
++ else if (hard_LC_COLLATE && !folding)
++ {
++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1);
++ }
++ else
++ {
++ diff = memcmp (texta, textb, MIN (lena, lenb));
++ if (diff == 0)
++ diff = lena < lenb ? -1 : lena != lenb;
++ }
++
++ if (ignore || translate)
++ free (texta);
++ else
++ {
++ texta[lena] = enda;
++ textb[lenb] = endb;
+ }
+
+ if (diff)
@@ -3312,19 +3137,35 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+ }
+ }
+
-+ return 0;
-+
-+greater:
-+ diff = 1;
+not_equal:
-+ return key->reverse ? -diff : diff;
++ if (key && key->reverse)
++ return -diff;
++ else
++ return diff;
+}
+#endif
+
/* Compare two lines A and B, returning negative, zero, or positive
depending on whether A compares less than, equal to, or greater than B. */
-@@ -4113,7 +4726,7 @@ main (int argc, char **argv)
+@@ -2968,7 +3612,7 @@ compare (struct line const *a, struct line const *b)
+ diff = - NONZERO (blen);
+ else if (blen == 0)
+ diff = 1;
+- else if (hard_LC_COLLATE)
++ else if (hard_LC_COLLATE && !folding)
+ {
+ /* xmemcoll0 is a performance enhancement as
+ it will not unconditionally write '\0' after the
+@@ -4340,6 +4984,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
+ break;
+ case 'f':
+ key->translate = fold_toupper;
++ folding = true;
+ break;
+ case 'g':
+ key->general_numeric = true;
+@@ -4419,7 +5064,7 @@ main (int argc, char **argv)
initialize_exit_failure (SORT_FAILURE);
hard_LC_COLLATE = hard_locale (LC_COLLATE);
@@ -3333,8 +3174,8 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
hard_LC_TIME = hard_locale (LC_TIME);
#endif
-@@ -4134,6 +4747,29 @@ main (int argc, char **argv)
- thousands_sep = -1;
+@@ -4442,6 +5087,29 @@ main (int argc, char **argv)
+ thousands_sep = NON_CHAR;
}
+#if HAVE_MBRTOWC
@@ -3363,7 +3204,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
have_read_stdin = false;
inittables ();
-@@ -4404,13 +5040,34 @@ main (int argc, char **argv)
+@@ -4717,13 +5385,34 @@ main (int argc, char **argv)
case 't':
{
@@ -3396,20 +3237,19 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
+#endif
+ if (newtab_length == 1 && optarg[1])
{
- if (STREQ (optarg, "\\0"))
+ if (streq (optarg, "\\0"))
- newtab = '\0';
+ newtab[0] = '\0';
else
{
- /* Provoke with `sort -txx'. Complain about
-@@ -4421,9 +5078,12 @@ main (int argc, char **argv)
+ /* Provoke with 'sort -txx'. Complain about
+@@ -4734,9 +5423,11 @@ main (int argc, char **argv)
quote (optarg));
}
}
- if (tab != TAB_DEFAULT && tab != newtab)
-+ if (tab_length
-+ && (tab_length != newtab_length
-+ || memcmp (tab, newtab, tab_length) != 0))
++ if (tab_length && (tab_length != newtab_length
++ || memcmp (tab, newtab, tab_length) != 0))
error (SORT_FAILURE, 0, _("incompatible tabs"));
- tab = newtab;
+ memcpy (tab, newtab, newtab_length);
@@ -3417,783 +3257,1027 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c
}
break;
-diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c
---- coreutils-8.15-orig/src/unexpand.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/unexpand.c 2013-01-30 13:40:37.358398268 +0100
-@@ -39,12 +39,29 @@
+diff --git a/src/unexpand.c b/src/unexpand.c
+index ff234d7..7c36ef6 100644
+--- a/src/unexpand.c
++++ b/src/unexpand.c
+@@ -39,6 +39,9 @@
#include
#include
#include
+
-+/* Get mbstate_t, mbrtowc(), wcwidth(). */
-+#if HAVE_WCHAR_H
-+# include
-+#endif
++#include
+
#include "system.h"
- #include "error.h"
- #include "fadvise.h"
- #include "quote.h"
- #include "xstrndup.h"
+ #include "expand-common.h"
-+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
-+ installation; work around this configuration error. */
-+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
-+# define MB_LEN_MAX 16
-+#endif
-+
-+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-+#if HAVE_MBRTOWC && defined mbstate_t
-+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-+#endif
-+
- /* The official name of this program (e.g., no `g' prefix). */
- #define PROGRAM_NAME "unexpand"
+@@ -105,24 +108,46 @@ unexpand (void)
+ {
+ /* Input stream. */
+ FILE *fp = next_file (nullptr);
++ mb_file_t mbf;
-@@ -104,6 +121,208 @@ static struct option const longopts[] =
- {NULL, 0, NULL, 0}
- };
+ /* The array of pending blanks. In non-POSIX locales, blanks can
+ include characters other than spaces, so the blanks must be
+ stored, not merely counted. */
+- char *pending_blank;
++ mbf_char_t *pending_blank;
++ /* True if the starting locale is utf8. */
++ bool using_utf_locale;
++
++ /* True if the first file contains BOM header. */
++ bool found_bom;
++ using_utf_locale=check_utf_locale();
-+static FILE *next_file (FILE *fp);
+ if (!fp)
+ return;
+
++ mbf_init (mbf, fp);
++ found_bom=check_bom(fp,&mbf);
+
-+#if HAVE_MBRTOWC
-+static void
-+unexpand_multibyte (void)
-+{
-+ FILE *fp; /* Input stream. */
-+ mbstate_t i_state; /* Current shift state of the input stream. */
-+ mbstate_t i_state_bak; /* Back up the I_STATE. */
-+ mbstate_t o_state; /* Current shift state of the output stream. */
-+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */
-+ char *bufpos = buf; /* Next read position of BUF. */
-+ size_t buflen = 0; /* The length of the byte sequence in buf. */
-+ wint_t wc; /* A gotten wide character. */
-+ size_t mblength; /* The byte size of a multibyte character
-+ which shows as same character as WC. */
-+
-+ /* Index in `tab_list' of next tabstop: */
-+ int tab_index = 0; /* For calculating width of pending tabs. */
-+ int print_tab_index = 0; /* For printing as many tabs as possible. */
-+ unsigned int column = 0; /* Column on screen of next char. */
-+ int next_tab_column; /* Column the next tab stop is on. */
-+ int convert = 1; /* If nonzero, perform translations. */
-+ unsigned int pending = 0; /* Pending columns of blanks. */
-+
-+ fp = next_file ((FILE *) NULL);
-+ if (fp == NULL)
-+ return;
-+
-+ memset (&o_state, '\0', sizeof(mbstate_t));
-+ memset (&i_state, '\0', sizeof(mbstate_t));
-+
-+ for (;;)
++ if (using_utf_locale == false && found_bom == true)
+ {
-+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp))
-+ {
-+ memmove (buf, bufpos, buflen);
-+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp);
-+ bufpos = buf;
-+ }
-+
-+ /* Get a wide character. */
-+ if (buflen < 1)
-+ {
-+ mblength = 1;
-+ wc = WEOF;
-+ }
-+ else
-+ {
-+ i_state_bak = i_state;
-+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state);
-+ }
-+
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ i_state = i_state_bak;
-+ wc = L'\0';
-+ }
-+
-+ if (wc == L' ' && convert && column < INT_MAX)
-+ {
-+ ++pending;
-+ ++column;
-+ }
-+ else if (wc == L'\t' && convert)
-+ {
-+ if (tab_size == 0)
-+ {
-+ /* Do not let tab_index == first_free_tab;
-+ stop when it is 1 less. */
-+ while (tab_index < first_free_tab - 1
-+ && column >= tab_list[tab_index])
-+ tab_index++;
-+ next_tab_column = tab_list[tab_index];
-+ if (tab_index < first_free_tab - 1)
-+ tab_index++;
-+ if (column >= next_tab_column)
-+ {
-+ convert = 0; /* Ran out of tab stops. */
-+ goto flush_pend_mb;
-+ }
-+ }
-+ else
-+ {
-+ next_tab_column = column + tab_size - column % tab_size;
-+ }
-+ pending += next_tab_column - column;
-+ column = next_tab_column;
-+ }
-+ else
-+ {
-+flush_pend_mb:
-+ /* Flush pending spaces. Print as many tabs as possible,
-+ then print the rest as spaces. */
-+ if (pending == 1)
-+ {
-+ putchar (' ');
-+ pending = 0;
-+ }
-+ column -= pending;
-+ while (pending > 0)
-+ {
-+ if (tab_size == 0)
-+ {
-+ /* Do not let print_tab_index == first_free_tab;
-+ stop when it is 1 less. */
-+ while (print_tab_index < first_free_tab - 1
-+ && column >= tab_list[print_tab_index])
-+ print_tab_index++;
-+ next_tab_column = tab_list[print_tab_index];
-+ if (print_tab_index < first_free_tab - 1)
-+ print_tab_index++;
-+ }
-+ else
-+ {
-+ next_tab_column =
-+ column + tab_size - column % tab_size;
-+ }
-+ if (next_tab_column - column <= pending)
-+ {
-+ putchar ('\t');
-+ pending -= next_tab_column - column;
-+ column = next_tab_column;
-+ }
-+ else
-+ {
-+ --print_tab_index;
-+ column += pending;
-+ while (pending != 0)
-+ {
-+ putchar (' ');
-+ pending--;
-+ }
-+ }
-+ }
-+
-+ if (wc == WEOF)
-+ {
-+ fp = next_file (fp);
-+ if (fp == NULL)
-+ break; /* No more files. */
-+ else
-+ {
-+ memset (&i_state, '\0', sizeof(mbstate_t));
-+ continue;
-+ }
-+ }
-+
-+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
-+ {
-+ if (convert)
-+ {
-+ ++column;
-+ if (convert_entire_line == 0)
-+ convert = 0;
-+ }
-+ mblength = 1;
-+ putchar (buf[0]);
-+ }
-+ else if (mblength == 0)
-+ {
-+ if (convert && convert_entire_line == 0)
-+ convert = 0;
-+ mblength = 1;
-+ putchar ('\0');
-+ }
-+ else
-+ {
-+ if (convert)
-+ {
-+ if (wc == L'\b')
-+ {
-+ if (column > 0)
-+ --column;
-+ }
-+ else
-+ {
-+ int width; /* The width of WC. */
-+
-+ width = wcwidth (wc);
-+ column += (width > 0) ? width : 0;
-+ if (convert_entire_line == 0)
-+ convert = 0;
-+ }
-+ }
-+
-+ if (wc == L'\n')
-+ {
-+ tab_index = print_tab_index = 0;
-+ column = pending = 0;
-+ convert = 1;
-+ }
-+ fwrite (bufpos, sizeof(char), mblength, stdout);
-+ }
-+ }
-+ buflen -= mblength;
-+ bufpos += mblength;
-+ }
-+}
-+#endif
-+
-+
- void
- usage (int status)
- {
-@@ -526,7 +745,12 @@ main (int argc, char **argv)
-
- file_list = (optind < argc ? &argv[optind] : stdin_argv);
-
-- unexpand ();
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ unexpand_multibyte ();
-+ else
-+#endif
-+ unexpand ();
-
- if (have_read_stdin && fclose (stdin) != 0)
- error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c
---- coreutils-8.15-orig/src/uniq.c 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/src/uniq.c 2013-01-30 15:54:04.584020982 +0100
-@@ -21,6 +21,16 @@
- #include
- #include
-
-+/* Get mbstate_t, mbrtowc(). */
-+#if HAVE_WCHAR_H
-+# include
-+#endif
-+
-+/* Get isw* functions. */
-+#if HAVE_WCTYPE_H
-+# include
-+#endif
-+
- #include "system.h"
- #include "argmatch.h"
- #include "linebuffer.h"
-@@ -32,7 +42,19 @@
- #include "stdio--.h"
- #include "xmemcoll.h"
- #include "xstrtol.h"
--#include "memcasecmp.h"
-+#include "xmemcoll.h"
-+
-+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
-+ installation; work around this configuration error. */
-+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
-+# define MB_LEN_MAX 16
-+#endif
-+
-+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-+#if HAVE_MBRTOWC && defined mbstate_t
-+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-+#endif
-+
-
- /* The official name of this program (e.g., no `g' prefix). */
- #define PROGRAM_NAME "uniq"
-@@ -108,6 +130,10 @@ static enum delimit_method const delimit
- /* Select whether/how to delimit groups of duplicate lines. */
- static enum delimit_method delimit_groups;
-
-+/* Function pointers. */
-+static char *
-+(*find_field) (struct linebuffer *line);
-+
- static struct option const longopts[] =
- {
- {"count", no_argument, NULL, 'c'},
-@@ -207,7 +233,7 @@ size_opt (char const *opt, char const *m
- return a pointer to the beginning of the line's field to be compared. */
-
- static char * _GL_ATTRIBUTE_PURE
--find_field (struct linebuffer const *line)
-+find_field_uni (struct linebuffer *line)
- {
- size_t count;
- char const *lp = line->buffer;
-@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin
- return line->buffer + i;
- }
-
-+#if HAVE_MBRTOWC
-+
-+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \
-+ do \
-+ { \
-+ mbstate_t state_bak; \
-+ \
-+ CONVFAIL = 0; \
-+ state_bak = *STATEP; \
-+ \
-+ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \
-+ \
-+ switch (MBLENGTH) \
-+ { \
-+ case (size_t)-2: \
-+ case (size_t)-1: \
-+ *STATEP = state_bak; \
-+ CONVFAIL++; \
-+ /* Fall through */ \
-+ case 0: \
-+ MBLENGTH = 1; \
-+ } \
-+ } \
-+ while (0)
-+
-+static char *
-+find_field_multi (struct linebuffer *line)
-+{
-+ size_t count;
-+ char *lp = line->buffer;
-+ size_t size = line->length - 1;
-+ size_t pos;
-+ size_t mblength;
-+ wchar_t wc;
-+ mbstate_t *statep;
-+ int convfail = 0;
-+
-+ pos = 0;
-+ statep = &(line->state);
-+
-+ /* skip fields. */
-+ for (count = 0; count < skip_fields && pos < size; count++)
-+ {
-+ while (pos < size)
++ /* Try using some predefined locale */
++ if (set_utf_locale () != 0)
+ {
-+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
-+
-+ if (convfail || !iswblank (wc))
-+ {
-+ pos += mblength;
-+ break;
-+ }
-+ pos += mblength;
-+ }
-+
-+ while (pos < size)
-+ {
-+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
-+
-+ if (!convfail && iswblank (wc))
-+ break;
-+
-+ pos += mblength;
++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
+ }
+ }
+
-+ /* skip fields. */
-+ for (count = 0; count < skip_chars && pos < size; count++)
-+ {
-+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
-+ pos += mblength;
-+ }
+ /* The worst case is a non-blank character, then one blank, then a
+ tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so
+ allocate MAX_COLUMN_WIDTH bytes to store the blanks. */
+- pending_blank = ximalloc (max_column_width);
++ pending_blank = ximalloc (max_column_width * sizeof (mbf_char_t));
+
-+ return lp + pos;
-+}
-+#endif
-+
- /* Return false if two strings OLD and NEW match, true if not.
- OLD and NEW point not to the beginnings of the lines
- but rather to the beginnings of the fields to compare.
-@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin
- static bool
- different (char *old, char *new, size_t oldlen, size_t newlen)
- {
-+ char *copy_old, *copy_new;
-+
- if (check_chars < oldlen)
- oldlen = check_chars;
- if (check_chars < newlen)
-@@ -242,14 +347,100 @@ different (char *old, char *new, size_t
++ if (found_bom == true)
++ print_bom();
- if (ignore_case)
+ while (true)
{
-- /* FIXME: This should invoke strcoll somehow. */
-- return oldlen != newlen || memcasecmp (old, new, oldlen);
-+ size_t i;
-+
-+ copy_old = xmalloc (oldlen + 1);
-+ copy_new = xmalloc (oldlen + 1);
-+
-+ for (i = 0; i < oldlen; i++)
-+ {
-+ copy_old[i] = toupper (old[i]);
-+ copy_new[i] = toupper (new[i]);
-+ }
-+ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen);
-+ free (copy_old);
-+ free (copy_new);
-+ return rc;
- }
-- else if (hard_LC_COLLATE)
-- return xmemcoll (old, oldlen, new, newlen) != 0;
- else
-- return oldlen != newlen || memcmp (old, new, oldlen);
-+ {
-+ copy_old = (char *)old;
-+ copy_new = (char *)new;
-+ }
-+
-+ return xmemcoll (copy_old, oldlen, copy_new, newlen);
-+}
-+
-+#if HAVE_MBRTOWC
-+static int
-+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate)
-+{
-+ size_t i, j, chars;
-+ const char *str[2];
-+ char *copy[2];
-+ size_t len[2];
-+ mbstate_t state[2];
-+ size_t mblength;
-+ wchar_t wc, uwc;
-+ mbstate_t state_bak;
-+
-+ str[0] = old;
-+ str[1] = new;
-+ len[0] = oldlen;
-+ len[1] = newlen;
-+ state[0] = oldstate;
-+ state[1] = newstate;
-+
-+ for (i = 0; i < 2; i++)
-+ {
-+ copy[i] = xmalloc (len[i] + 1);
-+
-+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
-+ {
-+ state_bak = state[i];
-+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i]));
-+
-+ switch (mblength)
-+ {
-+ case (size_t)-1:
-+ case (size_t)-2:
-+ state[i] = state_bak;
-+ /* Fall through */
-+ case 0:
-+ mblength = 1;
-+ break;
-+
-+ default:
-+ if (ignore_case)
-+ {
-+ uwc = towupper (wc);
-+
-+ if (uwc != wc)
-+ {
-+ mbstate_t state_wc;
-+
-+ memset (&state_wc, '\0', sizeof(mbstate_t));
-+ wcrtomb (copy[i] + j, uwc, &state_wc);
-+ }
-+ else
-+ memcpy (copy[i] + j, str[i] + j, mblength);
-+ }
-+ else
-+ memcpy (copy[i] + j, str[i] + j, mblength);
-+ }
-+ j += mblength;
-+ }
-+ copy[i][j] = '\0';
-+ len[i] = j;
-+ }
-+
-+ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]);
-+ free (copy[0]);
-+ free (copy[1]);
-+ return rc;
-+
- }
-+#endif
+ /* Input character, or EOF. */
+- int c;
++ mbf_char_t c;
- /* Output the line in linebuffer LINE to standard output
- provided that the switches say it should be output.
-@@ -305,15 +496,43 @@ check_file (const char *infile, const ch
- {
- char *prevfield IF_LINT ( = NULL);
- size_t prevlen IF_LINT ( = 0);
-+#if HAVE_MBRTOWC
-+ mbstate_t prevstate;
-+
-+ memset (&prevstate, '\0', sizeof (mbstate_t));
-+#endif
+ /* If true, perform translations. */
+ bool convert = true;
+@@ -156,12 +181,44 @@ unexpand (void)
- while (!feof (stdin))
+ do
{
- char *thisfield;
- size_t thislen;
-+#if HAVE_MBRTOWC
-+ mbstate_t thisstate;
-+#endif
-+
- if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
- break;
- thisfield = find_field (thisline);
- thislen = thisline->length - 1 - (thisfield - thisline->buffer);
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ {
-+ thisstate = thisline->state;
-+
-+ if (prevline->length == 0 || different_multi
-+ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate))
+- while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
+- continue;
++ while (true) {
++ mbf_getc (c, mbf);
++ if ((mb_iseof (c)) && (fp = next_file (fp)))
+ {
-+ fwrite (thisline->buffer, sizeof (char),
-+ thisline->length, stdout);
-+
-+ SWAP_LINES (prevline, thisline);
-+ prevfield = thisfield;
-+ prevlen = thislen;
-+ prevstate = thisstate;
++ mbf_init (mbf, fp);
++ if (fp!=NULL)
++ {
++ if (check_bom(fp,&mbf)==true)
++ {
++ /*Not the first file - check BOM header*/
++ if (using_utf_locale==false && found_bom==false)
++ {
++ /*BOM header in subsequent file but not in the first one. */
++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
++ }
++ }
++ else
++ {
++ if(using_utf_locale==false && found_bom==true)
++ {
++ /*First file conatined BOM header - locale was switched to UTF
++ *all subsequent files should contain BOM. */
++ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
++ }
++ }
++ }
++ continue;
++ }
++ else
++ {
++ break;
+ }
-+ }
-+ else
-+#endif
- if (prevline->length == 0
- || different (thisfield, prevfield, thislen, prevlen))
- {
-@@ -332,17 +551,26 @@ check_file (const char *infile, const ch
- size_t prevlen;
- uintmax_t match_count = 0;
- bool first_delimiter = true;
-+#if HAVE_MBRTOWC
-+ mbstate_t prevstate;
-+#endif
-
- if (readlinebuffer_delim (prevline, stdin, delimiter) == 0)
- goto closefiles;
- prevfield = find_field (prevline);
- prevlen = prevline->length - 1 - (prevfield - prevline->buffer);
-+#if HAVE_MBRTOWC
-+ prevstate = prevline->state;
-+#endif
-
- while (!feof (stdin))
- {
- bool match;
- char *thisfield;
- size_t thislen;
-+#if HAVE_MBRTOWC
-+ mbstate_t thisstate = thisline->state;
-+#endif
- if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
- {
- if (ferror (stdin))
-@@ -351,6 +579,14 @@ check_file (const char *infile, const ch
- }
- thisfield = find_field (thisline);
- thislen = thisline->length - 1 - (thisfield - thisline->buffer);
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ {
-+ match = !different_multi (thisfield, prevfield,
-+ thislen, prevlen, thisstate, prevstate);
+ }
-+ else
-+#endif
- match = !different (thisfield, prevfield, thislen, prevlen);
- match_count += match;
++
-@@ -383,6 +619,9 @@ check_file (const char *infile, const ch
- SWAP_LINES (prevline, thisline);
- prevfield = thisfield;
- prevlen = thislen;
-+#if HAVE_MBRTOWC
-+ prevstate = thisstate;
-+#endif
- if (!match)
- match_count = 0;
+ if (convert)
+ {
+- bool blank = !! isblank (c);
++ bool blank = mb_isblank (c);
+
+ if (blank)
+ {
+@@ -175,16 +232,16 @@ unexpand (void)
+
+ if (convert)
+ {
+- if (c == '\t')
++ if (mb_iseq (c, '\t'))
+ {
+ column = next_tab_column;
+
+ if (pending)
+- pending_blank[0] = '\t';
++ mb_setascii (&pending_blank[0], '\t');
+ }
+ else
+ {
+- column++;
++ column += mb_width (c);
+
+ if (! (prev_blank && column == next_tab_column))
+ {
+@@ -192,13 +249,14 @@ unexpand (void)
+ will be replaced by tabs. */
+ if (column == next_tab_column)
+ one_blank_before_tab_stop = true;
+- pending_blank[pending++] = c;
++ mb_copy (&pending_blank[pending++], &c);
+ prev_blank = true;
+ continue;
+ }
+
+ /* Replace the pending blanks by a tab or two. */
+- pending_blank[0] = c = '\t';
++ mb_setascii (&c, '\t');
++ mb_setascii (&pending_blank[0], '\t');
+ }
+
+ /* Discard pending blanks, unless it was a single
+@@ -206,7 +264,7 @@ unexpand (void)
+ pending = one_blank_before_tab_stop;
+ }
+ }
+- else if (c == '\b')
++ else if (mb_iseq (c, '\b'))
+ {
+ /* Go back one column, and force recalculation of the
+ next tab stop. */
+@@ -216,16 +274,20 @@ unexpand (void)
+ }
+ else
+ {
+- column++;
+- if (!column)
++ const uintmax_t orig_column = column;
++ column += mb_width (c);
++ if (column < orig_column)
+ error (EXIT_FAILURE, 0, _("input line is too long"));
+ }
+
+ if (pending)
+ {
+ if (pending > 1 && one_blank_before_tab_stop)
+- pending_blank[0] = '\t';
+- if (fwrite (pending_blank, 1, pending, stdout) != pending)
++ mb_setascii (&pending_blank[0], '\t');
++
++ for (int n = 0; n < pending; ++n)
++ mb_putc (pending_blank[n], stdout);
++ if (ferror (stdout))
+ write_error ();
+ pending = 0;
+ one_blank_before_tab_stop = false;
+@@ -235,16 +297,17 @@ unexpand (void)
+ convert &= convert_entire_line || blank;
}
-@@ -428,6 +667,19 @@ main (int argc, char **argv)
- atexit (close_stdout);
+- if (c < 0)
++ if (mb_iseof (c))
+ {
+ free (pending_blank);
+ return;
+ }
-+#if HAVE_MBRTOWC
-+ if (MB_CUR_MAX > 1)
-+ {
-+ find_field = find_field_multi;
-+ }
-+ else
-+#endif
-+ {
-+ find_field = find_field_uni;
-+ }
+- if (putchar (c) < 0)
++ mb_putc (c, stdout);
++ if (ferror (stdout))
+ write_error ();
+ }
+- while (c != '\n');
++ while (!mb_iseq (c, '\n'));
+ }
+ }
+
+diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm
+index b55fb9d..ac80f49 100644
+--- a/tests/Coreutils.pm
++++ b/tests/Coreutils.pm
+@@ -269,6 +269,9 @@ sub run_tests ($$$$$)
+ # Yes, this is an arbitrary limit. If it causes trouble,
+ # consider removing it.
+ my $max = 30;
++ # The downstream i18n multi-byte tests have a "-mb" suffix.
++ # Therefore add 3 to the maximum test name length.
++ $max += 3;
+ if ($max < length $test_name)
+ {
+ warn "$program_name: $test_name: test name is too long (> $max)\n";
+diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh
+new file mode 100644
+index 0000000..dd6007c
+--- /dev/null
++++ b/tests/expand/mb.sh
+@@ -0,0 +1,183 @@
++#!/bin/sh
++
++# Copyright (C) 2012-2015 Free Software Foundation, Inc.
++
++# This program is free software: you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation, either version 3 of the License, or
++# (at your option) any later version.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program. If not, see .
++
++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
++print_ver_ expand
++
++export LC_ALL=en_US.UTF-8
++
++#input containing multibyte characters
++cat <<\EOF > in || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++EOF
++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_
++
++cat <<\EOF > exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#multiple files as an input
++cat <<\EOF >> exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++expand ./in ./in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#test characters with display widths != 1
++env printf '12345678
++e\t|ascii(1)
++\u00E9\t|composed(1)
++e\u0301\t|decomposed(1)
++\u3000\t|ideo-space(2)
++\uFF0D\t|full-hypen(2)
++' > in || framework_failure_
++
++env printf '12345678
++e |ascii(1)
++\u00E9 |composed(1)
++e\u0301 |decomposed(1)
++\u3000 |ideo-space(2)
++\uFF0D |full-hypen(2)
++' > exp || framework_failure_
++
++expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#shouldn't fail with "input line too long"
++#when a line starts with a control character
++env printf '\n' > in || framework_failure_
++
++expand < in > out || fail=1
++compare in out > /dev/null 2>&1 || fail=1
++
++#non-Unicode characters interspersed between Unicode ones
++env printf '12345678
++\t\xFF|
++\xFF\t|
++\t\xFFä|
++ä\xFF\t|
++\tä\xFF|
++\xFF\tä|
++äbcdef\xFF\t|
++' > in || framework_failure_
++
++env printf '12345678
++ \xFF|
++\xFF |
++ \xFFä|
++ä\xFF |
++ ä\xFF|
++\xFF ä|
++äbcdef\xFF |
++' > exp || framework_failure_
++
++expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
+
+
+
- skip_chars = 0;
- skip_fields = 0;
- check_chars = SIZE_MAX;
-diff -urNp coreutils-8.15-orig/tests/Makefile.am coreutils-8.15/tests/Makefile.am
---- coreutils-8.15-orig/tests/Makefile.am 2013-01-30 13:39:59.940175847 +0100
-+++ coreutils-8.15/tests/Makefile.am 2013-01-30 13:40:37.361294753 +0100
-@@ -240,6 +240,7 @@ TESTS = \
- misc/sort-debug-keys \
- misc/sort-debug-warn \
- misc/sort-files0-from \
-+ misc/sort-mb-tests \
- misc/sort-float \
- misc/sort-merge \
- misc/sort-merge-fdlimit \
-@@ -529,6 +530,10 @@ TESTS = \
- $(root_tests)
++#BOM header test 1
++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++EOF
++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_
++
++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++
++expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LANG=C expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LC_ALL=C expand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++
++printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++EOF
++env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_
++
++
++printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++expand in1 in1 > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LANG=C expand in1 in1 > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LC_ALL=C expand in1 in1 > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++exit $fail
+diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh
+new file mode 100644
+index 0000000..26c95de
+--- /dev/null
++++ b/tests/i18n/sort.sh
+@@ -0,0 +1,29 @@
++#!/bin/sh
++# Verify sort's multi-byte support.
++
++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
++print_ver_ sort
++
++export LC_ALL=en_US.UTF-8
++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
++ || skip_ "No UTF-8 locale available"
++
++# Enable heap consistency checkng on older systems
++export MALLOC_CHECK_=2
++
++
++# check buffer overflow issue due to
++# expanding multi-byte representation due to case conversion
++# https://bugzilla.suse.com/show_bug.cgi?id=928749
++cat < exp
++.
++ɑ
++EOF
++cat < out || fail=1
++.
++ɑ
++EOF
++compare exp out || { fail=1; cat out; }
++
++
++Exit $fail
+diff --git a/tests/local.mk b/tests/local.mk
+index 53fc53e..0148422 100644
+--- a/tests/local.mk
++++ b/tests/local.mk
+@@ -412,6 +412,8 @@ all_tests = \
+ tests/sort/sort-field-limit.sh \
+ tests/sort/sort-files0-from.pl \
+ tests/sort/sort-float.sh \
++ tests/misc/sort-mb-tests.sh \
++ tests/i18n/sort.sh \
+ tests/sort/sort-h-thousands-sep.sh \
+ tests/sort/sort-merge.pl \
+ tests/sort/sort-merge-fdlimit.sh \
+@@ -618,6 +620,7 @@ all_tests = \
+ tests/du/threshold.sh \
+ tests/du/trailing-slash.sh \
+ tests/du/two-args.sh \
++ tests/expand/mb.sh \
+ tests/id/gnu-zero-uids.sh \
+ tests/id/no-context.sh \
+ tests/id/context.sh \
+@@ -774,6 +777,7 @@ all_tests = \
+ tests/touch/read-only.sh \
+ tests/touch/relative.sh \
+ tests/touch/trailing-slash.sh \
++ tests/unexpand/mb.sh \
+ $(all_root_tests)
- pr_data = \
-+ misc/mb1.X \
-+ misc/mb1.I \
-+ misc/mb2.X \
-+ misc/mb2.I \
- pr/0F \
- pr/0FF \
- pr/0FFnt \
-diff -urNp coreutils-8.15-orig/tests/misc/cut coreutils-8.15/tests/misc/cut
---- coreutils-8.15-orig/tests/misc/cut 2012-01-01 10:04:06.000000000 +0100
-+++ coreutils-8.15/tests/misc/cut 2013-01-30 13:40:37.361294753 +0100
-@@ -23,14 +23,15 @@ use strict;
+ # See tests/factor/create-test.sh.
+diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl
+index 4b07210..68b9ea1 100755
+--- a/tests/misc/expand.pl
++++ b/tests/misc/expand.pl
+@@ -27,6 +27,15 @@ my $prog = 'expand';
+ # Turn off localization of executable's output.
+ @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
++#comment out next line to disable multibyte tests
++my $mb_locale = $ENV{LOCALE_FR_UTF8};
++! defined $mb_locale || $mb_locale eq 'none'
++ and $mb_locale = 'C';
++
++my $prog = 'expand';
++my $try = "Try \`$prog --help' for more information.\n";
++my $inval = "$prog: invalid byte, character or field list\n$try";
++
+ my @Tests =
+ (
+ ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}],
+@@ -168,6 +177,8 @@ my @Tests =
+
+
+ # Test errors
++ # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES
++ # So we force LC_MESSAGES=C to make them pass.
+ ['e1', '--tabs="a"', {IN=>''}, {OUT=>''}, {EXIT=>1},
+ {ERR => "$prog: tab size contains invalid character(s): 'a'\n"}],
+ ['e2', "-t $UINTMAX_OFLOW", {IN=>''}, {OUT=>''}, {EXIT=>1},
+@@ -184,6 +195,37 @@ my @Tests =
+ {ERR => "$prog: '/' specifier not at start of number: '/'\n"}],
+ );
+
++if ($mb_locale ne 'C')
++ {
++ # Duplicate each test vector, appending "-mb" to the test name and
++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
++ # provide coverage for the distro-added multi-byte code paths.
++ my @new;
++ foreach my $t (@Tests)
++ {
++ my @new_t = @$t;
++ my $test_name = shift @new_t;
++
++ # Depending on whether expand is multi-byte-patched,
++ # it emits different diagnostics:
++ # non-MB: invalid byte or field list
++ # MB: invalid byte, character or field list
++ # Adjust the expected error output accordingly.
++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
++ (@new_t))
++ {
++ my $sub = {ERR_SUBST => 's/, character//'};
++ push @new_t, $sub;
++ push @$t, $sub;
++ }
++ push @new, ["$test_name-mb", @new_t, {ENV => "LANG=$mb_locale LC_MESSAGES=C"}];
++ }
++ push @Tests, @new;
++ }
++
++
++@Tests = triple_test \@Tests;
++
+ my $save_temps = $ENV{DEBUG};
+ my $verbose = $ENV{VERBOSE};
+
+diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh
+new file mode 100644
+index 0000000..11836ba
+--- /dev/null
++++ b/tests/misc/sort-mb-tests.sh
+@@ -0,0 +1,45 @@
++#!/bin/sh
++# Verify sort's multi-byte support.
++
++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
++print_ver_ sort
++
++export LC_ALL=en_US.UTF-8
++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \
++ || skip_ "No UTF-8 locale available"
++
++
++cat < exp
++Banana@5
++Apple@10
++Citrus@20
++Cherry@30
++EOF
++
++cat < out || fail=1
++Apple@10
++Banana@5
++Citrus@20
++Cherry@30
++EOF
++
++compare exp out || { fail=1; cat out; }
++
++
++cat < exp
++Citrus@AA20@@5
++Cherry@AA30@@10
++Apple@AA10@@20
++Banana@AA5@@30
++EOF
++
++cat < out || fail=1
++Apple@AA10@@20
++Banana@AA5@@30
++Citrus@AA20@@5
++Cherry@AA30@@10
++EOF
++
++compare exp out || { fail=1; cat out; }
++
++Exit $fail
+diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl
+index bb7469c..c1dec95 100755
+--- a/tests/misc/unexpand.pl
++++ b/tests/misc/unexpand.pl
+@@ -27,6 +27,14 @@ my $limits = getlimits ();
+
+ my $prog = 'unexpand';
+
++# comment out next line to disable multibyte tests
++my $mb_locale = $ENV{LOCALE_FR_UTF8};
++! defined $mb_locale || $mb_locale eq 'none'
++ and $mb_locale = 'C';
++
++my $try = "Try \`$prog --help' for more information.\n";
++my $inval = "$prog: invalid byte, character or field list\n$try";
++
+ my @Tests =
+ (
+ ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}],
+@@ -132,6 +140,37 @@ my @Tests =
+ ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}],
+ );
+
++if ($mb_locale ne 'C')
++ {
++ # Duplicate each test vector, appending "-mb" to the test name and
++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
++ # provide coverage for the distro-added multi-byte code paths.
++ my @new;
++ foreach my $t (@Tests)
++ {
++ my @new_t = @$t;
++ my $test_name = shift @new_t;
++
++ # Depending on whether unexpand is multi-byte-patched,
++ # it emits different diagnostics:
++ # non-MB: invalid byte or field list
++ # MB: invalid byte, character or field list
++ # Adjust the expected error output accordingly.
++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
++ (@new_t))
++ {
++ my $sub = {ERR_SUBST => 's/, character//'};
++ push @new_t, $sub;
++ push @$t, $sub;
++ }
++ next if ($test_name =~ 'b-1');
++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
++ }
++ push @Tests, @new;
++ }
++
++@Tests = triple_test \@Tests;
++
+ my $save_temps = $ENV{DEBUG};
+ my $verbose = $ENV{VERBOSE};
+
+diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl
+index 60e6106..3c64a08 100755
+--- a/tests/pr/pr-tests.pl
++++ b/tests/pr/pr-tests.pl
+@@ -24,6 +24,15 @@ use strict;
+ my $prog = 'pr';
+ my $normalize_strerror = "s/': .*/'/";
+
++my $mb_locale;
++#Uncomment the following line to enable multibyte tests
++$mb_locale = $ENV{LOCALE_FR_UTF8};
++! defined $mb_locale || $mb_locale eq 'none'
++ and $mb_locale = 'C';
++
++my $try = "Try \`$prog --help' for more information.\n";
++my $inval = "$prog: invalid byte, character or field list\n$try";
++
+ my @tv = (
+
+ # -b option is no longer an official option. But it's still working to
+@@ -515,8 +524,48 @@ push @Tests,
+ {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"},
+ {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\n"} ];
+
++# Add _POSIX2_VERSION=199209 to the environment of each test
++# that uses an old-style option like +1.
++if ($mb_locale ne 'C')
++ {
++ # Duplicate each test vector, appending "-mb" to the test name and
++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
++ # provide coverage for the distro-added multi-byte code paths.
++ my @new;
++ foreach my $t (@Tests)
++ {
++ my @new_t = @$t;
++ my $test_name = shift @new_t;
++
++ # Depending on whether pr is multi-byte-patched,
++ # it emits different diagnostics:
++ # non-MB: invalid byte or field list
++ # MB: invalid byte, character or field list
++ # Adjust the expected error output accordingly.
++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
++ (@new_t))
++ {
++ my $sub = {ERR_SUBST => 's/, character//'};
++ push @new_t, $sub;
++ push @$t, $sub;
++ }
++ #temporarily skip some failing tests
++ next if ($test_name =~ "col-0" or $test_name =~ "col-inval" or $test_name =~ "asan1");
++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
++ }
++ push @Tests, @new;
++ }
++
+ @Tests = triple_test \@Tests;
+
++# Remember that triple_test creates from each test with exactly one "IN"
++# file two more tests (.p and .r suffix on name) corresponding to reading
++# input from a file and from a pipe. The pipe-reading test would fail
++# due to a race condition about 1 in 20 times.
++# Remove the IN_PIPE version of the "output-is-input" test above.
++# The others aren't susceptible because they have three inputs each.
++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
++
+ my $save_temps = $ENV{DEBUG};
+ my $verbose = $ENV{VERBOSE};
+
+diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl
+index a3204d3..40942a5 100755
+--- a/tests/sort/sort-merge.pl
++++ b/tests/sort/sort-merge.pl
+@@ -26,6 +26,15 @@ my $prog = 'sort';
+ # Turn off localization of executable's output.
+ @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
++my $mb_locale;
++# uncommented according to upstream commit enabling multibyte paths
++$mb_locale = $ENV{LOCALE_FR_UTF8};
++! defined $mb_locale || $mb_locale eq 'none'
++ and $mb_locale = 'C';
++
++my $try = "Try \`$prog --help' for more information.\n";
++my $inval = "$prog: invalid byte, character or field list\n$try";
++
+ # three empty files and one that says 'foo'
+ my @inputs = (+(map{{IN=> {"empty$_"=> ''}}}1..3), {IN=> {foo=> "foo\n"}});
+
+@@ -77,6 +86,39 @@ my @Tests =
+ {OUT=>$big_input}],
+ );
+
++# Add _POSIX2_VERSION=199209 to the environment of each test
++# that uses an old-style option like +1.
++if ($mb_locale ne 'C')
++ {
++ # Duplicate each test vector, appending "-mb" to the test name and
++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
++ # provide coverage for the distro-added multi-byte code paths.
++ my @new;
++ foreach my $t (@Tests)
++ {
++ my @new_t = @$t;
++ my $test_name = shift @new_t;
++
++ # Depending on whether sort is multi-byte-patched,
++ # it emits different diagnostics:
++ # non-MB: invalid byte or field list
++ # MB: invalid byte, character or field list
++ # Adjust the expected error output accordingly.
++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
++ (@new_t))
++ {
++ my $sub = {ERR_SUBST => 's/, character//'};
++ push @new_t, $sub;
++ push @$t, $sub;
++ }
++ next if ($test_name =~ "nmerge-.");
++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
++ }
++ push @Tests, @new;
++ }
++
++@Tests = triple_test \@Tests;
++
+ my $save_temps = $ENV{DEBUG};
+ my $verbose = $ENV{VERBOSE};
+
+diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl
+index 5fa9d52..a66952a 100755
+--- a/tests/sort/sort.pl
++++ b/tests/sort/sort.pl
+@@ -24,10 +24,15 @@ my $prog = 'sort';
# Turn off localization of executable's output.
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
-my $mb_locale = $ENV{LOCALE_FR_UTF8};
--! defined $mb_locale || $mb_locale eq 'none'
-- and $mb_locale = 'C';
-+#my $mb_locale = $ENV{LOCALE_FR_UTF8};
-+#! defined $mb_locale || $mb_locale eq 'none'
-+# and $mb_locale = 'C';
-+my $mb_locale = 'C';
++my $mb_locale;
++#Comment out next line to disable multibyte tests
++$mb_locale = $ENV{LOCALE_FR_UTF8};
+ ! defined $mb_locale || $mb_locale eq 'none'
+ and $mb_locale = 'C';
- my $prog = 'cut';
- my $try = "Try \`$prog --help' for more information.\n";
- my $from_1 = "$prog: fields and positions are numbered from 1\n$try";
--my $inval = "$prog: invalid byte or field list\n$try";
++my $try = "Try \`$prog --help' for more information.\n";
+my $inval = "$prog: invalid byte, character or field list\n$try";
- my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try";
++
+ # Since each test is run with a file name and with redirected stdin,
+ # the name in the diagnostic is either the file name or "-".
+ # Normalize each diagnostic to use '-'.
+@@ -428,6 +433,38 @@ foreach my $t (@Tests)
+ }
+ }
- my @Tests =
-@@ -147,7 +148,7 @@ my @Tests =
++if ($mb_locale ne 'C')
++ {
++ # Duplicate each test vector, appending "-mb" to the test name and
++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we
++ # provide coverage for the distro-added multi-byte code paths.
++ my @new;
++ foreach my $t (@Tests)
++ {
++ my @new_t = @$t;
++ my $test_name = shift @new_t;
++
++ # Depending on whether sort is multi-byte-patched,
++ # it emits different diagnostics:
++ # non-MB: invalid byte or field list
++ # MB: invalid byte, character or field list
++ # Adjust the expected error output accordingly.
++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval}
++ (@new_t))
++ {
++ my $sub = {ERR_SUBST => 's/, character//'};
++ push @new_t, $sub;
++ push @$t, $sub;
++ }
++ #disable several failing tests until investigation, disable all tests with envvars set
++ next if (grep {ref $_ eq 'HASH' && exists $_->{ENV}} (@new_t));
++ next if ($test_name =~ "18g" or $test_name =~ "sort-numeric" or $test_name =~ "08[ab]" or $test_name =~ "03[def]" or $test_name =~ "h4" or $test_name =~ "n1" or $test_name =~ "2[01]a");
++ next if ($test_name =~ "11[ab]"); # avoid FP: expected result differs to MB result due to collation rules.
++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}];
++ }
++ push @Tests, @new;
++ }
++
+ @Tests = triple_test \@Tests;
- # None of the following invalid ranges provoked an error up to coreutils-6.9.
- ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1},
-- {ERR=>"$prog: invalid decreasing range\n$try"}],
-+ {ERR=>"$prog: invalid byte, character or field list\n$try"}],
- ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
- ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
- ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1},
-diff -urNp coreutils-8.15-orig/tests/misc/mb1.I coreutils-8.15/tests/misc/mb1.I
---- coreutils-8.15-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.15/tests/misc/mb1.I 2013-01-30 13:40:37.362395749 +0100
-@@ -0,0 +1,4 @@
-+Apple@10
-+Banana@5
-+Citrus@20
-+Cherry@30
-diff -urNp coreutils-8.15-orig/tests/misc/mb1.X coreutils-8.15/tests/misc/mb1.X
---- coreutils-8.15-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.15/tests/misc/mb1.X 2013-01-30 13:40:37.363395657 +0100
-@@ -0,0 +1,4 @@
-+Banana@5
-+Apple@10
-+Citrus@20
-+Cherry@30
-diff -urNp coreutils-8.15-orig/tests/misc/mb2.I coreutils-8.15/tests/misc/mb2.I
---- coreutils-8.15-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.15/tests/misc/mb2.I 2013-01-30 13:40:37.363395657 +0100
-@@ -0,0 +1,4 @@
-+Apple@AA10@@20
-+Banana@AA5@@30
-+Citrus@AA20@@5
-+Cherry@AA30@@10
-diff -urNp coreutils-8.15-orig/tests/misc/mb2.X coreutils-8.15/tests/misc/mb2.X
---- coreutils-8.15-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.15/tests/misc/mb2.X 2013-01-30 13:40:37.364411214 +0100
-@@ -0,0 +1,4 @@
-+Citrus@AA20@@5
-+Cherry@AA30@@10
-+Apple@AA10@@20
-+Banana@AA5@@30
-diff -urNp coreutils-8.15-orig/tests/misc/sort-mb-tests coreutils-8.15/tests/misc/sort-mb-tests
---- coreutils-8.15-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.15/tests/misc/sort-mb-tests 2013-01-30 13:40:37.365177992 +0100
-@@ -0,0 +1,58 @@
-+#! /bin/sh
-+case $# in
-+ 0) xx='../src/sort';;
-+ *) xx="$1";;
-+esac
-+test "$VERBOSE" && echo=echo || echo=:
-+$echo testing program: $xx
-+errors=0
-+test "$srcdir" || srcdir=.
-+test "$VERBOSE" && $xx --version 2> /dev/null
+ # Remember that triple_test creates from each test with exactly one "IN"
+@@ -437,6 +474,7 @@ foreach my $t (@Tests)
+ # Remove the IN_PIPE version of the "output-is-input" test above.
+ # The others aren't susceptible because they have three inputs each.
+ @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
++@Tests = grep {$_->[0] ne 'output-is-input-mb.p'} @Tests;
+
+ my $save_temps = $ENV{DEBUG};
+ my $verbose = $ENV{VERBOSE};
+diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh
+new file mode 100644
+index 0000000..8a82d74
+--- /dev/null
++++ b/tests/unexpand/mb.sh
+@@ -0,0 +1,172 @@
++#!/bin/sh
++
++# Copyright (C) 2012-2015 Free Software Foundation, Inc.
++
++# This program is free software: you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation, either version 3 of the License, or
++# (at your option) any later version.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program. If not, see .
++
++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
++print_ver_ unexpand
+
+export LC_ALL=en_US.UTF-8
-+locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77
-+errors=0
+
-+$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O
-+code=$?
-+if test $code != 0; then
-+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0"
-+ errors=`expr $errors + 1`
-+else
-+ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1
-+ case $? in
-+ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;;
-+ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2
-+ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null
-+ errors=`expr $errors + 1`;;
-+ 2) $echo "Test mb1 may have failed." 1>&2
-+ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2
-+ errors=`expr $errors + 1`;;
-+ esac
-+fi
++#input containing multibyte characters
++cat > in <<\EOF
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
+
-+$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O
-+code=$?
-+if test $code != 0; then
-+ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2
-+ errors=`expr $errors + 1`
-+else
-+ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1
-+ case $? in
-+ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;;
-+ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2
-+ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null
-+ errors=`expr $errors + 1`;;
-+ 2) $echo "Test mb2 may have failed." 1>&2
-+ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2
-+ errors=`expr $errors + 1`;;
-+ esac
-+fi
++cat > exp <<\EOF
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
+
-+if test $errors = 0; then
-+ $echo Passed all 113 tests. 1>&2
-+else
-+ $echo Failed $errors tests. 1>&2
-+fi
-+test $errors = 0 || errors=1
-+exit $errors
++unexpand -a < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++
++#multiple files as an input
++cat >> exp <<\EOF
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++
++unexpand -a ./in ./in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#test characters with a display width larger than 1
++
++env printf '12345678
++e |ascii(1)
++\u00E9 |composed(1)
++e\u0301 |decomposed(1)
++\u3000 |ideo-space(2)
++\uFF0D |full-hypen(2)
++' > in || framework_failure_
++
++env printf '12345678
++e\t|ascii(1)
++\u00E9\t|composed(1)
++e\u0301\t|decomposed(1)
++\u3000\t|ideo-space(2)
++\uFF0D\t|full-hypen(2)
++' > exp || framework_failure_
++
++unexpand -a < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#test input where a blank of width > 1 is not being substituted
++in="$(LC_ALL=en_US.UTF-8 printf ' \u3000 ö ü ß')"
++exp=' ö ü ß'
++
++unexpand -a < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#non-Unicode characters interspersed between Unicode ones
++env printf '12345678
++ \xFF|
++\xFF |
++ \xFFä|
++ä\xFF |
++ ä\xFF|
++\xFF ä|
++äbcdef\xFF |
++' > in || framework_failure_
++
++env printf '12345678
++\t\xFF|
++\xFF\t|
++\t\xFFä|
++ä\xFF\t|
++\tä\xFF|
++\xFF\tä|
++äbcdef\xFF\t|
++' > exp || framework_failure_
++
++unexpand -a < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++#BOM header test 1
++printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_
++
++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++unexpand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LANG=C unexpand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LC_ALL=C unexpand < in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++
++printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++1234567812345678123456781
++. . . .
++a b c d
++. . . .
++ä ö ü ß
++. . . .
++ äöü . öüä. ä xx
++EOF
++
++
++unexpand in in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LANG=C unexpand in in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
++
++LC_ALL=C unexpand in in > out || fail=1
++compare exp out > /dev/null 2>&1 || fail=1
+--
+2.52.0
+
diff --git a/coreutils-keyring.gpg b/coreutils-keyring.gpg
new file mode 100644
index 0000000..003a885
--- /dev/null
+++ b/coreutils-keyring.gpg
@@ -0,0 +1,312 @@
+Release GPG keyring of coreutils group.
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+ELphkzjc6eM3CaOZ73u4GVXotheeUabUHQ==
+=drvb
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/coreutils-overflow.patch b/coreutils-overflow.patch
deleted file mode 100644
index 0d55a6d..0000000
--- a/coreutils-overflow.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- coreutils-5.2.1/src/who.c.overflow 2005-05-25 09:59:06.000000000 +0100
-+++ coreutils-5.2.1/src/who.c 2005-05-25 10:00:31.000000000 +0100
-@@ -75,7 +75,7 @@
- # define UT_TYPE_NEW_TIME(U) false
- #endif
-
--#define IDLESTR_LEN 6
-+#define IDLESTR_LEN 10
-
- #if HAVE_STRUCT_XTMP_UT_PID
- # define PIDSTR_DECL_AND_INIT(Var, Utmp_ent) \
diff --git a/coreutils-python3.patch b/coreutils-python3.patch
new file mode 100644
index 0000000..447fdbc
--- /dev/null
+++ b/coreutils-python3.patch
@@ -0,0 +1,65 @@
+From 8927d505ecb5334f09c48ef98ef1f464f581d0f7 Mon Sep 17 00:00:00 2001
+From: rpm-build
+Date: Tue, 2 Apr 2024 14:11:26 +0100
+Subject: [PATCH] coreutils-python3.patch
+
+---
+ init.cfg | 4 ++--
+ tests/d_type-check | 2 +-
+ tests/du/move-dir-while-traversing.sh | 6 +++---
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/init.cfg b/init.cfg
+index ac05f7b..26d9516 100644
+--- a/init.cfg
++++ b/init.cfg
+@@ -601,10 +601,10 @@ seek_data_capable_()
+ # Skip the current test if "." lacks d_type support.
+ require_dirent_d_type_()
+ {
+- python < /dev/null \
++ python3 < /dev/null \
+ || skip_ python missing: assuming no d_type support
+
+- python "$abs_srcdir"/tests/d_type-check \
++ python3 "$abs_srcdir"/tests/d_type-check \
+ || skip_ requires d_type support
+ }
+
+diff --git a/tests/d_type-check b/tests/d_type-check
+index 1a2f76f..42d3924 100644
+--- a/tests/d_type-check
++++ b/tests/d_type-check
+@@ -1,4 +1,4 @@
+-#!/usr/bin/python
++#!/usr/bin/python3
+ # Exit 0 if "." and "./tempfile" have useful d_type information, else 1.
+ # Intended to exit 0 only on Linux/GNU systems.
+ import os
+diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh
+index adf482b..cf9214a 100755
+--- a/tests/du/move-dir-while-traversing.sh
++++ b/tests/du/move-dir-while-traversing.sh
+@@ -21,8 +21,8 @@ print_ver_ du
+ require_trap_signame_
+
+ # We use a python-inotify script, so...
+-python -m pyinotify -h > /dev/null \
+- || skip_ 'python inotify package not installed'
++python3 -m pyinotify -h > /dev/null \
++ || skip_ 'python3 inotify package not installed'
+
+ # Move a directory "up" while du is processing its sub-directories.
+ # While du is processing a hierarchy .../B/C/D/... this script
+@@ -33,7 +33,7 @@ python -m pyinotify -h > /dev/null \
+ # rename syscall before du finishes processing the subtree under D/.
+
+ cat <<'EOF' > inotify-watch-for-dir-access.py
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ import pyinotify as pn
+ import os,sys
+
+--
+2.51.0
+
diff --git a/coreutils-runuser-l.pamd b/coreutils-runuser-l.pamd
deleted file mode 100644
index fa1e4d8..0000000
--- a/coreutils-runuser-l.pamd
+++ /dev/null
@@ -1,4 +0,0 @@
-#%PAM-1.0
-auth include runuser
-session optional pam_keyinit.so force revoke
-session include runuser
diff --git a/coreutils-runuser.pamd b/coreutils-runuser.pamd
deleted file mode 100644
index 37f0e84..0000000
--- a/coreutils-runuser.pamd
+++ /dev/null
@@ -1,5 +0,0 @@
-#%PAM-1.0
-auth sufficient pam_rootok.so
-session optional pam_keyinit.so revoke
-session required pam_limits.so
-session required pam_unix.so
diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch
deleted file mode 100644
index 3e5c143..0000000
--- a/coreutils-selinux.patch
+++ /dev/null
@@ -1,656 +0,0 @@
-diff -urNp coreutils-8.13-orig/configure.ac coreutils-8.13/configure.ac
---- coreutils-8.13-orig/configure.ac 2011-09-09 10:29:52.584690353 +0200
-+++ coreutils-8.13/configure.ac 2011-09-09 10:30:39.524564991 +0200
-@@ -141,6 +141,13 @@ if test "$gl_gcc_warnings" = yes; then
- AC_SUBST([GNULIB_TEST_WARN_CFLAGS])
- fi
-
-+dnl Give the chance to enable SELINUX
-+AC_ARG_ENABLE(selinux, dnl
-+[ --enable-selinux Enable use of the SELINUX libraries],
-+[AC_DEFINE(WITH_SELINUX, 1, [Define if you want to use SELINUX])
-+LIB_SELINUX="-lselinux"
-+AC_SUBST(LIB_SELINUX)])
-+
- AC_FUNC_FORK
-
- AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
-diff -urNp coreutils-8.13-orig/man/chcon.x coreutils-8.13/man/chcon.x
---- coreutils-8.13-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200
-+++ coreutils-8.13/man/chcon.x 2011-09-09 10:30:39.524564991 +0200
-@@ -1,4 +1,4 @@
- [NAME]
--chcon \- change file security context
-+chcon \- change file SELinux security context
- [DESCRIPTION]
- .\" Add any additional description here
-diff -urNp coreutils-8.13-orig/man/runcon.x coreutils-8.13/man/runcon.x
---- coreutils-8.13-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200
-+++ coreutils-8.13/man/runcon.x 2011-09-09 10:30:39.544686472 +0200
-@@ -1,5 +1,5 @@
- [NAME]
--runcon \- run command with specified security context
-+runcon \- run command with specified SELinux security context
- [DESCRIPTION]
- Run COMMAND with completely-specified CONTEXT, or with current or
- transitioned security context modified by one or more of LEVEL,
-diff -urNp coreutils-8.13-orig/src/chcon.c coreutils-8.13/src/chcon.c
---- coreutils-8.13-orig/src/chcon.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/chcon.c 2011-09-09 10:30:39.562561252 +0200
-@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\
- "),
- program_name, program_name, program_name);
- fputs (_("\
--Change the security context of each FILE to CONTEXT.\n\
-+Change the SELinux security context of each FILE to CONTEXT.\n\
- With --reference, change the security context of each FILE to that of RFILE.\n\
- \n\
- "), stdout);
-diff -urNp coreutils-8.13-orig/src/copy.c coreutils-8.13/src/copy.c
---- coreutils-8.13-orig/src/copy.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/copy.c 2011-09-09 10:30:39.564562214 +0200
-@@ -2244,6 +2244,8 @@ copy_internal (char const *src_name, cha
- {
- /* Here, we are crossing a file system boundary and cp's -x option
- is in effect: so don't copy the contents of this directory. */
-+ if (x->preserve_security_context)
-+ restore_default_fscreatecon_or_die ();
- }
- else
- {
-diff -urNp coreutils-8.13-orig/src/copy.h coreutils-8.13/src/copy.h
---- coreutils-8.13-orig/src/copy.h 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/copy.h 2011-09-09 10:30:39.565563712 +0200
-@@ -158,6 +158,9 @@ struct cp_options
- bool preserve_mode;
- bool preserve_timestamps;
-
-+ /* If true, attempt to set specified security context */
-+ bool set_security_context;
-+
- /* Enabled for mv, and for cp by the --preserve=links option.
- If true, attempt to preserve in the destination files any
- logical hard links between the source files. If used with cp's
-diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c
---- coreutils-8.13-orig/src/cp.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/cp.c 2011-09-09 10:30:39.566562062 +0200
-@@ -141,6 +141,7 @@ static struct option const long_opts[] =
- {"target-directory", required_argument, NULL, 't'},
- {"update", no_argument, NULL, 'u'},
- {"verbose", no_argument, NULL, 'v'},
-+ {"context", required_argument, NULL, 'Z'},
- {GETOPT_HELP_OPTION_DECL},
- {GETOPT_VERSION_OPTION_DECL},
- {NULL, 0, NULL, 0}
-@@ -204,6 +205,9 @@ Mandatory arguments to long options are
- all\n\
- "), stdout);
- fputs (_("\
-+ -c same as --preserve=context\n\
-+"), stdout);
-+ fputs (_("\
- --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
- --parents use full source file name under DIRECTORY\n\
- "), stdout);
-@@ -230,6 +234,7 @@ Mandatory arguments to long options are
- destination file is missing\n\
- -v, --verbose explain what is being done\n\
- -x, --one-file-system stay on this file system\n\
-+ -Z, --context=CONTEXT set security context of copy to CONTEXT\n\
- "), stdout);
- fputs (HELP_OPTION_DESCRIPTION, stdout);
- fputs (VERSION_OPTION_DESCRIPTION, stdout);
-@@ -786,6 +791,7 @@ cp_option_init (struct cp_options *x)
- x->preserve_timestamps = false;
- x->preserve_security_context = false;
- x->require_preserve_context = false;
-+ x->set_security_context = false;
- x->preserve_xattr = false;
- x->reduce_diagnostics = false;
- x->require_preserve_xattr = false;
-@@ -933,7 +939,7 @@ main (int argc, char **argv)
- we'll actually use backup_suffix_string. */
- backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
-
-- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T",
-+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:",
- long_opts, NULL))
- != -1)
- {
-@@ -981,6 +987,16 @@ main (int argc, char **argv)
- copy_contents = true;
- break;
-
-+ case 'c':
-+ if ( x.set_security_context ) {
-+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]);
-+ exit( 1 );
-+ }
-+ else if (selinux_enabled) {
-+ x.preserve_security_context = true;
-+ x.require_preserve_context = true;
-+ }
-+ break;
- case 'd':
- x.preserve_links = true;
- x.dereference = DEREF_NEVER;
-@@ -1090,6 +1106,27 @@ main (int argc, char **argv)
- x.one_file_system = true;
- break;
-
-+
-+ case 'Z':
-+ /* politely decline if we're not on a selinux-enabled kernel. */
-+ if( !selinux_enabled ) {
-+ fprintf( stderr, "Warning: ignoring --context (-Z). "
-+ "It requires a SELinux enabled kernel.\n" );
-+ break;
-+ }
-+ if ( x.preserve_security_context ) {
-+ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg);
-+ exit( 1 );
-+ }
-+ x.set_security_context = true;
-+ /* if there's a security_context given set new path
-+ components to that context, too */
-+ if ( setfscreatecon(optarg) < 0 ) {
-+ (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg);
-+ exit( 1 );
-+ }
-+ break;
-+
- case 'S':
- make_backups = true;
- backup_suffix_string = optarg;
-diff -urNp coreutils-8.13-orig/src/id.c coreutils-8.13/src/id.c
---- coreutils-8.13-orig/src/id.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/id.c 2011-09-09 10:30:39.567562153 +0200
-@@ -107,7 +107,7 @@ int
- main (int argc, char **argv)
- {
- int optc;
-- int selinux_enabled = (is_selinux_enabled () > 0);
-+ bool selinux_enabled = (is_selinux_enabled () > 0);
-
- /* If true, output the list of all group IDs. -G */
- bool just_group_list = false;
-diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c
---- coreutils-8.13-orig/src/install.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/install.c 2011-09-09 10:30:39.569562422 +0200
-@@ -261,6 +261,7 @@ cp_option_init (struct cp_options *x)
- x->data_copy_required = true;
- x->require_preserve = false;
- x->require_preserve_context = false;
-+ x->set_security_context = false;
- x->require_preserve_xattr = false;
- x->recursive = false;
- x->sparse_mode = SPARSE_AUTO;
-@@ -622,7 +623,7 @@ Mandatory arguments to long options are
- -v, --verbose print the name of each directory as it is created\n\
- "), stdout);
- fputs (_("\
-- --preserve-context preserve SELinux security context\n\
-+ -P, --preserve-context preserve SELinux security context\n\
- -Z, --context=CONTEXT set SELinux security context of files and directories\
- \n\
- "), stdout);
-@@ -765,7 +766,7 @@ main (int argc, char **argv)
- we'll actually use backup_suffix_string. */
- backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
-
-- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options,
-+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z:", long_options,
- NULL)) != -1)
- {
- switch (optc)
-@@ -835,6 +836,7 @@ main (int argc, char **argv)
- no_target_directory = true;
- break;
-
-+ case 'P':
- case PRESERVE_CONTEXT_OPTION:
- if ( ! selinux_enabled)
- {
-@@ -842,6 +844,10 @@ main (int argc, char **argv)
- "this kernel is not SELinux-enabled"));
- break;
- }
-+ if ( x.set_security_context ) {
-+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]);
-+ exit( 1 );
-+ }
- x.preserve_security_context = true;
- use_default_selinux_context = false;
- break;
-@@ -853,6 +859,7 @@ main (int argc, char **argv)
- break;
- }
- scontext = optarg;
-+ x.set_security_context = true;
- use_default_selinux_context = false;
- break;
- case_GETOPT_HELP_CHAR;
-diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c
---- coreutils-8.13-orig/src/ls.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/ls.c 2011-09-09 10:30:39.575562845 +0200
-@@ -166,7 +166,8 @@ enum filetype
- symbolic_link,
- sock,
- whiteout,
-- arg_directory
-+ arg_directory,
-+ command_line
- };
-
- /* Display letters and indicators for each filetype.
-@@ -282,6 +283,7 @@
- bool command_line_arg);
- static void sort_files (void);
- static void parse_ls_color (void);
-+static void print_scontext_format (const struct fileinfo *f);
-
- /* Initial size of hash table.
- Most hierarchies are likely to be shallower than this. */
-@@ -352,7 +354,7 @@ static struct pending *pending_dirs;
-
- static struct timespec current_time;
-
--static bool print_scontext;
-+static int print_scontext = 0;
- static char UNKNOWN_SECURITY_CONTEXT[] = "?";
-
- /* Whether any of the files has an ACL. This affects the width of the
-@@ -392,7 +394,9 @@ enum format
- one_per_line, /* -1 */
- many_per_line, /* -C */
- horizontal, /* -x */
-- with_commas /* -m */
-+ with_commas, /* -m */
-+ security_format, /* -Z */
-+ invalid_format
- };
-
- static enum format format;
-@@ -794,6 +798,9 @@ enum
- SHOW_CONTROL_CHARS_OPTION,
- SI_OPTION,
- SORT_OPTION,
-+ CONTEXT_OPTION,
-+ LCONTEXT_OPTION,
-+ SCONTEXT_OPTION,
- TIME_OPTION,
- TIME_STYLE_OPTION
- };
-@@ -839,7 +846,9 @@ static struct option const long_options[
- {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
- {"color", optional_argument, NULL, COLOR_OPTION},
- {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
-- {"context", no_argument, 0, 'Z'},
-+ {"context", no_argument, 0, CONTEXT_OPTION},
-+ {"lcontext", no_argument, 0, LCONTEXT_OPTION},
-+ {"scontext", no_argument, 0, SCONTEXT_OPTION},
- {"author", no_argument, NULL, AUTHOR_OPTION},
- {GETOPT_HELP_OPTION_DECL},
- {GETOPT_VERSION_OPTION_DECL},
-@@ -849,12 +858,12 @@ static struct option const long_options[
- static char const *const format_args[] =
- {
- "verbose", "long", "commas", "horizontal", "across",
-- "vertical", "single-column", NULL
-+ "vertical", "single-column", "context", NULL
- };
- static enum format const format_types[] =
- {
- long_format, long_format, with_commas, horizontal, horizontal,
-- many_per_line, one_per_line
-+ many_per_line, one_per_line, security_format
- };
- ARGMATCH_VERIFY (format_args, format_types);
-
-@@ -1296,7 +1305,8 @@ main (int argc, char **argv)
- /* Avoid following symbolic links when possible. */
- if (is_colored (C_ORPHAN)
- || (is_colored (C_EXEC) && color_symlink_as_referent)
-- || (is_colored (C_MISSING) && format == long_format))
-+ || (is_colored (C_MISSING) && (format == long_format
-+ || format == security_format)))
- check_symlink_color = true;
-
- /* If the standard output is a controlling terminal, watch out
-@@ -1343,7 +1353,7 @@ main (int argc, char **argv)
- if (dereference == DEREF_UNDEFINED)
- dereference = ((immediate_dirs
- || indicator_style == classify
-- || format == long_format)
-+ || format == long_format || format == security_format)
- ? DEREF_NEVER
- : DEREF_COMMAND_LINE_SYMLINK_TO_DIR);
-
-@@ -1363,7 +1373,7 @@ main (int argc, char **argv)
-
- format_needs_stat = sort_type == sort_time || sort_type == sort_size
- || format == long_format
-- || print_scontext
-+ || format == security_format || print_scontext
- || print_block_size;
- format_needs_type = (! format_needs_stat
- && (recursive
-@@ -1394,7 +1404,7 @@ main (int argc, char **argv)
- }
- else
- do
-- gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
-+ gobble_file (argv[i++], command_line, NOT_AN_INODE_NUMBER, true, "");
- while (i < argc);
-
- if (cwd_n_used)
-@@ -1565,7 +1575,7 @@ decode_switches (int argc, char **argv)
- ignore_mode = IGNORE_DEFAULT;
- ignore_patterns = NULL;
- hide_patterns = NULL;
-- print_scontext = false;
-+ print_scontext = 0;
-
- /* FIXME: put this in a function. */
- {
-@@ -1947,13 +1957,27 @@ decode_switches (int argc, char **argv)
- break;
-
- case 'Z':
-- print_scontext = true;
-+ print_scontext = 1;
-+ format = security_format;
- break;
-
- case_GETOPT_HELP_CHAR;
-
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
-
-+ case CONTEXT_OPTION: /* default security context format */
-+ print_scontext = 1;
-+ format = security_format;
-+ break;
-+ case LCONTEXT_OPTION: /* long format plus security context */
-+ print_scontext = 1;
-+ format = long_format;
-+ break;
-+ case SCONTEXT_OPTION: /* short form of new security format */
-+ print_scontext = 0;
-+ format = security_format;
-+ break;
-+
- default:
- usage (LS_FAILURE);
- }
-@@ -2757,6 +2783,7 @@ gobble_file (char const *name, enum file
- memset (f, '\0', sizeof *f);
- f->stat.st_ino = inode;
- f->filetype = type;
-+ f->scontext = NULL;
-
- if (command_line_arg
- || format_needs_stat
-@@ -2869,7 +2896,7 @@ gobble_file (char const *name, enum file
- && print_with_color && is_colored (C_CAP))
- f->has_capability = has_capability (absolute_name);
-
-- if (format == long_format || print_scontext)
-+ if (format == long_format || format == security_format || print_scontext)
- {
- bool have_selinux = false;
- bool have_acl = false;
-@@ -2892,7 +2919,7 @@ gobble_file (char const *name, enum file
- err = 0;
- }
-
-- if (err == 0 && format == long_format)
-+ if (err == 0 && (format == long_format || format == security_format))
- {
- int n = file_has_acl (absolute_name, &f->stat);
- err = (n < 0);
-@@ -2911,7 +2938,8 @@ gobble_file (char const *name, enum file
- }
-
- if (S_ISLNK (f->stat.st_mode)
-- && (format == long_format || check_symlink_color))
-+ && (format == long_format || format == security_format
-+ || check_symlink_color))
- {
- char *linkname;
- struct stat linkstats;
-@@ -2931,6 +2959,7 @@ gobble_file (char const *name, enum file
- command line are automatically traced if not being
- listed as files. */
- if (!command_line_arg || format == long_format
-+ || format == security_format
- || !S_ISDIR (linkstats.st_mode))
- {
- /* Get the linked-to file's mode for the filetype indicator
-@@ -2970,7 +2999,7 @@ gobble_file (char const *name, enum file
- block_size_width = len;
- }
-
-- if (format == long_format)
-+ if (format == long_format || format == security_format)
- {
- if (print_owner)
- {
-@@ -3471,6 +3500,13 @@ print_current_files (void)
- print_long_format (sorted_file[i]);
- DIRED_PUTCHAR ('\n');
- }
-+ break;
-+ case security_format:
-+ for (i = 0; i < cwd_n_used; i++)
-+ {
-+ print_scontext_format (sorted_file[i]);
-+ DIRED_PUTCHAR ('\n');
-+ }
- break;
- }
- }
-@@ -3633,6 +3669,67 @@ format_inode (char *buf, size_t buflen,
- : (char *) "?");
- }
-
-+/* Print info about f in scontext format */
-+static void
-+print_scontext_format (const struct fileinfo *f)
-+{
-+ char modebuf[12];
-+
-+ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes,
-+ 1 10-byte mode string,
-+ 9 spaces, one following each of these fields, and
-+ 1 trailing NUL byte. */
-+
-+ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1];
-+ char *buf = init_bigbuf;
-+ char *p;
-+
-+ p = buf;
-+
-+ if ( print_scontext ) { /* zero means terse listing */
-+ filemodestring (&f->stat, modebuf);
-+ if (! any_has_acl)
-+ modebuf[10] = '\0';
-+ else if (f->acl_type == ACL_T_SELINUX_ONLY)
-+ modebuf[10] = '.';
-+ else if (f->acl_type == ACL_T_YES)
-+ modebuf[10] = '+';
-+ modebuf[11] = '\0';
-+
-+ /* print mode */
-+
-+ (void) sprintf (p, "%s ", modebuf);
-+ p += strlen (p);
-+
-+ /* print standard user and group */
-+
-+ DIRED_FPUTS (buf, stdout, p - buf);
-+ format_user (f->stat.st_uid, owner_width, f->stat_ok);
-+ format_group (f->stat.st_gid, group_width, f->stat_ok);
-+ p = buf;
-+ }
-+
-+ (void) sprintf (p, "%-32s ", f->scontext ?: "");
-+ p += strlen (p);
-+
-+ DIRED_INDENT ();
-+ DIRED_FPUTS (buf, stdout, p - buf);
-+ size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf);
-+
-+ if (f->filetype == symbolic_link) {
-+ if (f->linkname) {
-+ DIRED_FPUTS_LITERAL (" -> ", stdout);
-+ print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);
-+ if (indicator_style != none)
-+ print_type_indicator (f->stat_ok, f->linkmode, f->filetype);
-+ }
-+ }
-+ else {
-+ if (indicator_style != none)
-+ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
-+ }
-+}
-+
- /* Print information about F in long format. */
- static void
- print_long_format (const struct fileinfo *f)
-@@ -3724,9 +3821,15 @@ print_long_format (const struct fileinfo
- The latter is wrong when nlink_width is zero. */
- p += strlen (p);
-
-+ if (print_scontext)
-+ {
-+ sprintf (p, "%-32s ", f->scontext ? f->scontext : "");
-+ p += strlen (p);
-+ }
-+
- DIRED_INDENT ();
-
-- if (print_owner || print_group || print_author || print_scontext)
-+ if (print_owner || print_group || print_author)
- {
- DIRED_FPUTS (buf, stdout, p - buf);
-
-@@ -3739,9 +3842,6 @@ print_long_format (const struct fileinfo
- if (print_author)
- format_user (f->stat.st_author, author_width, f->stat_ok);
-
-- if (print_scontext)
-- format_user_or_group (f->scontext, 0, scontext_width);
--
- p = buf;
- }
-
-@@ -4086,9 +4186,6 @@ print_file_name_and_frills (const struct
- : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size));
-
-- if (print_scontext)
-- printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
--
- size_t width = print_name_with_quoting (f, false, NULL, start_col);
-
- if (indicator_style != none)
-@@ -4292,9 +4389,6 @@ length_of_file_name_and_frills (const st
- output_block_size))
- : block_size_width);
-
-- if (print_scontext)
-- len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width);
--
- quote_name (NULL, f->name, filename_quoting_options, &name_width);
- len += name_width;
-
-@@ -4733,9 +4827,16 @@ Mandatory arguments to long options are
- -w, --width=COLS assume screen width instead of current value\n\
- -x list entries by lines instead of by columns\n\
- -X sort alphabetically by entry extension\n\
-- -Z, --context print any SELinux security context of each file\n\
- -1 list one file per line\n\
- "), stdout);
-+ fputs(_("\nSELinux options:\n\n\
-+ --lcontext Display security context. Enable -l. Lines\n\
-+ will probably be too wide for most displays.\n\
-+ -Z, --context Display security context so it fits on most\n\
-+ displays. Displays only mode, user, group,\n\
-+ security context and file name.\n\
-+ --scontext Display only security context and file name.\n\
-+"), stdout);
- fputs (HELP_OPTION_DESCRIPTION, stdout);
- fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_size_note ();
-diff -urNp coreutils-8.13-orig/src/mkdir.c coreutils-8.13/src/mkdir.c
---- coreutils-8.13-orig/src/mkdir.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/mkdir.c 2011-09-09 10:30:39.576564256 +0200
-@@ -38,6 +38,7 @@
- static struct option const longopts[] =
- {
- {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
-+ {"context", required_argument, NULL, 'Z'},
- {"mode", required_argument, NULL, 'm'},
- {"parents", no_argument, NULL, 'p'},
- {"verbose", no_argument, NULL, 'v'},
-diff -urNp coreutils-8.13-orig/src/mknod.c coreutils-8.13/src/mknod.c
---- coreutils-8.13-orig/src/mknod.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/mknod.c 2011-09-09 10:30:39.577563177 +0200
-@@ -35,7 +35,7 @@
-
- static struct option const longopts[] =
- {
-- {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
-+ {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
- {"mode", required_argument, NULL, 'm'},
- {GETOPT_HELP_OPTION_DECL},
- {GETOPT_VERSION_OPTION_DECL},
-diff -urNp coreutils-8.13-orig/src/mv.c coreutils-8.13/src/mv.c
---- coreutils-8.13-orig/src/mv.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/mv.c 2011-09-09 10:30:39.578562234 +0200
-@@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x)
- x->preserve_mode = true;
- x->preserve_timestamps = true;
- x->preserve_security_context = selinux_enabled;
-+ x->set_security_context = false;
- x->reduce_diagnostics = false;
- x->data_copy_required = true;
- x->require_preserve = false; /* FIXME: maybe make this an option */
-diff -urNp coreutils-8.13-orig/src/runcon.c coreutils-8.13/src/runcon.c
---- coreutils-8.13-orig/src/runcon.c 2011-07-28 12:38:27.000000000 +0200
-+++ coreutils-8.13/src/runcon.c 2011-09-09 10:30:39.579564283 +0200
-@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\
- or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\
- "), program_name, program_name);
- fputs (_("\
--Run a program in a different security context.\n\
-+Run a program in a different SELinux security context.\n\
- With neither CONTEXT nor COMMAND, print the current security context.\n\
- \n\
- CONTEXT Complete security context\n\
-diff -urNp coreutils-8.13-orig/tests/init.cfg coreutils-8.13/tests/init.cfg
---- coreutils-8.13-orig/tests/init.cfg 2011-09-07 18:00:55.000000000 +0200
-+++ coreutils-8.13/tests/init.cfg 2011-09-09 10:32:17.031688699 +0200
-@@ -253,8 +253,8 @@ require_selinux_()
-
- # Independent of whether SELinux is enabled system-wide,
- # the current file system may lack SELinux support.
-- case `ls -Zd .` in
-- '? .'|'unlabeled .')
-+ case `ls -Zd . | cut -f4 -d" "` in
-+ '?'|'unlabeled')
- skip_ "this system (or maybe just" \
- "the current file system) lacks SELinux support"
- ;;
-diff -urNp coreutils-8.13-orig/tests/misc/selinux coreutils-8.13/tests/misc/selinux
---- coreutils-8.13-orig/tests/misc/selinux 2011-08-08 09:42:16.000000000 +0200
-+++ coreutils-8.13/tests/misc/selinux 2011-09-09 10:30:39.586563144 +0200
-@@ -37,7 +37,7 @@ chcon $ctx f d p ||
-
- # inspect that context with both ls -Z and stat.
- for i in d f p; do
-- c=`ls -dogZ $i|cut -d' ' -f3`; test x$c = x$ctx || fail=1
-+ c=`ls -dogZ $i|cut -d' ' -f4`; test x$c = x$ctx || fail=1
- c=`stat --printf %C $i`; test x$c = x$ctx || fail=1
- done
-
diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch
deleted file mode 100644
index 9cbc166..0000000
--- a/coreutils-selinuxmanpages.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi
---- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200
-+++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200
-@@ -6981,6 +6981,11 @@ for i; do
- done
- @end example
-
-+@item -c
-+@cindex SELinux security context information, preserving
-+Preserve SELinux security context of the original files if possible.
-+Some file systems don't support storing of SELinux security context.
-+
- @item --copy-contents
- @cindex directories, copying recursively
- @cindex copying directories recursively
diff --git a/coreutils-setsid.patch b/coreutils-setsid.patch
deleted file mode 100644
index 714383f..0000000
--- a/coreutils-setsid.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-diff -urNp coreutils-8.6-orig/src/su.c coreutils-8.6/src/su.c
---- coreutils-8.6-orig/src/su.c 2010-11-03 13:56:11.679069689 +0100
-+++ coreutils-8.6/src/su.c 2010-11-03 13:56:45.304325661 +0100
-@@ -153,6 +153,9 @@ static bool simulate_login;
- /* If true, change some environment vars to indicate the user su'd to. */
- static bool change_environment;
-
-+/* If true, then don't call setsid() with a command. */
-+int same_session = 0;
-+
- #ifdef USE_PAM
- static bool _pam_session_opened;
- static bool _pam_cred_established;
-@@ -161,6 +164,7 @@ static bool _pam_cred_established;
- static struct option const longopts[] =
- {
- {"command", required_argument, NULL, 'c'},
-+ {"session-command", required_argument, NULL, 'C'},
- {"fast", no_argument, NULL, 'f'},
- {"login", no_argument, NULL, 'l'},
- {"preserve-environment", no_argument, NULL, 'p'},
-@@ -335,14 +339,27 @@ create_watching_parent (void)
- sigemptyset (&action.sa_mask);
- action.sa_flags = 0;
- sigemptyset (&ourset);
-- if (sigaddset (&ourset, SIGTERM)
-- || sigaddset (&ourset, SIGALRM)
-- || sigaction (SIGTERM, &action, NULL)
-- || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
-- {
-+ if (!same_session)
-+ {
-+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
-+ {
-+ error (0, errno, _("cannot set signal handler"));
-+ caught_signal = true;
-+ }
-+ }
-+ if (!caught_signal && (sigaddset(&ourset, SIGTERM)
-+ || sigaddset(&ourset, SIGALRM)
-+ || sigaction(SIGTERM, &action, NULL)
-+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
- error (0, errno, _("cannot set signal handler"));
- caught_signal = true;
- }
-+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
-+ || sigaction(SIGQUIT, &action, NULL)))
-+ {
-+ error (0, errno, _("cannot set signal handler"));
-+ caught_signal = true;
-+ }
- }
- if (!caught_signal)
- {
-@@ -627,6 +644,8 @@ Change the effective user id and group i
- \n\
- -, -l, --login make the shell a login shell\n\
- -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
-+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
-+ and do not create a new session\n\
- -f, --fast pass -f to the shell (for csh or tcsh)\n\
- -m, --preserve-environment do not reset environment variables\n\
- -p same as -m\n\
-@@ -649,6 +668,7 @@ main (int argc, char **argv)
- int optc;
- const char *new_user = DEFAULT_USER;
- char *command = NULL;
-+ int request_same_session = 0;
- char *shell = NULL;
- struct passwd *pw;
- struct passwd pw_copy;
-@@ -674,6 +694,11 @@ main (int argc, char **argv)
- command = optarg;
- break;
-
-+ case 'C':
-+ command = optarg;
-+ request_same_session = 1;
-+ break;
-+
- case 'f':
- fast_startup = true;
- break;
-@@ -743,6 +768,9 @@ main (int argc, char **argv)
- }
- #endif
-
-+ if (request_same_session || !command || !pw->pw_uid)
-+ same_session = 1;
-+
- if (!shell && !change_environment)
- shell = getenv ("SHELL");
- if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
-@@ -764,6 +792,8 @@ main (int argc, char **argv)
- #endif
-
- change_identity (pw);
-+ if (!same_session)
-+ setsid ();
-
- /* Set environment after pam_open_session, which may put KRB5CCNAME
- into the pam_env, etc. */
diff --git a/coreutils-su-l.pamd b/coreutils-su-l.pamd
deleted file mode 100644
index 656a139..0000000
--- a/coreutils-su-l.pamd
+++ /dev/null
@@ -1,6 +0,0 @@
-#%PAM-1.0
-auth include su
-account include su
-password include su
-session optional pam_keyinit.so force revoke
-session include su
diff --git a/coreutils-su.pamd b/coreutils-su.pamd
deleted file mode 100644
index 030657f..0000000
--- a/coreutils-su.pamd
+++ /dev/null
@@ -1,14 +0,0 @@
-#%PAM-1.0
-auth sufficient pam_rootok.so
-# Uncomment the following line to implicitly trust users in the "wheel" group.
-#auth sufficient pam_wheel.so trust use_uid
-# Uncomment the following line to require a user to be in the "wheel" group.
-#auth required pam_wheel.so use_uid
-auth substack system-auth
-auth include postlogin
-account sufficient pam_succeed_if.so uid = 0 use_uid quiet
-account include system-auth
-password include system-auth
-session include system-auth
-session include postlogin
-session optional pam_xauth.so
diff --git a/coreutils.spec b/coreutils.spec
index 067333f..6712263 100644
--- a/coreutils.spec
+++ b/coreutils.spec
@@ -1,456 +1,1084 @@
Summary: A set of basic GNU tools commonly used in shell scripts
Name: coreutils
-Version: 8.15
-Release: 10%{?dist}
-License: GPLv3+
-Group: System Environment/Base
-Url: http://www.gnu.org/software/coreutils/
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
-Source101: coreutils-DIR_COLORS
-Source102: coreutils-DIR_COLORS.lightbgcolor
-Source103: coreutils-DIR_COLORS.256color
+Version: 9.9
+Release: 2%{?dist}
+# some used parts of gnulib are under various variants of LGPL
+License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later
+Url: https://www.gnu.org/software/coreutils/
+Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
+Source1: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig
+# From https://savannah.gnu.org/project/release-gpgkeys.php?group=coreutils&download=1
+# which is linked as project keyring on https://savannah.gnu.org/projects/coreutils
+Source2: coreutils-keyring.gpg
+Source50: supported_utils
Source105: coreutils-colorls.sh
Source106: coreutils-colorls.csh
-Source200: coreutils-su.pamd
-Source201: coreutils-runuser.pamd
-Source202: coreutils-su-l.pamd
-Source203: coreutils-runuser-l.pamd
-# From upstream
-Patch1: coreutils-8.15-cp-attribute-truncate.patch
-Patch2: coreutils-8.15-du-x-nondir.patch
-Patch3: coreutils-8.17-cp-freememoryread.patch
-Patch4: coreutils-8.17-sort-uniq-fmr.patch
-Patch5: coreutils-8.17-df-duplicates.patch
+# do not make coreutils-single depend on /usr/bin/coreutils
+%global __requires_exclude ^%{_bindir}/coreutils$
-# Our patches
-#general patch to workaround koji build system issues
-Patch100: coreutils-6.10-configuration.patch
-#add note about no difference between binary/text mode on Linux - md5sum manpage
-Patch101: coreutils-6.10-manpages.patch
-#temporarily workaround probable kernel issue with TCSADRAIN(#504798)
-Patch102: coreutils-7.4-sttytcsadrain.patch
-#do display processor type for uname -p/-i based on uname(2) syscall
-Patch103: coreutils-8.2-uname-processortype.patch
-#df --direct
+# disable the test-lock gnulib test prone to deadlock
+Patch100: coreutils-8.26-test-lock.patch
+
+# require_selinux_(): use selinuxenabled(8) if available
+Patch101: coreutils-8.26-selinuxenable.patch
+
+# downstream changes to default DIR_COLORS
+Patch102: coreutils-8.32-DIR_COLORS.patch
+
+# use python3 in tests
+Patch103: coreutils-python3.patch
+
+# df --direct
Patch104: coreutils-df-direct.patch
-#add note about mkdir --mode behaviour into info documentation(#610559)
-Patch107: coreutils-8.4-mkdir-modenote.patch
-# sh-utils
-#add info about TZ envvar to date manpage
-Patch703: sh-utils-2.0.11-dateman.patch
-#set paths for su explicitly, don't get influenced by paths.h
-Patch704: sh-utils-1.16-paths.patch
-# RMS will never accept the PAM patch because it removes his historical
-# rant about Twenex and the wheel group, so we'll continue to maintain
-# it here indefinitely. Patch is now the same in Fedora and SUSE.
-Patch706: coreutils-8.5-pam.patch
-Patch713: coreutils-4.5.3-langinfo.patch
+# gnulib C23 support
+# https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626
+Patch105: coreutils-9.9-gnulib-c23.patch
+
+# fix cut test failure on aarch64 rawhide (rhbz#2424302)
+# https://github.com/coreutils/coreutils/commit/95044cb5eaea83d02f768feb5ab79fcf5e6ad782
+Patch106: coreutils-9.9-fix-cut-test-aarch64.patch
# (sb) lin18nux/lsb compliance - multibyte functionality patch
Patch800: coreutils-i18n.patch
-#Call setsid() in su under some circumstances (bug #173008).
-Patch900: coreutils-setsid.patch
-#make runuser binary based on su.c
-Patch907: coreutils-8.7-runuser.patch
-#getgrouplist() patch from Ulrich Drepper.
-Patch908: coreutils-getgrouplist.patch
-#Prevent buffer overflow in who(1) (bug #158405).
-Patch912: coreutils-overflow.patch
-#compile su with pie flag and RELRO protection
-Patch917: coreutils-8.4-su-pie.patch
-
-#SELINUX Patch - implements Redhat changes
-#(upstream did some SELinux implementation unlike with RedHat patch)
-Patch950: coreutils-selinux.patch
-Patch951: coreutils-selinuxmanpages.patch
-#Deprecate cp -Z/--context non-upstream option
-Patch952: coreutils-cpZ-deprecate.patch
-
Conflicts: filesystem < 3
-Provides: /bin/basename
-Provides: /bin/cat
-Provides: /bin/chgrp
-Provides: /bin/chmod
-Provides: /bin/chown
-Provides: /bin/cp
-Provides: /bin/cut
-Provides: /bin/date
-Provides: /bin/dd
-Provides: /bin/df
-Provides: /bin/echo
-Provides: /bin/env
-Provides: /bin/false
-Provides: /bin/ln
-Provides: /bin/ls
-Provides: /bin/mkdir
-Provides: /bin/mknod
-Provides: /bin/mktemp
-Provides: /bin/mv
-Provides: /bin/nice
-Provides: /bin/pwd
-Provides: /bin/readlink
-Provides: /bin/rm
-Provides: /bin/rmdir
-Provides: /bin/sleep
-Provides: /bin/sort
-Provides: /bin/stty
-Provides: /bin/su
-Provides: /bin/sync
-Provides: /bin/touch
-Provides: /bin/true
-Provides: /bin/uname
-Provides: /sbin/runuser
-BuildRequires: libselinux-devel
-BuildRequires: libacl-devel
-BuildRequires: gettext bison
-BuildRequires: texinfo
+# To avoid clobbering installs
+Conflicts: coreutils-single
+
+BuildRequires: attr
BuildRequires: autoconf
BuildRequires: automake
-%{?!nopam:BuildRequires: pam-devel}
-BuildRequires: libcap-devel
-BuildRequires: libattr-devel
+BuildRequires: gcc
+BuildRequires: gettext-devel
BuildRequires: gmp-devel
-BuildRequires: attr
+BuildRequires: hostname
+BuildRequires: libacl-devel
+BuildRequires: libattr-devel
+BuildRequires: libcap-devel
+BuildRequires: libselinux-devel
+BuildRequires: libselinux-utils
+BuildRequires: make
+BuildRequires: openssl-devel
BuildRequires: strace
+BuildRequires: systemd-devel
+BuildRequires: texinfo
-Requires(pre): /sbin/install-info
-Requires(preun): /sbin/install-info
-Requires(post): /sbin/install-info
-Requires(post): grep
-%{?!nopam:Requires: pam >= 1.1.3-7}
-Requires: ncurses
-Requires: gmp
+# For gpg verification of source tarball
+BuildRequires: gnupg2
+# test-only dependencies
+BuildRequires: acl
+BuildRequires: gdb
+BuildRequires: perl-interpreter
+BuildRequires: perl(FileHandle)
+BuildRequires: python3
+BuildRequires: tzdata
+%ifarch %valgrind_arches
+BuildRequires: valgrind
+%endif
+
+%if 0%{?fedora}
+BuildRequires: perl(Expect)
+BuildRequires: python3-inotify
+%endif
+
+%if 23 < 0%{?fedora} || 7 < 0%{?rhel}
+# needed by i18n test-cases
+BuildRequires: glibc-langpack-en
+BuildRequires: glibc-langpack-fr
+BuildRequires: glibc-langpack-ko
+BuildRequires: glibc-langpack-sv
+%endif
+
+Requires: %{name}-common = %{version}-%{release}
+
+Provides: coreutils-full = %{version}-%{release}
Provides: bundled(gnulib)
-Provides: fileutils = %{version}-%{release}
-Provides: sh-utils = %{version}-%{release}
-Provides: stat = %{version}-%{release}
-Provides: textutils = %{version}-%{release}
-#old mktemp package had epoch 3, so we have to use 4 for coreutils
-Provides: mktemp = 4:%{version}-%{release}
-Obsoletes: mktemp < 4:%{version}-%{release}
-Obsoletes: fileutils <= 4.1.9
-Obsoletes: sh-utils <= 2.0.12
-Obsoletes: stat <= 3.3
-Obsoletes: textutils <= 2.0.21
-#coreutils-libs dropped in f17
-Obsoletes: coreutils-libs < 8.13
+Obsoletes: %{name} < 8.24-100
%description
These are the GNU core utilities. This package is the combination of
the old GNU fileutils, sh-utils, and textutils packages.
+%package single
+Summary: coreutils multicall binary
+Suggests: coreutils-common
+Provides: coreutils = %{version}-%{release}
+Provides: coreutils%{?_isa} = %{version}-%{release}
+Provides: bundled(gnulib)
+# To avoid clobbering installs
+Conflicts: coreutils < 8.24-100
+# Note RPM doesn't support separate buildroots for %files
+# http://rpm.org/ticket/874 so use RemovePathPostfixes
+# (new in rpm 4.13) to support separate file sets.
+RemovePathPostfixes: .single
+%description single
+These are the GNU core utilities,
+packaged as a single multicall binary.
+
+
+%package common
+# yum obsoleting rules explained at:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7
+Obsoletes: %{name} < 8.24-100
+
+# Gnulib translations are maintained seprately since coreutils 9.6 (#2393892)
+Requires: gnulib-l10n
+
+# info doc refers to "Specifying the Time Zone" from glibc-doc (#959597)
+Suggests: glibc-doc
+
+Summary: coreutils common optional components
+%description common
+Optional though recommended components,
+including documentation and translations.
+
%prep
-%setup -q
+%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
+%autosetup -N
-# From upstream
-%patch1 -p1 -b .trunc
-%patch2 -p1 -b .xnondir
-%patch3 -p1 -b .cpfmr
-%patch4 -p1 -b .sortfmr
-%patch5 -p1 -b .duplic
+# will be regenerated in the build directories
+rm -f src/fs.h
-# Our patches
-%patch100 -p1 -b .configure
-%patch101 -p1 -b .manpages
-%patch102 -p1 -b .tcsadrain
-%patch103 -p1 -b .sysinfo
-%patch104 -p1 -b .dfdirect
-%patch107 -p1 -b .mkdirmode
+# will be further modified by coreutils-8.32-DIR_COLORS.patch
+sed src/dircolors.hin \
+ -e 's| 00;36$| 01;36|' \
+ > DIR_COLORS
+sed src/dircolors.hin \
+ -e 's| 01;31$| 00;31|' \
+ -e 's| 01;35$| 00;35|' \
+ > DIR_COLORS.lightbgcolor
-# sh-utils
-%patch703 -p1 -b .dateman
-%patch704 -p1 -b .paths
-%patch706 -p1 -b .pam
-%patch713 -p1 -b .langinfo
+# git add DIR_COLORS{,.lightbgcolor}
+# git commit -m "clone DIR_COLORS before patching"
-# li18nux/lsb
-%patch800 -p1 -b .i18n
+# apply all patches
+%autopatch -p1
-# Coreutils
-%patch900 -p1 -b .setsid
-%patch907 -p1 -b .runuser
-%patch908 -p1 -b .getgrouplist
-%patch912 -p1 -b .overflow
-%patch917 -p1 -b .pie
+(echo ">>> Fixing permissions on tests") 2>/dev/null
+find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+'
+(echo "<<< done") 2>/dev/null
-#SELinux
-%patch950 -p1 -b .selinux
-%patch951 -p1 -b .selinuxman
-%patch952 -p1 -b .cpZ
+# FIXME: Force a newer gettext version to workaround `autoreconf -i` errors
+# with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel.
+sed -i "s/0.19.2/$(rpm -q --queryformat '%%{VERSION}\n' gettext-devel)/" bootstrap.conf configure.ac
-chmod a+x tests/misc/sort-mb-tests tests/df/direct tests/cp/attr-existing || :
-
-#fix typos/mistakes in localized documentation(#439410, #440056)
-find ./po/ -name "*.p*" | xargs \
- sed -i \
- -e 's/-dpR/-cdpR/'
+autoreconf -fiv
%build
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic"
+
+# Upstream suggests to build with -Dlint for static analyzers:
+# https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html
+# ... and even for production binary RPMs:
+# https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00130.html
+# There is currently no measurable performance drop or other known downside.
+CFLAGS="$CFLAGS -Dlint"
+
+# make mknod work again in chroot without /proc being mounted (#1811038)
+export ac_cv_func_lchmod="no"
+
+# needed for out-of-tree build
+%global _configure ../configure
+
%{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1}
-#autoreconf -i -v
-touch aclocal.m4 configure config.hin Makefile.in */Makefile.in
-aclocal -I m4
-autoconf --force
-automake --copy --add-missing
-%configure --enable-largefile %{?!nopam:--enable-pam} \
- %{?!noselinux:--enable-selinux} \
- --enable-install-program=su,hostname,arch \
- --with-tty-group \
- DEFAULT_POSIX2_VERSION=200112 alternative=199209 || :
+for type in separate single; do
+ mkdir -p $type && \
+ (cd $type || exit $?
+ if test $type = 'single'; then
+ config_single='--enable-single-binary'
+ config_single="$config_single --without-openssl" # smaller/slower sha*sum
+ config_single="$config_single --without-libgmp" # expr/factor machine ints
+ else
+ config_single='--with-openssl' # faster sha*sum
+ fi
+ %configure $config_single \
+ --cache-file=../config.cache \
+ --enable-install-program=arch \
+ --enable-no-install-program=kill,uptime \
+ --enable-systemd \
+ --with-tty-group \
+ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || :
+ %make_build all V=1
-# Regenerate manpages
-touch man/*.x
+ # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079)
+ ln -fv ../lib/parse-datetime.{c,y} .
+ )
+done
-make all %{?_smp_mflags} \
- %{?!nopam:CPPFLAGS="-DUSE_PAM"}
-
-# XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp
-sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi
+# Get the list of supported utilities
+cp %SOURCE50 .
%check
-make check
+for type in separate single; do
+ test $type = 'single' && subdirs='SUBDIRS=.' # Only check gnulib once
+ (cd $type && make check %{?_smp_mflags} $subdirs)
+done
%install
-rm -rf $RPM_BUILD_ROOT
-make DESTDIR=$RPM_BUILD_ROOT install
+for type in separate single; do
+ install=install
+ if test $type = 'single'; then
+ subdir=%{_libexecdir}/%{name}; install=install-exec
+ fi
+ (cd $type && make DESTDIR=$RPM_BUILD_ROOT/$subdir $install)
-# man pages are not installed with make install
-make mandir=$RPM_BUILD_ROOT%{_mandir} install-man
+%if "%{_sbindir}" != "%{_bindir}"
+ # chroot was in /usr/sbin :
+ mkdir -p $RPM_BUILD_ROOT/$subdir/%_sbindir
+ mv $RPM_BUILD_ROOT/$subdir/{%_bindir,%_sbindir}/chroot
+%endif
-# fix japanese catalog file
-if [ -d $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES ]; then
- mkdir -p $RPM_BUILD_ROOT%{_datadir}/locale/ja/LC_MESSAGES
- mv $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES/*mo \
- $RPM_BUILD_ROOT%{_datadir}/locale/ja/LC_MESSAGES
- rm -rf $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC
-fi
-
-bzip2 -9f ChangeLog
-
-# let be compatible with old fileutils, sh-utils and textutils packages :
-mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}
-%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d}
-
-# chroot was in /usr/sbin :
-mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot
+ # Move multicall variants to *.single.
+ # RemovePathPostfixes will strip that later.
+ if test $type = 'single'; then
+ for dir in %{_bindir} \
+%if "%{_sbindir}" != "%{_bindir}"
+%{_sbindir} \
+%endif
+%{_libexecdir}/%{name}; do
+ for bin in $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/$dir/*; do
+ basebin=$(basename $bin)
+ mv $bin $RPM_BUILD_ROOT/$dir/$basebin.single
+ done
+ done
+ fi
+done
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d
-install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS
-install -p -c -m644 %SOURCE102 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.lightbgcolor
-install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color
+install -p -c -m644 DIR_COLORS{,.lightbgcolor} $RPM_BUILD_ROOT%{_sysconfdir}
install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh
install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh
-# su
-install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir}
-%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}}
-# do not ship runuser in /usr/bin/runuser
-rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || :
-
-# These come from util-linux and/or procps.
-for i in hostname uptime kill ; do
- rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1}
-done
-
-%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su}
-%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l}
-%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser}
-%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l}
-
-# Compress ChangeLogs from before the fileutils/textutils/etc merge
-bzip2 -f9 old/*/C*
-
-# Use hard links instead of symbolic links for LC_TIME files (bug #246729).
-find %{buildroot}%{_datadir}/locale -type l | \
-(while read link
- do
- target=$(readlink "$link")
- rm -f "$link"
- ln "$(dirname "$link")/$target" "$link"
- done)
-
%find_lang %name
+# Add the %%lang(xyz) ownership for the LC_TIME dirs as well...
+grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lang
# (sb) Deal with Installed (but unpackaged) file(s) found
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
-%clean
-rm -rf $RPM_BUILD_ROOT
+%files -f supported_utils
+%exclude %{_bindir}/*.single
+%dir %{_libexecdir}/coreutils
+%{_libexecdir}/coreutils/*.so
-%pre
-# We must deinstall these info files since they're merged in
-# coreutils.info. else their postun'll be run too late
-# and install-info will fail badly because of duplicates
-for file in sh-utils textutils fileutils; do
- if [ -f %{_infodir}/$file.info.gz ]; then
- /sbin/install-info --delete %{_infodir}/$file.info.gz --dir=%{_infodir}/dir &> /dev/null || :
- fi
-done
+%files single
+%{_bindir}/*.single
+%if "%{_sbindir}" != "%{_bindir}"
+%{_sbindir}/chroot.single
+%endif
+%dir %{_libexecdir}/coreutils
+%{_libexecdir}/coreutils/*.so.single
+# duplicate the license because coreutils-common does not need to be installed
+%{!?_licensedir:%global license %%doc}
+%license COPYING
-%preun
-if [ $1 = 0 ]; then
- if [ -f %{_infodir}/%{name}.info.gz ]; then
- /sbin/install-info --delete %{_infodir}/%{name}.info.gz %{_infodir}/dir || :
- fi
-fi
-
-%post
-%{_bindir}/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \
- %{_infodir}/dir.rpmmodify || exit 0
- /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir
-if [ -f %{_infodir}/%{name}.info.gz ]; then
- /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || :
-fi
-
-%files -f %{name}.lang
-%defattr(-,root,root,-)
-%dir %{_datadir}/locale/*/LC_TIME
+%files common -f %{name}.lang
%config(noreplace) %{_sysconfdir}/DIR_COLORS*
%config(noreplace) %{_sysconfdir}/profile.d/*
-%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su}
-%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su-l}
-%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser}
-%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l}
-%doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/*
-%{_bindir}/arch
-%{_bindir}/basename
-%{_bindir}/cat
-%{_bindir}/chgrp
-%{_bindir}/chmod
-%{_bindir}/chown
-%{_bindir}/cp
-%{_bindir}/cut
-%{_bindir}/date
-%{_bindir}/dd
-%{_bindir}/df
-%{_bindir}/echo
-%{_bindir}/env
-%{_bindir}/false
-%{_bindir}/link
-%{_bindir}/ln
-%{_bindir}/ls
-%{_bindir}/mkdir
-%{_bindir}/mknod
-%{_bindir}/mv
-%{_bindir}/nice
-%{_bindir}/pwd
-%{_bindir}/readlink
-%{_bindir}/rm
-%{_bindir}/rmdir
-%{_bindir}/sleep
-%{_bindir}/sort
-%{_bindir}/stty
-%attr(4755,root,root) %{_bindir}/su
-%{_bindir}/sync
-%{_bindir}/mktemp
-%{_bindir}/touch
-%{_bindir}/true
-%{_bindir}/uname
-%{_bindir}/unlink
-%{_bindir}/[
-%{_bindir}/base64
-%{_bindir}/chcon
-%{_bindir}/cksum
-%{_bindir}/comm
-%{_bindir}/csplit
-%{_bindir}/dir
-%{_bindir}/dircolors
-%{_bindir}/dirname
-%{_bindir}/du
-%{_bindir}/expand
-%{_bindir}/expr
-%{_bindir}/factor
-%{_bindir}/fmt
-%{_bindir}/fold
-%{_bindir}/groups
-%{_bindir}/head
-%{_bindir}/hostid
-%{_bindir}/id
-%{_bindir}/install
-%{_bindir}/join
-%{_bindir}/logname
-%{_bindir}/md5sum
-%{_bindir}/mkfifo
-%{_bindir}/nl
-%{_bindir}/nohup
-%{_bindir}/nproc
-%{_bindir}/od
-%{_bindir}/paste
-%{_bindir}/pathchk
-%{_bindir}/pinky
-%{_bindir}/pr
-%{_bindir}/printenv
-%{_bindir}/printf
-%{_bindir}/ptx
-%{_bindir}/realpath
-%{_bindir}/runcon
-%{_bindir}/seq
-%{_bindir}/sha1sum
-%{_bindir}/sha224sum
-%{_bindir}/sha256sum
-%{_bindir}/sha384sum
-%{_bindir}/sha512sum
-%{_bindir}/shred
-%{_bindir}/shuf
-%{_bindir}/split
-%{_bindir}/stat
-%{_bindir}/stdbuf
-%{_bindir}/sum
-%{_bindir}/tac
-%{_bindir}/tail
-%{_bindir}/tee
-%{_bindir}/test
-%{_bindir}/timeout
-%{_bindir}/tr
-%{_bindir}/truncate
-%{_bindir}/tsort
-%{_bindir}/tty
-%{_bindir}/unexpand
-%{_bindir}/uniq
-%{_bindir}/users
-%{_bindir}/vdir
-%{_bindir}/wc
-%{_bindir}/who
-%{_bindir}/whoami
-%{_bindir}/yes
%{_infodir}/coreutils*
-%{_libexecdir}/coreutils*
%{_mandir}/man*/*
-%{_sbindir}/chroot
-%{?!norunuser:%{_sbindir}/runuser}
+# The following go to /usr/share/doc/coreutils-common
+%doc ABOUT-NLS NEWS README THANKS TODO
+%license COPYING
%changelog
-* Wed Jan 30 2013 Ondrej Vasik 8.15-10
-- fix multiple segmantation faults in i18n patch (by SUSE)
- (#869442, #902917)- CVE2013-0223/CVE2013-0221/CVE2013-0222
+* Tue Jan 13 2026 Lukáš Zaoral - 9.9-2
+- fix cut test failure on aarch64 rawhide (rhbz#2424302)
-* Wed Dec 12 2012 Ondrej Vasik 8.15-9
+* Wed Nov 26 2025 Lukáš Zaoral - 9.9-1
+- rebase to latest upstream release (rhbz#2413803)
+
+* Mon Sep 29 2025 Lukáš Zaoral - 9.8-3
+- require gnulib-l10n for translations of gnulib messages (rhbz#2393892)
+
+* Thu Sep 25 2025 Lukáš Zaoral - 9.8-2
+- tail: fix tailing larger number of lines in regular files (rhbz#2398008)
+
+* Wed Sep 24 2025 Lukáš Zaoral - 9.8-1
+- rebase to latest upstream release (rhbz#2397467)
+- remove downstream patch for selinux options deprecated since 2009
+
+* Wed Jul 23 2025 Fedora Release Engineering - 9.7-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
+
+* Mon Jun 30 2025 Lukáš Zaoral - 9.7-4
+- stty: add support for arbitrary baud rates (rhbz#2375439)
+
+* Wed May 28 2025 Lukáš Zaoral - 9.7-3
+- sort: fix buffer under-read (CVE-2025-5278)
+
+* Mon May 19 2025 Lukáš Zaoral - 9.7-2
+- cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149)
+
+* Wed Apr 09 2025 Lukáš Zaoral - 9.7-1
+- rebase to latest upstream release (rhbz#2358624)
+
+* Tue Feb 25 2025 Lukáš Zaoral - 9.6-2
+- fix 'who -m' with guessed tty names (rhbz#2343998)
+
+* Mon Jan 20 2025 Lukáš Zaoral - 9.6-1
+- rebase to latest upstream version (rhbz#2338620)
+- sync i18n patch with SUSE (Kudos to Berny Völker!)
+
+* Thu Jan 16 2025 Fedora Release Engineering - 9.5-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
+
+* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 9.5-12
+- Rebuilt for the bin-sbin merge (2nd attempt)
+
+* Wed Nov 13 2024 Florian Weimer - 9.5-11
+- Affinity mask handling in nproc for large CPU counts (rhbz#2325167)
+
+* Fri Sep 27 2024 Lukáš Zaoral - 9.5-10
+- fix fold -b with UTF8 locale (RHEL-60295)
+
+* Tue Aug 27 2024 Lukáš Zaoral - 9.5-9
+- show web sessions in who output (rhbz#2307847)
+
+* Wed Aug 21 2024 Lukáš Zaoral - 9.5-8
+- add missing systemd-devel buildrequires
+
+* Wed Jul 17 2024 Fedora Release Engineering - 9.5-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
+
+* Mon Jul 15 2024 Lukáš Zaoral - 9.5-6
+- Rebuilt for the bin-sbin merge
+
+* Mon Jul 15 2024 Sohum Mendon - 9.5-5
+- fix incorrect exit status when fold is called with a non-existent file
+
+* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 9.5-4
+- Rebuilt for the bin-sbin merge
+
+* Thu Jul 04 2024 Lukáš Zaoral - 9.5-3
+- do not buildrequire perl(Expect) on ELN
+
+* Tue Jun 04 2024 Lukáš Zaoral - 9.5-2
+- enable LTO on ppc64le
+
+* Tue Apr 02 2024 Lukáš Zaoral - 9.5-1
+- rebase to latest upstream version (rhbz#2272063)
+- sync i18n patch with SUSE (Kudos to Berny Völker!)
+- add some test dependencies to execute additional part of the upstream test-suite
+
+* Mon Jan 29 2024 Lukáš Zaoral - 9.4-6
+- fix tail on kernels with 64k page sizes (RHEL-22866)
+
+* Wed Jan 24 2024 Fedora Release Engineering - 9.4-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Fri Jan 19 2024 Fedora Release Engineering - 9.4-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Thu Jan 18 2024 Lukáš Zaoral - 9.4-3
+- fix compilation on i686
+
+* Thu Jan 18 2024 Lukáš Zaoral - 9.4-2
+- fix buffer overflow in split (CVE-2024-0684)
+
+* Fri Sep 15 2023 Lukáš Zaoral - 9.4-1
+- new upstream release 9.4 (#2235759)
+- enable integration with systemd
+- fix the license field
+
+* Wed Jul 19 2023 Fedora Release Engineering - 9.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Tue Apr 18 2023 Kamil Dudka - 9.3-1
+- remove obsolete Provides for absolute paths
+- new upstream release 9.3
+
+* Tue Apr 11 2023 Lukáš Zaoral - 9.2-4
+- migrate to SPDX license format
+
+* Fri Mar 24 2023 Kamil Dudka - 9.2-3
+- copy: fix --reflink=auto to fallback in more cases (#2180056)
+- cksum: fix reporting of failed checks (#2180056)
+
+* Wed Mar 22 2023 Kamil Dudka - 9.2-2
+- coreutils-getgrouplist.patch: drop a patch no longer needed
+
+* Wed Mar 22 2023 Kamil Dudka - 9.2-1
+- new upstream release 9.2
+
+* Thu Jan 19 2023 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
+
+* Mon Jan 02 2023 Kamil Dudka - 9.1-10
+- drop obsolete downstream-only extension of date(1) man page
+- undocument downstream SELinux options deprecated since 2009
+
+* Mon Jan 02 2023 Kamil Dudka - 9.1-9
+- basic support for checking NFSv4 ACLs (#2137866)
+
+* Mon Sep 19 2022 Kamil Dudka - 9.1-8
+- remove obsolete extension of mkdir(1) info documentation
+
+* Tue Aug 23 2022 Kamil Dudka - 9.1-7
+- remove non-upstream patch for uname -i/-p (#548834)
+
+* Mon Aug 08 2022 Kamil Dudka - 9.1-6
+- improve wording of a comment in /etc/DIR_COLORS (#2112593)
+
+* Mon Aug 08 2022 Kamil Dudka - 9.1-5
+- improve handling of control characters in unexpand (#2112870)
+
+* Mon Aug 01 2022 Kamil Dudka - 9.1-4
+- prevent unexpand from failing on control characters (#2112870)
+
+* Wed Jul 20 2022 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Sat Apr 23 2022 Pádraig Brady - 9.1-2
+- make simple backups in correct dir; broken in 9.1
+
+* Tue Apr 19 2022 Kamil Dudka - 9.1-1
+- new upstream release 9.1
+
+* Mon Mar 21 2022 Kamil Dudka - 9.0-5
+- ls, stat: avoid triggering automounts (#2044981)
+
+* Tue Mar 01 2022 Kamil Dudka - 9.0-4
+- make `df --direct` work again (#2058686)
+
+* Wed Jan 19 2022 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Mon Oct 04 2021 Kamil Dudka - 9.0-2
+- chmod: fix exit status when ignoring symlinks
+
+* Sun Sep 26 2021 Kamil Dudka - 9.0-1
+- new upstream release 9.0
+
+* Tue Sep 14 2021 Sahana Prasad
+- Rebuilt with OpenSSL 3.0.0
+
+* Wed Jul 21 2021 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Wed Jul 07 2021 Kamil Dudka - 8.32-30
+- df: fix duplicated remote entries due to bind mounts (#1979814)
+
+* Thu Jul 01 2021 Kamil Dudka - 8.32-28
+- tail: fix stack out-of-bounds write with --follow
+
+* Tue Jun 08 2021 Kamil Dudka - 8.32-27
+- mountlist: recognize fuse.portal as dummy file system (#1913358)
+
+* Mon May 17 2021 Kamil Dudka - 8.32-26
+- cp: pick additional copy_file_range()-related fixes from upstream
+
+* Mon May 03 2021 Kamil Dudka - 8.32-24
+- copy: ensure we enforce --reflink=never (#1956080)
+
+* Tue Apr 27 2021 Kamil Dudka - 8.32-23
+- copy: do not refuse to copy a swap file
+
+* Fri Apr 09 2021 Kamil Dudka - 8.32-22
+- weaken the dependency on glibc-doc to reduce minimal installations
+- drop the last use of ncurses no longer needed (#1830318)
+- utimens: fix confusing arg type in internal func
+
+* Fri Mar 26 2021 Kamil Dudka - 8.32-21
+- hostname,ln: fix memory leaks detected by Coverity
+
+* Wed Mar 24 2021 Kamil Dudka - 8.32-20
+- cp: use copy_file_range if available
+
+* Thu Feb 18 2021 Kamil Dudka - 8.32-19
+- stat: add support for the exfat file system (#1921427)
+
+* Wed Feb 03 2021 Kamil Dudka - 8.32-18
+- make coreutils-common recommend glibc-doc for info doc refs (#959597)
+
+* Tue Feb 02 2021 Kamil Dudka - 8.32-17
+- ls: fix crash printing SELinux context for unstatable files (#1921249)
+- split: fix --number=K/N to output correct part of file (#1921246)
+- expr: fix invalid read with unmatched \(...\) (#1919775)
+
+* Tue Jan 26 2021 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Tue Dec 08 2020 Kamil Dudka - 8.32-15
+- rm: do not skip files upon failure to remove an empty dir (#1905481)
+
+* Tue Nov 03 2020 Kamil Dudka - 8.32-14
+- df,stat,tail: recognize more file system types
+
+* Wed Oct 14 2020 Kamil Dudka - 8.32-13
+- make the %%build section idempotent
+
+* Mon Aug 17 2020 Kamil Dudka - 8.32-12
+- do not install /etc/DIR_COLORS.256color (#1830318)
+
+* Thu Jul 30 2020 Kamil Dudka - 8.32-11
+- cp: default to --reflink=auto (#1861108)
+
+* Mon Jul 27 2020 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Fri Jul 24 2020 Kamil Dudka - 8.32-9
+- disable -flto on ppc64le to make test-float pass (#1789115)
+
+* Mon Jul 13 2020 Tom Stellard - 8.32-8
+- Use make macros
+- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
+
+* Fri Jun 26 2020 James Cassell - 8.32-7
+- move ncurses to -common package since it's needed for colorls.sh
+- make ncurses optional
+
+* Fri May 15 2020 Kamil Dudka - 8.32-6
+- compile with -Dlint to enable optional initialization and cleanup code
+
+* Thu Apr 23 2020 Kamil Dudka - 8.32-5
+- du: simplify leaf optimization for XFS (#1823247)
+
+* Fri Apr 17 2020 Tom Stellard - 8.32-4
+- Fix missing inline function definition
+
+* Wed Mar 11 2020 Kamil Dudka - 8.32-3
+- uniq: remove collation handling as required by newer POSIX
+
+* Mon Mar 09 2020 Kamil Dudka - 8.32-2
+- make mknod work again in chroot without /proc being mounted (#1811038)
+- ls: restore 8.31 behavior on removed directories
+
+* Thu Mar 05 2020 Kamil Dudka - 8.32-1
+- new upstream release 8.32
+
+* Tue Feb 11 2020 Kamil Dudka - 8.31-10
+- make upstream test-suite work with root privileges (#1800597)
+
+* Wed Feb 05 2020 Kamil Dudka - 8.31-9
+- use upstream fix the cp/proc-short-read test
+
+* Thu Jan 30 2020 Kamil Dudka - 8.31-8
+- skip a test that relies on /proc/kallsyms having immutable content
+
+* Tue Jan 28 2020 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Thu Oct 17 2019 Kamil Dudka - 8.31-6
+- temporarily disable the use of statx (#1760300)
+
+* Fri Oct 11 2019 Kamil Dudka - 8.31-5
+- use statx instead of stat when available (#1760300)
+
+* Wed Jul 24 2019 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Tue Jul 16 2019 Kamil Dudka - 8.31-3
+- disable flashing in ls colors for broken symbolic links (#1728986)
+
+* Mon Mar 18 2019 Kamil Dudka - 8.31-2
+- fix formatting of sha512sum(1) man page (#1688740)
+
+* Mon Mar 11 2019 Kamil Dudka - 8.31-1
+- new upstream release 8.31
+
+* Thu Jan 31 2019 Fedora Release Engineering
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Wed Nov 07 2018 Kamil Dudka - 8.30-8
+- sync: fix open() fallback bug
+- fix implicit declaration warning in coreutils-getgrouplist.patch
+
+* Sat Nov 03 2018 Kevin Fenzi - 8.30-7
+- Also remove Requires pre/post used by info scriptlets.
+
+* Sat Nov 03 2018 Kevin Fenzi - 8.30-6
+- Remove no longer needed info scriptlets
+
+* Thu Oct 11 2018 Kamil Dudka - 8.30-5
+- fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942)
+
+* Thu Jul 12 2018 Fedora Release Engineering - 8.30-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Tue Jul 10 2018 Kamil Dudka - 8.30-3
+- rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518)
+
+* Wed Jul 04 2018 Kamil Dudka - 8.30-2
+- sync i18n patches with Suse (patch by Bernhard Voelker)
+
+* Mon Jul 02 2018 Kamil Dudka - 8.30-1
+- new upstream release 8.30
+
+* Wed May 30 2018 Kamil Dudka - 8.29-12
+- add provides to coreutils-single to make it a drop-in replacement
+
+* Mon May 28 2018 Kamil Dudka - 8.29-11
+- ls: increase the allowed abmon width from 5 to 12 (#1577872)
+- date, ls: pick strftime fixes from glibc to improve locale support (#1577872)
+
+* Fri Apr 20 2018 Kamil Dudka - 8.29-10
+- fix crash caused by mistakenly enabled leaf optimization (#1558249)
+
+* Fri Mar 23 2018 Kamil Dudka - 8.29-9
+- make it possible to install the latest available Adobe Reader RPM for Linux
+
+* Mon Mar 19 2018 Kamil Dudka - 8.29-8
+- drop BR for bison, which is not used during the build
+
+* Fri Mar 16 2018 Kamil Dudka - 8.29-7
+- make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079)
+
+* Tue Mar 06 2018 Kamil Dudka - 8.29-6
+- fix build failure with glibc-2.28
+
+* Mon Feb 26 2018 Igor Gnatenko - 8.29-5
+- Remove /bin/* Provides
+
+* Mon Feb 19 2018 Kamil Dudka - 8.29-4
+- add explicit BR for the gcc compiler
+
+* Wed Feb 07 2018 Fedora Release Engineering - 8.29-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Tue Jan 23 2018 Kamil Dudka - 8.29-2
+- doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018)
+- mv -n: do not overwrite the destination
+
+* Tue Jan 02 2018 Kamil Dudka - 8.29-1
+- new upstream release 8.29
+
+* Tue Nov 07 2017 Igor Gnatenko - 8.28-2
+- Remove very old Provides (mktemp, sh-utils, textwrap, fileutils, stat)
+
+* Mon Sep 04 2017 Kamil Dudka - 8.28-1
+- new upstream release 8.28
+
+* Tue Aug 22 2017 Ville Skyttä - 8.27-16
+- Own the %%{_libexecdir}/coreutils dir
+
+* Fri Aug 18 2017 Kamil Dudka - 8.27-15
+- ptx: fix a possible crash caused by integer overflow (#1482445)
+
+* Wed Aug 02 2017 Fedora Release Engineering - 8.27-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Fri Jul 28 2017 Igor Gnatenko - 8.27-13
+- Enable separate debuginfo back
+
+* Wed Jul 26 2017 Kamil Dudka - 8.27-12
+- avoid build failure caused broken RPM code that produces debuginfo packages
+
+* Wed Jul 26 2017 Fedora Release Engineering - 8.27-11
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Tue May 30 2017 Sebastian Kisela - 8.27-10
+- doc: mention `setpriv --no-new-privs` feature in runcon info
+
+* Tue May 16 2017 Kamil Dudka - 8.27-9
+- add coreutils-full provides for coreutils to make it explicitly installable
+
+* Wed May 03 2017 Kamil Dudka - 8.27-8
+- drop coreutils-overflow.patch no longer needed (#158405)
+
+* Wed May 03 2017 Kamil Dudka - 8.27-7
+- drop workaround for already fixed rpm-build bug (#1306559)
+
+* Wed May 03 2017 Kamil Dudka - 8.27-6
+- do not mention a deprecated option in localized man pages
+- drop workaround no longer needed for 10 years old rpm-build bug (#246729)
+- drop unnecessary uses of %%defattr
+
+* Fri Apr 28 2017 Sebastian Kisela - 8.27-5
+- tail: revert to polling if a followed directory is replaced (#1283760)
+
+* Thu Apr 27 2017 Kamil Dudka - 8.27-4
+- date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476)
+
+* Tue Apr 25 2017 Kamil Dudka - 8.27-3
+- do not obsolete coreutils-single, so it can be installed by DNF2 (#1444802)
+
+* Wed Mar 15 2017 Kamil Dudka - 8.27-2
+- fix spurious build failure caused by the misc/date-debug test
+
+* Thu Mar 09 2017 Kamil Dudka - 8.27-1
+- new upstream release 8.27
+
+* Fri Feb 10 2017 Fedora Release Engineering - 8.26-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Fri Feb 03 2017 Kamil Dudka - 8.26-6
+- fold: preserve new-lines in mutlibyte text (#1418505)
+
+* Mon Jan 23 2017 Kamil Dudka - 8.26-5
+- date: fix TZ= regression (patch by Pádraig Brady)
+
+* Mon Jan 02 2017 Kamil Dudka - 8.26-4
+- use upstream patch for gnulib's test-lock (instead of disabling it)
+
+* Thu Dec 15 2016 Kamil Dudka - 8.26-3
+- drop build fixes no longer needed
+
+* Fri Dec 02 2016 Kamil Dudka - 8.26-2
+- apply patches automatically to ease maintenance
+
+* Thu Dec 01 2016 Kamil Dudka - 8.26-1
+- new upstream release 8.26
+
+* Mon Oct 31 2016 Kamil Dudka - 8.25-17
+- md5sum,sha*sum: fix --ignore-missing with checksums starting with 00
+
+* Tue Oct 11 2016 Tomáš Mráz - 8.25-16
+- rebuild with OpenSSL 1.1.0
+
+* Wed Sep 07 2016 Kamil Dudka - 8.25-15
+- ls: allow interruption when reading slow directories (#1365933)
+
+* Tue Jul 19 2016 Kamil Dudka - 8.25-14
+- run autoreconf in %%prep
+- drop post-install fix for Japanese locales that no longer applies
+- fix 'sort -h -k' in locales that use blank as thousands separator (#1355780)
+
+* Thu Jul 14 2016 Kamil Dudka - 8.25-13
+- make 'sort -h' work for arbitrary column even when using UTF-8 locales
+
+* Mon Jul 11 2016 Kamil Dudka - 8.25-12
+- install -Z now sets default SELinux context for created directories (#1339135)
+- drop the %%pre scriptlet, which is no longer needed (#1354078)
+- clarify recognition of "^COLOR.*none" in /etc/DIR_COLORS (#1349579)
+
+* Thu Jul 07 2016 Jakub Martisko - 8.25-11
+- switch to UTF8 locale when (un)expand input contains BOM header
+ (#1158494)
+- fixed regression where (un)expand would end with "long input line"
+ error when BOM header is present
+
+* Fri Jun 24 2016 Ondrej Vasik - 8.25-10
+- change way of detection of interactive shell in colorls.sh script
+ (#1321648)
+
+* Mon Jun 20 2016 Kamil Dudka - 8.25-9
+- add BR for glibc-langpack-en to prevent the expand/mb test from failing
+- do not use /bin/mv in %%post to avoid a circular dependency (#1348043)
+
+* Fri Jun 17 2016 Kamil Dudka - 8.25-8
+- sync /etc/DIR_COLORS with latest upstream (#1335320)
+
+* Wed Jun 15 2016 Kamil Dudka - 8.25-7
+- handle info doc in RPM scriptlets of coreutils-common, which provides it
+- make sure that the license file is installed, even if coreutils-common is not
+
+* Thu Jun 09 2016 Jakub Martisko - 8.25-6
+- (un)expand: fix regression in handling input files, where only
+ the first file was processed.
+
+* Sat Mar 05 2016 Ondrej Vasik - 8.25-5
+- cut: move back to the old i18n implementation (#1314722)
+
+* Mon Feb 15 2016 Ondrej Vasik - 8.25-4
+- cut: fix regression in handling fields for lines wider
+ than 64 chars (#1304839)
+
+* Thu Feb 11 2016 Lubomir Rintel - 8.25-3
+- Fix a regression in unexpand empty line handling
+
+* Thu Jan 21 2016 Ondrej Vasik - 8.25-2
+- Adjust the i18n patch for coreutils-8.25
+- add new base32 binary
+
+* Wed Jan 20 2016 Ondrej Vasik - 8.25-1
+- new upstream release(#1300282)
+
+* Fri Jan 15 2016 Ondrej Oprala - 8.24-108
+- cut: be MB for ALL archs
+
+* Fri Jan 15 2016 Ondrej Oprala - 8.24-107
+- Use the new i18n implementation for the cut utility
+
+* Wed Jan 13 2016 Ondrej Vasik - 8.24-106
+- mv: prevent dataloss when source dir is specified multiple
+ times (#1297464, by P.Brady)
+
+* Mon Dec 14 2015 Pádraig Brady - 8.24-105
+- Give explicit priority to coreutils over coreutils-single
+
+* Thu Dec 03 2015 Pádraig Brady - 8.24-104
+- Avoid libgmp and libcrypto dependencies from coreutils-single
+
+* Thu Dec 03 2015 Pádraig Brady - 8.24-103
+- Remove erroneous /usr/bin/kill from coreutils-single
+
+* Tue Dec 01 2015 Ondrej Oprala