diff --git a/coreutils-8.17.de.po.xz b/coreutils-8.17.de.po.xz deleted file mode 100644 index ba527eb..0000000 --- a/coreutils-8.17.de.po.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d62887c50239bfa3c743df063fb20b319c1b70ec019a017da1c8b50a11b87ef -size 98604 diff --git a/coreutils-8.17.tar.xz b/coreutils-8.17.tar.xz deleted file mode 100644 index 4b6b684..0000000 --- a/coreutils-8.17.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e075a0d238072a5bd079046e1f024dc5e0d9133d43a39c73d0b86b0d1e2c5e5 -size 5077388 diff --git a/coreutils-8.21.de.po.xz b/coreutils-8.21.de.po.xz new file mode 100644 index 0000000..c5a3891 --- /dev/null +++ b/coreutils-8.21.de.po.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b28dba154ded8117dc043125a7e0fae2e7b613a7d287c46e9faa6866a81d377 +size 102904 diff --git a/coreutils-8.21.tar.xz b/coreutils-8.21.tar.xz new file mode 100644 index 0000000..393b16d --- /dev/null +++ b/coreutils-8.21.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adaa44bdab3fa5eb352e80d8a31fdbf957b78653d0c2cd30d63e161444288e18 +size 5357988 diff --git a/coreutils-8.6-compile-su-with-fpie.diff b/coreutils-8.6-compile-su-with-fpie.diff deleted file mode 100644 index f113b77..0000000 --- a/coreutils-8.6-compile-su-with-fpie.diff +++ /dev/null @@ -1,39 +0,0 @@ -From d1a49cccf99373293a88f5bce74857d5bb813e46 Mon Sep 17 00:00:00 2001 -From: Thorsten Kukuk -Date: Tue, 17 Aug 2010 09:21:22 +0200 -Subject: [PATCH 7/7] compile su with -fpie - ---- - lib/Makefile.am | 2 +- - src/Makefile.am | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -Index: lib/Makefile.am -=================================================================== ---- lib/Makefile.am.orig -+++ lib/Makefile.am -@@ -28,7 +28,7 @@ noinst_LIBRARIES = - - include gnulib.mk - --AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) -+AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) -fpie - - libcoreutils_a_SOURCES += \ - buffer-lcm.c buffer-lcm.h -Index: src/Makefile.am -=================================================================== ---- src/Makefile.am.orig -+++ src/Makefile.am -@@ -361,6 +361,11 @@ uptime_LDADD += $(GETLOADAVG_LIBS) - su_SOURCES = su.c getdef.c - su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) - -+su_CFLAGS = -fpie -+su_LDFLAGS = -pie -+timeout_CFLAGS = -fpie -+timeout_LDFLAGS = -pie -+ - # for various ACL functions - copy_LDADD += $(LIB_ACL) - ls_LDADD += $(LIB_ACL) diff --git a/coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff b/coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff deleted file mode 100644 index 17e2c21..0000000 --- a/coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff +++ /dev/null @@ -1,385 +0,0 @@ -From d776b1b67eb1bc1b815426fdf22f38b25ef1e2df Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Mon, 9 Aug 2010 16:03:12 +0200 -Subject: [PATCH 5/7] honor settings in /etc/default/su resp /etc/login.defs - ---- - src/Makefile.am | 1 - src/Makefile.in | 4 - src/getdef.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/getdef.h | 29 ++++++ - src/su.c | 13 ++ - 5 files changed, 302 insertions(+), 4 deletions(-) - create mode 100644 src/getdef.c - create mode 100644 src/getdef.h - -Index: src/Makefile.am -=================================================================== ---- src/Makefile.am.orig -+++ src/Makefile.am -@@ -358,6 +358,7 @@ factor_LDADD += $(LIB_GMP) - uptime_LDADD += $(GETLOADAVG_LIBS) - - # for crypt and pam -+su_SOURCES = su.c getdef.c - su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) - - # for various ACL functions -Index: src/Makefile.in -=================================================================== ---- src/Makefile.in.orig -+++ src/Makefile.in -@@ -592,8 +592,8 @@ stdbuf_DEPENDENCIES = $(am__DEPENDENCIES - stty_SOURCES = stty.c - stty_OBJECTS = stty.$(OBJEXT) - stty_DEPENDENCIES = $(am__DEPENDENCIES_2) --su_SOURCES = su.c --su_OBJECTS = su.$(OBJEXT) -+su_SOURCES = su.c getdef.c -+su_OBJECTS = su.$(OBJEXT) getdef.$(OBJEXT) - su_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) - sum_SOURCES = sum.c - sum_OBJECTS = sum.$(OBJEXT) -Index: src/getdef.c -=================================================================== ---- /dev/null -+++ src/getdef.c -@@ -0,0 +1,259 @@ -+/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk -+ Author: Thorsten Kukuk -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License version 2 or -+ later as published by the Free Software Foundation. -+ -+ 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, write to the Free Software Foundation, -+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "getdef.h" -+ -+struct item { -+ char *name; /* Name of the option. */ -+ char *value; /* Value of the option. */ -+ struct item *next; /* Pointer to next option. */ -+}; -+ -+static struct item *list = NULL; -+ -+void -+free_getdef_data (void) -+{ -+ struct item *ptr; -+ -+ ptr = list; -+ while (ptr != NULL) -+ { -+ struct item *tmp; -+ tmp = ptr->next; -+ free (ptr->name); -+ free (ptr->value); -+ free (ptr); -+ ptr = tmp; -+ } -+ -+ list = NULL; -+} -+ -+/* Add a new entry to the list. */ -+static void -+store (const char *name, const char *value) -+{ -+ struct item *new = malloc (sizeof (struct item)); -+ -+ if (new == NULL) -+ abort (); -+ -+ if (name == NULL) -+ abort (); -+ -+ new->name = strdup (name); -+ new->value = strdup (value ?: ""); -+ new->next = list; -+ list = new; -+} -+ -+/* Search a special entry in the list and return the value. */ -+static const char * -+search (const char *name) -+{ -+ struct item *ptr; -+ -+ ptr = list; -+ while (ptr != NULL) -+ { -+ if (strcasecmp (name, ptr->name) == 0) -+ return ptr->value; -+ ptr = ptr->next; -+ } -+ -+ return NULL; -+} -+ -+/* Load the login.defs file (/etc/login.defs). */ -+static void -+load_defaults_internal (const char *filename) -+{ -+ FILE *fp; -+ char *buf = NULL; -+ size_t buflen = 0; -+ -+ fp = fopen (filename, "r"); -+ if (NULL == fp) -+ return; -+ -+ while (!feof (fp)) -+ { -+ char *tmp, *cp; -+#if defined(HAVE_GETLINE) -+ ssize_t n = getline (&buf, &buflen, fp); -+#elif defined (HAVE_GETDELIM) -+ ssize_t n = getdelim (&buf, &buflen, '\n', fp); -+#else -+ ssize_t n; -+ -+ if (buf == NULL) -+ { -+ buflen = 8096; -+ buf = malloc (buflen); -+ } -+ buf[0] = '\0'; -+ fgets (buf, buflen - 1, fp); -+ if (buf != NULL) -+ n = strlen (buf); -+ else -+ n = 0; -+#endif /* HAVE_GETLINE / HAVE_GETDELIM */ -+ cp = buf; -+ -+ if (n < 1) -+ break; -+ -+ tmp = strchr (cp, '#'); /* remove comments */ -+ if (tmp) -+ *tmp = '\0'; -+ while (isspace ((unsigned char) *cp)) /* remove spaces and tabs */ -+ ++cp; -+ if (*cp == '\0') /* ignore empty lines */ -+ continue; -+ -+ if (cp[strlen (cp) - 1] == '\n') -+ cp[strlen (cp) - 1] = '\0'; -+ -+ tmp = strsep (&cp, " \t="); -+ if (cp != NULL) -+ while (isspace ((unsigned char) *cp) || *cp == '=') -+ ++cp; -+ -+ store (tmp, cp); -+ } -+ fclose (fp); -+ -+ if (buf) -+ free (buf); -+} -+ -+static void -+load_defaults (void) -+{ -+ load_defaults_internal ("/etc/default/su"); -+ load_defaults_internal ("/etc/login.defs"); -+} -+ -+int -+getdef_bool (const char *name, int dflt) -+{ -+ const char *val; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ return (strcasecmp (val, "yes") == 0); -+} -+ -+long -+getdef_num (const char *name, long dflt) -+{ -+ const char *val; -+ char *cp; -+ long retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ errno = 0; -+ retval = strtol (val, &cp, 0); -+ if (*cp != '\0' -+ || ((retval == LONG_MAX || retval == LONG_MIN) && errno == ERANGE)) -+ { -+ fprintf (stderr, -+ "%s contains invalid numerical value: %s!\n", -+ name, val); -+ retval = dflt; -+ } -+ return retval; -+} -+ -+unsigned long -+getdef_unum (const char *name, unsigned long dflt) -+{ -+ const char *val; -+ char *cp; -+ unsigned long retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ errno = 0; -+ retval = strtoul (val, &cp, 0); -+ if (*cp != '\0' || (retval == ULONG_MAX && errno == ERANGE)) -+ { -+ fprintf (stderr, -+ "%s contains invalid numerical value: %s!\n", -+ name, val); -+ retval = dflt; -+ } -+ return retval; -+} -+ -+const char * -+getdef_str (const char *name, const char *dflt) -+{ -+ const char *retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ retval = search (name); -+ -+ return retval ?: dflt; -+} -+ -+#if defined(TEST) -+ -+int -+main () -+{ -+ printf ("CYPT=%s\n", getdef_str ("cRypt", "no")); -+ printf ("LOG_UNKFAIL_ENAB=%s\n", getdef_str ("log_unkfail_enab","")); -+ printf ("DOESNOTEXIST=%s\n", getdef_str ("DOESNOTEXIST","yes")); -+ return 0; -+} -+ -+#endif -Index: src/getdef.h -=================================================================== ---- /dev/null -+++ src/getdef.h -@@ -0,0 +1,29 @@ -+/* Copyright (C) 2003, 2005 Thorsten Kukuk -+ Author: Thorsten Kukuk -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License version 2 or -+ later published by the Free Software Foundation. -+ -+ 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, write to the Free Software Foundation, -+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#ifndef _GETDEF_H_ -+ -+#define _GETDEF_H_ 1 -+ -+extern int getdef_bool (const char *name, int dflt); -+extern long getdef_num (const char *name, long dflt); -+extern unsigned long getdef_unum (const char *name, unsigned long dflt); -+extern const char *getdef_str (const char *name, const char *dflt); -+ -+/* Free all data allocated by getdef_* calls before. */ -+extern void free_getdef_data (void); -+ -+#endif /* _GETDEF_H_ */ -Index: src/su.c -=================================================================== ---- src/su.c.orig -+++ src/su.c -@@ -111,6 +111,8 @@ - # include - #endif - -+#include "getdef.h" -+ - /* The default PATH for simulated logins to non-superuser accounts. */ - #define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" - -@@ -478,8 +480,8 @@ modify_environment (const struct passwd - xsetenv ("USER", pw->pw_name); - xsetenv ("LOGNAME", pw->pw_name); - xsetenv ("PATH", (pw->pw_uid -- ? DEFAULT_LOGIN_PATH -- : DEFAULT_ROOT_LOGIN_PATH)); -+ ? getdef_str ("PATH", DEFAULT_LOGIN_PATH) -+ : getdef_str ("SUPATH", DEFAULT_ROOT_LOGIN_PATH))); - } - else - { -@@ -489,6 +491,12 @@ modify_environment (const struct passwd - { - xsetenv ("HOME", pw->pw_dir); - xsetenv ("SHELL", shell); -+ if (getdef_bool ("ALWAYS_SET_PATH", 0)) -+ xsetenv ("PATH", (pw->pw_uid -+ ? getdef_str ("PATH", -+ DEFAULT_LOGIN_PATH) -+ : getdef_str ("SUPATH", -+ DEFAULT_ROOT_LOGIN_PATH))); - if (pw->pw_uid) - { - xsetenv ("USER", pw->pw_name); -@@ -722,6 +730,7 @@ main (int argc, char **argv) - #ifdef SYSLOG_FAILURE - log_su (pw, false); - #endif -+ sleep (getdef_num ("FAIL_DELAY", 1)); - error (EXIT_CANCELED, 0, _("incorrect password")); - } - #ifdef SYSLOG_SUCCESS diff --git a/coreutils-8.6-log-all-su-attempts.diff b/coreutils-8.6-log-all-su-attempts.diff deleted file mode 100644 index d2c9c53..0000000 --- a/coreutils-8.6-log-all-su-attempts.diff +++ /dev/null @@ -1,23 +0,0 @@ -From f2ea0c33d8c25ee40e7fe7a16d0994c8069bc120 Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Tue, 17 Aug 2010 13:22:01 +0200 -Subject: [PATCH 3/7] log all su attempts - ---- - src/su.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -Index: coreutils-8.17/src/su.c -=================================================================== ---- coreutils-8.17.orig/src/su.c -+++ coreutils-8.17/src/su.c -@@ -75,6 +75,9 @@ - - #if HAVE_SYSLOG_H && HAVE_SYSLOG - # include -+# define SYSLOG_SUCCESS 1 -+# define SYSLOG_FAILURE 1 -+# define SYSLOG_NON_ROOT 1 - #else - # undef SYSLOG_SUCCESS - # undef SYSLOG_FAILURE diff --git a/coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff b/coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff deleted file mode 100644 index c74e496..0000000 --- a/coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff +++ /dev/null @@ -1,154 +0,0 @@ -From b43728c1f0c7abe90e73369542564d3ad4704963 Mon Sep 17 00:00:00 2001 -From: Werner Fink -Date: Tue, 17 Aug 2010 09:09:55 +0200 -Subject: [PATCH 6/7] make sure /sbin resp /usr/sbin are in PATH - ---- - src/su.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 127 insertions(+), 0 deletions(-) - -Index: src/su.c -=================================================================== ---- src/su.c.orig -+++ src/su.c -@@ -458,6 +458,117 @@ correct_password (const struct passwd *p - #endif /* !USE_PAM */ - } - -+/* Add or clear /sbin and /usr/sbin for the su command -+ used without `-'. */ -+ -+/* Set if /sbin is found in path. */ -+#define SBIN_MASK 0x01 -+/* Set if /usr/sbin is found in path. */ -+#define USBIN_MASK 0x02 -+ -+static char * -+addsbin (const char *const path) -+{ -+ unsigned char smask = 0; -+ char *ptr, *tmp, *cur, *ret = NULL; -+ size_t len; -+ -+ if (!path || *path == 0) -+ return NULL; -+ -+ tmp = xstrdup (path); -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr != NULL; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, "/sbin")) -+ smask |= SBIN_MASK; -+ if (!strcmp (ptr, "/usr/sbin")) -+ smask |= USBIN_MASK; -+ } -+ -+ if ((smask & (USBIN_MASK|SBIN_MASK)) == (USBIN_MASK|SBIN_MASK)) -+ { -+ free (tmp); -+ return NULL; -+ } -+ -+ len = strlen (path); -+ if (!(smask & USBIN_MASK)) -+ len += strlen ("/usr/sbin:"); -+ -+ if (!(smask & SBIN_MASK)) -+ len += strlen (":/sbin"); -+ -+ ret = xmalloc (len + 1); -+ strcpy (tmp, path); -+ -+ *ret = 0; -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, ".")) -+ continue; -+ if (*ret) -+ strcat (ret, ":"); -+ if (!(smask & USBIN_MASK) && !strcmp (ptr, "/bin")) -+ { -+ strcat (ret, "/usr/sbin:"); -+ strcat (ret, ptr); -+ smask |= USBIN_MASK; -+ continue; -+ } -+ if (!(smask & SBIN_MASK) && !strcmp (ptr, "/usr/bin")) -+ { -+ strcat (ret, ptr); -+ strcat (ret, ":/sbin"); -+ smask |= SBIN_MASK; -+ continue; -+ } -+ strcat (ret, ptr); -+ } -+ free (tmp); -+ -+ if (!(smask & USBIN_MASK)) -+ strcat (ret, ":/usr/sbin"); -+ -+ if (!(smask & SBIN_MASK)) -+ strcat (ret, ":/sbin"); -+ -+ return ret; -+} -+ -+static char * -+clearsbin (const char *const path) -+{ -+ char *ptr, *tmp, *cur, *ret = NULL; -+ -+ if (!path || *path == 0) -+ return NULL; -+ -+ tmp = strdup (path); -+ if (!tmp) -+ return NULL; -+ -+ ret = xmalloc (strlen (path) + 1); -+ *ret = 0; -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, "/sbin")) -+ continue; -+ if (!strcmp (ptr, "/usr/sbin")) -+ continue; -+ if (!strcmp (ptr, "/usr/local/sbin")) -+ continue; -+ if (*ret) -+ strcat (ret, ":"); -+ strcat (ret, ptr); -+ } -+ free (tmp); -+ -+ return ret; -+} -+ - /* Update 'environ' for the new shell based on PW, with SHELL being - the value for the SHELL environment variable. */ - -@@ -497,6 +608,22 @@ modify_environment (const struct passwd - DEFAULT_LOGIN_PATH) - : getdef_str ("SUPATH", - DEFAULT_ROOT_LOGIN_PATH))); -+ else -+ { -+ char const *path = getenv ("PATH"); -+ char *new = NULL; -+ -+ if (pw->pw_uid) -+ new = clearsbin (path); -+ else -+ new = addsbin (path); -+ -+ if (new) -+ { -+ xsetenv ("PATH", new); -+ free (new); -+ } -+ } - if (pw->pw_uid) - { - xsetenv ("USER", pw->pw_name); diff --git a/coreutils-8.6-pam-support-for-su.diff b/coreutils-8.6-pam-support-for-su.diff deleted file mode 100644 index f45e733..0000000 --- a/coreutils-8.6-pam-support-for-su.diff +++ /dev/null @@ -1,402 +0,0 @@ -From 8b1e75c55ea6be5c8639c98b73ecfa0cf15226ce Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Tue, 17 Aug 2010 13:21:44 +0200 -Subject: [PATCH 1/7] pam support for su - ---- - configure.ac | 14 +++ - src/Makefile.am | 4 +- - src/su.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 278 insertions(+), 6 deletions(-) - -Index: configure.ac -=================================================================== ---- configure.ac.orig -+++ configure.ac -@@ -185,6 +185,20 @@ fi - - AC_FUNC_FORK - -+AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], -+ [Enable PAM support in su (default=auto)]), , [enable_pam=yes]) -+if test "x$enable_pam" != xno; then -+ AC_CHECK_LIB([pam], [pam_start], [enable_pam=yes], [enable_pam=no]) -+ AC_CHECK_LIB([pam_misc], [misc_conv], [:], [enable_pam=no]) -+ if test "x$enable_pam" != xno; then -+ AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) -+ PAM_LIBS="-lpam -lpam_misc" -+ AC_SUBST(PAM_LIBS) -+ fi -+fi -+AC_MSG_CHECKING([whether to enable PAM support in su]) -+AC_MSG_RESULT([$enable_pam]) -+ - optional_bin_progs= - AC_CHECK_FUNCS([chroot], - gl_ADD_PROG([optional_bin_progs], [chroot])) -Index: src/Makefile.am -=================================================================== ---- src/Makefile.am.orig -+++ src/Makefile.am -@@ -357,8 +357,8 @@ factor_LDADD += $(LIB_GMP) - # for getloadavg - uptime_LDADD += $(GETLOADAVG_LIBS) - --# for crypt --su_LDADD += $(LIB_CRYPT) -+# for crypt and pam -+su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) - - # for various ACL functions - copy_LDADD += $(LIB_ACL) -Index: src/su.c -=================================================================== ---- src/su.c.orig -+++ src/su.c -@@ -37,6 +37,16 @@ - restricts who can su to UID 0 accounts. RMS considers that to - be fascist. - -+#ifdef USE_PAM -+ -+ Actually, with PAM, su has nothing to do with whether or not a -+ wheel group is enforced by su. RMS tries to restrict your access -+ to a su which implements the wheel group, but PAM considers that -+ to be fascist, and gives the user/sysadmin the opportunity to -+ enforce a wheel group by proper editing of /etc/pam.d/su -+ -+#endif -+ - Compile-time options: - -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. - -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. -@@ -52,6 +62,13 @@ - #include - #include - #include -+#ifdef USE_PAM -+#include -+#include -+#include -+#include -+#include -+#endif - - #include "system.h" - #include "getpass.h" -@@ -111,7 +128,9 @@ - /* The user to become if none is specified. */ - #define DEFAULT_USER "root" - -+#ifndef USE_PAM - char *crypt (char const *key, char const *salt); -+#endif - - static void run_shell (char const *, char const *, char **, size_t) - ATTRIBUTE_NORETURN; -@@ -125,6 +144,11 @@ static bool simulate_login; - /* If true, change some environment vars to indicate the user su'd to. */ - static bool change_environment; - -+#ifdef USE_PAM -+static bool _pam_session_opened; -+static bool _pam_cred_established; -+#endif -+ - static struct option const longopts[] = - { - {"command", required_argument, NULL, 'c'}, -@@ -203,7 +227,164 @@ log_su (struct passwd const *pw, bool su - } - #endif - -+#ifdef USE_PAM -+#define PAM_SERVICE_NAME PROGRAM_NAME -+#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l" -+static sig_atomic_t volatile caught_signal = false; -+static pam_handle_t *pamh = NULL; -+static int retval; -+static struct pam_conv conv = -+{ -+ misc_conv, -+ NULL -+}; -+ -+#define PAM_BAIL_P(a) \ -+ if (retval) \ -+ { \ -+ pam_end (pamh, retval); \ -+ a; \ -+ } -+ -+static void -+cleanup_pam (int retcode) -+{ -+ if (_pam_session_opened) -+ pam_close_session (pamh, 0); -+ -+ if (_pam_cred_established) -+ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); -+ -+ pam_end(pamh, retcode); -+} -+ -+/* Signal handler for parent process. */ -+static void -+su_catch_sig (int sig) -+{ -+ caught_signal = true; -+} -+ -+/* Export env variables declared by PAM modules. */ -+static void -+export_pamenv (void) -+{ -+ char **env; -+ -+ /* This is a copy but don't care to free as we exec later anyways. */ -+ env = pam_getenvlist (pamh); -+ while (env && *env) -+ { -+ if (putenv (*env) != 0) -+ xalloc_die (); -+ env++; -+ } -+} -+ -+static void -+create_watching_parent (void) -+{ -+ pid_t child; -+ sigset_t ourset; -+ int status = 0; -+ -+ retval = pam_open_session (pamh, 0); -+ if (retval != PAM_SUCCESS) -+ { -+ cleanup_pam (retval); -+ error (EXIT_FAILURE, 0, _("cannot not open session: %s"), -+ pam_strerror (pamh, retval)); -+ } -+ else -+ _pam_session_opened = 1; -+ -+ child = fork (); -+ if (child == (pid_t) -1) -+ { -+ cleanup_pam (PAM_ABORT); -+ error (EXIT_FAILURE, errno, _("cannot create child process")); -+ } -+ -+ /* the child proceeds to run the shell */ -+ if (child == 0) -+ return; -+ -+ /* In the parent watch the child. */ -+ -+ /* su without pam support does not have a helper that keeps -+ sitting on any directory so let's go to /. */ -+ if (chdir ("/") != 0) -+ error (0, errno, _("warning: cannot change directory to %s"), "/"); -+ -+ sigfillset (&ourset); -+ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) -+ { -+ error (0, errno, _("cannot block signals")); -+ caught_signal = true; -+ } -+ if (!caught_signal) -+ { -+ struct sigaction action; -+ action.sa_handler = su_catch_sig; -+ sigemptyset (&action.sa_mask); -+ action.sa_flags = 0; -+ sigemptyset (&ourset); -+ if (sigaddset (&ourset, SIGTERM) -+ || sigaddset (&ourset, SIGALRM) -+ || sigaction (SIGTERM, &action, NULL) -+ || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal) -+ { -+ pid_t pid; -+ for (;;) -+ { -+ pid = waitpid (child, &status, WUNTRACED); -+ -+ if (pid != (pid_t)-1 && WIFSTOPPED (status)) -+ { -+ kill (getpid (), SIGSTOP); -+ /* once we get here, we must have resumed */ -+ kill (pid, SIGCONT); -+ } -+ else -+ break; -+ } -+ if (pid != (pid_t)-1) -+ if (WIFSIGNALED (status)) -+ status = WTERMSIG (status) + 128; -+ else -+ status = WEXITSTATUS (status); -+ else -+ status = 1; -+ } -+ else -+ status = 1; -+ -+ if (caught_signal) -+ { -+ fprintf (stderr, _("\nSession terminated, killing shell...")); -+ kill (child, SIGTERM); -+ } -+ -+ cleanup_pam (PAM_SUCCESS); -+ -+ if (caught_signal) -+ { -+ sleep (2); -+ kill (child, SIGKILL); -+ fprintf (stderr, _(" ...killed.\n")); -+ } -+ exit (status); -+} -+#endif -+ - /* Ask the user for a password. -+ If PAM is in use, let PAM ask for the password if necessary. - Return true if the user gives the correct password for entry PW, - false if not. Return true without asking for a password if run by UID 0 - or if PW has an empty password. */ -@@ -211,10 +392,52 @@ log_su (struct passwd const *pw, bool su - static bool - correct_password (const struct passwd *pw) - { -+#ifdef USE_PAM -+ const struct passwd *lpw; -+ const char *cp; -+ -+ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME, -+ pw->pw_name, &conv, &pamh); -+ PAM_BAIL_P (return false); -+ -+ if (isatty (0) && (cp = ttyname (0)) != NULL) -+ { -+ const char *tty; -+ -+ if (strncmp (cp, "/dev/", 5) == 0) -+ tty = cp + 5; -+ else -+ tty = cp; -+ retval = pam_set_item (pamh, PAM_TTY, tty); -+ PAM_BAIL_P (return false); -+ } -+#if 0 /* Manpage discourages use of getlogin. */ -+ cp = getlogin (); -+ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ())) -+#endif -+ lpw = getpwuid (getuid ()); -+ if (lpw && lpw->pw_name) -+ { -+ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); -+ PAM_BAIL_P (return false); -+ } -+ retval = pam_authenticate (pamh, 0); -+ PAM_BAIL_P (return false); -+ retval = pam_acct_mgmt (pamh, 0); -+ if (retval == PAM_NEW_AUTHTOK_REQD) -+ { -+ /* Password has expired. Offer option to change it. */ -+ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); -+ PAM_BAIL_P (return false); -+ } -+ PAM_BAIL_P (return false); -+ /* Must be authenticated if this point was reached. */ -+ return true; -+#else /* !USE_PAM */ - char *unencrypted, *encrypted, *correct; - #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP - /* Shadow passwd stuff for SVR3 and maybe other systems. */ -- struct spwd *sp = getspnam (pw->pw_name); -+ const struct spwd *sp = getspnam (pw->pw_name); - - endspent (); - if (sp) -@@ -235,6 +458,7 @@ correct_password (const struct passwd *p - encrypted = crypt (unencrypted, correct); - memset (unencrypted, 0, strlen (unencrypted)); - return STREQ (encrypted, correct); -+#endif /* !USE_PAM */ - } - - /* Update 'environ' for the new shell based on PW, with SHELL being -@@ -277,19 +501,41 @@ modify_environment (const struct passwd - } - } - } -+ -+#ifdef USE_PAM -+ export_pamenv (); -+#endif - } - - /* Become the user and group(s) specified by PW. */ - - static void --change_identity (const struct passwd *pw) -+init_groups (const struct passwd *pw) - { - #ifdef HAVE_INITGROUPS - errno = 0; - if (initgroups (pw->pw_name, pw->pw_gid) == -1) -- error (EXIT_CANCELED, errno, _("cannot set groups")); -+ { -+#ifdef USE_PAM -+ cleanup_pam (PAM_ABORT); -+#endif -+ error (EXIT_FAILURE, errno, _("cannot set groups")); -+ } - endgrent (); - #endif -+ -+#ifdef USE_PAM -+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); -+ if (retval != PAM_SUCCESS) -+ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval)); -+ else -+ _pam_cred_established = 1; -+#endif -+} -+ -+static void -+change_identity (const struct passwd *pw) -+{ - if (setgid (pw->pw_gid)) - error (EXIT_CANCELED, errno, _("cannot set group id")); - if (setuid (pw->pw_uid)) -@@ -502,9 +748,21 @@ main (int argc, char **argv) - shell = NULL; - } - shell = xstrdup (shell ? shell : pw->pw_shell); -- modify_environment (pw, shell); -+ -+ init_groups (pw); -+ -+#ifdef USE_PAM -+ create_watching_parent (); -+ /* Now we're in the child. */ -+#endif - - change_identity (pw); -+ -+ /* Set environment after pam_open_session, which may put KRB5CCNAME -+ into the pam_env, etc. */ -+ -+ modify_environment (pw, shell); -+ - if (simulate_login && chdir (pw->pw_dir) != 0) - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); - diff --git a/coreutils-8.6-set-sane-default-path.diff b/coreutils-8.6-set-sane-default-path.diff deleted file mode 100644 index fbde488..0000000 --- a/coreutils-8.6-set-sane-default-path.diff +++ /dev/null @@ -1,34 +0,0 @@ -From 3c13edc2b9aeab8f24e60a62ab5e8a8db554486f Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Mon, 9 Aug 2010 16:02:30 +0200 -Subject: [PATCH 4/7] set sane default path - ---- - src/su.c | 12 ++---------- - 1 files changed, 2 insertions(+), 10 deletions(-) - -Index: coreutils-8.17/src/su.c -=================================================================== ---- coreutils-8.17.orig/src/su.c -+++ coreutils-8.17/src/su.c -@@ -112,18 +112,10 @@ - #endif - - /* The default PATH for simulated logins to non-superuser accounts. */ --#ifdef _PATH_DEFPATH --# define DEFAULT_LOGIN_PATH _PATH_DEFPATH --#else --# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin" --#endif -+#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" - - /* The default PATH for simulated logins to superuser accounts. */ --#ifdef _PATH_DEFPATH_ROOT --# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT --#else --# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" --#endif -+#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" - - /* The shell to run if none is given in the user's passwd entry. */ - #define DEFAULT_SHELL "/bin/sh" diff --git a/coreutils-8.6-update-man-page-for-pam.diff b/coreutils-8.6-update-man-page-for-pam.diff deleted file mode 100644 index 892582d..0000000 --- a/coreutils-8.6-update-man-page-for-pam.diff +++ /dev/null @@ -1,61 +0,0 @@ -From 13ed7b537ae655c6d67965f1486aa2e3b181e574 Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Tue, 17 Aug 2010 08:59:35 +0200 -Subject: [PATCH 2/7] update man page for pam - ---- - doc/coreutils.texi | 34 +++++----------------------------- - 1 files changed, 5 insertions(+), 29 deletions(-) - -Index: doc/coreutils.texi -=================================================================== ---- doc/coreutils.texi.orig -+++ doc/coreutils.texi -@@ -15806,8 +15806,11 @@ to certain shells, etc.). - @findex syslog - @command{su} can optionally be compiled to use @code{syslog} to report - failed, and optionally successful, @command{su} attempts. (If the system --supports @code{syslog}.) However, GNU @command{su} does not check if the --user is a member of the @code{wheel} group; see below. -+supports @code{syslog}.) -+ -+This version of @command{su} has support for using PAM for -+authentication. You can edit @file{/etc/pam.d/su} resp @file{/etc/pam.d/su-l} -+to customize its behaviour. - - The program accepts the following options. Also see @ref{Common options}. - -@@ -15888,33 +15891,6 @@ Exit status: - the exit status of the subshell otherwise - @end display - --@cindex wheel group, not supported --@cindex group wheel, not supported --@cindex fascism --@subsection Why GNU @command{su} does not support the @samp{wheel} group -- --(This section is by Richard Stallman.) -- --@cindex Twenex --@cindex MIT AI lab --Sometimes a few of the users try to hold total power over all the --rest. For example, in 1984, a few users at the MIT AI lab decided to --seize power by changing the operator password on the Twenex system and --keeping it secret from everyone else. (I was able to thwart this coup --and give power back to the users by patching the kernel, but I --wouldn't know how to do that in Unix.) -- --However, occasionally the rulers do tell someone. Under the usual --@command{su} mechanism, once someone learns the root password who --sympathizes with the ordinary users, he or she can tell the rest. The --``wheel group'' feature would make this impossible, and thus cement the --power of the rulers. -- --I'm on the side of the masses, not that of the rulers. If you are --used to supporting the bosses and sysadmins in whatever they do, you --might find this idea strange at first. -- -- - @node timeout invocation - @section @command{timeout}: Run a command with a time limit - diff --git a/coreutils-acl-nofollow.patch b/coreutils-acl-nofollow.patch deleted file mode 100644 index 475d4df..0000000 --- a/coreutils-acl-nofollow.patch +++ /dev/null @@ -1,87 +0,0 @@ -commit 95f7c57ff4090a5dee062044d2c7b99879077808 -Author: Kamil Dudka -Date: Fri Jul 22 14:48:42 2011 +0200 - - file-has-acl: use acl_extended_file_nofollow if available - - * lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro. - (acl_extended_file): New macro. - * lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow. - * m4/acl.m4 (gl_FUNC_ACL): Check for acl_extended_file_nofollow. - This addresses http://bugzilla.redhat.com/692823. - -Index: lib/acl-internal.h -=================================================================== ---- lib/acl-internal.h.orig -+++ lib/acl-internal.h -@@ -142,6 +142,12 @@ rpl_acl_set_fd (int fd, acl_t acl) - # endif - - /* Linux-specific */ -+# ifndef HAVE_ACL_EXTENDED_FILE_NOFOLLOW -+# define HAVE_ACL_EXTENDED_FILE_NOFOLLOW false -+# define acl_extended_file_nofollow(name) (-1) -+# endif -+ -+/* Linux-specific */ - # ifndef HAVE_ACL_FROM_MODE - # define HAVE_ACL_FROM_MODE false - # define acl_from_mode(mode) (NULL) -Index: lib/file-has-acl.c -=================================================================== ---- lib/file-has-acl.c.orig -+++ lib/file-has-acl.c -@@ -492,12 +492,20 @@ file_has_acl (char const *name, struct s - /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ - int ret; - -- if (HAVE_ACL_EXTENDED_FILE) /* Linux */ -+ if (HAVE_ACL_EXTENDED_FILE || HAVE_ACL_EXTENDED_FILE_NOFOLLOW) /* Linux */ - { -+# if HAVE_ACL_EXTENDED_FILE_NOFOLLOW -+ /* acl_extended_file_nofollow() uses lgetxattr() in order to prevent -+ unnecessary mounts, but it returns the same result as we already -+ know that NAME is not a symbolic link at this point (modulo the -+ TOCTTOU race condition). */ -+ ret = acl_extended_file_nofollow (name); -+# else - /* On Linux, acl_extended_file is an optimized function: It only - makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for - ACL_TYPE_DEFAULT. */ - ret = acl_extended_file (name); -+# endif - } - else /* FreeBSD, MacOS X, IRIX, Tru64 */ - { -Index: m4/acl.m4 -=================================================================== ---- m4/acl.m4.orig -+++ m4/acl.m4 -@@ -33,7 +33,7 @@ AC_DEFUN([gl_FUNC_ACL], - AC_CHECK_FUNCS( - [acl_get_file acl_get_fd acl_set_file acl_set_fd \ - acl_free acl_from_mode acl_from_text \ -- acl_delete_def_file acl_extended_file \ -+ acl_delete_def_file acl_extended_file acl_extended_file_nofollow \ - acl_delete_fd_np acl_delete_file_np \ - acl_copy_ext_native acl_create_entry_np \ - acl_to_short_text acl_free_text]) -Index: ChangeLog -=================================================================== ---- ChangeLog.orig -+++ ChangeLog -@@ -3272,6 +3272,14 @@ - MacOS X 10.7 has an fdatasync that is not declared, and is rumored to - be ineffective. (Bug#9141) - -+2011-07-22 Kamil Dudka -+ -+ file-has-acl: use acl_extended_file_nofollow if available -+ * lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro. -+ (acl_extended_file): New macro. -+ * lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow. -+ * m4/acl.m4 (gl_FUNC_ACL): Check for acl_extended_file_nofollow. -+ - 2011-07-20 Mike Frysinger - - dircolors: add screen.Eterm terminal type diff --git a/coreutils-basename_documentation.patch b/coreutils-basename_documentation.patch deleted file mode 100644 index e8f59fa..0000000 --- a/coreutils-basename_documentation.patch +++ /dev/null @@ -1,21 +0,0 @@ -Index: doc/coreutils.texi -=================================================================== ---- doc/coreutils.texi.orig -+++ doc/coreutils.texi -@@ -12457,6 +12457,16 @@ This section describes commands that man - @command{basename} removes any leading directory components from - @var{name}. Synopsis: - -+@table @samp -+ -+@item -z -+@itemx --zero -+@opindex -z -+@opindex --zero -+Separate output items with @sc{nul} characters. -+ -+@end table -+ - @example - basename @var{name} [@var{suffix}] - basename @var{option}... @var{name}... diff --git a/coreutils-bnc#697897-setsid.patch b/coreutils-bnc#697897-setsid.patch deleted file mode 100644 index 81f1681..0000000 --- a/coreutils-bnc#697897-setsid.patch +++ /dev/null @@ -1,137 +0,0 @@ -Index: doc/coreutils.info -=================================================================== ---- doc/coreutils.info.orig -+++ doc/coreutils.info -@@ -12796,6 +12796,10 @@ and optionally successful, `su' attempts - `syslog'.) However, GNU `su' does not check if the user is a member of - the `wheel' group; see below. - -+ If the environment variable SU_COMMAND_SAME_SESSION is set, su will -+not open a new session for running a command thus making -c behaves just -+like -C. -+ - The program accepts the following options. Also see *note Common - options::. - -@@ -12804,6 +12808,12 @@ options::. - Pass COMMAND, a single command line to run, to the shell with a - `-c' option instead of starting an interactive shell. - -+`-C COMMAND' -+`--session-command=COMMAND' -+ Pass COMMAND, a single command line to run, to the shell with a -+ `-c' option instead of starting an interactive and do not create -+ a new session for it. -+ - `-f' - `--fast' - Pass the `-f' option to the shell. This probably only makes sense -Index: src/su.c -=================================================================== ---- src/su.c.orig -+++ src/su.c -@@ -141,6 +141,9 @@ static bool simulate_login; - /* If true, change some environment vars to indicate the user su'd to. */ - static bool change_environment; - -+/* If true, then don't call setsid() with a command. */ -+int same_session = 0; -+ - #ifdef USE_PAM - static bool _pam_session_opened; - static bool _pam_cred_established; -@@ -149,6 +152,7 @@ static bool _pam_cred_established; - static struct option const longopts[] = - { - {"command", required_argument, NULL, 'c'}, -+ {"session-command", required_argument, NULL, 'C'}, - {"fast", no_argument, NULL, 'f'}, - {"login", no_argument, NULL, 'l'}, - {"preserve-environment", no_argument, NULL, 'p'}, -@@ -326,14 +330,29 @@ create_watching_parent (void) - sigemptyset (&action.sa_mask); - action.sa_flags = 0; - sigemptyset (&ourset); -- if (sigaddset (&ourset, SIGTERM) -- || sigaddset (&ourset, SIGALRM) -- || sigaction (SIGTERM, &action, NULL) -- || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) -- { -+ -+ if (!same_session) -+ { -+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal && (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) -+ { - error (0, errno, _("cannot set signal handler")); - caught_signal = true; - } -+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) -+ || sigaction(SIGQUIT, &action, NULL))) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } - } - if (!caught_signal) - { -@@ -750,6 +769,8 @@ Change the effective user id and group i - \n\ - -, -l, --login make the shell a login shell\n\ - -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ and do not create a new session\n\ - -f, --fast pass -f to the shell (for csh or tcsh)\n\ - -m, --preserve-environment do not reset environment variables\n\ - -p same as -m\n\ -@@ -772,6 +793,7 @@ main (int argc, char **argv) - int optc; - const char *new_user = DEFAULT_USER; - char *command = NULL; -+ int request_same_session = 0; - char *shell = NULL; - struct passwd *pw; - struct passwd pw_copy; -@@ -795,6 +817,14 @@ main (int argc, char **argv) - { - case 'c': - command = optarg; -+ if (NULL != getenv ("SU_COMMAND_SAME_SESSION") || -+ NULL != getenv ("SU_COMMAND_OPENS_SESSION")) -+ request_same_session = 1; -+ break; -+ -+ case 'C': -+ command = optarg; -+ request_same_session = 1; - break; - - case 'f': -@@ -867,6 +897,9 @@ main (int argc, char **argv) - } - #endif - -+ if (request_same_session || !command || !pw->pw_uid) -+ same_session = 1; -+ - if (!shell && !change_environment) - shell = getenv ("SHELL"); - if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) -@@ -889,6 +922,9 @@ main (int argc, char **argv) - - change_identity (pw); - -+ if (!same_session) -+ setsid (); -+ - /* Set environment after pam_open_session, which may put KRB5CCNAME - into the pam_env, etc. */ - diff --git a/coreutils-build-timeout-as-pie.patch b/coreutils-build-timeout-as-pie.patch new file mode 100644 index 0000000..c65d89a --- /dev/null +++ b/coreutils-build-timeout-as-pie.patch @@ -0,0 +1,39 @@ +From d1a49cccf99373293a88f5bce74857d5bb813e46 Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Thu, 10 Jan 2013 09:21:22 +0200 +Subject: build timeout as PIE + +The OBS requires /usr/bin/timeout to be built as an position +independent executable (PIE). This is enforced via RPMLINT. + +* src/local.mk (AM_CFLAGS): Add -fpie option. +(timeout_CFLAGS): Likewise. +(timeout_LDFLAGS): Add -pie option. + +--- + src/local.mk | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: src/local.mk +=================================================================== +--- src/local.mk.orig ++++ src/local.mk +@@ -17,7 +17,7 @@ + ## along with this program. If not, see . + + # FIXME: once lib/ and gnulib-tests/ are also converted, hoist to Makefile.am +-AM_CFLAGS = $(WERROR_CFLAGS) ++AM_CFLAGS = $(WERROR_CFLAGS) -fpie + + # The list of all programs (separated in different variables to express + # the how and when they should be installed) is defined in this makefile +@@ -266,6 +266,9 @@ src_factor_LDADD += $(LIB_GMP) + # for getloadavg + src_uptime_LDADD += $(GETLOADAVG_LIBS) + ++src_timeout_CFLAGS = -fpie ++src_timeout_LDFLAGS = -pie ++ + # for various ACL functions + copy_ldadd += $(LIB_ACL) + src_ls_LDADD += $(LIB_ACL) diff --git a/coreutils-cp-corrupt-fragmented-sparse.patch b/coreutils-cp-corrupt-fragmented-sparse.patch deleted file mode 100644 index 2310787..0000000 --- a/coreutils-cp-corrupt-fragmented-sparse.patch +++ /dev/null @@ -1,109 +0,0 @@ -commit 64aef5fb9afecc023a6e719da161dbbf450908b8 -Author: Jim Meyering -Date: Tue Oct 16 17:43:49 2012 +0200 - - cp: avoid data-corrupting free-memory-read - - NEWS entry: - cp could read from freed memory and could even make corrupt copies. - This could happen with a very fragmented and sparse input file, - on GNU/Linux file systems supporting fiemap extent scanning. - This bug also affects mv when it resorts to copying, and install. - [bug introduced in coreutils-8.11] - - * src/extent-scan.c (extent_scan_read): Reset our last_ei - pointer whenever the parent buffer might have just been freed. - * tests/cp/fiemap-extent-FMR.sh: New test. - * tests/local.mk (all_tests): Add it. - * NEWS (Bug fixes): Mention it. - Reported by Mike Gerth in http://bugs.gnu.org/12656, and with - help from Alan Curry. Bug introduced in commit v8.10-60-g18f5a85. - -Index: src/extent-scan.c -=================================================================== ---- src/extent-scan.c.orig -+++ src/extent-scan.c -@@ -89,7 +89,7 @@ extern bool - extent_scan_read (struct extent_scan *scan) - { - unsigned int si = 0; -- struct extent_info *last_ei IF_LINT ( = scan->ext_info); -+ struct extent_info *last_ei = scan->ext_info; - - while (true) - { -@@ -127,8 +127,14 @@ extent_scan_read (struct extent_scan *sc - - assert (scan->ei_count <= SIZE_MAX - fiemap->fm_mapped_extents); - scan->ei_count += fiemap->fm_mapped_extents; -- scan->ext_info = xnrealloc (scan->ext_info, scan->ei_count, -- sizeof (struct extent_info)); -+ { -+ /* last_ei points into a buffer that may be freed via xnrealloc. -+ Record its offset and adjust after allocation. */ -+ size_t prev_idx = last_ei - scan->ext_info; -+ scan->ext_info = xnrealloc (scan->ext_info, scan->ei_count, -+ sizeof (struct extent_info)); -+ last_ei = scan->ext_info + prev_idx; -+ } - - unsigned int i = 0; - for (i = 0; i < fiemap->fm_mapped_extents; i++) -Index: tests/cp/fiemap-FMR -=================================================================== ---- /dev/null -+++ tests/cp/fiemap-FMR -@@ -0,0 +1,41 @@ -+#!/bin/sh -+# Trigger a free-memory read bug in cp from coreutils-[8.11..8.19] -+ -+# Copyright (C) 2012 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/init.sh"; path_prepend_ ../src -+print_ver_ cp -+ -+# Skip the current test if valgrind doesn't work, -+# which could happen if not installed, -+# or hasn't support for the built architecture, -+# or hasn't appropriate error suppressions installed etc. -+require_valgrind_() -+{ -+ valgrind --error-exitcode=1 true 2>/dev/null || -+ skip_ "requires a working valgrind" -+} -+ -+require_valgrind_ -+require_perl_ -+: ${PERL=perl} -+ -+$PERL -e 'for (1..600) { sysseek (*STDOUT, 4096, 1)' \ -+ -e '&& syswrite (*STDOUT, "a" x 1024) or die "$!"}' > j || fail=1 -+valgrind --quiet --error-exitcode=3 cp j j2 || fail=1 -+cmp j j2 || fail=1 -+ -+Exit $fail -Index: tests/Makefile.am -=================================================================== ---- tests/Makefile.am.orig -+++ tests/Makefile.am -@@ -342,6 +342,7 @@ TESTS = \ - cp/existing-perm-race \ - cp/fail-perm \ - cp/fiemap-empty \ -+ cp/fiemap-FMR \ - cp/fiemap-perf \ - cp/fiemap-2 \ - cp/file-perm-race \ diff --git a/coreutils-df-always-hide-rootfs.patch b/coreutils-df-always-hide-rootfs.patch deleted file mode 100644 index 62abea4..0000000 --- a/coreutils-df-always-hide-rootfs.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: coreutils-8.17/src/df.c -=================================================================== ---- coreutils-8.17.orig/src/df.c -+++ coreutils-8.17/src/df.c -@@ -474,6 +474,9 @@ get_dev (char const *disk, char const *m - if (!selected_fstype (fstype) || excluded_fstype (fstype)) - return; - -+ if (fstype && !show_all_fs && (STRNCMP_LIT (fstype, "rootfs") == 0)) -+ return; -+ - /* If MOUNT_POINT is NULL, then the file system is not mounted, and this - program reports on the file system that the special file is on. - It would be better to report on the unmounted file system, diff --git a/coreutils-getaddrinfo.patch b/coreutils-getaddrinfo.patch deleted file mode 100644 index b71a324..0000000 --- a/coreutils-getaddrinfo.patch +++ /dev/null @@ -1,17 +0,0 @@ -Index: gnulib-tests/test-getaddrinfo.c -=================================================================== ---- gnulib-tests/test-getaddrinfo.c.orig -+++ gnulib-tests/test-getaddrinfo.c -@@ -86,11 +86,7 @@ simple (char const *host, char const *se - the test merely because someone is down the country on their - in-law's farm. */ - if (res == EAI_AGAIN) -- { -- skip++; -- fprintf (stderr, "skipping getaddrinfo test: no network?\n"); -- return 77; -- } -+ return 0; - /* IRIX reports EAI_NONAME for "https". Don't fail the test - merely because of this. */ - if (res == EAI_NONAME) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e3c66a4..a1bd0eb 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -191,7 +191,7 @@ Index: src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -206,7 +283,7 @@ Mandatory arguments to long options are +@@ -205,7 +282,7 @@ Print selected parts of lines from each -f, --fields=LIST select only these fields; also print any line\n\ that contains no delimiter character, unless\n\ the -s option is specified\n\ @@ -200,35 +200,7 @@ Index: src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) - in_digits = false; - /* Starting a range. */ - if (dash_found) -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - dash_found = true; - fieldstr++; - -@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) - 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) -@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) +@@ -480,6 +557,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -238,16 +210,7 @@ Index: src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) - fieldstr++; - } - else -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - } - - max_range_endpoint = 0; -@@ -581,6 +663,77 @@ cut_bytes (FILE *stream) +@@ -588,6 +668,77 @@ cut_bytes (FILE *stream) } } @@ -325,7 +288,7 @@ Index: src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -703,13 +856,195 @@ cut_fields (FILE *stream) +@@ -709,13 +860,195 @@ cut_fields (FILE *stream) } } @@ -524,7 +487,7 @@ Index: src/cut.c } /* Process file FILE to standard output. -@@ -761,6 +1096,8 @@ main (int argc, char **argv) +@@ -767,6 +1100,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -533,7 +496,7 @@ Index: src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -783,7 +1120,6 @@ main (int argc, char **argv) +@@ -789,7 +1124,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -541,7 +504,7 @@ Index: src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -791,6 +1127,14 @@ main (int argc, char **argv) +@@ -797,6 +1131,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -556,7 +519,7 @@ Index: src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -802,10 +1146,35 @@ main (int argc, char **argv) +@@ -808,10 +1150,36 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -581,6 +544,7 @@ Index: src/cut.c + if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') + FATAL_ERROR (_("the delimiter must be a single character")); + memcpy (mbdelim, optarg, delimlen); ++ mbdelim[delimlen] = '\0'; + } + } + @@ -596,7 +560,7 @@ Index: src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -818,6 +1187,7 @@ main (int argc, char **argv) +@@ -824,6 +1192,7 @@ main (int argc, char **argv) break; case 'n': @@ -604,16 +568,7 @@ Index: src/cut.c break; case 's': -@@ -840,7 +1210,7 @@ main (int argc, char **argv) - if (operating_mode == undefined_mode) - FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); - -- if (delim != '\0' && operating_mode != field_mode) -+ if (delim_specified && operating_mode != field_mode) - FATAL_ERROR (_("an input delimiter may be specified only\ - when operating on fields")); - -@@ -867,15 +1237,34 @@ main (int argc, char **argv) +@@ -873,15 +1242,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -688,7 +643,7 @@ Index: src/expand.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "expand" -@@ -358,6 +375,142 @@ expand (void) +@@ -357,6 +374,142 @@ expand (void) } } @@ -701,7 +656,7 @@ Index: src/expand.c + mbstate_t i_state_bak; /* Back up the I_STATE. */ + mbstate_t o_state; /* Current shift state of the output stream. */ + char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ ++ char *bufpos = buf; /* Next read position of BUF. */ + size_t buflen = 0; /* The length of the byte sequence in buf. */ + wchar_t wc; /* A gotten wide character. */ + size_t mblength; /* The byte size of a multibyte character @@ -755,7 +710,7 @@ Index: src/expand.c + if (convert) + { + ++column; -+ if (convert_entire_line == 0) ++ if (convert_entire_line == 0 && !isblank(*bufpos)) + convert = 0; + } + putchar (*bufpos); @@ -815,7 +770,7 @@ Index: src/expand.c + + width = wcwidth (wc); + column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0) ++ if (convert_entire_line == 0 && !iswblank(wc)) + convert = 0; + } + } @@ -831,7 +786,7 @@ Index: src/expand.c int main (int argc, char **argv) { -@@ -422,7 +575,12 @@ main (int argc, char **argv) +@@ -421,7 +574,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -930,15 +885,15 @@ Index: src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -77,6 +120,7 @@ Mandatory arguments to long options are - "), stdout); +@@ -76,6 +119,7 @@ standard output.\n\ + fputs (_("\ -b, --bytes count bytes rather than columns\n\ + -c, --characters count characters rather than columns\n\ -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -94,7 +138,7 @@ Mandatory arguments to long options are +@@ -93,7 +137,7 @@ standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -947,7 +902,7 @@ Index: src/fold.c { if (c == '\b') { -@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -980,7 +935,7 @@ Index: src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -170,6 +198,15 @@ fold_file (char const *filename, size_t +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -996,7 +951,7 @@ Index: src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -216,11 +253,222 @@ fold_file (char const *filename, size_t +@@ -215,11 +252,222 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } @@ -1014,12 +969,12 @@ Index: src/fold.c +{ + char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ + size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ char *bufpos = NULL; /* Next read position of BUF. */ ++ char *bufpos = buf; /* Next read position of BUF. */ + wint_t wc; /* A gotten wide character. */ + size_t mblength; /* The byte size of a multibyte character which shows + as same character as WC. */ + mbstate_t state, state_bak; /* State of the stream. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ + + static char *line_out = NULL; + size_t offset_out = 0; /* Index in `line_out' for next char. */ @@ -1220,7 +1175,7 @@ Index: src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -253,7 +501,8 @@ main (int argc, char **argv) +@@ -252,7 +500,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1230,7 +1185,7 @@ Index: src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -262,7 +511,15 @@ main (int argc, char **argv) +@@ -261,7 +510,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1691,7 +1646,7 @@ Index: src/join.c case 't': { - unsigned char newtab = optarg[0]; -+ char *newtab; ++ char *newtab = NULL; + size_t newtablen; + newtab = xstrdup (optarg); +#if HAVE_MBRTOWC @@ -1712,8 +1667,9 @@ Index: src/join.c +#endif + newtablen = 1; if (! newtab) +- newtab = '\n'; /* '' => process the whole line. */ + { - newtab = '\n'; /* '' => process the whole line. */ ++ newtab = "\n"; /* '' => process the whole line. */ + } else if (optarg[1]) { @@ -1866,7 +1822,7 @@ Index: src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -638,7 +692,13 @@ static int power_10; +@@ -634,7 +688,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1881,7 +1837,7 @@ Index: src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -691,6 +751,7 @@ static bool use_col_separator = false; +@@ -687,6 +747,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1889,7 +1845,7 @@ Index: src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) +@@ -843,6 +904,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1903,7 +1859,7 @@ Index: src/pr.c } int -@@ -871,6 +939,21 @@ main (int argc, char **argv) +@@ -867,6 +935,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1925,7 +1881,7 @@ Index: src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -947,8 +1030,12 @@ main (int argc, char **argv) +@@ -943,8 +1026,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1940,7 +1896,7 @@ Index: src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -961,8 +1048,12 @@ main (int argc, char **argv) +@@ -957,8 +1044,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1955,7 +1911,7 @@ Index: src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -989,8 +1080,8 @@ main (int argc, char **argv) +@@ -985,8 +1076,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1966,7 +1922,7 @@ Index: src/pr.c break; case 'N': skip_count = false; -@@ -1029,7 +1120,7 @@ main (int argc, char **argv) +@@ -1025,7 +1116,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1975,7 +1931,7 @@ Index: src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1186,10 +1277,45 @@ main (int argc, char **argv) +@@ -1182,10 +1273,45 @@ main (int argc, char **argv) a number. */ static void @@ -2023,7 +1979,19 @@ Index: src/pr.c if (*arg) { long int tmp_long; -@@ -1248,7 +1374,7 @@ init_parameters (int number_of_files) +@@ -1207,6 +1333,11 @@ static void + init_parameters (int number_of_files) + { + int chars_used_by_number = 0; ++ int mb_len = 1; ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ mb_len = MB_LEN_MAX; ++#endif + + lines_per_body = lines_per_page - lines_per_header - lines_per_footer; + if (lines_per_body <= 0) +@@ -1244,7 +1375,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2032,7 +2000,7 @@ Index: src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1279,11 +1405,11 @@ init_parameters (int number_of_files) +@@ -1274,11 +1405,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ /* Estimate chars_per_text without any margin and keep it constant. */ @@ -2046,7 +2014,7 @@ Index: src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1298,7 +1424,7 @@ init_parameters (int number_of_files) +@@ -1287,7 +1418,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number @@ -2055,7 +2023,16 @@ Index: src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1423,7 +1549,7 @@ init_funcs (void) +@@ -1305,7 +1436,7 @@ init_parameters (int number_of_files) + We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 + to expand a tab which is not an input_tab-char. */ + free (clump_buff); +- clump_buff = xmalloc (MAX (8, chars_per_input_tab)); ++ clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); + } + + /* Open the necessary files, +@@ -1413,7 +1544,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2064,7 +2041,7 @@ Index: src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1457,7 +1583,7 @@ init_funcs (void) +@@ -1447,7 +1578,7 @@ init_funcs (void) } else { @@ -2073,7 +2050,7 @@ Index: src/pr.c h_next = h + chars_per_column; } } -@@ -1748,9 +1874,9 @@ static void +@@ -1738,9 +1869,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2085,7 +2062,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2021,13 +2147,13 @@ store_char (char c) +@@ -2011,13 +2142,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2099,9 +2076,9 @@ Index: src/pr.c - int i; + int i, j; char *s; - int left_cut; + int num_width; -@@ -2050,22 +2176,24 @@ add_line_number (COLUMN *p) +@@ -2034,22 +2165,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -2130,7 +2107,7 @@ Index: src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2226,7 +2354,7 @@ print_white_space (void) +@@ -2210,7 +2343,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2139,7 +2116,7 @@ Index: src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2246,6 +2374,7 @@ print_sep_string (void) +@@ -2230,6 +2363,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2147,7 +2124,7 @@ Index: src/pr.c s = col_sep_string; -@@ -2259,6 +2388,7 @@ print_sep_string (void) +@@ -2243,6 +2377,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2155,7 +2132,7 @@ Index: src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2272,12 +2402,15 @@ print_sep_string (void) +@@ -2256,12 +2391,15 @@ print_sep_string (void) } else { @@ -2172,7 +2149,7 @@ Index: src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2305,7 +2438,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2289,7 +2427,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2181,7 +2158,7 @@ Index: src/pr.c { if (tabify_output) { -@@ -2329,6 +2462,74 @@ print_char (char c) +@@ -2313,6 +2451,74 @@ print_char (char c) putchar (c); } @@ -2256,7 +2233,7 @@ Index: src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2508,9 +2709,9 @@ read_line (COLUMN *p) +@@ -2492,9 +2698,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2268,7 +2245,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2611,9 +2812,9 @@ print_stored (COLUMN *p) +@@ -2595,9 +2801,9 @@ print_stored (COLUMN *p) } } @@ -2280,7 +2257,7 @@ Index: src/pr.c padding_not_printed = ANYWHERE; } -@@ -2626,8 +2827,8 @@ print_stored (COLUMN *p) +@@ -2610,8 +2816,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2291,7 +2268,7 @@ Index: src/pr.c } return true; -@@ -2646,7 +2847,7 @@ print_stored (COLUMN *p) +@@ -2630,7 +2836,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2300,7 +2277,7 @@ Index: src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2656,10 +2857,10 @@ char_to_clump (char c) +@@ -2640,10 +2846,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2313,7 +2290,7 @@ Index: src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2740,6 +2941,154 @@ char_to_clump (char c) +@@ -2724,6 +2930,154 @@ char_to_clump (char c) return chars; } @@ -2358,7 +2335,7 @@ Index: src/pr.c + width = +4; + chars = +4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", mbc[0]); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); + for (i = 0; i <= 2; ++i) + *s++ = (int) esc_buff[i]; + } @@ -2407,7 +2384,7 @@ Index: src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } @@ -2428,7 +2405,7 @@ Index: src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } @@ -2472,17 +2449,10 @@ Index: src/sort.c =================================================================== --- src/sort.c.orig +++ src/sort.c -@@ -22,12 +22,21 @@ - - #include - -+#include - #include - #include - #include - #include +@@ -29,6 +29,14 @@ #include #include + #include +#if HAVE_WCHAR_H +# include +#endif @@ -2494,7 +2464,7 @@ Index: src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -165,12 +174,34 @@ static int thousands_sep; +@@ -166,12 +174,34 @@ static int thousands_sep; /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; @@ -2530,7 +2500,7 @@ Index: src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -341,13 +372,11 @@ static bool reverse; +@@ -345,13 +375,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2547,7 +2517,7 @@ Index: src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -780,6 +809,46 @@ reap_all (void) +@@ -783,6 +811,46 @@ reap_all (void) reap (-1); } @@ -2594,7 +2564,7 @@ Index: src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1212,7 +1281,7 @@ zaptemp (char const *name) +@@ -1223,7 +1291,7 @@ zaptemp (char const *name) free (node); } @@ -2603,7 +2573,7 @@ Index: src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1227,7 +1296,7 @@ struct_month_cmp (void const *m1, void c +@@ -1238,7 +1306,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2612,7 +2582,7 @@ Index: src/sort.c { size_t i; -@@ -1239,7 +1308,7 @@ inittables (void) +@@ -1250,7 +1318,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2621,7 +2591,7 @@ Index: src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1321,6 +1390,84 @@ specify_nmerge (int oi, char c, char con +@@ -1332,6 +1400,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2706,7 +2676,7 @@ Index: src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1549,7 +1696,7 @@ buffer_linelim (struct buffer const *buf +@@ -1564,7 +1710,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2715,7 +2685,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1558,10 +1705,10 @@ begfield (struct line const *line, struc +@@ -1573,10 +1719,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2728,7 +2698,7 @@ Index: src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1587,11 +1734,70 @@ begfield (struct line const *line, struc +@@ -1602,11 +1748,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2800,7 +2770,7 @@ Index: src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1606,10 +1812,10 @@ limfield (struct line const *line, struc +@@ -1621,10 +1826,10 @@ limfield (struct line const *line, struc 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2813,7 +2783,7 @@ Index: src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1655,10 +1861,10 @@ limfield (struct line const *line, struc +@@ -1670,10 +1875,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2826,7 +2796,7 @@ Index: src/sort.c if (newlim) lim = newlim; } -@@ -1689,6 +1895,130 @@ limfield (struct line const *line, struc +@@ -1704,6 +1909,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2957,7 +2927,7 @@ Index: src/sort.c /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1775,8 +2105,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1790,8 +2119,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2982,7 +2952,7 @@ Index: src/sort.c line->keybeg = line_start; } } -@@ -1897,7 +2241,7 @@ human_numcompare (char const *a, char co +@@ -1912,7 +2255,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2991,8 +2961,8 @@ Index: src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1925,6 +2269,25 @@ nan_compare (char const *sa, char const - return memcmp (&a, &b, sizeof a); +@@ -1922,6 +2265,25 @@ numcompare (char const *a, char const *b + return strnumcmp (a, b, decimal_point, thousands_sep); } +#if HAVE_MBRTOWC @@ -3014,10 +2984,10 @@ Index: src/sort.c +} +#endif /* HAV_EMBRTOWC */ + - static int - general_numcompare (char const *sa, char const *sb) - { -@@ -1957,7 +2320,7 @@ general_numcompare (char const *sa, char + /* Work around a problem whereby the long double value returned by glibc's + strtold ("NaN", ...) contains uninitialized bits: clear all bytes of + A and B before calling strtold. FIXME: remove this function once +@@ -1972,7 +2334,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3026,7 +2996,7 @@ Index: src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2232,15 +2595,14 @@ debug_key (struct line const *line, stru +@@ -2247,15 +2609,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3044,7 +3014,7 @@ Index: src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2384,7 +2746,7 @@ key_warnings (struct keyfield const *gke +@@ -2399,7 +2760,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3053,7 +3023,7 @@ Index: src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2442,11 +2804,87 @@ key_warnings (struct keyfield const *gke +@@ -2457,11 +2818,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3119,12 +3089,12 @@ Index: src/sort.c + } + while (hi - lo > 1); + -+ if (ea) -+ *ea = (char *) month; -+ + result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) + ? monthtab[lo].val : 0); + ++ if (ea && result) ++ *ea = s + strlen (monthtab[lo].name); ++ + free (month); + free (tmp); + free (month_wcs); @@ -3138,11 +3108,11 @@ Index: src/sort.c static int -keycompare (struct line const *a, struct line const *b) -+keycompare_uni (struct line const *a, struct line const *b) ++keycompare_uni (const struct line *a, const struct line *b) { struct keyfield *key = keylist; -@@ -2531,7 +2969,7 @@ keycompare (struct line const *a, struct +@@ -2546,7 +2983,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3151,7 +3121,7 @@ Index: src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2647,6 +3085,181 @@ keycompare (struct line const *a, struct +@@ -2662,6 +3099,181 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3207,7 +3177,7 @@ Index: src/sort.c + { + if (ignore || translate) + { -+ char *copy_a = xmalloc (lena + 1 + lenb + 1); ++ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1); + char *copy_b = copy_a + lena + 1; + size_t new_len_a, new_len_b; + size_t i, j; @@ -3333,7 +3303,7 @@ Index: src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4107,7 +4720,7 @@ main (int argc, char **argv) +@@ -4157,7 +4769,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3342,7 +3312,7 @@ Index: src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4128,6 +4741,29 @@ main (int argc, char **argv) +@@ -4178,6 +4790,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3372,7 +3342,7 @@ Index: src/sort.c have_read_stdin = false; inittables (); -@@ -4398,13 +5034,34 @@ main (int argc, char **argv) +@@ -4452,13 +5087,34 @@ main (int argc, char **argv) case 't': { @@ -3411,7 +3381,7 @@ Index: src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4415,9 +5072,12 @@ main (int argc, char **argv) +@@ -4469,9 +5125,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3460,7 +3430,7 @@ Index: src/unexpand.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -103,6 +120,208 @@ static struct option const longopts[] = +@@ -103,6 +120,210 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -3475,11 +3445,12 @@ Index: src/unexpand.c + mbstate_t i_state_bak; /* Back up the I_STATE. */ + mbstate_t o_state; /* Current shift state of the output stream. */ + char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ ++ char *bufpos = buf; /* Next read position of BUF. */ + size_t buflen = 0; /* The length of the byte sequence in buf. */ + wint_t wc; /* A gotten wide character. */ + size_t mblength; /* The byte size of a multibyte character + which shows as same character as WC. */ ++ bool prev_tab = false; + + /* Index in `tab_list' of next tabstop: */ + int tab_index = 0; /* For calculating width of pending tabs. */ @@ -3558,7 +3529,7 @@ Index: src/unexpand.c +flush_pend_mb: + /* Flush pending spaces. Print as many tabs as possible, + then print the rest as spaces. */ -+ if (pending == 1) ++ if (pending == 1 && column != 1 && !prev_tab) + { + putchar (' '); + pending = 0; @@ -3659,6 +3630,7 @@ Index: src/unexpand.c + fwrite (bufpos, sizeof(char), mblength, stdout); + } + } ++ prev_tab = wc == L'\t'; + buflen -= mblength; + bufpos += mblength; + } @@ -3669,7 +3641,7 @@ Index: src/unexpand.c void usage (int status) { -@@ -524,7 +743,12 @@ main (int argc, char **argv) +@@ -523,7 +744,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3736,16 +3708,16 @@ Index: src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -206,7 +232,7 @@ size_opt (char const *opt, char const *m +@@ -205,7 +231,7 @@ size_opt (char const *opt, char const *m return a pointer to the beginning of the line's field to be compared. */ static char * _GL_ATTRIBUTE_PURE -find_field (struct linebuffer const *line) -+find_field_uni (struct linebuffer const *line) ++find_field_uni (struct linebuffer *line) { size_t count; char const *lp = line->buffer; -@@ -226,6 +252,83 @@ find_field (struct linebuffer const *lin +@@ -225,6 +251,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3784,7 +3756,7 @@ Index: src/uniq.c + size_t mblength; + wchar_t wc; + mbstate_t *statep; -+ int convfail; ++ int convfail = 0; + + pos = 0; + statep = &(line->state); @@ -3829,7 +3801,7 @@ Index: src/uniq.c /* Return false if two strings OLD and NEW match, true if not. OLD and NEW point not to the beginnings of the lines but rather to the beginnings of the fields to compare. -@@ -234,6 +337,8 @@ find_field (struct linebuffer const *lin +@@ -233,6 +336,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3838,7 +3810,7 @@ Index: src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -241,14 +346,100 @@ different (char *old, char *new, size_t +@@ -240,14 +345,100 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3846,8 +3818,8 @@ Index: src/uniq.c - return oldlen != newlen || memcasecmp (old, new, oldlen); + size_t i; + -+ copy_old = xmalloc (sizeof(char) * (oldlen + 1)); -+ copy_new = xmalloc (sizeof(char) * (oldlen + 1)); ++ copy_old = xmalloc (oldlen + 1); ++ copy_new = xmalloc (oldlen + 1); + + for (i = 0; i < oldlen; i++) + { @@ -3944,7 +3916,7 @@ Index: src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -304,15 +495,43 @@ check_file (const char *infile, const ch +@@ -303,15 +494,43 @@ check_file (const char *infile, const ch { char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3988,7 +3960,7 @@ Index: src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -331,17 +550,26 @@ check_file (const char *infile, const ch +@@ -330,17 +549,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4010,19 +3982,18 @@ Index: src/uniq.c char *thisfield; size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate = thisline->state; +#endif if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -350,6 +578,15 @@ check_file (const char *infile, const ch +@@ -349,6 +577,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + { -+ thisstate = thisline->state; + match = !different_multi (thisfield, prevfield, + thislen, prevlen, thisstate, prevstate); + } @@ -4031,7 +4002,7 @@ Index: src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -382,6 +619,9 @@ check_file (const char *infile, const ch +@@ -381,6 +617,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4041,7 +4012,7 @@ Index: src/uniq.c if (!match) match_count = 0; } -@@ -427,6 +667,19 @@ main (int argc, char **argv) +@@ -426,6 +665,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4061,168 +4032,152 @@ Index: src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -Index: tests/Makefile.am +Index: tests/local.mk =================================================================== ---- tests/Makefile.am.orig -+++ tests/Makefile.am -@@ -247,6 +247,7 @@ TESTS = \ - misc/sort-debug-warn \ - misc/sort-discrim \ - misc/sort-files0-from \ -+ misc/sort-mb-tests \ - misc/sort-float \ - misc/sort-merge \ - misc/sort-merge-fdlimit \ -@@ -543,6 +544,10 @@ TESTS = \ - $(root_tests) +--- tests/local.mk.orig ++++ tests/local.mk +@@ -324,6 +324,7 @@ all_tests = \ + tests/misc/sort-debug-warn.sh \ + tests/misc/sort-discrim.sh \ + tests/misc/sort-files0-from.pl \ ++ tests/misc/sort-mb-tests.sh \ + tests/misc/sort-float.sh \ + tests/misc/sort-merge.pl \ + tests/misc/sort-merge-fdlimit.sh \ +@@ -655,6 +656,10 @@ $(factor_tests): $(tf)/run.sh $(tf)/crea + CLEANFILES += $(factor_tests) pr_data = \ -+ misc/mb1.X \ -+ misc/mb1.I \ -+ misc/mb2.X \ -+ misc/mb2.I \ - pr/0F \ - pr/0FF \ - pr/0FFnt \ -Index: tests/misc/cut ++ tests/misc/mb1.X \ ++ tests/misc/mb1.I \ ++ tests/misc/mb2.X \ ++ tests/misc/mb2.I \ + tests/pr/0F \ + tests/pr/0FF \ + tests/pr/0FFnt \ +Index: tests/misc/cut.pl =================================================================== ---- tests/misc/cut.orig -+++ tests/misc/cut -@@ -30,7 +30,7 @@ my $mb_locale = $ENV{LOCALE_FR_UTF8}; +--- tests/misc/cut.pl.orig ++++ tests/misc/cut.pl +@@ -23,9 +23,10 @@ use strict; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; +-! defined $mb_locale || $mb_locale eq 'none' +- and $mb_locale = 'C'; ++#my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++#! defined $mb_locale || $mb_locale eq 'none' ++# and $mb_locale = 'C'; ++my $mb_locale = 'C'; + my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; - my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; --my $inval = "$prog: invalid byte or field list\n$try"; +Index: tests/misc/expand.pl +=================================================================== +--- tests/misc/expand.pl.orig ++++ tests/misc/expand.pl +@@ -23,6 +23,15 @@ use strict; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++# uncommented according to upstream commit enabling multibyte paths ++my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ ++my $prog = 'expand'; ++my $try = "Try \`$prog --help' for more information.\n"; +my $inval = "$prog: invalid byte, character or field list\n$try"; - my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; - ++ my @Tests = -@@ -147,7 +147,7 @@ my @Tests = + ( + ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], +@@ -31,6 +40,37 @@ my @Tests = + ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], + ); - # None of the following invalid ranges provoked an error up to coreutils-6.9. - ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -- {ERR=>"$prog: invalid decreasing range\n$try"}], -+ {ERR=>"$prog: invalid byte, character or field list\n$try"}], - ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -@@ -176,13 +176,13 @@ if ($mb_locale ne 'C') - # non-MB: invalid byte or field list - # MB: invalid byte, character or field list - # Adjust the expected error output accordingly. -- if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -- (@new_t)) -- { -- my $sub = {ERR_SUBST => 's/, character//'}; -- push @new_t, $sub; -- push @$t, $sub; -- } -+# if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+# (@new_t)) -+# { -+# my $sub = {ERR_SUBST => 's/, character//'}; -+# push @new_t, $sub; -+# push @$t, $sub; -+# } - push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; - } - push @Tests, @new; -Index: tests/misc/mb1.I ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether expand is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +Index: tests/misc/sort-mb-tests.sh =================================================================== --- /dev/null -+++ tests/misc/mb1.I -@@ -0,0 +1,4 @@ -+Apple@10 -+Banana@5 -+Citrus@20 -+Cherry@30 -Index: tests/misc/mb1.X -=================================================================== ---- /dev/null -+++ tests/misc/mb1.X -@@ -0,0 +1,4 @@ -+Banana@5 -+Apple@10 -+Citrus@20 -+Cherry@30 -Index: tests/misc/mb2.I -=================================================================== ---- /dev/null -+++ tests/misc/mb2.I -@@ -0,0 +1,4 @@ -+Apple@AA10@@20 -+Banana@AA5@@30 -+Citrus@AA20@@5 -+Cherry@AA30@@10 -Index: tests/misc/mb2.X -=================================================================== ---- /dev/null -+++ tests/misc/mb2.X -@@ -0,0 +1,4 @@ -+Citrus@AA20@@5 -+Cherry@AA30@@10 -+Apple@AA10@@20 -+Banana@AA5@@30 -Index: tests/misc/sort-mb-tests -=================================================================== ---- /dev/null -+++ tests/misc/sort-mb-tests -@@ -0,0 +1,58 @@ -+#! /bin/sh -+case $# in -+ 0) xx='../src/sort';; -+ *) xx="$1";; -+esac -+test "$VERBOSE" && echo=echo || echo=: -+$echo testing program: $xx -+errors=0 -+test "$srcdir" || srcdir=. -+test "$VERBOSE" && $xx --version 2> /dev/null ++++ tests/misc/sort-mb-tests.sh +@@ -0,0 +1,45 @@ ++#!/bin/sh ++# Verify sort's multi-byte support. ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort + +export LC_ALL=en_US.UTF-8 -+locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 -+errors=0 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ ++ || skip_ "No UTF-8 locale available" + -+$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; -+ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 -+ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb1 may have failed." 1>&2 -+ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi + -+$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; -+ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 -+ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb2 may have failed." 1>&2 -+ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi ++cat < exp ++Banana@5 ++Apple@10 ++Citrus@20 ++Cherry@30 ++EOF + -+if test $errors = 0; then -+ $echo Passed all 113 tests. 1>&2 -+else -+ $echo Failed $errors tests. 1>&2 -+fi -+test $errors = 0 || errors=1 -+exit $errors ++cat < out || fail=1 ++Apple@10 ++Banana@5 ++Citrus@20 ++Cherry@30 ++EOF ++ ++compare exp out || { fail=1; cat out; } ++ ++ ++cat < exp ++Citrus@AA20@@5 ++Cherry@AA30@@10 ++Apple@AA10@@20 ++Banana@AA5@@30 ++EOF ++ ++cat < out || fail=1 ++Apple@AA10@@20 ++Banana@AA5@@30 ++Citrus@AA20@@5 ++Cherry@AA30@@10 ++EOF ++ ++compare exp out || { fail=1; cat out; } ++ ++Exit $fail diff --git a/coreutils-misc.patch b/coreutils-misc.patch deleted file mode 100644 index 7436d26..0000000 --- a/coreutils-misc.patch +++ /dev/null @@ -1,55 +0,0 @@ -Index: gnulib-tests/test-isnanl.h -=================================================================== ---- gnulib-tests/test-isnanl.h.orig -+++ gnulib-tests/test-isnanl.h -@@ -47,7 +47,7 @@ main () - /* Quiet NaN. */ - ASSERT (isnanl (NaNl ())); - --#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT -+#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT && 0 - /* A bit pattern that is different from a Quiet NaN. With a bit of luck, - it's a Signalling NaN. */ - { -@@ -89,6 +89,7 @@ main () - { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; - ASSERT (isnanl (x.value)); - } -+#if 0 - /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities, - Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in - Intel IA-64 Architecture Software Developer's Manual, Volume 1: -@@ -122,6 +123,7 @@ main () - ASSERT (isnanl (x.value)); - } - #endif -+#endif - - return 0; - } -Index: tests/misc/help-version -=================================================================== ---- tests/misc/help-version.orig -+++ tests/misc/help-version -@@ -251,6 +251,7 @@ parted_setup () { args="-s $tmp_in mklab - for i in $built_programs; do - # Skip these. - case $i in chroot|stty|tty|false|chcon|runcon) continue;; esac -+ case $i in df) continue;; esac - - rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out $bigZ_in $zin $zin2 - echo z |gzip > $zin -Index: tests/other-fs-tmpdir -=================================================================== ---- tests/other-fs-tmpdir.orig -+++ tests/other-fs-tmpdir -@@ -43,6 +43,9 @@ for d in $CANDIDATE_TMP_DIRS; do - - done - -+# Autobuild hack -+test -f /bin/uname.bin && other_partition_tmpdir= -+ - if test -z "$other_partition_tmpdir"; then - skip_ \ - "requires a writable directory on a different disk partition, diff --git a/coreutils-no_silent-rule.patch b/coreutils-no_silent-rule.patch deleted file mode 100644 index 68edca4..0000000 --- a/coreutils-no_silent-rule.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Philipp Thomas -Date: 2012-11-08 13:06:34+01:00 -Subject: Remove AM_SILENT_RULES -References: -Upstream: - -This removes AM_SILENT_RULES so that autoreconf succeeds with older automake -versions. - ---- - configure.ac | 1 - - 1 file changed, 1 deletion(-) - -Index: configure.ac -=================================================================== ---- configure.ac.orig 2012-11-08 12:57:12.224507908 +0100 -+++ configure.ac 2012-11-08 13:04:32.064100936 +0100 -@@ -33,7 +33,6 @@ AC_CONFIG_AUX_DIR([build-aux]) - AC_CONFIG_HEADERS([lib/config.h:lib/config.hin]) - - AM_INIT_AUTOMAKE([1.11.1 no-dist-gzip dist-xz color-tests parallel-tests]) --AM_SILENT_RULES([yes]) # make --enable-silent-rules the default. - - dnl POSIXCHECK is worthwhile for maintainers, but adds several seconds - dnl (more than 10% execution time) to ./configure, with no benefit for diff --git a/coreutils-ptr_int_casts.patch b/coreutils-ptr_int_casts.patch deleted file mode 100644 index 96a8ebc..0000000 --- a/coreutils-ptr_int_casts.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: src/join.c -=================================================================== ---- src/join.c.orig -+++ src/join.c -@@ -1335,7 +1335,7 @@ main (int argc, char **argv) - - case 't': - { -- char *newtab; -+ char *newtab = NULL; - size_t newtablen; - newtab = xstrdup (optarg); - #if HAVE_MBRTOWC -@@ -1357,7 +1357,7 @@ main (int argc, char **argv) - newtablen = 1; - if (! newtab) - { -- newtab = '\n'; /* '' => process the whole line. */ -+ newtab = "\n"; /* '' => process the whole line. */ - } - else if (optarg[1]) - { diff --git a/coreutils-remove_hostname_documentation.patch b/coreutils-remove_hostname_documentation.patch index bfc4896..f550902 100644 --- a/coreutils-remove_hostname_documentation.patch +++ b/coreutils-remove_hostname_documentation.patch @@ -17,9 +17,9 @@ Index: doc/coreutils.texi -* System context:: date arch nproc uname hostname hostid uptime +* System context:: date arch nproc uname hostid uptime * SELinux context:: chcon runcon - * Modified command invocation:: chroot env nice nohup stdbuf su timeout + * Modified command invocation:: chroot env nice nohup stdbuf timeout * Process control:: kill -@@ -416,7 +415,6 @@ System context +@@ -419,7 +418,6 @@ System context * date invocation:: Print or set system date and time * nproc invocation:: Print the number of processors * uname invocation:: Print system information @@ -27,7 +27,7 @@ Index: doc/coreutils.texi * hostid invocation:: Print numeric host identifier * uptime invocation:: Print system uptime and load -@@ -14145,7 +14143,6 @@ information. +@@ -14626,7 +14624,6 @@ information. * arch invocation:: Print machine hardware name. * nproc invocation:: Print the number of processors. * uname invocation:: Print system information. @@ -35,7 +35,7 @@ Index: doc/coreutils.texi * hostid invocation:: Print numeric host identifier. * uptime invocation:: Print system uptime and load. @end menu -@@ -14932,15 +14929,6 @@ easily available, as is the case with Li +@@ -15448,15 +15445,6 @@ easily available, as is the case with Li Print the machine hardware name (sometimes called the hardware class or hardware type). @@ -51,7 +51,7 @@ Index: doc/coreutils.texi @item -p @itemx --processor @opindex -p -@@ -14994,30 +14982,6 @@ Print the kernel version. +@@ -15510,30 +15498,6 @@ Print the kernel version. @exitstatus @@ -82,29 +82,3 @@ Index: doc/coreutils.texi @node hostid invocation @section @command{hostid}: Print numeric host identifier -Index: man/Makefile.am -=================================================================== ---- man/Makefile.am.orig -+++ man/Makefile.am -@@ -199,7 +199,7 @@ check-x-vs-1: - @PATH=../src$(PATH_SEPARATOR)$$PATH; export PATH; \ - t=$@-t; \ - (cd $(srcdir) && ls -1 *.x) | sed 's/\.x$$//' | $(ASSORT) > $$t;\ -- (echo $(dist_man1_MANS) $(NO_INSTALL_PROGS_DEFAULT) \ -+ (echo $(dist_man1_MANS) $(NO_INSTALL_PROGS_DEFAULT) hostid \ - | tr -s ' ' '\n' | sed 's/\.1$$//') \ - | $(ASSORT) -u | diff - $$t || { rm $$t; exit 1; }; \ - rm $$t -Index: man/Makefile.in -=================================================================== ---- man/Makefile.in.orig -+++ man/Makefile.in -@@ -2065,7 +2065,7 @@ check-x-vs-1: - @PATH=../src$(PATH_SEPARATOR)$$PATH; export PATH; \ - t=$@-t; \ - (cd $(srcdir) && ls -1 *.x) | sed 's/\.x$$//' | $(ASSORT) > $$t;\ -- (echo $(dist_man1_MANS) $(NO_INSTALL_PROGS_DEFAULT) \ -+ (echo $(dist_man1_MANS) $(NO_INSTALL_PROGS_DEFAULT) hostid \ - | tr -s ' ' '\n' | sed 's/\.1$$//') \ - | $(ASSORT) -u | diff - $$t || { rm $$t; exit 1; }; \ - rm $$t diff --git a/coreutils-skip-du-slink-test.patch b/coreutils-skip-du-slink-test.patch deleted file mode 100644 index e17e128..0000000 --- a/coreutils-skip-du-slink-test.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Bernhard Voelker -Date: Sun, 20 Jan 2013 14:12:00 +0200 -Subject: [PATCH] Skip tests/du/slink on OBS - -This test does not work on OBS infrastructure. -Discussed at: -http://lists.gnu.org/archive/html/coreutils/2013-01/msg00053.html - -The test will be removed upstreams with coreutils-8.21. -Until then, skip this test. - - ---- - tests/du/slink | 2 ++ - 1 file changed, 2 insertions(+) - -Index: coreutils-8.17/tests/du/slink -=================================================================== ---- coreutils-8.17.orig/tests/du/slink -+++ coreutils-8.17/tests/du/slink -@@ -19,6 +19,8 @@ - . "${srcdir=.}/init.sh"; path_prepend_ ../src - print_ver_ du - -+skip_ "test does not work on OpenSUSE Build Service infrastructure" -+ - # Determine if '.' is on a local (would non-NFS be sufficient?) file system. - # At least on OSF/1 4.0d, when using an nfsv3 file system, - # each created symlink can end up having a size of 0. diff --git a/coreutils-su.patch b/coreutils-su.patch new file mode 100644 index 0000000..95c50b8 --- /dev/null +++ b/coreutils-su.patch @@ -0,0 +1,1664 @@ +From: Bernhard Voelker +Date: Tue, 19 Mar 2013 17:00:00 +0200 +Subject: add su again for compatibility + +As su(1) has been moved from coreutils to util-linux upstreams, this package +must provide it via compatibility symlinks to the old coreutils version. +This is needed until there is a newer version of the receiving util-linux +package available which would then provide su. + +--- + doc/coreutils.texi | 141 +++++++ + man/local.mk | 2 + man/su.x | 4 + po/coreutils.pot | 67 +++ + src/cu-progs.mk | 1 + src/getdef.c | 259 +++++++++++++ + src/getdef.h | 29 + + src/local.mk | 6 + src/su.c | 945 ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/local.mk | 1 + tests/misc/su-fail.sh | 30 + + 11 files changed, 1483 insertions(+), 2 deletions(-) + +Index: src/cu-progs.mk +=================================================================== +--- src/cu-progs.mk.orig ++++ src/cu-progs.mk +@@ -87,6 +87,7 @@ default__progs += src/sleep + default__progs += src/sort + default__progs += src/split + default__progs += src/stat ++default__progs += src/su + default__progs += src/sum + default__progs += src/sync + default__progs += src/tac +Index: src/local.mk +=================================================================== +--- src/local.mk.orig ++++ src/local.mk +@@ -205,6 +205,12 @@ src_who_LDADD = $(LDADD) + src_whoami_LDADD = $(LDADD) + src_yes_LDADD = $(LDADD) + ++ ++src_su_CFLAGS = -fpie -DUSE_PAM=1 ++src_su_LDFLAGS = -pie ++PAM_LIBS = -lpam -lpam_misc ++src_su_LDADD = src/getdef.c $(LDADD) -lcrypt $(PAM_LIBS) ++ + # Synonyms. Recall that Automake transliterates '[' and '/' to '_'. + src___LDADD = $(src_test_LDADD) + src_dir_LDADD = $(src_ls_LDADD) +Index: src/su.c +=================================================================== +--- /dev/null ++++ src/su.c +@@ -0,0 +1,945 @@ ++/* su for GNU. Run a shell with substitute user and group IDs. ++ Copyright (C) 1992-2012 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Run a shell with the real and effective UID and GID and groups ++ of USER, default 'root'. ++ ++ The shell run is taken from USER's password entry, /bin/sh if ++ none is specified there. If the account has a password, su ++ prompts for a password unless run by a user with real UID 0. ++ ++ Does not change the current directory. ++ Sets 'HOME' and 'SHELL' from the password entry for USER, and if ++ USER is not root, sets 'USER' and 'LOGNAME' to USER. ++ The subshell is not a login shell. ++ ++ If one or more ARGs are given, they are passed as additional ++ arguments to the subshell. ++ ++ Does not handle /bin/sh or other shells specially ++ (setting argv[0] to "-su", passing -c only to certain shells, etc.). ++ I don't see the point in doing that, and it's ugly. ++ ++ This program intentionally does not support a "wheel group" that ++ restricts who can su to UID 0 accounts. RMS considers that to ++ be fascist. ++ ++#ifdef USE_PAM ++ ++ Actually, with PAM, su has nothing to do with whether or not a ++ wheel group is enforced by su. RMS tries to restrict your access ++ to a su which implements the wheel group, but PAM considers that ++ to be fascist, and gives the user/sysadmin the opportunity to ++ enforce a wheel group by proper editing of /etc/pam.d/su ++ ++#endif ++ ++ Compile-time options: ++ -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. ++ -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. ++ ++ -DSYSLOG_NON_ROOT Log all su's, not just those to root (UID 0). ++ Never logs attempted su's to nonexistent accounts. ++ ++ Written by David MacKenzie . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef USE_PAM ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#include "system.h" ++#include "getpass.h" ++ ++#if HAVE_SYSLOG_H && HAVE_SYSLOG ++# include ++# define SYSLOG_SUCCESS 1 ++# define SYSLOG_FAILURE 1 ++# define SYSLOG_NON_ROOT 1 ++#else ++# undef SYSLOG_SUCCESS ++# undef SYSLOG_FAILURE ++# undef SYSLOG_NON_ROOT ++#endif ++ ++#if HAVE_SYS_PARAM_H ++# include ++#endif ++ ++#ifndef HAVE_ENDGRENT ++# define endgrent() ((void) 0) ++#endif ++ ++#ifndef HAVE_ENDPWENT ++# define endpwent() ((void) 0) ++#endif ++ ++#if HAVE_SHADOW_H ++# include ++#endif ++ ++#include "error.h" ++ ++/* The official name of this program (e.g., no 'g' prefix). */ ++#define PROGRAM_NAME "su" ++ ++#define AUTHORS proper_name ("David MacKenzie") ++ ++#if HAVE_PATHS_H ++# include ++#endif ++ ++#include "getdef.h" ++ ++/* The default PATH for simulated logins to non-superuser accounts. */ ++#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" ++ ++/* The default PATH for simulated logins to superuser accounts. */ ++#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" ++ ++/* The shell to run if none is given in the user's passwd entry. */ ++#define DEFAULT_SHELL "/bin/sh" ++ ++/* The user to become if none is specified. */ ++#define DEFAULT_USER "root" ++ ++#ifndef USE_PAM ++char *crypt (char const *key, char const *salt); ++#endif ++ ++static void run_shell (char const *, char const *, char **, size_t) ++ ATTRIBUTE_NORETURN; ++ ++/* If true, pass the '-f' option to the subshell. */ ++static bool fast_startup; ++ ++/* If true, simulate a login instead of just starting a shell. */ ++static bool simulate_login; ++ ++/* If true, change some environment vars to indicate the user su'd to. */ ++static bool change_environment; ++ ++/* If true, then don't call setsid() with a command. */ ++int same_session = 0; ++ ++#ifdef USE_PAM ++static bool _pam_session_opened; ++static bool _pam_cred_established; ++#endif ++ ++static struct option const longopts[] = ++{ ++ {"command", required_argument, NULL, 'c'}, ++ {"session-command", required_argument, NULL, 'C'}, ++ {"fast", no_argument, NULL, 'f'}, ++ {"login", no_argument, NULL, 'l'}, ++ {"preserve-environment", no_argument, NULL, 'p'}, ++ {"shell", required_argument, NULL, 's'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Add NAME=VAL to the environment, checking for out of memory errors. */ ++ ++static void ++xsetenv (char const *name, char const *val) ++{ ++ size_t namelen = strlen (name); ++ size_t vallen = strlen (val); ++ char *string = xmalloc (namelen + 1 + vallen + 1); ++ strcpy (string, name); ++ string[namelen] = '='; ++ strcpy (string + namelen + 1, val); ++ if (putenv (string) != 0) ++ xalloc_die (); ++} ++ ++#if defined SYSLOG_SUCCESS || defined SYSLOG_FAILURE ++/* Log the fact that someone has run su to the user given by PW; ++ if SUCCESSFUL is true, they gave the correct password, etc. */ ++ ++static void ++log_su (struct passwd const *pw, bool successful) ++{ ++ const char *new_user, *old_user, *tty; ++ ++# ifndef SYSLOG_NON_ROOT ++ if (pw->pw_uid) ++ return; ++# endif ++ new_user = pw->pw_name; ++ /* The utmp entry (via getlogin) is probably the best way to identify ++ the user, especially if someone su's from a su-shell. */ ++ old_user = getlogin (); ++ if (!old_user) ++ { ++ /* getlogin can fail -- usually due to lack of utmp entry. ++ Resort to getpwuid. */ ++ errno = 0; ++ uid_t ruid = getuid (); ++ uid_t NO_UID = -1; ++ struct passwd *pwd = (ruid == NO_UID && errno ? NULL : getpwuid (ruid)); ++ old_user = (pwd ? pwd->pw_name : ""); ++ } ++ tty = ttyname (STDERR_FILENO); ++ if (!tty) ++ tty = "none"; ++ /* 4.2BSD openlog doesn't have the third parameter. */ ++ openlog (last_component (program_name), 0 ++# ifdef LOG_AUTH ++ , LOG_AUTH ++# endif ++ ); ++ syslog (LOG_NOTICE, ++# ifdef SYSLOG_NON_ROOT ++ "%s(to %s) %s on %s", ++# else ++ "%s%s on %s", ++# endif ++ successful ? "" : "FAILED SU ", ++# ifdef SYSLOG_NON_ROOT ++ new_user, ++# endif ++ old_user, tty); ++ closelog (); ++} ++#endif ++ ++#ifdef USE_PAM ++#define PAM_SERVICE_NAME PROGRAM_NAME ++#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l" ++static sig_atomic_t volatile caught_signal = false; ++static pam_handle_t *pamh = NULL; ++static int retval; ++static struct pam_conv conv = ++{ ++ misc_conv, ++ NULL ++}; ++ ++#define PAM_BAIL_P(a) \ ++ if (retval) \ ++ { \ ++ pam_end (pamh, retval); \ ++ a; \ ++ } ++ ++static void ++cleanup_pam (int retcode) ++{ ++ if (_pam_session_opened) ++ pam_close_session (pamh, 0); ++ ++ if (_pam_cred_established) ++ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); ++ ++ pam_end(pamh, retcode); ++} ++ ++/* Signal handler for parent process. */ ++static void ++su_catch_sig (int sig) ++{ ++ caught_signal = true; ++} ++ ++/* Export env variables declared by PAM modules. */ ++static void ++export_pamenv (void) ++{ ++ char **env; ++ ++ /* This is a copy but don't care to free as we exec later anyways. */ ++ env = pam_getenvlist (pamh); ++ while (env && *env) ++ { ++ if (putenv (*env) != 0) ++ xalloc_die (); ++ env++; ++ } ++} ++ ++static void ++create_watching_parent (void) ++{ ++ pid_t child; ++ sigset_t ourset; ++ int status = 0; ++ ++ retval = pam_open_session (pamh, 0); ++ if (retval != PAM_SUCCESS) ++ { ++ cleanup_pam (retval); ++ error (EXIT_FAILURE, 0, _("cannot not open session: %s"), ++ pam_strerror (pamh, retval)); ++ } ++ else ++ _pam_session_opened = 1; ++ ++ child = fork (); ++ if (child == (pid_t) -1) ++ { ++ cleanup_pam (PAM_ABORT); ++ error (EXIT_FAILURE, errno, _("cannot create child process")); ++ } ++ ++ /* the child proceeds to run the shell */ ++ if (child == 0) ++ return; ++ ++ /* In the parent watch the child. */ ++ ++ /* su without pam support does not have a helper that keeps ++ sitting on any directory so let's go to /. */ ++ if (chdir ("/") != 0) ++ error (0, errno, _("warning: cannot change directory to %s"), "/"); ++ ++ sigfillset (&ourset); ++ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) ++ { ++ error (0, errno, _("cannot block signals")); ++ caught_signal = true; ++ } ++ if (!caught_signal) ++ { ++ struct sigaction action; ++ action.sa_handler = su_catch_sig; ++ sigemptyset (&action.sa_mask); ++ action.sa_flags = 0; ++ sigemptyset (&ourset); ++ ++ if (!same_session) ++ { ++ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) ++ { ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; ++ } ++ } ++ if (!caught_signal && (sigaddset(&ourset, SIGTERM) ++ || sigaddset(&ourset, SIGALRM) ++ || sigaction(SIGTERM, &action, NULL) ++ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) ++ { ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; ++ } ++ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) ++ || sigaction(SIGQUIT, &action, NULL))) ++ { ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; ++ } ++ } ++ if (!caught_signal) ++ { ++ pid_t pid; ++ for (;;) ++ { ++ pid = waitpid (child, &status, WUNTRACED); ++ ++ if (pid != (pid_t)-1 && WIFSTOPPED (status)) ++ { ++ kill (getpid (), SIGSTOP); ++ /* once we get here, we must have resumed */ ++ kill (pid, SIGCONT); ++ } ++ else ++ break; ++ } ++ if (pid != (pid_t)-1) ++ if (WIFSIGNALED (status)) ++ status = WTERMSIG (status) + 128; ++ else ++ status = WEXITSTATUS (status); ++ else ++ status = 1; ++ } ++ else ++ status = 1; ++ ++ if (caught_signal) ++ { ++ fprintf (stderr, _("\nSession terminated, killing shell...")); ++ kill (child, SIGTERM); ++ } ++ ++ cleanup_pam (PAM_SUCCESS); ++ ++ if (caught_signal) ++ { ++ sleep (2); ++ kill (child, SIGKILL); ++ fprintf (stderr, _(" ...killed.\n")); ++ } ++ exit (status); ++} ++#endif ++ ++/* Ask the user for a password. ++ If PAM is in use, let PAM ask for the password if necessary. ++ Return true if the user gives the correct password for entry PW, ++ false if not. Return true without asking for a password if run by UID 0 ++ or if PW has an empty password. */ ++ ++static bool ++correct_password (const struct passwd *pw) ++{ ++#ifdef USE_PAM ++ const struct passwd *lpw; ++ const char *cp; ++ ++ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME, ++ pw->pw_name, &conv, &pamh); ++ PAM_BAIL_P (return false); ++ ++ if (isatty (0) && (cp = ttyname (0)) != NULL) ++ { ++ const char *tty; ++ ++ if (strncmp (cp, "/dev/", 5) == 0) ++ tty = cp + 5; ++ else ++ tty = cp; ++ retval = pam_set_item (pamh, PAM_TTY, tty); ++ PAM_BAIL_P (return false); ++ } ++#if 0 /* Manpage discourages use of getlogin. */ ++ cp = getlogin (); ++ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ())) ++#endif ++ lpw = getpwuid (getuid ()); ++ if (lpw && lpw->pw_name) ++ { ++ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); ++ PAM_BAIL_P (return false); ++ } ++ retval = pam_authenticate (pamh, 0); ++ PAM_BAIL_P (return false); ++ retval = pam_acct_mgmt (pamh, 0); ++ if (retval == PAM_NEW_AUTHTOK_REQD) ++ { ++ /* Password has expired. Offer option to change it. */ ++ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); ++ PAM_BAIL_P (return false); ++ } ++ PAM_BAIL_P (return false); ++ /* Must be authenticated if this point was reached. */ ++ return true; ++#else /* !USE_PAM */ ++ char *unencrypted, *encrypted, *correct; ++#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP ++ /* Shadow passwd stuff for SVR3 and maybe other systems. */ ++ const struct spwd *sp = getspnam (pw->pw_name); ++ ++ endspent (); ++ if (sp) ++ correct = sp->sp_pwdp; ++ else ++#endif ++ correct = pw->pw_passwd; ++ ++ if (getuid () == 0 || !correct || correct[0] == '\0') ++ return true; ++ ++ unencrypted = getpass (_("Password:")); ++ if (!unencrypted) ++ { ++ error (0, 0, _("getpass: cannot open /dev/tty")); ++ return false; ++ } ++ encrypted = crypt (unencrypted, correct); ++ memset (unencrypted, 0, strlen (unencrypted)); ++ return STREQ (encrypted, correct); ++#endif /* !USE_PAM */ ++} ++ ++/* Add or clear /sbin and /usr/sbin for the su command ++ used without `-'. */ ++ ++/* Set if /sbin is found in path. */ ++#define SBIN_MASK 0x01 ++/* Set if /usr/sbin is found in path. */ ++#define USBIN_MASK 0x02 ++ ++static char * ++addsbin (const char *const path) ++{ ++ unsigned char smask = 0; ++ char *ptr, *tmp, *cur, *ret = NULL; ++ size_t len; ++ ++ if (!path || *path == 0) ++ return NULL; ++ ++ tmp = xstrdup (path); ++ cur = tmp; ++ for (ptr = strsep (&cur, ":"); ptr != NULL; ptr = strsep (&cur, ":")) ++ { ++ if (!strcmp (ptr, "/sbin")) ++ smask |= SBIN_MASK; ++ if (!strcmp (ptr, "/usr/sbin")) ++ smask |= USBIN_MASK; ++ } ++ ++ if ((smask & (USBIN_MASK|SBIN_MASK)) == (USBIN_MASK|SBIN_MASK)) ++ { ++ free (tmp); ++ return NULL; ++ } ++ ++ len = strlen (path); ++ if (!(smask & USBIN_MASK)) ++ len += strlen ("/usr/sbin:"); ++ ++ if (!(smask & SBIN_MASK)) ++ len += strlen (":/sbin"); ++ ++ ret = xmalloc (len + 1); ++ strcpy (tmp, path); ++ ++ *ret = 0; ++ cur = tmp; ++ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) ++ { ++ if (!strcmp (ptr, ".")) ++ continue; ++ if (*ret) ++ strcat (ret, ":"); ++ if (!(smask & USBIN_MASK) && !strcmp (ptr, "/bin")) ++ { ++ strcat (ret, "/usr/sbin:"); ++ strcat (ret, ptr); ++ smask |= USBIN_MASK; ++ continue; ++ } ++ if (!(smask & SBIN_MASK) && !strcmp (ptr, "/usr/bin")) ++ { ++ strcat (ret, ptr); ++ strcat (ret, ":/sbin"); ++ smask |= SBIN_MASK; ++ continue; ++ } ++ strcat (ret, ptr); ++ } ++ free (tmp); ++ ++ if (!(smask & USBIN_MASK)) ++ strcat (ret, ":/usr/sbin"); ++ ++ if (!(smask & SBIN_MASK)) ++ strcat (ret, ":/sbin"); ++ ++ return ret; ++} ++ ++static char * ++clearsbin (const char *const path) ++{ ++ char *ptr, *tmp, *cur, *ret = NULL; ++ ++ if (!path || *path == 0) ++ return NULL; ++ ++ tmp = strdup (path); ++ if (!tmp) ++ return NULL; ++ ++ ret = xmalloc (strlen (path) + 1); ++ *ret = 0; ++ cur = tmp; ++ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) ++ { ++ if (!strcmp (ptr, "/sbin")) ++ continue; ++ if (!strcmp (ptr, "/usr/sbin")) ++ continue; ++ if (!strcmp (ptr, "/usr/local/sbin")) ++ continue; ++ if (*ret) ++ strcat (ret, ":"); ++ strcat (ret, ptr); ++ } ++ free (tmp); ++ ++ return ret; ++} ++ ++/* Update 'environ' for the new shell based on PW, with SHELL being ++ the value for the SHELL environment variable. */ ++ ++static void ++modify_environment (const struct passwd *pw, const char *shell) ++{ ++ if (simulate_login) ++ { ++ /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. ++ Unset all other environment variables. */ ++ char const *term = getenv ("TERM"); ++ if (term) ++ term = xstrdup (term); ++ environ = xmalloc ((6 + !!term) * sizeof (char *)); ++ environ[0] = NULL; ++ if (term) ++ xsetenv ("TERM", term); ++ xsetenv ("HOME", pw->pw_dir); ++ xsetenv ("SHELL", shell); ++ xsetenv ("USER", pw->pw_name); ++ xsetenv ("LOGNAME", pw->pw_name); ++ xsetenv ("PATH", (pw->pw_uid ++ ? getdef_str ("PATH", DEFAULT_LOGIN_PATH) ++ : getdef_str ("SUPATH", DEFAULT_ROOT_LOGIN_PATH))); ++ } ++ else ++ { ++ /* Set HOME, SHELL, and if not becoming a super-user, ++ USER and LOGNAME. */ ++ if (change_environment) ++ { ++ xsetenv ("HOME", pw->pw_dir); ++ xsetenv ("SHELL", shell); ++ if (getdef_bool ("ALWAYS_SET_PATH", 0)) ++ xsetenv ("PATH", (pw->pw_uid ++ ? getdef_str ("PATH", ++ DEFAULT_LOGIN_PATH) ++ : getdef_str ("SUPATH", ++ DEFAULT_ROOT_LOGIN_PATH))); ++ else ++ { ++ char const *path = getenv ("PATH"); ++ char *new = NULL; ++ ++ if (pw->pw_uid) ++ new = clearsbin (path); ++ else ++ new = addsbin (path); ++ ++ if (new) ++ { ++ xsetenv ("PATH", new); ++ free (new); ++ } ++ } ++ if (pw->pw_uid) ++ { ++ xsetenv ("USER", pw->pw_name); ++ xsetenv ("LOGNAME", pw->pw_name); ++ } ++ } ++ } ++ ++#ifdef USE_PAM ++ export_pamenv (); ++#endif ++} ++ ++/* Become the user and group(s) specified by PW. */ ++ ++static void ++init_groups (const struct passwd *pw) ++{ ++#ifdef HAVE_INITGROUPS ++ errno = 0; ++ if (initgroups (pw->pw_name, pw->pw_gid) == -1) ++ { ++#ifdef USE_PAM ++ cleanup_pam (PAM_ABORT); ++#endif ++ error (EXIT_FAILURE, errno, _("cannot set groups")); ++ } ++ endgrent (); ++#endif ++ ++#ifdef USE_PAM ++ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); ++ if (retval != PAM_SUCCESS) ++ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval)); ++ else ++ _pam_cred_established = 1; ++#endif ++} ++ ++static void ++change_identity (const struct passwd *pw) ++{ ++ if (setgid (pw->pw_gid)) ++ error (EXIT_CANCELED, errno, _("cannot set group id")); ++ if (setuid (pw->pw_uid)) ++ error (EXIT_CANCELED, errno, _("cannot set user id")); ++} ++ ++/* Run SHELL, or DEFAULT_SHELL if SHELL is empty. ++ If COMMAND is nonzero, pass it to the shell with the -c option. ++ Pass ADDITIONAL_ARGS to the shell as more arguments; there ++ are N_ADDITIONAL_ARGS extra arguments. */ ++ ++static void ++run_shell (char const *shell, char const *command, char **additional_args, ++ size_t n_additional_args) ++{ ++ size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; ++ char const **args = xnmalloc (n_args, sizeof *args); ++ size_t argno = 1; ++ ++ if (simulate_login) ++ { ++ char *arg0; ++ char *shell_basename; ++ ++ shell_basename = last_component (shell); ++ arg0 = xmalloc (strlen (shell_basename) + 2); ++ arg0[0] = '-'; ++ strcpy (arg0 + 1, shell_basename); ++ args[0] = arg0; ++ } ++ else ++ args[0] = last_component (shell); ++ if (fast_startup) ++ args[argno++] = "-f"; ++ if (command) ++ { ++ args[argno++] = "-c"; ++ args[argno++] = command; ++ } ++ memcpy (args + argno, additional_args, n_additional_args * sizeof *args); ++ args[argno + n_additional_args] = NULL; ++ execv (shell, (char **) args); ++ ++ { ++ int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); ++ error (0, errno, "%s", shell); ++ exit (exit_status); ++ } ++} ++ ++/* Return true if SHELL is a restricted shell (one not returned by ++ getusershell), else false, meaning it is a standard shell. */ ++ ++static bool ++restricted_shell (const char *shell) ++{ ++ char *line; ++ ++ setusershell (); ++ while ((line = getusershell ()) != NULL) ++ { ++ if (*line != '#' && STREQ (line, shell)) ++ { ++ endusershell (); ++ return false; ++ } ++ } ++ endusershell (); ++ return true; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ emit_try_help (); ++ else ++ { ++ printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); ++ fputs (_("\ ++Change the effective user id and group id to that of USER.\n\ ++\n\ ++ -, -l, --login make the shell a login shell\n\ ++ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ ++ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\ ++ and do not create a new session\n\ ++ -f, --fast pass -f to the shell (for csh or tcsh)\n\ ++ -m, --preserve-environment do not reset environment variables\n\ ++ -p same as -m\n\ ++ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++A mere - implies -l. If USER not given, assume root.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int optc; ++ const char *new_user = DEFAULT_USER; ++ char *command = NULL; ++ int request_same_session = 0; ++ char *shell = NULL; ++ struct passwd *pw; ++ struct passwd pw_copy; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ initialize_exit_failure (EXIT_CANCELED); ++ atexit (close_stdout); ++ ++ fast_startup = false; ++ simulate_login = false; ++ change_environment = true; ++ ++ while ((optc = getopt_long (argc, argv, "c:C:flmps:", longopts, NULL)) != -1) ++ { ++ switch (optc) ++ { ++ case 'c': ++ command = optarg; ++ if (NULL != getenv ("SU_COMMAND_SAME_SESSION") || ++ NULL != getenv ("SU_COMMAND_OPENS_SESSION")) ++ request_same_session = 1; ++ break; ++ ++ case 'C': ++ command = optarg; ++ request_same_session = 1; ++ break; ++ ++ case 'f': ++ fast_startup = true; ++ break; ++ ++ case 'l': ++ simulate_login = true; ++ break; ++ ++ case 'm': ++ case 'p': ++ change_environment = false; ++ break; ++ ++ case 's': ++ shell = optarg; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_CANCELED); ++ } ++ } ++ ++ if (optind < argc && STREQ (argv[optind], "-")) ++ { ++ simulate_login = true; ++ ++optind; ++ } ++ if (optind < argc) ++ new_user = argv[optind++]; ++ ++ pw = getpwnam (new_user); ++ if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0] ++ && pw->pw_passwd)) ++ error (EXIT_CANCELED, 0, _("user %s does not exist"), new_user); ++ ++ /* Make a copy of the password information and point pw at the local ++ copy instead. Otherwise, some systems (e.g. GNU/Linux) would clobber ++ the static data through the getlogin call from log_su. ++ Also, make sure pw->pw_shell is a nonempty string. ++ It may be NULL when NEW_USER is a username that is retrieved via NIS (YP), ++ but that doesn't have a default shell listed. */ ++ pw_copy = *pw; ++ pw = &pw_copy; ++ pw->pw_name = xstrdup (pw->pw_name); ++ pw->pw_passwd = xstrdup (pw->pw_passwd); ++ pw->pw_dir = xstrdup (pw->pw_dir); ++ pw->pw_shell = xstrdup (pw->pw_shell && pw->pw_shell[0] ++ ? pw->pw_shell ++ : DEFAULT_SHELL); ++ endpwent (); ++ ++ if (!correct_password (pw)) ++ { ++#ifdef SYSLOG_FAILURE ++ log_su (pw, false); ++#endif ++ sleep (getdef_num ("FAIL_DELAY", 1)); ++ error (EXIT_CANCELED, 0, _("incorrect password")); ++ } ++#ifdef SYSLOG_SUCCESS ++ else ++ { ++ log_su (pw, true); ++ } ++#endif ++ ++ if (request_same_session || !command || !pw->pw_uid) ++ same_session = 1; ++ ++ if (!shell && !change_environment) ++ shell = getenv ("SHELL"); ++ if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) ++ { ++ /* The user being su'd to has a nonstandard shell, and so is ++ probably a uucp account or has restricted access. Don't ++ compromise the account by allowing access with a standard ++ shell. */ ++ error (0, 0, _("using restricted shell %s"), pw->pw_shell); ++ shell = NULL; ++ } ++ shell = xstrdup (shell ? shell : pw->pw_shell); ++ ++ init_groups (pw); ++ ++#ifdef USE_PAM ++ create_watching_parent (); ++ /* Now we're in the child. */ ++#endif ++ ++ change_identity (pw); ++ ++ if (!same_session) ++ setsid (); ++ ++ /* Set environment after pam_open_session, which may put KRB5CCNAME ++ into the pam_env, etc. */ ++ ++ modify_environment (pw, shell); ++ ++ if (simulate_login && chdir (pw->pw_dir) != 0) ++ error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); ++ ++ /* error() flushes stderr, but does not check for write failure. ++ Normally, we would catch this via our atexit() hook of ++ close_stdout, but execv() gets in the way. If stderr ++ encountered a write failure, there is no need to try calling ++ error() again. */ ++ if (ferror (stderr)) ++ exit (EXIT_CANCELED); ++ ++ run_shell (shell, command, argv + optind, MAX (0, argc - optind)); ++} +Index: src/getdef.h +=================================================================== +--- /dev/null ++++ src/getdef.h +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2003, 2005 Thorsten Kukuk ++ Author: Thorsten Kukuk ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 or ++ later published by the Free Software Foundation. ++ ++ 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, write to the Free Software Foundation, ++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#ifndef _GETDEF_H_ ++ ++#define _GETDEF_H_ 1 ++ ++extern int getdef_bool (const char *name, int dflt); ++extern long getdef_num (const char *name, long dflt); ++extern unsigned long getdef_unum (const char *name, unsigned long dflt); ++extern const char *getdef_str (const char *name, const char *dflt); ++ ++/* Free all data allocated by getdef_* calls before. */ ++extern void free_getdef_data (void); ++ ++#endif /* _GETDEF_H_ */ +Index: src/getdef.c +=================================================================== +--- /dev/null ++++ src/getdef.c +@@ -0,0 +1,259 @@ ++/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk ++ Author: Thorsten Kukuk ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 or ++ later as published by the Free Software Foundation. ++ ++ 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, write to the Free Software Foundation, ++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "getdef.h" ++ ++struct item { ++ char *name; /* Name of the option. */ ++ char *value; /* Value of the option. */ ++ struct item *next; /* Pointer to next option. */ ++}; ++ ++static struct item *list = NULL; ++ ++void ++free_getdef_data (void) ++{ ++ struct item *ptr; ++ ++ ptr = list; ++ while (ptr != NULL) ++ { ++ struct item *tmp; ++ tmp = ptr->next; ++ free (ptr->name); ++ free (ptr->value); ++ free (ptr); ++ ptr = tmp; ++ } ++ ++ list = NULL; ++} ++ ++/* Add a new entry to the list. */ ++static void ++store (const char *name, const char *value) ++{ ++ struct item *new = malloc (sizeof (struct item)); ++ ++ if (new == NULL) ++ abort (); ++ ++ if (name == NULL) ++ abort (); ++ ++ new->name = strdup (name); ++ new->value = strdup (value ?: ""); ++ new->next = list; ++ list = new; ++} ++ ++/* Search a special entry in the list and return the value. */ ++static const char * ++search (const char *name) ++{ ++ struct item *ptr; ++ ++ ptr = list; ++ while (ptr != NULL) ++ { ++ if (strcasecmp (name, ptr->name) == 0) ++ return ptr->value; ++ ptr = ptr->next; ++ } ++ ++ return NULL; ++} ++ ++/* Load the login.defs file (/etc/login.defs). */ ++static void ++load_defaults_internal (const char *filename) ++{ ++ FILE *fp; ++ char *buf = NULL; ++ size_t buflen = 0; ++ ++ fp = fopen (filename, "r"); ++ if (NULL == fp) ++ return; ++ ++ while (!feof (fp)) ++ { ++ char *tmp, *cp; ++#if defined(HAVE_GETLINE) ++ ssize_t n = getline (&buf, &buflen, fp); ++#elif defined (HAVE_GETDELIM) ++ ssize_t n = getdelim (&buf, &buflen, '\n', fp); ++#else ++ ssize_t n; ++ ++ if (buf == NULL) ++ { ++ buflen = 8096; ++ buf = malloc (buflen); ++ } ++ buf[0] = '\0'; ++ fgets (buf, buflen - 1, fp); ++ if (buf != NULL) ++ n = strlen (buf); ++ else ++ n = 0; ++#endif /* HAVE_GETLINE / HAVE_GETDELIM */ ++ cp = buf; ++ ++ if (n < 1) ++ break; ++ ++ tmp = strchr (cp, '#'); /* remove comments */ ++ if (tmp) ++ *tmp = '\0'; ++ while (isspace ((unsigned char) *cp)) /* remove spaces and tabs */ ++ ++cp; ++ if (*cp == '\0') /* ignore empty lines */ ++ continue; ++ ++ if (cp[strlen (cp) - 1] == '\n') ++ cp[strlen (cp) - 1] = '\0'; ++ ++ tmp = strsep (&cp, " \t="); ++ if (cp != NULL) ++ while (isspace ((unsigned char) *cp) || *cp == '=') ++ ++cp; ++ ++ store (tmp, cp); ++ } ++ fclose (fp); ++ ++ if (buf) ++ free (buf); ++} ++ ++static void ++load_defaults (void) ++{ ++ load_defaults_internal ("/etc/default/su"); ++ load_defaults_internal ("/etc/login.defs"); ++} ++ ++int ++getdef_bool (const char *name, int dflt) ++{ ++ const char *val; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ return (strcasecmp (val, "yes") == 0); ++} ++ ++long ++getdef_num (const char *name, long dflt) ++{ ++ const char *val; ++ char *cp; ++ long retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ errno = 0; ++ retval = strtol (val, &cp, 0); ++ if (*cp != '\0' ++ || ((retval == LONG_MAX || retval == LONG_MIN) && errno == ERANGE)) ++ { ++ fprintf (stderr, ++ "%s contains invalid numerical value: %s!\n", ++ name, val); ++ retval = dflt; ++ } ++ return retval; ++} ++ ++unsigned long ++getdef_unum (const char *name, unsigned long dflt) ++{ ++ const char *val; ++ char *cp; ++ unsigned long retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ errno = 0; ++ retval = strtoul (val, &cp, 0); ++ if (*cp != '\0' || (retval == ULONG_MAX && errno == ERANGE)) ++ { ++ fprintf (stderr, ++ "%s contains invalid numerical value: %s!\n", ++ name, val); ++ retval = dflt; ++ } ++ return retval; ++} ++ ++const char * ++getdef_str (const char *name, const char *dflt) ++{ ++ const char *retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ retval = search (name); ++ ++ return retval ?: dflt; ++} ++ ++#if defined(TEST) ++ ++int ++main () ++{ ++ printf ("CYPT=%s\n", getdef_str ("cRypt", "no")); ++ printf ("LOG_UNKFAIL_ENAB=%s\n", getdef_str ("log_unkfail_enab","")); ++ printf ("DOESNOTEXIST=%s\n", getdef_str ("DOESNOTEXIST","yes")); ++ return 0; ++} ++ ++#endif +Index: doc/coreutils.texi +=================================================================== +--- doc/coreutils.texi.orig ++++ doc/coreutils.texi +@@ -109,6 +109,7 @@ + * stat: (coreutils)stat invocation. Report file(system) status. + * stdbuf: (coreutils)stdbuf invocation. Modify stdio buffering. + * stty: (coreutils)stty invocation. Print/change terminal settings. ++* su: (coreutils)su invocation. Modify user and group ID. + * sum: (coreutils)sum invocation. Print traditional checksum. + * sync: (coreutils)sync invocation. Synchronize memory and disk. + * tac: (coreutils)tac invocation. Reverse files. +@@ -199,7 +200,7 @@ Free Documentation License''. + * User information:: id logname whoami groups users who + * System context:: date arch nproc uname hostid uptime + * SELinux context:: chcon runcon +-* Modified command invocation:: chroot env nice nohup stdbuf timeout ++* Modified command invocation:: chroot env nice nohup stdbuf su timeout + * Process control:: kill + * Delaying:: sleep + * Numeric operations:: factor seq +@@ -444,6 +445,7 @@ Modified command invocation + * nice invocation:: Run a command with modified niceness + * nohup invocation:: Run a command immune to hangups + * stdbuf invocation:: Run a command with modified I/O buffering ++* su invocation:: Run a command with substitute user and group ID + * timeout invocation:: Run a command with a time limit + + Process control +@@ -767,7 +769,8 @@ meanings with the values @samp{0} and @s + Here are some of the exceptions: + @command{chroot}, @command{env}, @command{expr}, @command{nice}, + @command{nohup}, @command{numfmt}, @command{printenv}, @command{sort}, +-@command{stdbuf}, @command{test}, @command{timeout}, @command{tty}. ++@command{su}, @command{stdbuf}, @command{test}, @command{timeout}, ++@command{tty}. + + + @node Backup options +@@ -15762,6 +15765,7 @@ user, etc. + * nice invocation:: Modify niceness. + * nohup invocation:: Immunize to hangups. + * stdbuf invocation:: Modify buffering of standard streams. ++* su invocation:: Modify user and group ID. + * timeout invocation:: Run with time limit. + @end menu + +@@ -16293,6 +16297,149 @@ the exit status of @var{command} otherwi + @end display + + ++@node su invocation ++@section @command{su}: Run a command with substitute user and group ID ++ ++@pindex su ++@cindex substitute user and group IDs ++@cindex user ID, switching ++@cindex super-user, becoming ++@cindex root, becoming ++ ++@command{su} allows one user to temporarily become another user. It runs a ++command (often an interactive shell) with the real and effective user ++ID, group ID, and supplemental groups of a given @var{user}. Synopsis: ++ ++@example ++su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] ++@end example ++ ++@cindex passwd entry, and @command{su} shell ++@flindex /bin/sh ++@flindex /etc/passwd ++If no @var{user} is given, the default is @code{root}, the super-user. ++The shell to use is taken from @var{user}'s @code{passwd} entry, or ++@file{/bin/sh} if none is specified there. If @var{user} has a ++password, @command{su} prompts for the password unless run by a user with ++effective user ID of zero (the super-user). ++ ++@vindex HOME ++@vindex SHELL ++@vindex USER ++@vindex LOGNAME ++@cindex login shell ++By default, @command{su} does not change the current directory. ++It sets the environment variables @env{HOME} and @env{SHELL} ++from the password entry for @var{user}, and if @var{user} is not ++the super-user, sets @env{USER} and @env{LOGNAME} to @var{user}. ++By default, the shell is not a login shell. ++ ++Any additional @var{arg}s are passed as additional arguments to the ++shell. ++ ++@cindex @option{-su} ++GNU @command{su} does not treat @file{/bin/sh} or any other shells specially ++(e.g., by setting @code{argv[0]} to @option{-su}, passing @option{-c} only ++to certain shells, etc.). ++ ++@findex syslog ++@command{su} can optionally be compiled to use @code{syslog} to report ++failed, and optionally successful, @command{su} attempts. (If the system ++supports @code{syslog}.) ++ ++This version of @command{su} has support for using PAM for ++authentication. You can edit @file{/etc/pam.d/su} resp @file{/etc/pam.d/su-l} ++to customize its behaviour. ++ ++If the environment variable SU_COMMAND_SAME_SESSION is set, @command{su} su will ++not open a new session for running a command thus making @option{-c} behaves ++just like @option{--session-command}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -c @var{command} ++@itemx --command=@var{command} ++@opindex -c ++@opindex --command ++Pass @var{command}, a single command line to run, to the shell with ++a @option{-c} option instead of starting an interactive shell. ++ ++@itemx --session-command=@var{command} ++@opindex --session-command ++Pass @var{command}, a single command line to run, to the shell with a ++@option{-c} option instead of starting an interactive and do not create ++a new session for it. ++ ++@item -f ++@itemx --fast ++@opindex -f ++@opindex --fast ++@flindex .cshrc ++@cindex file name pattern expansion, disabled ++@cindex globbing, disabled ++Pass the @option{-f} option to the shell. This probably only makes sense ++if the shell run is @command{csh} or @command{tcsh}, for which the @option{-f} ++option prevents reading the startup file (@file{.cshrc}). With ++Bourne-like shells, the @option{-f} option disables file name pattern ++expansion (globbing), which is not likely to be useful. ++ ++@item - ++@itemx -l ++@itemx --login ++@opindex - ++@opindex -l ++@opindex --login ++@c other variables already indexed above ++@vindex TERM ++@vindex PATH ++@cindex login shell, creating ++Make the shell a login shell. This means the following. Unset all ++environment variables except @env{TERM}, @env{HOME}, and @env{SHELL} ++(which are set as described above), and @env{USER} and @env{LOGNAME} ++(which are set, even for the super-user, as described above), and set ++@env{PATH} to a compiled-in default value. Change to @var{user}'s home ++directory. Prepend @samp{-} to the shell's name, intended to make it ++read its login startup file(s). ++ ++@item -m ++@itemx -p ++@itemx --preserve-environment ++@opindex -m ++@opindex -p ++@opindex --preserve-environment ++@cindex environment, preserving ++@flindex /etc/shells ++@cindex restricted shell ++Do not change the environment variables @env{HOME}, @env{USER}, ++@env{LOGNAME}, or @env{SHELL}. Run the shell given in the environment ++variable @env{SHELL} instead of the shell from @var{user}'s passwd ++entry, unless the user running @command{su} is not the super-user and ++@var{user}'s shell is restricted. A @dfn{restricted shell} is one that ++is not listed in the file @file{/etc/shells}, or in a compiled-in list ++if that file does not exist. Parts of what this option does can be ++overridden by @option{--login} and @option{--shell}. ++ ++@item -s @var{shell} ++@itemx --shell=@var{shell} ++@opindex -s ++@opindex --shell ++Run @var{shell} instead of the shell from @var{user}'s passwd entry, ++unless the user running @command{su} is not the super-user and @var{user}'s ++shell is restricted (see @option{-m} just above). ++ ++@end table ++ ++@cindex exit status of @command{su} ++Exit status: ++ ++@display ++125 if @command{su} itself fails ++126 if subshell is found but cannot be invoked ++127 if subshell cannot be found ++the exit status of the subshell otherwise ++@end display ++ + @node timeout invocation + @section @command{timeout}: Run a command with a time limit + +Index: man/local.mk +=================================================================== +--- man/local.mk.orig ++++ man/local.mk +@@ -26,6 +26,7 @@ run_help2man = $(SHELL) $(srcdir)/man/du + endif + + man1_MANS = @man1_MANS@ ++man1_MANS += man/su.1 + EXTRA_DIST += $(man1_MANS:.1=.x) + + EXTRA_MANS = @EXTRA_MANS@ +@@ -144,6 +145,7 @@ man/split.1: src/split + man/stat.1: src/stat + man/stdbuf.1: src/stdbuf + man/stty.1: src/stty ++man/su.1: src/su + man/sum.1: src/sum + man/sync.1: src/sync + man/tac.1: src/tac +Index: man/su.x +=================================================================== +--- /dev/null ++++ man/su.x +@@ -0,0 +1,4 @@ ++[NAME] ++su \- run a shell with substitute user and group IDs ++[DESCRIPTION] ++.\" Add any additional description here +Index: tests/misc/su-fail.sh +=================================================================== +--- /dev/null ++++ tests/misc/su-fail.sh +@@ -0,0 +1,30 @@ ++#!/bin/sh ++# Test su failure cases ++ ++# Copyright (C) 2009-2012 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ su ++ ++#require_built_ su ++ ++# Very little that we can test without a root password ++su --- / true # unknown option ++test $? = 125 || fail=1 ++su no_such_user ++test $? = 125 || fail=1 ++ ++Exit $fail +Index: tests/local.mk +=================================================================== +--- tests/local.mk.orig ++++ tests/local.mk +@@ -361,6 +361,7 @@ all_tests = \ + tests/misc/stty-invalid.sh \ + tests/misc/stty-pairs.sh \ + tests/misc/stty-row-col.sh \ ++ tests/misc/su-fail.sh \ + tests/misc/sum.pl \ + tests/misc/sum-sysv.sh \ + tests/misc/tac.pl \ +Index: po/coreutils.pot +=================================================================== +--- po/coreutils.pot.orig ++++ po/coreutils.pot +@@ -8461,6 +8461,73 @@ msgstr "" + msgid "invalid integer argument %s" + msgstr "" + ++#: src/su.c:229 ++msgid "Password:" ++msgstr "" ++ ++#: src/su.c:232 ++#, c-format ++msgid "getpass: cannot open /dev/tty" ++msgstr "" ++ ++#: src/su.c:290 ++#, c-format ++msgid "cannot set groups" ++msgstr "" ++ ++#: src/su.c:294 ++#, c-format ++msgid "cannot set group id" ++msgstr "" ++ ++#: src/su.c:296 ++#, c-format ++msgid "cannot set user id" ++msgstr "" ++ ++#: src/su.c:371 ++#, c-format ++msgid "Usage: %s [OPTION]... [-] [USER [ARG]...]\n" ++msgstr "" ++ ++#: src/su.c:372 ++msgid "" ++"Change the effective user id and group id to that of USER.\n" ++"\n" ++" -, -l, --login make the shell a login shell\n" ++" -c, --command=COMMAND pass a single COMMAND to the shell with -c\n" ++" -f, --fast pass -f to the shell (for csh or tcsh)\n" ++" -m, --preserve-environment do not reset environment variables\n" ++" -p same as -m\n" ++" -s, --shell=SHELL run SHELL if /etc/shells allows it\n" ++msgstr "" ++ ++#: src/su.c:384 ++msgid "" ++"\n" ++"A mere - implies -l. If USER not given, assume root.\n" ++msgstr "" ++ ++#: src/su.c:461 ++#, c-format ++msgid "user %s does not exist" ++msgstr "" ++ ++#: src/su.c:484 ++#, c-format ++msgid "incorrect password" ++msgstr "" ++ ++#: src/su.c:501 ++#, c-format ++msgid "using restricted shell %s" ++msgstr "" ++ ++#: src/su.c:509 ++#, c-format ++msgid "warning: cannot change directory to %s" ++msgstr "" ++ + #. This is a proper name. See the gettext manual, section Names. + #: src/sum.c:37 + msgid "Kayvan Aghaiepour" +Index: README +=================================================================== +--- README.orig ++++ README +@@ -13,7 +13,7 @@ The programs that can be built with this + link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup + nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink + realpath rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum +- shred shuf sleep sort split stat stdbuf stty sum sync tac tail tee test ++ shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test + timeout touch tr true truncate tsort tty uname unexpand uniq unlink + uptime users vdir wc who whoami yes + diff --git a/coreutils-testsuite.changes b/coreutils-testsuite.changes index 17a603c..e0661a6 100644 --- a/coreutils-testsuite.changes +++ b/coreutils-testsuite.changes @@ -1,9 +1,419 @@ ------------------------------------------------------------------- -Thu Mar 21 11:55:32 UTC 2013 - mmeister@suse.com +Thu Apr 4 23:25:17 UTC 2013 - mail@bernhard-voelker.de + +- Fix source url for coreutils-testsuite. + +------------------------------------------------------------------- +Thu Mar 21 11:55:13 UTC 2013 - mmeister@suse.com - Added url as source. Please see http://en.opensuse.org/SourceUrls +------------------------------------------------------------------- +Thu Mar 21 11:54:05 UTC 2013 - mail@bernhard-voelker.de + +- Fix multibyte issue in unexpand (rh#821262) + (coreutils-i18n.patch: patch by Roman Kollár ) + +- Fix cut to terminate mbdelim string + + Otherwise, cut might do an unbounded strdup of the delimiter string + in i18n mode (https://bugzilla.redhat.com/show_bug.cgi?id=911929) + (coreutils-i18n.patch, from Mark Wielaard ) + +- Add su(1) again + + Now, su(1) will be provided via a symlink trick + to the file installed with a ".core" suffix. + By this, we can upgrade to 8.21 without having to wait + for a util-linux version providing it. + + * coreutils-su.patch: Add cumulative su patch from previous Base:System + version 8.17, ported to 8.21 build structure. This supersedes the + following partial patches: + coreutils-8.6-compile-su-with-fpie.diff, + coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff, + coreutils-8.6-log-all-su-attempts.diff, + coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff, + coreutils-8.6-pam-support-for-su.diff, + coreutils-8.6-set-sane-default-path.diff, + coreutils-8.6-update-man-page-for-pam.diff, + coreutils-bnc#697897-setsid.patch. + + * pam, pam-devel: Add as requirements, also during build. + * coreutils.spec (%description): Clarify that su is included although removed + upstreams. + (%install): Install su+kill files with suffix ".core". + (%post): Move setting permissions on su from %posttrans to %install. + (%posttrans): Create symlinks to files with ".core" suffix unless already + existing. + +- Install kill(1) with the same symlink trick. + +- Remove now-obsolete patches and files: + + * coreutils-8.17.de.po.xz: + * coreutils-8.17.tar.xz: + Remove sources + translation of previous version + + * coreutils-acl-nofollow.patch: + * coreutils-basename_documentation.patch: + * coreutils-cp-corrupt-fragmented-sparse.patch: + * coreutils-df-always-hide-rootfs.patch: + * coreutils-skip-du-slink-test.patch: + Fixed upstream. + + * coreutils-getaddrinfo.patch: + * coreutils-misc.patch: + * coreutils-no_silent-rule.patch: + Remove test and build related patches. + + * coreutils-ptr_int_casts.patch: + Remove because merged into coreutils-i18n.patch. + +- Add files: + + * coreutils-8.21.tar.xz: + Add tarball of the new upstream version + * coreutils-8.21.de.po.xz: + Add language file. + +- Update patches: + + * coreutils-i18n.patch + Merge some Fedora changes to keep the i18n patch like theirs. + Fix and cleanup sort's multibyte test with incorporated test data. + + * coreutils-remove_hostname_documentation.patch + +- Add patch to build 'timeout' as PIE (OBS requires it). + This patch actually was included in one of the old su patches. + + * new patch name: coreutils-build-timeout-as-pie.patch + +- Temporary disable some questionable patches (by commenting in the spec file): + + * coreutils-gl_printf_safe.patch + * coreutils-8.9-singlethreaded-sort.patch + +- Change build / spec file: + + * Bump version from 8.17 to 8.21. + * Fix macro invocation in "Provides" for stat. + * Remove ancient "Obsoletes" entries. + * Remove/add the above removed/added sources and patches. + * Temporarily comment the code for statically linking LIB_GMP + (as it does not work). + * Remove -Wall from CFLAGS as it is already included in OBS' default options. + * Remove the --without-included-regex option to use + coreutils' regex implementation. + * Remove custom gl_cv_func_printf_directive_n and gl_cv_func_isnanl_works. + * Touch "man/*.x" to force the rebuild of the man pages. + * Make sort's multi-byte test script executable in %check section. + * Hardcode package name for "%find_lang" and "%files lang -f" lines. + * In the %files section, add the COPYING and THANKS files. + Furthermore, fix the path to the LC_TIME files. + * Change package description to accomodate to added programs + (hostid, nproc, realpath, stdbuf, truncate) + and mention the hacky installation of programs to move (kill, su). + + +- Update to 8.21 (2013-02-14) [stable] + + ** New programs + + numfmt: reformat numbers + + ** New features + + df now accepts the --output[=FIELD_LIST] option to define the list of columns + to include in the output, or all available columns if the FIELD_LIST is + omitted. Note this enables df to output both block and inode fields together. + + du now accepts the --threshold=SIZE option to restrict the output to entries + with such a minimum SIZE (or a maximum SIZE if it is negative). + du recognizes -t SIZE as equivalent, for compatibility with FreeBSD. + + ** Bug fixes + + cp --no-preserve=mode now no longer exits non-zero. + [bug introduced in coreutils-8.20] + + cut with a range like "N-" no longer allocates N/8 bytes. That buffer + would never be used, and allocation failure could cause cut to fail. + [bug introduced in coreutils-8.10] + + cut no longer accepts the invalid range 0-, which made it print empty lines. + Instead, cut now fails and emits an appropriate diagnostic. + [This bug was present in "the beginning".] + + cut now handles overlapping to-EOL ranges properly. Before, it would + interpret "-b2-,3-" like "-b3-". Now it's treated like "-b2-". + [This bug was present in "the beginning".] + + cut no longer prints extraneous delimiters when a to-EOL range subsumes + another range. Before, "echo 123|cut --output-delim=: -b2-,3" would print + "2:3". Now it prints "23". [bug introduced in 5.3.0] + + cut -f no longer inspects input line N+1 before fully outputting line N, + which avoids delayed output for intermittent input. + [bug introduced in TEXTUTILS-1_8b] + + factor no longer loops infinitely on 32 bit powerpc or sparc systems. + [bug introduced in coreutils-8.20] + + install -m M SOURCE DEST no longer has a race condition where DEST's + permissions are temporarily derived from SOURCE instead of from M. + + pr -n no longer crashes when passed values >= 32. Also, line numbers are + consistently padded with spaces, rather than with zeros for certain widths. + [bug introduced in TEXTUTILS-1_22i] + + seq -w ensures that for numbers input in scientific notation, + the output numbers are properly aligned and of the correct width. + [This bug was present in "the beginning".] + + seq -w ensures correct alignment when the step value includes a precision + while the start value does not, and the number sequence narrows. + [This bug was present in "the beginning".] + + seq -s no longer prints an erroneous newline after the first number, and + outputs a newline after the last number rather than a trailing separator. + Also seq no longer ignores a specified step value when the end value is 1. + [bugs introduced in coreutils-8.20] + + timeout now ensures that blocking of ALRM signals is not inherited from + its parent, which would cause timeouts to be ignored. + [the bug dates back to the initial implementation] + + ** Changes in behavior + + df --total now prints '-' into the target column (mount point) of the + summary line, accommodating the --output option where the target field + can be in any column. If there is no source column, then df prints + 'total' in the target column. + + df now properly outputs file system information with bind mounts present on + the system by skipping duplicate entries (identified by the device number). + Consequently, df also elides the early-boot pseudo file system type "rootfs". + + nl no longer supports the --page-increment option, which has been + deprecated since coreutils-7.5. Use --line-increment instead. + + ** Improvements + + readlink now supports multiple arguments, and a complementary + -z, --zero option to delimit output items with the NUL character. + + stat and tail now know about CEPH. stat -f --format=%T now reports the file + system type, and tail -f uses polling for files on CEPH file systems. + + stty now supports configuring DTR/DSR hardware flow control where available. + + ** Build-related + + Perl is now more of a prerequisite. It has long been required in order + to run (not skip) a significant percentage of the tests. Now, it is + also required in order to generate proper man pages, via help2man. The + generated man/*.1 man pages are no longer distributed. Building without + perl, you would create stub man pages. Thus, while perl is not an + official prerequisite (build and "make check" will still succeed), any + resulting man pages would be inferior. In addition, this fixes a bug + in distributed (not from clone) Makefile.in that could cause parallel + build failure when building from modified sources, as is common practice + for a patched distribution package. + + factor now builds on x86_64 with x32 ABI, 32 bit MIPS, and all HPPA systems, + by avoiding incompatible asm. [bug introduced in coreutils-8.20] + + A root-only test predicate would always fail. Its job was to determine + whether our dummy user, $NON_ROOT_USERNAME, was able to run binaries from + the build directory. As a result, all dependent tests were always skipped. + Now, those tests may be run once again. [bug introduced in coreutils-8.20] + + +- Update to 8.20 (2012-10-23) [stable] + + ** New features + + dd now accepts 'status=none' to suppress all informational output. + + md5sum now accepts the --tag option to print BSD-style output with GNU + file name escaping. This also affects sha1sum, sha224sum, sha256sum, + sha384sum and sha512sum. + + ** Bug fixes + + cp could read from freed memory and could even make corrupt copies. + This could happen with a very fragmented and sparse input file, + on GNU/Linux file systems supporting fiemap extent scanning. + This bug also affects mv when it resorts to copying, and install. + [bug introduced in coreutils-8.11] + + cp --no-preserve=mode now no longer preserves the original file's + permissions but correctly sets mode specified by 0666 & ~umask + + du no longer emits a "disk-corrupted"-style diagnostic when it detects + a directory cycle that is due to a bind-mounted directory. Instead, + it detects this precise type of cycle, diagnoses it as such and + eventually exits nonzero. + + factor (when using gmp) would mistakenly declare some composite numbers + to be prime, e.g., 465658903, 2242724851, 6635692801 and many more. + The fix makes factor somewhat slower (~25%) for ranges of consecutive + numbers, and up to 8 times slower for some worst-case individual numbers. + [bug introduced in coreutils-7.0, with GNU MP support] + + ls now correctly colors dangling symlinks when listing their containing + directories, with orphaned symlink coloring disabled in LS_COLORS. + [bug introduced in coreutils-8.14] + + rm -i -d now prompts the user then removes an empty directory, rather + than ignoring the -d option and failing with an 'Is a directory' error. + [bug introduced in coreutils-8.19, with the addition of --dir (-d)] + + rm -r S/ (where S is a symlink-to-directory) no longer gives the invalid + "Too many levels of symbolic links" diagnostic. + [bug introduced in coreutils-8.6] + + seq now handles arbitrarily long non-negative whole numbers when the + increment is 1 and when no format-changing option is specified. + Before, this would infloop: + b=100000000000000000000; seq $b $b + [the bug dates back to the initial implementation] + + ** Changes in behavior + + nproc now diagnoses with an error, non option command line parameters. + + ** Improvements + + factor's core has been rewritten for speed and increased range. + It can now factor numbers up to 2^128, even without GMP support. + Its speed is from a few times better (for small numbers) to over + 10,000 times better (just below 2^64). The new code also runs a + deterministic primality test for each prime factor, not just a + probabilistic test. + + seq is now up to 70 times faster than it was in coreutils-8.19 and prior, + but only with non-negative whole numbers, an increment of 1, and no + format-changing options. + + stat and tail know about ZFS, VZFS and VMHGFS. stat -f --format=%T now + reports the file system type, and tail -f now uses inotify for files on + ZFS and VZFS file systems, rather than the default (for unknown file + system types) of issuing a warning and reverting to polling. tail -f + still uses polling for files on VMHGFS file systems. + + ** Build-related + + root-only tests now check for permissions of our dummy user, + $NON_ROOT_USERNAME, before trying to run binaries from the build directory. + Before, we would get hard-to-diagnose reports of failing root-only tests. + Now, those tests are skipped with a useful diagnostic when the root tests + are run without following the instructions in README. + + We now build most directories using non-recursive make rules. I.e., + rather than running make in man/, lib/, src/, tests/, instead, the top + level Makefile.am includes a $dir/local.mk that describes how to build + the targets in the corresponding directory. Two directories remain + unconverted: po/, gnulib-tests/. One nice side-effect is that the more + accurate dependencies have eliminated a nagging occasional failure that + was seen when running parallel "make syntax-check". + + +- Update to 8.19 (2012-08-20) [stable] + + ** Bug fixes + + df now fails when the list of mounted file systems (/etc/mtab) cannot + be read, yet the file system type information is needed to process + certain options like -a, -l, -t and -x. + [This bug was present in "the beginning".] + + sort -u could fail to output one or more result lines. + For example, this command would fail to print "1": + (yes 7 | head -11; echo 1) | sort --p=1 -S32b -u + [bug introduced in coreutils-8.6] + + sort -u could read freed memory. + For example, this evokes a read from freed memory: + perl -le 'print "a\n"."0"x900'|valgrind sort --p=1 -S32b -u>/dev/null + [bug introduced in coreutils-8.6] + + ** New features + + rm now accepts the --dir (-d) option which makes it remove empty directories. + Since removing empty directories is relatively safe, this option can be + used as a part of the alias rm='rm --dir'. This improves compatibility + with Mac OS X and BSD systems which also honor the -d option. + + +- Update to 8.18 (2012-08-12) [stable] + + ** Bug fixes + + cksum now prints checksums atomically so that concurrent + processes will not intersperse their output. + [the bug dates back to the initial implementation] + + date -d "$(printf '\xb0')" would print 00:00:00 with today's date + rather than diagnosing the invalid input. Now it reports this: + date: invalid date '\260' + [This bug was present in "the beginning".] + + df no longer outputs control characters present in the mount point name. + Such characters are replaced with '?', so for example, scripts consuming + lines output by df, can work reliably. + [This bug was present in "the beginning".] + + df --total now exits with an appropriate diagnostic and error code, when + file system --type options do not lead to a processed file system. + [This bug dates back to when --total was added in coreutils-7.0] + + head --lines=-N (-n-N) now resets the read pointer of a seekable input file. + This means that "head -n-3" no longer consumes all of its input, and lines + not output by head may be processed by other programs. For example, this + command now prints the final line, 2, while before it would print nothing: + seq 2 > k; (head -n-1 > /dev/null; cat) < k + [This bug was present in "the beginning".] + + ls --color would mis-color relative-named symlinks in / + [bug introduced in coreutils-8.17] + + split now ensures it doesn't overwrite the input file with generated output. + [the bug dates back to the initial implementation] + + stat and df now report the correct file system usage, + in all situations on GNU/Linux, by correctly determining the block size. + [df bug since coreutils-5.0.91, stat bug since the initial implementation] + + tail -f no longer tries to use inotify on AUFS or PanFS file systems + [you might say this was introduced in coreutils-7.5, along with inotify + support, but even now, its magic number isn't in the usual place.] + + ** New features + + stat -f recognizes the new remote file system types: aufs, panfs. + + ** Changes in behavior + + su: this program has been removed. We stopped installing "su" by + default with the release of coreutils-6.9.90 on 2007-12-01. Now, + that the util-linux package has the union of the Suse and Fedora + patches as well as enough support to build on the Hurd, we no longer + have any reason to include it here. + + ** Improvements + + sort avoids redundant processing in the presence of inaccessible inputs, + or unwritable output. Sort now diagnoses certain errors at start-up, + rather than after potentially expensive processing. + + sort now allocates no more than 75% of physical memory by default, + to better share system resources, and thus operate more efficiently. + [The default max memory usage changed from 50% to 100% in coreutils-8.16] + ------------------------------------------------------------------- Sun Jan 27 08:16:16 UTC 2013 - coolo@suse.com diff --git a/coreutils-testsuite.spec b/coreutils-testsuite.spec index 45f6acc..62a0209 100644 --- a/coreutils-testsuite.spec +++ b/coreutils-testsuite.spec @@ -20,6 +20,10 @@ Name: coreutils-testsuite Summary: GNU Core Utilities License: GPL-3.0+ Group: System/Base +Url: http://www.gnu.org/software/coreutils/ +Version: 8.21 +Release: 0 + BuildRequires: automake BuildRequires: gmp-devel BuildRequires: help2man @@ -27,8 +31,8 @@ BuildRequires: libacl-devel BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: makeinfo -BuildRequires: pam-devel BuildRequires: perl +BuildRequires: xz %if "%{name}" == "coreutils-testsuite" BuildRequires: acl BuildRequires: gdb @@ -37,110 +41,100 @@ BuildRequires: python-pyinotify BuildRequires: strace BuildRequires: valgrind %endif -BuildRequires: xz -Url: http://www.gnu.org/software/coreutils/ -Version: 8.17 -Release: 0 + +Provides: %{name} = %{version} +%if "%{name}" == "coreutils" Provides: fileutils = %{version} Provides: mktemp = %{version} Provides: sh-utils = %{version} -Provides: stat = %version} +Provides: stat = %{version} Provides: textutils = %{version} -Obsoletes: fileutils < %{version} -Obsoletes: libselinux <= 1.23.11-3 -Obsoletes: libselinux-32bit = 9 -Obsoletes: libselinux-64bit = 9 -Obsoletes: libselinux-x86 = 9 -Obsoletes: mktemp < %{version} -Obsoletes: sh-utils < %{version} -Obsoletes: stat < %version} -Obsoletes: textutils < %{version} -PreReq: %{install_info_prereq} +%endif + +%if "%{name}" == "coreutils" Recommends: %{name}-lang = %version +%endif + +# Needed for su. +BuildRequires: pam-devel Requires: pam >= 1.1.1.90 + +# this will create a cycle, broken up randomly - coreutils is just +# too core to have other prerequisites. +#PreReq: permissions +PreReq: %{install_info_prereq} + +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%if "%{name}" == "coreutils" +# For upgrading you now just need to increase the version, remove the old +# tarballs, then run osc service localrun download_files, osc addremove, +# osc vc and osc ci and you are done. +Source: http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +%else +# In "coreutils-testsuite", we use the version controlled file from "coreutils". +# otherwise that file would be downloaded twice during the above mentioned +# upgrade procedure. Source: coreutils-%{version}.tar.xz +%endif + Source1: su.pamd Source2: su.default Source3: baselibs.conf Source4: coreutils-%{version}.de.po.xz -Patch0: coreutils-misc.patch + Patch1: coreutils-remove_hostname_documentation.patch -Patch2: coreutils-gl_printf_safe.patch -#Remove the bogus coreutils version from the i18n patch name +#Patch2: coreutils-gl_printf_safe.patch Patch4: coreutils-i18n.patch Patch8: coreutils-sysinfo.patch Patch16: coreutils-invalid-ids.patch -Patch20: coreutils-8.6-pam-support-for-su.diff -Patch21: coreutils-8.6-update-man-page-for-pam.diff -Patch22: coreutils-8.6-log-all-su-attempts.diff -Patch23: coreutils-8.6-set-sane-default-path.diff -Patch24: coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff -Patch25: coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff # -Patch30: coreutils-8.6-compile-su-with-fpie.diff -Patch31: coreutils-getaddrinfo.patch -Patch32: coreutils-ptr_int_casts.patch -Patch33: coreutils-8.9-singlethreaded-sort.patch -Patch34: coreutils-acl-nofollow.patch -Patch36: coreutils-basename_documentation.patch -Patch37: coreutils-bnc#697897-setsid.patch -Patch38: coreutils-cp-corrupt-fragmented-sparse.patch -Patch39: coreutils-no_silent-rule.patch -Patch40: coreutils-df-always-hide-rootfs.patch -Patch41: coreutils-skip-du-slink-test.patch -BuildRoot: %{_tmppath}/%{name}-%{version}-build -# this will create a cycle, broken up randomly - coreutils is just too core to have other -# prerequires -#PreReq: permissions +#Patch33: coreutils-8.9-singlethreaded-sort.patch + +# OBS / RPMLINT require /usr/bin/timeout to be built with the -fpie option. +Patch100: coreutils-build-timeout-as-pie.patch +Patch101: coreutils-su.patch # ================================================ %description -Basic file, shell, and text manipulation utilities. The package -contains the following programs: +These are the GNU core utilities. This package is the union of +the GNU fileutils, sh-utils, and textutils packages. -[ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp -csplit cut date dd df dir dircolors dirname du echo env expand expr -factor false fmt fold groups head id install join kill link ln logname -ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup od paste pathchk -pinky pr printenv printf ptx pwd readlink rm rmdir runcon seq sha1sum -sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort split -stat stty su sum sync tac tail tee test timeout touch tr true tsort tty -uname unexpand uniq unlink uptime users vdir wc who whoami yes + [ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp + csplit cut date dd df dir dircolors dirname du echo env expand expr + factor false fmt fold groups head hostid id install join + link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup + nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink + realpath rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum + shred shuf sleep sort split stat stdbuf stty sum sync tac tail tee test + timeout touch tr true truncate tsort tty uname unexpand uniq unlink + uptime users vdir wc who whoami yes + +As su(1) and kill(1) have been moved from coreutils to util-linux upstreams, +this package provides compatibility symlinks to the old coreutils versions +of both programs. This is needed until there's a newer version of the +receiving util-linux package available which comes with the new binaries. # ================================================ %lang_package %prep %setup -q -n coreutils-%{version} %patch4 -%patch0 %patch1 -%patch2 +#%%if 0%%{suse_version} > 1200 +#%%patch2 +#%%endif %patch8 %patch16 -%patch20 -%patch21 -%patch22 -p1 -%patch23 -p1 -%patch24 -%patch25 -%patch30 -%patch31 -%patch32 -%patch33 -%patch34 -%patch36 -%patch37 -%patch38 -%if 0%{suse_version} < 1200 -%patch39 -%endif -%patch40 -p1 -%patch41 -p1 +# +#%%patch33 +%patch100 +%patch101 xz -dc %{S:4} >po/de.po -# We need to statically link to gmp, otherwise we have a build loop -sed -i s,'$(LIB_GMP)',%{_libdir}/libgmp.a,g src/Makefile.am +#???## We need to statically link to gmp, otherwise we have a build loop +#???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in # ================================================ %build @@ -148,71 +142,121 @@ sed -i s,'$(LIB_GMP)',%{_libdir}/libgmp.a,g src/Makefile.am AUTOPOINT=true autoreconf -fi %endif export CFLAGS="%optflags" -%configure --libexecdir=%{_libdir} --without-included-regex \ - --enable-install-program=arch,su \ - gl_cv_func_printf_directive_n=yes \ - gl_cv_func_isnanl_works=yes \ - DEFAULT_POSIX2_VERSION=200112 alternative=199209 +%configure --libexecdir=%{_libdir} \ + --enable-install-program=arch \ + DEFAULT_POSIX2_VERSION=200112 \ + alternative=199209 make -C po update-po -make %{?_smp_mflags} V=1 + +# Regenerate manpages +touch man/*.x + +make all %{?_smp_mflags} V=1 # ================================================ %check %if "%{name}" == "coreutils-testsuite" + # Make our multi-byte test for sort executable + chmod a+x tests/misc/sort-mb-tests.sh + # Avoid parallel make, because otherwise some timeout based tests like # rm/ext3-perf may fail due to high CPU or IO load. - make check-very-expensive - install -d -m 755 %{buildroot}%{_docdir}/%{name} - xz -c tests/test-suite.log > %{buildroot}%{_docdir}/%{name}/test-suite.log.xz + make check-very-expensive \ + && install -d -m 755 %{buildroot}%{_docdir}/%{name} \ + && xz -c tests/test-suite.log \ + > %{buildroot}%{_docdir}/%{name}/test-suite.log.xz %endif # ================================================ %install %if "%{name}" == "coreutils" %makeinstall pkglibexecdir=%{_libdir}/%{name} -test -f %{buildroot}%{_bindir}/su || \ - install src/su %{buildroot}%{_bindir}/su + +# === TRICKERY - PART 1/3 === +# trickery to make the move of su and kill to util-linux as easy as possible +# this all needs to go when util-linux 2.22 has been checked in and +# everything has settled. 15.10.2012 pth@suse.de +# Install su and kill with a ".core" suffix. + +install -d -m 755 %{buildroot}/etc/pam.d +install -m 644 %{S:1} %{buildroot}/etc/pam.d/su.core +install -m 644 %{S:1} %{buildroot}/etc/pam.d/su-l.core + +install -d -m 755 %{buildroot}/etc/default +install -m 644 %{S:2} %{buildroot}/etc/default/su.core + +install -s -m 755 src/su %{buildroot}%{_bindir}/su.core +install -m 644 man/su.1 %{buildroot}%{_mandir}/man1/su.core.1 +rm -f %{buildroot}%{_mandir}/man1/su.1 + +# kill is still part of coreutils, so rename it (stripped). +install -s -m 755 %{buildroot}%{_bindir}/kill %{buildroot}%{_bindir}/kill.core +rm -f %{buildroot}%{_bindir}/kill +mv -v %{buildroot}%{_mandir}/man1/kill.1 %{buildroot}%{_mandir}/man1/kill.core.1 + #UsrMerge install -d %{buildroot}/bin -for i in arch basename cat chgrp chmod chown cp date dd df echo false kill ln ls mkdir mknod mktemp mv pwd rm rmdir sleep sort stat stty su sync touch true uname readlink md5sum +for i in arch basename cat chgrp chmod chown cp date dd df echo \ + false ln ls mkdir mknod mktemp mv pwd rm rmdir sleep sort stat \ + stty sync touch true uname readlink md5sum do ln -sf %{_bindir}/$i %{buildroot}/bin/$i done #EndUsrMerge -install -d -m 755 %{buildroot}/etc/pam.d -install -m 644 %{S:1} %{buildroot}/etc/pam.d/su -install -m 644 %{S:1} %{buildroot}/etc/pam.d/su-l -install -d -m 755 %{buildroot}/etc/default -install -m 644 %{S:2} %{buildroot}/etc/default/su echo '.so man1/test.1' > %{buildroot}/%{_mandir}/man1/\[.1 %find_lang coreutils %endif # ================================================ %post +%if "%{name}" == "coreutils" %install_info --info-dir=%{_infodir} %{_infodir}/coreutils.info.gz + # may fail if permissions is not there, but there is no way around that -%set_permissions %{_bindir}/su +%set_permissions %{_bindir}/su.core +%endif + +# ================================================ +%posttrans +%if "%{name}" == "coreutils" +# === TRICKERY - PART 2/3 === +# If the files are missing after installation, then create links to the +# saved ones (with suffix .core). +if [ ! -r %{_bindir}/su -a -e %{_bindir}/su.core ]; then + echo "%{_bindir}/su does not exist, setting compat symlink to %{_bindir}/su.core" + ln -svf %{_bindir}/su.core %{_bindir}/su + ln -svf %{_bindir}/kill.core %{_bindir}/kill + ln -svf %{_bindir}/su.core /bin/su + ln -svf %{_bindir}/kill.core /bin/kill + ln -svf /etc/pam.d/su.core /etc/pam.d/su + ln -svf /etc/pam.d/su-l.core /etc/pam.d/su-l + ln -svf /etc/default/su.core /etc/default/su + # man pages are already zipped at that point. + mv -vf %{_mandir}/man1/kill.core.1.gz %{_mandir}/man1/kill.1.gz + mv -vf %{_mandir}/man1/su.core.1.gz %{_mandir}/man1/su.1.gz +fi +%endif # ================================================ %postun +%if "%{name}" == "coreutils" %install_info_delete --info-dir=%{_infodir} %{_infodir}/coreutils.info.gz +%endif # ================================================ %verifyscript -%verify_permissions -e %{_bindir}/su +%if "%{name}" == "coreutils" +%verify_permissions -e %{_bindir}/su.core +%endif # ================================================ %files %if "%{name}" == "coreutils" %defattr(-,root,root) -%doc README NEWS -%config %{_sysconfdir}/pam.d/su -%config %{_sysconfdir}/pam.d/su-l -%config(noreplace) %{_sysconfdir}/default/su -%attr(4755,root,root) %{_bindir}/su +%doc COPYING NEWS README THANKS +%attr(4755,root,root) %{_bindir}/su.core %{_bindir}/* #UsrMerge /bin/* @@ -220,7 +264,11 @@ echo '.so man1/test.1' > %{buildroot}/%{_mandir}/man1/\[.1 %{_libdir}/%{name} %doc %{_infodir}/coreutils.info*.gz %doc %{_mandir}/man1/*.1.gz -%dir %{_prefix}/share/locale/*/LC_TIME +%dir %{_datadir}/locale/*/LC_TIME +# === TRICKERY - PART 3/3 === +%config /etc/default/su.core +%config /etc/pam.d/su-l.core +%config /etc/pam.d/su.core %files lang -f coreutils.lang %defattr(-,root,root) diff --git a/coreutils.changes b/coreutils.changes index 8c50440..e0661a6 100644 --- a/coreutils.changes +++ b/coreutils.changes @@ -1,9 +1,419 @@ +------------------------------------------------------------------- +Thu Apr 4 23:25:17 UTC 2013 - mail@bernhard-voelker.de + +- Fix source url for coreutils-testsuite. + ------------------------------------------------------------------- Thu Mar 21 11:55:13 UTC 2013 - mmeister@suse.com - Added url as source. Please see http://en.opensuse.org/SourceUrls +------------------------------------------------------------------- +Thu Mar 21 11:54:05 UTC 2013 - mail@bernhard-voelker.de + +- Fix multibyte issue in unexpand (rh#821262) + (coreutils-i18n.patch: patch by Roman Kollár ) + +- Fix cut to terminate mbdelim string + + Otherwise, cut might do an unbounded strdup of the delimiter string + in i18n mode (https://bugzilla.redhat.com/show_bug.cgi?id=911929) + (coreutils-i18n.patch, from Mark Wielaard ) + +- Add su(1) again + + Now, su(1) will be provided via a symlink trick + to the file installed with a ".core" suffix. + By this, we can upgrade to 8.21 without having to wait + for a util-linux version providing it. + + * coreutils-su.patch: Add cumulative su patch from previous Base:System + version 8.17, ported to 8.21 build structure. This supersedes the + following partial patches: + coreutils-8.6-compile-su-with-fpie.diff, + coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff, + coreutils-8.6-log-all-su-attempts.diff, + coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff, + coreutils-8.6-pam-support-for-su.diff, + coreutils-8.6-set-sane-default-path.diff, + coreutils-8.6-update-man-page-for-pam.diff, + coreutils-bnc#697897-setsid.patch. + + * pam, pam-devel: Add as requirements, also during build. + * coreutils.spec (%description): Clarify that su is included although removed + upstreams. + (%install): Install su+kill files with suffix ".core". + (%post): Move setting permissions on su from %posttrans to %install. + (%posttrans): Create symlinks to files with ".core" suffix unless already + existing. + +- Install kill(1) with the same symlink trick. + +- Remove now-obsolete patches and files: + + * coreutils-8.17.de.po.xz: + * coreutils-8.17.tar.xz: + Remove sources + translation of previous version + + * coreutils-acl-nofollow.patch: + * coreutils-basename_documentation.patch: + * coreutils-cp-corrupt-fragmented-sparse.patch: + * coreutils-df-always-hide-rootfs.patch: + * coreutils-skip-du-slink-test.patch: + Fixed upstream. + + * coreutils-getaddrinfo.patch: + * coreutils-misc.patch: + * coreutils-no_silent-rule.patch: + Remove test and build related patches. + + * coreutils-ptr_int_casts.patch: + Remove because merged into coreutils-i18n.patch. + +- Add files: + + * coreutils-8.21.tar.xz: + Add tarball of the new upstream version + * coreutils-8.21.de.po.xz: + Add language file. + +- Update patches: + + * coreutils-i18n.patch + Merge some Fedora changes to keep the i18n patch like theirs. + Fix and cleanup sort's multibyte test with incorporated test data. + + * coreutils-remove_hostname_documentation.patch + +- Add patch to build 'timeout' as PIE (OBS requires it). + This patch actually was included in one of the old su patches. + + * new patch name: coreutils-build-timeout-as-pie.patch + +- Temporary disable some questionable patches (by commenting in the spec file): + + * coreutils-gl_printf_safe.patch + * coreutils-8.9-singlethreaded-sort.patch + +- Change build / spec file: + + * Bump version from 8.17 to 8.21. + * Fix macro invocation in "Provides" for stat. + * Remove ancient "Obsoletes" entries. + * Remove/add the above removed/added sources and patches. + * Temporarily comment the code for statically linking LIB_GMP + (as it does not work). + * Remove -Wall from CFLAGS as it is already included in OBS' default options. + * Remove the --without-included-regex option to use + coreutils' regex implementation. + * Remove custom gl_cv_func_printf_directive_n and gl_cv_func_isnanl_works. + * Touch "man/*.x" to force the rebuild of the man pages. + * Make sort's multi-byte test script executable in %check section. + * Hardcode package name for "%find_lang" and "%files lang -f" lines. + * In the %files section, add the COPYING and THANKS files. + Furthermore, fix the path to the LC_TIME files. + * Change package description to accomodate to added programs + (hostid, nproc, realpath, stdbuf, truncate) + and mention the hacky installation of programs to move (kill, su). + + +- Update to 8.21 (2013-02-14) [stable] + + ** New programs + + numfmt: reformat numbers + + ** New features + + df now accepts the --output[=FIELD_LIST] option to define the list of columns + to include in the output, or all available columns if the FIELD_LIST is + omitted. Note this enables df to output both block and inode fields together. + + du now accepts the --threshold=SIZE option to restrict the output to entries + with such a minimum SIZE (or a maximum SIZE if it is negative). + du recognizes -t SIZE as equivalent, for compatibility with FreeBSD. + + ** Bug fixes + + cp --no-preserve=mode now no longer exits non-zero. + [bug introduced in coreutils-8.20] + + cut with a range like "N-" no longer allocates N/8 bytes. That buffer + would never be used, and allocation failure could cause cut to fail. + [bug introduced in coreutils-8.10] + + cut no longer accepts the invalid range 0-, which made it print empty lines. + Instead, cut now fails and emits an appropriate diagnostic. + [This bug was present in "the beginning".] + + cut now handles overlapping to-EOL ranges properly. Before, it would + interpret "-b2-,3-" like "-b3-". Now it's treated like "-b2-". + [This bug was present in "the beginning".] + + cut no longer prints extraneous delimiters when a to-EOL range subsumes + another range. Before, "echo 123|cut --output-delim=: -b2-,3" would print + "2:3". Now it prints "23". [bug introduced in 5.3.0] + + cut -f no longer inspects input line N+1 before fully outputting line N, + which avoids delayed output for intermittent input. + [bug introduced in TEXTUTILS-1_8b] + + factor no longer loops infinitely on 32 bit powerpc or sparc systems. + [bug introduced in coreutils-8.20] + + install -m M SOURCE DEST no longer has a race condition where DEST's + permissions are temporarily derived from SOURCE instead of from M. + + pr -n no longer crashes when passed values >= 32. Also, line numbers are + consistently padded with spaces, rather than with zeros for certain widths. + [bug introduced in TEXTUTILS-1_22i] + + seq -w ensures that for numbers input in scientific notation, + the output numbers are properly aligned and of the correct width. + [This bug was present in "the beginning".] + + seq -w ensures correct alignment when the step value includes a precision + while the start value does not, and the number sequence narrows. + [This bug was present in "the beginning".] + + seq -s no longer prints an erroneous newline after the first number, and + outputs a newline after the last number rather than a trailing separator. + Also seq no longer ignores a specified step value when the end value is 1. + [bugs introduced in coreutils-8.20] + + timeout now ensures that blocking of ALRM signals is not inherited from + its parent, which would cause timeouts to be ignored. + [the bug dates back to the initial implementation] + + ** Changes in behavior + + df --total now prints '-' into the target column (mount point) of the + summary line, accommodating the --output option where the target field + can be in any column. If there is no source column, then df prints + 'total' in the target column. + + df now properly outputs file system information with bind mounts present on + the system by skipping duplicate entries (identified by the device number). + Consequently, df also elides the early-boot pseudo file system type "rootfs". + + nl no longer supports the --page-increment option, which has been + deprecated since coreutils-7.5. Use --line-increment instead. + + ** Improvements + + readlink now supports multiple arguments, and a complementary + -z, --zero option to delimit output items with the NUL character. + + stat and tail now know about CEPH. stat -f --format=%T now reports the file + system type, and tail -f uses polling for files on CEPH file systems. + + stty now supports configuring DTR/DSR hardware flow control where available. + + ** Build-related + + Perl is now more of a prerequisite. It has long been required in order + to run (not skip) a significant percentage of the tests. Now, it is + also required in order to generate proper man pages, via help2man. The + generated man/*.1 man pages are no longer distributed. Building without + perl, you would create stub man pages. Thus, while perl is not an + official prerequisite (build and "make check" will still succeed), any + resulting man pages would be inferior. In addition, this fixes a bug + in distributed (not from clone) Makefile.in that could cause parallel + build failure when building from modified sources, as is common practice + for a patched distribution package. + + factor now builds on x86_64 with x32 ABI, 32 bit MIPS, and all HPPA systems, + by avoiding incompatible asm. [bug introduced in coreutils-8.20] + + A root-only test predicate would always fail. Its job was to determine + whether our dummy user, $NON_ROOT_USERNAME, was able to run binaries from + the build directory. As a result, all dependent tests were always skipped. + Now, those tests may be run once again. [bug introduced in coreutils-8.20] + + +- Update to 8.20 (2012-10-23) [stable] + + ** New features + + dd now accepts 'status=none' to suppress all informational output. + + md5sum now accepts the --tag option to print BSD-style output with GNU + file name escaping. This also affects sha1sum, sha224sum, sha256sum, + sha384sum and sha512sum. + + ** Bug fixes + + cp could read from freed memory and could even make corrupt copies. + This could happen with a very fragmented and sparse input file, + on GNU/Linux file systems supporting fiemap extent scanning. + This bug also affects mv when it resorts to copying, and install. + [bug introduced in coreutils-8.11] + + cp --no-preserve=mode now no longer preserves the original file's + permissions but correctly sets mode specified by 0666 & ~umask + + du no longer emits a "disk-corrupted"-style diagnostic when it detects + a directory cycle that is due to a bind-mounted directory. Instead, + it detects this precise type of cycle, diagnoses it as such and + eventually exits nonzero. + + factor (when using gmp) would mistakenly declare some composite numbers + to be prime, e.g., 465658903, 2242724851, 6635692801 and many more. + The fix makes factor somewhat slower (~25%) for ranges of consecutive + numbers, and up to 8 times slower for some worst-case individual numbers. + [bug introduced in coreutils-7.0, with GNU MP support] + + ls now correctly colors dangling symlinks when listing their containing + directories, with orphaned symlink coloring disabled in LS_COLORS. + [bug introduced in coreutils-8.14] + + rm -i -d now prompts the user then removes an empty directory, rather + than ignoring the -d option and failing with an 'Is a directory' error. + [bug introduced in coreutils-8.19, with the addition of --dir (-d)] + + rm -r S/ (where S is a symlink-to-directory) no longer gives the invalid + "Too many levels of symbolic links" diagnostic. + [bug introduced in coreutils-8.6] + + seq now handles arbitrarily long non-negative whole numbers when the + increment is 1 and when no format-changing option is specified. + Before, this would infloop: + b=100000000000000000000; seq $b $b + [the bug dates back to the initial implementation] + + ** Changes in behavior + + nproc now diagnoses with an error, non option command line parameters. + + ** Improvements + + factor's core has been rewritten for speed and increased range. + It can now factor numbers up to 2^128, even without GMP support. + Its speed is from a few times better (for small numbers) to over + 10,000 times better (just below 2^64). The new code also runs a + deterministic primality test for each prime factor, not just a + probabilistic test. + + seq is now up to 70 times faster than it was in coreutils-8.19 and prior, + but only with non-negative whole numbers, an increment of 1, and no + format-changing options. + + stat and tail know about ZFS, VZFS and VMHGFS. stat -f --format=%T now + reports the file system type, and tail -f now uses inotify for files on + ZFS and VZFS file systems, rather than the default (for unknown file + system types) of issuing a warning and reverting to polling. tail -f + still uses polling for files on VMHGFS file systems. + + ** Build-related + + root-only tests now check for permissions of our dummy user, + $NON_ROOT_USERNAME, before trying to run binaries from the build directory. + Before, we would get hard-to-diagnose reports of failing root-only tests. + Now, those tests are skipped with a useful diagnostic when the root tests + are run without following the instructions in README. + + We now build most directories using non-recursive make rules. I.e., + rather than running make in man/, lib/, src/, tests/, instead, the top + level Makefile.am includes a $dir/local.mk that describes how to build + the targets in the corresponding directory. Two directories remain + unconverted: po/, gnulib-tests/. One nice side-effect is that the more + accurate dependencies have eliminated a nagging occasional failure that + was seen when running parallel "make syntax-check". + + +- Update to 8.19 (2012-08-20) [stable] + + ** Bug fixes + + df now fails when the list of mounted file systems (/etc/mtab) cannot + be read, yet the file system type information is needed to process + certain options like -a, -l, -t and -x. + [This bug was present in "the beginning".] + + sort -u could fail to output one or more result lines. + For example, this command would fail to print "1": + (yes 7 | head -11; echo 1) | sort --p=1 -S32b -u + [bug introduced in coreutils-8.6] + + sort -u could read freed memory. + For example, this evokes a read from freed memory: + perl -le 'print "a\n"."0"x900'|valgrind sort --p=1 -S32b -u>/dev/null + [bug introduced in coreutils-8.6] + + ** New features + + rm now accepts the --dir (-d) option which makes it remove empty directories. + Since removing empty directories is relatively safe, this option can be + used as a part of the alias rm='rm --dir'. This improves compatibility + with Mac OS X and BSD systems which also honor the -d option. + + +- Update to 8.18 (2012-08-12) [stable] + + ** Bug fixes + + cksum now prints checksums atomically so that concurrent + processes will not intersperse their output. + [the bug dates back to the initial implementation] + + date -d "$(printf '\xb0')" would print 00:00:00 with today's date + rather than diagnosing the invalid input. Now it reports this: + date: invalid date '\260' + [This bug was present in "the beginning".] + + df no longer outputs control characters present in the mount point name. + Such characters are replaced with '?', so for example, scripts consuming + lines output by df, can work reliably. + [This bug was present in "the beginning".] + + df --total now exits with an appropriate diagnostic and error code, when + file system --type options do not lead to a processed file system. + [This bug dates back to when --total was added in coreutils-7.0] + + head --lines=-N (-n-N) now resets the read pointer of a seekable input file. + This means that "head -n-3" no longer consumes all of its input, and lines + not output by head may be processed by other programs. For example, this + command now prints the final line, 2, while before it would print nothing: + seq 2 > k; (head -n-1 > /dev/null; cat) < k + [This bug was present in "the beginning".] + + ls --color would mis-color relative-named symlinks in / + [bug introduced in coreutils-8.17] + + split now ensures it doesn't overwrite the input file with generated output. + [the bug dates back to the initial implementation] + + stat and df now report the correct file system usage, + in all situations on GNU/Linux, by correctly determining the block size. + [df bug since coreutils-5.0.91, stat bug since the initial implementation] + + tail -f no longer tries to use inotify on AUFS or PanFS file systems + [you might say this was introduced in coreutils-7.5, along with inotify + support, but even now, its magic number isn't in the usual place.] + + ** New features + + stat -f recognizes the new remote file system types: aufs, panfs. + + ** Changes in behavior + + su: this program has been removed. We stopped installing "su" by + default with the release of coreutils-6.9.90 on 2007-12-01. Now, + that the util-linux package has the union of the Suse and Fedora + patches as well as enough support to build on the Hurd, we no longer + have any reason to include it here. + + ** Improvements + + sort avoids redundant processing in the presence of inaccessible inputs, + or unwritable output. Sort now diagnoses certain errors at start-up, + rather than after potentially expensive processing. + + sort now allocates no more than 75% of physical memory by default, + to better share system resources, and thus operate more efficiently. + [The default max memory usage changed from 50% to 100% in coreutils-8.16] + ------------------------------------------------------------------- Sun Jan 27 08:16:16 UTC 2013 - coolo@suse.com diff --git a/coreutils.spec b/coreutils.spec index 4f8692f..7f607cb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -20,6 +20,10 @@ Name: coreutils Summary: GNU Core Utilities License: GPL-3.0+ Group: System/Base +Url: http://www.gnu.org/software/coreutils/ +Version: 8.21 +Release: 0 + BuildRequires: automake BuildRequires: gmp-devel BuildRequires: help2man @@ -27,8 +31,8 @@ BuildRequires: libacl-devel BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: makeinfo -BuildRequires: pam-devel BuildRequires: perl +BuildRequires: xz %if "%{name}" == "coreutils-testsuite" BuildRequires: acl BuildRequires: gdb @@ -37,110 +41,100 @@ BuildRequires: python-pyinotify BuildRequires: strace BuildRequires: valgrind %endif -BuildRequires: xz -Url: http://www.gnu.org/software/coreutils/ -Version: 8.17 -Release: 0 + +Provides: %{name} = %{version} +%if "%{name}" == "coreutils" Provides: fileutils = %{version} Provides: mktemp = %{version} Provides: sh-utils = %{version} -Provides: stat = %version} +Provides: stat = %{version} Provides: textutils = %{version} -Obsoletes: fileutils < %{version} -Obsoletes: libselinux <= 1.23.11-3 -Obsoletes: libselinux-32bit = 9 -Obsoletes: libselinux-64bit = 9 -Obsoletes: libselinux-x86 = 9 -Obsoletes: mktemp < %{version} -Obsoletes: sh-utils < %{version} -Obsoletes: stat < %version} -Obsoletes: textutils < %{version} -PreReq: %{install_info_prereq} +%endif + +%if "%{name}" == "coreutils" Recommends: %{name}-lang = %version +%endif + +# Needed for su. +BuildRequires: pam-devel Requires: pam >= 1.1.1.90 + +# this will create a cycle, broken up randomly - coreutils is just +# too core to have other prerequisites. +#PreReq: permissions +PreReq: %{install_info_prereq} + +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%if "%{name}" == "coreutils" +# For upgrading you now just need to increase the version, remove the old +# tarballs, then run osc service localrun download_files, osc addremove, +# osc vc and osc ci and you are done. Source: http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +%else +# In "coreutils-testsuite", we use the version controlled file from "coreutils". +# otherwise that file would be downloaded twice during the above mentioned +# upgrade procedure. +Source: coreutils-%{version}.tar.xz +%endif + Source1: su.pamd Source2: su.default Source3: baselibs.conf Source4: coreutils-%{version}.de.po.xz -Patch0: coreutils-misc.patch + Patch1: coreutils-remove_hostname_documentation.patch -Patch2: coreutils-gl_printf_safe.patch -#Remove the bogus coreutils version from the i18n patch name +#Patch2: coreutils-gl_printf_safe.patch Patch4: coreutils-i18n.patch Patch8: coreutils-sysinfo.patch Patch16: coreutils-invalid-ids.patch -Patch20: coreutils-8.6-pam-support-for-su.diff -Patch21: coreutils-8.6-update-man-page-for-pam.diff -Patch22: coreutils-8.6-log-all-su-attempts.diff -Patch23: coreutils-8.6-set-sane-default-path.diff -Patch24: coreutils-8.6-honor-settings-in-etc-default-su-resp-etc-login.defs.diff -Patch25: coreutils-8.6-make-sure-sbin-resp-usr-sbin-are-in-PATH.diff # -Patch30: coreutils-8.6-compile-su-with-fpie.diff -Patch31: coreutils-getaddrinfo.patch -Patch32: coreutils-ptr_int_casts.patch -Patch33: coreutils-8.9-singlethreaded-sort.patch -Patch34: coreutils-acl-nofollow.patch -Patch36: coreutils-basename_documentation.patch -Patch37: coreutils-bnc#697897-setsid.patch -Patch38: coreutils-cp-corrupt-fragmented-sparse.patch -Patch39: coreutils-no_silent-rule.patch -Patch40: coreutils-df-always-hide-rootfs.patch -Patch41: coreutils-skip-du-slink-test.patch -BuildRoot: %{_tmppath}/%{name}-%{version}-build -# this will create a cycle, broken up randomly - coreutils is just too core to have other -# prerequires -#PreReq: permissions +#Patch33: coreutils-8.9-singlethreaded-sort.patch + +# OBS / RPMLINT require /usr/bin/timeout to be built with the -fpie option. +Patch100: coreutils-build-timeout-as-pie.patch +Patch101: coreutils-su.patch # ================================================ %description -Basic file, shell, and text manipulation utilities. The package -contains the following programs: +These are the GNU core utilities. This package is the union of +the GNU fileutils, sh-utils, and textutils packages. -[ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp -csplit cut date dd df dir dircolors dirname du echo env expand expr -factor false fmt fold groups head id install join kill link ln logname -ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup od paste pathchk -pinky pr printenv printf ptx pwd readlink rm rmdir runcon seq sha1sum -sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort split -stat stty su sum sync tac tail tee test timeout touch tr true tsort tty -uname unexpand uniq unlink uptime users vdir wc who whoami yes + [ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp + csplit cut date dd df dir dircolors dirname du echo env expand expr + factor false fmt fold groups head hostid id install join + link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup + nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink + realpath rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum + shred shuf sleep sort split stat stdbuf stty sum sync tac tail tee test + timeout touch tr true truncate tsort tty uname unexpand uniq unlink + uptime users vdir wc who whoami yes + +As su(1) and kill(1) have been moved from coreutils to util-linux upstreams, +this package provides compatibility symlinks to the old coreutils versions +of both programs. This is needed until there's a newer version of the +receiving util-linux package available which comes with the new binaries. # ================================================ %lang_package %prep %setup -q -n coreutils-%{version} %patch4 -%patch0 %patch1 -%patch2 +#%%if 0%%{suse_version} > 1200 +#%%patch2 +#%%endif %patch8 %patch16 -%patch20 -%patch21 -%patch22 -p1 -%patch23 -p1 -%patch24 -%patch25 -%patch30 -%patch31 -%patch32 -%patch33 -%patch34 -%patch36 -%patch37 -%patch38 -%if 0%{suse_version} < 1200 -%patch39 -%endif -%patch40 -p1 -%patch41 -p1 +# +#%%patch33 +%patch100 +%patch101 xz -dc %{S:4} >po/de.po -# We need to statically link to gmp, otherwise we have a build loop -sed -i s,'$(LIB_GMP)',%{_libdir}/libgmp.a,g src/Makefile.am +#???## We need to statically link to gmp, otherwise we have a build loop +#???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in # ================================================ %build @@ -148,71 +142,121 @@ sed -i s,'$(LIB_GMP)',%{_libdir}/libgmp.a,g src/Makefile.am AUTOPOINT=true autoreconf -fi %endif export CFLAGS="%optflags" -%configure --libexecdir=%{_libdir} --without-included-regex \ - --enable-install-program=arch,su \ - gl_cv_func_printf_directive_n=yes \ - gl_cv_func_isnanl_works=yes \ - DEFAULT_POSIX2_VERSION=200112 alternative=199209 +%configure --libexecdir=%{_libdir} \ + --enable-install-program=arch \ + DEFAULT_POSIX2_VERSION=200112 \ + alternative=199209 make -C po update-po -make %{?_smp_mflags} V=1 + +# Regenerate manpages +touch man/*.x + +make all %{?_smp_mflags} V=1 # ================================================ %check %if "%{name}" == "coreutils-testsuite" + # Make our multi-byte test for sort executable + chmod a+x tests/misc/sort-mb-tests.sh + # Avoid parallel make, because otherwise some timeout based tests like # rm/ext3-perf may fail due to high CPU or IO load. - make check-very-expensive - install -d -m 755 %{buildroot}%{_docdir}/%{name} - xz -c tests/test-suite.log > %{buildroot}%{_docdir}/%{name}/test-suite.log.xz + make check-very-expensive \ + && install -d -m 755 %{buildroot}%{_docdir}/%{name} \ + && xz -c tests/test-suite.log \ + > %{buildroot}%{_docdir}/%{name}/test-suite.log.xz %endif # ================================================ %install %if "%{name}" == "coreutils" %makeinstall pkglibexecdir=%{_libdir}/%{name} -test -f %{buildroot}%{_bindir}/su || \ - install src/su %{buildroot}%{_bindir}/su + +# === TRICKERY - PART 1/3 === +# trickery to make the move of su and kill to util-linux as easy as possible +# this all needs to go when util-linux 2.22 has been checked in and +# everything has settled. 15.10.2012 pth@suse.de +# Install su and kill with a ".core" suffix. + +install -d -m 755 %{buildroot}/etc/pam.d +install -m 644 %{S:1} %{buildroot}/etc/pam.d/su.core +install -m 644 %{S:1} %{buildroot}/etc/pam.d/su-l.core + +install -d -m 755 %{buildroot}/etc/default +install -m 644 %{S:2} %{buildroot}/etc/default/su.core + +install -s -m 755 src/su %{buildroot}%{_bindir}/su.core +install -m 644 man/su.1 %{buildroot}%{_mandir}/man1/su.core.1 +rm -f %{buildroot}%{_mandir}/man1/su.1 + +# kill is still part of coreutils, so rename it (stripped). +install -s -m 755 %{buildroot}%{_bindir}/kill %{buildroot}%{_bindir}/kill.core +rm -f %{buildroot}%{_bindir}/kill +mv -v %{buildroot}%{_mandir}/man1/kill.1 %{buildroot}%{_mandir}/man1/kill.core.1 + #UsrMerge install -d %{buildroot}/bin -for i in arch basename cat chgrp chmod chown cp date dd df echo false kill ln ls mkdir mknod mktemp mv pwd rm rmdir sleep sort stat stty su sync touch true uname readlink md5sum +for i in arch basename cat chgrp chmod chown cp date dd df echo \ + false ln ls mkdir mknod mktemp mv pwd rm rmdir sleep sort stat \ + stty sync touch true uname readlink md5sum do ln -sf %{_bindir}/$i %{buildroot}/bin/$i done #EndUsrMerge -install -d -m 755 %{buildroot}/etc/pam.d -install -m 644 %{S:1} %{buildroot}/etc/pam.d/su -install -m 644 %{S:1} %{buildroot}/etc/pam.d/su-l -install -d -m 755 %{buildroot}/etc/default -install -m 644 %{S:2} %{buildroot}/etc/default/su echo '.so man1/test.1' > %{buildroot}/%{_mandir}/man1/\[.1 %find_lang coreutils %endif # ================================================ %post +%if "%{name}" == "coreutils" %install_info --info-dir=%{_infodir} %{_infodir}/coreutils.info.gz + # may fail if permissions is not there, but there is no way around that -%set_permissions %{_bindir}/su +%set_permissions %{_bindir}/su.core +%endif + +# ================================================ +%posttrans +%if "%{name}" == "coreutils" +# === TRICKERY - PART 2/3 === +# If the files are missing after installation, then create links to the +# saved ones (with suffix .core). +if [ ! -r %{_bindir}/su -a -e %{_bindir}/su.core ]; then + echo "%{_bindir}/su does not exist, setting compat symlink to %{_bindir}/su.core" + ln -svf %{_bindir}/su.core %{_bindir}/su + ln -svf %{_bindir}/kill.core %{_bindir}/kill + ln -svf %{_bindir}/su.core /bin/su + ln -svf %{_bindir}/kill.core /bin/kill + ln -svf /etc/pam.d/su.core /etc/pam.d/su + ln -svf /etc/pam.d/su-l.core /etc/pam.d/su-l + ln -svf /etc/default/su.core /etc/default/su + # man pages are already zipped at that point. + mv -vf %{_mandir}/man1/kill.core.1.gz %{_mandir}/man1/kill.1.gz + mv -vf %{_mandir}/man1/su.core.1.gz %{_mandir}/man1/su.1.gz +fi +%endif # ================================================ %postun +%if "%{name}" == "coreutils" %install_info_delete --info-dir=%{_infodir} %{_infodir}/coreutils.info.gz +%endif # ================================================ %verifyscript -%verify_permissions -e %{_bindir}/su +%if "%{name}" == "coreutils" +%verify_permissions -e %{_bindir}/su.core +%endif # ================================================ %files %if "%{name}" == "coreutils" %defattr(-,root,root) -%doc README NEWS -%config %{_sysconfdir}/pam.d/su -%config %{_sysconfdir}/pam.d/su-l -%config(noreplace) %{_sysconfdir}/default/su -%attr(4755,root,root) %{_bindir}/su +%doc COPYING NEWS README THANKS +%attr(4755,root,root) %{_bindir}/su.core %{_bindir}/* #UsrMerge /bin/* @@ -220,7 +264,11 @@ echo '.so man1/test.1' > %{buildroot}/%{_mandir}/man1/\[.1 %{_libdir}/%{name} %doc %{_infodir}/coreutils.info*.gz %doc %{_mandir}/man1/*.1.gz -%dir %{_prefix}/share/locale/*/LC_TIME +%dir %{_datadir}/locale/*/LC_TIME +# === TRICKERY - PART 3/3 === +%config /etc/default/su.core +%config /etc/pam.d/su-l.core +%config /etc/pam.d/su.core %files lang -f coreutils.lang %defattr(-,root,root)