--- cpio-2.4.2/copyin.c.fbsd	Mon Oct  1 13:50:04 2001
+++ cpio-2.4.2/copyin.c	Mon Oct  1 13:50:05 2001
@@ -13,6 +13,13 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if ((defined(BSD) && (BSD >= 199306)) || defined(__GLIBC__))
+#define HAVE_STRFTIME
+#include <ctype.h>
+#endif
 #include "filetypes.h"
 #include "system.h"
 #include "cpiohdr.h"
@@ -28,6 +38,9 @@
 #ifndef	FNM_PATHNAME
 #include <fnmatch.h>
 #endif
+#if defined(HAVE_STRFTIME)
+#include <langinfo.h>
+#endif
 
 /* Debian hack to fix a bug in the --sparse option.  This bug has been
    reported to "bug-gnu-utils@prep.ai.mit.edu".  (96/7/10) -BEM */
@@ -969,13 +982,24 @@
 		  break;
 		}
 	      
-	      res = mknod (file_hdr.c_name, file_hdr.c_mode,
-			makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
+#ifdef CP_IFIFO
+	      if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
+		res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
+	      else
+#endif
+		res = mknod (file_hdr.c_name, file_hdr.c_mode,
+		      makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
 	      if (res < 0 && create_dir_flag)
 		{
 		  create_all_directories (file_hdr.c_name);
-		  res = mknod (file_hdr.c_name, file_hdr.c_mode,
-			makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
+#ifdef CP_IFIFO
+		  if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
+		    res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
+		  else
+#endif
+		    res = mknod (file_hdr.c_name, file_hdr.c_mode,
+				 makedev (file_hdr.c_rdev_maj,
+					  file_hdr.c_rdev_min));
 		}
 	      if (res < 0)
 		{
@@ -1087,12 +1111,31 @@
   char mbuf[11];
   char tbuf[40];
   time_t when;
+  char *ptbuf;
+#ifdef HAVE_STRFTIME
+  static int d_first = -1;
+#endif
 
   mode_string (file_hdr->c_mode, mbuf);
   mbuf[10] = '\0';
 
   /* Get time values ready to print.  */
   when = file_hdr->c_mtime;
+#ifdef HAVE_STRFTIME
+#ifdef __FreeBSD__
+  if (d_first < 0)
+	d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
+#else
+  d_first = 0;
+#endif
+  if (current_time - when > 6L * 30L * 24L * 60L * 60L
+      || current_time - when < 0L)
+	ptbuf = d_first ? "%e %b  %Y" : "%b %e  %Y";
+  else
+	ptbuf = d_first ? "%e %b %R" : "%b %e %R";
+  strftime(tbuf, sizeof(tbuf), ptbuf, localtime(&when));
+  ptbuf = tbuf;
+#else
   strcpy (tbuf, ctime (&when));
   if (current_time - when > 6L * 30L * 24L * 60L * 60L
       || current_time - when < 0L)
@@ -1102,8 +1145,10 @@
       strcpy (tbuf + 11, tbuf + 19);
     }
   tbuf[16] = '\0';
+  ptbuf = tbuf + 4;
+#endif
 
-  printf ("%s %3u ", mbuf, file_hdr->c_nlink);
+  printf ("%s %3lu ", mbuf, file_hdr->c_nlink);
 
 #ifndef __MSDOS__
   if (numeric_uid)
@@ -1117,13 +1162,12 @@
 
   if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
       || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
-    printf ("%3u, %3u ", file_hdr->c_rdev_maj,
-	    file_hdr->c_rdev_min);
+    printf ("%3lu, %3lu ", file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
   else
 #endif
     printf ("%8lu ", file_hdr->c_filesize);
 
-  printf ("%s ", tbuf + 4);
+  printf ("%s ", ptbuf);
 
   print_name_with_quoting (file_hdr->c_name);
   if (link_name)
@@ -1179,6 +1223,9 @@
 	  break;
 
 	default:
+#if ((defined(BSD) && BSD >= 199306) || defined(__GLIBC__))
+	  if (isprint(c))
+#else
 	  if (c > 040 &&
 #ifdef __MSDOS__
 	      c < 0377 && c != 0177
@@ -1186,6 +1233,7 @@
 	      c < 0177
 #endif
 	    )
+#endif
 	    putchar (c);
 	  else
 	    printf ("\\%03o", (unsigned int) c);
--- cpio-2.4.2/copyout.c.fbsd	Mon Oct  1 13:50:04 2001
+++ cpio-2.4.2/copyout.c	Mon Oct  1 13:51:21 2001
@@ -36,6 +36,7 @@
 static void writeout_final_defers();
 static void writeout_defered_file ();
 static void check_for_changed_file ();
+static int check_rdev ();
 
 /* Write out header FILE_HDR, including the file name, to file
    descriptor OUT_DES.  */
@@ -294,8 +295,32 @@
 	  file_hdr.c_uid = file_stat.st_uid;
 	  file_hdr.c_gid = file_stat.st_gid;
 	  file_hdr.c_nlink = file_stat.st_nlink;
-	  file_hdr.c_rdev_maj = major (file_stat.st_rdev);
-	  file_hdr.c_rdev_min = minor (file_stat.st_rdev);
+
+	  /* The rdev is meaningless except for block and character
+	     special files (POSIX standard) and perhaps fifos and
+	     sockets.  Clear it for other types of files so that
+	     check_rdev() doesn't reject files just because stat()
+	     put garbage in st_rdev and so that the output doesn't
+	     depend on the garbage.  */
+	  switch (file_hdr.c_mode & CP_IFMT)
+	    {
+	      case CP_IFBLK:
+	      case CP_IFCHR:
+#ifdef CP_IFIFO
+	      case CP_IFIFO:
+#endif
+#ifdef CP_IFSOCK
+	      case CP_IFSOCK:
+#endif
+		file_hdr.c_rdev_maj = major (file_stat.st_rdev);
+		file_hdr.c_rdev_min = minor (file_stat.st_rdev);
+		break;
+	      default:
+	      	file_hdr.c_rdev_maj = 0;
+		file_hdr.c_rdev_min = 0;
+		break;
+	    }
+
 	  file_hdr.c_mtime = file_stat.st_mtime;
 	  file_hdr.c_filesize = file_stat.st_size;
 	  file_hdr.c_chksum = 0;
@@ -339,6 +364,23 @@
 	      continue;
 	    }
 
+	  switch (check_rdev (&file_hdr))
+	    {
+	      case 1:
+		error (0, 0, "%s not dumped: major number would be truncated",
+		       file_hdr.c_name);
+		continue;
+	      case 2:
+		error (0, 0, "%s not dumped: minor number would be truncated",
+		       file_hdr.c_name);
+		continue;
+	      case 4:
+		error (0, 0, "%s not dumped: device number would be truncated",
+		       file_hdr.c_name);
+		continue;
+	    }
+
+
 	  /* Copy the named file to the output.  */
 	  switch (file_hdr.c_mode & CP_IFMT)
 	    {
@@ -822,6 +864,102 @@
   return;
 }
 
+
+static int
+check_rdev (file_hdr)
+     struct new_cpio_header *file_hdr;
+{
+  if (archive_format == arf_newascii || archive_format == arf_crcascii)
+    {
+      if ((file_hdr->c_rdev_maj & 0xFFFFFFFF) != file_hdr->c_rdev_maj)
+        return 1;
+      if ((file_hdr->c_rdev_min & 0xFFFFFFFF) != file_hdr->c_rdev_min)
+        return 2;
+    }
+  else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
+    {
+#ifndef __MSDOS__
+      dev_t rdev;
+
+      rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
+      if (archive_format == arf_oldascii)
+	{
+	  if ((rdev & 0xFFFF) != rdev)
+	    return 4;
+	}
+      else
+	{
+	  switch (file_hdr->c_mode & CP_IFMT)
+	    {
+	      case CP_IFCHR:
+	      case CP_IFBLK:
+#ifdef CP_IFSOCK
+	      case CP_IFSOCK:
+#endif
+#ifdef CP_IFIFO
+	      case CP_IFIFO:
+#endif
+		/* We could handle one more bit if longs are >= 33 bits.  */
+		if ((rdev & 037777777777) != rdev)
+		  return 4;
+		break;
+	      default:
+		if ((rdev & 0xFFFF) != rdev)
+		  return 4;
+		break;
+	    }
+	}
+#endif
+    }
+  else if (archive_format == arf_tar || archive_format == arf_ustar)
+    {
+      /* The major and minor formats are limited to 7 octal digits in ustar
+	 format, and to_oct () adds a gratuitous trailing blank to further
+	 limit the format to 6 octal digits.  */
+      if ((file_hdr->c_rdev_maj & 0777777) != file_hdr->c_rdev_maj)
+        return 1;
+      if ((file_hdr->c_rdev_min & 0777777) != file_hdr->c_rdev_min)
+        return 2;
+    }
+  else
+    {
+#ifndef __MSDOS__
+      dev_t rdev;
+
+      rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
+      if (archive_format != arf_hpbinary)
+	{
+	  if ((rdev & 0xFFFF) != rdev)
+	return 4;
+    }
+  else
+    {
+      switch (file_hdr->c_mode & CP_IFMT)
+	{
+	  case CP_IFCHR:
+	  case CP_IFBLK:
+#ifdef CP_IFSOCK
+	  case CP_IFSOCK:
+#endif
+#ifdef CP_IFIFO
+	  case CP_IFIFO:
+#endif
+	    if ((rdev & 0xFFFFFFFF) != rdev)
+	      return 4;
+	    file_hdr->c_filesize = rdev;
+	    rdev = makedev (0, 1);
+	    break;
+	  default:
+	    if ((rdev & 0xFFFF) != rdev)
+	      return 4;
+	    break;
+	}
+    }
+#endif
+  }
+  return 0;
+}
+
 static void
 check_for_changed_file (name, header)
      char *name;
--- cpio-2.4.2/copypass.c.fbsd	Mon Oct  1 13:50:05 2001
+++ cpio-2.4.2/copypass.c	Mon Oct  1 13:50:05 2001
@@ -311,13 +311,23 @@
 
 	  if (link_res < 0)
 	    {
-	      res = mknod (output_name.ds_string, in_file_stat.st_mode,
-			   in_file_stat.st_rdev);
+#ifdef S_ISFIFO
+	      if (S_ISFIFO (in_file_stat.st_mode))
+		res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
+	      else
+#endif
+		res = mknod (output_name.ds_string, in_file_stat.st_mode,
+			     in_file_stat.st_rdev);
 	      if (res < 0 && create_dir_flag)
 		{
 		  create_all_directories (output_name.ds_string);
-		  res = mknod (output_name.ds_string, in_file_stat.st_mode,
-			       in_file_stat.st_rdev);
+#ifdef S_ISFIFO
+		  if (S_ISFIFO (in_file_stat.st_mode))
+		    res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
+		  else
+#endif
+		    res = mknod (output_name.ds_string, in_file_stat.st_mode,
+				 in_file_stat.st_rdev);
 		}
 	      if (res < 0)
 		{
--- cpio-2.4.2/main.c.fbsd	Mon Oct  1 13:50:05 2001
+++ cpio-2.4.2/main.c	Mon Oct  1 13:50:05 2001
@@ -19,7 +19,13 @@
 #include <stdio.h>
 #include <getopt.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if (defined(BSD) && (BSD >= 199306)) || defined(__GLIBC__)
+#include <locale.h>
+#endif
 #include "filetypes.h"
 #include "system.h"
 #include "cpiohdr.h"
@@ -508,13 +516,16 @@
   bzero (zeros_512, 512);
 }
 
-void
+int
 main (argc, argv)
      int argc;
      char *argv[];
 {
   program_name = argv[0];
-  umask (0);
+
+#if (defined(BSD) && (BSD >= 199306)) || defined(__GLIBC__)
+  (void) setlocale (LC_ALL, "");
+#endif
 
 #ifdef __TURBOC__
   _fmode = O_BINARY;		/* Put stdin and stdout in binary mode.  */
@@ -525,6 +536,7 @@
 #endif
 
   process_args (argc, argv);
+  umask (0);
 
   initialize_buffers ();
 
--- cpio-2.4.2/util.c.fbsd	Mon Oct  1 13:50:05 2001
+++ cpio-2.4.2/util.c	Mon Oct  1 13:50:05 2001
@@ -883,9 +883,9 @@
     fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number,
 	     new_media_message_after_number);
   else if (archive_name)
-    fprintf (tty_out, "Found end of tape.  Load next tape and press RETURN. ");
+    fprintf (tty_out, "Found end of volume.  Load next volume and press RETURN. ");
   else
-    fprintf (tty_out, "Found end of tape.  To continue, type device/file name when ready.\n");
+    fprintf (tty_out, "Found end of volume.  To continue, type device/file name when ready.\n");
 
   fflush (tty_out);
 
