From 25051789712d783c23f02b175814359bf50b5b7a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Sat, 12 Sep 2009 09:28:49 +0000 Subject: [PATCH] new upstream bugfix release 7.6, removed applied patches,defuzzed the rest --- .cvsignore | 2 +- coreutils-4.5.3-langinfo.patch | 22 +- coreutils-4.5.3-sysinfo.patch | 12 +- coreutils-5.2.1-runuser.patch | 82 +- coreutils-6.10-configuration.patch | 11 - coreutils-6.10-manpages.patch | 2 +- coreutils-7.4-sttytcsadrain.patch | 4 +- coreutils-7.5-df-localdevice.patch | 17 - coreutils-7.5-kojiutimensatskip.patch | 18 - coreutils-7.5-ls-inode.patch | 193 -- coreutils-i18n.patch | 2349 ++++++++++++------------- coreutils-pam.patch | 12 +- coreutils-selinux.patch | 458 ++--- coreutils-setsid.patch | 40 +- coreutils.spec | 14 +- sources | 2 +- 16 files changed, 1487 insertions(+), 1751 deletions(-) delete mode 100644 coreutils-7.5-df-localdevice.patch delete mode 100644 coreutils-7.5-kojiutimensatskip.patch delete mode 100644 coreutils-7.5-ls-inode.patch diff --git a/.cvsignore b/.cvsignore index 2d04123..edb4b98 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.5.tar.xz +coreutils-7.6.tar.xz diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index 49a88aa..a45dcb3 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -3,16 +3,16 @@ @@ -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); - } + { +- /* 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-4.5.3-sysinfo.patch b/coreutils-4.5.3-sysinfo.patch index 94c9f91..cb61d81 100644 --- a/coreutils-4.5.3-sysinfo.patch +++ b/coreutils-4.5.3-sysinfo.patch @@ -17,9 +17,9 @@ + char *element = unknown; #if HAVE_SYSINFO && defined SI_ARCHITECTURE { - static char processor[257]; - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) - element = processor; + static char processor[257]; + if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) + element = processor; } +#else + { @@ -54,10 +54,10 @@ + char *element = unknown; #if HAVE_SYSINFO && defined SI_PLATFORM { - static char hardware_platform[257]; + static char hardware_platform[257]; @@ -356,6 +378,14 @@ - hardware_platform, sizeof hardware_platform)) - element = hardware_platform; + hardware_platform, sizeof hardware_platform)) + element = hardware_platform; } +#else + { diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index f879cdd..f78cbc0 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -121,11 +121,11 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c static void run_shell (char const *, char const *, char **, size_t, - const struct passwd *) -+ const struct passwd * ++ const struct passwd * +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) #ifdef USE_PAM ; #else @@ -180,9 +180,9 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c -change_identity (const struct passwd *pw) +change_identity (const struct passwd *pw +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) { #ifdef HAVE_INITGROUPS + int rc = 0; @@ -202,12 +202,12 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c static void run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args, const struct passwd *pw) -+ size_t n_additional_args, const struct passwd *pw +- size_t n_additional_args, const struct passwd *pw) ++ size_t n_additional_args, const struct passwd *pw +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); @@ -218,9 +218,9 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - change_identity (pw); + change_identity (pw +#ifdef RUNUSER -+ , groups, num_groups ++ , groups, num_groups +#endif -+ ); ++ ); pam_end(pamh, 0); if (!same_session) setsid (); @@ -279,43 +279,43 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "c:flmps:" +#ifdef RUNUSER -+ "g:G:" ++ "g:G:" +#endif -+ , longopts, NULL)) != -1) ++ , longopts, NULL)) != -1) { switch (optc) - { + { @@ -697,6 +773,28 @@ main (int argc, char **argv) - shell = optarg; - break; + 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': ++ 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; ++ 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_HELP_CHAR; - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -735,7 +833,20 @@ main (int argc, char **argv) - : DEFAULT_SHELL); + : DEFAULT_SHELL); endpwent (); - if (!correct_password (pw)) @@ -343,17 +343,17 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - change_identity (pw); + change_identity (pw +#ifdef RUNUSER -+ , groups, num_supp_groups ++ , groups, num_supp_groups +#endif -+ ); ++ ); #endif - run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw +#ifdef RUNUSER -+ , groups, num_supp_groups ++ , groups, num_supp_groups +#endif -+ ); ++ ); } diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/help-version --- coreutils-7.5.orig/tests/misc/help-version diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index c0813cb..9b1ec54 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -27,17 +27,6 @@ diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/ ## end gnulib module strverscmp-tests -diff -urN coreutils-6.11-orig/tests/mkdir/selinux coreutils-6.11/tests/mkdir/selinux ---- coreutils-6.11-orig/tests/mkdir/selinux 2008-04-19 23:34:23.000000000 +0200 -+++ coreutils-6.11/tests/mkdir/selinux 2008-04-22 13:23:50.000000000 +0200 -@@ -38,6 +28,7 @@ - # successfully, in spite of the invalid context string. - - . $srcdir/test-lib.sh -+require_selinux_ - - c=invalid-selinux-context - msg="failed to set default file creation context to \`$c':" diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.sh --- coreutils-6.11-orig/tests/test-lib.sh 2008-04-19 23:34:23.000000000 +0200 +++ coreutils-6.11/tests/test-lib.sh 2008-04-24 14:18:59.000000000 +0200 diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 792ce42..047c41c 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -2,7 +2,7 @@ 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 (_("\ + fputs (_("\ -t, --text read in text mode (default)\n\ "), stdout); + fputs (_("\ diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch index af25979..caf8387 100644 --- a/coreutils-7.4-sttytcsadrain.patch +++ b/coreutils-7.4-sttytcsadrain.patch @@ -2,11 +2,11 @@ diff -urNp coreutils-7.4-orig/src/stty.c coreutils-7.4/src/stty.c --- coreutils-7.4-orig/src/stty.c 2009-04-24 14:41:19.000000000 +0200 +++ coreutils-7.4/src/stty.c 2009-06-11 10:15:41.000000000 +0200 @@ -1001,7 +1001,7 @@ main (int argc, char **argv) - spurious difference in an uninitialized portion of the structure. */ + spurious difference in an uninitialized portion of the structure. */ DECLARE_ZEROED_AGGREGATE (struct termios, new_mode); - if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) + if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) - error (EXIT_FAILURE, errno, "%s", device_name); + error (EXIT_FAILURE, errno, "%s", device_name); /* POSIX (according to Zlotnick's book) tcsetattr returns zero if diff --git a/coreutils-7.5-df-localdevice.patch b/coreutils-7.5-df-localdevice.patch deleted file mode 100644 index fb45306..0000000 --- a/coreutils-7.5-df-localdevice.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -urNp coreutils-7.5-orig/src/df.c coreutils-7.5/src/df.c ---- coreutils-7.5-orig/src/df.c 2009-08-15 17:25:32.000000000 +0200 -+++ coreutils-7.5/src/df.c 2009-09-03 16:37:25.000000000 +0200 -@@ -995,7 +995,12 @@ main (int argc, char **argv) - for (i = optind; i < argc; ++i) - { - int fd = open (argv[i], O_RDONLY | O_NOCTTY); -- if (fd < 0 || fstat (fd, &stats[i - optind])) -+ if (0 <= fd && !fstat (fd, &stats[i - optind]) -+ && !stat (argv[i], &stats[i - optind])) -+ { -+ /* open() may have failed for normal user but stat() works */ -+ } -+ else - { - error (0, errno, "%s", quote (argv[i])); - exit_status = EXIT_FAILURE; diff --git a/coreutils-7.5-kojiutimensatskip.patch b/coreutils-7.5-kojiutimensatskip.patch deleted file mode 100644 index 98f9907..0000000 --- a/coreutils-7.5-kojiutimensatskip.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -urNp coreutils-7.5-orig/src/copy.c coreutils-7.5/src/copy.c ---- coreutils-7.5-orig/src/copy.c -+++ coreutils-7.5/src/copy.c -@@ -124,7 +124,13 @@ static inline int - utimens_symlink (char const *file, struct timespec const *timespec) - { - #if HAVE_UTIMENSAT -- return utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); -+ int err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); -+ /* When configuring on a system with new headers and libraries, and -+ running on one with a kernel that is old enough to lack the syscall, -+ utimensat fails with ENOSYS. Ignore that. */ -+ if (err && errno == ENOSYS) -+ err = 0; -+ return err; - #else - /* Don't set errno=ENOTSUP here as we don't want - to output an error message for this case. */ diff --git a/coreutils-7.5-ls-inode.patch b/coreutils-7.5-ls-inode.patch deleted file mode 100644 index 2363aff..0000000 --- a/coreutils-7.5-ls-inode.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 3af748aa25193e8a5a8fe520cd967cfbc4d71cb8 Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Wed, 2 Jul 2008 18:01:43 +0200 -Subject: [PATCH] ls -i: print consistent inode numbers also for mount points - -On most unix- and linux-based kernels, ls -i DIR_CONTAINING_MOUNT_POINT -would print the wrong inode number for any entry that is a mount point. -It would do that by relying on readdir's dirent.d_ino values, while -most readdir implementations return the inode number of the underlying, -inaccessible directory. Thus, it is not consistent with what you'd -get when applying stat to the same entry. This bug led to surprising -results like "ls -i" and "ls -i --color" printing different numbers (ls -must usually "stat" a file to colorize its name). This change makes it -so that on offending systems, ls must stat non-command-line-arguments -for which otherwise it would be able to use "for free" dirent.d_ino -values. Regardless of this change, ls is already required to stat every -command-line argument. Note: versions of GNU ls prior to coreutils-6.0 -did not perform the invalid optimization, and hence always printed -correct inode numbers. Thus, for the sake of correctness, ls -i is -forgoing the readdir optimization, for any kernel (including linux!) -with POSIX-nonconforming readdir. Note that currently, only Cygwin has -been agile enough to conform. - -* src/ls.c (RELIABLE_D_INO): Define. -(print_dir): Use it. -For plenty of discussion, see this long thread: -http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14020 -This bug was introduced by the 2006-02-26 commit, 33eb3efe: -"In ls, avoid calling stat for --inode (-i), when possible." -* tests/ls/readdir-mountpoint-inode: New test. -* tests/Makefile.am (TESTS): Add it. -* tests/ls/stat-vs-dirent: Don't suppress failure of this test, -now that ls -i is fixed. Though note that it doesn't test well, -since it compares only the always-stat'd command-line arguments. ---- - src/ls.c | 23 +++++++++++- - tests/Makefile.am | 1 + - tests/ls/readdir-mountpoint-inode | 72 +++++++++++++++++++++++++++++++++++++ - tests/ls/stat-vs-dirent | 7 +--- - 4 files changed, 96 insertions(+), 7 deletions(-) - create mode 100755 tests/ls/readdir-mountpoint-inode - -diff --git a/src/ls.c b/src/ls.c -index 6316dfa..553090d 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -126,6 +126,26 @@ - Subtracting doesn't always work, due to overflow. */ - #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b)) - -+/* Unix-based readdir implementations have historically returned a dirent.d_ino -+ value that is sometimes not equal to the stat-obtained st_ino value for -+ that same entry. This error occurs for a readdir entry that refers -+ to a mount point. readdir's error is to return the inode number of -+ the underlying directory -- one that typically cannot be stat'ed, as -+ long as a file system is mounted on that directory. RELIABLE_D_INO -+ encapsulates whether we can use the more efficient approach of relying -+ on readdir-supplied d_ino values, or whether we must incur the cost of -+ calling stat or lstat to obtain each guaranteed-valid inode number. */ -+ -+#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1 -+#endif -+ -+#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER -+#else -+# define RELIABLE_D_INO(dp) D_INO (dp) -+#endif -+ - #if ! HAVE_STRUCT_STAT_ST_AUTHOR - # define st_author st_uid - #endif -@@ -2501,7 +2521,8 @@ print_dir (char const *name, char const *realname, bool command_line_arg) - # endif - } - #endif -- total_blocks += gobble_file (next->d_name, type, D_INO (next), -+ total_blocks += gobble_file (next->d_name, type, -+ RELIABLE_D_INO (next), - false, name); - - /* In this narrow case, print out each name right away, so -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 3177056..0151cb0 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -358,6 +358,7 @@ TESTS = \ - ls/no-arg \ - ls/no-cap \ - ls/proc-selinux-segfault \ -+ ls/readdir-mountpoint-inode \ - ls/recursive \ - ls/rt-1 \ - ls/stat-dtype \ -diff --git a/tests/ls/readdir-mountpoint-inode b/tests/ls/readdir-mountpoint-inode -new file mode 100755 -index 0000000..763cab1 ---- /dev/null -+++ b/tests/ls/readdir-mountpoint-inode -@@ -0,0 +1,72 @@ -+#!/bin/sh -+# ensure that ls -i works also for mount points -+ -+# Copyright (C) 2009 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 . -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ ls --version -+fi -+ -+. $srcdir/test-lib.sh -+ -+fail=0 -+ -+mount_points=$(df --local -P 2>&1 | sed -n 's,.*[0-9]% \(/.\),\1,p') -+test -z "$mount_points" && skip_test_ "this test requires a non-root mount point" -+ -+# Given e.g., /dev/shm, produce the list of GNU ls options that -+# let us list just that entry using readdir data from its parent: -+# ls -i -I '[^s]*' -I 's[^h]*' -I 'sh[^m]*' -I 'shm?*' -I '.?*' \ -+# -I '?' -I '??' /dev -+ -+ls_ignore_options() -+{ -+ name=$1 -+ opts="-I '.?*' -I '$name?*'" -+ while :; do -+ glob=$(echo "$name"|sed 's/\(.*\)\(.\)$/\1[^\2]*/') -+ opts="$opts -I '$glob'" -+ name=$(echo "$name"|sed 's/.$//') -+ test -z "$name" && break -+ glob=$(echo "$name"|sed 's/./?/g') -+ opts="$opts -I '$glob'" -+ done -+ echo "$opts" -+} -+ -+inode_via_readdir() -+{ -+ mount_point=$1 -+ base=$(basename $mount_point) -+ case $base in -+ .*) skip_test_ 'mount point component starts with "."' ;; -+ *[*?]*) skip_test_ 'mount point component contains "?" or "*"' ;; -+ esac -+ opts=$(ls_ignore_options "$base") -+ parent_dir=$(dirname $mount_point) -+ eval "ls -i $opts $parent_dir" | sed 's/ .*//' -+} -+ -+# FIXME: use a timeout, in case stat'ing mount points takes too long. -+ -+for dir in $mount_points; do -+ readdir_inode=$(inode_via_readdir $dir) -+ stat_inode=$(env stat --format=%i $dir) -+ test "$readdir_inode" = "$stat_inode" || fail=1 -+done -+ -+Exit $fail -diff --git a/tests/ls/stat-vs-dirent b/tests/ls/stat-vs-dirent -index c1d7ff5..064ec12 100755 ---- a/tests/ls/stat-vs-dirent -+++ b/tests/ls/stat-vs-dirent -@@ -49,12 +49,7 @@ while :; do - The flaw isn't serious for coreutils, but it might break other tools, - so you should report it to your operating system vendor." 1>&2 - -- # This test fails too often, and we don't want to be distracted -- # with reports, since the code that could be affected by the losing -- # behavior (pwd and getcwd) works around any mismatch. -- # So do continue to issue the warning, but don't count it as a -- # real failure. -- # fail=1 -+ fail=1 - break - fi - fi --- -1.6.4.2.363.g2d6e diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e5174f1..4030eff 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -187,14 +187,6 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "expand" -@@ -183,6 +200,7 @@ - stops = num_start + len - 1; - } - } -+ - else - { - error (0, 0, _("tab size contains invalid character(s): %s"), @@ -365,6 +383,142 @@ } } @@ -414,7 +406,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am 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); + extract_field (line, ptr, sep - ptr); } else @@ -229,6 +248,148 @@ @@ -586,115 +578,100 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am outlist = outlist_head.next; if (outlist) -@@ -397,12 +628,12 @@ - if (o->file == 0) - { - if (line1 == &uni_blank) -- { -+ { - line = line2; - field = join_field_2; - } - else -- { -+ { - line = line1; - field = join_field_1; - } @@ -416,7 +647,7 @@ - o = o->next; - if (o == NULL) - break; -- putchar (output_separator); -+ PUT_TAB_CHAR; - } + o = o->next; + if (o == NULL) + break; +- putchar (output_separator); ++ PUT_TAB_CHAR; + } putchar ('\n'); } @@ -434,23 +665,23 @@ prfield (join_field_1, line1); for (i = 0; i < join_field_1 && i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } for (i = join_field_1 + 1; i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } for (i = 0; i < join_field_2 && i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } for (i = join_field_2 + 1; i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } putchar ('\n'); @@ -859,20 +1090,41 @@ - case 't': - { -- unsigned char newtab = optarg[0]; -- if (! newtab) -+ char *newtab; -+ size_t newtablen; -+ if (! optarg[0]) - error (EXIT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) -+ newtab = xstrdup (optarg); + case 't': + { +- unsigned char newtab = optarg[0]; +- if (! newtab) ++ char *newtab; ++ size_t newtablen; ++ if (! optarg[0]) + error (EXIT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++ newtab = xstrdup (optarg); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ mbstate_t state; ++ 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 ++ 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 +#endif -+ newtablen = 1; -+ -+ if (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ if (tab != NULL && strcmp (tab, newtab)) - { -- if (STREQ (optarg, "\\0")) -- newtab = '\0'; -- else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); - } -- if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; -+ tablen = newtablen; - } - break; - ++ newtablen = 1; ++ ++ if (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\\0")) ++ newtab[0] = '\0'; ++ } ++ if (tab != NULL && strcmp (tab, newtab)) + { +- if (STREQ (optarg, "\\0")) +- newtab = '\0'; +- else +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); ++ free (newtab); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); + } +- if (0 <= tab && tab != newtab) +- error (EXIT_FAILURE, 0, _("incompatible tabs")); + tab = newtab; ++ tablen = newtablen; + } + break; + diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c --- coreutils-6.11-orig/src/join.c 2008-04-21 13:44:32.000000000 +0200 +++ coreutils-6.11/src/join.c 2008-04-21 14:03:22.000000000 +0200 @@ -324,56 +324,115 @@ keycmp (struct line const *line1, struct - size_t jf_1, size_t jf_2) + size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ - char *beg1; @@ -814,7 +791,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c else { - if (hard_LC_COLLATE) -- return xmemcoll (beg1, len1, beg2, len2); +- 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]; @@ -899,26 +876,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#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; \ -+ } \ -+ } \ ++ 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 * @@ -940,26 +917,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + for (count = 0; count < skip_fields && pos < size; count++) + { + while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (convfail || !iswblank (wc)) -+ { -+ pos += mblength; -+ break; -+ } -+ pos += mblength; -+ } ++ if (convfail || !iswblank (wc)) ++ { ++ pos += mblength; ++ break; ++ } ++ pos += mblength; ++ } + + while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (!convfail && iswblank (wc)) -+ break; ++ if (!convfail && iswblank (wc)) ++ break; + -+ pos += mblength; -+ } ++ pos += mblength; ++ } + } + + /* skip fields. */ @@ -997,10 +974,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + copy_new = alloca (oldlen + 1); + + for (i = 0; i < oldlen; i++) -+ { -+ copy_old[i] = toupper (old[i]); -+ copy_new[i] = toupper (new[i]); -+ } ++ { ++ copy_old[i] = toupper (old[i]); ++ copy_new[i] = toupper (new[i]); ++ } } - else if (hard_LC_COLLATE) - return xmemcoll (old, oldlen, new, newlen) != 0; @@ -1039,40 +1016,40 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + copy[i] = alloca (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])); ++ { ++ 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; ++ 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); ++ default: ++ if (ignore_case) ++ { ++ uwc = towupper (wc); + -+ if (uwc != wc) -+ { -+ mbstate_t state_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; -+ } ++ 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; + } @@ -1094,19 +1071,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif while (!feof (stdin)) - { - char *thisfield; - size_t thislen; + { + char *thisfield; + size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate; +#endif + - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - break; - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); + 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) ++ if (MB_CUR_MAX > 1) + { + thisstate = thisline->state; + @@ -1122,11 +1099,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + prevstate = thisstate; + } + } -+ else ++ else +#endif - if (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)) - { + if (prevline->length == 0 + || different (thisfield, prevfield, thislen, prevlen)) + { @@ -322,17 +533,26 @@ size_t prevlen; uintmax_t match_count = 0; @@ -1136,7 +1113,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) - goto closefiles; + goto closefiles; prevfield = find_field (prevline); prevlen = prevline->length - 1 - (prevfield - prevline->buffer); +#if HAVE_MBRTOWC @@ -1144,42 +1121,42 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif while (!feof (stdin)) - { - bool match; - char *thisfield; - size_t thislen; + { + bool match; + char *thisfield; + size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate; +#endif - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - { - if (ferror (stdin)) + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + { + if (ferror (stdin)) @@ -341,6 +561,15 @@ - } - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); + } + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { ++ if (MB_CUR_MAX > 1) ++ { + thisstate = thisline->state; + match = !different_multi (thisfield, prevfield, + thislen, prevlen, thisstate, prevstate); + } -+ else ++ else +#endif - match = !different (thisfield, prevfield, thislen, prevlen); - match_count += match; + match = !different (thisfield, prevfield, thislen, prevlen); + match_count += match; @@ -373,6 +602,9 @@ - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; + SWAP_LINES (prevline, thisline); + prevfield = thisfield; + prevlen = thislen; +#if HAVE_MBRTOWC -+ prevstate = thisstate; ++ prevstate = thisstate; +#endif - if (!match) - match_count = 0; - } + if (!match) + match_count = 0; + } @@ -417,6 +649,19 @@ atexit (close_stdout); @@ -1298,7 +1275,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (operating_mode != byte_mode) { if (c == '\b') - { + { @@ -121,30 +165,14 @@ to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1333,21 +1310,21 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while ((c = getc (istream)) != EOF) { @@ -172,6 +200,15 @@ - bool found_blank = false; - size_t logical_end = offset_out; + 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; -+ } ++ /* 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) - { + /* Look for the last blank. */ + while (logical_end) + { @@ -218,11 +255,222 @@ line_out[offset_out++] = c; } @@ -1365,16 +1342,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +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. */ ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ + char *bufpos = NULL; /* 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; /* 1, when conversion is failed. Otherwise 0. */ ++ 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; /* 1, when conversion is failed. Otherwise 0. */ + + static char *line_out = NULL; -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ + static size_t allocated_out = 0; + + int increment; @@ -1388,26 +1365,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; \ -+ } \ ++#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; \ -+ } \ ++#define START_NEW_LINE \ ++ do \ ++ { \ ++ putchar ('\n'); \ ++ column = 0; \ ++ offset_out = 0; \ ++ CLEAR_FLAGS; \ ++ } \ + while (0) + + CLEAR_FLAGS; @@ -1416,14 +1393,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; -+ } ++ { ++ memmove (buf, bufpos, buflen); ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); ++ bufpos = buf; ++ } + + if (buflen < 1) -+ break; ++ break; + + /* Get a wide character. */ + convfail = 0; @@ -1431,102 +1408,102 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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 (size_t)-1: ++ case (size_t)-2: ++ convfail++; ++ state = state_bak; ++ /* Fall through. */ + -+ case 0: -+ mblength = 1; -+ break; -+ } ++ 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; ++ 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'\r': ++ increment = -1 * column; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } -+ } -+ } ++ 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'); ++ { ++ 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; -+ } ++ 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; -+ } ++ { ++ 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); -+ } ++ { ++ 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; ++ is_cr_after_last_blank = 1; + + if (is_bs_following_last_blank && !convfail && wc == L'\b') -+ ++bs_following_last_blank_num; ++ ++bs_following_last_blank_num; + else -+ is_bs_following_last_blank = 0; ++ 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; -+ } ++ { ++ 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; @@ -1584,21 +1561,21 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { @@ -264,7 +516,15 @@ 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 '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 '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. */ + case 's': /* Break at word boundaries. */ --- coreutils-6.8+/src/sort.c.i18n 2007-02-24 11:23:23.000000000 +0000 +++ coreutils-6.8+/src/sort.c 2007-03-01 15:10:57.000000000 +0000 @@ -23,10 +23,19 @@ @@ -1637,25 +1614,25 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #define NONZERO(x) ((x) != 0) +/* get a multibyte character's byte length. */ -+#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ -+ do \ -+ { \ -+ wchar_t wc; \ -+ mbstate_t state_bak; \ -+ \ -+ state_bak = STATE; \ -+ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ -+ \ -+ switch (MBLENGTH) \ -+ { \ -+ case (size_t)-1: \ -+ case (size_t)-2: \ -+ STATE = state_bak; \ -+ /* Fall through. */ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ } \ -+ } \ ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t wc; \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ STATE = state_bak; \ ++ /* Fall through. */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++ } \ + while (0) + /* The kind of blanks for '-b' to skip in various options. */ @@ -1776,35 +1753,35 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + memset (&state_wc, '\0', sizeof (mbstate_t)); + + for (j = 0; j < s_len;) -+ { -+ if (!ismbblank (s + j, s_len - j, &mblength)) -+ break; -+ j += mblength; -+ } ++ { ++ if (!ismbblank (s + j, s_len - j, &mblength)) ++ break; ++ j += mblength; ++ } + + for (k = 0; j < s_len;) -+ { -+ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); -+ assert (mblength != (size_t)-1 && mblength != (size_t)-2); -+ if (mblength == 0) -+ break; ++ { ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); ++ if (mblength == 0) ++ break; + -+ pwc = towupper (wc); -+ if (pwc == wc) -+ { -+ memcpy (mbc, s + j, mblength); -+ j += mblength; -+ } -+ else -+ { -+ j += mblength; -+ mblength = wcrtomb (mbc, pwc, &state_wc); -+ assert (mblength != (size_t)0 && mblength != (size_t)-1); -+ } ++ pwc = towupper (wc); ++ if (pwc == wc) ++ { ++ memcpy (mbc, s + j, mblength); ++ j += mblength; ++ } ++ else ++ { ++ j += mblength; ++ mblength = wcrtomb (mbc, pwc, &state_wc); ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); ++ } + -+ for (l = 0; l < mblength; l++) -+ name[k++] = mbc[l]; -+ } ++ for (l = 0; l < mblength; l++) ++ name[k++] = mbc[l]; ++ } + name[k] = '\0'; + } + qsort ((void *) monthtab, MONTHS_PER_YEAR, @@ -1832,11 +1809,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (tab_length) while (ptr < lim && sword--) { -- while (ptr < lim && *ptr != tab) -+ while (ptr < lim && *ptr != tab[0]) - ++ptr; - if (ptr < lim) - ++ptr; +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim) + ++ptr; @@ -1282,11 +1409,70 @@ return ptr; } @@ -1857,29 +1834,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (tab_length) + while (ptr < lim && sword--) + { -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } -+ if (ptr < lim) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } + } + else + while (ptr < lim && sword--) + { -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; -+ if (ptr < lim) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; + } + + if (key->skipsblanks) @@ -1891,9 +1868,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); + + if (ptr + mblength > lim) -+ break; ++ break; + else -+ ptr += mblength; ++ ptr += mblength; + } + + return ptr; @@ -1917,11 +1894,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (tab_length) while (ptr < lim && eword--) { -- while (ptr < lim && *ptr != tab) -+ while (ptr < lim && *ptr != tab[0]) - ++ptr; - if (ptr < lim && (eword | echar)) - ++ptr; +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim && (eword | echar)) + ++ptr; @@ -1348,10 +1534,10 @@ */ @@ -1933,7 +1910,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - newlim = memchr (ptr, tab, lim - ptr); + newlim = memchr (ptr, tab[0], lim - ptr); if (newlim) - lim = newlim; + lim = newlim; } @@ -1384,6 +1570,113 @@ return ptr; @@ -1957,29 +1934,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (tab_length) + while (ptr < lim && eword--) + { -+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } -+ if (ptr < lim && (eword | echar)) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim && (eword | echar)) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } + } + else + while (ptr < lim && eword--) + { -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; -+ if (ptr < lim) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } -+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; + } + + @@ -1991,16 +1968,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + + newlim = NULL; + for (p = ptr; p < lim;) -+ { -+ if (memcmp (p, tab, tab_length) == 0) -+ { -+ newlim = p; -+ break; -+ } ++ { ++ if (memcmp (p, tab, tab_length) == 0) ++ { ++ newlim = p; ++ break; ++ } + -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ p += mblength; -+ } ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ p += mblength; ++ } + } + else + { @@ -2008,14 +1985,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + newlim = ptr; + + while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) -+ newlim += mblength; ++ newlim += mblength; + if (ptr < lim) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } + while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) -+ newlim += mblength; ++ newlim += mblength; + lim = newlim; + } +# endif @@ -2036,9 +2013,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); + + if (ptr + mblength > lim) -+ break; ++ break; + else -+ ptr += mblength; ++ ptr += mblength; + } + } + @@ -2050,32 +2027,32 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c 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 @@ -1466,8 +1753,24 @@ - else - { - if (key->skipsblanks) -- while (blanks[to_uchar (*line_start)]) -- line_start++; -+ { + else + { + if (key->skipsblanks) +- while (blanks[to_uchar (*line_start)]) +- line_start++; ++ { +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ size_t mblength; -+ mbstate_t state; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ while (line_start < line->keylim && -+ ismbblank (line_start, -+ line->keylim - line_start, -+ &mblength)) -+ line_start += mblength; -+ } -+ else ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ mbstate_t state; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ while (line_start < line->keylim && ++ ismbblank (line_start, ++ line->keylim - line_start, ++ &mblength)) ++ line_start += mblength; ++ } ++ else +#endif -+ while (blanks[to_uchar (*line_start)]) -+ line_start++; -+ } - line->keybeg = line_start; - } - } ++ while (blanks[to_uchar (*line_start)]) ++ line_start++; ++ } + line->keybeg = line_start; + } + } @@ -1500,7 +1803,7 @@ hideously fast. */ @@ -2086,7 +2063,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while (blanks[to_uchar (*a)]) a++; @@ -1510,6 +1813,25 @@ - : strnumcmp (a, b, decimal_point, thousands_sep)); + : strnumcmp (a, b, decimal_point, thousands_sep)); } +#if HAVE_MBRTOWC @@ -2163,10 +2140,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + { + month_wcs[i] = towupper(month_wcs[i]); + if (iswblank (month_wcs[i])) -+ { -+ month_wcs[i] = L'\0'; -+ break; -+ } ++ { ++ month_wcs[i] = L'\0'; ++ break; ++ } + } + + wpp = (const wchar_t **)&month_wcs; @@ -2179,9 +2156,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + int ix = (lo + hi) / 2; + + if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) -+ hi = ix; ++ hi = ix; + else -+ lo = ix; ++ lo = ix; + } + while (hi - lo > 1); + @@ -2240,133 +2217,133 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; ++ { ++ 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, key)); -+ *lima = savea, *limb = saveb; -+ } ++ *lima = *limb = '\0'; ++ diff = (key->numeric ? numcompare (texta, textb) ++ : key->general_numeric ? general_numcompare (texta, textb) ++ : human_numcompare (texta, textb, key)); ++ *lima = savea, *limb = saveb; ++ } + else if (key->version) -+ diff = compare_version (texta, lena, textb, lenb); ++ diff = compare_version (texta, lena, textb, lenb); + else if (key->month) -+ diff = getmonth (texta, lena) - getmonth (textb, lenb); ++ diff = getmonth (texta, lena) - getmonth (textb, lenb); + else -+ { -+ if (ignore || translate) -+ { -+ char *copy_a = (char *) alloca (lena + 1 + lenb + 1); -+ char *copy_b = copy_a + lena + 1; -+ size_t new_len_a, new_len_b; -+ size_t i, j; ++ { ++ if (ignore || translate) ++ { ++ char *copy_a = (char *) alloca (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) \ -+ do \ -+ { \ -+ wchar_t uwc; \ -+ char mbc[MB_LEN_MAX]; \ -+ mbstate_t state_wc; \ -+ \ -+ for (NEW_LEN = i = 0; i < LEN;) \ -+ { \ -+ mbstate_t state_bak; \ -+ \ -+ state_bak = STATE; \ -+ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ -+ \ -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ -+ || MBLENGTH == 0) \ -+ { \ -+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ -+ STATE = state_bak; \ -+ if (!ignore) \ -+ COPY[NEW_LEN++] = TEXT[i++]; \ -+ continue; \ -+ } \ -+ \ -+ if (ignore) \ -+ { \ -+ if ((ignore == nonprinting && !iswprint (WC)) \ -+ || (ignore == nondictionary \ -+ && !iswalnum (WC) && !iswblank (WC))) \ -+ { \ -+ i += MBLENGTH; \ -+ continue; \ -+ } \ -+ } \ -+ \ -+ if (translate) \ -+ { \ -+ \ -+ uwc = towupper(WC); \ -+ if (WC == uwc) \ -+ { \ -+ memcpy (mbc, TEXT + i, MBLENGTH); \ -+ i += MBLENGTH; \ -+ } \ -+ else \ -+ { \ -+ i += MBLENGTH; \ -+ WC = uwc; \ -+ memset (&state_wc, '\0', sizeof (mbstate_t)); \ -+ \ -+ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ -+ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ -+ } \ -+ \ -+ for (j = 0; j < MBLENGTH; j++) \ -+ COPY[NEW_LEN++] = mbc[j]; \ -+ } \ -+ else \ -+ for (j = 0; j < MBLENGTH; j++) \ -+ COPY[NEW_LEN++] = TEXT[i++]; \ -+ } \ -+ COPY[NEW_LEN] = '\0'; \ -+ } \ ++ /* Ignore and/or translate chars before comparing. */ ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t uwc; \ ++ char mbc[MB_LEN_MAX]; \ ++ mbstate_t state_wc; \ ++ \ ++ for (NEW_LEN = i = 0; i < LEN;) \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ ++ \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ ++ || MBLENGTH == 0) \ ++ { \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ ++ STATE = state_bak; \ ++ if (!ignore) \ ++ COPY[NEW_LEN++] = TEXT[i++]; \ ++ continue; \ ++ } \ ++ \ ++ if (ignore) \ ++ { \ ++ if ((ignore == nonprinting && !iswprint (WC)) \ ++ || (ignore == nondictionary \ ++ && !iswalnum (WC) && !iswblank (WC))) \ ++ { \ ++ i += MBLENGTH; \ ++ continue; \ ++ } \ ++ } \ ++ \ ++ if (translate) \ ++ { \ ++ \ ++ uwc = towupper(WC); \ ++ if (WC == uwc) \ ++ { \ ++ memcpy (mbc, TEXT + i, MBLENGTH); \ ++ i += MBLENGTH; \ ++ } \ ++ else \ ++ { \ ++ i += MBLENGTH; \ ++ WC = uwc; \ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ ++ \ ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ ++ } \ ++ \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = mbc[j]; \ ++ } \ ++ else \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = TEXT[i++]; \ ++ } \ ++ 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); -+ } -+ else if (lena == 0) -+ diff = - NONZERO (lenb); -+ else if (lenb == 0) -+ goto greater; -+ else -+ diff = xmemcoll (texta, lena, textb, lenb); -+ } ++ 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); ++ } ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ goto greater; ++ else ++ diff = xmemcoll (texta, lena, textb, lenb); ++ } + + if (diff) -+ goto not_equal; ++ goto not_equal; + + key = key->next; + if (! key) -+ break; ++ break; + + /* Find the beginning and limit of the next field. */ + if (key->eword != -1) -+ lima = limfield (a, key), limb = limfield (b, key); ++ lima = limfield (a, key), limb = limfield (b, key); + else -+ lima = a->text + a->length - 1, limb = b->text + b->length - 1; ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; + + if (key->sword != -1) -+ texta = begfield (a, key), textb = begfield (b, key); ++ texta = begfield (a, key), textb = begfield (b, key); + else -+ { -+ texta = a->text, textb = b->text; -+ if (key->skipsblanks) -+ { -+ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) -+ texta += mblength_a; -+ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) -+ textb += mblength_b; -+ } -+ } ++ { ++ texta = a->text, textb = b->text; ++ if (key->skipsblanks) ++ { ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) ++ texta += mblength_a; ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) ++ textb += mblength_b; ++ } ++ } + } + + return 0; @@ -2420,58 +2397,58 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -3015,13 +3599,35 @@ - case 't': - { -- char newtab = optarg[0]; -- if (! newtab) -+ char newtab[MB_LEN_MAX + 1]; -+ size_t newtab_length = 1; -+ strncpy (newtab, optarg, MB_LEN_MAX); -+ if (! newtab[0]) - error (SORT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) + case 't': + { +- char newtab = optarg[0]; +- if (! newtab) ++ char newtab[MB_LEN_MAX + 1]; ++ size_t newtab_length = 1; ++ strncpy (newtab, optarg, MB_LEN_MAX); ++ if (! newtab[0]) + error (SORT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ wchar_t wc; -+ mbstate_t state; -+ size_t i; ++ if (MB_CUR_MAX > 1) ++ { ++ wchar_t wc; ++ mbstate_t state; ++ size_t i; + -+ memset (&state, '\0', sizeof (mbstate_t)); -+ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, -+ MB_LEN_MAX), -+ &state); -+ switch (newtab_length) -+ { -+ case (size_t) -1: -+ case (size_t) -2: -+ case 0: -+ newtab_length = 1; -+ } -+ } ++ memset (&state, '\0', sizeof (mbstate_t)); ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, ++ MB_LEN_MAX), ++ &state); ++ switch (newtab_length) ++ { ++ case (size_t) -1: ++ case (size_t) -2: ++ case 0: ++ newtab_length = 1; ++ } ++ } +#endif -+ if (newtab_length == 1 && optarg[1]) - { - if (STREQ (optarg, "\\0")) -- newtab = '\0'; -+ newtab[0] = '\0'; - else - { - /* Provoke with `sort -txx'. Complain about ++ if (newtab_length == 1 && optarg[1]) + { + if (STREQ (optarg, "\\0")) +- newtab = '\0'; ++ newtab[0] = '\0'; + else + { + /* Provoke with `sort -txx'. Complain about @@ -3032,9 +3638,12 @@ - quote (optarg)); - } - } -- if (tab != TAB_DEFAULT && tab != newtab) -+ 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); -+ tab_length = newtab_length; - } - break; + quote (optarg)); + } + } +- if (tab != TAB_DEFAULT && tab != newtab) ++ 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); ++ tab_length = newtab_length; + } + break; --- coreutils-6.8+/src/unexpand.c.i18n 2007-01-14 15:41:28.000000000 +0000 +++ coreutils-6.8+/src/unexpand.c 2007-03-01 15:08:24.000000000 +0000 @@ -2807,8 +2784,8 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c static void pad_across_to (int position); static void add_line_number (COLUMN *p); static void getoptarg (char *arg, char switch_char, char *character, -+ int *character_length, int *character_width, - int *number); ++ int *character_length, int *character_width, + int *number); void usage (int status); static void print_files (int number_of_files, char **av); @@ -440,7 +492,6 @@ @@ -2907,134 +2884,134 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + n_files = 0; file_names = (argc > 1 - ? xmalloc ((argc - 1) * sizeof (char *)) + ? xmalloc ((argc - 1) * sizeof (char *)) @@ -949,8 +1032,12 @@ - break; - case 'e': - if (optarg) -- getoptarg (optarg, 'e', &input_tab_char, -- &chars_per_input_tab); -+ { -+ int dummy_length, dummy_width; + break; + case 'e': + if (optarg) +- getoptarg (optarg, 'e', &input_tab_char, +- &chars_per_input_tab); ++ { ++ int dummy_length, dummy_width; + -+ getoptarg (optarg, 'e', input_tab_char, &dummy_length, -+ &dummy_width, &chars_per_input_tab); -+ } - /* Could check tab width > 0. */ - untabify_input = true; - break; ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, ++ &dummy_width, &chars_per_input_tab); ++ } + /* Could check tab width > 0. */ + untabify_input = true; + break; @@ -963,8 +1050,12 @@ - break; - case 'i': - if (optarg) -- getoptarg (optarg, 'i', &output_tab_char, -- &chars_per_output_tab); -+ { -+ int dummy_width; + break; + case 'i': + if (optarg) +- getoptarg (optarg, 'i', &output_tab_char, +- &chars_per_output_tab); ++ { ++ int dummy_width; + -+ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, -+ &dummy_width, &chars_per_output_tab); -+ } - /* Could check tab width > 0. */ - tabify_output = true; - break; ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, ++ &dummy_width, &chars_per_output_tab); ++ } + /* Could check tab width > 0. */ + tabify_output = true; + break; @@ -991,8 +1082,8 @@ - case 'n': - numbered_lines = true; - if (optarg) -- getoptarg (optarg, 'n', &number_separator, -- &chars_per_number); -+ getoptarg (optarg, 'n', number_separator, &number_separator_length, -+ &number_separator_width, &chars_per_number); - break; - case 'N': - skip_count = false; + case 'n': + numbered_lines = true; + if (optarg) +- getoptarg (optarg, 'n', &number_separator, +- &chars_per_number); ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, ++ &number_separator_width, &chars_per_number); + break; + case 'N': + skip_count = false; @@ -1031,7 +1122,7 @@ - old_s = false; - /* 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; - use_col_separator = true; - if (optarg) - separator_string (optarg); + old_s = false; + /* 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; + use_col_separator = true; + if (optarg) + separator_string (optarg); @@ -1188,10 +1279,45 @@ a number. */ static void -getoptarg (char *arg, char switch_char, char *character, int *number) +getoptarg (char *arg, char switch_char, char *character, int *character_length, -+ int *character_width, int *number) ++ int *character_width, int *number) { if (!ISDIGIT (*arg)) - *character = *arg++; + { +#ifdef HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) /* for multibyte locale. */ -+ { -+ wchar_t wc; -+ size_t mblength; -+ int width; -+ mbstate_t state = {'\0'}; ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ ++ { ++ wchar_t wc; ++ size_t mblength; ++ int width; ++ mbstate_t state = {'\0'}; + -+ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); + -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ *character_length = 1; -+ *character_width = 1; -+ } -+ else -+ { -+ *character_length = (mblength < 1) ? 1 : mblength; -+ width = wcwidth (wc); -+ *character_width = (width < 0) ? 0 : width; -+ } ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ *character_length = 1; ++ *character_width = 1; ++ } ++ else ++ { ++ *character_length = (mblength < 1) ? 1 : mblength; ++ width = wcwidth (wc); ++ *character_width = (width < 0) ? 0 : width; ++ } + -+ strncpy (character, arg, *character_length); -+ arg += *character_length; -+ } -+ else /* for single byte locale. */ ++ strncpy (character, arg, *character_length); ++ arg += *character_length; ++ } ++ else /* for single byte locale. */ +#endif -+ { -+ *character = *arg++; -+ *character_length = 1; -+ *character_width = 1; -+ } ++ { ++ *character = *arg++; ++ *character_length = 1; ++ *character_width = 1; ++ } + } + if (*arg) { long int tmp_long; @@ -1256,7 +1382,7 @@ - else - col_sep_string = column_separator; + else + col_sep_string = column_separator; -- col_sep_length = 1; -+ col_sep_length = col_sep_width = 1; - use_col_separator = true; - } +- col_sep_length = 1; ++ col_sep_length = col_sep_width = 1; + use_col_separator = true; + } /* It's rather pointless to define a TAB separator with column @@ -1288,11 +1414,11 @@ - TAB_WIDTH (chars_per_input_tab, chars_per_number); */ + 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; +- 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. */ + printing files in parallel. */ @@ -1307,7 +1433,7 @@ } chars_per_column = (chars_per_line - chars_used_by_number - -- (columns - 1) * col_sep_length) / columns; -+ (columns - 1) * col_sep_width) / columns; +- (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")); @@ -3048,13 +3025,13 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* This loop takes care of all but the rightmost column. */ @@ -1466,7 +1592,7 @@ - } + } else - { -- h = h_next + col_sep_length; -+ h = h_next + col_sep_width; - h_next = h + chars_per_column; - } + { +- h = h_next + col_sep_length; ++ h = h_next + col_sep_width; + h_next = h + chars_per_column; + } } @@ -1756,9 +1882,9 @@ align_column (COLUMN *p) @@ -3086,19 +3063,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -2058,22 +2184,24 @@ /* Tabification is assumed for multiple columns, also for n-separators, - but `default n-separator = TAB' hasn't been given priority over - equal column_width also specified by POSIX. */ + 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') { i = number_width - chars_per_number; while (i-- > 0) - (p->char_func) (' '); + (p->char_func) (' '); } else - (p->char_func) (number_separator); -+ for (j = 0; j < number_separator_length; j++) -+ (p->char_func) (number_separator[j]); ++ for (j = 0; j < number_separator_length; j++) ++ (p->char_func) (number_separator[j]); } else /* To comply with POSIX, we avoid any expansion of default TAB @@ -3108,14 +3085,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - (p->char_func) (number_separator); - if (number_separator == '\t') + for (j = 0; j < number_separator_length; j++) -+ (p->char_func) (number_separator[j]); ++ (p->char_func) (number_separator[j]); + if (number_separator[0] == '\t') output_position = POS_AFTER_TAB (chars_per_output_tab, - output_position); + output_position); } @@ -2234,7 +2362,7 @@ while (goal - h_old > 1 - && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { - putchar (output_tab_char); + fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); @@ -3133,28 +3110,28 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -2267,6 +2396,7 @@ { for (; separators_not_printed > 0; --separators_not_printed) - { -+ not_space_flag = 0; - while (l-- > 0) - { - /* 3 types of sep_strings: spaces only, spaces and chars, + { ++ not_space_flag = 0; + while (l-- > 0) + { + /* 3 types of sep_strings: spaces only, spaces and chars, @@ -2280,12 +2410,15 @@ - } - else - { -+ not_space_flag = 1; - if (spaces_not_printed > 0) - print_white_space (); - putchar (*s++); -- ++output_position; - } - } -+ if (not_space_flag) -+ output_position += col_sep_width; + } + else + { ++ not_space_flag = 1; + if (spaces_not_printed > 0) + print_white_space (); + putchar (*s++); +- ++output_position; + } + } ++ if (not_space_flag) ++ output_position += col_sep_width; + /* sep_string ends with some spaces */ - if (spaces_not_printed > 0) - print_white_space (); + if (spaces_not_printed > 0) + print_white_space (); @@ -2313,7 +2446,7 @@ required number of tabs and spaces. */ @@ -3187,49 +3164,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + mblength = mbrtowc (&wc, mbc, mbc_pos, &state); + + while (mbc_pos > 0) -+ { -+ switch (mblength) -+ { -+ case (size_t)-2: -+ state = state_bak; -+ return; ++ { ++ switch (mblength) ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return; + -+ case (size_t)-1: -+ state = state_bak; -+ ++output_position; -+ putchar (mbc[0]); -+ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); -+ --mbc_pos; -+ break; ++ case (size_t)-1: ++ state = state_bak; ++ ++output_position; ++ putchar (mbc[0]); ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); ++ --mbc_pos; ++ break; + -+ case 0: -+ mblength = 1; ++ case 0: ++ mblength = 1; + -+ default: -+ if (wc == L' ') -+ { -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); -+ --mbc_pos; -+ ++spaces_not_printed; -+ return; -+ } -+ else if (spaces_not_printed > 0) -+ print_white_space (); ++ default: ++ if (wc == L' ') ++ { ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ --mbc_pos; ++ ++spaces_not_printed; ++ return; ++ } ++ else if (spaces_not_printed > 0) ++ print_white_space (); + -+ /* Nonprintables are assumed to have width 0, except L'\b'. */ -+ if ((width = wcwidth (wc)) < 1) -+ { -+ if (wc == L'\b') -+ --output_position; -+ } -+ else -+ output_position += width; ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ ++ if ((width = wcwidth (wc)) < 1) ++ { ++ if (wc == L'\b') ++ --output_position; ++ } ++ else ++ output_position += width; + -+ fwrite (mbc, sizeof(char), mblength, stdout); -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); -+ mbc_pos -= mblength; -+ } -+ } ++ fwrite (mbc, sizeof(char), mblength, stdout); ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ } + return; + } + putchar (c); @@ -3240,19 +3217,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c PAGE may be larger than total number of pages. */ @@ -2517,9 +2718,9 @@ - align_empty_cols = false; - } + align_empty_cols = false; + } - if (padding_not_printed - col_sep_length > 0) + if (padding_not_printed - col_sep_width > 0) - { -- pad_across_to (padding_not_printed - col_sep_length); -+ pad_across_to (padding_not_printed - col_sep_width); - padding_not_printed = ANYWHERE; - } + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } @@ -2620,9 +2821,9 @@ - } + } } - if (padding_not_printed - col_sep_length > 0) @@ -3268,9 +3245,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { output_position = p->start_position + end_vector[line]; - if (p->start_position - col_sep_length == chars_per_margin) -- output_position -= col_sep_length; +- output_position -= col_sep_length; + if (p->start_position - col_sep_width == chars_per_margin) -+ output_position -= col_sep_width; ++ output_position -= col_sep_width; } return true; @@ -3327,118 +3304,118 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + while (mbc_pos > 0) + { + switch (mblength) -+ { -+ case (size_t)-2: -+ state = state_bak; -+ return 0; ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return 0; + -+ case (size_t)-1: -+ state = state_bak; -+ mblength = 1; ++ case (size_t)-1: ++ state = state_bak; ++ mblength = 1; + -+ if (use_esc_sequence || use_cntrl_prefix) -+ { -+ width = +4; -+ chars = +4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", mbc[0]); -+ for (i = 0; i <= 2; ++i) -+ *s++ = (int) esc_buff[i]; -+ } -+ else -+ { -+ width += 1; -+ chars += 1; -+ *s++ = mbc[0]; -+ } -+ break; ++ if (use_esc_sequence || use_cntrl_prefix) ++ { ++ width = +4; ++ chars = +4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", mbc[0]); ++ for (i = 0; i <= 2; ++i) ++ *s++ = (int) esc_buff[i]; ++ } ++ else ++ { ++ width += 1; ++ chars += 1; ++ *s++ = mbc[0]; ++ } ++ break; + -+ case 0: -+ mblength = 1; -+ /* Fall through */ ++ case 0: ++ mblength = 1; ++ /* Fall through */ + -+ default: -+ if (memcmp (mbc, input_tab_char, mblength) == 0) -+ chars_per_c = chars_per_input_tab; ++ default: ++ if (memcmp (mbc, input_tab_char, mblength) == 0) ++ chars_per_c = chars_per_input_tab; + -+ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') -+ { -+ int width_inc; ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') ++ { ++ int width_inc; + -+ width_inc = TAB_WIDTH (chars_per_c, input_position); -+ width += width_inc; ++ width_inc = TAB_WIDTH (chars_per_c, input_position); ++ width += width_inc; + -+ if (untabify_input) -+ { -+ for (i = width_inc; i; --i) -+ *s++ = ' '; -+ chars += width_inc; -+ } -+ else -+ { -+ for (i = 0; i < mblength; i++) -+ *s++ = mbc[i]; -+ chars += mblength; -+ } -+ } -+ else if ((wc_width = wcwidth (wc)) < 1) -+ { -+ if (use_esc_sequence) -+ { -+ for (i = 0; i < mblength; i++) -+ { -+ width += 4; -+ chars += 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); -+ for (j = 0; j <= 2; ++j) -+ *s++ = (int) esc_buff[j]; -+ } -+ } -+ else if (use_cntrl_prefix) -+ { -+ if (wc < 0200) -+ { -+ width += 2; -+ chars += 2; -+ *s++ = '^'; -+ *s++ = wc ^ 0100; -+ } -+ else -+ { -+ for (i = 0; i < mblength; i++) -+ { -+ width += 4; -+ chars += 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); -+ for (j = 0; j <= 2; ++j) -+ *s++ = (int) esc_buff[j]; -+ } -+ } -+ } -+ else if (wc == L'\b') -+ { -+ width += -1; -+ chars += 1; -+ *s++ = c; -+ } -+ else -+ { -+ width += 0; -+ chars += mblength; -+ for (i = 0; i < mblength; i++) -+ *s++ = mbc[i]; -+ } -+ } -+ else -+ { -+ width += wc_width; -+ chars += mblength; -+ for (i = 0; i < mblength; i++) -+ *s++ = mbc[i]; -+ } -+ } ++ if (untabify_input) ++ { ++ for (i = width_inc; i; --i) ++ *s++ = ' '; ++ chars += width_inc; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ chars += mblength; ++ } ++ } ++ else if ((wc_width = wcwidth (wc)) < 1) ++ { ++ if (use_esc_sequence) ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", c); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ else if (use_cntrl_prefix) ++ { ++ if (wc < 0200) ++ { ++ width += 2; ++ chars += 2; ++ *s++ = '^'; ++ *s++ = wc ^ 0100; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", c); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ } ++ else if (wc == L'\b') ++ { ++ width += -1; ++ chars += 1; ++ *s++ = c; ++ } ++ else ++ { ++ width += 0; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } ++ else ++ { ++ width += wc_width; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } + memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); + mbc_pos -= mblength; + } @@ -3470,7 +3447,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #include "xstrndup.h" +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ ++ installation; work around this configuration error. */ +#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 +# undef MB_LEN_MAX +# define MB_LEN_MAX 16 @@ -3489,49 +3466,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while (0) +/* Refill the buffer BUF to get a multibyte character. */ -+#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ -+ do \ -+ { \ -+ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ -+ { \ -+ memmove (BUF, BUFPOS, BUFLEN); \ -+ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ -+ BUFPOS = BUF; \ -+ } \ -+ } \ ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ ++ do \ ++ { \ ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ ++ { \ ++ memmove (BUF, BUFPOS, BUFLEN); \ ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ ++ BUFPOS = BUF; \ ++ } \ ++ } \ + 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. */ +#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ -+ do \ -+ { \ -+ mbstate_t state_bak; \ -+ \ -+ if (BUFLEN < 1) \ -+ { \ -+ WC = WEOF; \ -+ break; \ -+ } \ -+ \ -+ /* Get a wide character. */ \ -+ CONVFAIL = 0; \ -+ 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 througn. */ \ -+ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ break; \ -+ } \ -+ } \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ if (BUFLEN < 1) \ ++ { \ ++ WC = WEOF; \ ++ break; \ ++ } \ ++ \ ++ /* Get a wide character. */ \ ++ CONVFAIL = 0; \ ++ 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 througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ + while (0) + struct range_pair @@ -3608,49 +3585,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c fputs (_("\ --complement complement the set of selected bytes, characters\n\ @@ -362,7 +439,7 @@ - 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++; + 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++; @@ -387,14 +464,16 @@ - if (!rhs_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")); + if (!rhs_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) + /* Is there already a range going to end of line? */ + if (eol_range_start != 0) @@ -467,6 +546,9 @@ - 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)); + 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)); @@ -477,7 +559,7 @@ - fieldstr++; - } + fieldstr++; + } else -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); } max_range_endpoint = 0; @@ -3670,15 +3647,15 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +static void +cut_characters_or_cut_bytes_no_split (FILE *stream) +{ -+ int idx; /* number of bytes or characters in the line so far. */ ++ int 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. */ -+ 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 of the stream. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* 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. */ ++ mbstate_t state; /* State of the stream. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ + + idx = 0; + buflen = 0; @@ -3692,29 +3669,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); + + if (wc == WEOF) -+ { -+ if (idx > 0) -+ putchar ('\n'); -+ break; -+ } ++ { ++ if (idx > 0) ++ putchar ('\n'); ++ break; ++ } + else if (wc == L'\n') -+ { -+ putchar ('\n'); -+ idx = 0; -+ } ++ { ++ putchar ('\n'); ++ idx = 0; ++ } + else -+ { -+ idx += (operating_mode == byte_mode) ? mblength : 1; -+ if (print_kth (idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ } ++ { ++ idx += (operating_mode == byte_mode) ? mblength : 1; ++ if (print_kth (idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } + + buflen -= mblength; + bufpos += mblength; + } +} +#endif -+ ++ /* Read from stream STREAM, printing to standard output any selected fields. */ static void @@ -3732,13 +3709,13 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + int buffer_first_field; + int empty_input; + 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. */ -+ wint_t wc = 0; /* 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 of the stream. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc = 0; /* 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 of the stream. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ + + found_any_selected_field = 0; + field_idx = 1; @@ -3764,111 +3741,111 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + while (1) + { + if (field_idx == 1 && buffer_first_field) -+ { -+ int len = 0; ++ { ++ int len = 0; + -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); + -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); + -+ if (wc == WEOF) -+ break; ++ if (wc == WEOF) ++ break; + -+ field_1_buffer = xrealloc (field_1_buffer, len + mblength); -+ memcpy (field_1_buffer + len, bufpos, mblength); -+ len += mblength; -+ buflen -= mblength; -+ bufpos += mblength; ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); ++ memcpy (field_1_buffer + len, bufpos, mblength); ++ len += mblength; ++ buflen -= mblength; ++ bufpos += mblength; + -+ if (!convfail && (wc == L'\n' || wc == wcdelim)) -+ break; -+ } ++ if (!convfail && (wc == L'\n' || wc == wcdelim)) ++ break; ++ } + -+ if (wc == WEOF) -+ break; ++ if (wc == WEOF) ++ break; + -+ /* If the first field extends to the end of line (it is not -+ delimited) and we are printing all non-delimited lines, -+ print this one. */ -+ if (convfail || (!convfail && wc != wcdelim)) -+ { -+ if (suppress_non_delimited) -+ { -+ /* Empty. */ -+ } -+ else -+ { -+ fwrite (field_1_buffer, sizeof (char), len, stdout); -+ /* Make sure the output line is newline terminated. */ -+ if (convfail || (!convfail && wc != L'\n')) -+ putchar ('\n'); -+ } -+ continue; -+ } ++ /* If the first field extends to the end of line (it is not ++ delimited) and we are printing all non-delimited lines, ++ print this one. */ ++ if (convfail || (!convfail && wc != wcdelim)) ++ { ++ if (suppress_non_delimited) ++ { ++ /* Empty. */ ++ } ++ else ++ { ++ fwrite (field_1_buffer, sizeof (char), len, stdout); ++ /* Make sure the output line is newline terminated. */ ++ if (convfail || (!convfail && wc != L'\n')) ++ putchar ('\n'); ++ } ++ continue; ++ } + -+ if (print_kth (1, NULL)) -+ { -+ /* Print the field, but not the trailing delimiter. */ -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); -+ found_any_selected_field = 1; -+ } -+ ++field_idx; -+ } ++ if (print_kth (1, NULL)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ ++field_idx; ++ } + + if (wc != WEOF) -+ { -+ if (print_kth (field_idx, NULL)) -+ { -+ if (found_any_selected_field) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ found_any_selected_field = 1; -+ } ++ { ++ if (print_kth (field_idx, NULL)) ++ { ++ if (found_any_selected_field) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ found_any_selected_field = 1; ++ } + -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); + -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); + -+ if (wc == WEOF) -+ break; -+ else if (!convfail && (wc == wcdelim || wc == L'\n')) -+ { -+ buflen -= mblength; -+ bufpos += mblength; -+ break; -+ } ++ if (wc == WEOF) ++ break; ++ else if (!convfail && (wc == wcdelim || wc == L'\n')) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } + -+ if (print_kth (field_idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); ++ if (print_kth (field_idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); + -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+ } ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } + + if ((!convfail || wc == L'\n') && buflen < 1) -+ wc = WEOF; ++ wc = WEOF; + + if (!convfail && wc == wcdelim) -+ ++field_idx; ++ ++field_idx; + else if (wc == WEOF || (!convfail && wc == L'\n')) -+ { -+ if (found_any_selected_field -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) -+ putchar ('\n'); -+ if (wc == WEOF) -+ break; -+ field_idx = 1; -+ found_any_selected_field = 0; -+ } ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar ('\n'); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ found_any_selected_field = 0; ++ } + } +} +#endif @@ -3882,34 +3859,34 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (MB_CUR_MAX > 1 && !force_singlebyte_mode) + { + switch (operating_mode) -+ { -+ case byte_mode: -+ if (byte_mode_character_aware) -+ cut_characters_or_cut_bytes_no_split (stream); -+ else -+ cut_bytes (stream); -+ break; ++ { ++ case byte_mode: ++ if (byte_mode_character_aware) ++ cut_characters_or_cut_bytes_no_split (stream); ++ else ++ cut_bytes (stream); ++ break; + -+ case character_mode: -+ cut_characters_or_cut_bytes_no_split (stream); -+ break; ++ case character_mode: ++ cut_characters_or_cut_bytes_no_split (stream); ++ break; + -+ case field_mode: -+ cut_fields_mb (stream); -+ break; ++ case field_mode: ++ cut_fields_mb (stream); ++ break; + -+ default: -+ abort (); -+ } ++ default: ++ abort (); ++ } + } else - cut_fields (stream); +#endif + { + if (operating_mode == field_mode) -+ cut_fields (stream); ++ cut_fields (stream); + else -+ cut_bytes (stream); ++ cut_bytes (stream); + } } @@ -3925,75 +3902,75 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c set_program_name (argv[0]); @@ -770,7 +1090,6 @@ 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")); + { + case 'b': +- case 'c': + /* Build the byte list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); @@ -778,6 +1097,14 @@ - spec_list_string = optarg; - break; + spec_list_string = optarg; + break; -+ case 'c': -+ /* Build the character list. */ -+ if (operating_mode != undefined_mode) -+ FATAL_ERROR (_("only one type of list may be specified")); -+ operating_mode = character_mode; -+ spec_list_string = optarg; -+ break; ++ case 'c': ++ /* Build the character list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = character_mode; ++ spec_list_string = optarg; ++ break; + - case 'f': - /* Build the field list. */ - if (operating_mode != undefined_mode) + case 'f': + /* Build the field list. */ + if (operating_mode != undefined_mode) @@ -789,10 +1116,35 @@ - case 'd': - /* 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]; -- delim_specified = true; -+ { + case 'd': + /* 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]; +- delim_specified = true; ++ { +#if HAVE_MBRTOWC -+ if(MB_CUR_MAX > 1) -+ { -+ mbstate_t state; ++ if(MB_CUR_MAX > 1) ++ { ++ mbstate_t state; + -+ memset (&state, '\0', sizeof(mbstate_t)); -+ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); ++ memset (&state, '\0', sizeof(mbstate_t)); ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); + -+ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) -+ ++force_singlebyte_mode; -+ else -+ { -+ delimlen = (delimlen < 1) ? 1 : delimlen; -+ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') -+ FATAL_ERROR (_("the delimiter must be a single character")); -+ memcpy (mbdelim, optarg, delimlen); -+ } -+ } ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) ++ ++force_singlebyte_mode; ++ else ++ { ++ delimlen = (delimlen < 1) ? 1 : delimlen; ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ memcpy (mbdelim, optarg, delimlen); ++ } ++ } + -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) +#endif -+ { -+ if (optarg[0] != '\0' && optarg[1] != '\0') -+ FATAL_ERROR (_("the delimiter must be a single character")); -+ delim = (unsigned char) optarg[0]; -+ } -+ delim_specified = true; -+ } - break; ++ { ++ if (optarg[0] != '\0' && optarg[1] != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ delim = (unsigned char) optarg[0]; ++ } ++ delim_specified = true; ++ } + break; - case OUTPUT_DELIMITER_OPTION: + case OUTPUT_DELIMITER_OPTION: @@ -805,6 +1157,7 @@ - break; + break; - case 'n': -+ byte_mode_character_aware = 1; - break; + case 'n': ++ byte_mode_character_aware = 1; + break; - case 's': + case 's': @@ -827,7 +1180,7 @@ if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -4027,20 +4004,20 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - output_delimiter_length = 1; +#ifdef HAVE_MBRTOWC + if (MB_CUR_MAX > 1 && !force_singlebyte_mode) -+ { -+ output_delimiter_string = xstrdup(mbdelim); -+ output_delimiter_length = delimlen; -+ } ++ { ++ output_delimiter_string = xstrdup(mbdelim); ++ output_delimiter_length = delimlen; ++ } + + if (MB_CUR_MAX <= 1 || force_singlebyte_mode) +#endif -+ { -+ static char dummy[2]; -+ dummy[0] = delim; -+ dummy[1] = '\0'; -+ output_delimiter_string = dummy; -+ output_delimiter_length = 1; -+ } ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } } if (optind == argc) diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 6e9a0f2..4881c7c 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -155,15 +155,15 @@ + char const *display = getenv ("DISPLAY"); + char const *xauthority = getenv ("XAUTHORITY"); if (term) - term = xstrdup (term); + term = xstrdup (term); environ = xmalloc ((6 + !!term) * sizeof (char *)); environ[0] = NULL; if (term) - xsetenv ("TERM", term); + xsetenv ("TERM", term); + if (display) -+ xsetenv ("DISPLAY", display); ++ xsetenv ("DISPLAY", display); + if (xauthority) -+ xsetenv ("XAUTHORITY", xauthority); ++ xsetenv ("XAUTHORITY", xauthority); xsetenv ("HOME", pw->pw_dir); xsetenv ("SHELL", shell); xsetenv ("USER", pw->pw_name); @@ -218,8 +218,8 @@ static void run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args) -+ size_t n_additional_args, const struct passwd *pw) +- size_t n_additional_args) ++ size_t n_additional_args, const struct passwd *pw) { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 21bd492..233af56 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -38,14 +38,14 @@ diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c --- coreutils-7.1-orig/src/copy.c 2009-02-18 15:32:52.000000000 +0100 +++ coreutils-7.1/src/copy.c 2009-02-24 13:47:15.000000000 +0100 @@ -1830,6 +1830,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. */ + { + /* 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 (); - } ++ restore_default_fscreatecon_or_die (); + } else - { + { diff -urNp coreutils-7.1-orig/src/copy.h coreutils-7.1/src/copy.h --- coreutils-7.1-orig/src/copy.h 2009-02-18 15:32:52.000000000 +0100 +++ coreutils-7.1/src/copy.h 2009-02-24 13:47:15.000000000 +0100 @@ -102,60 +102,60 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c - while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", + while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:", - long_opts, NULL)) - != -1) + long_opts, NULL)) + != -1) { @@ -945,6 +951,16 @@ main (int argc, char **argv) - copy_contents = true; - break; + 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; ++ 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; @@ -1054,6 +1070,27 @@ main (int argc, char **argv) - x.one_file_system = true; - break; + 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 '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; + case 'S': + make_backups = true; + backup_suffix_string = optarg; diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c --- coreutils-7.1-orig/src/chcon.c 2008-10-12 16:12:56.000000000 +0200 +++ coreutils-7.1/src/chcon.c 2009-02-24 13:47:15.000000000 +0100 @@ -346,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), - program_name, program_name, program_name); + 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\ @@ -191,36 +191,36 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c - 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) + NULL)) != -1) { switch (optc) @@ -539,6 +540,7 @@ main (int argc, char **argv) - error (0, 0, _("WARNING: --preserve_context is deprecated; " - "use --preserve-context instead")); - /* fall through */ -+ case 'P': - case PRESERVE_CONTEXT_OPTION: - if ( ! selinux_enabled) - { + error (0, 0, _("WARNING: --preserve_context is deprecated; " + "use --preserve-context instead")); + /* fall through */ ++ case 'P': + case PRESERVE_CONTEXT_OPTION: + if ( ! selinux_enabled) + { @@ -546,6 +548,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; + "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; @@ -557,6 +563,7 @@ main (int argc, char **argv) - break; - } - scontext = optarg; -+ x.set_security_context = true; - use_default_selinux_context = false; - break; - case_GETOPT_HELP_CHAR; + break; + } + scontext = optarg; ++ x.set_security_context = true; + use_default_selinux_context = false; + break; + case_GETOPT_HELP_CHAR; @@ -990,8 +997,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); @@ -312,21 +312,21 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c @@ -1194,7 +1203,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; + || (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 @@ -1241,7 +1251,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); + || indicator_style == classify +- || format == long_format) ++ || format == long_format || format == security_format) + ? DEREF_NEVER + : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); @@ -1261,7 +1271,7 @@ main (int argc, char **argv) @@ -336,7 +336,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c + || format == security_format || print_scontext || print_block_size; format_needs_type = (! format_needs_stat - && (recursive + && (recursive @@ -1292,7 +1302,7 @@ main (int argc, char **argv) } else @@ -356,42 +356,42 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* FIXME: put this in a function. */ { @@ -1837,13 +1847,27 @@ decode_switches (int argc, char **argv) - break; + break; - case 'Z': -- print_scontext = true; -+ print_scontext = 1; + case 'Z': +- print_scontext = true; ++ print_scontext = 1; + format = security_format; - break; + break; - case_GETOPT_HELP_CHAR; + case_GETOPT_HELP_CHAR; - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + 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; ++ 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); - } + default: + usage (LS_FAILURE); + } @@ -2557,8 +2581,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); - if (f->scontext != UNKNOWN_SECURITY_CONTEXT) -- freecon (f->scontext); +- freecon (f->scontext); + if (f->scontext != UNKNOWN_SECURITY_CONTEXT) { -+ freecon (f->scontext); ++ freecon (f->scontext); + f->scontext = NULL; + } } @@ -411,49 +411,49 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) - { - bool have_selinux = false; - bool have_acl = false; + { + bool have_selinux = false; + bool have_acl = false; @@ -2732,7 +2760,7 @@ gobble_file (char const *name, enum file - err = 0; - } + 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); +- 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); @@ -2751,7 +2779,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; +- && (format == long_format || check_symlink_color)) ++ && (format == long_format || format == security_format ++ || check_symlink_color)) + { + char *linkname; + struct stat linkstats; @@ -2771,6 +2800,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 + 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 @@ -2810,7 +2840,7 @@ gobble_file (char const *name, enum file - block_size_width = len; - } + block_size_width = len; + } - if (format == long_format) + if (format == long_format || format == security_format) - { - if (print_owner) - { + { + if (print_owner) + { @@ -3312,6 +3341,13 @@ print_current_files (void) - print_long_format (sorted_file[i]); - DIRED_PUTCHAR ('\n'); - } + print_long_format (sorted_file[i]); + DIRED_PUTCHAR ('\n'); + } + break; + case security_format: + for (i = 0; i < cwd_n_used; i++) @@ -514,15 +514,15 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c + DIRED_INDENT (); + DIRED_FPUTS (buf, stdout, p - buf); + size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE(f), f->linkok, -+ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); ++ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); + + if (f->filetype == symbolic_link) { + if (f->linkname) { -+ DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, -+ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); ++ DIRED_FPUTS_LITERAL (" -> ", stdout); ++ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, ++ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); ++ if (indicator_style != none) ++ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); + } + } + else { @@ -553,27 +553,27 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c @@ -3543,9 +3648,6 @@ print_long_format (const struct fileinfo if (print_author) - format_user (f->stat.st_author, author_width, f->stat_ok); + format_user (f->stat.st_author, author_width, f->stat_ok); - if (print_scontext) -- format_user_or_group (f->scontext, 0, scontext_width); +- format_user_or_group (f->scontext, 0, scontext_width); - p = buf; } @@ -3888,9 +3990,6 @@ print_file_name_and_frills (const struct - human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, - ST_NBLOCKSIZE, output_block_size)); + 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->name, FILE_OR_LINK_MODE (f), - f->linkok, f->stat_ok, f->filetype, - NULL, f->stat.st_nlink, start_col); + f->linkok, f->stat_ok, f->filetype, + NULL, f->stat.st_nlink, start_col); @@ -4105,9 +4204,6 @@ length_of_file_name_and_frills (const st - output_block_size)) - : block_size_width); + output_block_size)) + : block_size_width); - if (print_scontext) - len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); @@ -598,7 +598,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +"), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\n\ + emit_size_note (); diff -urNp coreutils-7.1-orig/src/mkdir.c coreutils-7.1/src/mkdir.c --- coreutils-7.1-orig/src/mkdir.c 2008-10-19 21:47:57.000000000 +0200 +++ coreutils-7.1/src/mkdir.c 2009-02-24 13:47:15.000000000 +0100 @@ -665,32 +665,32 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c + if (terse) { - format = (terse -- ? "%n %i %l %t %s %S %b %f %a %c %d\n" -- : " File: \"%n\"\n" -- " ID: %-8i Namelen: %-7l Type: %T\n" -- "Block size: %-10s Fundamental block size: %S\n" -- "Blocks: Total: %-10b Free: %-10f Available: %a\n" -- "Inodes: Total: %-10c Free: %d\n"); +- ? "%n %i %l %t %s %S %b %f %a %c %d\n" +- : " File: \"%n\"\n" +- " ID: %-8i Namelen: %-7l Type: %T\n" +- "Block size: %-10s Fundamental block size: %S\n" +- "Blocks: Total: %-10b Free: %-10f Available: %a\n" +- "Inodes: Total: %-10c Free: %d\n"); + if (secure) + format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; -+ else -+ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; ++ else ++ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; } + else -+ { -+ if (secure) -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n" -+ " S_Context: %C\n"; -+ else -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n"; ++ { ++ if (secure) ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n" ++ " S_Context: %C\n"; ++ else ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n"; + } + } @@ -709,46 +709,46 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c if (format == NULL) { if (terse) -- { -- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -- } +- { +- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; +- } + { + if (secure) -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; -+ else -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; ++ else ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; + } else - { - /* Temporary hack to match original output until conditional + { + /* Temporary hack to match original output until conditional @@ -885,12 +904,22 @@ do_stat (char const *filename, bool ters - } - else - { -- format = -- " File: %N\n" -- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + } + else + { +- format = +- " File: %N\n" +- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" +- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" +- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" +- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + if (secure) + format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" -+ " Device type: %t,%T\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ " S_Context: %C\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" ++ " Device type: %t,%T\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ " S_Context: %C\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + else -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; - } - } ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + } + } } @@ -911,6 +940,7 @@ usage (int status) Display file or file system status.\n\ @@ -767,34 +767,34 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c bool ok = true; @@ -1034,13 +1065,13 @@ main (int argc, char *argv[]) - terse = true; - break; + terse = true; + break; -- case 'Z': /* FIXME: remove in 2010 */ -- /* Ignore, for compatibility with distributions -- that implemented this before upstream. -- But warn of impending removal. */ -- error (0, 0, -- _("the --context (-Z) option is obsolete and will be removed\n" -- "in a future release")); -+ case 'Z': +- case 'Z': /* FIXME: remove in 2010 */ +- /* Ignore, for compatibility with distributions +- that implemented this before upstream. +- But warn of impending removal. */ +- error (0, 0, +- _("the --context (-Z) option is obsolete and will be removed\n" +- "in a future release")); ++ case 'Z': + if((is_selinux_enabled()>0)) -+ secure = 1; -+ else { -+ error (0, 0, _("Kernel is not SELinux enabled")); -+ usage (EXIT_FAILURE); -+ } - break; ++ secure = 1; ++ else { ++ error (0, 0, _("Kernel is not SELinux enabled")); ++ usage (EXIT_FAILURE); ++ } + break; - case_GETOPT_HELP_CHAR; + case_GETOPT_HELP_CHAR; @@ -1060,8 +1091,8 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs -- ? do_statfs (argv[i], terse, format) -- : do_stat (argv[i], terse, format)); -+ ? do_statfs (argv[i], terse, secure, format) -+ : do_stat (argv[i], terse, secure, format)); +- ? do_statfs (argv[i], terse, format) +- : do_stat (argv[i], terse, format)); ++ ? do_statfs (argv[i], terse, secure, format) ++ : do_stat (argv[i], terse, secure, format)); exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/coreutils-setsid.patch b/coreutils-setsid.patch index e54535f..78ab64d 100644 --- a/coreutils-setsid.patch +++ b/coreutils-setsid.patch @@ -33,24 +33,24 @@ - || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { + if (!same_session) + { -+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -+ { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; -+ } ++ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) ++ { ++ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); ++ caught = 1; ++ } + } + if (!caught && (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { ++ || sigaddset(&ourset, SIGALRM) ++ || sigaction(SIGTERM, &action, NULL) ++ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); caught = 1; } + if (!caught && !same_session && (sigaction(SIGINT, &action, NULL) -+ || sigaction(SIGQUIT, &action, NULL))) ++ || sigaction(SIGQUIT, &action, NULL))) + { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; ++ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); ++ caught = 1; + } } if (!caught) { @@ -73,17 +73,17 @@ struct passwd *pw; struct passwd pw_copy; @@ -656,6 +679,11 @@ - command = optarg; - break; + command = optarg; + break; -+ case 'C': -+ command = optarg; -+ request_same_session = 1; -+ break; ++ case 'C': ++ command = optarg; ++ request_same_session = 1; ++ break; + - case 'f': - fast_startup = true; - break; + case 'f': + fast_startup = true; + break; @@ -725,6 +753,9 @@ } #endif diff --git a/coreutils.spec b/coreutils.spec index 2126148..2141d49 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.5 -Release: 6%{?dist} +Version: 7.6 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,14 +18,11 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-7.5-kojiutimensatskip.patch -Patch2: coreutils-7.5-ls-inode.patch # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch -Patch103: coreutils-7.5-df-localdevice.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -110,14 +107,11 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .kojiutimensat -%patch2 -p1 -b .inode # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain -%patch103 -p1 -b .localdevice # sh-utils %patch703 -p1 -b .dateman @@ -333,6 +327,10 @@ fi %{_libdir}/coreutils %changelog +* Sat Sep 12 2009 Ondrej Vasik - 7.6-1 +- new upstream bugfix release 7.6, removed applied patches, + defuzzed the rest + * Thu Sep 10 2009 Ondrej Vasik - 7.5-6 - fix double free error in fold for singlebyte locales (caused by multibyte patch) diff --git a/sources b/sources index 577a3ac..2cffc5b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ca9219c5b7efa533d552f61a3880f458 coreutils-7.5.tar.xz +a9fb9368e40205d70fc37b9fe441e8ec coreutils-7.6.tar.xz