diff -cp -r test/tar-1.12/configure tar-1.12/configure
*** test/tar-1.12/configure	Fri Apr 25 20:03:34 1997
--- tar-1.12/configure	Sat Sep 27 11:52:54 1997
*************** fi
*** 535,545 ****
  
  ac_aux_dir=
  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
!   if test -f $ac_dir/install-sh; then
      ac_aux_dir=$ac_dir
      ac_install_sh="$ac_aux_dir/install-sh -c"
      break
!   elif test -f $ac_dir/install.sh; then
      ac_aux_dir=$ac_dir
      ac_install_sh="$ac_aux_dir/install.sh -c"
      break
--- 535,545 ----
  
  ac_aux_dir=
  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
!   if test -x $ac_dir/install-sh; then
      ac_aux_dir=$ac_dir
      ac_install_sh="$ac_aux_dir/install-sh -c"
      break
!   elif test -x $ac_dir/install.sh; then
      ac_aux_dir=$ac_dir
      ac_install_sh="$ac_aux_dir/install.sh -c"
      break
*************** else
*** 576,582 ****
      *)
        # OSF1 and SCO ODT 3.0 have their own names for install.
        for ac_prog in ginstall installbsd scoinst install; do
!         if test -f $ac_dir/$ac_prog; then
  	  if test $ac_prog = install &&
              grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
  	    # AIX install.  It has an incompatible calling convention.
--- 576,582 ----
      *)
        # OSF1 and SCO ODT 3.0 have their own names for install.
        for ac_prog in ginstall installbsd scoinst install; do
!         if test -x $ac_dir/$ac_prog; then
  	  if test $ac_prog = install &&
              grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
  	    # AIX install.  It has an incompatible calling convention.
*************** else
*** 813,819 ****
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_prog_CC="gcc"
        break
      fi
--- 813,819 ----
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_prog_CC="gcc"
        break
      fi
*************** else
*** 843,849 ****
    ac_prog_rejected=no
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
          ac_prog_rejected=yes
  	continue
--- 843,849 ----
    ac_prog_rejected=no
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
          ac_prog_rejected=yes
  	continue
*************** else
*** 1164,1170 ****
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_prog_RANLIB="ranlib"
        break
      fi
--- 1164,1170 ----
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_prog_RANLIB="ranlib"
        break
      fi
*************** else
*** 1195,1201 ****
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_prog_YACC="$ac_prog"
        break
      fi
--- 1195,1201 ----
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_prog_YACC="$ac_prog"
        break
      fi
*************** else
*** 3272,3278 ****
      for ac_file in /usr/ucb/rsh /usr/bin/remsh /usr/bin/rsh /usr/bsd/rsh \
    	/usr/bin/nsh /usr/bin/rcmd
      do
!       if test -f $ac_file; then
          tar_cv_path_RSH=$ac_file
          break
        fi
--- 3272,3278 ----
      for ac_file in /usr/ucb/rsh /usr/bin/remsh /usr/bin/rsh /usr/bsd/rsh \
    	/usr/bin/nsh /usr/bin/rcmd
      do
!       if test -x $ac_file; then
          tar_cv_path_RSH=$ac_file
          break
        fi
*************** if eval "test \"`echo '$''{'ac_cv_path_M
*** 4090,4103 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$MSGFMT" in
!   /*)
    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_MSGFMT="$ac_dir/$ac_word"
  	break
--- 4090,4103 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$MSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_MSGFMT="$ac_dir/$ac_word"
  	break
*************** if eval "test \"`echo '$''{'ac_cv_path_G
*** 4179,4192 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
--- 4179,4192 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
*************** if eval "test \"`echo '$''{'ac_cv_path_X
*** 4211,4224 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
--- 4211,4224 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /* | [A-z]:/*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
*************** if eval "test \"`echo '$''{'ac_cv_path_G
*** 4380,4393 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GENCAT" in
!   /*)
    ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_path_GENCAT="$ac_dir/$ac_word"
        break
      fi
--- 4380,4393 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GENCAT" in
!   /* | [A-z]:/*)
    ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_path_GENCAT="$ac_dir/$ac_word"
        break
      fi
*************** if eval "test \"`echo '$''{'ac_cv_path_G
*** 4412,4425 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
--- 4412,4425 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
*************** if eval "test \"`echo '$''{'ac_cv_path_G
*** 4445,4458 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
  	break
--- 4445,4458 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
  	break
*************** if eval "test \"`echo '$''{'ac_cv_path_X
*** 4480,4493 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
--- 4480,4493 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /* | [A-z]:/*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
*************** if eval "test \"`echo '$''{'ac_cv_path_M
*** 4538,4551 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$MSGFMT" in
!   /*)
    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_MSGFMT="$ac_dir/$ac_word"
  	break
--- 4538,4551 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$MSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
  	ac_cv_path_MSGFMT="$ac_dir/$ac_word"
  	break
*************** if eval "test \"`echo '$''{'ac_cv_path_G
*** 4572,4585 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
--- 4572,4585 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$GMSGFMT" in
!   /* | [A-z]:/*)
    ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
        break
      fi
*************** if eval "test \"`echo '$''{'ac_cv_path_X
*** 4604,4617 ****
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -f $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
--- 4604,4617 ----
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    case "$XGETTEXT" in
!   /* | [A-z]:/*)
    ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
    ;;
    *)
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
!     if test -x $ac_dir/$ac_word; then
        if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
  	ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
  	break
*************** fi
*** 4745,4751 ****
                 sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
     fi
        sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
!      $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
  
              if test "$PACKAGE" = "gettext"; then
       GT_NO="#NO#"
--- 4745,4751 ----
                 sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
     fi
        sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
!      $srcdir/intl/po2tbl_sed.in > intl/po2tbl.sed
  
              if test "$PACKAGE" = "gettext"; then
       GT_NO="#NO#"
*************** for ac_option
*** 4868,4875 ****
  do
    case "\$ac_option" in
    -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
!     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
!     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
    -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
      echo "$CONFIG_STATUS generated by autoconf version 2.12"
      exit 0 ;;
--- 4868,4875 ----
  do
    case "\$ac_option" in
    -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
!     echo "running \${CONFIG_SHELL-bash} $0 $ac_configure_args --no-create --no-recursion"
!     exec \${CONFIG_SHELL-bash} $0 $ac_configure_args --no-create --no-recursion ;;
    -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
      echo "$CONFIG_STATUS generated by autoconf version 2.12"
      exit 0 ;;
*************** do
*** 4880,4886 ****
  done
  
  ac_given_srcdir=$srcdir
! ac_given_INSTALL="$INSTALL"
  
  trap 'rm -fr `echo "Makefile doc/Makefile intl/Makefile lib/Makefile po/Makefile.in \
  scripts/Makefile src/Makefile tests/Makefile tests/preset config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
--- 4880,4886 ----
  done
  
  ac_given_srcdir=$srcdir
! ac_given_INSTALL='$INSTALL'
  
  trap 'rm -fr `echo "Makefile doc/Makefile intl/Makefile lib/Makefile po/Makefile.in \
  scripts/Makefile src/Makefile tests/Makefile tests/preset config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
*************** s%@POSUB@%$POSUB%g
*** 4954,4959 ****
--- 4954,4963 ----
  s%@GT_NO@%$GT_NO%g
  s%@GT_YES@%$GT_YES%g
  s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+ s,\.h\.in,.h-in,g
+ s,\.sed\.in,_sed.in,g
+ s,\.inst\.in,_inst.in,g
+ s,\.tab\.,_tab.,g
  
  CEOF
  EOF
*************** EOF
*** 4995,5001 ****
  
  cat >> $CONFIG_STATUS <<EOF
  
! CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile intl/Makefile lib/Makefile po/Makefile.in \
  scripts/Makefile src/Makefile tests/Makefile tests/preset"}
  EOF
  cat >> $CONFIG_STATUS <<\EOF
--- 4999,5005 ----
  
  cat >> $CONFIG_STATUS <<EOF
  
! CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile intl/Makefile lib/Makefile po/Makefile.in:po/Makefile.in-in \
  scripts/Makefile src/Makefile tests/Makefile tests/preset"}
  EOF
  cat >> $CONFIG_STATUS <<\EOF
*************** for ac_file in .. $CONFIG_FILES; do if t
*** 5025,5038 ****
    .)  srcdir=.
        if test -z "$ac_dots"; then top_srcdir=.
        else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
!   /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
    *) # Relative path.
      srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
      top_srcdir="$ac_dots$ac_given_srcdir" ;;
    esac
  
    case "$ac_given_INSTALL" in
!   [/$]*) INSTALL="$ac_given_INSTALL" ;;
    *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
    esac
  
--- 5029,5042 ----
    .)  srcdir=.
        if test -z "$ac_dots"; then top_srcdir=.
        else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
!   /* | [A-z]:/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
    *) # Relative path.
      srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
      top_srcdir="$ac_dots$ac_given_srcdir" ;;
    esac
  
    case "$ac_given_INSTALL" in
!   [/$]* | [A-z]:/*) INSTALL="$ac_given_INSTALL" ;;
    *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
    esac
  
*************** ac_eD='%g'
*** 5077,5083 ****
  if test "${CONFIG_HEADERS+set}" != set; then
  EOF
  cat >> $CONFIG_STATUS <<EOF
!   CONFIG_HEADERS="config.h"
  EOF
  cat >> $CONFIG_STATUS <<\EOF
  fi
--- 5081,5087 ----
  if test "${CONFIG_HEADERS+set}" != set; then
  EOF
  cat >> $CONFIG_STATUS <<EOF
!   CONFIG_HEADERS="config.h:config.h-in"
  EOF
  cat >> $CONFIG_STATUS <<\EOF
  fi
*************** while test -n "$ac_sources"; do
*** 5196,5202 ****
    fi
  
    case "$srcdir" in
!   [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
    *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
    esac
  
--- 5200,5206 ----
    fi
  
    case "$srcdir" in
!   [/$]* | [A-z]:/*) ac_rel_source="$srcdir/$ac_source" ;;
    *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
    esac
  
*************** exit 0
*** 5219,5223 ****
  EOF
  chmod +x $CONFIG_STATUS
  rm -fr confdefs* $ac_clean_files
! test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
  
--- 5223,5227 ----
  EOF
  chmod +x $CONFIG_STATUS
  rm -fr confdefs* $ac_clean_files
! test "$no_create" = yes || ${CONFIG_SHELL-bash} $CONFIG_STATUS || exit 1
  
diff -cp -r test/tar-1.12/doc/tar.texi tar-1.12/doc/tar.texi
*** test/tar-1.12/doc/tar.texi	Thu Apr 24 13:19:40 1997
--- tar-1.12/doc/tar.texi	Fri Oct 10 21:00:26 1997
***************
*** 126,132 ****
  @set xref-block-number @xref{verbose}
  @set pxref-block-number @pxref{verbose}
  
! @set op-blocking-factor @kbd{--blocking-factor=@var{512-size}} (@kbd{-b @var{512-size}})
  @set ref-blocking-factor @ref{Blocking Factor}
  @set xref-blocking-factor @xref{Blocking Factor}
  @set pxref-blocking-factor @pxref{Blocking Factor}
--- 126,132 ----
  @set xref-block-number @xref{verbose}
  @set pxref-block-number @pxref{verbose}
  
! @set op-blocking-factor @kbd{--blocking-factor=@var{blocks}} (@kbd{-b @var{blocks}})
  @set ref-blocking-factor @ref{Blocking Factor}
  @set xref-blocking-factor @xref{Blocking Factor}
  @set pxref-blocking-factor @pxref{Blocking Factor}
***************
*** 376,382 ****
  @set xref-suffix @xref{Backup options}
  @set pxref-suffix @pxref{Backup options}
  
! @set op-tape-length @kbd{--tape-length=@var{1024-size}} (@kbd{-L @var{1024-size}})
  @set ref-tape-length @ref{Using Multiple Tapes}
  @set xref-tape-length @xref{Using Multiple Tapes}
  @set pxref-tape-length @pxref{Using Multiple Tapes}
--- 376,382 ----
  @set xref-suffix @xref{Backup options}
  @set pxref-suffix @pxref{Backup options}
  
! @set op-tape-length @kbd{--tape-length=@var{KBytes}} (@kbd{-L @var{KBytes}})
  @set ref-tape-length @ref{Using Multiple Tapes}
  @set xref-tape-length @xref{Using Multiple Tapes}
  @set pxref-tape-length @pxref{Using Multiple Tapes}
*************** or comments.
*** 801,807 ****
  
  The second chapter is a tutorial (@pxref{Tutorial}) which provides a
  gentle introduction for people who are new to using @code{tar}.  It is
! meant to be self contained, not requiring any reading from subsequent
  chapters to make sense.  It moves from topic to topic in a logical,
  progressive order, building on information already explained.
  
--- 801,807 ----
  
  The second chapter is a tutorial (@pxref{Tutorial}) which provides a
  gentle introduction for people who are new to using @code{tar}.  It is
! meant to be self-contained, not requiring any reading from subsequent
  chapters to make sense.  It moves from topic to topic in a logical,
  progressive order, building on information already explained.
  
*************** with tape drives.  @xref{Media} for comp
*** 1100,1105 ****
--- 1100,1109 ----
  @heading Stylistic Conventions
  @end ifinfo
  
+ @FIXME{all of the three fonts mentioned in the next paragraph look the
+ same in Info, which makes people wonder what's going on here.  should
+ use ifinfo and iftex.}
+ 
  In the examples, @samp{$} represents a typical shell prompt.  It
  precedes lines you should type; to make this more clear, those lines are
  shown in @kbd{this font}, as opposed to lines which represent the
*************** This is an example of a line which would
*** 1117,1125 ****
  @section Basic @code{tar} Operations and Options
  
  @code{tar} can take a wide variety of arguments which specify and define
! the actions it will have on the particular set of files or the archive.
! The main types of arguments to @code{tar} fall into one of two classes:
! operations, and options.
  
  Some arguments fall into a class called @dfn{operations}; exactly one of
  these is both allowed and required for any instance of using @code{tar};
--- 1121,1129 ----
  @section Basic @code{tar} Operations and Options
  
  @code{tar} can take a wide variety of arguments which specify and define
! the actions it will have @FIXME{HAVE actions??} on the particular set
! of files or the archive.  The main types of arguments to @code{tar} fall
! into one of two classes: operations, and options.
  
  Some arguments fall into a class called @dfn{operations}; exactly one of
  these is both allowed and required for any instance of using @code{tar};
*************** You can specify an argument for the @val
*** 1241,1251 ****
  use @code{tar}; this option determines the name of the archive file
  that @code{tar} will work on.
  
! If you don't specify this argument, then @code{tar} will use a
! default, usually some physical tape drive attached to your machine.
! If there is no tape drive attached, or the default is not meaningful,
! then @code{tar} will print an error message.  The error message might
! look roughly like one of the following:
  
  @example
  tar: can't open /dev/rmt8 : No such device or address
--- 1245,1255 ----
  use @code{tar}; this option determines the name of the archive file
  that @code{tar} will work on.
  
! If you don't specify this argument, then @code{tar} will use a default,
! usually standard output or standard input, or some physical tape drive
! attached to your machine.  If there is no tape drive attached, or the
! default is not meaningful, then @code{tar} will print an error message.
! The error message might look roughly like one of the following:
  
  @example
  tar: can't open /dev/rmt8 : No such device or address
*************** jazz
*** 1477,1488 ****
  @end example
  
  This example is just like the example we showed which did not use
! @samp{--verbose}, except that @code{tar} generated the remaining lines
  @iftex
! (note the different font styles).
  @end iftex
  @ifinfo
! .
  @end ifinfo
  
  In the rest of the examples in this chapter, we will frequently use
--- 1481,1492 ----
  @end example
  
  This example is just like the example we showed which did not use
! @samp{--verbose}, except that @code{tar} generated the remaining
  @iftex
! lines (note the different font styles).
  @end iftex
  @ifinfo
! lines.
  @end ifinfo
  
  In the rest of the examples in this chapter, we will frequently use
*************** following way:
*** 1521,1533 ****
  
  @example
  $ @kbd{tar -cfv collection.tar blues folk jazz}
  @end example
  
  @noindent
! In this case, @code{tar} will make an archive file called @file{v},
  containing the files @file{blues}, @file{folk}, and @file{jazz}, because
  the @samp{v} is the closest ``file name'' to the @samp{-f} option, and
! is thus taken to be the chosen archive file name.  @code{tar} will try
  to add a file called @file{collection.tar} to the @file{v} archive file;
  if the file @file{collection.tar} did not already exist, @code{tar} will
  report an error indicating that this file does not exist.  If the file
--- 1525,1543 ----
  
  @example
  $ @kbd{tar -cfv collection.tar blues folk jazz}
+ tar: Cannot add file collection.tar: No such file or directory
+ tar: Error exit delayed from previous errors
+ $ @kbd{ls}
+ blues   folk   jazz   v
+ $
  @end example
  
  @noindent
! You got error messages and a file called @file{v}.  What happened is
! that @code{tar} tried to make an archive file called @file{v}, 
  containing the files @file{blues}, @file{folk}, and @file{jazz}, because
  the @samp{v} is the closest ``file name'' to the @samp{-f} option, and
! is thus taken to be the chosen archive file name.  @code{tar} tried
  to add a file called @file{collection.tar} to the @file{v} archive file;
  if the file @file{collection.tar} did not already exist, @code{tar} will
  report an error indicating that this file does not exist.  If the file
*************** depend on this behavior unless you are c
*** 1644,1650 ****
  @code{tar}.  @FIXME{bob doesn't like this sentence, since he does it
  all the time, and we've been doing it in the editing passes for this
  manual: In general, make sure that the archive is not inside a
! directory being dumped.})
  
  @node list, extract, create, Tutorial
  @section How to List Archives
--- 1654,1663 ----
  @code{tar}.  @FIXME{bob doesn't like this sentence, since he does it
  all the time, and we've been doing it in the editing passes for this
  manual: In general, make sure that the archive is not inside a
! directory being dumped.})  Some MS-Windows file systems (notably,
! Windows 95 VFAT disks) don't support the feature which is used by GNU
! @code{tar} to detect that the archive is included in itself, so the
! archive @emph{will} be included on those file systems.
  
  @node list, extract, create, Tutorial
  @section How to List Archives
*************** expect to find; remember that if you use
*** 1724,1729 ****
--- 1737,1760 ----
  names as arguments, @code{tar} will print the names of all the members
  stored in the specified archive.
  
+ As an exception to member name preservation when creating the archive,
+ @code{tar} on MS-DOS/MS-Windows mirrors the DOS-style backslashes into
+ Unix-style forward slashes.  This is because the bulk of @code{tar} code
+ is deeply entrenched in the Unix world and assumes that forward slashes
+ are used in too many places.  Converting slashes automatically lets the
+ users specify files as they are used to on those systems.  But it also
+ means that you need to remember about this conversion, so you won't be
+ surprised when @code{tar} lists the files differently than what you
+ typed on the command line.  For example:
+ 
+ @smallexample
+ $ @kbd{tar -cvf c:\files\backup\today.tar d:\data\may97 d:\data\june97}
+ data/may97
+ data/june97
+ $ @kbd{tar -xvf c:\files\backup\today.tar data\may97}
+ data/may97
+ @end smallexample
+ 
  @menu
  * list dir::
  @end menu
*************** $ @kbd{tar -xvf collection.tar}
*** 1804,1812 ****
  produces this:
  
  @example
! -rw-rw-rw- me user     28 1996-10-18 16:31 jazz
! -rw-rw-rw- me user     21 1996-09-23 16:44 blues
! -rw-rw-rw- me user     20 1996-09-23 16:44 folk
  @end example
  
  @node extracting files, extract dir, extracting archives, extract
--- 1835,1843 ----
  produces this:
  
  @example
! jazz
! blues
! folk
  @end example
  
  @node extracting files, extract dir, extracting archives, extract
*************** files in the working directory were more
*** 1874,1880 ****
  
  However, if a file was stored with a directory name as part of its file
  name, and that directory does not exist under the working directory when
! the file is extracted, @code{tar} will create the directory.
  
  We can demonstrate how to use @samp{--extract} to extract a directory
  file with an example.  Change to the @file{practice} directory if you
--- 1905,1913 ----
  
  However, if a file was stored with a directory name as part of its file
  name, and that directory does not exist under the working directory when
! the file is extracted, @code{tar} will create the directory. @FIXME{why
! does this paragraph begin with ``However''?  It is not opposed to the
! previous one.}
  
  We can demonstrate how to use @samp{--extract} to extract a directory
  file with an example.  Change to the @file{practice} directory if you
*************** on the entire contents of the archive.
*** 2070,2079 ****
  Besides successful exits, GNU @code{tar} may fail for many reasons.
  Some reasons correspond to bad usage, that is, when the @code{tar}
  command is improperly written.
! Errors may be encountered later, while encountering an error
  processing the archive or the files.  Some errors are recoverable,
  in which case the failure is delayed until @code{tar} has completed
! all its work.  Some errors are such that it would not meaningful,
  or at least risky, to continue processing: @code{tar} then aborts
  processing immediately.  All abnormal exits, whether immediate or
  delayed, should always be clearly diagnosed on @code{stderr}, after
--- 2103,2112 ----
  Besides successful exits, GNU @code{tar} may fail for many reasons.
  Some reasons correspond to bad usage, that is, when the @code{tar}
  command is improperly written.
! Errors may be encountered later, while
  processing the archive or the files.  Some errors are recoverable,
  in which case the failure is delayed until @code{tar} has completed
! all its work.  Some errors are such that it would be not meaningful,
  or at least risky, to continue processing: @code{tar} then aborts
  processing immediately.  All abnormal exits, whether immediate or
  delayed, should always be clearly diagnosed on @code{stderr}, after
*************** GNU @code{tar} returns only a few exit s
*** 2083,2089 ****
  aiming simplicity in that area, for now.  If you are not using the
  @value{op-compare} option, zero means that everything went well, besides
  maybe innocuous warnings.  Nonzero means that something went wrong.
! Right now, as of today, ``nonzero'' is almost always 2, except for
  remote operations, where it may be 128.
  
  @node using tar options, Styles, Synopsis, tar invocation
--- 2116,2122 ----
  aiming simplicity in that area, for now.  If you are not using the
  @value{op-compare} option, zero means that everything went well, besides
  maybe innocuous warnings.  Nonzero means that something went wrong.
! As of today, ``nonzero'' is almost always 2, except for
  remote operations, where it may be 128.
  
  @node using tar options, Styles, Synopsis, tar invocation
*************** optionally take an argument}
*** 2167,2175 ****
  "mnemonic" with "long", or *ugh* vice versa.}
  
  Each option has at least one long (or mnemonic) name starting with two
! dashes in a row, e.g. @samp{list}.  The long names are more clear than
  their corresponding short or old names.  It sometimes happens that a
! single mnemonic option has many different different names which are
  synonymous, such as @samp{--compare} and @samp{--diff}.  In addition,
  long option names can be given unique abbreviations.  For example,
  @samp{--cre} can be used in place of @samp{--create} because there is no
--- 2200,2208 ----
  "mnemonic" with "long", or *ugh* vice versa.}
  
  Each option has at least one long (or mnemonic) name starting with two
! dashes in a row, e.g. @samp{--list}.  The long names are more clear than
  their corresponding short or old names.  It sometimes happens that a
! single mnemonic option has many different names which are
  synonymous, such as @samp{--compare} and @samp{--diff}.  In addition,
  long option names can be given unique abbreviations.  For example,
  @samp{--cre} can be used in place of @samp{--create} because there is no
*************** users.  For example, the two commands:
*** 2297,2303 ****
  are quite different.  The first example uses @file{archive.tar.gz} as
  the value for option @samp{f} and recognizes the option @samp{z}.  The
  second example, however, uses @file{z} as the value for option
! @samp{f}---probably not what was intended.
  
  Old options are kept for compatibility with old versions of @code{tar}.
  
--- 2330,2336 ----
  are quite different.  The first example uses @file{archive.tar.gz} as
  the value for option @samp{f} and recognizes the option @samp{z}.  The
  second example, however, uses @file{z} as the value for option
! @samp{-f}---probably not what was intended.
  
  Old options are kept for compatibility with old versions of @code{tar}.
  
*************** the previous set:
*** 2377,2383 ****
  
  @noindent
  These last examples mean something completely different from what the
! user intended (judging based on the example in the previous set which
  uses long options, whose intent is therefore very clear).  The first
  four specify that the @code{tar} archive would be a file named
  @samp{-c}, @samp{c}, @samp{carchive.tar} or @samp{archive.tarc},
--- 2410,2416 ----
  
  @noindent
  These last examples mean something completely different from what the
! user intended (judging by the example in the previous set which
  uses long options, whose intent is therefore very clear).  The first
  four specify that the @code{tar} archive would be a file named
  @samp{-c}, @samp{c}, @samp{carchive.tar} or @samp{archive.tarc},
*************** Creates a new @code{tar} archive.  @xref
*** 2439,2446 ****
  
  @item --delete
  
! Deletes members from the archive.  Don't try this on a archive on a
! tape!  @xref{delete}.
  
  @item --diff
  @itemx -d
--- 2472,2479 ----
  
  @item --delete
  
! Deletes members from the archive.  Don't try this on an archive on a
! magnetic tape!  @xref{delete}.
  
  @item --diff
  @itemx -d
*************** exist in the archive.
*** 2480,2524 ****
  
  @table @kbd
  
  @item --absolute-names
  @itemx -P
  
! Normally when creating an archive, @code{tar} strips an initial @samp{/} from
! member names.  This option disables that behavior.  @FIXME-xref{}.
  
  @item --after-date
  
! (See @samp{--newer}; @FIXME-pxref{}.)
  
  @item --atime-preserve
  
  Tells @code{tar} to preserve the access time field in a file's inode when
! dumping it.  @FIXME-xref{}.
  
  @item --backup=@var{backup-type}
  
  Rather than deleting files from the file system, @code{tar} will back them up
  using simple or numbered backups, depending upon @var{backup-type}.
! @FIXME-xref{}.
  
  @item --block-number
  @itemx -R
  
  With this option present, @code{tar} prints error messages for read errors
! with the block number in the archive file.  @FIXME-xref{}.
  
  @item --blocking-factor=@var{blocking}
  @itemx -b @var{blocking}
  
  Sets the blocking factor @code{tar} uses to @var{blocking} x 512 bytes per
! record.  @FIXME-xref{}.
  
  @item --checkpoint
  
  This option directs @code{tar} to print periodic checkpoint messages as it
! reads through the archive.  Its intended for when you want a visual
  indication that @code{tar} is still running, but don't want to see
! @samp{--verbose} output.  @FIXME-xref{}.
  
  @item --compress
  @itemx --uncompress
--- 2513,2564 ----
  
  @table @kbd
  
+ @item -[0-7][lmh]
+ 
+ Specify drive and density.  @xref{Device}.
+ 
  @item --absolute-names
  @itemx -P
  
! Normally when creating an archive, @code{tar} converts absolute file
! names to relative, by stripping an initial @samp{/} from member names
! (on MS-DOS and MS-Windows, @code{tar} also strips the drive letter and
! the colon that follows it).  This option disables that behavior.
! @xref{absolute}.
  
  @item --after-date
  
! (See @samp{--newer}; @pxref{after}.)
  
  @item --atime-preserve
  
  Tells @code{tar} to preserve the access time field in a file's inode when
! dumping it.  @xref{Attributes}.
  
  @item --backup=@var{backup-type}
  
  Rather than deleting files from the file system, @code{tar} will back them up
  using simple or numbered backups, depending upon @var{backup-type}.
! @xref{backup}.
  
  @item --block-number
  @itemx -R
  
  With this option present, @code{tar} prints error messages for read errors
! with the block number in the archive file.  @xref{verbose}.
  
  @item --blocking-factor=@var{blocking}
  @itemx -b @var{blocking}
  
  Sets the blocking factor @code{tar} uses to @var{blocking} x 512 bytes per
! record.  @xref{Blocking Factor}.
  
  @item --checkpoint
  
  This option directs @code{tar} to print periodic checkpoint messages as it
! reads through the archive.  It's intended for when you want a visual
  indication that @code{tar} is still running, but don't want to see
! @samp{--verbose} output.  @xref{verbose}.
  
  @item --compress
  @itemx --uncompress
*************** indication that @code{tar} is still runn
*** 2526,2592 ****
  
  @code{tar} will use the @code{compress} program when reading or writing the
  archive.  This allows you to directly act on archives while saving
! space.  @FIXME-xref{}.
  
  @item --confirmation
  
! (See @samp{--interactive};  @FIXME-pxref{}.)
  
  @item --dereference
  @itemx -h
  
  When creating a @code{tar} archive, @code{tar} will archive the file that a symbolic
! link points to, rather than archiving the symlink.  @FIXME-xref{}.
  
  @item --directory=@var{dir}
  @itemx -C @var{dir}
  
  When this option is specified, @code{tar} will change its current directory
  to @var{dir} before performing any operations.  When this option is used
! during archive creation, it is order sensitive.  @FIXME-xref{}.
  
  @item --exclude=@var{pattern}
  
  When performing operations, @code{tar} will skip files that match
! @var{pattern}.  @FIXME-xref{}.
  
  @item --exclude-from=@var{file}
  @itemx -X @var{file}
  
  Similar to @samp{--exclude}, except @code{tar} will use the list of patterns
! in the file @var{file}.  @FIXME-xref{}.
  
  @item --file=@var{archive}
  @itemx -f @var{archive}
  
  @code{tar} will use the file @var{archive} as the @code{tar} archive it
! performs operations on, rather than @code{tar}'s compilation dependent
! default.  @FIXME-xref{}.
  
  @item --files-from=@var{file}
  @itemx -T @var{file}
  
  @code{tar} will use the contents of @var{file} as a list of archive members
  or files to operate on, in addition to those specified on the
! command-line.  @FIXME-xref{}.
  
  @item --force-local
  
  Forces @code{tar} to interpret the filename given to @samp{--file} as a local
! file, even if it looks like a remote tape drive name.  @FIXME-xref{}.
  
  @item --group=@var{group}
  
  Files added to the @code{tar} archive will have a group id of @var{group},
! rather than the group from the source file.  @var{group} is first decoded
! as a group symbolic name, but if this interpretation fails, it has to be
! a decimal numeric group ID.  @FIXME-xref{}.
  
  Also see the comments for the @value{op-owner} option.
  
  @item --gunzip
  
! (See @samp{--gzip}; @FIXME-pxref{}.)
  
  @item --gzip
  @itemx --gunzip
--- 2566,2630 ----
  
  @code{tar} will use the @code{compress} program when reading or writing the
  archive.  This allows you to directly act on archives while saving
! space.  @xref{gzip}.
  
  @item --confirmation
  
! (See @samp{--interactive} and @pxref{verbose}.)
  
  @item --dereference
  @itemx -h
  
  When creating a @code{tar} archive, @code{tar} will archive the file that a symbolic
! link points to, rather than archiving the symlink.  @xref{dereference}.
  
  @item --directory=@var{dir}
  @itemx -C @var{dir}
  
  When this option is specified, @code{tar} will change its current directory
  to @var{dir} before performing any operations.  When this option is used
! during archive creation, it is order sensitive.  @xref{directory}.
  
  @item --exclude=@var{pattern}
  
  When performing operations, @code{tar} will skip files that match
! @var{pattern}.  @xref{exclude}.
  
  @item --exclude-from=@var{file}
  @itemx -X @var{file}
  
  Similar to @samp{--exclude}, except @code{tar} will use the list of patterns
! in the file @var{file}.  @xref{exclude}.
  
  @item --file=@var{archive}
  @itemx -f @var{archive}
  
  @code{tar} will use the file @var{archive} as the @code{tar} archive it
! performs operations on, rather than @code{tar}'s compilation-dependent
! default.  @xref{file} and @xref{Device}.
  
  @item --files-from=@var{file}
  @itemx -T @var{file}
  
  @code{tar} will use the contents of @var{file} as a list of archive members
  or files to operate on, in addition to those specified on the
! command-line.  @xref{files}.
  
  @item --force-local
  
  Forces @code{tar} to interpret the filename given to @samp{--file} as a local
! file, even if it looks like a remote tape drive name.  @xref{Device}.
  
  @item --group=@var{group}
  
  Files added to the @code{tar} archive will have a group id of @var{group},
! rather than the group from the source file.  @xref{Attributes}.
  
  Also see the comments for the @value{op-owner} option.
  
  @item --gunzip
  
! (See @samp{--gzip}; @pxref{gzip}.)
  
  @item --gzip
  @itemx --gunzip
*************** Also see the comments for the @value{op-
*** 2595,2611 ****
  
  This option tells @code{tar} to read or write archives through @code{gzip},
  allowing @code{tar} to directly operate on several kinds of compressed
! archives transparently.  @FIXME-xref{}.
  
  @item --help
  
  @code{tar} will print out a short message summarizing the operations and
! options to @code{tar} and exit.  @FIXME-xref{}.
  
  @item --ignore-failed-read
  
  Instructs @code{tar} to exit successfully if it encounters an
! unreadable file.  @xref{Reading}.
  
  @item --ignore-umask
  @FIXME{does this exist?}
--- 2633,2649 ----
  
  This option tells @code{tar} to read or write archives through @code{gzip},
  allowing @code{tar} to directly operate on several kinds of compressed
! archives transparently.  @xref{gzip}.
  
  @item --help
  
  @code{tar} will print out a short message summarizing the operations and
! options to @code{tar} and exit.  @xref{help}.
  
  @item --ignore-failed-read
  
  Instructs @code{tar} to exit successfully if it encounters an
! unreadable file.  @xref{Ignore Failed Read}.
  
  @item --ignore-umask
  @FIXME{does this exist?}
*************** unreadable file.  @xref{Reading}.
*** 2616,2636 ****
  @itemx -i
  
  With this option, @code{tar} will ignore zeroed blocks in the archive, which
! normally signals EOF.  @xref{Reading}.
  
  @item --incremental
  @itemx -G
  
  Used to inform @code{tar} that it is working with an  old GNU-format
  incremental backup archive.  It is intended primarily for backwards
! compatibility only.  @FIXME-xref{}.
  
  @item --info-script=@var{script-file}
  @itemx --new-volume-script=@var{script-file}
  @itemx -F @var{script-file}
  
  When @code{tar} is performing multi-tape backups, @var{script-file} is run
! at the end of each tape.  @FIXME-xref{}.
  
  @item --interactive
  @itemx --confirmation
--- 2654,2674 ----
  @itemx -i
  
  With this option, @code{tar} will ignore zeroed blocks in the archive, which
! normally signals EOF.  @xref{Ignore Zeros} and @xref{Blocking Factor}.
  
  @item --incremental
  @itemx -G
  
  Used to inform @code{tar} that it is working with an  old GNU-format
  incremental backup archive.  It is intended primarily for backwards
! compatibility.  @xref{incremental and listed-incremental}.
  
  @item --info-script=@var{script-file}
  @itemx --new-volume-script=@var{script-file}
  @itemx -F @var{script-file}
  
  When @code{tar} is performing multi-tape backups, @var{script-file} is run
! at the end of each tape.  @xref{Device} and @xref{Using Multiple Tapes}.
  
  @item --interactive
  @itemx --confirmation
*************** at the end of each tape.  @FIXME-xref{}.
*** 2638,2650 ****
  
  Specifies that @code{tar} should ask the user for confirmation before
  performing potentially destructive options, such as overwriting files.
! @FIXME-xref{}.
  
  @item --keep-old-files
  @itemx -k
  
  When extracting files from an archive, @code{tar} will not overwrite existing
! files if this option is present.  @xref{Writing}.
  
  @item --label=@var{name}
  @itemx -V @var{name}
--- 2676,2688 ----
  
  Specifies that @code{tar} should ask the user for confirmation before
  performing potentially destructive options, such as overwriting files.
! @xref{verbose}.
  
  @item --keep-old-files
  @itemx -k
  
  When extracting files from an archive, @code{tar} will not overwrite existing
! files if this option is present.  @xref{Keep Old Files}.
  
  @item --label=@var{name}
  @itemx -V @var{name}
*************** files if this option is present.  @xref{
*** 2652,2658 ****
  When creating an archive, instructs @code{tar} to write @var{name} as a name
  record in the archive.  When extracting or listing archives, @code{tar} will
  only operate on archives that have a label matching the pattern
! specified in @var{name}.  @FIXME-xref{}.
  
  @item --listed-incremental=@var{snapshot-file}
  @itemx -g @var{snapshot-file}
--- 2690,2696 ----
  When creating an archive, instructs @code{tar} to write @var{name} as a name
  record in the archive.  When extracting or listing archives, @code{tar} will
  only operate on archives that have a label matching the pattern
! specified in @var{name}.  @xref{mt} and @xref{label}.
  
  @item --listed-incremental=@var{snapshot-file}
  @itemx -g @var{snapshot-file}
*************** During a @samp{--create} operation, spec
*** 2661,2667 ****
  @code{tar} creates is a new GNU-format incremental backup, using
  @var{snapshot-file} to determine which files to backup.
  With other operations, informs @code{tar} that the archive is in incremental
! format.  @FIXME-xref{}.
  
  @item --mode=@var{permissions}
  
--- 2699,2705 ----
  @code{tar} creates is a new GNU-format incremental backup, using
  @var{snapshot-file} to determine which files to backup.
  With other operations, informs @code{tar} that the archive is in incremental
! format.  @xref{incremental and listed-incremental}.
  
  @item --mode=@var{permissions}
  
*************** or on any other file already marked as e
*** 2683,2689 ****
  @itemx -M
  
  Informs @code{tar} that it should create or otherwise operate on a
! multi-volume @code{tar} archive.  @FIXME-xref{}.
  
  @item --new-volume-script
  
--- 2721,2728 ----
  @itemx -M
  
  Informs @code{tar} that it should create or otherwise operate on a
! multi-volume @code{tar} archive.  @xref{Multi-Volume Archives} and
! @xref{Using Multiple Tapes}.
  
  @item --new-volume-script
  
*************** multi-volume @code{tar} archive.  @FIXME
*** 2694,2767 ****
  @itemx -N
  
  When creating an archive, @code{tar} will only add files that have changed
! since @var{date}.  @FIXME-xref{}.
  
  @item --newer-mtime
  
  In conjunction with @samp{--newer}, @code{tar} will only add files whose
  contents have changed (as opposed to just @samp{--newer}, which will
! also back up files for which any status information has changed).
  
  @item --no-recursion
  
  With this option, @code{tar} will not recurse into directories unless a
! directory is explicitly named as an argument to @code{tar}.  @FIXME-xref{}.
  
  @item --null
  
  When @code{tar} is using the @samp{--files-from} option, this option
  instructs @code{tar} to expect filenames terminated with @kbd{NUL}, so
  @code{tar} can correctly work with file names that contain newlines.
! @FIXME-xref{}.
  
  @item --numeric-owner
  
  This option will notify @code{tar} that it should use numeric user and group
! IDs when creating a @code{tar} file, rather than names.  @FIXME-xref{}.
  
  @item --old-archive
  
! (See @samp{--portability}; @FIXME-pxref{}.)
  
  @item --one-file-system
  @itemx -l
  
  Used when creating an archive.  Prevents @code{tar} from recursing into
  directories that are on different file systems from the current
! directory.  @FIXME-xref{}.
  
  @item --owner=@var{user}
  
  Specifies that @code{tar} should use @var{user} as the owner of members
  when creating archives, instead of the user associated with the source
! file.  @var{user} is first decoded as a user symbolic name, but if
! this interpretation fails, it has to be a decimal numeric user ID.
! @FIXME-xref{}.
! 
! There is no value indicating a missing number, and @samp{0} usually means
! @code{root}.  Some people like to force @samp{0} as the value to offer in
! their distributions for the owner of files, because the @code{root} user is
! anonymous anyway, so that might as well be the owner of anonymous archives.
  
  @item --portability
  @itemx --old-archive
  @itemx -o
  
  Tells @code{tar} to create an archive that is compatible with Unix V7
! @code{tar}.  @FIXME-xref{}.
  
  @item --posix
  
! Instructs @code{tar} to create a POSIX compliant @code{tar} archive.  @FIXME-xref{}.
  
  @item --preserve
  
  Synonymous with specifying both @samp{--preserve-permissions} and
! @samp{--same-order}.  @FIXME-xref{}.
  
  @item --preserve-order
  
! (See @samp{--same-order}; @pxref{Reading}.)
  
  @item --preserve-permissions
  @itemx --same-permissions
--- 2733,2803 ----
  @itemx -N
  
  When creating an archive, @code{tar} will only add files that have changed
! since @var{date}.  @xref{after}.
  
  @item --newer-mtime
  
  In conjunction with @samp{--newer}, @code{tar} will only add files whose
  contents have changed (as opposed to just @samp{--newer}, which will
! also back up files for which any status information has changed).  On
! MS-DOS, where there is only one time stamp for a file, @samp{--newer}
! and @samp{--newer-mtime} have identical effect.  @xref{after}.
  
  @item --no-recursion
  
  With this option, @code{tar} will not recurse into directories unless a
! directory is explicitly named as an argument to @code{tar}.
! @xref{recurse}.
  
  @item --null
  
  When @code{tar} is using the @samp{--files-from} option, this option
  instructs @code{tar} to expect filenames terminated with @kbd{NUL}, so
  @code{tar} can correctly work with file names that contain newlines.
! @xref{nul}.
  
  @item --numeric-owner
  
  This option will notify @code{tar} that it should use numeric user and group
! IDs when creating a @code{tar} file, rather than names.  @xref{Attributes}.
  
  @item --old-archive
  
! (See @samp{--portability}; @pxref{old}.)
  
  @item --one-file-system
  @itemx -l
  
  Used when creating an archive.  Prevents @code{tar} from recursing into
  directories that are on different file systems from the current
! directory.  @xref{one}.
  
  @item --owner=@var{user}
  
  Specifies that @code{tar} should use @var{user} as the owner of members
  when creating archives, instead of the user associated with the source
! file.  @xref{Attributes}.
  
  @item --portability
  @itemx --old-archive
  @itemx -o
  
  Tells @code{tar} to create an archive that is compatible with Unix V7
! @code{tar}.  @xref{old}.
  
  @item --posix
  
! Instructs @code{tar} to create a POSIX compliant @code{tar} archive.
! @xref{posix}.
  
  @item --preserve
  
  Synonymous with specifying both @samp{--preserve-permissions} and
! @samp{--same-order}.  @xref{Attributes}.
  
  @item --preserve-order
  
! (See @samp{--same-order}; @pxref{Same Order}.)
  
  @item --preserve-permissions
  @itemx --same-permissions
*************** When @code{tar} is extracting an archive
*** 2771,2804 ****
  umask from the permissions specified in the archive and uses that
  number as the permissions to create the destination file.  Specifying
  this option instructs @code{tar} that it should use the permissions directly
! from the archive.  @xref{Writing}.
  
  @item --read-full-records
  @itemx -B
  
  Specifies that @code{tar} should reblock its input, for reading from pipes on
! systems with buggy implementations.  @xref{Reading}.
  
  @item --record-size=@var{size}
  
  Instructs @code{tar} to use @var{size} bytes per record when accessing the
! archive.  @FIXME-xref{}.
  
  @item --recursive-unlink
  
  Similar to the @samp{--unlink-first} option, removing existing
  directory hierarchies before extracting directories of the same name
! from the archive.  @xref{Writing}.
  
  @item --remove-files
  
  Directs @code{tar} to remove the source file from the file system after
! appending it to an archive.  @FIXME-xref{}.
  
  @item --rsh-command=@var{cmd}
  
  Notifies @code{tar} that is should use @var{cmd} to communicate with remote
! devices.  @FIXME-xref{}.
  
  @item --same-order
  @itemx --preserve-order
--- 2807,2840 ----
  umask from the permissions specified in the archive and uses that
  number as the permissions to create the destination file.  Specifying
  this option instructs @code{tar} that it should use the permissions directly
! from the archive.  @xref{Setting Access Permissions} and @xref{Attributes}.
  
  @item --read-full-records
  @itemx -B
  
  Specifies that @code{tar} should reblock its input, for reading from pipes on
! systems with buggy implementations.  @xref{Reading} and @xref{Blocking}.
  
  @item --record-size=@var{size}
  
  Instructs @code{tar} to use @var{size} bytes per record when accessing the
! archive.  @xref{Blocking}.
  
  @item --recursive-unlink
  
  Similar to the @samp{--unlink-first} option, removing existing
  directory hierarchies before extracting directories of the same name
! from the archive.  @xref{Recursive Unlink}.
  
  @item --remove-files
  
  Directs @code{tar} to remove the source file from the file system after
! appending it to an archive.  @xref{remove files}.
  
  @item --rsh-command=@var{cmd}
  
  Notifies @code{tar} that is should use @var{cmd} to communicate with remote
! devices.  @xref{Device}.
  
  @item --same-order
  @itemx --preserve-order
*************** devices.  @FIXME-xref{}.
*** 2807,2818 ****
  This option is an optimization for @code{tar} when running on machines with
  small amounts of memory.  It informs @code{tar} that the list of file
  arguments has already been sorted to match the order of files in the
! archive.  @xref{Reading}.
  
  @item --same-owner
  
  When extracting an archive, @code{tar} will attempt to preserve the owner
! specified in the @code{tar} archive with this option present.  @FIXME-xref{}.
  
  @item --same-permissions
  
--- 2843,2855 ----
  This option is an optimization for @code{tar} when running on machines with
  small amounts of memory.  It informs @code{tar} that the list of file
  arguments has already been sorted to match the order of files in the
! archive.  @xref{Same Order}.
  
  @item --same-owner
  
  When extracting an archive, @code{tar} will attempt to preserve the owner
! specified in the @code{tar} archive with this option present.
! @xref{Attributes}.
  
  @item --same-permissions
  
*************** specified in the @code{tar} archive with
*** 2820,2912 ****
  
  @item --show-omitted-dirs
  
! Instructs @code{tar} to mention directories its skipping over when operating
! on a @code{tar} archive.  @FIXME-xref{}.
  
  @item --sparse
  @itemx -S
  
  Invokes a GNU extension when adding files to an archive that handles
! sparse files efficiently.  @FIXME-xref{}.
  
  @item --starting-file=@var{name}
  @itemx -K @var{name}
  
  This option affects extraction only; @code{tar} will skip extracting
  files in the archive until it finds one that matches @var{name}.
! @xref{Scarce}.
  
  @item --suffix=@var{suffix}
  
  Alters the suffix @code{tar} uses when backing up files from the default
! @samp{~}.  @FIXME-xref{}.
  
  @item --tape-length=@var{num}
  @itemx -L @var{num}
  
  Specifies the length of tapes that @code{tar} is writing as being
! @w{@var{num} x 1024} bytes long.  @FIXME-xref{}.
  
  @item --to-stdout
  @itemx -O
  
  During extraction, @code{tar} will extract files to stdout rather than to the
! file system.  @xref{Writing}.
  
  @item --totals
  
  Displays the total number of bytes written after creating an archive.
! @FIXME-xref{}.
  
  @item --touch
  @itemx -m
  
  Sets the modification time of extracted files to the extraction time,
  rather than the modification time stored in the archive.
! @xref{Writing}.
  
  @item --uncompress
  
! (See @samp{--compress}; @FIXME-pxref{}.)
  
  @item --ungzip
  
! (See @samp{--gzip}; @FIXME-pxref{}.)
  
  @item --unlink-first
  @itemx -U
  
  Directs @code{tar} to remove the corresponding file from the file system
! before extracting it from the archive.  @xref{Writing}.
  
  @item --use-compress-program=@var{prog}
  
  Instructs @code{tar} to access the archive through @var{prog}, which is
! presumed to be a compression program of some sort.  @FIXME-xref{}.
  
  @item --verbose
  @itemx -v
  
  Specifies that @code{tar} should be more verbose about the operations its
  performing.  This option can be specified multiple times for some
! operations to increase the amount of information displayed.  @FIXME-xref{}.
  
  @item --verify
  @itemx -W
  
  Verifies that the archive was correctly written when creating an
! archive.  @FIXME-xref{}.
  
  @item --version
  
  @code{tar} will print an informational message about what version it is and a
! copyright message, some credits, and then exit.  @FIXME-xref{}.
  
  @item --volno-file=@var{file}
  
  Used in conjunction with @samp{--multi-volume}.  @code{tar} will keep track
  of which volume of a multi-volume archive its working in @var{file}.
! @FIXME-xref{}.
  @end table
  
  @node Short Option Summary,  , Option Summary, All Options
--- 2857,2949 ----
  
  @item --show-omitted-dirs
  
! Instructs @code{tar} to mention directories it's skipping over when operating
! on a @code{tar} archive.  @xref{verbose}.
  
  @item --sparse
  @itemx -S
  
  Invokes a GNU extension when adding files to an archive that handles
! sparse files efficiently.  @xref{sparse}.
  
  @item --starting-file=@var{name}
  @itemx -K @var{name}
  
  This option affects extraction only; @code{tar} will skip extracting
  files in the archive until it finds one that matches @var{name}.
! @xref{Starting File}.
  
  @item --suffix=@var{suffix}
  
  Alters the suffix @code{tar} uses when backing up files from the default
! @samp{~}.  @xref{backup}.
  
  @item --tape-length=@var{num}
  @itemx -L @var{num}
  
  Specifies the length of tapes that @code{tar} is writing as being
! @w{@var{num} x 1024} bytes long.  @xref{Device}.
  
  @item --to-stdout
  @itemx -O
  
  During extraction, @code{tar} will extract files to stdout rather than to the
! file system.  @xref{Writing to Standard Output}.
  
  @item --totals
  
  Displays the total number of bytes written after creating an archive.
! @xref{verbose}.
  
  @item --touch
  @itemx -m
  
  Sets the modification time of extracted files to the extraction time,
  rather than the modification time stored in the archive.
! @xref{Modification Times}.
  
  @item --uncompress
  
! (See @samp{--compress}; @pxref{gzip}.)
  
  @item --ungzip
  
! (See @samp{--gzip}; @pxref{gzip}.)
  
  @item --unlink-first
  @itemx -U
  
  Directs @code{tar} to remove the corresponding file from the file system
! before extracting it from the archive.  @xref{Prevention Overwriting}.
  
  @item --use-compress-program=@var{prog}
  
  Instructs @code{tar} to access the archive through @var{prog}, which is
! presumed to be a compression program of some sort.  @xref{gzip}.
  
  @item --verbose
  @itemx -v
  
  Specifies that @code{tar} should be more verbose about the operations its
  performing.  This option can be specified multiple times for some
! operations to increase the amount of information displayed.  @xref{verbose}.
  
  @item --verify
  @itemx -W
  
  Verifies that the archive was correctly written when creating an
! archive.  @xref{verify}.
  
  @item --version
  
  @code{tar} will print an informational message about what version it is and a
! copyright message, some credits, and then exit.  @xref{help}.
  
  @item --volno-file=@var{file}
  
  Used in conjunction with @samp{--multi-volume}.  @code{tar} will keep track
  of which volume of a multi-volume archive its working in @var{file}.
! @xref{Using Multiple Tapes}.
  @end table
  
  @node Short Option Summary,  , Option Summary, All Options
*************** not specify which is stronger, here; exp
*** 3137,3143 ****
  The short help output is quite succint, and you might have to get back
  to the full documentation for precise points.  If you are reading this
  paragraph, you already have the @code{tar} manual in some form.  This
! manual is available in printed form, as a kind of small book.  It may
  printed out of the GNU @code{tar} distribution, provided you have @TeX{}
  already installed somewhere, and a laser printer around.  Just configure
  the distribution, execute the command @w{@samp{make dvi}}, then print
--- 3174,3180 ----
  The short help output is quite succint, and you might have to get back
  to the full documentation for precise points.  If you are reading this
  paragraph, you already have the @code{tar} manual in some form.  This
! manual is available in printed form, as a kind of small book.  It may be
  printed out of the GNU @code{tar} distribution, provided you have @TeX{}
  already installed somewhere, and a laser printer around.  Just configure
  the distribution, execute the command @w{@samp{make dvi}}, then print
*************** If GNU @code{tar} has been conveniently 
*** 3146,3157 ****
  manual is also available in interactive, hypertextual form as an Info
  file.  Just call @w{@samp{info tar}} or, if you do not have the
  @code{info} program handy, use the Info reader provided within GNU
! Emacs, calling @samp{tar} from the main Info menu.
  
  There is currently no @code{man} page for GNU @code{tar}.  If you observe
  such a @code{man} page on the system you are running, either it does not
! long to GNU @code{tar}, or it has not been produced by GNU.  Currently,
! GNU @code{tar} documentation is provided in Texinfo format only, if we
  except, of course, the short result of @kbd{tar --help}.
  
  @node verbose, interactive, help, tar invocation
--- 3183,3195 ----
  manual is also available in interactive, hypertextual form as an Info
  file.  Just call @w{@samp{info tar}} or, if you do not have the
  @code{info} program handy, use the Info reader provided within GNU
! Emacs, and choose @samp{tar} from the main Info menu (with @kbd{m tar
! @key{RET}}).
  
  There is currently no @code{man} page for GNU @code{tar}.  If you observe
  such a @code{man} page on the system you are running, either it does not
! belong to GNU @code{tar}, or it has not been produced by GNU.  Currently,
! GNU @code{tar} documentation is provided in Texinfo format only,
  except, of course, the short result of @kbd{tar --help}.
  
  @node verbose, interactive, help, tar invocation
*************** The @value{op-totals} option---which is 
*** 3214,3221 ****
  amount written to the archive, after it has been fully created.
  
  The @value{op-checkpoint} option prints an occasional message
! as @code{tar} reads or writes the archive.  In fact, it print
! directory names while reading the archive.  It is designed for
  those who don't need the more detailed (and voluminous) output of
  @value{op-block-number}, but do want visual confirmation that @code{tar}
  is actually making forward progress.
--- 3252,3258 ----
  amount written to the archive, after it has been fully created.
  
  The @value{op-checkpoint} option prints an occasional message
! as @code{tar} reads or writes the archive.  It is designed for
  those who don't need the more detailed (and voluminous) output of
  @value{op-block-number}, but do want visual confirmation that @code{tar}
  is actually making forward progress.
*************** If @value{op-block-number} is used, @cod
*** 3235,3241 ****
  message it would normally produce, the block number within the archive
  where the message was triggered.  Also, supplementary messages are
  triggered when reading blocks full of NULs, or when hitting end of file on
! the archive.  As of now, if the archive if properly terminated with a NUL
  block, the reading of the file may stop before end of file is met, so the
  position of end of file will not usually show when @value{op-block-number}
  is used.  Note that GNU @code{tar} drains the archive before exiting when
--- 3272,3278 ----
  message it would normally produce, the block number within the archive
  where the message was triggered.  Also, supplementary messages are
  triggered when reading blocks full of NULs, or when hitting end of file on
! the archive.  As of now, if the archive is properly terminated with a NUL
  block, the reading of the file may stop before end of file is met, so the
  position of end of file will not usually show when @value{op-block-number}
  is used.  Note that GNU @code{tar} drains the archive before exiting when
*************** it helps pinpoint the damaged sections. 
*** 3247,3253 ****
  choose among several backup tapes when retrieving a file later, in
  favor of the tape where the file appears earliest (closest to the
  front of the tape).  @FIXME-xref{when the node name is set and the
! backup section written}.
  
  @node interactive,  , verbose, tar invocation
  @section Asking for Confirmation During Operations
--- 3284,3290 ----
  choose among several backup tapes when retrieving a file later, in
  favor of the tape where the file appears earliest (closest to the
  front of the tape).  @FIXME-xref{when the node name is set and the
! backup section written.}
  
  @node interactive,  , verbose, tar invocation
  @section Asking for Confirmation During Operations
*************** intent was to extract the full contents 
*** 3327,3333 ****
  is likely: keys @kbd{c} and @kbd{x} are right next ot each other on
  the QWERTY keyboard.  Instead of being unpacked, the archive then
  gets wholly destroyed.  When users speak about @dfn{exploding} an
! archive, they usually mean something else :-).
  
  @item
  Forgetting the argument to @code{file}, when the intent was to create
--- 3364,3371 ----
  is likely: keys @kbd{c} and @kbd{x} are right next ot each other on
  the QWERTY keyboard.  Instead of being unpacked, the archive then
  gets wholly destroyed.  When users speak about @dfn{exploding} an
! archive, they usually mean something else :-). @FIXME{I think this
! smiley needs some markup, like code or samp, to be pretty in print.}
  
  @item
  Forgetting the argument to @code{file}, when the intent was to create
*************** So, recognizing the likelihood and the c
*** 3342,3348 ****
  errors, GNU @code{tar} now takes some distance from elegance, and
  cowardly refuses to create an archive when @value{op-create} option is
  given, there are no arguments besides options, and @value{op-files-from}
! option is @emph{not} used.  To get around the cautiousness of GNU
  @code{tar} and nevertheless create an archive with nothing in it,
  one may still use, as the value for the @value{op-files-from} option,
  a file with no names in it, as shown in the following commands:
--- 3380,3398 ----
  errors, GNU @code{tar} now takes some distance from elegance, and
  cowardly refuses to create an archive when @value{op-create} option is
  given, there are no arguments besides options, and @value{op-files-from}
! option is @emph{not} used.  Observe:
! 
! @example
! $ @kbd{tar c}
! tar: Cowardly refusing to create an empty archive
! Try `tar --help' for more information.
! $ @kbd{tar cf foo}
! tar: Cowardly refusing to create an empty archive
! Try `tar --help' for more information.
! @end example
! 
! @noindent
! To get around the cautiousness of GNU
  @code{tar} and nevertheless create an archive with nothing in it,
  one may still use, as the value for the @value{op-files-from} option,
  a file with no names in it, as shown in the following commands:
*************** a file with no names in it, as shown in 
*** 3356,3361 ****
--- 3406,3469 ----
  
  A socket is stored, within a GNU @code{tar} archive, as a pipe.
  
+ When archives created on Unix are extracted on MS-DOS and MS-Windows
+ 3.x, several problems pop up due to their incompatibilities with the
+ Unix filesystem.  GNU @code{tar} has several trick up its sleeve, to
+ overcome such problems:
+ 
+ @itemize @bullet{}
+ @cindex Filenames, illegal characters on MS-DOS
+ @cindex Extracting files on MS-DOS, illegal characters
+ @item Illegal characters in file names
+ MS-DOS filesystem disallows certain characters from appearing in a file
+ name.  Except on Windows 9X, it also doesn't allow file names with a
+ leading dot and file names with more that a single dot in the basename
+ of the file.
+ 
+ GNU @code{tar} tries to repair such names automatically, by replacing
+ the offending characters with legal ones.  For example, @file{.emacs} is
+ exracted as @file{_emacs}, @file{foo.bar.c} will be converted to
+ @file{foo_bar.c}, @file{lost+found} will become @file{lost_found}, etc.
+ (@code{tar} even tries to be intelligent by treating some cases
+ specially; for example, files which end with @file{.c++} are extracted
+ as @file{.cxx}.)
+ 
+ When the file is thus renamed, @code{tar} will print a message to that
+ effect when operating verbosely (@pxref{verbose}).  Note that if a
+ directory needs to be renamed, @code{tar} will print such a message for
+ all the files in that directory.
+ 
+ @item DOS device names
+ MS-DOS and MS-Windows define its own reserved names of character
+ devices.  For example, the console device is @samp{CON}, the printer
+ device is @samp{PRN}, the serial port device is @samp{AUX}, etc.
+ 
+ These names are special on DOS, in that files with these names, if they
+ exist in any directory, are inaccessible: the device driver will
+ intercept any file-related call before the filesystem ever sees it.
+ (That's because MS-DOS wants to create an illusion that the devices are
+ present in every directory; in contrast, on Unix the devices live under
+ a special directory called @file{/dev}.)
+ 
+ When archives created on Unix are unpacked on MS-DOS, they might include
+ files with these ``forbidden'' names, such as @file{prn.txt} or
+ @file{aux.c}.  Trying to extract such files will lead to crashes, system
+ wedges, and other atrocities, as the device drivers will try to
+ interpret the data they get and act on it (e.g., some devices are
+ read-only, and don't know how to handle incoming data).
+ 
+ Therefore, @code{tar} checks every file name it is about to extract, and
+ if it refers to a character device, @code{tar} changes that file's name
+ by prepending an underscore @file{_} to it; thus, @file{aux.c} will be
+ extracted as @file{_aux.c}.  (Actually, @code{tar} tries to prepend up
+ to 2 underscore characters, each time checking if the new name is a
+ regular file.  If both attempts are insuccessful, @code{tar} will print
+ an error message and refuse to extract that file.)
+ 
+ As with illegal characters, @code{tar} announces each renamed file when
+ under verbose operation.
+ @end itemize
+ 
  @item @value{op-list}
  
  GNU @code{tar} now shows dates as @samp{1996-11-09}, while it used to
*************** are curious, it contains a detailed expl
*** 3377,3383 ****
  Now that you have learned the basics of using GNU @code{tar}, you may
  want to learn about further ways in which @code{tar} can help you.
  
! This chapter presents five, more advanced operations which you probably
  won't use on a daily basis, but which serve more specialized functions.
  We also explain the different styles of options and why you might want
  to use one or another, or a combination of them in your @code{tar}
--- 3485,3491 ----
  Now that you have learned the basics of using GNU @code{tar}, you may
  want to learn about further ways in which @code{tar} can help you.
  
! This chapter presents five, more advanced, operations which you probably
  won't use on a daily basis, but which serve more specialized functions.
  We also explain the different styles of options and why you might want
  to use one or another, or a combination of them in your @code{tar}
*************** Compare archive members to their counter
*** 3457,3479 ****
  Currently, the listing of the directory using @code{ls} is as follows:
  
  @example
! 
  @end example
  
  @noindent
! The archive file @samp{collection.tar} looks like this:
  
  @example
  $ @kbd{tar -tvf collection.tar}
! 
  @end example
  
  @noindent
! The archive file @samp{music.tar} looks like this:
  
  @example
! $ @kbd{tar -tvf music.tar}
! 
  @end example
  
  @FIXME{need to fill in the above!!!}
--- 3565,3593 ----
  Currently, the listing of the directory using @code{ls} is as follows:
  
  @example
! $ @kbd{ls}
! blues   collection.tar   folk   jazz
  @end example
  
  @noindent
! The archive file @file{collection.tar} looks like this:
  
  @example
  $ @kbd{tar -tvf collection.tar}
! jazz
! blues
! folk
  @end example
  
  @noindent
! The archive file @file{../music.tar}, in the parent directory, looks
! like this:
  
  @example
! $ @kbd{tar -tvf ../music.tar}
! practice/folk
! practice/jazz
! practice/rock
  @end example
  
  @FIXME{need to fill in the above!!!}
*************** do this with @samp{--update}, @pxref{upd
*** 3492,3501 ****
  @FIXME{Explain in second paragraph whether you can get to the previous
  version -- explain whole situation somewhat more clearly.}
  
! If you use @value{op-append} to add a file that has the same name as an
! archive member to an archive containing that archive member, then the
  old member is not deleted.  What does happen, however, is somewhat
! complex.  @code{tar} @emph{allows} you to have infinite numbers of files
  with the same name.  Some operations treat these same-named members no
  differently than any other set of archive members: for example, if you
  view an archive with @value{op-list}, you will see all of those members
--- 3606,3616 ----
  @FIXME{Explain in second paragraph whether you can get to the previous
  version -- explain whole situation somewhat more clearly.}
  
! If you use @value{op-append} to add a file to an archive which already
! contains a member with the same name, then the
  old member is not deleted.  What does happen, however, is somewhat
! complex.  @code{tar} @emph{allows} you to have infinite numbers of
! archive members
  with the same name.  Some operations treat these same-named members no
  differently than any other set of archive members: for example, if you
  view an archive with @value{op-list}, you will see all of those members
*************** listed, with their modification times, o
*** 3503,3509 ****
  
  Other operations don't deal with these members as perfectly as you might
  prefer; if you were to use @value{op-extract} to extract the archive,
! only the most recently added copy of a member with the same name as four
  other members would end up in the working directory.  This is because
  @samp{--extract} extracts an archive in the order the members appeared
  in the archive; the most recently archived members will be extracted
--- 3618,3624 ----
  
  Other operations don't deal with these members as perfectly as you might
  prefer; if you were to use @value{op-extract} to extract the archive,
! only the most recently added copy of a member with the same name as
  other members would end up in the working directory.  This is because
  @samp{--extract} extracts an archive in the order the members appeared
  in the archive; the most recently archived members will be extracted
*************** last.  Additionally, an extracted member
*** 3511,3534 ****
  the same name which existed in the directory already, and @code{tar}
  will not prompt you about this.  Thus, only the most recently archived
  member will end up being extracted, as it will overwrite the one
! extracted before it, and so on.
  
  @FIXME{ hag -- you might want to incorporate some of the above into the
  MMwtSN node; not sure.  i didn't know how to make it simpler...}
  
! There are a few ways to get around this.  @FIXME-xref{Multiple Members
! with the Same Name}.
  
  @cindex Members, replacing with other members
  @cindex Replacing members with other members
  If you want to replace an archive member, use @value{op-delete} to
! delete the member you want to remove from the archive, , and then use
! @samp{--append} to add the member you want to be in the archive.  Note
! that you can not change the order of the archive; the most recently
! added member will still appear last.  In this sense, you cannot truely
! ``replace'' one member with another.  (Replacing one member with another
! will not work on certain types of media, such as tapes; see @ref{delete}
! and @ref{Media}, for more information.)
  
  @menu
  * appending files::             Appending Files to an Archive
--- 3626,3651 ----
  the same name which existed in the directory already, and @code{tar}
  will not prompt you about this.  Thus, only the most recently archived
  member will end up being extracted, as it will overwrite the one
! extracted before it, and so on.  (One way of extracting all of the
! members wiithout overwriting them is to use the @value{op-backup}
! option, see @ref{backup}.)
  
  @FIXME{ hag -- you might want to incorporate some of the above into the
  MMwtSN node; not sure.  i didn't know how to make it simpler...}
  
! Other than using @value{op-backup}, there are a few additional ways to
! get around this.  @FIXME-xref{Multiple Members with the Same Name.}
  
  @cindex Members, replacing with other members
  @cindex Replacing members with other members
  If you want to replace an archive member, use @value{op-delete} to
! delete the member you want to remove from the archive, and then use
! @samp{--append} to add the member you want to be in the archive.
! (Replacing one member with another will not work on certain types of
! media, such as tapes; see @ref{delete} and @ref{Media}, for more
! information.)  Note that you can not change the order of the archive;
! the most recently added member will still appear last.  In this sense,
! you cannot truely ``replace'' one member with another.
  
  @menu
  * appending files::             Appending Files to an Archive
*************** and @ref{Media}, for more information.)
*** 3544,3564 ****
  
  The simplest way to add a file to an already existing archive is the
  @value{op-append} operation, which writes specified files into the
! archive whether or not they are already among the archived files.
! When you use @samp{--append}, you @emph{must} specify file name
! arguments, as there is no default.  If you specify a file that already
! exists in the archive, another copy of the file will be added to the
! end of the archive.  As with other operations, the member names of the
! newly added files will be exactly the same as their names given on the
! command line.  The @value{op-verbose} option will print out the names
! of the files as they are written into the archive.
  
  @samp{--append} cannot be performed on some tape drives, unfortunately,
  due to deficiencies in the formats those tape drives use.  The archive
  must be a valid @code{tar} archive, or else the results of using this
  operation will be unpredictable.  @xref{Media}.
  
! To demonstrate using @samp{--append} to add a file to an archive,
  create a file called @file{rock} in the @file{practice} directory.
  Make sure you are in the @file{practice} directory.  Then, run the
  following @code{tar} command to add @file{rock} to
--- 3661,3682 ----
  
  The simplest way to add a file to an already existing archive is the
  @value{op-append} operation, which writes specified files into the
! archive whether or not they are already among the archived files.  When
! you use @samp{--append}, you @emph{must} specify file name arguments, as
! there is no default.  If you specify a file that already exists in the
! archive, another copy of the file will be added to the end of the
! archive.  As with other operations, the member names of the newly added
! files will be exactly the same as their names given on the command line
! (except that backslashes in MS-DOS file names are mirrored to Unix-style
! forward slashes).  The @value{op-verbose} option will print out the
! names of the files as they are written into the archive.
  
  @samp{--append} cannot be performed on some tape drives, unfortunately,
  due to deficiencies in the formats those tape drives use.  The archive
  must be a valid @code{tar} archive, or else the results of using this
  operation will be unpredictable.  @xref{Media}.
  
! To demonstrate use of @samp{--append} to add a file to an archive,
  create a file called @file{rock} in the @file{practice} directory.
  Make sure you are in the @file{practice} directory.  Then, run the
  following @code{tar} command to add @file{rock} to
*************** $ @kbd{tar --append --file=collection.ta
*** 3572,3577 ****
--- 3690,3696 ----
  If you now use the @value{op-list} operation, you will see that
  @file{rock} has been added to the archive:
  
+ @ignore
  @example
  $ @kbd{tar --list --file=collection.tar}
  -rw-rw-rw- me user     28 1996-10-18 16:31 jazz
*************** $ @kbd{tar --list --file=collection.tar}
*** 3579,3584 ****
--- 3698,3718 ----
  -rw-rw-rw- me user     20 1996-09-23 16:44 folk
  -rw-rw-rw- me user     20 1996-09-23 16:44 rock
  @end example
+ @end ignore
+ 
+ @FIXME{The above example is wrong: the long listing is only printed if
+ you say --verbose.  I think the verbose listing should be used only
+ where required, since most people will see slightly different values
+ printed for everything but the file names, and newbies might get
+ confused.  So I left the command as it was, but changed the output:}
+ 
+ @example
+ $ @kbd{tar --list --file=collection.tar}
+ jazz
+ blues
+ folk
+ rock
+ @end example
  
  @FIXME{in theory, dan will (soon) try to turn this node into what it's
  title claims it will become...}
*************** updating it.
*** 3710,3717 ****
  
  (The reason @code{tar} does not overwrite the older file when updating
  it is because writing to the middle of a section of tape is a difficult
! process.  Tapes are not designed to go backward.  @xref{Media} for more
! information about tapes.
  
  @value{op-update} is not suitable for performing backups for two
  reasons: it does not change directory content entries, and it lengthens
--- 3844,3852 ----
  
  (The reason @code{tar} does not overwrite the older file when updating
  it is because writing to the middle of a section of tape is a difficult
! process.  Tapes are not designed to get data inserted in their middle;
! doing so would destroy any data after the place you write.  @xref{Media}
! for more information about tapes.)
  
  @value{op-update} is not suitable for performing backups for two
  reasons: it does not change directory content entries, and it lengthens
*************** backups, please consult @ref{Backups}.
*** 3726,3735 ****
  @cindex Concatenating Archives
  Sometimes it may be convenient to add a second archive onto the end of
  an archive rather than adding individual files to the archive.  To add
! one or more archives to the end of another archive, you should use the
! @value{op-concatenate} operation.
  
! To use @samp{--concatenate}, name the archives to be concatenated on the
  command line.  (Nothing happens if you don't list any.)  The members,
  and their member names, will be copied verbatim from those archives.  If
  this causes multiple members to have the same name, it does not delete
--- 3861,3870 ----
  @cindex Concatenating Archives
  Sometimes it may be convenient to add a second archive onto the end of
  an archive rather than adding individual files to the archive.  To add
! the contents of one or more archives to the end of another archive, you
! should use the @value{op-concatenate} operation.
  
! To use @samp{--concatenate}, name two archives to be concatenated on the
  command line.  (Nothing happens if you don't list any.)  The members,
  and their member names, will be copied verbatim from those archives.  If
  this causes multiple members to have the same name, it does not delete
*************** $ @kbd{tar -tvf folkjazz.tar}
*** 3765,3776 ****
  
  We can concatenate these two archives with @code{tar}:
  
  @example
  $ @kbd{cd ..}
  $ @kbd{tar --concatenate --file=bluesrock.tar jazzfolk.tar}
  @end example
  
! If you now list the contents of the @file{bluesclass.tar}, you will see
  that now it also contains the archive members of @file{jazzfolk.tar}:
  
  @example
--- 3900,3919 ----
  
  We can concatenate these two archives with @code{tar}:
  
+ @ignore
  @example
  $ @kbd{cd ..}
  $ @kbd{tar --concatenate --file=bluesrock.tar jazzfolk.tar}
  @end example
+ @end ignore
+ 
+ @FIXME{why the "cd .." above?  I think it's wrong, so I deleted it.}
  
! @example
! $ @kbd{tar --concatenate --file=bluesrock.tar jazzfolk.tar}
! @end example
! 
! If you now list the contents of the @file{bluesrock.tar}, you will see
  that now it also contains the archive members of @file{jazzfolk.tar}:
  
  @example
*************** folk
*** 3782,3792 ****
  @end example
  
  When you use @samp{--concatenate}, the source and target archives must
! already exist and must have been created using compatable format
  parameters (@FIXME-pxref{Matching Format Parameters}).  The new,
  concatenated archive will be called by the same name as the first
  archive listed on the command line. @FIXME{is there a way to specify a
! new name?}
  
  Like @value{op-append}, this operation cannot be performed on some
  tape drives, due to deficiencies in the formats those tape drives use.
--- 3925,3936 ----
  @end example
  
  When you use @samp{--concatenate}, the source and target archives must
! already exist and must have been created using compatible format
  parameters (@FIXME-pxref{Matching Format Parameters}).  The new,
  concatenated archive will be called by the same name as the first
  archive listed on the command line. @FIXME{is there a way to specify a
! new name? of course, there is: set $TAPE to the new name, and use
! --concatenate with no --file= argument.}
  
  Like @value{op-append}, this operation cannot be performed on some
  tape drives, due to deficiencies in the formats those tape drives use.
*************** from the target archive before each new 
*** 3806,3818 ****
  archive that was added to using the @code{cat} utility, use the
  @value{op-ignore-zeros} option.  @xref{Ignore Zeros} for further
  information on dealing with archives improperly combined using the
! @code{cat} shell utility.
  
  @FIXME{this shouldn't go here.  where should it go?} You must specify
  the source archives using @value{op-file} (@value{pxref-file}).  If you
  do not specify the target archive, @code{tar} uses the value of the
  environment variable @code{TAPE}, or, if this has not been set, the
! default archive name.
  
  @node delete, compare, concatenate, Advanced tar
  @subsection Removing Archive Members Using @samp{--delete}
--- 3950,3963 ----
  archive that was added to using the @code{cat} utility, use the
  @value{op-ignore-zeros} option.  @xref{Ignore Zeros} for further
  information on dealing with archives improperly combined using the
! @code{cat} utility.
  
  @FIXME{this shouldn't go here.  where should it go?} You must specify
  the source archives using @value{op-file} (@value{pxref-file}).  If you
  do not specify the target archive, @code{tar} uses the value of the
  environment variable @code{TAPE}, or, if this has not been set, the
! default archive name.  If the default archive name is the standard
! output, @code{tar} will print an error message.
  
  @node delete, compare, concatenate, Advanced tar
  @subsection Removing Archive Members Using @samp{--delete}
*************** are in that directory, and then,
*** 3849,3868 ****
  
  @example
  $ @kbd{tar --list --file=collection.tar}
  blues
  folk
- jazz
  rock
! practice/blues
! practice/folk
! practice/jazz
! practice/rock
! practice/blues
  $ @kbd{tar --delete --file=collection.tar blues}
  $ @kbd{tar --list --file=collection.tar}
- folk
  jazz
  rock
  $
  @end example
  
--- 3994,4012 ----
  
  @example
  $ @kbd{tar --list --file=collection.tar}
+ jazz
  blues
  folk
  rock
! blues
! blues
! classical
  $ @kbd{tar --delete --file=collection.tar blues}
  $ @kbd{tar --list --file=collection.tar}
  jazz
+ folk
  rock
+ classical
  $
  @end example
  
*************** files of the same name in the file syste
*** 3901,3917 ****
  $ @kbd{tar --compare --file=bluesrock.tar rock blues funk}
  rock
  blues
! tar: funk not found in archive
  @end example
  
  @noindent
  @FIXME{what does this actually depend on?  i'm making a guess,
! here.}Depending on the system where you are running @code{tar} and the
! version you are running, @code{tar} may have a different error message,
! such as:
  
  @example
! funk: does not exist
  @end example
  
  @FIXME-xref{somewhere, for more information about format parameters.
--- 4045,4068 ----
  $ @kbd{tar --compare --file=bluesrock.tar rock blues funk}
  rock
  blues
! funk: File does not exist
  @end example
  
  @noindent
  @FIXME{what does this actually depend on?  i'm making a guess,
! here.
! It depends on the type of the file; see the corrected wording:}
! @ignore
! Depending on the system where you are running @code{tar} and the
! version you are running,
! @end ignore
! 
! @noindent
! If the file in the archive is a link, @code{tar} may have a different
! error message, such as:
  
  @example
! funk: Does not exist
  @end example
  
  @FIXME-xref{somewhere, for more information about format parameters.
*************** The spirit behind the @value{op-compare}
*** 3922,3927 ****
--- 4073,4088 ----
  archive represents the current state of files on disk, more than validating
  the integrity of the archive media.  For this later goal, @xref{verify}.
  
+ @cindex Timestamp differences, on MS-DOS/MS-Windows filesystems
+ @cindex Mod time differs message on MS-DOS disks
+ Some filesystems, such as the FAT and VFAT used on MS-DOS and
+ MS-Windows, only maintain file modification times up to the nearest even
+ second.  @code{tar} compiled for such systems knows about this, and
+ doesn't report difference in mod times unless it is larger than one
+ second.  But if you run @code{tar} on Unix and your files reside on a
+ FAT disk (via some network interface), you could have some false alarms
+ in this case.
+ 
  @node extract options, backup, Advanced tar, operations
  @section Options Used by @code{--extract}
  @UNREVISED
*************** If the name of a corresponding file name
*** 4068,4074 ****
  pointed to by the symbolic link will be overwritten instead of the
  symbolic link itself (if this is possible).  Moreover, special devices,
  empty directories and even symbolic links are automatically removed if
! they are found to be on the way of the proper extraction.
  
  To prevent @code{tar} from extracting an archive member from an archive
  if doing so will overwrite a file in the file system, use
--- 4229,4235 ----
  pointed to by the symbolic link will be overwritten instead of the
  symbolic link itself (if this is possible).  Moreover, special devices,
  empty directories and even symbolic links are automatically removed if
! they are found to be in the way of the proper extraction.
  
  To prevent @code{tar} from extracting an archive member from an archive
  if doing so will overwrite a file in the file system, use
*************** this option is specified, @code{tar} wil
*** 4077,4098 ****
  name of the files in conflict instead of overwriting the file with the
  corresponding extracted archive member.
  
! @FIXME{these two P's have problems.  i don't understand what they're
  trying to talk about well enough to fix them; i may have just made them
  worse (in particular the first of the two).  waiting to talk with hag.}
  
  The @value{op-unlink-first} option removes existing files, symbolic links,
  empty directories, devices, etc., @emph{prior} to extracting over them.
! In particular, using this option will prevent replacing an already existing
! symbolic link by the name of an extracted file, since the link itself
! is removed prior to the extraction, rather than the file it points to.
! On some systems, the backing store for the executable @emph{is} the
! original program text.  You could use the @value{op-unlink-first} option
! to prevent segmentation violations or other woes when extracting arbitrary
! executables over currently running copies.  Note that if something goes
! wrong with the extraction and you @emph{did} use this option, you might
! end up with no file at all.  Without this option, if something goes wrong
! with the extraction, the existing file is not overwritten and preserved.
  
  @FIXME{huh?} If you specify the @value{op-recursive-unlink} option,
  @code{tar} removes @emph{anything} that keeps you from extracting a file
--- 4238,4269 ----
  name of the files in conflict instead of overwriting the file with the
  corresponding extracted archive member.
  
! @FIXME{these three P's have problems.  i don't understand what they're
  trying to talk about well enough to fix them; i may have just made them
  worse (in particular the first of the two).  waiting to talk with hag.}
  
  The @value{op-unlink-first} option removes existing files, symbolic links,
  empty directories, devices, etc., @emph{prior} to extracting over them.
! This could take care of several situations where overwriting files is
! undesirable.
!  
! One such situation is when the archive includes a regular file whereas
! the filesystem has a symbolic link by the same name.  Using this option
! will prevent @code{tar} from overwriting the file to which the symbolic
! link points by the contents of an extracted file, since the link itself
! is removed prior to the extraction.
! 
! Another situation is with overwriting a running program's executable
! file.  On some systems, the backing store for the executable @emph{is}
! the original program file; overwriting it while the program runs could
! lead to segmentation violation and other crashes.  You could use the
! @value{op-unlink-first} option to prevent such woes when extracting
! arbitrary executables over currently running copies.  Note that if
! something goes wrong with the extraction and you @emph{did} use this
! option, you might end up with no file at all.  Without this option, if
! something goes wrong with the extraction, the existing file is not
! overwritten and preserved.  (If you want to be safe either way, use
! both @value{op-unlink-first} and @value{op-backup}; @ref{backup}.)
  
  @FIXME{huh?} If you specify the @value{op-recursive-unlink} option,
  @code{tar} removes @emph{anything} that keeps you from extracting a file
*************** using this feature may be very surprised
*** 4102,4107 ****
--- 4273,4297 ----
  a directory entry from the archive.  This option can be dangerous; be
  very aware of what you are doing if you choose to use it.
  
+ Without @value{op-recursive-unlink}, GNU @code{tar} silently overwrites
+ non-directories, but will never overwrite existing non-empty
+ directories.
+ 
+ @cindex Removing existing files on MS-DOS
+ @cindex Overwriting prevention on MS-DOS and MS-Windows
+ One especially nasty subtlety with both @value{op-unlink-first} and
+ @value{op-recursive-unlink} options happens on filesystems which
+ silently truncate the names of the files in the archive when they are
+ extracted to the file system.  (MS-DOS and MS-Windows 3.X are two
+ notorious examples.)  In such case, @code{tar} might incidentally delete
+ a file or a directory which has nothing to do with the extracted file,
+ only because their names are the same after truncation.  We recommend
+ not to use these two options on such filesystems.  In fact, we recommend
+ that if you unpack on MS-DOS archives which were created on Unix, you
+ @emph{always} use either @value{op-keep-old-files} or @value{op-backup},
+ to prevent overwriting existing files due to file name truncation.
+ @xref{backup}.
+ 
  @menu
  * Keep Old Files::
  * Unlink First::
*************** files with other files when extracting. 
*** 4146,4152 ****
  archive, they expect to see a faithful copy of the state of the filesystem
  when the archive was created.  It is debatable that this would always
  be a proper behaviour.  For example, suppose one has an archive in
! which @file{usr/local} is a link to @file{usr/local2}.  Since then,
  maybe the site removed the link and renamed the whole hierarchy from
  @file{/usr/local2} to @file{/usr/local}.  Such things happen all the time.
  I guess it would not be welcome at all that GNU @code{tar} removes the
--- 4336,4343 ----
  archive, they expect to see a faithful copy of the state of the filesystem
  when the archive was created.  It is debatable that this would always
  be a proper behaviour.  For example, suppose one has an archive in
! which @file{usr/local} is a link to @file{usr/local2}.  Since the
! archive was created,
  maybe the site removed the link and renamed the whole hierarchy from
  @file{/usr/local2} to @file{/usr/local}.  Such things happen all the time.
  I guess it would not be welcome at all that GNU @code{tar} removes the
*************** To write the extracted files to the stan
*** 4206,4214 ****
  creating the files on the file system, use @value{op-to-stdout} in
  conjunction with @value{op-extract}.  This option is useful if you are
  extracting files to send them through a pipe, and do not need to
! preserve them in the file system.  If you extract multiple members,
! they appear on standard output concatenated, in the order they are
! found in the archive.
  
  @table @kbd
  @item --to-stdout
--- 4397,4408 ----
  creating the files on the file system, use @value{op-to-stdout} in
  conjunction with @value{op-extract}.  This option is useful if you are
  extracting files to send them through a pipe, and do not need to
! preserve them in the file system.  You might need to use this option to
! browse one or more files with a pager such as @code{less}, or if you
! want the extracted file to have another name on the file system.
! 
! If you extract multiple members, they appear on standard output
! concatenated, in the order they are found in the archive.
  
  @table @kbd
  @item --to-stdout
*************** containing many members having identical
*** 4315,4325 ****
  on systems having file name limitations, making different members appear
  has having similar names through the side-effect of name truncation.
  (This is true only if we have a good scheme for truncated backup names,
! which I'm not sure at all: I suspect work is needed in this area.)
  When any existing file is backed up before being overwritten by extraction,
  then clashing files are automatically be renamed to be unique, and the
  true name is kept for only the last file of a series of clashing files.
  By using verbose mode, users may track exactly what happens.
  
  At the detail level, some decisions are still experimental, and may
  change in the future, we are waiting comments from our users.  So, please
--- 4509,4524 ----
  on systems having file name limitations, making different members appear
  has having similar names through the side-effect of name truncation.
  (This is true only if we have a good scheme for truncated backup names,
! which I'm not sure at all: I suspect work is needed in this area.
! The MS-DOS/MS-Windows version works with numbered backups, even when
! file names are truncated.)
  When any existing file is backed up before being overwritten by extraction,
  then clashing files are automatically be renamed to be unique, and the
  true name is kept for only the last file of a series of clashing files.
  By using verbose mode, users may track exactly what happens.
+ We recommend that you @strong{always} use numbered backups when
+ unpacking archives on MS-DOS and on other systems that have file name
+ limitations.
  
  At the detail level, some decisions are still experimental, and may
  change in the future, we are waiting comments from our users.  So, please
*************** the default backup type is @samp{existin
*** 4365,4373 ****
  
  @vindex version-control @r{Emacs variable}
  This option corresponds to the Emacs variable @samp{version-control};
! the same values for @var{method} are accepted as in Emacs.  This options
! also more descriptive name.  The valid @var{method}s (unique
! abbreviations are accepted):
  
  @table @samp
  @item t
--- 4564,4572 ----
  
  @vindex version-control @r{Emacs variable}
  This option corresponds to the Emacs variable @samp{version-control};
! the same values for @var{method} are accepted as in Emacs.  The values
! that this option accepts have also more descriptive name.  Here are the
! valid @var{method}s (unique abbreviations are accepted):
  
  @table @samp
  @item t
*************** Always make simple backups.
*** 4390,4401 ****
  
  @end table
  
! Some people express the desire to @emph{always} use the @var{op-backup}
  option, by defining some kind of alias or script.  This is not as easy
! as one may thing, due to the fact old style options should appear first
! and consume arguments a bit inpredictably for an alias or script.  But,
  if you are ready to give up using old style options, you may resort to
! using something like (a Bourne shell function here):
  
  @example
  tar () @{ /usr/local/bin/tar --backup $*; @}
--- 4589,4600 ----
  
  @end table
  
! Some people express the desire to @emph{always} use the @value{op-backup}
  option, by defining some kind of alias or script.  This is not as easy
! as one may thing, due to the fact that old style options should appear first
! and consume arguments a bit unpredictably for an alias or script.  But,
  if you are ready to give up using old style options, you may resort to
! using something like a (Bourne shell) function here:
  
  @example
  tar () @{ /usr/local/bin/tar --backup $*; @}
*************** one disk to another, while preserving th
*** 4426,4441 ****
  link-structure of all the files therein.  In this case, the transfer
  medium is a @dfn{pipe}, which is one a Unix redirection mechanism:
  
  @smallexample
! $ @kbd{cd sourcedir; tar -cf - . | (cd targetdir; tar -xf -)}
  @end smallexample
  
  @noindent
  The command also works using short option forms:
  
- @FIXME{The following using standard input/output correct??}
  @smallexample
! $ @w{@kbd{cd sourcedir; tar --create --file=- . | (cd targetdir; tar --extract --file=-)}}
  @end smallexample
  
  @noindent
--- 4625,4640 ----
  link-structure of all the files therein.  In this case, the transfer
  medium is a @dfn{pipe}, which is one a Unix redirection mechanism:
  
+ @FIXME{The following using standard input/output correct??}
  @smallexample
! $ @w{@kbd{cd sourcedir; tar --create --file=- . | (cd targetdir; tar --extract --file=-)}}
  @end smallexample
  
  @noindent
  The command also works using short option forms:
  
  @smallexample
! $ @kbd{cd sourcedir; tar -cf - . | (cd targetdir; tar -xf -)}
  @end smallexample
  
  @noindent
*************** Full dumps should only be made when no o
*** 4557,4563 ****
  are modifying files in the filesystem.  If files are modified while
  @code{tar} is making the backup, they may not be stored properly in
  the archive, in which case you won't be able to restore them if you
! have to.  (Files not being modified are written with no trouble, and do
  not corrupt the entire archive.)
  
  You will want to use the @value{op-label} option to give the archive a
--- 4756,4762 ----
  are modifying files in the filesystem.  If files are modified while
  @code{tar} is making the backup, they may not be stored properly in
  the archive, in which case you won't be able to restore them if you
! have to.  (Files being modified are written with no trouble, and do
  not corrupt the entire archive.)
  
  You will want to use the @value{op-label} option to give the archive a
*************** also detect cases where the file was mod
*** 4583,4598 ****
  it was being archived.  Not all media (notably cartridge tapes) are
  capable of being verified, unfortunately.
  
! @value{op-listed-incremental} take a file name argument always.  If the
! file doesn't exist, run a level zero dump, creating the file.  If the
! file exists, uses that file to see what has changed.
  
  @value{op-incremental} @FIXME{look it up}
  
  @value{op-incremental} handle old GNU-format incremental backup.
  
! This option should only be used when creating an incremental backup of
! a filesystem.  When the @value{op-incremental} option is used, @code{tar}
  writes, at the beginning of the archive, an entry for each of the
  directories that will be operated on.  The entry for a directory
  includes a list of all the files in the directory at the time the
--- 4782,4801 ----
  it was being archived.  Not all media (notably cartridge tapes) are
  capable of being verified, unfortunately.
  
! @value{op-listed-incremental} takes a file name argument always.  If the
! file doesn't exist, @code{tar} runs a level zero dump, creating the
! file.  If the file exists, @code{tar} uses that file to see what has
! changed.
  
  @value{op-incremental} @FIXME{look it up}
  
  @value{op-incremental} handle old GNU-format incremental backup.
  
! The @value{op-incremental} option means the archive is an incremental
! backup.  Its meaning depends on the command that it modifies.
! 
! When this option is used for creating an incremental backup of
! a filesystem, @code{tar}
  writes, at the beginning of the archive, an entry for each of the
  directories that will be operated on.  The entry for a directory
  includes a list of all the files in the directory at the time the
*************** Note that this option causes @code{tar} 
*** 4604,4612 ****
  archive that may not be readable by non-GNU versions of the @code{tar}
  program.
  
- The @value{op-incremental} option means the archive is an incremental
- backup.  Its meaning depends on the command that it modifies.
- 
  If the @value{op-incremental} option is used with @value{op-list}, @code{tar}
  will list, for each directory in the archive, the list of files in
  that directory at the time the archive was created.  This information
--- 4807,4812 ----
*************** was made.  If you don't use @value{op-in
*** 4630,4640 ****
  probably fill up with files that shouldn't exist any more.
  
  @value{op-listed-incremental} handle new GNU-format incremental backup.
- This option handles new GNU-format incremental backup.  It has much the
- same effect as @value{op-incremental}, but also the time when the dump
- is done and the list of directories dumped is written to the given
- @var{file}. When restoring, only files newer than the saved time are
- restored, and the direcotyr list is used to speed up operations.
  
  @value{op-listed-incremental} acts like @value{op-incremental}, but when
  used in conjunction with @value{op-create} will also cause @code{tar} to
--- 4830,4835 ----
*************** a changed directory name.  The file is u
*** 4653,4658 ****
--- 4848,4856 ----
  be archived are determined, but before the new archive is actually
  created.
  
+ When restoring, only files newer than the saved time are
+ restored, and the directory list is used to speed up operations.
+ 
  GNU @code{tar} actually writes the file twice: once before the data
  and written, and once after.
  
*************** although a few more options will usually
*** 4669,4679 ****
  You will need to use the @samp{-N @var{date}} option to tell @code{tar}
  to only store files that have been modified since @var{date}.
  @var{date} should be the date and time of the last full/incremental
! dump.
  
  A standard scheme is to do a @emph{monthly} (full) dump once a month,
  a @emph{weekly} dump once a week of everything since the last monthly
! and a @emph{daily} every day of everything since the last (weekly or
  monthly) dump.
  
  Here is a copy of the script used to dump the filesystems of the
--- 4867,4877 ----
  You will need to use the @samp{-N @var{date}} option to tell @code{tar}
  to only store files that have been modified since @var{date}.
  @var{date} should be the date and time of the last full/incremental
! dump.  @xref{after}.
  
  A standard scheme is to do a @emph{monthly} (full) dump once a month,
  a @emph{weekly} dump once a week of everything since the last monthly
! and a @emph{daily} dump every day of everything since the last (weekly or
  monthly) dump.
  
  Here is a copy of the script used to dump the filesystems of the
*************** of the last dump.
*** 4714,4720 ****
  Since this is a streaming tape drive, no attempt to verify the archive
  is done.  This is also why the high blocking factor (126) is used.
  The tape drive must also be rewound by the @code{mt} command after
! the dump is made.
  
  @node incremental and listed-incremental, Backup Levels, Inc Dumps, Backups
  @section The Incremental Options
--- 4912,4918 ----
  Since this is a streaming tape drive, no attempt to verify the archive
  is done.  This is also why the high blocking factor (126) is used.
  The tape drive must also be rewound by the @code{mt} command after
! the dump is made.  @FIXME{care to explain why?}
  
  @node incremental and listed-incremental, Backup Levels, Inc Dumps, Backups
  @section The Incremental Options
*************** the dump is made.
*** 4723,4729 ****
  @value{op-incremental} is used in conjunction with @value{op-create},
  @value{op-extract} or @value{op-list} when backing up and restoring file
  systems.  An archive cannot be extracted or listed with the
! @value{op-incremental} option specified unless it was created with the
  option specified.  This option should only be used by a script, not by
  the user, and is usually disregarded in favor of
  @value{op-listed-incremental}, which is described below.
--- 4921,4927 ----
  @value{op-incremental} is used in conjunction with @value{op-create},
  @value{op-extract} or @value{op-list} when backing up and restoring file
  systems.  An archive cannot be extracted or listed with the
! @value{op-incremental} option specified unless it was created with this
  option specified.  This option should only be used by a script, not by
  the user, and is usually disregarded in favor of
  @value{op-listed-incremental}, which is described below.
*************** program.
*** 4741,4747 ****
  
  @value{op-incremental} in conjunction with @value{op-extract} causes
  @code{tar} to read the lists of directory contents previously stored
! in the archive, @emph{delete} files in the file system that did not
  exist in their directories when the archive was created, and then
  extract the files in the archive.
  
--- 4939,4945 ----
  
  @value{op-incremental} in conjunction with @value{op-extract} causes
  @code{tar} to read the lists of directory contents previously stored
! in the archive, @emph{delete} files in the file system that did @emph{not}
  exist in their directories when the archive was created, and then
  extract the files in the archive.
  
*************** and device but a changed directory name.
*** 4779,4787 ****
  the files to be archived are determined, but before the new archive is
  actually created.
  
! Despite it should be obvious that a device has a non-volatile value, NFS
  devices have non-dependable values when an automounter gets in the picture.
! This led to a great deal of spurious redumping in incremental dumps,
  so it is somewhat useless to compare two NFS devices numbers over time.
  So @code{tar} now considers all NFS devices as being equal when it comes
  to comparing directories; this is fairly gross, but there does not seem
--- 4977,4985 ----
  the files to be archived are determined, but before the new archive is
  actually created.
  
! Althought it should be obvious that a device has a non-volatile value, NFS
  devices have non-dependable values when an automounter gets in the picture.
! This leads to a great deal of spurious redumping in incremental dumps,
  so it is somewhat useless to compare two NFS devices numbers over time.
  So @code{tar} now considers all NFS devices as being equal when it comes
  to comparing directories; this is fairly gross, but there does not seem
*************** substantial amount of archive media and 
*** 4800,4806 ****
  are daily re-archived.
  
  It is more efficient to do a full dump only occasionally.  To back up
! files between full dumps, you can a incremental dump.  A @dfn{level
  one} dump archives all the files that have changed since the last full
  dump.
  
--- 4998,5004 ----
  are daily re-archived.
  
  It is more efficient to do a full dump only occasionally.  To back up
! files between full dumps, you can do an incremental dump.  A @dfn{level
  one} dump archives all the files that have changed since the last full
  dump.
  
*************** file name lists and @code{tar} commands 
*** 4821,4845 ****
  Before you use these scripts, you need to edit the file
  @file{backup-specs}, which specifies parameters used by the backup
  scripts and by the restore script.  @FIXME{There is no such restore
! script!}.  @FIXME-xref{Script Syntax}.  Once the backup parameters
  are set, you can perform backups or restoration by running the
  appropriate script.
  
  The name of the restore script is @code{restore}.  @FIXME{There is
! no such restore script!}.  The names of the level one and full backup
  scripts are, respectively, @code{level-1} and @code{level-0}.
  The @code{level-0} script also exists under the name @code{weekly}, and
  the @code{level-1} under the name @code{daily}---these additional names
! can be changed according to your backup schedule.  @FIXME-xref{Scripted
  Restoration}, for more information on running the restoration script.
! @FIXME-xref{Scripted Backups}, for more information on running the
  backup scripts.
  
  @emph{Please Note:} The backup scripts and the restoration scripts are
  designed to be used together.  While it is possible to restore files by
  hand from an archive which was created using a backup script, and to create
  an archive by hand which could then be extracted using the restore script,
! it is easier to use the scripts.  @FIXME{There is no such restore script!}.
  @value{xref-incremental}, and @value{xref-listed-incremental},
  before making such an attempt.
  
--- 5019,5043 ----
  Before you use these scripts, you need to edit the file
  @file{backup-specs}, which specifies parameters used by the backup
  scripts and by the restore script.  @FIXME{There is no such restore
! script!}  @xref{Script Syntax}.  Once the backup parameters
  are set, you can perform backups or restoration by running the
  appropriate script.
  
  The name of the restore script is @code{restore}.  @FIXME{There is
! no such restore script!}  The names of the level one and full backup
  scripts are, respectively, @code{level-1} and @code{level-0}.
  The @code{level-0} script also exists under the name @code{weekly}, and
  the @code{level-1} under the name @code{daily}---these additional names
! can be changed according to your backup schedule.  @xref{Scripted
  Restoration}, for more information on running the restoration script.
! @xref{Scripted Backups}, for more information on running the
  backup scripts.
  
  @emph{Please Note:} The backup scripts and the restoration scripts are
  designed to be used together.  While it is possible to restore files by
  hand from an archive which was created using a backup script, and to create
  an archive by hand which could then be extracted using the restore script,
! it is easier to use the scripts.  @FIXME{There is no such restore script!}
  @value{xref-incremental}, and @value{xref-listed-incremental},
  before making such an attempt.
  
*************** before using these scripts.
*** 4857,4867 ****
  @FIXME{This about backup scripts needs to be written: BS is a shell
  script ....  thus ... @file{backup-specs} is in shell script syntax.}
  
! @FIXME-xref{Script Syntax}, for an explanation of this syntax.
  
  @FIXME{Whats a parameter ....  looked at by the backup scripts
  ... which will be expecting to find ... now syntax ... value is linked
! to lame ...  @file{backup-specs} specifies the following parameters:}
  
  @table @samp
  @item ADMINISTRATOR
--- 5055,5065 ----
  @FIXME{This about backup scripts needs to be written: BS is a shell
  script ....  thus ... @file{backup-specs} is in shell script syntax.}
  
! @xref{Script Syntax}, for an explanation of this syntax.
  
  @FIXME{Whats a parameter ....  looked at by the backup scripts
  ... which will be expecting to find ... now syntax ... value is linked
! to lame ...}  @file{backup-specs} specifies the following parameters:
  
  @table @samp
  @item ADMINISTRATOR
*************** name in the list---subdirectories on tha
*** 4892,4903 ****
  included, regardless of how they may look to other networked machines.
  Subdirectories on other file systems will be ignored.
  
  The host name specifies which host to run @code{tar} on, and should
  normally be the host that actually contains the file system.  However,
  the host machine must have GNU @code{tar} installed, and must be able
  to access the directory containing the backup scripts and their
  support files using the same file name that is used on the machine
! where the scripts are run (ie. what @code{pwd} will print when in that
  directory on that machine).  If the host that contains the file system
  does not have this capability, you can specify another host as long as
  it can access the file system through NFS.
--- 5090,5102 ----
  included, regardless of how they may look to other networked machines.
  Subdirectories on other file systems will be ignored.
  
+ @item HOST_NAME
  The host name specifies which host to run @code{tar} on, and should
  normally be the host that actually contains the file system.  However,
  the host machine must have GNU @code{tar} installed, and must be able
  to access the directory containing the backup scripts and their
  support files using the same file name that is used on the machine
! where the scripts are run (i.e. what @code{pwd} will print when in that
  directory on that machine).  If the host that contains the file system
  does not have this capability, you can specify another host as long as
  it can access the file system through NFS.
*************** The syntax for running a backup script i
*** 4978,4984 ****
  
  where @var{time-to-be-run} can be a specific system time, or can be
  @kbd{now}.  If you do not specify a time, the script runs at the time
! specified in @file{backup-specs} (@FIXME-pxref{Script Syntax}).
  
  You should start a script with a tape or disk mounted.  Once you
  start a script, it prompts you for new tapes or disks as it
--- 5177,5183 ----
  
  where @var{time-to-be-run} can be a specific system time, or can be
  @kbd{now}.  If you do not specify a time, the script runs at the time
! specified in @file{backup-specs} (@pxref{Script Syntax}).
  
  You should start a script with a tape or disk mounted.  Once you
  start a script, it prompts you for new tapes or disks as it
*************** tape that already contains the end of an
*** 4988,5005 ****
  The @code{restore} script prompts for media by its archive volume,
  so to avoid an error message you should keep track of which tape
  (or disk) contains which volume of the archive.  @FIXME{There is
! no such restore script!}.  @FIXME-xref{Scripted Restoration}.
  @FIXME{Have file names changed?}
  
  The backup scripts write two files on the file system.  The first is a
  record file in @file{/etc/tar-backup/}, which is used by the scripts
  to store and retrieve information about which files were dumped.  This
  file is not meant to be read by humans, and should not be deleted by
! them.  @FIXME-xref{incremental and listed-incremental}, for a more
  detailed explanation of this file.
  
  The second file is a log file containing the names of the file systems
! and files dumped, what time the backup was made, and any error
  messages that were generated, as well as how much space was left in
  the media volume after the last volume of the archive was written.
  You should check this log file after every backup.  The file name is
--- 5187,5204 ----
  The @code{restore} script prompts for media by its archive volume,
  so to avoid an error message you should keep track of which tape
  (or disk) contains which volume of the archive.  @FIXME{There is
! no such restore script!}  @xref{Scripted Restoration}.
  @FIXME{Have file names changed?}
  
  The backup scripts write two files on the file system.  The first is a
  record file in @file{/etc/tar-backup/}, which is used by the scripts
  to store and retrieve information about which files were dumped.  This
  file is not meant to be read by humans, and should not be deleted by
! them.  @xref{incremental and listed-incremental}, for a more
  detailed explanation of this file.
  
  The second file is a log file containing the names of the file systems
! and files dumped, the time when the backup was made, and any error
  messages that were generated, as well as how much space was left in
  the media volume after the last volume of the archive was written.
  You should check this log file after every backup.  The file name is
*************** first volume of the archive mounted.  Th
*** 5043,5049 ****
  volumes as they are needed.  If the archive is on tape, you don't need
  to rewind the tape to to its beginning---if the tape head is
  positioned past the beginning of the archive, the script will rewind
! the tape as needed.  @FIXME-xref{Media}, for a discussion of tape
  positioning.
  
  If you specify @samp{--all} as the @var{files} argument, the
--- 5242,5248 ----
  volumes as they are needed.  If the archive is on tape, you don't need
  to rewind the tape to to its beginning---if the tape head is
  positioned past the beginning of the archive, the script will rewind
! the tape as needed.  @xref{Media}, for a discussion of tape
  positioning.
  
  If you specify @samp{--all} as the @var{files} argument, the
*************** are in specified directories.
*** 5097,5105 ****
  @FIXME{should the title of this section actually be, "naming an
  archive"?}
  
! By default, @code{tar} uses an archive file name that was compiled when
! it was built on the system; usually this name refers to some physical
! tape drive on the machine.  However, the person who installed @code{tar}
  on the system may not set the default to a meaningful value as far as
  most users are concerned.  As a result, you will usually want to tell
  @code{tar} where to find (or create) the archive.  The @value{op-file}
--- 5296,5307 ----
  @FIXME{should the title of this section actually be, "naming an
  archive"?}
  
! By default, @code{tar} uses an archive file name that was compiled into
! it when @code{tar} was built on the system; usually this name refers to
! some physical tape drive on the machine.  Later versions of GNU
! @code{tar} use standard output as the default archive file name (wich
! you can redirect to anoter file).
! However, the person who installed @code{tar}
  on the system may not set the default to a meaningful value as far as
  most users are concerned.  As a result, you will usually want to tell
  @code{tar} where to find (or create) the archive.  The @value{op-file}
*************** floppy disk, or CD write drive.
*** 5136,5142 ****
  If you do not name the archive, @code{tar} uses the value of the
  environment variable @code{TAPE} as the file name for the archive.  If
  that is not available, @code{tar} uses a default, compiled-in archive
! name, usually that for tape unit zero (ie. @file{/dev/tu00}).
  @code{tar} always needs an archive name.
  
  If you use @file{-} as an @var{archive-name}, @code{tar} reads the
--- 5338,5345 ----
  If you do not name the archive, @code{tar} uses the value of the
  environment variable @code{TAPE} as the file name for the archive.  If
  that is not available, @code{tar} uses a default, compiled-in archive
! name, usually that for tape unit zero (ie. @file{/dev/tu00}), or the
! standard output.
  @code{tar} always needs an archive name.
  
  If you use @file{-} as an @var{archive-name}, @code{tar} reads the
*************** $ @kbd{cd sourcedir; tar -cf - . | (cd t
*** 5157,5162 ****
--- 5360,5367 ----
  
  @cindex Standard input and output
  @cindex tar to standard input and output
+ @cindex Remote archives specification
+ @cindex Archives, on remote machines
  To specify an archive file on a device attached to a remote machine,
  use the following:
  
*************** use the following:
*** 5165,5175 ****
  @end example
  
  @noindent
! @code{tar} will complete the remote connection, if possible, and
! prompt you for a username and password.  If you use
! @samp{--file=@@@var{hostname}:/@var{dev}/@var{file name}}, @code{tar}
! will complete the remote connection, if possible, using your username
! as the username on the remote machine.
  
  If the archive file name includes a colon (@samp{:}), then it is assumed
  to be a file on another machine.  If the archive file is
--- 5370,5380 ----
  @end example
  
  @noindent
! @code{tar} will initiate the remote connection, if possible, and prompt
! you for a username and password.  If you use
! @samp{--file=@var{user}@@@var{hostname}:/@var{dev}/@var{file name}},
! @code{tar} will initiate the remote connection, if possible, using your
! username as the username on the remote machine.
  
  If the archive file name includes a colon (@samp{:}), then it is assumed
  to be a file on another machine.  If the archive file is
*************** have the @file{/usr/ucb/rmt} program ins
*** 5183,5188 ****
--- 5388,5408 ----
  file whose name includes a colon, then the remote tape drive behavior
  can be inhibited by using the @value{op-force-local} option.
  
+ @cindex Remote archives and MS-DOS file names
+ The MS-DOS/MS-Windows version of @code{tar} makes an exception to the
+ above: it does @strong{not} treat archive names with drive letters, such
+ as @file{d:/backups/dayly.tar}, as remote.  This is so you would not be
+ forced to use @value{op-force-local} with the usual DOS-style absolute
+ file names.  @code{tar} only makes this exception when the colon is
+ preceded by a single character in the range @kbd{[A-z]}, which are valid
+ MS-DOS/MS-Windows drive letters.  (Yes, DOS also allows the drive letter
+ to be one of the 6 characters between uppercase @kbd{Z} and lowercase
+ @kbd{a}.)  This means that remote machines with single-letter names are
+ effectively disallowed by the MS-DOS version of @code{tar}.  However, we
+ find it hard to believe that anybody will use a one-letter name for a
+ machine.  (And as of now, @code{tar} doesn't support remote access on
+ MS-DOS anyway.)
+ 
  @FIXME{i know we went over this yesterday, but bob (and now i do again,
  too) thinks it's out of the middle of nowhere.  it doesn't seem to tie
  into what came before it well enough <<i moved it now, is it better
*************** archive.  If you specify any operation o
*** 5223,5230 ****
  By default, @code{tar} takes file names from the command line.  However,
  there are other ways to specify file or member names, or to modify the
  manner in which @code{tar} selects the files or members upon which to
! operate; @FIXME{add xref here}.  In general, these methods work both for
! specifying the names of files and archive members.
  
  @node files, exclude, Selecting Archive Members, Choosing
  @section Reading Names from a File
--- 5443,5450 ----
  By default, @code{tar} takes file names from the command line.  However,
  there are other ways to specify file or member names, or to modify the
  manner in which @code{tar} selects the files or members upon which to
! operate; @xref{files}; see @ref{exclude}.  In general, these methods
! work both for specifying the names of files and archive members.
  
  @node files, exclude, Selecting Archive Members, Choosing
  @section Reading Names from a File
*************** create the archive @file{little.tgz}.  (
*** 5266,5278 ****
  more information.)
  
  @example
! $ @kbd{find . -size -400 -print > small-files}
  $ @kbd{tar -c -v -z -T small-files -f little.tgz}
  @end example
  
  @noindent
  @FIXME{say more here to conclude the example/section?}
  
  @menu
  * nul::
  @end menu
--- 5486,5504 ----
  more information.)
  
  @example
! $ @kbd{find . ! -type d -size -400 -print > small-files}
  $ @kbd{tar -c -v -z -T small-files -f little.tgz}
  @end example
  
  @noindent
  @FIXME{say more here to conclude the example/section?}
  
+ The @samp{! -type d} predicate is needed so that @code{find} won't print
+ the name @file{.} directory itself, if it happens to be small in size.
+ If @code{find} were to print the name of @file{.}, all of the files in
+ the current directory would end up in the archive, in addition to the
+ files that are smaller than 400KB!
+ 
  @menu
  * nul::
  @end menu
*************** case there are any files out there calle
*** 5302,5308 ****
  
  This example shows how to use @code{find} to generate a list of files
  larger than 800K in length and put that list into a file called
! @file{long-files}.  The @samp{-print0} option to @code{find} just just
  like @samp{-print}, except that it separates files with a @kbd{NUL}
  rather than with a newline.  You can then run @code{tar} with both the
  @samp{--null} and @samp{-T} options to specify that @code{tar} get the
--- 5528,5534 ----
  
  This example shows how to use @code{find} to generate a list of files
  larger than 800K in length and put that list into a file called
! @file{long-files}.  The @samp{-print0} option to @code{find} works just
  like @samp{-print}, except that it separates files with a @kbd{NUL}
  rather than with a newline.  You can then run @code{tar} with both the
  @samp{--null} and @samp{-T} options to specify that @code{tar} get the
*************** files from that file, @file{long-files},
*** 5311,5320 ****
  @code{tar} to recognize the @kbd{NUL} separator between files.
  
  @example
! $ @kbd{find . -size +800 -print0 > long-files}
  $ @kbd{tar -c -v --null --files-from=long-files --file=big.tar}
  @end example
  
  @FIXME{say anything else here to conclude the section?}
  
  @node exclude, Wildcards, files, Choosing
--- 5537,5551 ----
  @code{tar} to recognize the @kbd{NUL} separator between files.
  
  @example
! $ @kbd{find . ! -type d -size +800 -print0 > long-files}
  $ @kbd{tar -c -v --null --files-from=long-files --file=big.tar}
  @end example
  
+ @noindent
+ Again, you need the @samp{! -type d} predicate to prevent @code{find}
+ from printing the @file{.} directory name, which would have caused
+ @code{tar} to include the entire directory in the archive.
+ 
  @FIXME{say anything else here to conclude the section?}
  
  @node exclude, Wildcards, files, Choosing
*************** Causes @code{tar} to ignore files that m
*** 5351,5357 ****
  @findex exclude-from
  Use the @samp{--exclude-from=@var{file-of-patterns}} option to read a
  list of shell wildcards, one per line, from @var{file}; @code{tar} will
! ignore files matching those regular expressions.  Thus if @code{tar} is
  called as @w{@samp{tar -c -X foo .}} and the file @file{foo} contains a
  single line @file{*.o}, no files whose names end in @file{.o} will be
  added to the archive.
--- 5582,5588 ----
  @findex exclude-from
  Use the @samp{--exclude-from=@var{file-of-patterns}} option to read a
  list of shell wildcards, one per line, from @var{file}; @code{tar} will
! ignore files matching those wildcards.  Thus if @code{tar} is
  called as @w{@samp{tar -c -X foo .}} and the file @file{foo} contains a
  single line @file{*.o}, no files whose names end in @file{.o} will be
  added to the archive.
*************** $ @kbd{tar -c -f @var{archive.tar} -X */
*** 5418,5424 ****
  You must use use shell syntax, or globbing, rather than @code{regexp}
  syntax, when using exclude options in @code{tar}.  If you try to use
  @code{regexp} syntax to describe files to be excluded, your command
! might fail.
  
  @item
  In earlier versions of @code{tar}, what is now the
--- 5649,5655 ----
  You must use use shell syntax, or globbing, rather than @code{regexp}
  syntax, when using exclude options in @code{tar}.  If you try to use
  @code{regexp} syntax to describe files to be excluded, your command
! might fail.  @xref{Wildcards}.
  
  @item
  In earlier versions of @code{tar}, what is now the
*************** the matched string.  The character @samp
*** 5453,5460 ****
  character of the pattern @emph{literally}; it is useful when one needs to
  match the @samp{?}, @samp{*}, @samp{[} or @samp{\} characters, themselves.
  
! The character @samp{[}, up to the matching @samp{]}, introduces a character
! class.  A @dfn{character class} is a list of acceptable characters
  for the next single character of the matched string.  For example,
  @samp{[abcde]} would match any of the first five letters of the alphabet.
  Note that within a character class, all of the ``special characters''
--- 5684,5691 ----
  character of the pattern @emph{literally}; it is useful when one needs to
  match the @samp{?}, @samp{*}, @samp{[} or @samp{\} characters, themselves.
  
! The character @samp{[}, up to the matching @samp{]}, introduces a
! @dfn{character class}.  A character class is a list of acceptable characters
  for the next single character of the matched string.  For example,
  @samp{[abcde]} would match any of the first five letters of the alphabet.
  Note that within a character class, all of the ``special characters''
*************** To be precise, @value{op-after-date} che
*** 5547,5552 ****
--- 5778,5792 ----
  disregards @code{ctime}.  Neither uses @code{atime} (the last time the
  contents of the file were looked at).
  
+ @cindex File time stamp on MS-DOS/MS-Windows
+ @cindex Modification time, on MS-DOS
+ The MS-DOS/MS-Windows file systems record only one time stamp per file
+ (Windows 9X and NT file systems usually do have all three time fields).
+ On those file systems, @value{op-after-date} and @value{op-newer-mtime}
+ will have the same effect.  MS-DOS stores file time with 2-second
+ granularity; you need to consider this when setting the value of
+ @var{date} for these two options.
+ 
  Date specifiers can have embedded spaces.  Because of this, you may need
  to quote date arguments to keep the shell from parsing them as separate
  arguments.
*************** use the @code{find} utility for hunting 
*** 5597,5603 ****
  construct a list of file names which you could then pass to @code{tar}.
  @code{find} allows you to be more selective when choosing which files to
  archive; see @ref{files} for more information on using @code{find} with
! @code{tar}, or look.
  
  @table @kbd
  @item --no-recursion
--- 5837,5843 ----
  construct a list of file names which you could then pass to @code{tar}.
  @code{find} allows you to be more selective when choosing which files to
  archive; see @ref{files} for more information on using @code{find} with
! @code{tar}.
  
  @table @kbd
  @item --no-recursion
*************** a directory is not on the same filesyste
*** 5649,5659 ****
  itself, @code{tar} will not archive anything beneath it; in other words,
  @code{tar} will not cross mount points.
  
! It is reported that using this option, the mount point is is archived,
! but nothing under it.
  
  This option is useful for making full or incremental archival backups of
! a file system.  If this option is used in conjunction with
  @value{op-verbose}, files that are excluded are mentioned by name on the
  standard error.
  
--- 5889,5899 ----
  itself, @code{tar} will not archive anything beneath it; in other words,
  @code{tar} will not cross mount points.
  
! It is reported that using this option, the mount point @strong{is}
! archived, but nothing under it is.
  
  This option is useful for making full or incremental archival backups of
! a single file system.  If this option is used in conjunction with
  @value{op-verbose}, files that are excluded are mentioned by name on the
  standard error.
  
*************** will place the files @file{grape} and @f
*** 5696,5702 ****
  directory into the archive @file{jams.tar}, followed by the file
  @file{cherry} from the directory @file{food}.  This option is especially
  useful when you have several widely separated files that you want to
! store in the same archive.
  
  Note that the file @file{cherry} is recorded in the archive under the
  precise name @file{cherry}, @emph{not} @file{food/cherry}.  Thus, the
--- 5936,5942 ----
  directory into the archive @file{jams.tar}, followed by the file
  @file{cherry} from the directory @file{food}.  This option is especially
  useful when you have several widely separated files that you want to
! store as if they were in the same directory.
  
  Note that the file @file{cherry} is recorded in the archive under the
  precise name @file{cherry}, @emph{not} @file{food/cherry}.  Thus, the
*************** same directory; if the archive is extrac
*** 5707,5722 ****
  Contrast this with the command,
  
  @example
! $ @kbd{tar -c -f jams.tar grape prune -C food red/cherry}
  @end example
  
  @noindent
  which records the third file in the archive under the name
! @file{red/cherry} so that, if the archive is extracted using
  @samp{tar --extract}, the third file will be written in a subdirectory
! named @file{orange-colored}.
  
! You can use the @samp{--directory} option to make the archive
  independent of the original name of the directory holding the files.
  The following command places the files @file{/etc/passwd},
  @file{/etc/hosts}, and @file{/lib/libc.a} into the archive
--- 5947,5962 ----
  Contrast this with the command,
  
  @example
! $ @kbd{tar -c -f jams.tar grape prune food/cherry}
  @end example
  
  @noindent
  which records the third file in the archive under the name
! @file{food/cherry} so that, if the archive is extracted using
  @samp{tar --extract}, the third file will be written in a subdirectory
! named @file{food}.
  
! You can use the @value{op-directory} option to make the archive
  independent of the original name of the directory holding the files.
  The following command places the files @file{/etc/passwd},
  @file{/etc/hosts}, and @file{/lib/libc.a} into the archive
*************** on the command line: @file{passwd}, @fil
*** 5732,5739 ****
  They will not appear to be related by file name to the original
  directories where those files were located.
  
! Note that @samp{--directory} options are interpreted consecutively.  If
! @samp{--directory} specifies a relative file name, it is interpreted
  relative to the then current directory, which might not be the same as
  the original current working directory of @code{tar}, due to a previous
  @samp{--directory} option.
--- 5972,5979 ----
  They will not appear to be related by file name to the original
  directories where those files were located.
  
! Note that @value{op-directory} options are interpreted consecutively.  If
! @value{op-directory} specifies a relative file name, it is interpreted
  relative to the then current directory, which might not be the same as
  the original current working directory of @code{tar}, due to a previous
  @samp{--directory} option.
*************** in the archive.  For example, if the arc
*** 5771,5776 ****
--- 6011,6019 ----
  @file{/etc/passwd}, @code{tar} will extract it as if the name were
  really @file{etc/passwd}.
  
+ On MS-DOS and MS-Windows, @code{tar} also strips the drive letter and
+ the colon that follows it, if the original file names include them.
+ 
  Other @code{tar} programs do not do this.  As a result, if you create an
  archive whose member names start with a slash, they will be difficult
  for other people with a non-GNU @code{tar} program to use.  Therefore,
*************** the @value{op-absolute-names} option.
*** 5787,5796 ****
  
  Normally, @code{tar} acts on files relative to the working
  directory---ignoring superior directory names when archiving, and
! ignoring leading slashes when extracting.
  
  When you specify @value{op-absolute-names}, @code{tar} stores file names
! including all superior directory names, and preserves leading slashes.
  If you only invoked @code{tar} from the root directory you would never
  need the @value{op-absolute-names} option, but using this option may be
  more convenient than switching to root.
--- 6030,6042 ----
  
  Normally, @code{tar} acts on files relative to the working
  directory---ignoring superior directory names when archiving, and
! ignoring leading slashes when extracting.  (On MS-DOS/MS-Windows, it
! also ignores any drive specifications, a letter and a colon, so
! @file{d:/foo/bar} is archived as @file{foo/bar}.)
  
  When you specify @value{op-absolute-names}, @code{tar} stores file names
! including all superior directory names, and preserves leading slashes
! (and drive specs on MS-DOS/MS-Windows).
  If you only invoked @code{tar} from the root directory you would never
  need the @value{op-absolute-names} option, but using this option may be
  more convenient than switching to root.
*************** archiving files.  Preserves leading slas
*** 5812,5818 ****
  @code{tar} prints out a message about removing the @samp{/} from file
  names.  This message appears once per GNU @code{tar} invocation.  It
  represents something which ought to be told; ignoring what it means can
! cause very serious surprises, later.
  
  Some people, nevertheless, do not want to see this message.  Wanting to
  play really dangerously, one may of course redirect @code{tar} standard
--- 6058,6065 ----
  @code{tar} prints out a message about removing the @samp{/} from file
  names.  This message appears once per GNU @code{tar} invocation.  It
  represents something which ought to be told; ignoring what it means can
! cause very serious surprises, later.  (On MS-DOS/MS-Windows, @code{tar}
! also reports the removing of drive spec.)
  
  Some people, nevertheless, do not want to see this message.  Wanting to
  play really dangerously, one may of course redirect @code{tar} standard
*************** If you intend to have your @code{tar} ar
*** 6385,6390 ****
--- 6632,6640 ----
  you should not rely on case distinction for file names, and you might
  use the GNU @code{doschk} program for helping you further diagnosing
  illegal MSDOS names, which are even more limited than System V's.
+ @code{tar} compiled for MSDOS @emph{does} try to cope with filenames
+ which are illegal on MSDOS file systems (@pxref{Basic tar}), but the
+ best portability strategy is to avoid such problems in the first place.
  
  @node dereference, old, Portable Names, Portability
  @subsection Symbolic Links
*************** contiguous files, and device files, and 
*** 6433,6439 ****
  group and user IDs instead of group and user names.
  
  When updating an archive, do not use @value{op-old-archive}
! unless the archive was created with using this option.
  
  In most cases, a @emph{new} format archive can be read by an @emph{old}
  @code{tar} program without serious trouble, so this option should
--- 6683,6689 ----
  group and user IDs instead of group and user names.
  
  When updating an archive, do not use @value{op-old-archive}
! unless the archive was created using this option.
  
  In most cases, a @emph{new} format archive can be read by an @emph{old}
  @code{tar} program without serious trouble, so this option should
*************** We plan to reimplement these GNU extensi
*** 6457,6463 ****
  upward compatible with the latest POSIX @code{tar} format, but we
  don't know when this will be done.
  
! In the mean time, there is simply no telling what might happen if you
  read a GNU @code{tar} archive, which uses the GNU extensions, using
  some other @code{tar} program.  So if you want to read the archive
  with another @code{tar} program, be sure to write it using the
--- 6707,6713 ----
  upward compatible with the latest POSIX @code{tar} format, but we
  don't know when this will be done.
  
! In the mean time, there is simply no way of telling what might happen if you
  read a GNU @code{tar} archive, which uses the GNU extensions, using
  some other @code{tar} program.  So if you want to read the archive
  with another @code{tar} program, be sure to write it using the
*************** limitations will pop up, but until now, 
*** 6519,6525 ****
  references to other parts of the standard I do not have, which should
  normally enforce limitations on stored file names (I suspect things
  like fixing what @kbd{/} and @kbd{@key{NUL}} means).  There are also
! some points which the standard does not make clear, Existing practice
  will then drive what I should do.
  
  POSIX mandates that, when a file name cannot fit within 100 to
--- 6769,6775 ----
  references to other parts of the standard I do not have, which should
  normally enforce limitations on stored file names (I suspect things
  like fixing what @kbd{/} and @kbd{@key{NUL}} means).  There are also
! some points which the standard does not make clear.  Existing practice
  will then drive what I should do.
  
  POSIX mandates that, when a file name cannot fit within 100 to
*************** fit within 100 characters, a warning sho
*** 6531,6537 ****
  should disobey this specification, and automatically switch to using
  GNU extensions to overcome file name or link name length limitations.
  
! There is a problem, however, which I did not intimately studied yet.
  Given a truly POSIX archive with names having more than 100 characters,
  I guess that GNU @code{tar} up to 1.11.8 will process it as if it were an
  old V7 archive, and be fooled by some fields which are coded differently.
--- 6781,6787 ----
  should disobey this specification, and automatically switch to using
  GNU extensions to overcome file name or link name length limitations.
  
! There is a problem, however, which I have not intimately studied yet.
  Given a truly POSIX archive with names having more than 100 characters,
  I guess that GNU @code{tar} up to 1.11.8 will process it as if it were an
  old V7 archive, and be fooled by some fields which are coded differently.
*************** the correction.
*** 6631,6637 ****
  SunOS and HP-UX @code{tar} fail to accept archives created using GNU
  @code{tar} and containing non-ASCII file names, that is, file names
  having characters with the eight bit set, because they use signed
! checksums, while GNU @code{tar} uses unsigned checksums while creating
  archives, as per POSIX standards.  On reading, GNU @code{tar} computes
  both checksums and accept any.  It is somewhat worrying that a lot of
  people may go around doing backup of their files using faulty (or at
--- 6881,6887 ----
  SunOS and HP-UX @code{tar} fail to accept archives created using GNU
  @code{tar} and containing non-ASCII file names, that is, file names
  having characters with the eight bit set, because they use signed
! checksums, while GNU @code{tar} uses unsigned checksums when creating
  archives, as per POSIX standards.  On reading, GNU @code{tar} computes
  both checksums and accept any.  It is somewhat worrying that a lot of
  people may go around doing backup of their files using faulty (or at
*************** least non-standard) software, not learni
*** 6639,6656 ****
  to restore their missing files with an incompatible file extractor,
  or vice versa.
  
! GNU @code{tar} compute checksums both ways, and accept any on read,
  so GNU tar can read Sun tapes even with their wrong checksums.
  GNU @code{tar} produces the standard checksum, however, raising
  incompatibilities with Sun.  That is to say, GNU @code{tar} has not
  been modified to @emph{produce} incorrect archives to be read by buggy
! @code{tar}'s.  I've been told that more recent Sun @code{tar} now
  read standard archives, so maybe Sun did a similar patch, after all?
  
  The story seems to be that when Sun first imported @code{tar}
  sources on their system, they recompiled it without realizing that
  the checksums were computed differently, because of a change in
! the default signing of @code{char}'s in their compiler.  So they
  started computing checksums wrongly.  When they later realized their
  mistake, they merely decided to stay compatible with it, and with
  themselves afterwards.  Presumably, but I do not really know, HP-UX
--- 6889,6906 ----
  to restore their missing files with an incompatible file extractor,
  or vice versa.
  
! GNU @code{tar} computes checksums both ways, and accept any on read,
  so GNU tar can read Sun tapes even with their wrong checksums.
  GNU @code{tar} produces the standard checksum, however, raising
  incompatibilities with Sun.  That is to say, GNU @code{tar} has not
  been modified to @emph{produce} incorrect archives to be read by buggy
! @code{tar}s.  I've been told that more recent Sun @code{tar} now
  read standard archives, so maybe Sun did a similar patch, after all?
  
  The story seems to be that when Sun first imported @code{tar}
  sources on their system, they recompiled it without realizing that
  the checksums were computed differently, because of a change in
! the default signing of @code{char}s in their compiler.  So they
  started computing checksums wrongly.  When they later realized their
  mistake, they merely decided to stay compatible with it, and with
  themselves afterwards.  Presumably, but I do not really know, HP-UX
*************** a @code{tar} able to read the good archi
*** 6673,6678 ****
--- 6923,6938 ----
  @cindex Storing archives in compressed format
  @UNREVISED
  
+ You can have archives be compressed by using the @value{op-gzip} option.
+ This will arrange for @code{tar} to use the @code{gzip} program to be
+ used to compress or uncompress the archive wren writing or reading it.
+ 
+ To use the older, obsolete, @code{compress} program, use the
+ @value{op-compress} option.  The GNU Project recommends you not use
+ @code{compress}, because there is a patent covering the algorithm it
+ uses.  You could be sued for patent infringment merely by running
+ @code{compress}.
+ 
  @table @kbd
  @item -z
  @itemx --gzip
*************** a @code{tar} able to read the good archi
*** 6680,6700 ****
  Filter the archive through @code{gzip}.
  @end table
  
! @FIXME{ach; these two bits orig from "compare" (?).  where to put?} Some
! format parameters must be taken into consideration when modifying an
! archive: @FIXME{???}.  Compressed archives cannot be modified.
  
  You can use @samp{--gzip} and @samp{--gunzip} on physical devices
  (tape drives, etc.) and remote files as well as on normal files; data
  to or from such devices or remote files is reblocked by another copy
  of the @code{tar} program to enforce the specified (or default) record
! size.  The default compression parameters are used; if you need to
! override them, avoid the @value{op-gzip} option and run @code{gzip}
! explicitly.  (Or set the @samp{GZIP} environment variable.)
! 
! The @value{op-gzip} option does not work with the @value{op-multi-volume}
! option, or with the @value{op-update}, @value{op-append},
! @value{op-concatenate}, or @value{op-delete} operations.
  
  It is not exact to say that GNU @code{tar} is to work in concert
  with @code{gzip} in a way similar to @code{zip}, say.  Surely, it is
--- 6940,6973 ----
  Filter the archive through @code{gzip}.
  @end table
  
! To perform compression and uncompression on the archive, @code{tar} runs
! the @code{gzip} utility.  @code{tar} uses the default compression
! parameters; if you need to override them, avoid the @value{op-gzip}
! option and run the @code{gzip} utility explicitly.  (Or set the
! @samp{GZIP} environment variable.)  It is useful to be able to call the
! @code{gzip} utility from within @code{tar} because the @code{gzip}
! utility by itself cannot access remote tape drives.
! 
! The @value{op-gzip} option will not work in conjunction with the
! @value{op-multi-volume} option or the @value{op-append}, @value{op-update},
! @value{op-concatenate} and @value{op-delete} operations.
! @xref{Operations}, for more information on these operations.
  
  You can use @samp{--gzip} and @samp{--gunzip} on physical devices
  (tape drives, etc.) and remote files as well as on normal files; data
  to or from such devices or remote files is reblocked by another copy
  of the @code{tar} program to enforce the specified (or default) record
! size.
! 
! @table @kbd
! @item -Z
! @itemx --compress
! @itemx --uncompress
! Filter the archive through @code{compress}.  Otherwise like @value{op-gzip}.
! 
! @item --use-compress-program=@var{prog}
! Filter through @var{prog} (must accept @samp{-d}).
! @end table
  
  It is not exact to say that GNU @code{tar} is to work in concert
  with @code{gzip} in a way similar to @code{zip}, say.  Surely, it is
*************** disk space, by using pipes internally:
*** 6728,6733 ****
--- 7001,7018 ----
  $ @kbd{tar tfz archive.tar.gz}
  @end example
  
+ (@code{tar} on MS-DOS and MS-Windows also supports this on-the-fly
+ compression with @code{gzip}, but since pipes are simulated with disk
+ files on MS-DOS, you @emph{do} need disk space to store the uncompressed
+ copy, while @code{tar} runs.  In particular, make sure the disk with the
+ directory which is the value of the environment variable @code{TMPDIR}
+ has enough free space, as many DOS users tend to point it to a RAM
+ disk.)
+ 
+ If there is no compress utility available, @code{tar} will report an error.
+ @strong{Please note} that the @code{compress} program may be covered by
+ a patent, and therefore we recommend you stop using it.
+ 
  @cindex corrupted archives
  About corrupted compressed archives: @code{gzip}'ed files have no
  redundancy, for maximum compression.  The adaptive nature of the
*************** There are pending suggestions for having
*** 6740,6802 ****
  compression in GNU @code{tar}.  This would allow for viewing the
  contents without decompression, and for resynchronizing decompression at
  every volume or file, in case of corrupted archives.  Doing so, we might
! loose some compressibility.  But this would have make recovering easier.
  So, there are pros and cons.  We'll see!
  
- @table @kbd
- @item -Z
- @itemx --compress
- @itemx --uncompress
- Filter the archive through @code{compress}.  Otherwise like @value{op-gzip}.
- 
- @item --use-compress-program=@var{prog}
- Filter through @var{prog} (must accept @samp{-d}).
- @end table
- 
- @value{op-compress} stores an archive in compressed format.  This
- option is useful in saving time over networks and space in pipes, and
- when storage space is at a premium.  @value{op-compress} causes
- @code{tar} to compress when writing the archive, or to uncompress when
- reading the archive.
- 
- To perform compression and uncompression on the archive, @code{tar}
- runs the @code{compress} utility.  @code{tar} uses the default
- compression parameters; if you need to override them, avoid the
- @value{op-compress} option and run the @code{compress} utility
- explicitly.  It is useful to be able to call the @code{compress}
- utility from within @code{tar} because the @code{compress} utility by
- itself cannot access remote tape drives.
- 
- The @value{op-compress} option will not work in conjunction with the
- @value{op-multi-volume} option or the @value{op-append}, @value{op-update},
- @value{op-append} and @value{op-delete} operations.  @xref{Operations}, for
- more information on these operations.
- 
- If there is no compress utility available, @code{tar} will report an error.
- @strong{Please note} that the @code{compress} program may be covered by
- a patent, and therefore we recommend you stop using it.
- 
- @table @kbd
- @item --compress
- @itemx --uncompress
- @itemx -z
- @itemx -Z
- When this option is specified, @code{tar} will compress (when writing
- an archive), or uncompress (when reading an archive).  Used in
- conjunction with the @value{op-create}, @value{op-extract}, @value{op-list} and
- @value{op-compare} operations.
- @end table
- 
- You can have archives be compressed by using the @value{op-gzip} option.
- This will arrange for @code{tar} to use the @code{gzip} program to be
- used to compress or uncompress the archive wren writing or reading it.
- 
- To use the older, obsolete, @code{compress} program, use the
- @value{op-compress} option.  The GNU Project recommends you not use
- @code{compress}, because there is a patent covering the algorithm it
- uses.  You could be sued for patent infringment merely by running
- @code{compress}.
- 
  I have one question, or maybe it's a suggestion if there isn't a way
  to do it now. I would like to use @value{op-gzip}, but I'd also like the
  output to be fed through a program like GNU @code{ecc} (actually, right
--- 7025,7033 ----
  compression in GNU @code{tar}.  This would allow for viewing the
  contents without decompression, and for resynchronizing decompression at
  every volume or file, in case of corrupted archives.  Doing so, we might
! loose some compressibility.  But this would make recovering easier.
  So, there are pros and cons.  We'll see!
  
  I have one question, or maybe it's a suggestion if there isn't a way
  to do it now. I would like to use @value{op-gzip}, but I'd also like the
  output to be fed through a program like GNU @code{ecc} (actually, right
*************** the command line with the creation or up
*** 6855,6876 ****
  
  Files in the filesystem occasionally have ``holes.''  A hole in a file
  is a section of the file's contents which was never written.  The
! contents of a hole read as all zeros.  On many operating systems,
  actual disk storage is not allocated for holes, but they are counted
  in the length of the file.  If you archive such a file, @code{tar}
  could create an archive longer than the original.  To have @code{tar}
  attempt to recognize the holes in a file, use @value{op-sparse}.  When
  you use the @value{op-sparse} option, then, for any file using less
  disk space than would be expected from its length, @code{tar} searches
! the file for consecutive stretches of zeros.  It then records in the
! archive for the file where the consecutive stretches of zeros are, and
  only archives the ``real contents'' of the file.  On extraction (using
  @value{op-sparse} is not needed on extraction) any such files have
! hols created wherever the continuous stretches of zeros were found.
  Thus, if you use @value{op-sparse}, @code{tar} archives won't take
  more space than the original.
  
! A file is sparse if it contains blocks of zeros whose existence is
  recorded, but that have no space allocated on disk.  When you specify
  the @value{op-sparse} option in conjunction with the @value{op-create}
  operation, @code{tar} tests all files for sparseness while archiving.
--- 7086,7107 ----
  
  Files in the filesystem occasionally have ``holes.''  A hole in a file
  is a section of the file's contents which was never written.  The
! contents of a hole read as all zeroes.  On many operating systems,
  actual disk storage is not allocated for holes, but they are counted
  in the length of the file.  If you archive such a file, @code{tar}
  could create an archive longer than the original.  To have @code{tar}
  attempt to recognize the holes in a file, use @value{op-sparse}.  When
  you use the @value{op-sparse} option, then, for any file using less
  disk space than would be expected from its length, @code{tar} searches
! the file for consecutive stretches of zeroes.  It then records in the
! archive for the file where the consecutive stretches of zeroes are, and
  only archives the ``real contents'' of the file.  On extraction (using
  @value{op-sparse} is not needed on extraction) any such files have
! holes created wherever the continuous stretches of zeroes were found.
  Thus, if you use @value{op-sparse}, @code{tar} archives won't take
  more space than the original.
  
! A file is sparse if it contains blocks of zeroes whose existence is
  recorded, but that have no space allocated on disk.  When you specify
  the @value{op-sparse} option in conjunction with the @value{op-create}
  operation, @code{tar} tests all files for sparseness while archiving.
*************** the file in the archive.  @value{xref-cr
*** 6879,6885 ****
  about creating archives.
  
  @value{op-sparse} is useful when archiving files, such as dbm files,
! likely to contain many nulls.  This option dramatically
  decreases the amount of space needed to store such an archive.
  
  @quotation
--- 7110,7116 ----
  about creating archives.
  
  @value{op-sparse} is useful when archiving files, such as dbm files,
! that are likely to contain many nulls.  This option dramatically
  decreases the amount of space needed to store such an archive.
  
  @quotation
*************** the archive.  Use in conjunction with wr
*** 6905,6911 ****
  @end table
  
  However, users should be well aware that at archive creation time, GNU
! @code{tar} still has to read whole disk file to locate the @dfn{holes}, and
  so, even if sparse files use little space on disk and in the archive, they
  may sometimes require inordinate amount of time for reading and examining
  all-zero blocks of a file.  Although it works, it's painfully slow for a
--- 7136,7142 ----
  @end table
  
  However, users should be well aware that at archive creation time, GNU
! @code{tar} still has to read the whole disk file to locate the @dfn{holes}, and
  so, even if sparse files use little space on disk and in the archive, they
  may sometimes require inordinate amount of time for reading and examining
  all-zero blocks of a file.  Although it works, it's painfully slow for a
*************** Handling of file attributes
*** 6959,6965 ****
  
  @table @kbd
  @item --atime-preserve
! Do not change access times on dumped files.
  
  @item -m
  @itemx --touch
--- 7190,7198 ----
  
  @table @kbd
  @item --atime-preserve
! Do not change access times on dumped files.  This option doesn't have
! any effect on MS-DOS, since @code{atime} is not supported by the DOS FAT
! file system.  (It @emph{does} work on MS-Windows 9X.)
  
  @item -m
  @itemx --touch
*************** files are easily and silently lost when 
*** 6986,6993 ****
  When writing an archive, @code{tar} writes the user id and user name
  separately.  If it can't find a user name (because the user id is not
  in @file{/etc/passwd}), then it does not write one.  When restoring,
! and doing a @code{chmod} like when you use @value{op-same-permissions}
! (@FIXME{same-owner?}), it tries to look the name (if one was written)
  up in @file{/etc/passwd}.  If it fails, then it uses the user id
  stored in the archive instead.
  
--- 7219,7226 ----
  When writing an archive, @code{tar} writes the user id and user name
  separately.  If it can't find a user name (because the user id is not
  in @file{/etc/passwd}), then it does not write one.  When restoring,
! and doing a @code{chmod} like when you use @value{op-same-permissions},
! (@FIXME{same-owner?}) it tries to look the name (if one was written)
  up in @file{/etc/passwd}.  If it fails, then it uses the user id
  stored in the archive instead.
  
*************** fine tuning permissions and ownership.  
*** 7028,7033 ****
--- 7261,7294 ----
  I think.  GNU @code{tar} is already crowded with options and moreover,
  the approach just explained gives you a great deal of control already.
  
+ @item --group=@var{group}
+ 
+ Files added to the @code{tar} archive will have a group id of @var{group},
+ rather than the group from the source file.  @var{group} is first decoded
+ as a group symbolic name, but if this interpretation fails, it has to be
+ a decimal numeric group ID.  @code{tar} on MS-DOS/MS-Windows allows
+ @var{group} to be @emph{any} string.  These systems don't support group
+ id's, so @code{tar} allows them to give away files to anybody.  If
+ @var{group} consists only of digits, it is treated as a numeric GID;
+ otherwise it is treated as a group name.
+ 
+ @item --owner=@var{user}
+ 
+ Specifies that @code{tar} should use @var{user} as the owner of members
+ when creating archives, instead of the user associated with the source
+ file.  @var{user} is first decoded as a user symbolic name, but if
+ this interpretation fails, it has to be a decimal numeric user ID.
+ 
+ There is no value indicating a missing number, and @samp{0} usually means
+ @code{root}.  Some people like to force @samp{0} as the value to offer in
+ their distributions for the owner of files, because the @code{root} user is
+ anonymous anyway, so that might as well be the owner of anonymous archives.
+ 
+ @code{tar} on MS-DOS/MS-Windows allows @var{user} to be @emph{any}
+ string.  These systems don't support file ownership, so @code{tar} allows
+ them to give away files to anybody.  If @var{user} includes only digits,
+ it is treated as a numeric UID; otherwise, it is treated as a user name.
+ 
  @item -p
  @itemx --same-permissions
  @itemx --preserve-permissions
*************** ID of the file owners, respectively.  If
*** 7149,7155 ****
  not support numeric user or group IDs, these fields should be ignored.
  
  The @code{size} field is the size of the file in bytes; linked files
! are archived with this field specified as zero.  @FIXME-xref{Modifiers}, in
  particular the @value{op-incremental} option.
  
  The @code{mtime} field is the modification time of the file at the time
--- 7410,7416 ----
  not support numeric user or group IDs, these fields should be ignored.
  
  The @code{size} field is the size of the file in bytes; linked files
! are archived with this field specified as zero.  @xref{Backups}, in
  particular the @value{op-incremental} option.
  
  The @code{mtime} field is the modification time of the file at the time
*************** way puts one copy for every link, but yo
*** 7408,7414 ****
  of the names.
  
  @quotation
! What type of check sum (if any) is used, and how is this calculated.
  @end quotation
  
  See the attached manual pages for @code{tar} and @code{cpio} format.
--- 7669,7675 ----
  of the names.
  
  @quotation
! What type of check sum (if any) is used, and how is this calculated?
  @end quotation
  
  See the attached manual pages for @code{tar} and @code{cpio} format.
*************** See the attached manual pages for @code{
*** 7416,7423 ****
  @code{tar} header for a file; @code{cpio} uses no checksum.
  
  @quotation
! If anyone knows why @code{cpio} was made when @code{tar} was present
! at the unix scene,
  @end quotation
  
  It wasn't.  @code{cpio} first showed up in PWB/UNIX 1.0; no
--- 7677,7684 ----
  @code{tar} header for a file; @code{cpio} uses no checksum.
  
  @quotation
! Does anyone know why @code{cpio} was made when @code{tar} was present
! at the unix scene?
  @end quotation
  
  It wasn't.  @code{cpio} first showed up in PWB/UNIX 1.0; no
*************** know whether any version that was genera
*** 7426,7432 ****
  had @code{tar}, or, if so, whether the people within AT&T who did
  @code{cpio} knew about it.
  
! On restore, if there is a corruption on a tape @code{tar} will stop at
  that point, while @code{cpio} will skip over it and try to restore the
  rest of the files.
  
--- 7687,7693 ----
  had @code{tar}, or, if so, whether the people within AT&T who did
  @code{cpio} knew about it.
  
! On restore, if there is a corruption on a tape, @code{tar} will stop at
  that point, while @code{cpio} will skip over it and try to restore the
  rest of the files.
  
*************** to start on a record boundary.
*** 7437,7451 ****
  
  @quotation
  Is there any differences between the ability to recover crashed
! archives between the two of them. (Is there any chance of recovering
! crashed archives at all.)
  @end quotation
  
! Theoretically it should be easier under @code{tar} since the blocking
  lets you find a header with some variation of @samp{dd skip=@var{nn}}.
  However, modern @code{cpio}'s and variations have an option to just
  search for the next file header after an error with a reasonable chance
! of re-syncing.  However, lots of tape driver software won't allow you to
  continue past a media error which should be the only reason for getting
  out of sync unless a file changed sizes while you were writing the
  archive.
--- 7698,7712 ----
  
  @quotation
  Is there any differences between the ability to recover crashed
! archives between the two of them?  (Is there any chance of recovering
! crashed archives at all?)
  @end quotation
  
! Theoretically, it should be easier under @code{tar} since the blocking
  lets you find a header with some variation of @samp{dd skip=@var{nn}}.
  However, modern @code{cpio}'s and variations have an option to just
  search for the next file header after an error with a reasonable chance
! of re-syncing.  Note that lots of tape driver software won't allow you to
  continue past a media error which should be the only reason for getting
  out of sync unless a file changed sizes while you were writing the
  archive.
*************** physically smaller EXABYTE tape cartridg
*** 7491,7498 ****
  Magnetic media are re-usable---once the archive on a tape is no longer
  needed, the archive can be erased and the tape or disk used over.
  Media quality does deteriorate with use, however.  Most tapes or disks
! should be disgarded when they begin to produce data errors.  EXABYTE
! tape cartridges should be disgarded when they generate an @dfn{error
  count} (number of non-usable bits) of more than 10k.
  
  Magnetic media are written and erased using magnetic fields, and
--- 7752,7759 ----
  Magnetic media are re-usable---once the archive on a tape is no longer
  needed, the archive can be erased and the tape or disk used over.
  Media quality does deteriorate with use, however.  Most tapes or disks
! should be discarded when they begin to produce data errors.  EXABYTE
! tape cartridges should be discarded when they generate an @dfn{error
  count} (number of non-usable bits) of more than 10k.
  
  Magnetic media are written and erased using magnetic fields, and
*************** This program is free software from the U
*** 7542,7548 ****
  copy of the source code can be found with the sources for @code{tar};
  it's compiled and installed by default.
  
! If this option is not given, but the environment variable @code{TAPE} is
  set, its value is used; otherwise, old versions of @code{tar} used a default
  archive name (which was picked when @code{tar} was compiled).  The
  default is normally set up to be the @dfn{first} tape drive or other
--- 7803,7816 ----
  copy of the source code can be found with the sources for @code{tar};
  it's compiled and installed by default.
  
! Since absolute file names on MS-DOS and MS-Windows include a drive
! letter, like in @file{d:/dir/subdir/file}, @code{tar} compiled for these
! platforms does not treat file names with @samp{:} as remote files if
! there is a single letter before the colon.  @code{tar} also does not
! currently support archives on remote machines when it runs on
! MS-DOS/MS-Windows.
! 
! If @value{op-file} is not given, but the environment variable @code{TAPE} is
  set, its value is used; otherwise, old versions of @code{tar} used a default
  archive name (which was picked when @code{tar} was compiled).  The
  default is normally set up to be the @dfn{first} tape drive or other
*************** transportable I/O medium on the system.
*** 7551,7557 ****
  Starting with version 1.11.5, GNU @code{tar} uses standard input and
  standard output as the default device, and I will not try anymore
  supporting automatic device detection at installation time.  This was
! failing really in too many cases, it was hopeless.  This is now
  completely left to the installer to override standard input and standard
  output for default device, if this seems preferrable to him/her.
  Further, I think @emph{most} actual usages of @code{tar} are done with
--- 7819,7825 ----
  Starting with version 1.11.5, GNU @code{tar} uses standard input and
  standard output as the default device, and I will not try anymore
  supporting automatic device detection at installation time.  This was
! failing really in so many cases that it was hopeless to repair.  This is now
  completely left to the installer to override standard input and standard
  output for default device, if this seems preferrable to him/her.
  Further, I think @emph{most} actual usages of @code{tar} are done with
*************** could also check for @samp{DEFTAPE} in @
*** 7577,7590 ****
  
  @table @kbd
  @item --force-local
! Archive file is local even if it contains a colon.
  
  @item --rsh-command=@var{command}
  Use remote @var{command} instead of @code{rsh}.  This option exists
  so that people who use something other than the standard @code{rsh}
  (e.g., a Kerberized @code{rsh}) can access a remote device.
  
! When this command is not used, the shell command found when
  the @code{tar} program was installed is used instead.  This is
  the first found of @file{/usr/ucb/rsh}, @file{/usr/bin/remsh},
  @file{/usr/bin/rsh}, @file{/usr/bsd/rsh} or @file{/usr/bin/nsh}.
--- 7845,7860 ----
  
  @table @kbd
  @item --force-local
! Treat the archive file as local even if it contains a colon.  (The
! MS-DOS version always treats DOS-style absolute file names with a drive
! letter as local.)
  
  @item --rsh-command=@var{command}
  Use remote @var{command} instead of @code{rsh}.  This option exists
  so that people who use something other than the standard @code{rsh}
  (e.g., a Kerberized @code{rsh}) can access a remote device.
  
! When this option is not used, the shell command found when
  the @code{tar} program was installed is used instead.  This is
  the first found of @file{/usr/ucb/rsh}, @file{/usr/bin/remsh},
  @file{/usr/bin/rsh}, @file{/usr/bsd/rsh} or @file{/usr/bin/nsh}.
*************** The installer may have overriden this by
*** 7592,7598 ****
  variable @code{RSH} @emph{at installation time}.
  
  @item -[0-7][lmh]
! Specify drive and density.
  
  @item -M
  @itemx --multi-volume
--- 7862,7868 ----
  variable @code{RSH} @emph{at installation time}.
  
  @item -[0-7][lmh]
! Specify drive and density.  (Not supported on MS-DOS/MS-Windows.)
  
  @item -M
  @itemx --multi-volume
*************** Unless you use the @value{op-absolute-na
*** 7639,7656 ****
  not allow you to create an archive that contains absolute file names
  (a file name beginning with @samp{/}.) If you try, @code{tar} will
  automatically remove the leading @samp{/} from the file names it
! stores in the archive.  It will also type a warning message telling
! you what it is doing.
  
  When reading an archive that was created with a different @code{tar}
  program, GNU @code{tar} automatically extracts entries in the archive
  which have absolute file names as if the file names were not absolute.
- This is an important feature.  A visitor here once gave a
- @code{tar} tape to an operator to restore; the operator used Sun @code{tar}
- instead of GNU @code{tar}, and the result was that it replaced large
- portions of our @file{/bin} and friends with versions from the tape;
- needless to say, we were unhappy about having to recover the file system
- from backup tapes.
  
  For example, if the archive contained a file @file{/usr/bin/computoy},
  GNU @code{tar} would extract the file to @file{usr/bin/computoy},
--- 7909,7921 ----
  not allow you to create an archive that contains absolute file names
  (a file name beginning with @samp{/}.) If you try, @code{tar} will
  automatically remove the leading @samp{/} from the file names it
! stores in the archive.  (On MS-DOS/MS-Windows, @code{tar} also removes
! the drive specification @file{d:/}.)  It will also type a warning
! message telling you that it is doing so.
  
  When reading an archive that was created with a different @code{tar}
  program, GNU @code{tar} automatically extracts entries in the archive
  which have absolute file names as if the file names were not absolute.
  
  For example, if the archive contained a file @file{/usr/bin/computoy},
  GNU @code{tar} would extract the file to @file{usr/bin/computoy},
*************** relative to the current directory.  If y
*** 7658,7667 ****
  an archive to the same absolute names that they had when the archive
  was created, you should do a @samp{cd /} before extracting the files
  from the archive, or you should either use the @value{op-absolute-names}
! option, or use the command @samp{tar -C / @dots{}}.
  
  @cindex Ultrix 3.1 and write failure
! Some versions of Unix (Ultrix 3.1 is know to have this problem),
  can claim that a short write near the end of a tape succeeded,
  when it actually failed.  This will result in the -M option not
  working correctly.  The best workaround at the moment is to use a
--- 7923,7941 ----
  an archive to the same absolute names that they had when the archive
  was created, you should do a @samp{cd /} before extracting the files
  from the archive, or you should either use the @value{op-absolute-names}
! option, or use the command @samp{tar -C / @dots{}}.  (On MS-DOS, include
! the drive specification in the @samp{-C} option, or change the current
! drive before the @samp{cd} command.)
! 
! This is an important feature.  A visitor here once gave a
! @code{tar} tape to an operator to restore; the operator used Sun @code{tar}
! instead of GNU @code{tar}, and the result was that it replaced large
! portions of our @file{/bin} and friends with versions from the tape;
! needless to say, we were unhappy about having to recover the file system
! from backup tapes.
  
  @cindex Ultrix 3.1 and write failure
! Some versions of Unix (Ultrix 3.1 is known to have this problem),
  can claim that a short write near the end of a tape succeeded,
  when it actually failed.  This will result in the -M option not
  working correctly.  The best workaround at the moment is to use a
*************** to a device, after which reading or writ
*** 7752,7766 ****
  being lost.  In this manual, the term @dfn{block} usually refers to
  a disk physical block, @emph{assuming} that each disk block is 512
  bytes in length.  It is true that some disk devices have different
! physical blocks, but @code{tar} ignore these differences in its own
  format, which is meant to be portable, so a @code{tar} block is always
! 512 bytes in length, and @dfn{block} always mean a @code{tar} block.
  The term @dfn{logical block} often represents the basic chunk of
  allocation of many disk blocks as a single entity, which the operating
  system treats somewhat atomically; this concept is only barely used
  in GNU @code{tar}.
  
! The term @dfn{physical record} is another way to speak of a physical
  block, those two terms are somewhat interchangeable.  In this manual,
  the term @dfn{record} usually refers to a tape physical block,
  @emph{assuming} that the @code{tar} archive is kept on magnetic tape.
--- 8026,8040 ----
  being lost.  In this manual, the term @dfn{block} usually refers to
  a disk physical block, @emph{assuming} that each disk block is 512
  bytes in length.  It is true that some disk devices have different
! physical blocks, but @code{tar} ignores these differences in its own
  format, which is meant to be portable, so a @code{tar} block is always
! 512 bytes in length, and @dfn{block} always means a @code{tar} block.
  The term @dfn{logical block} often represents the basic chunk of
  allocation of many disk blocks as a single entity, which the operating
  system treats somewhat atomically; this concept is only barely used
  in GNU @code{tar}.
  
! The term @dfn{physical record} is another way of speaking about a physical
  block, those two terms are somewhat interchangeable.  In this manual,
  the term @dfn{record} usually refers to a tape physical block,
  @emph{assuming} that the @code{tar} archive is kept on magnetic tape.
*************** it would normally.  To extract files fro
*** 7923,7929 ****
  blocking factor (particularly if you're not sure what the blocking factor
  is), you can usually use the @value{op-read-full-records} option while
  specifying a blocking factor larger then the blocking factor of the archive
! (ie. @samp{tar --extract --read-full-records --blocking-factor=300}.
  @xref{list}, for more information on the @value{op-list}
  operation.  @xref{Reading}, for a more detailed explanation of that option.
  
--- 8197,8203 ----
  blocking factor (particularly if you're not sure what the blocking factor
  is), you can usually use the @value{op-read-full-records} option while
  specifying a blocking factor larger then the blocking factor of the archive
! (ie. @samp{tar --extract --read-full-records --blocking-factor=300}).
  @xref{list}, for more information on the @value{op-list}
  operation.  @xref{Reading}, for a more detailed explanation of that option.
  
*************** with no information on it, used for dece
*** 8081,8087 ****
  full stop, and for later regaining the reading or writing speed.
  When the tape driver starts reading a record, the record has to
  be read whole without stopping, as a tape gap is needed to stop the
! tape motion without loosing information.
  
  @cindex Exabyte blocking
  @cindex DAT blocking
--- 8355,8361 ----
  full stop, and for later regaining the reading or writing speed.
  When the tape driver starts reading a record, the record has to
  be read whole without stopping, as a tape gap is needed to stop the
! tape motion without losing information.
  
  @cindex Exabyte blocking
  @cindex DAT blocking
*************** low, nor it should be too high.  @code{t
*** 8096,8105 ****
  writing to disk.  Current tape technology would easily accomodate higher
  blockings.  Sun recommends a blocking of 126 for Exabytes and 96 for DATs.
  We were told that for some DLT drives, the blocking should be a multiple
! of 4Kb, preferably 64Kb (@w{@kbd{-b 128}}) or 256 for decent performance.
  Other manufacturers may use different recommendations for the same tapes.
! This might also depends of the buffering techniques used inside modern
! tape controllers.  Some imposes a minimum blocking, or a maximum blocking.
  Others request blocking to be some exponent of two.
  
  So, there is no fixed rule for blocking.  But blocking at read time
--- 8370,8379 ----
  writing to disk.  Current tape technology would easily accomodate higher
  blockings.  Sun recommends a blocking of 126 for Exabytes and 96 for DATs.
  We were told that for some DLT drives, the blocking should be a multiple
! of 4Kb, preferably 64Kb (@w{@kbd{-b 128}} or @kbd{256}) for decent performance.
  Other manufacturers may use different recommendations for the same tapes.
! This might also depend of the buffering techniques used inside modern
! tape controllers.  Some impose a minimum blocking, or a maximum blocking.
  Others request blocking to be some exponent of two.
  
  So, there is no fixed rule for blocking.  But blocking at read time
*************** end of the tape, and this destroyed info
*** 8159,8165 ****
  recovered.
  
  To save @var{directory-1} as a first archive at the beginning of a
! tape, and leave that tape ready for a second archive, you should use:
  
  @example
  $ @kbd{mt -f /dev/nrtape rewind}
--- 8433,8440 ----
  recovered.
  
  To save @var{directory-1} as a first archive at the beginning of a
! tape, and leave that tape ready for a second archive, you should use the
! @emph{non-rewinding} tape device:
  
  @example
  $ @kbd{mt -f /dev/nrtape rewind}
*************** $ @kbd{tar cf /dev/nrtape @var{directory
*** 8171,8177 ****
  media, which are later recognizable by the reading hardware.  These
  marks are used after each file, when there are many on a single tape.
  An empty file (that is to say, two tape marks in a row) signal the
! logical end of the tape, after which no file exist.  Usually,
  non-rewinding tape device drivers will react to the close request issued
  by @code{tar} by first writing two tape marks after your archive, and by
  backspacing over one of these.  So, if you remove the tape at that time
--- 8446,8452 ----
  media, which are later recognizable by the reading hardware.  These
  marks are used after each file, when there are many on a single tape.
  An empty file (that is to say, two tape marks in a row) signal the
! logical end of the tape, after which no files exist.  Usually,
  non-rewinding tape device drivers will react to the close request issued
  by @code{tar} by first writing two tape marks after your archive, and by
  backspacing over one of these.  So, if you remove the tape at that time
*************** another file at the current position, th
*** 8180,8186 ****
  erased by the new information, leaving only one tape mark between files.
  
  So, you may now save @var{directory-2} as a second archive after the
! first on the same tape by issuing the command:
  
  @example
  $ @kbd{tar cf /dev/nrtape @var{directory-2}}
--- 8455,8461 ----
  erased by the new information, leaving only one tape mark between files.
  
  So, you may now save @var{directory-2} as a second archive after the
! first on the same non-rewinding tape by issuing the command:
  
  @example
  $ @kbd{tar cf /dev/nrtape @var{directory-2}}
*************** data on the tape will be overwritten (un
*** 8240,8246 ****
  Before reading an archive, you should make sure the tape head is at
  the beginning of the archive you want to read.  (The @code{restore}
  script will find the archive automatically.  @FIXME{There is no such
! restore script!}.  @FIXME-xref{Scripted Restoration}).  @xref{mt}, for
  an explanation of the tape moving utility.
  
  If you want to add new archive file entries to a tape, you should
--- 8515,8521 ----
  Before reading an archive, you should make sure the tape head is at
  the beginning of the archive you want to read.  (The @code{restore}
  script will find the archive automatically.  @FIXME{There is no such
! restore script!}  @FIXME-xref{Scripted Restoration}.)  @xref{mt}, for
  an explanation of the tape moving utility.
  
  If you want to add new archive file entries to a tape, you should
*************** Prints status information about the tape
*** 8306,8312 ****
  @FIXME{Is there a better way to frob the spacing on the list?}
  
  If you don't specify a @var{tapename}, @code{mt} uses the environment
! variable TAPE; if TAPE does not exist, @code{mt} uses the device
  @file{/dev/rmt12}.
  
  @code{mt} returns a 0 exit status when the operation(s) were
--- 8581,8587 ----
  @FIXME{Is there a better way to frob the spacing on the list?}
  
  If you don't specify a @var{tapename}, @code{mt} uses the environment
! variable @code{TAPE}; if @code{TAPE} is not defined, @code{mt} uses the device
  @file{/dev/rmt12}.
  
  @code{mt} returns a 0 exit status when the operation(s) were
*************** If you use @value{op-extract} with the @
*** 8320,8326 ****
  on it) and print an error if the archive label doesn't match the
  @var{archive-name} specified.  @var{archive-name} can be any regular
  expression.  If the labels match, @code{tar} extracts the archive.
! @value{xref-label}.  @FIXME-xref{Matching Format Parameters}.
  @FIXME{fix cross references} @samp{tar --list --label} will cause
  @code{tar} to print the label.
  
--- 8595,8601 ----
  on it) and print an error if the archive label doesn't match the
  @var{archive-name} specified.  @var{archive-name} can be any regular
  expression.  If the labels match, @code{tar} extracts the archive.
! @value{xref-label}.  @FIXME-xref{Matching Format Parameters}
  @FIXME{fix cross references} @samp{tar --list --label} will cause
  @code{tar} to print the label.
  
*************** Request @code{tar} to run a subshell.
*** 8365,8371 ****
  Request @code{tar} to begin writing the next volume.
  @end table
  
! (You should only type @samp{y} after you have changed the tape;
  otherwise @code{tar} will write over the volume it just finished.)
  
  If you want more elaborate behavior than this, give @code{tar} the
--- 8640,8646 ----
  Request @code{tar} to begin writing the next volume.
  @end table
  
! (You should type @samp{y} only @strong{after} you have changed the tape;
  otherwise @code{tar} will write over the volume it just finished.)
  
  If you want more elaborate behavior than this, give @code{tar} the
*************** floppy disk, you should change disks; et
*** 8455,8461 ****
  You can read each individual volume of a multi-volume archive as if it
  were an archive by itself.  For example, to list the contents of one
  volume, use @value{op-list}, without @value{op-multi-volume} specified.
! To extract an archive member from one volume (assuming it is described
  that volume), use @value{op-extract}, again without
  @value{op-multi-volume}.
  
--- 8730,8736 ----
  You can read each individual volume of a multi-volume archive as if it
  were an archive by itself.  For example, to list the contents of one
  volume, use @value{op-list}, without @value{op-multi-volume} specified.
! To extract an archive member from one volume (assuming it is on
  that volume), use @value{op-extract}, again without
  @value{op-multi-volume}.
  
*************** which will be displayed when the archive
*** 8528,8534 ****
  If you are creating a multi-volume archive with @value{op-multi-volume}
  (@FIXME-pxref{Using Multiple Tapes}), then the volume label will have
  @samp{Volume @var{nnn}} appended to the name you give, where @var{nnn} is
! the number of the volume of the archive.  (If you use the @value{op-label}
  option when reading an archive, it checks to make sure the label on the
  tape matches the one you give.  @value{xref-label}.
  
--- 8803,8809 ----
  If you are creating a multi-volume archive with @value{op-multi-volume}
  (@FIXME-pxref{Using Multiple Tapes}), then the volume label will have
  @samp{Volume @var{nnn}} appended to the name you give, where @var{nnn} is
! the number of the volume of the archive.  If you use the @value{op-label}
  option when reading an archive, it checks to make sure the label on the
  tape matches the one you give.  @value{xref-label}.
  
*************** of tapes into a sequence of tape files, 
*** 8543,8549 ****
  People seem to often do:
  
  @example
! @kbd{--label="@var{some-prefix} `date +@var{some-format}`"}
  @end example
  
  or such, for pushing a common date in all volumes or an archive set.
--- 8818,8824 ----
  People seem to often do:
  
  @example
! @kbd{tar --label="@var{some-prefix} `date +@var{some-format}`"}
  @end example
  
  or such, for pushing a common date in all volumes or an archive set.
*************** If you create an archive using both @val
*** 8578,8584 ****
  @value{op-multi-volume}, each volume of the archive will have an
  archive label of the form @samp{@var{archive-label} Volume @var{n}},
  where @var{n} is 1 for the first volume, 2 for the next, and so on.
! @FIXME-xref{Multi-Volume Archives}, for information on creating multiple
  volume archives.
  
  If you list or extract an archive using @value{op-label}, @code{tar} will
--- 8853,8859 ----
  @value{op-multi-volume}, each volume of the archive will have an
  archive label of the form @samp{@var{archive-label} Volume @var{n}},
  where @var{n} is 1 for the first volume, 2 for the next, and so on.
! @xref{Multi-Volume Archives}, for information on creating multiple
  volume archives.
  
  If you list or extract an archive using @value{op-label}, @code{tar} will
*************** Includes an @dfn{archive-label} at the b
*** 8617,8623 ****
  the archive is being created, when used in conjunction with the
  @value{op-create} option.  Checks to make sure the archive label
  matches the one specified (when used in conjunction with the
! @value{op-extract} option.
  @end table
  
  To get a common information on all tapes of a series, use the
--- 8892,8898 ----
  the archive is being created, when used in conjunction with the
  @value{op-create} option.  Checks to make sure the archive label
  matches the one specified (when used in conjunction with the
! @value{op-extract} option).
  @end table
  
  To get a common information on all tapes of a series, use the
*************** manage to get some date string as part o
*** 8628,8634 ****
  @example
  $ @kbd{tar cfMV /dev/tape "Daily backup for `date +%Y-%m-%d`"}
  $ @kbd{tar --create --file=/dev/tape --multi-volume \
!      --volume="Daily backup for `date +%Y-%m-%d`"}
  @end example
  
  Also note that each label has its own date and time, which corresponds
--- 8903,8909 ----
  @example
  $ @kbd{tar cfMV /dev/tape "Daily backup for `date +%Y-%m-%d`"}
  $ @kbd{tar --create --file=/dev/tape --multi-volume \
!      --label="Daily backup for `date +%Y-%m-%d`"}
  @end example
  
  Also note that each label has its own date and time, which corresponds
*************** by using the @value{op-compare} option, 
*** 8684,8690 ****
  @value{op-verify} option.  @value{xref-compare}.
  
  Note that these two options have a slightly different intent.  The
! @value{op-compare} option how identical are the logical contents of some
  archive with what is on your disks, while the @value{op-verify} option is
  really for checking if the physical contents agree and if the recording
  media itself is of dependable quality.  So, for the @value{op-verify}
--- 8959,8965 ----
  @value{op-verify} option.  @value{xref-compare}.
  
  Note that these two options have a slightly different intent.  The
! @value{op-compare} option checks how identical are the logical contents of some
  archive with what is on your disks, while the @value{op-verify} option is
  really for checking if the physical contents agree and if the recording
  media itself is of dependable quality.  So, for the @value{op-verify}
diff -cp -r test/tar-1.12/doc/version.texi tar-1.12/doc/version.texi
*** test/tar-1.12/doc/version.texi	Fri Apr 25 20:05:30 1997
--- tar-1.12/doc/version.texi	Fri Oct 10 14:08:26 1997
***************
*** 1,3 ****
! @set UPDATED 24 April 1997
  @set EDITION 1.12
  @set VERSION 1.12
--- 1,3 ----
! @set UPDATED 10 October 1996
  @set EDITION 1.12
  @set VERSION 1.12
diff -cp -r test/tar-1.12/lib/backupfile.c tar-1.12/lib/backupfile.c
*** test/tar-1.12/lib/backupfile.c	Thu Apr 17 01:17:42 1997
--- tar-1.12/lib/backupfile.c	Sat Oct 11 14:51:44 1997
*************** enum backup_type backup_type = none;
*** 94,99 ****
--- 94,107 ----
     to numbered) backup file name.  */
  char *simple_backup_suffix = "~";
  
+ #ifdef MSDOS
+ /* Support long file names when available (Windows 9X).  */
+ # ifdef __DJGPP__
+ #  include <fcntl.h>
+ # endif
+ static int lfn = 0;
+ #endif
+ 
  static char *concat ();
  char *find_backup_file_name ();
  static char *make_version_name ();
*************** find_backup_file_name (file)
*** 115,129 ****
    char *base_versions;
    int highest_backup;
  
    if (backup_type == simple)
      return concat (file, simple_backup_suffix);
  
!   copy = malloc (strlen (file) + 1);
    if (copy == 0)
      return 0;
    strcpy (copy, file);
  
    base = strrchr (copy, '/');
    if (base == 0)
      {
        base = copy;
--- 123,159 ----
    char *base_versions;
    int highest_backup;
  
+ #ifdef __DJGPP__
+   /* Support long file names when FILE resides on a filesystem
+      which makes them available.  */
+   lfn = _use_lfn (file);
+ #endif
+ 
    if (backup_type == simple)
      return concat (file, simple_backup_suffix);
  
!   copy = malloc (strlen (file) + 2);
    if (copy == 0)
      return 0;
    strcpy (copy, file);
  
    base = strrchr (copy, '/');
+ 
+   /* Make sure DIR is not empty for root directories.  */
+   if (base == copy
+ #if MSDOS
+       /* "d:" and "d:/" are NOT the same.  */
+       || (base == copy + 2 && base[-1] == ':')
+       /* "d:foo" is NOT relative to ".".  */
+       || (base == 0 && copy[1] == ':' && (base = copy + 1))
+ #endif
+       )
+     {
+       /* Leave the trailing slash alone, make a room for a NULL
+ 	 character after the slash.  */
+       strcpy (base + 2, file + (base - copy) + 1);
+       base++;
+     }
    if (base == 0)
      {
        base = copy;
*************** max_backup_version (file, dir)
*** 177,183 ****
  
    while ((dp = readdir (dirp)) != 0)
      {
!       if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
  	continue;
  
        this_version = version_number (file, dp->d_name, file_name_length);
--- 207,220 ----
  
    while ((dp = readdir (dirp)) != 0)
      {
!       if (!REAL_DIR_ENTRY (dp)
! #if !defined(MSDOS) || defined(__DJGPP__)
! 	  /* When long file names aren't supported, examine all files.  */
! 	  || (NLENGTH (dp) <= file_name_length
! 	  && lfn
! 	      )
! #endif
! 	  )
  	continue;
  
        this_version = version_number (file, dp->d_name, file_name_length);
*************** make_version_name (file, version)
*** 203,208 ****
--- 240,260 ----
    if (backup_name == 0)
      return 0;
    sprintf (backup_name, "%s.~%d~", file, version);
+ #ifdef MSDOS
+   /* If long filenames aren't supported on the filesystem where
+      FILE belongs, squeeze the backup suffix into 8+3 namespace.  */
+   if (!lfn)
+     {
+       char *short_name;
+ 
+       /* Let `concat' do the hard job (see below) when we
+ 	 cannot use long filenames.  */
+       sprintf (backup_name, ".~%d~", version);
+       short_name = concat (file, backup_name);
+       free (backup_name);
+       backup_name = short_name;
+     }
+ #endif
    return backup_name;
  }
  
*************** version_number (base, backup, base_lengt
*** 220,225 ****
--- 272,303 ----
    const char *p;
  
    version = 0;
+ #ifdef MSDOS
+   if (!lfn)
+     {
+       /* When long filenames aren't supported, the numbered backup
+ 	 suffix moves into the name; see `concat'.  We want filenames
+ 	 like e.g. "foo.bar" and "foo1234~" to match here.
+ 	 The call to `strncmp' is of course superflous after this,
+ 	 but letting the non-LFN systems suffer leaves the code cleaner.  */
+       const char *pbase = base, *pbackup = backup;
+       int len;
+ 
+       for (len = base_length; len; len--)
+ 	if (*pbase++ != *pbackup++)
+ 	  {
+ 	    base_length -= len;
+ 	    break;
+ 	  }
+       /* Avoid lossage when BASE is already a numbered backup.  */
+       if (!len && pbase > base + 2 && pbase[-1] == '~' && ISDIGIT (pbase[-2]))
+ 	{
+ 	  base_length--;
+ 	  for (pbase = pbase - 2; pbase >= base && ISDIGIT (*pbase); pbase--)
+ 	    base_length--;
+ 	}
+     }
+ #endif
    if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
      {
        for (p = &backup[base_length]; ISDIGIT (*p); ++p)
*************** concat (str1, str2)
*** 246,250 ****
--- 324,430 ----
      return 0;
    strcpy (newstr, str1);
    strcpy (newstr + str1_length, str2);
+ #ifdef MSDOS
+   if (!lfn)
+     {
+       /* Without long filenames, we have to live with the darn 8+3
+ 	 basename restriction.  The only way to have numbered
+ 	 backups in that case is to eat some characters off the end
+ 	 of the original name.  */
+       extern char *basename (const char *);
+       char *base = basename (newstr);
+       int baselen = strlen (base);
+       char *dot;
+       char *str2_start = newstr + str1_length;
+       int s2_len = strlen (str2_start);
+       int extlen;
+       int str2_starts_with_dot;
+ 
+       /* Kludgy feature: if `STR1' already has an extension, and
+ 	 `STR2' begins with ".~", we remove the `~'.  This is so
+ 	 we could salvage at least 1 character of the original
+ 	 extension for the first 9 backups (e.g., "foo.c" + ".~7~"
+ 	 is ``concatenated'' into "foo.c7~", not "foo.~7~").  */
+       if (memchr (base, '.', baselen - s2_len)
+ 	  && (*str2_start == '.' && str2_start[1] == '~'))
+ 	{
+ 	  memmove (str2_start + 1, str2_start + 2, s2_len - 1);
+ 	  s2_len--;
+ 	  baselen--;
+ 	}
+ 
+       /* Weed out all but the first dot in `base'.  */
+       dot = memchr (base, '.', baselen);
+       if (dot)
+ 	{
+ 	  char *s = dot + 1;
+ 	  char *d = s;
+ 	  int dots_before_str2 = 0;
+ 
+ 	  do {
+ 	    while (*s == '.')
+ 	      {
+ 		if (s < str2_start)
+ 		  dots_before_str2++;
+ 		else
+ 		  s2_len--;
+ 		s++;
+ 		baselen--;
+ 	      }
+ 	  } while ((*d++ = *s++));
+ 
+ 	  str2_start -= dots_before_str2;
+ 	  extlen = baselen - (dot - base) - 1; /* 1 for the dot itself */
+ 	}
+       else
+ 	{
+ 	  dot = base + baselen;
+ 	  extlen = 0;
+ 	}
+ 
+       /* Make sure `STR2' will not be truncated by the OS.  If `STR2' is
+ 	 in the extension, it must be in the first 3 characters after the
+ 	 dot; if it's before the dot, it must be one of the first 8
+ 	 characters of the basename.  */
+       str2_starts_with_dot = str2_start[0] == '.';
+       if (extlen > 3)
+ 	{
+ 	  char *new_str2_start;
+ 
+ 	  s2_len = strlen (str2_start);
+ 	  if (s2_len <= 3 + str2_starts_with_dot)
+ 	    new_str2_start = dot + !str2_starts_with_dot + 3 - s2_len;
+ 	  else
+ 	    {
+ 	      new_str2_start = dot;
+ 	      if (str2_start == new_str2_start)
+ 		{
+ 		  /* The case of foo -> foo.~10~
+ 		     The original file has no extension, but the backup
+ 		     extension is longer than 3 characters.  We need to
+ 		     move the extension into the name (make it foo10~).  */
+ 		  if (*++str2_start == '~')
+ 		    str2_start++;
+ 		  s2_len -= str2_start - dot;
+ 		}
+ 	      dot += s2_len;
+ 	    }
+ 	  memmove (new_str2_start, str2_start, s2_len + 1);
+ 	  str2_start = new_str2_start;
+ 	}
+       /* If the name part (before the dot) is longer than 8 characters,
+ 	 we cannot be sure it won't clash with an existing file.  So we
+ 	 must move `STR2' into the name.  */
+       if (dot - base > 8)
+ 	{
+ 	  if (str2_starts_with_dot)
+ 	    {
+ 	      str2_start++;
+ 	      s2_len--;
+ 	    }
+ 	  memmove (base + 8 - s2_len, str2_start, s2_len + 1);
+ 	}
+     }
+ #endif /* MSDOS */
    return newstr;
  }
diff -cp -r test/tar-1.12/lib/dirname.c tar-1.12/lib/dirname.c
*** test/tar-1.12/lib/dirname.c	Thu Apr 17 01:27:00 1997
--- tar-1.12/lib/dirname.c	Thu Oct  2 22:28:50 1997
*************** dirname (path)
*** 57,64 ****
--- 57,73 ----
    else
      {
        /* Remove any trailing slashes from the result.  */
+ #ifdef MSDOS
+       char *lim = (path[0] >= 'A' && path[0] <= 'z' && path[1] == ':')
+ 		  ? path + 2 : path;
+ 
+       /* If canonicalized "d:/path", leave alone the root case "d:/".  */
+       while (slash > lim && *slash == '/')
+ 	--slash;
+ #else
        while (slash > path && *slash == '/')
  	--slash;
+ #endif
  
        length = slash - path + 1;
      }
diff -cp -r test/tar-1.12/lib/fileblocks.c tar-1.12/lib/fileblocks.c
*** test/tar-1.12/lib/fileblocks.c	Mon Jul 15 03:35:12 1996
--- tar-1.12/lib/fileblocks.c	Sat Aug  9 07:02:12 1997
***************
*** 31,36 ****
--- 31,39 ----
  #  ifndef BSIZE
  #   define BSIZE 1024
  #  endif
+ #if defined (__DJGPP__)
+ typedef long daddr_t; /* for disk address */
+ #endif
  
  /* Number of inode pointers per indirect block. */
  #  define NINDIR (BSIZE/sizeof(daddr_t))
diff -cp -r test/tar-1.12/src/buffer.c tar-1.12/src/buffer.c
*** test/tar-1.12/src/buffer.c	Fri Apr 25 13:48:46 1997
--- tar-1.12/src/buffer.c	Fri Oct 10 18:42:22 1997
*************** static int new_volume PARAMS ((enum acce
*** 77,83 ****
  static void write_error PARAMS ((int));
  static void read_error PARAMS ((void));
  
! #if !MSDOS
  /* Obnoxious test to see if dimwit is trying to dump the archive.  */
  dev_t ar_dev;
  ino_t ar_ino;
--- 77,83 ----
  static void write_error PARAMS ((int));
  static void read_error PARAMS ((void));
  
! #if !MSDOS || defined (__DJGPP__)
  /* Obnoxious test to see if dimwit is trying to dump the archive.  */
  dev_t ar_dev;
  ino_t ar_ino;
*************** available_space_after (union block *poin
*** 244,279 ****
    return (int) (record_end->buffer - pointer->buffer);
  }
  
! /*------------------------------------------------------------------.
! | Close file having descriptor FD, and abort if close unsucessful.  |
! `------------------------------------------------------------------*/
  
! static void
! xclose (int fd)
  {
!   if (close (fd) < 0)
!     FATAL_ERROR ((0, errno, _("Cannot close file #%d"), fd));
! }
  
! /*-----------------------------------------------------------------------.
! | Duplicate file descriptor FROM into becoming INTO, or else, issue	 |
! | MESSAGE.  INTO is closed first and has to be the next available slot.	 |
! `-----------------------------------------------------------------------*/
  
! static void
! xdup2 (int from, int into, const char *message)
! {
!   if (from != into)
!     {
!       int status = close (into);
  
!       if (status < 0 && errno != EBADF)
! 	FATAL_ERROR ((0, errno, _("Cannot close descriptor %d"), into));
!       status = dup (from);
!       if (status != into)
! 	FATAL_ERROR ((0, errno, _("Cannot properly duplicate %s"), message));
!       xclose (from);
!     }
  }
  
  #if MSDOS
--- 244,266 ----
    return (int) (record_end->buffer - pointer->buffer);
  }
  
! /*---------------------------------------------------------------------.
! | Return nonzero if NAME is the name of a regular file, or if the file |
! | does not exist (so it would be created as a regular file).	       |
! `---------------------------------------------------------------------*/
  
! static int
! is_regular_file (const char *name)
  {
!   struct stat stbuf;
  
!   if (stat (name, &stbuf) < 0)
!     return 1;
  
!   if (S_ISREG (stbuf.st_mode))
!     return 1;
  
!   return 0;
  }
  
  #if MSDOS
*************** xdup2 (int from, int into, const char *m
*** 282,291 ****
  | Set ARCHIVE for writing, then compressing an archive.	 |
  `-------------------------------------------------------*/
  
  static void
  child_open_for_compress (void)
  {
!   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  }
  
  /*---------------------------------------------------------.
--- 269,324 ----
  | Set ARCHIVE for writing, then compressing an archive.	 |
  `-------------------------------------------------------*/
  
+ /* FIXME: A single pipe object is enough only as long as
+    GNU tar doesn't support updating compressed archives.  */
+ static struct {
+   FILE * pipe;
+   char * tfile;
+ } dos_pipe = { (FILE *)0, (char *)0 };
+ 
  static void
  child_open_for_compress (void)
  {
!   /* Use `popen' to simulate a pipe.  */
!   char pipe_cmd[PATH_MAX*5];
!   int to_stdout = strcmp (archive_name_array[0], "-") == 0;
!   
!   /* I think on MSDOS we only need special handling for remote files.  */
!   if (!_remdev (archive_name_array[0]))
!     {
!       if (backup_option)
! 	maybe_backup_file (archive_name_array[0], 1);
! 
!       sprintf (pipe_cmd, "%s%s%s",
! 	       use_compress_program_option,
! 	       to_stdout ? "" : " > ",
! 	       to_stdout ? "" : archive_name_array[0]);
!       dos_pipe.tfile = (char *)0;
!     }
!   else	/* In case somebody will make rtapelib.c work some day...  */
!     {
!       /*  We cannot write to a pipe and read from its other end at
! 	  the same time.  So we need a temporary file in-between.  */
!       char *tem_file = (char *)xmalloc (L_tmpnam);
! 
!       tmpnam (tem_file);
!       sprintf (pipe_cmd, "%s > %s", use_compress_program_option, tem_file);
!       dos_pipe.tfile = tem_file;
!     }
! 
!   /* Open the pipe to the compressor.  */
!   dos_pipe.pipe = popen (pipe_cmd, "wb");
!   if (!dos_pipe.pipe)
!     {
!       int saved_errno = errno;
! 
!       if (backup_option)
! 	undo_last_backup ();
!       dos_pipe.tfile = (char *)0;
!       FATAL_ERROR ((0, saved_errno, _("Cannot open pipe")));
!     }
! 
!   archive = fileno (dos_pipe.pipe);
  }
  
  /*---------------------------------------------------------.
*************** child_open_for_compress (void)
*** 295,322 ****
  static void
  child_open_for_uncompress (void)
  {
!   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  }
  
  #else /* not MSDOS */
  
! /*---------------------------------------------------------------------.
! | Return nonzero if NAME is the name of a regular file, or if the file |
! | does not exist (so it would be created as a regular file).	       |
! `---------------------------------------------------------------------*/
  
! static int
! is_regular_file (const char *name)
  {
!   struct stat stbuf;
  
!   if (stat (name, &stbuf) < 0)
!     return 1;
  
!   if (S_ISREG (stbuf.st_mode))
!     return 1;
  
!   return 0;
  }
  
  /*-------------------------------------------------------.
--- 328,461 ----
  static void
  child_open_for_uncompress (void)
  {
!   /* Use `popen' to simulate a pipe.  */
!   char pipe_cmd[PATH_MAX*5];
!   int from_stdout = strcmp (archive_name_array[0], "-") == 0;
!   
!   /* I think on MSDOS we only need special handling for remote files.  */
!   if (!_remdev (archive_name_array[0]))
!     {
!       /* We don't need a grandchild tar.  */
!       sprintf (pipe_cmd, "%s -d%s%s",
! 	       use_compress_program_option,
! 	       from_stdout ? "" : " < ",
! 	       from_stdout ? "" : archive_name_array[0]);
!       dos_pipe.tfile = 0;
!     }
!   else	/* In case somebody will make rtapelib.c work some day...  */
!     {
!       char *tem_file = (char *)xmalloc (L_tmpnam);
!       int   remote_archive, tem_fd;
! 
!       /* Since we cannot write to a pipe and read its other end, we
! 	 need first to copy the remote archive to a local temporary file.  */
!       remote_archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
! 				0666, rsh_command_option);
!       if (remote_archive < 0)
! 	FATAL_ERROR ((0, errno, _("Cannot open archive %s"),
! 		      archive_name_array[0]));
! 
!       tmpnam (tem_file);
!       tem_fd = open (tem_file, O_RDONLY | O_BINARY | O_CREAT | O_EXCL, 0666);
!       if (tem_fd < 0)
! 	FATAL_ERROR ((0, errno, _("Cannot open pipe")));
! 
!       /* Let's read the archive and pipe it into temporary file.  */
! 
!       while (1)
! 	{
! 	  char *cursor;
! 	  int maximum;
! 	  int count;
! 	  int status;
! 
! 	  read_error_count = 0;
! 
! 	error_loop:
! 	  status = rmtread (remote_archive, record_start->buffer,
! 			    (unsigned int) (record_size));
! 	  if (status < 0)
! 	    {
! 	      read_error ();
! 	      goto error_loop;
! 	    }
! 	  if (status == 0)
! 	    break;
! 	  cursor = record_start->buffer;
! 	  maximum = status;
! 	  while (maximum)
! 	    {
! 	      count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
! 	      status = write (tem_fd, cursor, (size_t) count);
! 	      if (status < 0)
! 		FATAL_ERROR ((0, errno, _("\
! Cannot write to compression program")));
! 
! 	      if (status != count)
! 		{
! 		  ERROR ((0, 0, _("\
! Write to compression program short %d bytes"),
! 			  count - status));
! 		  count = status;
! 		}
! 
! 	      cursor += count;
! 	      maximum -= count;
! 	    }
! 	}
! 
!       close (tem_fd);
!       sprintf (pipe_cmd, "%s -d < %s", use_compress_program_option, tem_file);
!       dos_pipe.tfile = tem_file;
!     }
! 
!   /* Open the pipe to the decompressor.  */
!   dos_pipe.pipe = popen (pipe_cmd, "rb");
!   if (!dos_pipe.pipe)
!     {
!       int saved_errno = errno;
! 
!       if (backup_option)
! 	undo_last_backup ();
!       dos_pipe.tfile = (char *)0;
!       FATAL_ERROR ((0, saved_errno, _("Cannot open pipe")));
!     }
! 
!   archive = fileno (dos_pipe.pipe);
  }
  
  #else /* not MSDOS */
  
! /*------------------------------------------------------------------.
! | Close file having descriptor FD, and abort if close unsucessful.  |
! `------------------------------------------------------------------*/
  
! static void
! xclose (int fd)
  {
!   if (close (fd) < 0)
!     FATAL_ERROR ((0, errno, _("Cannot close file #%d"), fd));
! }
  
! /*-----------------------------------------------------------------------.
! | Duplicate file descriptor FROM into becoming INTO, or else, issue	 |
! | MESSAGE.  INTO is closed first and has to be the next available slot.	 |
! `-----------------------------------------------------------------------*/
  
! static void
! xdup2 (int from, int into, const char *message)
! {
!   if (from != into)
!     {
!       int status = close (into);
  
!       if (status < 0 && errno != EBADF)
! 	FATAL_ERROR ((0, errno, _("Cannot close descriptor %d"), into));
!       status = dup (from);
!       if (status != into)
! 	FATAL_ERROR ((0, errno, _("Cannot properly duplicate %s"), message));
!       xclose (from);
!     }
  }
  
  /*-------------------------------------------------------.
*************** open_archive (enum access_mode access)
*** 798,815 ****
  		    archive_name_array[0]));
      }
  
! #if !MSDOS
  
!   fstat (archive, &archive_stat);
  
    /* Detect if outputting to "/dev/null".  */
!   {
!     struct stat dev_null_stat;
  
!     stat ("/dev/null", &dev_null_stat);
!     dev_null_output = (S_ISCHR (archive_stat.st_mode)
! 		       && archive_stat.st_rdev == dev_null_stat.st_rdev);
!   }
  
    if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
      {
--- 937,991 ----
  		    archive_name_array[0]));
      }
  
!   /* This is to guard against environments where there can be more
!      than 128 handles open at any given time.  `tar' currently
!      thinks that any handle above 128 belongs to a remote archive.  */
!   if (!_remdev (archive_name_array[0]) && _isrmt (archive))
!     {
!       int saved_errno = errno;
  
!       if (backed_up_flag)
! 	undo_last_backup ();
!       FATAL_ERROR ((0, saved_errno, _("Too many open files, cannot open %s"),
! 		    archive_name_array[0]));
!     }
! 
! #if !MSDOS || defined (__DJGPP__)
! 
! #ifdef __DJGPP__
!   /* When we are creating an archive, DOS won't assign it disk space
!      until we actually write something.  DJGPP uses the number of the
!      first disk block as the simulated inode number, wich will only work
!      if disk space is already allocated for this file.  Otherwise, the
!      ar_ino trick below (and in create.c) won't work.
! 
!      So we need to write something and fsync the handle, to get
!      meaningful ar_ino.  */
!   if (!isatty (archive) && access == ACCESS_WRITE && !_isrmt (archive))
!     {
!       write (archive, "xyzzy", 5);
!       fsync (archive);
!       lseek (archive, 0L, SEEK_SET); /* get back to the beginning */
!     }
! #endif /* __DJGPP__ */
  
    /* Detect if outputting to "/dev/null".  */
!   if (rmtfstat (archive, &archive_stat) == 0)
!     {
!       struct stat dev_null_stat;
  
!       stat ("/dev/null", &dev_null_stat);
! #ifdef __DJGPP__
!       /* DJGPP doesn't have st_rdev, and all its character devices
! 	 ``live'' on the same st_dev, so check st_ino also.  */
!       dev_null_output = (S_ISCHR (archive_stat.st_mode)
! 			 && archive_stat.st_dev == dev_null_stat.st_dev
! 			 && archive_stat.st_ino == dev_null_stat.st_ino);
! #else
!       dev_null_output = (S_ISCHR (archive_stat.st_mode)
! 			 && archive_stat.st_rdev == dev_null_stat.st_rdev);
! #endif
!     }
  
    if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
      {
*************** open_archive (enum access_mode access)
*** 820,826 ****
  #endif /* not MSDOS */
  
  #if MSDOS
!   setmode (archive, O_BINARY);
  #endif
  
    switch (access)
--- 996,1003 ----
  #endif /* not MSDOS */
  
  #if MSDOS
!   if (!isatty (archive))
!     setmode (archive, O_BINARY);
  #endif
  
    switch (access)
*************** flush_write (void)
*** 914,920 ****
  
  	  cursor = save_name;
  #if MSDOS
! 	  if (cursor[1] == ':')
  	    cursor += 2;
  #endif
  	  while (*cursor == '/')
--- 1091,1097 ----
  
  	  cursor = save_name;
  #if MSDOS
! 	  if (cursor[0] >= 'A' && cursor[0] <= 'z' && cursor[1] == ':')
  	    cursor += 2;
  #endif
  	  while (*cursor == '/')
*************** flush_write (void)
*** 1015,1021 ****
  	  char *cursor = save_name;
  
  #if MSDOS
! 	  if (cursor[1] == ':')
  	    cursor += 2;
  #endif
  	  while (*cursor == '/')
--- 1192,1198 ----
  	  char *cursor = save_name;
  
  #if MSDOS
! 	  if (cursor[0] >= 'A' && cursor[0] <= 'z' && cursor[1] == ':')
  	    cursor += 2;
  #endif
  	  while (*cursor == '/')
*************** flush_read (void)
*** 1105,1111 ****
  	char *cursor = save_name;
  
  #if MSDOS
! 	if (cursor[1] == ':')
  	  cursor += 2;
  #endif
  	while (*cursor == '/')
--- 1282,1288 ----
  	char *cursor = save_name;
  
  #if MSDOS
! 	if (cursor[0] >= 'A' && cursor[0] <= 'z' && cursor[1] == ':')
  	  cursor += 2;
  #endif
  	while (*cursor == '/')
*************** close_archive (void)
*** 1380,1393 ****
      while (rmtread (archive, record_start->buffer, (unsigned int) record_size)
  	   > 0)
        continue;
! #endif
  
    if (subcommand_option == DELETE_SUBCOMMAND)
      {
        off_t pos;
  
        pos = rmtlseek (archive, 0L, 1);
! #if MSDOS
        rmtwrite (archive, "", 0);
  #else
        ftruncate (archive, (size_t) pos);
--- 1557,1570 ----
      while (rmtread (archive, record_start->buffer, (unsigned int) record_size)
  	   > 0)
        continue;
! #endif /* !MSDOS */
  
    if (subcommand_option == DELETE_SUBCOMMAND)
      {
        off_t pos;
  
        pos = rmtlseek (archive, 0L, 1);
! #if MSDOS && !defined (__DJGPP__)
        rmtwrite (archive, "", 0);
  #else
        ftruncate (archive, (size_t) pos);
*************** close_archive (void)
*** 1396,1401 ****
--- 1573,1680 ----
    if (verify_option)
      verify_volume ();
  
+ #if MSDOS
+   if (dos_pipe.pipe)
+     {
+       int status = pclose (dos_pipe.pipe);
+ 
+       if (status == -1 || (status & 0xff) == 0xff)
+ 	FATAL_ERROR ((0, errno, _("Cannot exec %s"),
+ 		      use_compress_program_option));
+       else if (status)
+ 	ERROR ((0, 0, _("Child returned status %d"), (status & 0xff)));
+ 
+       if (dos_pipe.tfile && access_mode == ACCESS_WRITE)
+ 	{
+ 	  /* We need to copy the temporary file to the remote
+ 	     archive.  */
+ 
+ 	  int tem_fd = open (archive_name_array[0], O_RDONLY | O_BINARY, 0666);
+ 	  int remote_archive;
+ 
+ 	  if (tem_fd < 0)
+ 	    FATAL_ERROR ((0, errno, _("Cannot open archive %s"),
+ 			  archive_name_array[0]));
+ 
+ 	  remote_archive = rmtcreat (archive_name_array[0], 0666,
+ 				     rsh_command_option);
+ 	  if (remote_archive < 0)
+ 	    FATAL_ERROR ((0, errno, _("Cannot open archive %s"),
+ 			  archive_name_array[0]));
+ 
+ 	  while (1)
+ 	    {
+ 	      char *cursor;
+ 	      int length;
+ 
+ 	      status = 0;
+ 	      /* Assemble a record.  */
+ 
+ 	      for (length = 0, cursor = record_start->buffer;
+ 		   length < record_size;
+ 		   length += status, cursor += status)
+ 		{
+ 		  int size = record_size - length;
+ 
+ 		  if (size < BLOCKSIZE)
+ 		    size = BLOCKSIZE;
+ 		  status = read (tem_fd, cursor, (size_t) size);
+ 		  if (status <= 0)
+ 		    break;
+ 		}
+ 
+ 	      if (status < 0)
+ 		FATAL_ERROR ((0, errno, _("Cannot read from compression program")));
+ 
+ 	      /* Copy the record.  */
+ 
+ 	      if (status == 0)
+ 		{
+ 		  /* We hit the end of the file.  Write last record at
+ 		     full length, as the only role of the grandchild is
+ 		     doing proper reblocking.  */
+ 
+ 		  if (length > 0)
+ 		    {
+ 		      memset (record_start->buffer + length, 0,
+ 			      (size_t) record_size - length);
+ 		      status = rmtwrite (remote_archive, record_start->buffer,
+ 					 (unsigned int) record_size);
+ 		      if (status != record_size)
+ 			write_error (status);
+ 		    }
+ 
+ 		  /* There is nothing else to read, break out.  */
+ 		  break;
+ 		}
+ 
+ 	      status = rmtwrite (remote_archive, record_start->buffer,
+ 				 (unsigned int) record_size);
+ 	      if (status != record_size)
+ 		write_error (status);
+ 	    }
+ 	  close (tem_fd);
+ 	}
+ 
+       dos_pipe.pipe = (FILE *)0;
+       if (dos_pipe.tfile)
+ 	{
+ 	  remove (dos_pipe.tfile);
+ 	  free (dos_pipe.tfile);
+ 	  dos_pipe.tfile = (char *)0;
+ 	}
+ 
+       if (status < 0)
+ 	{
+ 	  if (access_mode == ACCESS_WRITE)
+ 	    FATAL_ERROR ((0, errno, _("Cannot write to compression program")));
+ 	  else
+ 	    FATAL_ERROR ((0, errno,
+ 			  _("Cannot read from compression program")));
+ 	}
+     }
+   else
+ #endif
    {
      int status = rmtclose (archive);
  
*************** new_volume (enum access_mode access)
*** 1513,1518 ****
--- 1792,1801 ----
    if (verify_option)
      verify_volume ();
  
+ #if MSDOS
+   /* Closing stdout or stdin is a bad idea.  */
+   if (archive != STDIN && archive != STDOUT)
+ #endif
    if (status = rmtclose (archive), status < 0)
      WARN ((0, errno, _("WARNING: Cannot close %s (%d, %d)"),
  	   *archive_name_cursor, archive, status));
*************** tryagain:
*** 1608,1614 ****
  
  	      case '!':
  #if MSDOS
! 		spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
  #else /* not MSDOS */
  		switch (fork ())
  		  {
--- 1891,1924 ----
  
  	      case '!':
  #if MSDOS
! 		{
! 		  int save_stdout = -1, save_stdin = -1;
! 
! 		  /* Exec'ing a child shell with standard steams
! 		     not connected to the terminal is a VERY bad idea.  */
! 		  if (!isatty (STDIN))
! 		    {
! 		      save_stdin = dup (STDIN);
! 		      freopen (TTY_NAME, "rt", stdin);
! 		    }
! 		  if (!isatty (STDOUT))
! 		    {
! 		      save_stdout = dup (STDOUT);
! 		      freopen (TTY_NAME, "wt", stdout);
! 		    }
! # ifdef __DJGPP__
! 		/* `system' is better, since it honors $SHELL.  */
! 		  if (system ("") == -1)
! 		    FATAL_ERROR ((0, errno, _("Cannot exec a shell %s"), ""));
! # else /* not __DJGPP__ */
! 		  spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
! # endif/* not __DJGPP__ */
! 		  /* Restore any redirected standard streams.  */
! 		  if (save_stdin >= 0)
! 		    dup2 (save_stdin, STDIN);
! 		  if (save_stdout >= 0)
! 		    dup2 (save_stdout, STDOUT);
! 		}
  #else /* not MSDOS */
  		switch (fork ())
  		  {
*************** tryagain:
*** 1649,1654 ****
--- 1959,1983 ----
      archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, 0666,
  		       rsh_command_option);
    else
+ #if MSDOS
+     if (strcmp (*archive_name_cursor, "-") == 0)
+       switch (access)
+ 	{
+ 	case ACCESS_READ:
+ 	  archive = STDIN;
+ 	  break;
+ 	case ACCESS_WRITE:
+ 	  archive = STDOUT;
+ 	  stdlis = stderr;
+ 	  break;
+ 	case ACCESS_UPDATE:
+ 	  archive = STDIN;
+ 	  stdlis = stderr;
+ 	  write_archive_to_stdout = 1;
+ 	  break;
+ 	}
+   else
+ #endif
      switch (access)
        {
        case ACCESS_READ:
*************** tryagain:
*** 1677,1683 ****
      }
  
  #if MSDOS
!   setmode (archive, O_BINARY);
  #endif
  
    return 1;
--- 2006,2013 ----
      }
  
  #if MSDOS
!   if (!isatty (archive))
!     setmode (archive, O_BINARY);
  #endif
  
    return 1;
diff -cp -r test/tar-1.12/src/compare.c tar-1.12/src/compare.c
*** test/tar-1.12/src/compare.c	Tue Apr 15 20:34:04 1997
--- tar-1.12/src/compare.c	Sat Oct 11 20:53:42 1997
*************** get_stat_data (struct stat *stat_data)
*** 405,410 ****
--- 405,415 ----
  		? stat (current_file_name, stat_data)
  		: lstat (current_file_name, stat_data));
  
+ #ifdef __DJGPP__
+   /* DJGPP doesn't set st_rdev.  Fix this.  */
+   stat_data->st_rdev = stat_data->st_dev;
+ #endif
+ 
    if (status < 0)
      {
        if (errno == ENOENT)
*************** get_stat_data (struct stat *stat_data)
*** 423,428 ****
--- 428,538 ----
    return 1;
  }
  
+ #if MSDOS
+ 
+ /*------------------------------------------------------------------.
+ | Diff two files.  Used on MS-DOS to compare with simulated links.  |
+ `------------------------------------------------------------------*/
+ 
+ static void
+ diff_two_files (const char *file_name1, const char *file_name2)
+ {
+   int diff_handle1, diff_handle2, r1, r2;
+   static unsigned char *buf;
+   char message[MESSAGE_BUFFER_SIZE];
+ 
+   if (!buf)
+     buf = (unsigned char *)xmalloc (record_size);
+ 
+   /* No need to check `open' succeeded, since the
+      two files were already verified to exist.  */
+   diff_handle1 = open (file_name1, O_RDONLY | O_BINARY);
+   diff_handle2 = open (file_name1, O_RDONLY | O_BINARY);
+ 
+   while ((r1 = read (diff_handle1, diff_buffer, record_size)) > 0
+ 	 && (r2 = read (diff_handle2, buf, record_size)) > 0)
+     {
+       if (r1 != r2)
+ 	{
+ 	  if (r1 < 0)
+ 	    {
+ 	      WARN ((0, errno, _("Cannot read %s"), file_name1));
+ 	      report_difference (NULL);
+ 	    }
+ 	  else if (r2 < 0)
+ 	    {
+ 	      WARN ((0, errno, _("Cannot read %s"), file_name2));
+ 	      report_difference (NULL);
+ 	    }
+ 	  else
+ 	    {
+ 	      sprintf (message, _("Could only read %d of %ld bytes"),
+ 		       r1 < r2 ? r1 : r2, r1 > r2 ? r1 : r2);
+ 	      report_difference (message);
+ 	    }
+ 	  return;
+ 	}
+       if (memcmp (buf, diff_buffer, (size_t) r1))
+ 	{
+ 	  report_difference (_("Data differs"));
+ 	  return;
+ 	}
+     }
+ }
+ 
+ /*------------------------------------------------------------------.
+ | Parameterization of comparing mode bits, mod times, uids, gids.   |
+ `------------------------------------------------------------------*/
+ 
+ static int
+ mode_bits_differ (mode_t mode1, mode_t mode2)
+ {
+   /* Quickly handle the (hopefully) usual case.  */
+   if (mode1 == mode2)
+     return 0;
+   if ((mode1 & S_IFMT) != (mode2 & S_IFMT))
+     return 1;
+   /* MS-DOS files are always readable, only writable by owner,
+      and the execute bit is invented, not really stored in the
+      filesystem.  This could cause some false alarms.  So only
+      report a difference when the user's write bit is different.  */
+   if (!S_ISDIR (mode1) && (mode1 & S_IWUSR) == (mode2 & S_IWUSR))
+     return 0;
+   /* For directories and non-files, check both write and execute bits.  */
+   if ((mode1 & (S_IWUSR | S_IXUSR)) == (mode2 & (S_IWUSR | S_IXUSR)))
+     return 0;
+   return 1;
+ }
+ 
+ #define uid_differs(u1,u2)	(0)
+ #define gid_differs(g1,g2)	(0)
+ 
+ int
+ mod_time_differs (time_t mt1, time_t mt2)
+ {
+   double tdiff;
+ 
+   /* Optimize the (hopefully) usual case.  */
+   if (mt1 == mt2)
+     return 0;
+ 
+   /* MS-DOS/MS-Windows FAT filesystems round file timestamps
+      to the nearest multiple of 2 seconds.  Don't report
+      differences unless file times differ by more than 1 second.  */
+   tdiff = difftime (mt1, mt2);
+ 
+   return (tdiff > 1) ? 1 : (tdiff < -1) ? -1 : 0;
+ }
+ 
+ #else  /* !MSDOS */
+ 
+ #define mode_bits_differ(m1,m2)	((m1) != (m2))
+ #define uid_differs(u1,u2)	((u1) != (u2))
+ #define gid_differs(g1,g2)	((g1) != (g2))
+ #define mod_time_differs(t1,t2)	((t1) != (t2))
+ 
+ #endif /* !MSDOS */
+ 
  /*----------------------------------.
  | Diff a file against the archive.  |
  `----------------------------------*/
*************** diff_archive (void)
*** 483,502 ****
  	}
  
        stat_data.st_mode &= 07777;
!       if (stat_data.st_mode != current_stat.st_mode)
  	report_difference (_("Mode differs"));
  
! #if !MSDOS
!       /* stat() in djgpp's C library gives a constant number of 42 as the
! 	 uid and gid of a file.  So, comparing an FTP'ed archive just after
! 	 unpack would fail on MSDOS.  */
!       if (stat_data.st_uid != current_stat.st_uid)
  	report_difference (_("Uid differs"));
!       if (stat_data.st_gid != current_stat.st_gid)
  	report_difference (_("Gid differs"));
- #endif
  
!       if (stat_data.st_mtime != current_stat.st_mtime)
  	report_difference (_("Mod time differs"));
        if (current_header->header.typeflag != GNUTYPE_SPARSE &&
  	  stat_data.st_size != current_stat.st_size)
--- 593,607 ----
  	}
  
        stat_data.st_mode &= 07777;
!       if (mode_bits_differ (stat_data.st_mode, current_stat.st_mode))
  	report_difference (_("Mode differs"));
  
!       if (uid_differs (stat_data.st_uid, current_stat.st_uid))
  	report_difference (_("Uid differs"));
!       if (gid_differs (stat_data.st_gid, current_stat.st_gid))
  	report_difference (_("Gid differs"));
  
!       if (mod_time_differs (stat_data.st_mtime, current_stat.st_mtime))
  	report_difference (_("Mod time differs"));
        if (current_header->header.typeflag != GNUTYPE_SPARSE &&
  	  stat_data.st_size != current_stat.st_size)
*************** diff_archive (void)
*** 514,520 ****
  
  	  *tmpbuf = '/';
  	  strcpy (tmpbuf + 1, current_file_name);
! 	  diff_handle = open (tmpbuf, O_NDELAY | O_RDONLY);
  	  free (tmpbuf);
  	}
        if (diff_handle < 0)
--- 619,625 ----
  
  	  *tmpbuf = '/';
  	  strcpy (tmpbuf + 1, current_file_name);
! 	  diff_handle = open (tmpbuf, O_NDELAY | O_RDONLY | O_BINARY);
  	  free (tmpbuf);
  	}
        if (diff_handle < 0)
*************** diff_archive (void)
*** 553,559 ****
      quit:
        break;
  
- #if !MSDOS
      case LNKTYPE:
        {
  	dev_t dev;
--- 658,663 ----
*************** diff_archive (void)
*** 568,583 ****
  	if (status < 0)
  	  {
  	    if (errno == ENOENT)
  	      report_difference (_("Does not exist"));
  	    else
  	      {
! 		WARN ((0, errno, _("Cannot stat file %s"), current_file_name));
  		report_difference (NULL);
  	      }
  	    break;
  	  }
  
! 	if (stat_data.st_dev != dev || stat_data.st_ino != ino)
  	  {
  	    char *message = (char *)
  	      xmalloc (MESSAGE_BUFFER_SIZE + strlen (current_link_name));
--- 672,696 ----
  	if (status < 0)
  	  {
  	    if (errno == ENOENT)
+ #if MSDOS
+ 	      report_difference (_("Target of link does not exist"));
+ #else
  	      report_difference (_("Does not exist"));
+ #endif
  	    else
  	      {
! 		WARN ((0, errno, _("Cannot stat file %s"), current_link_name));
  		report_difference (NULL);
  	      }
  	    break;
  	  }
  
! 	/* MSDOS doesn't support hard links, so don't compare inodes.  */
! 	if (stat_data.st_dev != dev
! #if !MSDOS
! 	    || stat_data.st_ino != ino
! #endif
! 	    )
  	  {
  	    char *message = (char *)
  	      xmalloc (MESSAGE_BUFFER_SIZE + strlen (current_link_name));
*************** diff_archive (void)
*** 588,596 ****
  	    break;
  	  }
  
  	break;
        }
- #endif /* not MSDOS */
  
  #ifdef S_ISLNK
      case SYMTYPE:
--- 701,714 ----
  	    break;
  	  }
  
+ #if MSDOS
+ 	/* Since these are actually two different files, make sure
+ 	   their contents is identical.  */
+ 	diff_two_files (current_file_name, current_link_name);
+ #endif
+ 
  	break;
        }
  
  #ifdef S_ISLNK
      case SYMTYPE:
*************** diff_archive (void)
*** 617,622 ****
--- 735,770 ----
  
  	break;
        }
+ #else  /* not S_ISLNK */
+     case SYMTYPE:
+       {
+ 	status = stat (current_link_name, &stat_data);
+ 	if (status < 0)
+ 	  {
+ 	    if (errno == ENOENT)
+ 	      report_difference (_("Target of link does not exist"));
+ 	    else
+ 	      {
+ 		WARN ((0, errno, _("Cannot stat file %s"), current_link_name));
+ 		report_difference (NULL);
+ 	      }
+ 	    break;
+ 	  }
+ 	status = stat (current_file_name, &stat_data);
+ 	if (status < 0)
+ 	  {
+ 	    if (errno == ENOENT)
+ 	      report_difference (_("No such file or directory"));
+ 	    else
+ 	      {
+ 		WARN ((0, errno, _("Cannot stat file %s"), current_file_name));
+ 		report_difference (NULL);
+ 	      }
+ 	  }
+ 	else
+ 	  diff_two_files (current_file_name, current_link_name);
+ 	break;
+       }
  #endif /* not S_ISLNK */
  
  #ifdef S_IFCHR
*************** diff_archive (void)
*** 658,667 ****
  
        if (
  #ifdef S_IFMT
! 	  current_stat.st_mode != stat_data.st_mode
  #else
  	  /* POSIX lossage.  */
! 	  (current_stat.st_mode & 07777) != (stat_data.st_mode & 07777)
  #endif
  	  )
  	{
--- 806,816 ----
  
        if (
  #ifdef S_IFMT
! 	  mode_bits_differ (current_stat.st_mode, stat_data.st_mode)
  #else
  	  /* POSIX lossage.  */
! 	  mode_bits_differ ((current_stat.st_mode & 07777),
! 			    (stat_data.st_mode & 07777))
  #endif
  	  )
  	{
*************** diff_archive (void)
*** 714,720 ****
  	  break;
  	}
  
!       if ((stat_data.st_mode & 07777) != (current_stat.st_mode & 07777))
  	report_difference (_("Mode differs"));
        break;
  
--- 863,870 ----
  	  break;
  	}
  
!       if (mode_bits_differ ((stat_data.st_mode & 07777),
! 			    (current_stat.st_mode & 07777)))
  	report_difference (_("Mode differs"));
        break;
  
*************** verify_volume (void)
*** 841,846 ****
--- 991,1002 ----
  	  }
        }
    }
+ #endif
+ 
+ #ifdef __DJGPP__
+   /* If they have some disk cache installed, try
+      to make it forget everything about the tar media.  */
+   _flush_disk_cache ();
  #endif
  
    access_mode = ACCESS_READ;
diff -cp -r test/tar-1.12/src/create.c tar-1.12/src/create.c
*** test/tar-1.12/src/create.c	Fri Apr 25 13:48:48 1997
--- tar-1.12/src/create.c	Sat Oct  4 16:23:22 1997
***************
*** 18,24 ****
  
  #include "system.h"
  
! #if !MSDOS
  # include <pwd.h>
  # include <grp.h>
  #endif
--- 18,24 ----
  
  #include "system.h"
  
! #if !MSDOS || defined (__DJGPP__)
  # include <pwd.h>
  # include <grp.h>
  #endif
*************** struct utimbuf
*** 35,41 ****
  
  #include "common.h"
  
! #ifndef MSDOS
  extern dev_t ar_dev;
  extern ino_t ar_ino;
  #endif
--- 35,41 ----
  
  #include "common.h"
  
! #if !MSDOS || defined (__DJGPP__)
  extern dev_t ar_dev;
  extern ino_t ar_ino;
  #endif
*************** start_header (const char *name, struct s
*** 179,192 ****
        static int warned_once = 0;
  
  #if MSDOS
!       if (name[1] == ':')
  	{
- 	  name += 2;
  	  if (!warned_once)
  	    {
! 	      warned_once = 1;
! 	      WARN ((0, 0, _("Removing drive spec from names in the archive")));
  	    }
  	}
  #endif
  
--- 179,197 ----
        static int warned_once = 0;
  
  #if MSDOS
!       if (name[0] >= 'A' && name[0] <= 'z' && name[1] == ':')
  	{
  	  if (!warned_once)
  	    {
! 	      char msg[60];
! 	      /* Don't set warned_once if the next character is a slash,
! 		 so that they will see the message about the slash as well.  */
! 	      if (name[2] != '/')
! 		warned_once = 1;
! 	      sprintf (msg, _("Removing drive spec `%2.2s' from path names in the archive"), name);
! 	      WARN ((0, 0, msg));
  	    }
+ 	  name += 2;
  	}
  #endif
  
*************** dump_file (char *p, int parent_device, i
*** 735,742 ****
       put in the archive.  */
  
    if (!incremental_option && !S_ISDIR (current_stat.st_mode)
!       && current_stat.st_mtime < newer_mtime_option
!       && (!after_date_option || current_stat.st_ctime < newer_ctime_option))
      {
        if (parent_device == -1)
  	WARN ((0, 0, _("%s: is unchanged; not dumped"), p));
--- 740,748 ----
       put in the archive.  */
  
    if (!incremental_option && !S_ISDIR (current_stat.st_mode)
!       && mtime_older (current_stat.st_mtime, newer_mtime_option)
!       && (!after_date_option
! 	  || mtime_older (current_stat.st_ctime, newer_ctime_option)))
      {
        if (parent_device == -1)
  	WARN ((0, 0, _("%s: is unchanged; not dumped"), p));
*************** dump_file (char *p, int parent_device, i
*** 744,750 ****
        return;
      }
  
! #if !MSDOS
    /* See if we are trying to dump the archive.  */
  
    if (ar_dev && current_stat.st_dev == ar_dev && current_stat.st_ino == ar_ino)
--- 750,756 ----
        return;
      }
  
! #if !MSDOS || defined (__DJGPP__)
    /* See if we are trying to dump the archive.  */
  
    if (ar_dev && current_stat.st_dev == ar_dev && current_stat.st_ino == ar_ino)
diff -cp -r test/tar-1.12/src/extract.c tar-1.12/src/extract.c
*** test/tar-1.12/src/extract.c	Wed Apr 23 00:05:56 1997
--- tar-1.12/src/extract.c	Sat Oct 11 13:03:48 1997
*************** make_directories (char *file_name)
*** 227,232 ****
--- 227,238 ----
        if (cursor == file_name || cursor[-1] == '/')
  	continue;
  
+ #if MSDOS
+       /* Avoid mkdir of a root directory on any drive.  */
+       if (cursor == file_name + 2 && cursor[-1] == ':')
+ 	continue;
+ #endif
+ 
        /* Avoid mkdir where last part of path is '.'.  */
  
        if (cursor[-1] == '.' && (cursor == file_name + 1 || cursor[-2] == '/'))
*************** make_directories (char *file_name)
*** 257,263 ****
  
        if (errno == EEXIST
  #if MSDOS
! 	  /* Turbo C mkdir gives a funny errno.  */
  	  || errno == EACCES
  #endif
  	  )
--- 263,271 ----
  
        if (errno == EEXIST
  #if MSDOS
! 	  /* Turbo C mkdir gives a funny errno.
! 	     MSDOS can also get EACCESS when trying to mkdir
! 	     a directory which is a cwd on another drive.  */
  	  || errno == EACCES
  #endif
  	  )
*************** make_directories (char *file_name)
*** 272,277 ****
--- 280,399 ----
    return did_something;		/* tell them to retry if we made one */
  }
  
+ #if MSDOS
+ 
+ /*------------------------------------------------------------.
+ | Attempt to repair file names that are illegal on MS-DOS and |
+ | MS-Windows by changing illegal characters.		      |
+ `------------------------------------------------------------*/
+ 
+ static int msdosify_count = 0;
+ 
+ static char *
+ msdosify (char *file_name)
+ {
+   static char dos_name[PATH_MAX];
+   static char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
+   static char *illegal_chars_w95 = &illegal_chars_dos[8];
+   int idx, dot_idx;
+   char *s = file_name, *d = dos_name;
+   char *illegal_aliens = illegal_chars_dos;
+   size_t len = sizeof (illegal_chars_dos) - 1;
+   int lfn = 0;
+   int save_errno = errno;	/* in case `_use_lfn' below sets errno */
+ 
+   /* Support for Windows 9X VFAT systems, when available.  */
+ #ifdef __DJGPP__
+   if (_use_lfn (file_name))
+     lfn = 1;
+ #endif
+   if (lfn)
+     {
+       illegal_aliens = illegal_chars_w95;
+       len -= (illegal_chars_w95 - illegal_chars_dos);
+     }
+ 
+   /* Get past the drive letter, if any. */
+   if (s[0] >= 'A' && s[0] <= 'z' && s[1] == ':')
+     {
+       *d++ = *s++;
+       *d++ = *s++;
+     }
+ 
+   for (idx = 0, dot_idx = -1; *s; s++, d++)
+     {
+       if (memchr (illegal_aliens, *s, len))
+ 	{
+ 	  /* Dots are special: DOS doesn't allow them as the leading
+ 	     character, and a file name cannot have more than a single dot.
+ 	     We leave the first non-leading dot alone, unless it comes too
+ 	     close to the beginning of the name: we want sh.lex.c to become
+ 	     sh_lex.c, not sh.lex-c.  */
+ 	  if (*s == '.')
+ 	    {
+ 	      if (idx == 0 && (s[1] == '/' || s[1] == '.' && s[2] == '/'))
+ 		{
+ 		  /* Copy "./" and "../" verbatim.  */
+ 		  *d++ = *s++;
+ 		  if (*s == '.')
+ 		    *d++ = *s++;
+ 		  *d = *s;
+ 		}
+ 	      else if (idx == 0)
+ 		*d = '_';
+ 	      else if (dot_idx >= 0)
+ 		{
+ 		  if (dot_idx < 5) /* 5 is a heuristic ad-hoc'ery */
+ 		    {
+ 		      d[dot_idx - idx] = '_'; /* replace previous dot */
+ 		      *d = '.';
+ 		    }
+ 		  else
+ 		    *d = '-';
+ 		}
+ 	      else
+ 		*d = '.';
+ 
+ 	      if (*s == '.')
+ 		dot_idx = idx;
+ 	    }
+ 	  else if (*s == '+' && s[1] == '+')
+ 	    {
+ 	      if (idx - 2 == dot_idx) /* .c++, .h++ etc. */
+ 		{
+ 		  *d++ = 'x';
+ 		  *d   = 'x';
+ 		}
+ 	      else
+ 		{
+ 		  /* libg++ etc.  */
+ 		  memcpy (d, "plus", 4);
+ 		  d += 3;
+ 		}
+ 	      s++;
+ 	      idx++;
+ 	    }
+ 	  else
+ 	    *d = '_';
+ 	}
+       else
+ 	*d = *s;
+       if (*s == '/')
+ 	{
+ 	  idx = 0;
+ 	  dot_idx = -1;
+ 	}
+       else
+ 	idx++;
+     }
+ 
+   *d = '\0';
+   errno = save_errno;		/* FIXME: errno should be read-only */
+   return dos_name;
+ }
+ 
+ #endif /* MSDOS */
+ 
  /*--------------------------------------------------------------------.
  | Attempt repairing what went wrong with the extraction.  Delete an   |
  | already existing file or create missing intermediate directories.   |
*************** maybe_recoverable (char *file_name)
*** 288,299 ****
--- 410,442 ----
        /* Attempt deleting an existing file.  However, with -k, just stay
  	 quiet.  */
  
+       /* FIXME: On MS-DOS, we could get EEXIST because names of two files
+ 	 clash in the 8+3 DOS namespace.  (This happens when the archive
+ 	 was brought from Unix.)  We could even be overwriting another
+ 	 file from the same archive.  Tough.  They should use --backup.  */
+ 
        if (keep_old_files_option)
  	return 0;
  
        return remove_any_file (file_name, 0);
  
      case ENOENT:
+ #if MSDOS
+     case EACCES:
+       /* FILE_NAME may include illegal characters.
+ 	 Try to replace them, but if it fails again, punt.  */
+       if (msdosify_count++ == 0)
+ 	{
+ 	  char *new_name = msdosify (file_name);
+ 	  if (strcmp (new_name, file_name))
+ 	    {
+ 	      if (verbose_option)
+ 		WARN ((0, 0, _("Renamed %s to %s"), file_name, new_name));
+ 	      strcpy (file_name, new_name);
+ 	      return 1;
+ 	    }
+ 	}
+ #endif
        /* Attempt creating missing intermediate directories.  */
  
        return make_directories (file_name);
*************** extract_sparse_file (int fd, long *sizel
*** 361,366 ****
--- 504,562 ----
    set_next_block_after (data_block);
  }
  
+ #if MSDOS
+ 
+ static char *
+ rename_if_dos_device_name (char *file_name)
+ {
+   /* We could have a file in an archive whose name is a device
+      on MS-DOS.  Trying to extract such a file would fail at
+      best and wedge us at worst.  We need to rename such files.
+ 
+      FIXME: I don't know how this can be tested in non-DJGPP
+      environment.  I will assume `stat' works for them also.  */
+   extern char *basename (const char *);
+   char *base;
+   struct stat st_buf;
+   char fname[PATH_MAX];
+   int i = 0;
+ 
+   strcpy (fname, file_name);
+   base = basename (fname);
+   while (stat (base, &st_buf) == 0 && S_ISCHR (st_buf.st_mode))
+     {
+       size_t blen = strlen (base);
+ 
+       /* I don't believe any DOS character device names begin with a
+ 	 `_'.  But in case they invent such a device, let us try twice.  */
+       if (++i > 2)
+ 	{
+ 	  ERROR ((0, EACCES, _("%s: Could not create file"), file_name));
+ 	  if (current_header->oldgnu_header.isextended)
+ 	    skip_extended_headers ();
+ 	  skip_file ((long) current_stat.st_size);
+ 	  return file_name;
+ 	}
+       /* Prepend a '_'.  */
+       memmove (base + 1, base, blen + 1);
+       base[0] = '_';
+     }
+   if (i)
+     {
+       char *p = 0;
+ 
+       if (verbose_option)
+ 	WARN ((0, 0, _("Renamed %s to %s"), file_name, fname));
+       assign_string (&p, fname);
+       free (file_name);
+       return p;
+     }
+   else
+     return file_name;
+ }
+ 
+ #endif /* MSDOS */
+ 
  /*----------------------------------.
  | Extract a file from the archive.  |
  `----------------------------------*/
*************** extract_archive (void)
*** 404,415 ****
    /* Check for fully specified file names and other atrocities.  */
  
    skipcrud = 0;
    while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
      {
        static int warned_once = 0;
  
        skipcrud++;		/* force relative path */
!       if (!warned_once)
  	{
  	  warned_once = 1;
  	  WARN ((0, 0, _("\
--- 600,624 ----
    /* Check for fully specified file names and other atrocities.  */
  
    skipcrud = 0;
+ #if MSDOS
+   msdosify_count = 0;
+   if (!to_stdout_option)
+     current_file_name = rename_if_dos_device_name (current_file_name);
+ 
+   /* The reason for perhaps too elaborate tests here is that we
+      could have a filename like "9:30:45", and we don't want to
+      treat it as if it were an absolute file name with a drive letter.  */
+   if (!absolute_names_option
+       && CURRENT_FILE_NAME[0] >= 'A' && CURRENT_FILE_NAME[0] <= 'z'
+       && CURRENT_FILE_NAME[1] == ':' && CURRENT_FILE_NAME[2] == '/')
+     skipcrud += 2;
+ #endif
    while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
      {
        static int warned_once = 0;
  
        skipcrud++;		/* force relative path */
!       if (!warned_once && !to_stdout_option)
  	{
  	  warned_once = 1;
  	  WARN ((0, 0, _("\
*************** Removing leading `/' from absolute path 
*** 541,546 ****
--- 750,764 ----
        if (to_stdout_option)
  	{
  	  fd = 1;
+ #if MSDOS
+ 	  /* If stdout is a pipe or was redirected to a file, we should
+ 	     write it in binary mode!  Otherwise, non-text files will end
+ 	     up corrupted.  (But if they want binary garbage on their
+ 	     screen, let them have fun, since switching the console to
+ 	     binary mode has some really nasty side-effects).  */
+ 	  if (!isatty (1))
+ 	    setmode (1, O_BINARY);
+ #endif
  	  goto extract_file;
  	}
  
*************** Attempting extraction of symbolic links 
*** 769,774 ****
--- 987,997 ----
        {
  	struct stat st1, st2;
  
+ #if MSDOS
+ 	/* Rename current_link_name if it might get us in trouble.  */
+ 	current_link_name = rename_if_dos_device_name (current_link_name);
+ #endif
+ 
  	/* MSDOS does not implement links.  However, djgpp's link() actually
  	   copies the file.  */
  	status = link (current_link_name, CURRENT_FILE_NAME);
*************** Attempting extraction of symbolic links 
*** 783,789 ****
  	if (stat (current_link_name, &st1) == 0
  	    && stat (CURRENT_FILE_NAME, &st2) == 0
  	    && st1.st_dev == st2.st_dev
! 	    && st1.st_ino == st2.st_ino)
  	  break;
  
  	ERROR ((0, errno, _("%s: Could not link to `%s'"),
--- 1006,1018 ----
  	if (stat (current_link_name, &st1) == 0
  	    && stat (CURRENT_FILE_NAME, &st2) == 0
  	    && st1.st_dev == st2.st_dev
! #if !MSDOS
! 	    /* We get here if both files already exist, and on MSDOS
! 	       they will have different inodes numbers.  So don't
! 	       check inodes on MSDOS.  */
! 	    && st1.st_ino == st2.st_ino
! #endif
! 	    )
  	  break;
  
  	ERROR ((0, errno, _("%s: Could not link to `%s'"),
*************** Attempting extraction of symbolic links 
*** 857,862 ****
--- 1086,1095 ----
        name_length = strlen (CURRENT_FILE_NAME) - 1;
  
      really_dir:
+ #if MSDOS
+       /* Under -P, we could have "d:/".  Leave that trailing slash alone.  */
+       if (skipcrud != 0 || name_length != 2 || CURRENT_FILE_NAME[1] != ':')
+ #endif
        /* Check for trailing /, and zap as many as we find.  */
        while (name_length && CURRENT_FILE_NAME[name_length] == '/')
  	CURRENT_FILE_NAME[name_length--] = '\0';
*************** Attempting extraction of symbolic links 
*** 874,879 ****
--- 1107,1117 ----
        if (to_stdout_option)
  	break;
  
+       /* We were promised by the manual that we would be able to nuke
+ 	 entire directory hierarchies, but stock tar 1.12 didn't do it.  */
+       if (recursive_unlink_option)
+ 	remove_any_file (CURRENT_FILE_NAME, 1);
+ 
      again_dir:
        status = mkdir (CURRENT_FILE_NAME,
  		     (we_are_root ? 0 : 0300) | (int) current_stat.st_mode);
*************** Attempting extraction of symbolic links 
*** 909,914 ****
--- 1147,1169 ----
  	      errno = saved_errno; /* FIXME: errno should be read-only */
  	    }
  
+ #if MSDOS
+ 	  /* The ubiquitous DOS "Access denied" lossage.
+ 	     If that disaster strikes us, and the directory already
+ 	     exists, avoid printing a message and/or failing.  */
+ 
+ 	  if (errno == EACCES)
+ 	    {
+ 	      struct stat st1;
+ 	      int saved_errno = errno;
+ 
+ 	      if (stat (CURRENT_FILE_NAME, &st1) == 0 && S_ISDIR (st1.st_mode))
+ 		break;
+ 
+ 	      errno = saved_errno; /* FIXME: errno should be read-only */
+ 	    }
+ #endif
+ 
  	  if (maybe_recoverable (CURRENT_FILE_NAME))
  	    goto again_dir;
  
*************** Attempting extraction of symbolic links 
*** 937,944 ****
  	}
  
  #if !MSDOS
!       /* MSDOS does not associate timestamps with directories.   In this
! 	 case, no need to try delaying their restoration.  */
  
        if (touch_option)
  
--- 1192,1199 ----
  	}
  
  #if !MSDOS
!       /* MSDOS does not allow to change timestamps of directories.
!          In this case, no need to try delaying their restoration.  */
  
        if (touch_option)
  
diff -cp -r test/tar-1.12/src/incremen.c tar-1.12/src/incremen.c
*** test/tar-1.12/src/incremen.c	Thu Apr 24 14:09:22 1997
--- tar-1.12/src/incremen.c	Fri Oct  3 16:17:52 1997
*************** get_directory_contents (char *path, int 
*** 290,298 ****
  
  	else
  	  if (!all_children
! 	      && stat_data.st_mtime < newer_mtime_option
  	      && (!after_date_option
! 		  || stat_data.st_ctime < newer_ctime_option))
  	    add_to_accumulator (accumulator, "N", 1);
  	  else
  	    add_to_accumulator (accumulator, "Y", 1);
--- 290,298 ----
  
  	else
  	  if (!all_children
! 	      && mtime_older (stat_data.st_mtime, newer_mtime_option)
  	      && (!after_date_option
! 		  || mtime_older (stat_data.st_ctime, newer_ctime_option)))
  	    add_to_accumulator (accumulator, "N", 1);
  	  else
  	    add_to_accumulator (accumulator, "Y", 1);
*************** read_directory_file (void)
*** 430,436 ****
    if (path == NULL)
      path = xmalloc (PATH_MAX);
    time (&time_now);
!   if (listed_incremental_option[0] != '/')
      {
  #if HAVE_GETCWD
        if (!getcwd (path, PATH_MAX))
--- 430,441 ----
    if (path == NULL)
      path = xmalloc (PATH_MAX);
    time (&time_now);
!   if (listed_incremental_option[0] != '/'
! #if MSDOS
!       /* The case of DOS absolute file name with a drive letter.  */
!       && (!listed_incremental_option[0] || listed_incremental_option[1] != ':')
! #endif
!       )
      {
  #if HAVE_GETCWD
        if (!getcwd (path, PATH_MAX))
diff -cp -r test/tar-1.12/src/list.c tar-1.12/src/list.c
*** test/tar-1.12/src/list.c	Fri Apr 25 20:16:30 1997
--- tar-1.12/src/list.c	Fri Oct  3 16:18:56 1997
*************** read_and (void (*do_something) ())
*** 67,73 ****
  	    = from_oct (1 + 12, current_header->header.mtime);
  
  	  if (!name_match (current_file_name)
! 	      || current_stat.st_mtime < newer_mtime_option
  	      || (exclude_option && check_exclude (current_file_name)))
  	    {
  	      int isextended = 0;
--- 67,73 ----
  	    = from_oct (1 + 12, current_header->header.mtime);
  
  	  if (!name_match (current_file_name)
! 	      || mtime_older (current_stat.st_mtime, newer_mtime_option)
  	      || (exclude_option && check_exclude (current_file_name)))
  	    {
  	      int isextended = 0;
diff -cp -r test/tar-1.12/src/misc.c tar-1.12/src/misc.c
*** test/tar-1.12/src/misc.c	Thu Apr 24 14:41:50 1997
--- tar-1.12/src/misc.c	Fri Oct 10 19:46:48 1997
*************** remove_any_file (const char *path, int r
*** 359,365 ****
--- 359,373 ----
  	if (dirp == NULL)
  	  return 0;
  
+      /* The original code here said this:
+ 
  	while (dp = readdir (dirp), dp && !is_dot_or_dotdot (dp->d_name))
+ 
+ 	I fail to see how could that ever work.  The first directory
+ 	entry is usually `.', so the loop would terminate immediately.  */
+ 
+ 	while ((dp = readdir (dirp)))
+ 	  if (!is_dot_or_dotdot (dp->d_name))
  	  {
  	    char *path_buffer = new_name (path, dp->d_name);
  
*************** maybe_backup_file (const char *path, int
*** 422,427 ****
--- 430,443 ----
  
    if (S_ISDIR (file_stat.st_mode))
      return 1;
+ 
+ #if MSDOS
+   /* Backing up non-regular files will never work on MSDOS, and
+      we change the names of files which are special to DOS anyway.
+      So just pretend we succeeded.  */
+   if (!S_ISREG (file_stat.st_mode))
+     return 1;
+ #endif
  
  #ifdef S_ISBLK
    if (archive && S_ISBLK (file_stat.st_mode))
diff -cp -r test/tar-1.12/src/names.c tar-1.12/src/names.c
*** test/tar-1.12/src/names.c	Tue Apr 22 05:35:50 1997
--- tar-1.12/src/names.c	Fri Oct 10 21:19:20 1997
*************** static char cached_gname[GNAME_FIELD_SIZ
*** 48,53 ****
--- 48,68 ----
  static uid_t cached_uid;	/* valid only if cached_uname is not empty */
  static gid_t cached_gid;	/* valid only if cached_gname is not empty */
  
+ /* Well, here's my version of ``something reasonable'' for MS-DOS and
+    MS-Windows: allow *any* name/uid or group/gid to be accepted.  These
+    systems don't give a damn about uids and gids, but we still would like
+    to let them set ownership for files inside archives.
+ 
+    Currently only enabled for systems which define MSDOS.  */
+ 
+ #if MSDOS
+ static char pw_name_buf[UNAME_FIELD_SIZE];
+ static char gr_name_buf[GNAME_FIELD_SIZE];
+ static struct passwd faked_passwd = {pw_name_buf, 42, 42, 0, 0};
+ static struct group  faked_group  = {42, 0, gr_name_buf};
+ static char digits[] = "0123456789";
+ #endif
+ 
  /*------------------------------------------.
  | Given UID, find the corresponding UNAME.  |
  `------------------------------------------*/
*************** uid_to_uname (uid_t uid, char uname[UNAM
*** 60,65 ****
--- 75,88 ----
    if (!cached_uname[0] || uid != cached_uid)
      {
        passwd = getpwuid (uid);
+ #if MSDOS
+       if (!passwd)
+ 	{
+ 	  passwd = &faked_passwd;
+ 	  sprintf (passwd->pw_name, "user-%d", uid);
+ 	  passwd->pw_uid = uid;
+ 	}
+ #endif
        if (passwd)
  	{
  	  cached_uid = uid;
*************** gid_to_gname (gid_t gid, char gname[GNAM
*** 84,89 ****
--- 107,120 ----
      {
        setgrent ();		/* FIXME: why?! */
        group = getgrgid (gid);
+ #if MSDOS
+       if (!group)
+ 	{
+ 	  group = &faked_group;
+ 	  sprintf (group->gr_name, "group-%d", gid);
+ 	  group->gr_gid = gid;
+ 	}
+ #endif
        if (group)
  	{
  	  cached_gid = gid;
*************** uname_to_uid (char uname[UNAME_FIELD_SIZ
*** 109,114 ****
--- 140,154 ----
        || strncmp (uname, cached_uname, UNAME_FIELD_SIZE) != 0)
      {
        passwd = getpwnam (uname);
+ #if MSDOS
+       /* Fail if UNAME is a number, so that they could use numeric UIDs.  */
+       if (!passwd && strspn (uname, digits) < strlen (uname) - 1)
+ 	{
+ 	  passwd = &faked_passwd;
+ 	  passwd->pw_uid++;
+ 	  strncpy (passwd->pw_name, uname, UNAME_FIELD_SIZE);
+ 	}
+ #endif
        if (passwd)
  	{
  	  cached_uid = passwd->pw_uid;
*************** gname_to_gid (char gname[GNAME_FIELD_SIZ
*** 135,140 ****
--- 175,189 ----
        || strncmp (gname, cached_gname, GNAME_FIELD_SIZE) != 0)
      {
        group = getgrnam (gname);
+ #if MSDOS
+       /* Fail if GNAME is a number, so that they could use numeric UIDs.  */
+       if (!group && strspn (gname, digits) < strlen (gname) - 1)
+ 	{
+ 	  group = &faked_group;
+ 	  group->gr_gid++;
+ 	  strncpy (group->gr_name, gname, GNAME_FIELD_SIZE);
+ 	}
+ #endif
        if (group)
  	{
  	  cached_gid = group->gr_gid;
*************** name_next (int change_dirs)
*** 320,328 ****
--- 369,403 ----
  	  strcpy (name_buffer, source);
  	}
  
+ #if MSDOS
+       /* The rest of code depends on getting Unix-style forward slashes
+ 	 and will break otherwise.  All recursions into subdirectories
+ 	 append forward slashes, so we only need to make sure the original
+ 	 file/directory gets its DOS-style backslashes mirrored.  It seems
+ 	 that here's the right place to do that.
+ 
+ 	 Note that I haven't even remotedly considered whether this will
+ 	 work with anything but DJGPP v2 and above.  I cannot be bothered
+ 	 to think about every broken MSDOS libc out there.  */
+       if ((cursor = strchr (name_buffer, '\\')))
+ 	{
+ 	  char *p = cursor;
+ 
+ 	  for ( ; *p; p++)
+ 	    if (*p == '\\')
+ 	      *p = '/';
+ 	}
+ #endif
        /* Zap trailing slashes.  */
  
        cursor = name_buffer + strlen (name_buffer) - 1;
+ #if MSDOS
+       if (name_buffer[0] >= 'A' && name_buffer[0] <= 'z'
+ 	  && name_buffer[1] == ':' && name_buffer[2] == '/')
+ 	while (cursor > name_buffer + 2 && *cursor == '/')
+ 	  *cursor-- = '\0';
+       else
+ #endif
        while (cursor > name_buffer && *cursor == '/')
  	*cursor-- = '\0';
  
*************** addname (const char *string)
*** 451,457 ****
        if (!chdir_name)
  	FATAL_ERROR ((0, 0, _("Missing file name after -C")));
  
!       if (chdir_name[0] != '/')
  	{
  	  char *path = xmalloc (PATH_MAX);
  
--- 526,537 ----
        if (!chdir_name)
  	FATAL_ERROR ((0, 0, _("Missing file name after -C")));
  
!       if (chdir_name[0] != '/'
! #if MSDOS
! 	  /* The case of drive letter.  */
! 	  && (!chdir_name[0] || chdir_name[1] != ':')
! #endif
! 	  )
  	{
  	  char *path = xmalloc (PATH_MAX);
  
diff -cp -r test/tar-1.12/src/rmt.h tar-1.12/src/rmt.h
*** test/tar-1.12/src/rmt.h	Wed Apr  9 16:21:44 1997
--- tar-1.12/src/rmt.h	Thu Oct  2 21:47:50 1997
*************** int rmt_ioctl__ PARAMS ((int, int, char 
*** 30,46 ****
--- 30,82 ----
     Distributed File System (DFS).  However, when --force-local, a
     filename is never remote.  */
  
+ #if MSDOS
+ /* MSDOS pathnames always include a drive letter and a colon.  So we have
+    no other choice but to disallow one-letter names of remote hosts if
+    the first letter is between `A' and `z' (which are valid DOS drives).  */
+ #define _remdev(Path) \
+   (!force_local_option && (rmt_path__ = strchr (Path, ':')) \
+    && (rmt_path__ > (Path) + 1 \
+        || (rmt_path__ == (Path) + 1 \
+ 	   && (rmt_path__[-1] < 'A' || rmt_path__[-1] > 'z'))))
+ #else
  #define _remdev(Path) \
    (!force_local_option && (rmt_path__ = strchr (Path, ':')) \
     && rmt_path__ > (Path) && rmt_path__[-1] != '/')
+ #endif
  
  #define _isrmt(Fd) \
    ((Fd) >= __REM_BIAS)
  
+ #ifdef __DJGPP__
+ /* DJGPP file handles can go up to 255.  */
+ #define __REM_BIAS 256
+ #else
  #define __REM_BIAS 128
+ #endif
  
  #ifndef O_CREAT
  # define O_CREAT 01000
+ #endif
+ 
+ /* Try hard to get EOPNOTSUPP defined.  486/ISC has it in net/errno.h,
+    3B2/SVR3 has it in sys/inet.h.  Otherwise, like on MSDOS, use
+    either ENOSYS, if available, or EINVAL.  */
+ 
+ #ifndef EOPNOTSUPP
+ # if HAVE_NET_ERRNO_H
+ #  include <net/errno.h>
+ # endif
+ # if HAVE_SYS_INET_H
+ #  include <sys/inet.h>
+ # endif
+ # ifndef EOPNOTSUPP
+ #  ifdef ENOSYS
+ #   define EOPNOTSUPP ENOSYS
+ #  else
+ #   define EOPNOTSUPP EINVAL
+ #  endif
+ # endif
  #endif
  
  #define rmtopen(Path, Oflag, Mode, Command) \
diff -cp -r test/tar-1.12/src/rtapelib.c tar-1.12/src/rtapelib.c
*** test/tar-1.12/src/rtapelib.c	Mon Nov 11 16:03:50 1996
--- tar-1.12/src/rtapelib.c	Sun Sep 28 23:51:10 1997
***************
*** 32,52 ****
  
  #include "system.h"
  
- /* Try hard to get EOPNOTSUPP defined.  486/ISC has it in net/errno.h,
-    3B2/SVR3 has it in sys/inet.h.  Otherwise, like on MSDOS, use EINVAL.  */
- 
- #ifndef EOPNOTSUPP
- # if HAVE_NET_ERRNO_H
- #  include <net/errno.h>
- # endif
- # if HAVE_SYS_INET_H
- #  include <sys/inet.h>
- # endif
- # ifndef EOPNOTSUPP
- #  define EOPNOTSUPP EINVAL
- # endif
- #endif
- 
  #include <signal.h>
  
  #if HAVE_NETDB_H
--- 32,37 ----
diff -cp -r test/tar-1.12/src/system.h tar-1.12/src/system.h
*** test/tar-1.12/src/system.h	Sun Apr 20 02:43:34 1997
--- tar-1.12/src/system.h	Fri Oct  3 16:16:40 1997
*************** extern int errno;
*** 162,171 ****
--- 162,177 ----
  
  /* On MSDOS, there are missing things from <sys/stat.h>.  */
  #if MSDOS
+ #if !defined (S_ISUID)
  # define S_ISUID 0
+ #endif
+ #if !defined (S_ISGID)
  # define S_ISGID 0
+ #endif
+ #if !defined (S_ISVTX)
  # define S_ISVTX 0
  #endif
+ #endif
  
  #ifndef S_ISREG			/* POSIX.1 stat stuff missing */
  # define mode_t unsigned short
*************** extern int errno;
*** 239,250 ****
--- 245,258 ----
  #endif
  
  #ifndef GOT_MAJOR
+ #if !defined (__DJGPP__)
  # if MSDOS
  #  define major(Device)		(Device)
  #  define minor(Device)		(Device)
  #  define makedev(Major, Minor)	(((Major) << 8) | (Minor))
  #  define GOT_MAJOR
  # endif
+ #endif /* !__DJGPP__ */
  #endif
  
  /* For HP-UX before HP-UX 8, major/minor are not in <sys/sysmacros.h>.  */
*************** char *getenv ();
*** 428,440 ****
  
  #include <stdio.h>
  
! #ifndef _POSIX_VERSION
! # if MSDOS
! #  include <io.h>
! # else
  off_t lseek ();
  # endif
  #endif
  
  #include <pathmax.h>
  
--- 436,462 ----
  
  #include <stdio.h>
  
! #if MSDOS
! # include <io.h>
! # include <time.h>
! #else
! # ifndef _POSIX_VERSION
  off_t lseek ();
  # endif
  #endif
+ 
+ #if MSDOS
+ 
+ /* Test for newer mod time: on MS-DOS, file timestamps have
+    2 second granularity.  (mod_time_differs is on compare.c)  */
+ 
+ #define mtime_older(t1,t2)	(mod_time_differs(t1,t2) < 0)
+ 
+ #else  /* !MSDOS */
+ 
+ #define mtime_older(t1,t2)	((t1) < (t2))
+ 
+ #endif /* !MSDOS */
  
  #include <pathmax.h>
  
diff -cp -r test/tar-1.12/src/tar.c tar-1.12/src/tar.c
*** test/tar-1.12/src/tar.c	Fri Apr 25 20:09:48 1997
--- tar-1.12/src/tar.c	Fri Oct 10 20:40:00 1997
*************** Local file selection:\n\
*** 390,396 ****
    -l, --one-file-system        stay in local file system when creating archive\n\
    -K, --starting-file=NAME     begin at file NAME in the archive\n"),
  	     stdout);
! #if !MSDOS
        fputs (_("\
    -N, --newer=DATE             only store files newer than DATE\n\
        --newer-mtime            compare date and time when data changed only\n\
--- 390,396 ----
    -l, --one-file-system        stay in local file system when creating archive\n\
    -K, --starting-file=NAME     begin at file NAME in the archive\n"),
  	     stdout);
! #if !MSDOS || defined (__DJGPP__)
        fputs (_("\
    -N, --newer=DATE             only store files newer than DATE\n\
        --newer-mtime            compare date and time when data changed only\n\
*************** set_use_compress_program_option (const c
*** 470,475 ****
--- 470,486 ----
    use_compress_program_option = string;
  }
  
+ #ifdef __DJGPP__
+ static char orig_dir[PATH_MAX];
+ 
+ static void
+ restore_orig_dir (void)
+ {
+   if (orig_dir[0])
+     chdir (orig_dir);
+ }
+ #endif
+ 
  static void
  decode_options (int argc, char *const *argv)
  {
*************** decode_options (int argc, char *const *a
*** 605,611 ****
--- 616,649 ----
  
        case 'C':
  	name_add ("-C");
+ #ifdef __DJGPP__
+ 	{
+ 	  char new_arg[PATH_MAX];
+ 
+ 	  /* This is DJGPP-specific.  It canonicalizes the file name,
+ 	     mirrors all the backslashes and downcases as appropriate.
+ 	     It is needed because code that handles the argument to -C
+ 	     doesn't work with backslashes.  */
+ 	  _fixpath (optarg, new_arg);
+ 	  name_add (new_arg);
+ 	}
+ 	/* We are going to chdir, and cwd is a global notion on MSDOS.
+ 	   Remember the original directory, to be restored at exit.
+ 
+ 	   Note that this isn't a DJGPP-specific problem, but only DJGPP's
+ 	   `chdir' can change the drive as well, so the code which changes
+ 	   the directory and restores it at exit won't work for others.  */
+ 	if (!orig_dir[0])
+ 	  {
+ 	    char *cwd = getcwd (0, PATH_MAX);
+ 	    if (!cwd)
+ 	      FATAL_ERROR ((0, 0, _("Could not get current directory")));
+ 	    strcpy (orig_dir, cwd);
+ 	    atexit (restore_orig_dir);
+ 	  }
+ #else
  	name_add (optarg);
+ #endif
  	break;
  
        case 'd':
*************** decode_options (int argc, char *const *a
*** 620,625 ****
--- 658,674 ----
  	      xrealloc (archive_name_array,
  			sizeof (const char *) * allocated_archive_names);
  	  }
+ #if MSDOS
+ 	/* Need to mirror the backslashes, some of the rest of
+ 	   the code cannot cope with DOS-style file names.  */
+ 	{
+ 	  char *p;
+ 
+ 	  for (p = optarg; *p; p++)
+ 	    if (*p == '\\')
+ 	      *p = '/';
+ 	}
+ #endif
  	archive_name_array[archive_names++] = optarg;
  	break;
  
*************** decode_options (int argc, char *const *a
*** 697,703 ****
  	multi_volume_option = 1;
  	break;
  
! #if !MSDOS
        case 'N':
  	after_date_option = 1;
  	/* Fall through.  */
--- 746,756 ----
  	multi_volume_option = 1;
  	break;
  
! 	/* It is beyond me why this shouldn't work on MSDOS.  When
! 	   DJGPP-compiled tar runs on Windows 9X, it even supports
! 	   both ctime and mtime fields.  But if some non-DJGPP MSDOS
! 	   compiler wants to disable this support, let them have it.  */
! #if !MSDOS || defined (__DJGPP__)
        case 'N':
  	after_date_option = 1;
  	/* Fall through.  */
*************** decode_options (int argc, char *const *a
*** 711,717 ****
  	  USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg));
  
  	break;
! #endif /* not MSDOS */
  
        case 'o':
  	if (archive_format == DEFAULT_FORMAT)
--- 764,770 ----
  	  USAGE_ERROR ((0, 0, _("Invalid date format `%s'"), optarg));
  
  	break;
! #endif /* not MSDOS || __DJGPP__ */
  
        case 'o':
  	if (archive_format == DEFAULT_FORMAT)
*************** decode_options (int argc, char *const *a
*** 748,754 ****
  	/* Print block numbers for debugging bad tar archives.  */
  
  	/* It would surely make sense to exchange -B and -R, but it seems
! 	   that -B has been used for a long while in Sun tar ans most
  	   BSD-derived systems.  This is a consequence of the block/record
  	   terminology confusion.  */
  
--- 801,807 ----
  	/* Print block numbers for debugging bad tar archives.  */
  
  	/* It would surely make sense to exchange -B and -R, but it seems
! 	   that -B has been used for a long while in Sun tar and most
  	   BSD-derived systems.  This is a consequence of the block/record
  	   terminology confusion.  */
  
*************** decode_options (int argc, char *const *a
*** 808,818 ****
--- 861,889 ----
  	break;
  
        case 'z':
+ #if MSDOS
+ 	/* Using explicit .exe suffix is a Good Thing for two reasons:
+ 
+ 	   1. If their shell is COMMAND.COM, it will NOT be called if
+ 	      they don't have gzip installed, and thus they get better
+ 	      diagnostics (COMMAND.COM returns 0 status even if it
+ 	      fails to invoke gzip).
+ 
+ 	   2. When we run the test suite, the `gzip.sh' script won't be
+ 	      invoked by DJGPP's too smart `popen' which tries all known
+ 	      executable suffixes, including .sh, in every directory.  */
+ 	set_use_compress_program_option ("gzip.exe");
+ #else
  	set_use_compress_program_option ("gzip");
+ #endif
  	break;
  
        case 'Z':
+ #if MSDOS
+ 	set_use_compress_program_option ("compress.exe");
+ #else
  	set_use_compress_program_option ("compress");
+ #endif
  	break;
  
        case OBSOLETE_VERSION_CONTROL:
*************** decode_options (int argc, char *const *a
*** 836,842 ****
  
        case GROUP_OPTION:
  	if (!gname_to_gid (optarg, &group_option))
! 	  if (!check_decimal (optarg) >= 0)
  	    ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option")));
  	  else
  	    group_option = check_decimal (optarg);
--- 907,913 ----
  
        case GROUP_OPTION:
  	if (!gname_to_gid (optarg, &group_option))
! 	  if (!(check_decimal (optarg) >= 0))
  	    ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option")));
  	  else
  	    group_option = check_decimal (optarg);
*************** decode_options (int argc, char *const *a
*** 862,868 ****
  
        case OWNER_OPTION:
  	if (!uname_to_uid (optarg, &owner_option))
! 	  if (!check_decimal (optarg) >= 0)
  	    ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option")));
  	  else
  	    owner_option = check_decimal (optarg);
--- 933,939 ----
  
        case OWNER_OPTION:
  	if (!uname_to_uid (optarg, &owner_option))
! 	  if (!(check_decimal (optarg) >= 0))
  	    ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option")));
  	  else
  	    owner_option = check_decimal (optarg);
*************** int
*** 1111,1116 ****
--- 1182,1209 ----
  main (int argc, char *const *argv)
  {
    program_name = argv[0];
+ #if MSDOS
+   /* The test suite needs the program_name to be just "tar".  Not nice!
+ 
+      We need to find the basename and drop the .exe suffix, if any;
+      any other solution could fail, since there are too many different
+      shells on MS-DOS.  (Does this really work with every Unix shell?)  */
+   {
+     char *p = (char *)program_name, *b = p, *e = p;
+ 
+     for ( ; *p; p++)
+       {
+ 	if (*p == '/' || *p == '\\' || *p == ':')
+ 	  b = p + 1;
+ 	else if (*p == '.')
+ 	  e = p + 1;
+       }
+     program_name = b;
+     if (e > b && tolower (*e) == 'e'
+ 	&& tolower (e[1]) == 'x' && tolower (e[2]) == 'e')
+       e[-1] = '\0';
+   }
+ #endif
    setlocale (LC_ALL, "");
    bindtextdomain (PACKAGE, LOCALEDIR);
    textdomain (PACKAGE);
diff -cp -r test/tar-1.12/src/update.c tar-1.12/src/update.c
*** test/tar-1.12/src/update.c	Sat Apr 19 22:44:12 1997
--- tar-1.12/src/update.c	Sat Oct  4 17:14:22 1997
*************** append_file (char *path)
*** 48,53 ****
--- 48,54 ----
    int handle;
    struct stat stat_data;
    long bytes_left;
+   int blocks_with_zeroes = 0;
  
    if (stat (path, &stat_data) != 0
        || (handle = open (path, O_RDONLY | O_BINARY), handle < 0))
*************** update_archive (void)
*** 129,135 ****
  		decode_header (current_header, &current_stat, &unused, 0);
  		if (stat (current_file_name, &stat_data) < 0)
  		  ERROR ((0, errno, _("Cannot stat %s"), current_file_name));
! 		else if (current_stat.st_mtime >= stat_data.st_mtime)
  		  name->found = 1;
  	      }
  	    set_next_block_after (current_header);
--- 130,137 ----
  		decode_header (current_header, &current_stat, &unused, 0);
  		if (stat (current_file_name, &stat_data) < 0)
  		  ERROR ((0, errno, _("Cannot stat %s"), current_file_name));
! 		else if (!mtime_older (current_stat.st_mtime,
! 				       stat_data.st_mtime))
  		  name->found = 1;
  	      }
  	    set_next_block_after (current_header);
diff -cp -r test/tar-1.12/tests/preset.i~ tar-1.12/tests/preset.in
*** test/tar-1.12/tests/preset.i~0	Tue Apr 22 22:17:00 1997
--- tar-1.12/tests/preset.in	Fri Oct 17 17:03:26 1997
***************
*** 15,17 ****
--- 15,20 ----
  LANG=
  export LC_MESSAGES
  LC_MESSAGES=
+ 
+ tmp_id=$$
+ export tmp_id
diff -cp -r test/tar-1.12/tests/after tar-1.12/tests/after
*** test/tar-1.12/tests/after	Thu Apr 24 23:33:58 1997
--- tar-1.12/tests/after	Thu Oct  2 19:28:46 1997
***************
*** 4,9 ****
  cd ..
  exec 1> /dev/null
  exec 2> /dev/null
! echo $echo_n "$out$echo_c" | cmp -s - tmp-$$/stdout || exit 1
! echo $echo_n "$err$echo_c" | cmp -s - tmp-$$/stderr || exit 1
! rm -rf tmp-$$
--- 4,9 ----
  cd ..
  exec 1> /dev/null
  exec 2> /dev/null
! echo $echo_n "$out$echo_c" | cmp -s - tmp$tmp_id/stdout || exit 1
! echo $echo_n "$err$echo_c" | cmp -s - tmp$tmp_id/stderr || exit 1
! rm -rf tmp$tmp_id
diff -cp -r test/tar-1.12/tests/before tar-1.12/tests/before
*** test/tar-1.12/tests/before	Fri Nov 22 17:39:54 1996
--- tar-1.12/tests/before	Thu Oct  2 19:28:24 1997
***************
*** 1,8 ****
  #! /bin/sh
  # Do common operations before a particular test.
  
! mkdir tmp-$$
! cd tmp-$$
  
  case $srcdir in
    /*|~*) ;;
--- 1,8 ----
  #! /bin/sh
  # Do common operations before a particular test.
  
! mkdir tmp$tmp_id
! cd tmp$tmp_id
  
  case $srcdir in
    /*|~*) ;;
diff -cp -r test/tar-1.12/tests/extrac02.sh tar-1.12/tests/extrac02.sh
*** test/tar-1.12/tests/extrac02.sh	Wed Jan 22 00:53:34 1997
--- tar-1.12/tests/extrac02.sh	Thu Oct  2 18:01:54 1997
***************
*** 6,12 ****
  
  set -e
  touch file
! ln -s file link 2> /dev/null || ln file link
  tar cf archive link
  rm link
  touch link
--- 6,12 ----
  
  set -e
  touch file
! ln file link
  tar cf archive link
  rm link
  touch link
diff -cp -r test/tar-1.12/tests/incremen.sh tar-1.12/tests/incremen.sh
*** test/tar-1.12/tests/incremen.sh	Fri Nov 22 19:58:28 1996
--- tar-1.12/tests/incremen.sh	Thu Oct  2 19:11:52 1997
*************** sleep 1
*** 12,17 ****
--- 12,18 ----
  tar cf archive --listed=list structure
  tar cfv archive --listed=list structure
  echo -----
+ sleep 2
  touch structure/file
  tar cfv archive --listed=list structure
  
*** /dev/null	Fri Oct 17 18:35:39 1997
--- djgpp/README.dos	Fri Oct 17 18:33:12 1997
***************
*** 0 ****
--- 1,308 ----
+     A port of GNU Tar 1.12 to MS-DOS/MS-Windows using DJGPP tools
+     =============================================================
+ 
+ Features
+ --------
+ 
+   This port of GNU Tar includes significant improvements as compared
+ to the official FSF distribution of version 1.12.  The official code
+ was failing in a lot of ways on MS-DOS (my favorite is that commands
+ like "tar cf d:/foo.tar" would fail because `tar' treated file names
+ with a colon as archives on remote machines and was trying to connect
+ to a machine called `d').  I believe that all the features in the
+ original Unix code work in this DOS port; the single most important
+ exception is the lack of support for remote archives (see the
+ "Missing" section below).
+ 
+ Here's the list of bug fixes and enhancements in this port:
+ 
+   1.  Compressed archives are now fully supported (yeah!).  All the
+       options which support compressed archives in the Unix version,
+       work on MS-DOS.  Compressed archives are produced by piping the
+       output of `tar' to or from `gzip', so it is a bit slow, since
+       DOS simulates pipes via disk files.  If you have a fast,
+       memory-abundant machine, point your TMPDIR to a large RAM drive,
+       which will greatly speed up compressed archive operations.
+ 
+   2.  Backup files are fully supported, including numbered backups,
+       even on plain MS-DOS and other non-LFN platforms.  You should
+       always unpack .tar.gz files of Unix origin with numbered backups
+       turned on, since file name collisions in the restricted 8+3 DOS
+       namespace might otherwise overwrite files (unlike `djtar', `tar'
+       will not prompt you to supply an alternate name).
+ 
+   3.  Automatic renaming of file names which are illegal on DOS.  When
+       extracting files, `tar' will automatically attempt to rename
+       file names such as `Makefile.in.in', `.emacs', `foo:bar;baz,'
+       and others.  Note that even Windows 9X disallows some characters
+       from appearing in a file name; this port correctly identifies
+       the set of characters which need to be replaced, depending on
+       whether long file names are or aren't available on the
+       filesystem where the file is being extracted.  The algorithm for
+       generating converted names is almost identical to what `djtar'
+       does, except that `tar' doesn't prompt you for another name when
+       it fails to extract a file.  Under verbose operation, `tar'
+       prints a message about renamed files.
+ 
+   4.  Similarly, any file in the archive whose name is reserved on
+       MS-DOS by a character device driver (e.g., `prn.txt', `aux.c',
+       `nul.foo' etc.), is automatically renamed.  This prevents
+       wedging `tar' and/or your system when unpacking Unix archives
+       with such files.  Tar renames such files by prepending a `_' to
+       their basename.
+ 
+   5.  Extraction of hard and symbolic links are simulated by copying
+       files.  The --diff (-d) mode compares the contents of two files
+       in this case.
+ 
+   6.  Full support of DOS absolute file names with drive letters (the
+       original code won't even work on tar file names like
+       `d:/foo/bar.tar').  Numerous snafus with root directories on
+       other drives and other such subtleties were resolved.  Tar now
+       supports backslashes in file names (but they are converted into
+       forward slashes before accessing the archives).
+ 
+   7.  Using -O option when `tar's stdout is redirected to a file would
+       corrupt binary files.  This is corrected in this port.
+ 
+   8.  When given the -C option, `tar' now correctly restores the
+       original directory before it exits.
+ 
+   9.  The -N and --newer-mtime options now work.  (They were disabled
+       in the DOS version for reasons that are beyond me.)  All the
+       time comparisons, including for -N, --newer-mtime and --diff,
+       now compare time stamps with a 2-second granularity, so you
+       won't see false "Mod times differ" messages due to DOS rounding
+       of file times to the nearest even second.
+ 
+   10. When --verify (-W) option is given, `tar' will flush the disk
+       cache, if one is installed.  This prevents some overly smart
+       caches from supplying disk data from memory, instead of
+       accessing the media, thus defeating the very goal of verifying.
+ 
+   11. The manual has been revised, most of the missing cross-
+       references fixed, and DOS-specific information added.  The
+       manual is under construction by the GNU project, and, IMHO,
+       still looks like a car crash (e.g., many subjects are described
+       twice, evidently from two different versions of the manual).
+       But I really couldn't afford rewriting the manual.  What's there
+       should be good enough, I think; if it's not, submit bug reports
+       to the GNU package maintainer.
+ 
+   12. The --recursive-unlink option now really works.  (This was
+       actually a genuine bug in the official release which is NOT
+       specific to DOS.)
+ 
+   13. You can use --group and --owner options to give files away to
+       any user and any group.  Thus you can create archives on DOS
+       with files that would be writable by specific users on Unix.
+       (The official code had a bug whereby numeric GIDs and UIDs would
+       not work, even on Unix; this is corrected in this port.)
+ 
+   14. The feature of the Unix code whereby `tar' will not dump the
+       archive it is creating into itself, works in this port.  (Due to
+       the peculiarities of inode number simulation in the DJGPP
+       library, this will NOT work on Windows 9X, Windows 3.11 with
+       32-bit File Access, and on networked drives.)
+ 
+   15. This port supports the optimization in cases that `tar's output
+       is meant for the NUL device.  This makes `tar' much faster in
+       these cases.
+ 
+   16. `Tar' will no more switch the console to binary mode.  It only
+       switches stdin and stdout to binary mode when they are
+       redirected to a file, and then only when `tar' reads or writes
+       the archive to one of these streams.  (Switching the console to
+       binary mode has unpleasant side-effects.  For example, it
+       disables SIGINT generation when you press Ctrl-C, so you cannot
+       interrupt a runaway `tar'.)  The original code also had a bug
+       with invoking a subsidiary shell when switching volumes in a
+       multi-volume tar file; this is now corrected.
+ 
+   17. All the scripts in the test suite work, except the `ignfail.sh'
+       test.  The latter will never work because it deals with file
+       permission bits which are impossible on MS-DOS (e.g.,
+       non-readable directories or files non-writeable by the owner).
+ 
+ 
+ Missing
+ -------
+ 
+   The following (short) list explains what functions are missing from
+ this port:
+ 
+   1.  Direct device access.
+ 
+       It would be nice to be able to say "tar cvf /dev/fd0 c:/" and
+       have an archive created on a floppy drive A: such that it could
+       be taken to a Unix box and untarred without mounting it as a DOS
+       filesystem.  At least for floppies with the most popular formats
+       (1.2M and 1.44M) this shouldn't be too hard; one just have to
+       use the DJGPP Filesystem Extensions feature to hook the
+       low-level I/O functions and read/write the diskette on the BIOS
+       level.  Any takers?
+ 
+   2.  Remote archive support.
+ 
+       The code in rtapelib.c which opens a pipe to `/etc/rsh', should
+       be tweaked to work on DOS.
+ 
+   3.  Internal compression/decompression.
+ 
+       Linking `tar' with parts of `gzip' code should make compressed
+       archive operations MUCH faster.  `djtar' already does that, but
+       it cannot create archives.
+ 
+ 
+ Installation the of pre-compiled binary distribution
+ ----------------------------------------------------
+ 
+   1. Go to the root of your DJGPP installation.  Assuming that DJGPP
+      is installed in C:\DJGPP:
+ 
+ 		  c:
+ 		  cd c:\djgpp
+ 
+      If you don't have DJGPP installed, you can do this from any
+      directory on your disk, but you will need to ensure that:
+ 
+ 	* You have DPMI services available.  This port was compiled
+           with DJGPP and will not run unless a DPMI server is
+           installed.  If you get an error message saying "No DPMI",
+           get a free DPMI server csdpmiNb.zip (N is the version
+           number) from the sibling v2misc directory of the same site
+           where you got this Tar distribution.
+ 
+ 	* After unzipping the distribution, you will need to move the
+           file tar.exe to a directory on your PATH.
+ 
+ 	* To read the on-line docs, you will need an Info reader.  A
+           stand-alone info.exe should be available in txiNNNb.zip (NNN
+           is a version number) from the same place where you got this
+           port of Tar.
+ 
+   2. Unzip the binary distribution preserving directory structure.
+      With PKUNZIP, type this:
+ 
+ 		  pkunzip -d tar112b
+ 
+      With InfoZip's UNZip, type this:
+ 
+ 		  unzip tar112b
+ 
+      If you are installing on Windows 9X, be sure to use an unzip
+      program that supports long file names!
+ 
+   3. Edit your main Info menu on the `info/dir' file, and add the
+      following item:
+ 
+ 	* Tar: (tar).		Making tape (or disk) archives.
+ 
+      (The asterisk which begins this line should be flushed to the
+      leftmost column of the file.)
+ 
+   4. Compressed archive (.tar.gz and .tar.Z) support requires an
+      external `gzip' (GNU Zip) program, or its close work-alike.  A
+      DJGPP port of `gzip' should be available in the gzpNNNb.zip
+      distribution from the same place where you got this Tar port.
+ 
+   5. WARNING!!!  Working with large compressed archives needs a lot of
+      temporary free disk space, since `tar' invokes `gzip' via a pipe,
+      which on MS-DOS is simulated with a disk file.  If you set the
+      TMPDIR environment variable to a RAM disk, make sure you have
+      enough space there for the uncompressed archive.  (For unpacking
+      .tar.gz files, the size of uncompressed archive can be estimated
+      by multiplying the compressed size by 4.)  When in doubt, point
+      TMPDIR to your hard drive before invoking `tar'.  If there's not
+      enough space on the drive where TMPDIR points, `tar' will
+      complain about unexpected end-of-file (depending on whether you
+      are creating or extracting files, the message might actually come
+      from `gzip').
+ 
+   6. GNU `tar' is a large and extremely complex program.  The same
+      multitude of options that makes it so powerful, also makes its
+      testing harder.  While testing this port, I made a point of using
+      every option and some popular combinations of different options;
+      that is how many bugs were found and corrected.  Still, other
+      bugs are probably lurking undetected.  If you find any of them,
+      please report them.  Bugs specific to MS-DOS should be posted to
+      the comp.os.msdos.djgpp news group first; otherwise, use the
+      address printed by "tar --help", at the end of the help screen.
+      The file DIFFS in the source distribution shows the source-level
+      changes agains the original GNU sources, in case you need to see
+      what I broke.
+ 
+ 
+ 
+ Building `tar' from sources
+ ---------------------------
+ 
+   First, unzip the binary distribution preserving directory structure.
+   With PKUNZIP, type this:
+ 
+ 		pkunzip -d tar112s
+ 
+   With InfoZip's UNZip, type this:
+ 
+ 		unzip tar112s
+ 
+   If you are building on Windows 9X, be sure to use an unzip program
+   that supports long file names!
+ 
+   The source distribution comes already configured for DJGPP, so you
+   only need to run Make.  For this to work, you will need the
+   following tools:
+ 
+ 	- The basic DJGPP development environment (GCC, Binutils and
+           djdev distributions);
+ 
+ 	- DJGPP port of GNU Make 3.75 or later;
+ 
+ 	- DJGPP port of Bash;
+ 
+ 	- GNU Sed;
+ 
+ 	- `rm' from GNU Fileutils.
+ 
+   To build `tar', make sure all the above are installed, then type
+   "make" and press [Enter].  This will produce tar.exe in the src
+   subdirectory.
+ 
+   To test the package, say "make check".  Running the test suite
+   requires the following tools, in addition to those listed above:
+ 
+ 	- `cp', `mkdir', `ln' and `touch' from Fileutils;
+ 
+ 	- `sleep' from GNU Sh-utils;
+ 
+ 	- `cat' from GNU Textutils;
+ 
+ 	- `cmp' from GNU Diffutils.
+ 
+   All of these are available from the usual DJGPP archives.
+ 
+   All of the tests should pass; they did for me.  The only test that
+   sometimes fails on fast machines is incremen.sh; if it fails for
+   you, simply run it a few more times, and it will succeed.  I believe
+   these failures are due to the 2-second granularity of DOS file
+   timestamps.  (The original test suite includes a script called
+   `ignfail.sh' that cannot work on MS-DOS, so the DJGPP configuration
+   script edits it out of the list of tests that tests/Makefile runs.)
+ 
+   Typing "make install" will install the program and the docs in the
+   relevant directories; you will need the `ginstall' program (from
+   Fileutils).  Alternatively, install the files by hand.
+ 
+   If you need to reconfigure `tar', you will need to install many
+   other GNU utilities.  I cannot be bothered to list them all here;
+   your best bet is to install all of the following: Fileutils,
+   Textutils, Sh-utils, Diffutils, Gawk, Sed, Findutils, and of course
+   Bash.  Then configure the package with the following command:
+ 
+ 	      djgpp\config
+ 
+   This sets up some environment variables, then runs the ./configure
+   script.  When it is done, run "make" as above.
+ 
+ 
+ 				Eli Zaretskii <eliz@is.elta.co.il>
*** /dev/null	Fri Oct 17 18:35:51 1997
--- djgpp/config.bat	Fri Oct 17 16:43:58 1997
***************
*** 0 ****
--- 1,28 ----
+ @echo off
+ echo Configuring GNU Tar for DJGPP v2.x...
+ 
+ Rem Update configuration files
+ echo Updating configuration scripts...
+ if not exist configure.orig update configure configure.orig
+ update djgpp/configure ./configure
+ 
+ Rem `configure' won't run correctly without these variables
+ set PATH_SEPARATOR=:
+ if not "%PATH_SEPARATOR%" == ":" goto SmallEnv
+ set PATH_EXPAND=y
+ if not "%PATH_EXPAND%" == "y" goto SmallEnv
+ set INSTALL=${DJDIR}/bin/ginstall -c
+ if not "%INSTALL%" == "${DJDIR}/bin/ginstall -c" goto SmallEnv
+ 
+ echo Running ./configure...
+ sh ./configure --host=i386-pc-msdosdjgpp --disable-nls
+ 
+ echo Done.
+ goto End
+ 
+ Rem Protect them against too small environment size
+ :SmallEnv
+ echo Your environment size is too small.  Enlarge it and run me again.
+ 
+ :End
+ set INSTALL=
*** test/tar-1.12/doc/ChangeLog	Fri Apr 25 20:26:58 1997
--- tar-1.12/doc/ChangeLog	Fri Oct 17 19:24:56 1997
***************
*** 1,3 ****
--- 1,8 ----
+ 1997-10-17  Eli Zaretskii  <eliz@is.elta.co.il>
+ 
+ 	* tar.texi: Fix missing cross-references.  Add DOS-specific info.
+ 	Fix typos.
+ 
  1997-04-23  Franois Pinard  <pinard@iro.umontreal.ca>
  
  	* Release 1.12.
*** test/tar-1.12/lib/ChangeLog	Fri Apr 25 20:34:50 1997
--- tar-1.12/lib/ChangeLog	Fri Oct 17 19:32:30 1997
***************
*** 1,3 ****
--- 1,16 ----
+ 1997-10-17  Eli Zaretskii  <eliz@is.elta.co.il>
+ 
+ 	* fileblocks.c [__DJGPP__]: Add missing typedef for daddr_t.
+ 
+ 	* dirname.c (dirname): Support for DOS-style file names with drive
+ 	letters.
+ 
+ 	* backupfile.c (find_backup_file_name): Support for numbered
+ 	backups on MS-DOS and Windows 9X.  Support DOS-style absolute file
+ 	names with drive letters.
+ 	(max_backup_version, make_version_name, version_number, concat):
+ 	Support for numbered backups with 8+3 file names.
+ 
  1997-04-25  Franois Pinard  <pinard@iro.umontreal.ca>
  
  	* Release 1.12.
*** test/tar-1.12/src/ChangeLog	Fri Apr 25 20:32:48 1997
--- tar-1.12/src/ChangeLog	Fri Oct 17 21:16:36 1997
***************
*** 1,3 ****
--- 1,141 ----
+ 1997-10-17  Eli Zaretskii  <eliz@is.elta.co.il>
+ 
+ 	* update.c (update_archive): Call `mtime_older' instead of
+ 	comparing time stamps directly, to support 2-sec granularity in
+ 	DOS file times.
+ 
+ 	* tar.c (usage) [__DJGPP__]: Advertise -N and --newer-mtime.
+ 	(restore_orig_dir) [__DJGPP__]: New function, called at exit to
+ 	restore original working directory when -C option was given.
+ 	(decode_options): Fix bug in testing the return value of
+ 	`check_decimal' which prevented --group and --owner options from
+ 	working with numeric UIDs and GIDs.
+ 	[__DJGPP__]: Convert the argument to -C to Unix-style forward
+ 	slashes and make default directories in "d:foo" pathnames
+ 	explicit.  Remember original working directory to restore it at
+ 	exit.  Arrange for `restore_orig_dir' to be called at exit.
+ 	Enable -N and --newer-mtime options.
+ 	[MSDOS]: Mirror any backslashes in file names to forward slashes.
+ 	Use explicit .exe suffixes in names of `gzip' and `compress'
+ 	programs.
+ 	(main) [MSDOS]: Remove the directories from argv[0] and drop the
+ 	.exe suffix, so the test suite works.
+ 
+ 	* system.h (S_ISUID, S_ISGID, S_ISVTX) [MSDOS]: Define them only
+ 	if they aren't already undefined by system headers.
+ 	(major, minor, makedev) [__DJGPP__]: Don't define.
+ 	Include <time.h>.
+ 	(mtime_older): New macro, on MS-DOS call `mod_time_differs'; on
+ 	Unix compares arguments directly (to support 2-sec granularity in
+ 	DOS file timestamps).
+ 
+ 	* rtapelib.c (EOPNOTSUPP): Remove definition.
+ 
+ 	* rmt.h (_remdev) [MSDOS]: Don't treat "d:/foo/bar" as remote file
+ 	specification.
+ 	(__REM_BIAS) [__DJGPP__]: Make the bias be 256 for DJGPP.
+ 	(EOPNOTSUPP): Define to ENOSYS where that is defined, or EINVAL if
+ 	ENOSYS is undefined.
+ 
+ 	* names.c (uid_to_uname) [MSDOS]: Allow to give away files to any
+ 	group, by faking missing user names.
+ 	(gid_to_gname) [MSDOS]: Allow to give away files to any group, by
+ 	faking missing group names.
+ 	(uname_to_uid) [MSDOS]: Allow to give away files to any user, by
+ 	faking missing UIDs.  Return failure for purely-numeric UID, so it
+ 	will be treated as numeric UID (on `tar.c').
+ 	(gname_to_gid) [MSDOS]: Allow to give away files to any group, by
+ 	faking missing GIDs.  Return failure for purely-numeric GID, so it
+ 	will be treated as numeric GID (on `tar.c').
+ 	(name_next) [MSDOS]: Mirror DOS-style backslashes into UNix-style
+ 	forward slashes.  Don't zap trailing slash in root directories
+ 	given with a drive letter "d:/".
+ 	(addname) [MSDOS]: Support DOS-style file names with drive
+ 	letters.
+ 
+ 	* misc.c (remove_any_file): Fix the loop which recursively empties
+ 	a directory.
+ 	(maybe_backup_file) [MSDOS]: Don't back up non-regular files.
+ 
+ 	* list.c (read_and): Call `mtime_older' instead of comparing
+ 	st_mtime directly, to suport DOS 2-sec time granularity in file
+ 	times.
+ 
+ 	* incremen.c (get_directory_contents): Use `mtime_older'.
+ 	(read_directory_file) [MSDOS]: Support --listed-incremental when
+ 	the listfile has DOS drive letter in its name.
+ 
+ 	* extract.c (make_directories) [MSDOS]: Avoid making root
+ 	directory on any drive.
+ 	(msdosify) [MSDOS]: New function, attempts to rename a file which
+ 	couldn't be extracted due to characters which are illegal in DOS
+ 	file names.
+ 	[__DJGPP__]: Support smaller set of illegal characters on
+ 	MS-Windows 9X.
+ 	(maybe_recoverable) [MSDOS]: Call `msdosify' when extraction
+ 	fails, but only once for each file.  Print a message about renamed
+ 	files when under verbose operation.
+ 	(rename_if_dos_device_name) [MSDOS]: New function, renames files
+ 	whose names are reserved by DOS character device drivers.
+ 	(extract_archive): Call `remove_any_file' when --recursive-unlink
+ 	option is in effect.
+ 	[MSDOS]: Call `rename_if_dos_device_name'.  Skip DOS drive letter
+ 	in absolute file names.  Write redirected stdout in binary mode.
+ 	Don't check inodes for simulated links.  Don't zap trailing slash
+ 	in DOS root directories given as "d:/".  Don't panic if we get
+ 	EACCES when trying to create an existing directory.
+ 
+ 	* create.c [__DJGPP__]: Include <pwd.h> and <grp.h>.  Declare
+ 	ar_dev and ar_ino.
+ 	(start_header) [MSDOS]: Make it so tar warns about removal of both
+ 	drive letter (if present) and the leading slash from absolute file
+ 	names.
+ 	(dump_file): Use `mtime_older' to decide whether a file is
+ 	eligible to put into the archive.
+ 	[__DJGPP__]: Avoid dumping the archive into itself.
+ 
+ 	* compare.c (get_stat_data) [__DJGPP__]: Set st_rdev to st_dev.
+ 	(diff_two_files) [MSDOS]: New function, used on MS-DOS to compare
+ 	with links which are simulatd by copying files.
+ 	(mode_bits_differ): New function on MS-DOS, macro for Unix;
+ 	compares mode bits for equality.  On MS-DOS, only compares bits
+ 	that are stored by the filesystem.
+ 	(uid_differs, gid_differs): New macros, compare UIDs and GIDs.  On
+ 	MS-DOS ignore arguments and return 0.
+ 	(mod_time_differs): New function on MS-DOS, macro on Unix; returns
+ 	-1, 0 or 1 if the timestamp of the first argument is respectively
+ 	older, equal or later than that of the second.  On MS-DOS the
+ 	comparisons are up to 2-sec granularity.
+ 	(diff_archive): Use the new functions/macros for comparing mode
+ 	bits, UIDs, GIDs and file times.  Use O_BINARY to open file
+ 	compared with the archive.  
+ 	[MSDOS]: Support --diff for simulated links.  Adjust messages'
+ 	text to the links simulation by copying.  Don't compare inodes of
+ 	the links, since they always differ on MS-DOS.
+ 	(verify_volume) [__DJGPP__]: Attempt to flush any disk caches, to
+ 	force the OS to actually read the tar media.
+ 
+ 	* buffer.c [MSDOS]: Declare ar_dev and ar_ino for DJGPP.
+ 	(child_open_for_compress, child_open_for_uncompress) [MSDOS]:
+ 	Support for compressed archives on MS-DOS and MS-Windows.
+ 	(open_archive): Make sure we don't get handles for local files
+ 	which are larger than 128 (and thus deemed to be remote).  Use
+ 	`rmtfstat' instead of `fstat'.
+ 	[__DJGPP__]: Write something to the archive and fsync the handle,
+ 	to make sure the archive won't be dumped into itself.  Look at
+ 	st_ino when comparing to `stat' results from "/dev/null".
+ 	[MSDOS]: Don't switch console device to binary mode.
+ 	(flush_write, flush_read) [MSDOS]: Test the drive letter before
+ 	deciding that `d' in "d:/foo" is a drive.
+ 	(close_archive) [MSDOS]: Use `ftruncate' for DJGPP.  Support
+ 	compressed archives.
+ 	(new_volume) [MSDOS]: Don't close archive if it's stdin or stdout.
+ 	(new_volume) [MSDOS]: Save standard streams when spawning the
+ 	child shell, and restore them after it returns.  When the new
+ 	volume name is "-", use stdin/stdout.  Don't switch console device
+ 	to binary mode.
+ 	[__DJGPP__]: Use `system' instead of `spawnl'.
+ 
  1997-04-25  Franois Pinard  <pinard@iro.umontreal.ca>
  
  	* Release 1.12.
*** test/tar-1.12/tests/ChangeLog	Fri Apr 25 20:31:26 1997
--- tar-1.12/tests/ChangeLog	Fri Oct 17 21:30:20 1997
***************
*** 1,3 ****
--- 1,22 ----
+ 1997-10-17  Eli Zaretskii  <eliz@is.elta.co.il>
+ 
+ 	* incremen.sh: Sleep for 2 seconds, to cover for the DOS 2-sec
+ 	granularity in file timestamps.
+ 
+ 	* extrac02.sh: Don't use `ln -s', since MS-DOS doesn't support it.
+ 
+ 	* before: Use `tmp_id' instead of $$, and make sure the temporary
+ 	directory name is unique in the first 8 characters, to avoid
+ 	clashes on MS-DOS.
+ 
+ 	* after: Use `tmp_id' instead of $$, and make sure the temporary
+ 	directory name is unique in the first 8 characters, to avoid
+ 	clashes on MS-DOS.
+ 
+ 	* preset.in (tmp_id): Set in the parent shell, since DOS port of
+ 	Bash gets a new PID to every subshell which runs subsidiary
+ 	scripts.
+ 
  1997-04-25  Franois Pinard  <pinard@iro.umontreal.ca>
  
  	* Release 1.12.
*** test/tar-1.12/ChangeLog	Fri Apr 25 20:25:46 1997
--- tar-1.12/ChangeLog	Fri Oct 17 21:31:48 1997
***************
*** 1,3 ****
--- 1,8 ----
+ 1997-10-17  Eli Zaretskii  <eliz@is.elta.co.il>
+ 
+ 	* djgpp/README.dos, djgpp/config.bat: New files, support for
+ 	building tar with DJGPP tools for MS-DOS and MS-Windows.
+ 
  1997-04-25  Franois Pinard  <pinard@iro.umontreal.ca>
  
  	* Release 1.12.
