diff --git a/.diffutils.metadata b/.diffutils.metadata
new file mode 100644
index 0000000..0a8c8e9
--- /dev/null
+++ b/.diffutils.metadata
@@ -0,0 +1 @@
+1287a553868b808ebfff3790a5cdc6fdf7cb2886 SOURCES/diffutils-3.6.tar.xz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a071027
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/diffutils-3.6.tar.xz
diff --git a/SOURCES/diffutils-3.6-covscan.patch b/SOURCES/diffutils-3.6-covscan.patch
new file mode 100644
index 0000000..76e1000
--- /dev/null
+++ b/SOURCES/diffutils-3.6-covscan.patch
@@ -0,0 +1,74 @@
+diff -up diffutils-3.6/lib/quotearg.c.covscan diffutils-3.6/lib/quotearg.c
+--- diffutils-3.6/lib/quotearg.c.covscan	2017-05-20 02:14:05.000000000 +0200
++++ diffutils-3.6/lib/quotearg.c	2018-08-13 14:20:54.934196535 +0200
+@@ -886,8 +886,9 @@ quotearg_n_options (int n, char const *a
+   if (nslots <= n)
+     {
+       bool preallocated = (sv == &slotvec0);
+-
+-      if (MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) <= n)
++      int nmax = MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) - 1;
++      
++      if (nmax < n)
+         xalloc_die ();
+ 
+       slotvec = sv = xrealloc (preallocated ? NULL : sv, (n + 1) * sizeof *sv);
+diff -up diffutils-3.6/src/diff.h.covscan diffutils-3.6/src/diff.h
+--- diffutils-3.6/src/diff.h.covscan	2018-08-13 14:20:54.931196520 +0200
++++ diffutils-3.6/src/diff.h	2018-08-13 14:20:54.935196541 +0200
+@@ -392,7 +392,7 @@ extern void print_sdiff_script (struct c
+ extern char const change_letter[4];
+ extern char const pr_program[];
+ extern char *concat (char const *, char const *, char const *);
+-extern bool (*lines_differ) (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
++extern bool (*lines_differ) (char const *, size_t, char const *, size_t);
+ extern bool lines_differ_singlebyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
+ #ifdef HANDLE_MULTIBYTE
+ extern bool lines_differ_multibyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
+diff -up diffutils-3.6/src/ifdef.c.covscan diffutils-3.6/src/ifdef.c
+--- diffutils-3.6/src/ifdef.c.covscan	2017-05-18 19:39:59.000000000 +0200
++++ diffutils-3.6/src/ifdef.c	2018-08-13 14:20:54.935196541 +0200
+@@ -362,20 +362,14 @@ do_printf_spec (FILE *out, char const *s
+ 	    printint print_value = value;
+ 	    size_t spec_prefix_len = f - spec - 2;
+ 	    size_t pI_len = sizeof pI - 1;
+-#if 0
+-	    char format[spec_prefix_len + pI_len + 2];
+-#else
+ 	    char *format = xmalloc (spec_prefix_len + pI_len + 2);
+-#endif
+ 	    char *p = format + spec_prefix_len + pI_len;
+ 	    memcpy (format, spec, spec_prefix_len);
+ 	    memcpy (format + spec_prefix_len, pI, pI_len);
+ 	    *p++ = c;
+ 	    *p = '\0';
+ 	    fprintf (out, format, print_value);
+-#if ! HAVE_C_VARARRAYS
+ 	    free (format);
+-#endif
+ 	  }
+       }
+       break;
+diff -up diffutils-3.6/src/sdiff.c.covscan diffutils-3.6/src/sdiff.c
+--- diffutils-3.6/src/sdiff.c.covscan	2018-08-13 14:41:13.969450849 +0200
++++ diffutils-3.6/src/sdiff.c	2018-08-13 14:44:07.877344103 +0200
+@@ -230,8 +230,10 @@ cleanup (int signo __attribute__((unused
+   if (0 < diffpid)
+     kill (diffpid, SIGPIPE);
+ #endif
+-  if (tmpname)
++  if (tmpname) {
+     unlink (tmpname);
++    free (tmpname);
++  }
+ }
+ 
+ static void exiterr (void) __attribute__((noreturn));
+@@ -685,6 +687,7 @@ main (int argc, char *argv[])
+ 	if (tmpname)
+ 	  {
+ 	    unlink (tmpname);
++	    free (tmpname);
+ 	    tmpname = 0;
+ 	  }
+ 
diff --git a/SOURCES/diffutils-cmp-s-empty.patch b/SOURCES/diffutils-cmp-s-empty.patch
new file mode 100644
index 0000000..7fc3a18
--- /dev/null
+++ b/SOURCES/diffutils-cmp-s-empty.patch
@@ -0,0 +1,20 @@
+diff -up diffutils-3.6/src/cmp.c.cmp-s-empty diffutils-3.6/src/cmp.c
+--- diffutils-3.6/src/cmp.c.cmp-s-empty	2017-05-18 18:39:59.000000000 +0100
++++ diffutils-3.6/src/cmp.c	2017-05-22 10:53:28.477147864 +0100
+@@ -330,12 +330,15 @@ main (int argc, char **argv)
+ 
+   /* If only a return code is needed,
+      and if both input descriptors are associated with plain files,
++     and if both files are larger than 0 bytes (procfs files are always 0),
+      conclude that the files differ if they have different sizes
+      and if more bytes will be compared than are in the smaller file.  */
+ 
+   if (comparison_type == type_status
+       && S_ISREG (stat_buf[0].st_mode)
+-      && S_ISREG (stat_buf[1].st_mode))
++      && S_ISREG (stat_buf[1].st_mode)
++      && stat_buf[0].st_size > 0
++      && stat_buf[1].st_size > 0)
+     {
+       off_t s0 = stat_buf[0].st_size - file_position (0);
+       off_t s1 = stat_buf[1].st_size - file_position (1);
diff --git a/SOURCES/diffutils-i18n.patch b/SOURCES/diffutils-i18n.patch
new file mode 100644
index 0000000..6d2b341
--- /dev/null
+++ b/SOURCES/diffutils-i18n.patch
@@ -0,0 +1,778 @@
+diff -up diffutils-3.6/src/diff.c.i18n diffutils-3.6/src/diff.c
+--- diffutils-3.6/src/diff.c.i18n	2017-05-06 20:02:54.000000000 +0100
++++ diffutils-3.6/src/diff.c	2017-05-22 10:52:21.989254674 +0100
+@@ -76,6 +76,8 @@ static void try_help (char const *, char
+ static void check_stdout (void);
+ static void usage (void);
+ 
++bool (*lines_differ) (char const *, size_t, char const *, size_t);
++
+ /* If comparing directories, compare their common subdirectories
+    recursively.  */
+ static bool recursive;
+@@ -298,6 +300,13 @@ main (int argc, char **argv)
+   excluded = new_exclude ();
+   presume_output_tty = false;
+ 
++#ifdef HANDLE_MULTIBYTE
++  if (MB_CUR_MAX > 1)
++    lines_differ = lines_differ_multibyte;
++  else
++#endif
++    lines_differ = lines_differ_singlebyte;
++
+   /* Decode the options.  */
+ 
+   while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
+diff -up diffutils-3.6/src/diff.h.i18n diffutils-3.6/src/diff.h
+--- diffutils-3.6/src/diff.h.i18n	2017-01-01 11:22:36.000000000 +0000
++++ diffutils-3.6/src/diff.h	2017-05-22 10:51:09.050371844 +0100
+@@ -23,6 +23,17 @@
+ #include <stdio.h>
+ #include <unlocked-io.h>
+ 
++/* For platforms which support the ISO C ammendment 1 functionality we
++   support user-defined character classes. */
++#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H
++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
++# include <wchar.h>
++# include <wctype.h>
++# if defined (HAVE_MBRTOWC)
++#  define HANDLE_MULTIBYTE	1
++# endif
++#endif
++
+ /* What kind of changes a hunk contains.  */
+ enum changes
+ {
+@@ -381,7 +392,11 @@ extern void print_sdiff_script (struct c
+ extern char const change_letter[4];
+ extern char const pr_program[];
+ extern char *concat (char const *, char const *, char const *);
+-extern bool lines_differ (char const *, char const *) _GL_ATTRIBUTE_PURE;
++extern bool (*lines_differ) (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
++extern bool lines_differ_singlebyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
++#ifdef HANDLE_MULTIBYTE
++extern bool lines_differ_multibyte (char const *, size_t, char const *, size_t) _GL_ATTRIBUTE_PURE;
++#endif
+ extern lin translate_line_number (struct file_data const *, lin);
+ extern struct change *find_change (struct change *);
+ extern struct change *find_reverse_change (struct change *);
+diff -up diffutils-3.6/src/io.c.i18n diffutils-3.6/src/io.c
+--- diffutils-3.6/src/io.c.i18n	2017-01-01 11:22:36.000000000 +0000
++++ diffutils-3.6/src/io.c	2017-05-22 10:51:09.050371844 +0100
+@@ -23,6 +23,7 @@
+ #include <cmpbuf.h>
+ #include <file-type.h>
+ #include <xalloc.h>
++#include <assert.h>
+ 
+ /* Rotate an unsigned value to the left.  */
+ #define ROL(v, n) ((v) << (n) | (v) >> (sizeof (v) * CHAR_BIT - (n)))
+@@ -215,6 +216,28 @@ slurp (struct file_data *current)
+ 
+ /* Split the file into lines, simultaneously computing the equivalence
+    class for each line.  */
++#ifdef HANDLE_MULTIBYTE
++# define MBC2WC(P, END, MBLENGTH, WC, STATE, CONVFAIL)		\
++do								\
++  {								\
++    mbstate_t state_bak = STATE;				\
++								\
++    CONVFAIL = 0;						\
++    MBLENGTH = mbrtowc (&WC, P, END - (char const *)P, &STATE);	\
++								\
++    switch (MBLENGTH)						\
++      {								\
++      case (size_t)-2:						\
++      case (size_t)-1:						\
++	STATE = state_bak;					\
++	++CONVFAIL;						\
++	/* Fall through. */					\
++      case 0:							\
++	MBLENGTH = 1;						\
++      }								\
++  }								\
++ while (0)
++#endif
+ 
+ static void
+ find_and_hash_each_line (struct file_data *current)
+@@ -241,12 +264,300 @@ find_and_hash_each_line (struct file_dat
+   bool same_length_diff_contents_compare_anyway =
+     diff_length_compare_anyway | ig_case;
+ 
++#ifdef HANDLE_MULTIBYTE
++  wchar_t wc;
++  size_t mblength;
++  mbstate_t state;
++  int convfail;
++
++  memset (&state, '\0', sizeof (mbstate_t));
++#endif
++
+   while (p < suffix_begin)
+     {
+       char const *ip = p;
+       hash_value h = 0;
+       unsigned char c;
+ 
++#ifdef HANDLE_MULTIBYTE
++      if (MB_CUR_MAX > 1)
++	{
++	  wchar_t lo_wc;
++	  char mbc[MB_LEN_MAX];
++	  mbstate_t state_wc;
++
++	  /* Hash this line until we find a newline.  */
++	  switch (ig_white_space)
++	    {
++	    case IGNORE_ALL_SPACE:
++	      while (1)
++		{
++		  if (*p == '\n')
++		    {
++		      ++p;
++		      break;
++		    }
++
++		  MBC2WC (p, suffix_begin, mblength, wc, state, convfail);
++
++		  if (convfail)
++		    mbc[0] = *p++;
++		  else if (!iswspace (wc))
++		    {
++		      bool flag = 0;
++
++		      if (ig_case)
++			{
++			  lo_wc = towlower (wc);
++			  if (lo_wc != wc)
++			    {
++			      flag = 1;
++
++			      p += mblength;
++			      memset (&state_wc, '\0', sizeof(mbstate_t));
++			      mblength = wcrtomb (mbc, lo_wc, &state_wc);
++
++			      assert (mblength != (size_t)-1 &&
++				      mblength != (size_t)-2);
++
++			      mblength = (mblength < 1) ? 1 : mblength;
++			    }
++			}
++
++		      if (!flag)
++			{
++			  for (i = 0; i < mblength; i++)
++			    mbc[i] = *p++;
++			}
++		    }
++		  else
++		    {
++		      p += mblength;
++		      continue;
++		    }
++
++		  for (i = 0; i < mblength; i++)
++		    h = HASH (h, mbc[i]);
++		}
++	      break;
++
++	    case IGNORE_SPACE_CHANGE:
++	      while (1)
++		{
++		  if (*p == '\n')
++		    {
++		      ++p;
++		      break;
++		    }
++
++		  MBC2WC (p, suffix_begin, mblength, wc, state, convfail);
++
++		  if (!convfail && iswspace (wc))
++		    {
++		      while (1)
++			{
++			  if (*p == '\n')
++			    {
++			      ++p;
++			      goto hashing_done;
++			    }
++
++			  p += mblength;
++			  MBC2WC (p, suffix_begin, mblength, wc, state, convfail);
++			  if (convfail || !iswspace (wc))
++			    break;
++			}
++		      h = HASH (h, ' ');
++		    }
++
++		  /* WC is now the first non-space.  */
++		  if (convfail)
++		    mbc[0] = *p++;
++		  else
++		    {
++		      bool flag = 0;
++
++		      if (ignore_case)
++			{
++			  lo_wc = towlower (wc);
++			  if (lo_wc != wc)
++			    {
++			      flag = 1;
++
++			      p += mblength;
++			      memset (&state_wc, '\0', sizeof(mbstate_t));
++			      mblength = wcrtomb (mbc, lo_wc, &state_wc);
++
++			      assert (mblength != (size_t)-1 &&
++				      mblength != (size_t)-2);
++
++			      mblength = (mblength < 1) ? 1 : mblength;
++			    }
++			}
++
++		      if (!flag)
++			{
++			  for (i = 0; i < mblength; i++)
++			    mbc[i] = *p++;
++			}
++		    }
++
++		  for (i = 0; i < mblength; i++)
++		    h = HASH (h, mbc[i]);
++		}
++	      break;
++
++	    case IGNORE_TAB_EXPANSION:
++	    case IGNORE_TAB_EXPANSION_AND_TRAILING_SPACE:
++	    case IGNORE_TRAILING_SPACE:
++	      {
++		size_t column = 0;
++		while (1)
++		  {
++		    if (*p == '\n')
++		      {
++			++p;
++			break;
++		      }
++
++		    MBC2WC (p, suffix_begin, mblength, wc, state, convfail);
++
++		    if (!convfail
++			&& ig_white_space & IGNORE_TRAILING_SPACE
++			&& iswspace (wc))
++		      {
++			char const *p1 = p;
++			while (1)
++			  {
++			    if (*p1 == '\n')
++			      {
++				p = p1 + 1;
++				goto hashing_done;
++			      }
++
++			    p1 += mblength;
++			    MBC2WC (p1, suffix_begin, mblength, wc, state, convfail);
++			    if (convfail || !iswspace (wc))
++			      break;
++			  }
++		      }
++
++		    size_t repetitions = 1;
++		    bool no_convert = 0;
++
++		    if (ig_white_space & IGNORE_TAB_EXPANSION)
++		      {
++			if (convfail)
++			  column++;
++			else
++			  switch (wc)
++			    {
++			    case L'\b':
++			      column -= 0 < column;
++			      break;
++
++			    case L'\t':
++			      mbc[0] = ' ';
++			      mblength = 1;
++			      no_convert = 1;
++			      p++;
++			      assert(mblength == 1);
++			      repetitions = tabsize - column % tabsize;
++			      column = (column + repetitions < column
++					? 0
++					: column + repetitions);
++			      break;
++
++			    case L'\r':
++			      column = 0;
++			      break;
++
++			    default:
++			      column += wcwidth (wc);
++			      break;
++			    }
++		      }
++
++		    if (ig_case)
++		      {
++			lo_wc = towlower (wc);
++			if (lo_wc != wc)
++			  {
++			    no_convert = 1;
++			    p += mblength;
++			    memset (&state_wc, '\0', sizeof(mbstate_t));
++			    mblength = wcrtomb (mbc, lo_wc, &state_wc);
++
++			    assert (mblength != (size_t)-1 &&
++				    mblength != (size_t)-2);
++
++			    mblength = (mblength < 1) ? 1 : mblength;
++			  }
++		      }
++
++		    if (!no_convert)
++		      for (i = 0; i < mblength; i++)
++			mbc[i] = *p++;
++
++		    do
++		      {
++			for (i = 0; i < mblength; i++)
++			  h = HASH (h, mbc[i]);
++		      }
++		    while (--repetitions != 0);
++		  }
++	      }
++	      break;
++
++	    default:
++	      while (1)
++		{
++		  if (*p == '\n')
++		    {
++		      ++p;
++		      break;
++		    }
++
++		  MBC2WC (p, suffix_begin, mblength, wc, state, convfail);
++
++		  if (convfail)
++		    mbc[0] = *p++;
++		  else
++		    {
++		      int flag = 0;
++
++		      if (ig_case)
++			{
++			  lo_wc = towlower (wc);
++			  if (lo_wc != wc)
++			    {
++			      flag = 1;
++			      p += mblength;
++			      memset (&state_wc, '\0', sizeof(mbstate_t));
++			      mblength = wcrtomb (mbc, lo_wc, &state_wc);
++
++			      assert (mblength != (size_t)-1 &&
++				      mblength != (size_t)-2);
++
++			      mblength = (mblength < 1) ? 1 : mblength;
++			    }
++			}
++
++		      if (!flag)
++			{
++			  for (i = 0; i < mblength; i++)
++			    mbc[i] = *p++;
++			}
++		    }
++
++		  for (i = 0; i < mblength; i++)
++		    h = HASH (h, mbc[i]);
++		}
++	    }
++	}
++      else
++#endif
++
+       /* Hash this line until we find a newline.  */
+       switch (ig_white_space)
+ 	{
+@@ -397,7 +708,7 @@ find_and_hash_each_line (struct file_dat
+ 	    else if (!diff_length_compare_anyway)
+ 	      continue;
+ 
+-	    if (! lines_differ (eqline, ip))
++	    if (! lines_differ (eqline, eqs[i].length + 1, ip, length + 1))
+ 	      break;
+ 	  }
+ 
+diff -up diffutils-3.6/src/util.c.i18n diffutils-3.6/src/util.c
+--- diffutils-3.6/src/util.c.i18n	2017-05-18 18:39:59.000000000 +0100
++++ diffutils-3.6/src/util.c	2017-05-22 10:51:09.050371844 +0100
+@@ -985,7 +985,8 @@ finish_output (void)
+    Return nonzero if the lines differ.  */
+ 
+ bool
+-lines_differ (char const *s1, char const *s2)
++lines_differ_singlebyte (char const *s1, size_t s1len,
++			 char const *s2, size_t s2len)
+ {
+   register char const *t1 = s1;
+   register char const *t2 = s2;
+@@ -1141,6 +1142,354 @@ lines_differ (char const *s1, char const
+ 
+   return true;
+ }
++
++#ifdef HANDLE_MULTIBYTE
++# define MBC2WC(T, END, MBLENGTH, WC, STATE, CONVFAIL)	\
++do							\
++  {							\
++    mbstate_t bak = STATE;				\
++							\
++    CONVFAIL = 0;					\
++    MBLENGTH = mbrtowc (&WC, T, END - T, &STATE);	\
++							\
++    switch (MBLENGTH)					\
++      {							\
++      case (size_t)-2:					\
++      case (size_t)-1:					\
++	STATE = bak;					\
++	++CONVFAIL;					\
++	/* Fall through. */				\
++      case 0:						\
++	MBLENGTH = 1;					\
++      }							\
++  }							\
++ while (0)
++
++bool
++lines_differ_multibyte (char const *s1, size_t s1len,
++			char const *s2, size_t s2len)
++{
++  char const *end1, *end2;
++  char c1, c2;
++  wchar_t wc1, wc2, wc1_bak, wc2_bak;
++  size_t mblen1, mblen2;
++  mbstate_t state1, state2, state1_bak, state2_bak;
++  int convfail1, convfail2, convfail1_bak, convfail2_bak;
++  
++  char const *t1 = s1;
++  char const *t2 = s2;
++  char const *t1_bak, *t2_bak;
++  size_t column = 0;
++
++  if (ignore_white_space == IGNORE_NO_WHITE_SPACE  && !ignore_case)
++    {
++      while (*t1 != '\n')
++	if (*t1++ != *t2++)
++	  return 1;
++      return 0;
++    }
++
++  end1 = t1 + s1len;
++  end2 = t2 + s2len;
++
++  memset (&state1, '\0', sizeof (mbstate_t));
++  memset (&state2, '\0', sizeof (mbstate_t));
++
++  while (1)
++    {
++      c1 = *t1;
++      c2 = *t2;
++      MBC2WC (t1, end1, mblen1, wc1, state1, convfail1);
++      MBC2WC (t2, end2, mblen2, wc2, state2, convfail2);
++
++      /* Test for exact char equality first, since it's a common case.  */
++      if (convfail1 ^ convfail2)
++	break;
++      else if (convfail1 && convfail2 && c1 != c2)
++	break;
++      else if (!convfail1 && !convfail2 && wc1 != wc2)
++	{
++	  switch (ignore_white_space)
++	    {
++	    case IGNORE_ALL_SPACE:
++	      /* For -w, just skip past any white space.  */
++	      while (1)
++		{
++		  if (convfail1)
++		    break;
++		  else if (wc1 == L'\n' || !iswspace (wc1))
++		    break;
++
++		  t1 += mblen1;
++		  c1 = *t1;
++		  MBC2WC (t1, end1, mblen1, wc1, state1, convfail1);
++		}
++
++	      while (1)
++		{
++		  if (convfail2)
++		    break;
++		  else if (wc2 == L'\n' || !iswspace (wc2))
++		    break;
++
++		  t2 += mblen2;
++		  c2 = *t2;
++		  MBC2WC (t2, end2, mblen2, wc2, state2, convfail2);
++		}
++	      t1 += mblen1;
++	      t2 += mblen2;
++	      break;
++
++	    case IGNORE_SPACE_CHANGE:
++	      /* For -b, advance past any sequence of white space in
++		 line 1 and consider it just one space, or nothing at
++		 all if it is at the end of the line.  */
++	      if (wc1 != L'\n' && iswspace (wc1))
++		{
++		  size_t mblen_bak;
++		  mbstate_t state_bak;
++
++		  do
++		    {
++		      t1 += mblen1;
++		      mblen_bak = mblen1;
++		      state_bak = state1;
++		      MBC2WC (t1, end1, mblen1, wc1, state1, convfail1);
++		    }
++		  while (!convfail1 && (wc1 != L'\n' && iswspace (wc1)));
++
++		  state1 = state_bak;
++		  mblen1 = mblen_bak;
++		  t1 -= mblen1;
++		  convfail1 = 0;
++		  wc1 = L' ';
++		}
++
++	      /* Likewise for line 2.  */
++	      if (wc2 != L'\n' && iswspace (wc2))
++		{
++		  size_t mblen_bak;
++		  mbstate_t state_bak;
++
++		  do
++		    {
++		      t2 += mblen2;
++		      mblen_bak = mblen2;
++		      state_bak = state2;
++		      MBC2WC (t2, end2, mblen2, wc2, state2, convfail2);
++		    }
++		  while (!convfail2 && (wc2 != L'\n' && iswspace (wc2)));
++
++		  state2 = state_bak;
++		  mblen2 = mblen_bak;
++		  t2 -= mblen2;
++		  convfail2 = 0;
++		  wc2 = L' ';
++		}
++
++	      if (wc1 != wc2)
++		{
++		  /* If we went too far when doing the simple test for
++		     equality, go back to the first non-whitespace
++		     character in both sides and try again.  */
++		  if (wc2 == L' ' && wc1 != L'\n' &&
++		      t1 > s1 &&
++		      !convfail1_bak && iswspace (wc1_bak))
++		    {
++		      t1 = t1_bak;
++		      wc1 = wc1_bak;
++		      state1 = state1_bak;
++		      convfail1 = convfail1_bak;
++		      continue;
++		    }
++		  if (wc1 == L' ' && wc2 != L'\n'
++		      && t2 > s2
++		      && !convfail2_bak && iswspace (wc2_bak))
++		    {
++		      t2 = t2_bak;
++		      wc2 = wc2_bak;
++		      state2 = state2_bak;
++		      convfail2 = convfail2_bak;
++		      continue;
++		    }
++		}
++
++	      t1_bak = t1;		  t2_bak = t2;
++	      wc1_bak = wc1;		  wc2_bak = wc2;
++	      state1_bak = state1;	  state2_bak = state2;
++	      convfail1_bak = convfail1;  convfail2_bak = convfail2;
++
++	      if (wc1 == L'\n')
++		wc1 = L' ';
++	      else
++		t1 += mblen1;
++
++	      if (wc2 == L'\n')
++		wc2 = L' ';
++	      else
++		t2 += mblen2;
++
++	      break;
++
++	    case IGNORE_TRAILING_SPACE:
++	    case IGNORE_TAB_EXPANSION_AND_TRAILING_SPACE:
++	      if (iswspace (wc1) && iswspace (wc2))
++		{
++		  char const *p;
++		  wchar_t wc;
++		  size_t mblength;
++		  int convfail;
++		  mbstate_t state;
++		  bool just_whitespace_left = 1;
++		  if (wc1 != L'\n')
++		    {
++		      mblength = mblen1;
++		      p = t1;
++		      memset (&state, '\0', sizeof(mbstate_t));
++		      while (p < end1)
++			{
++			  if (*p == '\n')
++			    break;
++
++			  p += mblength;
++			  MBC2WC (p, end1, mblength, wc, state, convfail);
++			  if (convfail || !iswspace (wc))
++			    {
++			      just_whitespace_left = 0;
++			      break;
++			    }
++			}
++		    }
++		  if (just_whitespace_left && wc2 != L'\n')
++		    {
++		      mblength = mblen2;
++		      p = t2;
++		      memset (&state, '\0', sizeof(mbstate_t));
++		      while (p < end2)
++			{
++			  if (*p == '\n')
++			    break;
++
++			  p += mblength;
++			  MBC2WC (p, end2, mblength, wc, state, convfail);
++			  if (convfail || !iswspace (wc))
++			    {
++			      just_whitespace_left = 0;
++			      break;
++			    }
++			}
++		    }
++
++		  if (just_whitespace_left)
++		    /* Both lines have nothing but whitespace left.  */
++		    return false;
++		}
++
++	      if (ignore_white_space == IGNORE_TRAILING_SPACE)
++		break;
++	      /* Fall through.  */
++	    case IGNORE_TAB_EXPANSION:
++	      if ((wc1 == L' ' && wc2 == L'\t')
++		  || (wc1 == L'\t' && wc2 == L' '))
++		{
++		  size_t column2 = column;
++
++		  while (1)
++		    {
++		      if (convfail1)
++			{
++			  ++t1;
++			  break;
++			}
++		      else if (wc1 == L' ')
++			column++;
++		      else if (wc1 == L'\t')
++			column += tabsize - column % tabsize;
++		      else
++			{
++			  t1 += mblen1;
++			  break;
++			}
++
++		      t1 += mblen1;
++		      c1 = *t1;
++		      MBC2WC (t1, end1, mblen1, wc1, state1, convfail1);
++		    }
++
++		  while (1)
++		    {
++		      if (convfail2)
++			{
++			  ++t2;
++			  break;
++			}
++		      else if (wc2 == L' ')
++			column2++;
++		      else if (wc2 == L'\t')
++			column2 += tabsize - column2 % tabsize;
++		      else
++			{
++			  t2 += mblen2;
++			  break;
++			}
++
++		      t2 += mblen2;
++		      c2 = *t2;
++		      MBC2WC (t2, end2, mblen2, wc2, state2, convfail2);
++		    }
++
++		  if (column != column2)
++		    return 1;
++		}
++	      else
++		{
++		  t1 += mblen1;
++		  t2 += mblen2;
++		}
++	      break;
++
++	    case IGNORE_NO_WHITE_SPACE:
++	      t1 += mblen1;
++	      t2 += mblen2;
++	      break;
++	    }
++
++	  /* Lowercase all letters if -i is specified.  */
++	  if (ignore_case)
++	    {
++	      if (!convfail1)
++		wc1 = towlower (wc1);
++	      if (!convfail2)
++		wc2 = towlower (wc2);
++	    }
++
++	  if (convfail1 ^ convfail2)
++	    break;
++	  else if (convfail1 && convfail2 && c1 != c2)
++	    break;
++	  else if (!convfail1 && !convfail2 && wc1 != wc2)
++	    break;
++	}
++      else
++	{
++	  t1_bak = t1;			t2_bak = t2;
++	  wc1_bak = wc1;		wc2_bak = wc2;
++	  state1_bak = state1;		state2_bak = state2;
++	  convfail1_bak = convfail1;	convfail2_bak = convfail2;
++
++	  t1 += mblen1;			t2 += mblen2;
++	}
++      
++      if (!convfail1 && wc1 == L'\n')
++	return 0;
++
++      column += convfail1 ? 1 :
++	(wc1 == L'\t') ? tabsize - column % tabsize : wcwidth (wc1);
++    }
++
++  return 1;
++}
++#endif
+ 
+ /* Find the consecutive changes at the start of the script START.
+    Return the last link before the first gap.  */
diff --git a/SPECS/diffutils.spec b/SPECS/diffutils.spec
new file mode 100644
index 0000000..e9a937e
--- /dev/null
+++ b/SPECS/diffutils.spec
@@ -0,0 +1,374 @@
+Summary: A GNU collection of diff utilities
+Name: diffutils
+Version: 3.6
+Release: 5%{?dist}
+Group: Applications/Text
+URL: http://www.gnu.org/software/diffutils/diffutils.html
+Source: ftp://ftp.gnu.org/gnu/diffutils/diffutils-%{version}.tar.xz
+Patch1: diffutils-cmp-s-empty.patch
+Patch2: diffutils-i18n.patch
+Patch3: diffutils-3.6-covscan.patch
+License: GPLv3+
+Requires(post): info
+Requires(preun): info
+Provides: bundled(gnulib)
+BuildRequires: help2man
+BuildRequires: autoconf, automake, texinfo
+
+%description
+Diffutils includes four utilities: diff, cmp, diff3 and sdiff. Diff
+compares two files and shows the differences, line by line.  The cmp
+command shows the offset and line numbers where two files differ, or
+cmp can show the characters that differ between the two files.  The
+diff3 command shows the differences between three files.  Diff3 can be
+used when two people have made independent changes to a common
+original; diff3 can produce a merged file that contains both sets of
+changes and warnings about conflicts.  The sdiff command can be used
+to merge two files interactively.
+
+Install diffutils if you need to compare text files.
+
+%prep
+%setup -q
+# For 'cmp -s', compare file sizes only if both non-zero (bug #563618).
+%patch1 -p1 -b .cmp-s-empty
+
+%patch2 -p1 -b .i18n
+# covscan issues
+%patch3 -p1 -b .covscan
+
+# Run autoreconf for aarch64 support (bug #925256).
+autoreconf
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS -Dlint"
+%configure
+make PR_PROGRAM=%{_bindir}/pr
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+%find_lang %{name}
+
+%check
+# Disable update-copyright gnulib test (bug #1239428).
+>gnulib-tests/test-update-copyright.sh
+make check
+
+%post
+/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
+
+%preun
+if [ $1 = 0 ]; then
+  /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
+fi
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files -f %{name}.lang
+%defattr(-,root,root)
+%doc NEWS README
+%{!?_licensedir:%global license %%doc}
+%license COPYING
+%{_bindir}/*
+%{_mandir}/*/*
+%{_infodir}/diffutils.info*gz
+
+%changelog
+* Mon Aug 13 2018 Than Ngo <than@redhat.com> - 3.6-5
+- Resolves: #1606949, covscan issues
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.6-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.6-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Mon May 22 2017 Tim Waugh <twaugh@redhat.com> - 3.6-1
+- 3.6 (bug #1453019).
+
+* Tue Feb 21 2017 Than Ngo <than@redhat.com> - 3.5-3
+- backport to fix  FTBFs with GCC 7
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.5-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Wed Sep 21 2016 Tim Waugh <twaugh@redhat.com> - 3.5-1
+- 3.5 (bug #1365325).
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 3.3-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Mon Jul  6 2015 Tim Waugh <twaugh@redhat.com> - 3.3-12
+- Disable update-copyright gnulib test (bug #1239428).
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3-11
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Sat Feb 21 2015 Till Maas <opensource@till.name> - 3.3-10
+- Rebuilt for Fedora 23 Change
+  https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
+
+* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Fri Jul 11 2014 Tom Callaway <spot@fedoraproject.org> - 3.3-8
+- fix license handling
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Thu Mar 27 2014 Tim Waugh <twaugh@redhat.com> 3.3-6
+- Fix --help output and man page (bug #1079076).
+
+* Wed Dec  4 2013 Tim Waugh <twaugh@redhat.com> 3.3-5
+- Applied upstream gnulib patch to avoid -Wformat-security warning
+  (bug #1037038).
+
+* Wed Oct 23 2013 Tim Waugh <twaugh@redhat.com> 3.3-4
+- Fixed multibyte handling logic for diff -Z (bug #1012075).
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Apr 29 2013 Tim Waugh <twaugh@redhat.com> 3.3-2
+- Run autoreconf for aarch64 support (bug #925256).
+
+* Tue Mar 26 2013 Tim Waugh <twaugh@redhat.com> 3.3-1
+- 3.3 (bug #927560).
+
+* Fri Feb 22 2013 Tim Waugh <twaugh@redhat.com> 3.2-13
+- Fixed i18n handling of 'diff -E' (bug #914666).
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2-12
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Fri Oct 26 2012 Tim Waugh <twaugh@redhat.com> 3.2-11
+- Ported i18n patch and reinstated it (bug #870460).
+
+* Wed Sep 19 2012 Tim Waugh <twaugh@redhat.com> 3.2-10
+- Fixed license as current source says GPLv3+.
+
+* Mon Jul 23 2012 Tim Waugh <twaugh@redhat.com> 3.2-9
+- Fixed build failure.
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Mon May 21  2012 Tim Waugh <twaugh@redhat.com> 3.2-7
+- Provides bundled(gnulib) (bug #821751).
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Thu Dec  8 2011 Tim Waugh <twaugh@redhat.com> 3.2-5
+- Fix bug #747969 again.
+
+* Tue Nov 29 2011 Tim Waugh <twaugh@redhat.com> 3.2-4
+- Real fix for bug #747969: the diffutils info file changed name in
+  3.1.  Updated the scriptlets to install/remove the correct filename
+  from the info directory.
+
+* Fri Nov 25 2011 Tim Waugh <twaugh@redhat.com> 3.2-3
+- Fixed up reference to info page in man pages (bug #747969).
+
+* Fri Nov 25 2011 Tim Waugh <twaugh@redhat.com> 3.2-2
+- Applied upstream gnulib fix for float test on ppc, as well as
+  correction for LDBL_MANT_DIG definition (bug #733536).
+
+* Fri Sep  2 2011 Tim Waugh <twaugh@redhat.com> 3.2-1
+- 3.2.
+
+* Thu Aug 11 2011 Tim Waugh <twaugh@redhat.com> 3.1-1
+- 3.1.
+
+* Wed Apr 13 2011 Tim Waugh <twaugh@redhat.com> 3.0-1
+- 3.0 (bug #566482).
+- The i18n patch is dropped for the time being.
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.8.1-30
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Fri Jun 25 2010 Tim Waugh <twaugh@redhat.com> 2.8.1-29
+- For 'cmp -s', compare file sizes only if both non-zero (bug #563618).
+
+* Wed Apr 21 2010 Tim Waugh <twaugh@redhat.com> - 2.8.1-28
+- Build requires help2man (bug #577325).  Fixes empty diff man page.
+
+* Wed Mar  3 2010 Tim Waugh <twaugh@redhat.com> - 2.8.1-27
+- Added comments for all patches.
+
+* Wed Mar  3 2010 Tim Waugh <twaugh@redhat.com> - 2.8.1-26
+- Use upstream man pages.
+- Ship COPYING file.
+
+* Tue Aug 11 2009 Tim Waugh <twaugh@redhat.com> 2.8.1-25
+- Only try to install the info file if it exists so that package
+  installation does not fail with --excludedocs (bug #515919).
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.8.1-24
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.8.1-23
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Fri Feb 13 2009 Tim Waugh <twaugh@redhat.com> 2.8.1-22
+- Fixed 'sdiff -E' (bug #484892).
+
+* Wed Feb 13 2008 Tim Waugh <twaugh@redhat.com> 2.8.1-21
+- Rebuild for GCC 4.3.
+
+* Wed Jan  2 2008 Tim Waugh <twaugh@redhat.com> 2.8.1-20
+- Converted spec file to UTF-8 (bug #225696).
+- Fixed summary (bug #225696).
+- Fixed PreReq (bug #225696).
+- Removed Prefix (bug #225696).
+- Fixed build root (bug #225696).
+- Avoid %%makeinstall (bug #225696).
+- Fixed license tag (bug #225696).
+
+* Tue Nov  6 2007 Tim Waugh <twaugh@redhat.com> 2.8.1-19
+- Rebuilt.
+
+* Tue Nov  6 2007 Tim Waugh <twaugh@redhat.com> 2.8.1-18
+- Fixed multibyte speed improvement patch (bug #363831).
+
+* Tue Aug 14 2007 Tim Waugh <twaugh@redhat.com> 2.8.1-17
+- Multibyte speed improvement (bug #252117).
+
+* Mon Jan 22 2007 Tim Waugh <twaugh@redhat.com> 2.8.1-16
+- Make scriptlet unconditionally succeed (bug #223683).
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 2.8.1-15.2.2
+- rebuild
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 2.8.1-15.2.1
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 2.8.1-15.2
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Wed Apr  6 2005 Tim Waugh <twaugh@redhat.com> 2.8.1-15
+- Fixed sdiff exit code handling (bug #152967).
+
+* Wed Mar  2 2005 Tim Waugh <twaugh@redhat.com> 2.8.1-14
+- Rebuild for new GCC.
+
+* Wed Feb  9 2005 Tim Waugh <twaugh@redhat.com> 2.8.1-13
+- Rebuilt.
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Thu Jan  8 2004 Tim Waugh <twaugh@redhat.com> 2.8.1-10
+- Fix mistaken use of '|' instead of '||'.
+
+* Sat Oct 25 2003 Tim Waugh <twaugh@redhat.com> 2.8.1-9
+- Rebuilt.
+
+* Tue Jun 17 2003 Tim Waugh <twaugh@redhat.com> 2.8.1-8
+- Rebuilt.
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
+- rebuilt
+
+* Tue Nov 19 2002 Tim Waugh <twaugh@redhat.com> 2.8.1-5
+- i18n patch.
+
+* Tue Oct 22 2002 Tim Waugh <twaugh@redhat.com> 2.8.1-4
+- Ship translations.
+
+* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Thu May 23 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Mon Apr 22 2002 Tim Waugh <twaugh@redhat.com> 2.8.1-1
+- 2.8.1.
+- No longer need immunix-owl-tmp patch.
+
+* Wed Feb 27 2002 Tim Waugh <twaugh@redhat.com> 2.7.2-5
+- Rebuild in new environment.
+
+* Wed Jan 09 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Fri Nov 02 2001 Tim Waugh <twaugh@redhat.com> 2.7.2-3
+- Make sure %%post scriplet doesn't fail if --excludedocs is used.
+
+* Fri Jun 01 2001 Tim Waugh <twaugh@redhat.com> 2.7.2-2
+- Install diff.1, since it's no longer in man-pages.
+
+* Fri Mar 30 2001 Tim Waugh <twaugh@redhat.com> 2.7.2-1
+- 2.7.2.
+
+* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
+- automatic rebuild
+
+* Thu Jul 06 2000 Trond Eivind Glomsrød <teg@redhat.com>
+- fix %%changelog entries (escape them)
+- update source location
+- remove manual stripping
+- add URL
+
+* Tue Jun 06 2000 Than Ngo <than@redhat.de>
+- add %%defattr
+- use rpm macros
+
+* Wed May 31 2000 Ngo Than <than@redhat.de>
+- put man pages and info files in correct place
+- cleanup specfile
+
+* Thu Feb 03 2000 Preston Brown <pbrown@redhat.com>
+- rebuild to gzip man pages.
+
+* Mon Apr 19 1999 Jeff Johnson <jbj@redhat.com>
+- man pages not in %%files.
+- but avoid conflict for diff.1
+
+* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com> 
+- auto rebuild in the new build environment (release 14)
+
+* Sun Mar 14 1999 Jeff Johnson <jbj@redhat.com>
+- add man pages (#831).
+- add %%configure and Prefix.
+
+* Thu Dec 17 1998 Cristian Gafton <gafton@redhat.com>
+- build for glibc 2.1
+
+* Tue Jul 14 1998 Bill Kawakami <billk@home.com>
+- included the four man pages stolen from Slackware
+
+* Tue May 05 1998 Prospector System <bugs@redhat.com>
+- translations modified for de, fr, tr
+
+* Sun May 03 1998 Cristian Gafton <gafton@redhat.com>
+- fixed spec file to reference/use the $RPM_BUILD_ROOT always
+    
+* Wed Dec 31 1997 Otto Hammersmith <otto@redhat.com>
+- fixed where it looks for 'pr' (/usr/bin, rather than /bin)
+
+* Fri Oct 17 1997 Donnie Barnes <djb@redhat.com>
+- added BuildRoot
+
+* Sun Sep 14 1997 Erik Troan <ewt@redhat.com>
+- uses install-info
+
+* Mon Jun 02 1997 Erik Troan <ewt@redhat.com>
+- built against glibc