Imported Upstream version 2.17 upstream/2.17
authorBdale Garbee <bdale@gag.com>
Sun, 9 Mar 2014 20:20:37 +0000 (14:20 -0600)
committerBdale Garbee <bdale@gag.com>
Sun, 9 Mar 2014 20:20:37 +0000 (14:20 -0600)
41 files changed:
Makefile.in
NEWS
config.guess
config.sub
configure
configure.in
cpm.5
cpm.5.in
cpm.ps [new file with mode: 0644]
cpmchattr.1
cpmchattr.1.in
cpmchattr.c
cpmchmod.1
cpmchmod.1.in
cpmchmod.c
cpmcp.1
cpmcp.1.in
cpmcp.c
cpmfs.c
cpmfs.h
cpmls.1
cpmls.1.in
cpmls.c
cpmrm.1
cpmrm.1.in
cpmrm.c
device.h
device_libdsk.c
device_posix.c
device_win32.c
diskdefs
fsck.cpm.1
fsck.cpm.1.in
fsck.cpm.c
fsed.cpm.1
fsed.cpm.1.in
fsed.cpm.c
install-sh
mkfs.cpm.1
mkfs.cpm.1.in
mkfs.cpm.c

index 53059a07067ef76a5c225a77438357fa38e01eed..679f13d4561d9dedd2c19b0da773df2f49f4c4c8 100644 (file)
@@ -80,6 +80,8 @@ fsck.test:    fsck.cpm
                -./fsck.cpm -f pcw -n badfs/label
 
 install:       all
+               [ -d $(MANDIR)/man1 ] || $(INSTALL) -m 755 -d $(MANDIR)/man1
+               [ -d $(MANDIR)/man5 ] || $(INSTALL) -m 755 -d $(MANDIR)/man5
                $(INSTALL) -s -m 755 cpmls $(BINDIR)/cpmls
                $(INSTALL) -s -m 755 cpmcp $(BINDIR)/cpmcp
                $(INSTALL) -s -m 755 cpmrm $(BINDIR)/cpmrm
@@ -87,7 +89,7 @@ install:      all
                $(INSTALL) -s -m 755 cpmchattr $(BINDIR)/cpmchattr
                $(INSTALL) -s -m 755 mkfs.cpm $(BINDIR)/mkfs.cpm
                $(INSTALL) -s -m 755 fsck.cpm $(BINDIR)/fsck.cpm
-               [ $(FSED_CPM) != '' ] && $(INSTALL) -s -m 755 fsed.cpm $(BINDIR)/fsed.cpm
+               [ "$(FSED_CPM)" != '' ] && $(INSTALL) -s -m 755 fsed.cpm $(BINDIR)/fsed.cpm
                $(INSTALL_DATA) diskdefs @datarootdir@/diskdefs
                $(INSTALL_DATA) cpmls.1 $(MANDIR)/man1/cpmls.1
                $(INSTALL_DATA) cpmcp.1 $(MANDIR)/man1/cpmcp.1
diff --git a/NEWS b/NEWS
index fa404572dd8ef01b96b8beea95b61e0454b8e845..a98a886a52a15b3f026860ad0a7832d2672937bb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
-Changes since 2.13:
+Changes since 2.16:
 
-o  Avoid unneccessary directory writes
+o  Improved filesystem documentation
+o  Many new diskdefs
+o  device_win32.c fixed by Bill Buckels
index d53e309f4b981ea4a966e53a7133ca290cefd1f3..2852378467cace09473584342ae0246a5093a6fc 100755 (executable)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 #   Free Software Foundation, Inc.
 
-timestamp='2009-11-19'
+timestamp='2010-08-21'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -56,8 +56,9 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -91,7 +92,7 @@ if test $# != 0; then
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
+trap 'exit 1' HUP INT TERM
 
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
@@ -105,7 +106,7 @@ trap 'exit 1' 1 2 15
 
 set_cc_for_build='
 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ;
 : ${TMPDIR=/tmp} ;
  { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
  { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
@@ -333,6 +334,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
        echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+       echo i386-pc-auroraux${UNAME_RELEASE}
+       exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
        eval $set_cc_for_build
        SUN_ARCH="i386"
@@ -548,7 +552,7 @@ EOF
                echo rs6000-ibm-aix3.2
        fi
        exit ;;
-    *:AIX:*:[456])
+    *:AIX:*:[4567])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
        if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
                IBM_ARCH=rs6000
@@ -964,6 +968,9 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
+    tile*:Linux:*:*)
+       echo ${UNAME_MACHINE}-tilera-linux-gnu
+       exit ;;
     vax:Linux:*:*)
        echo ${UNAME_MACHINE}-dec-linux-gnu
        exit ;;
index 17c91458a8ac1d5236161b435cc0b2115a4f3d1c..320e30388119ffd5e8c81f85998f075e4f888fba 100755 (executable)
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 #   Free Software Foundation, Inc.
 
-timestamp='2009-11-07'
+timestamp='2010-09-11'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -75,8 +75,9 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -123,8 +124,9 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
@@ -281,6 +283,7 @@ case $basic_machine in
        | moxie \
        | mt \
        | msp430 \
+       | nds32 | nds32le | nds32be \
        | nios | nios2 \
        | ns16k | ns32k \
        | or32 \
@@ -294,7 +297,7 @@ case $basic_machine in
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
        | spu | strongarm \
-       | tahoe | thumb | tic4x | tic80 | tron \
+       | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
        | v850 | v850e \
        | we32k \
@@ -302,6 +305,15 @@ case $basic_machine in
        | z8k | z80)
                basic_machine=$basic_machine-unknown
                ;;
+       c54x)
+               basic_machine=tic54x-unknown
+               ;;
+       c55x)
+               basic_machine=tic55x-unknown
+               ;;
+       c6x)
+               basic_machine=tic6x-unknown
+               ;;
        m6811 | m68hc11 | m6812 | m68hc12 | picochip)
                # Motorola 68HC11/12.
                basic_machine=$basic_machine-unknown
@@ -333,7 +345,7 @@ case $basic_machine in
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
        | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* \
        | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
@@ -367,6 +379,7 @@ case $basic_machine in
        | mmix-* \
        | mt-* \
        | msp430-* \
+       | nds32-* | nds32le-* | nds32be-* \
        | nios-* | nios2-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | orion-* \
@@ -380,7 +393,8 @@ case $basic_machine in
        | sparclite-* \
        | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
        | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tile-* | tilegx-* \
        | tron-* \
        | ubicom32-* \
        | v850-* | v850e-* | vax-* \
@@ -480,6 +494,15 @@ case $basic_machine in
                basic_machine=powerpc-ibm
                os=-cnk
                ;;
+       c54x-*)
+               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c55x-*)
+               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c6x-*)
+               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        c90)
                basic_machine=c90-cray
                os=-unicos
@@ -839,6 +862,12 @@ case $basic_machine in
        np1)
                basic_machine=np1-gould
                ;;
+        neo-tandem)
+               basic_machine=neo-tandem
+               ;;
+        nse-tandem)
+               basic_machine=nse-tandem
+               ;;
        nsr-tandem)
                basic_machine=nsr-tandem
                ;;
@@ -1073,17 +1102,10 @@ case $basic_machine in
                basic_machine=t90-cray
                os=-unicos
                ;;
-       tic54x | c54x*)
-               basic_machine=tic54x-unknown
-               os=-coff
-               ;;
-       tic55x | c55x*)
-               basic_machine=tic55x-unknown
-               os=-coff
-               ;;
-       tic6x | c6x*)
-               basic_machine=tic6x-unknown
-               os=-coff
+        # This must be matched before tile*.
+        tilegx*)
+               basic_machine=tilegx-unknown
+               os=-linux-gnu
                ;;
        tile*)
                basic_machine=tile-unknown
@@ -1256,6 +1278,9 @@ case $os in
         # First match some system type aliases
         # that might get confused with valid system types.
        # -solaris* is a basic system type, with this one exception.
+        -auroraux)
+               os=-auroraux
+               ;;
        -solaris1 | -solaris1.*)
                os=`echo $os | sed -e 's|solaris1|sunos4|'`
                ;;
@@ -1277,8 +1302,8 @@ case $os in
        # -sysv* is not here because it comes later, after sysvr4.
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -kopensolaris* \
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+             | -sym* | -kopensolaris* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
              | -aos* | -aros* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
@@ -1291,7 +1316,8 @@ case $os in
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
              | -chorusos* | -chorusrdb* | -cegcc* \
              | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+             | -mingw32* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-uclibc* \
              | -uxpv* | -beos* | -mpeix* | -udk* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1432,6 +1458,8 @@ case $os in
        -dicos*)
                os=-dicos
                ;;
+        -nacl*)
+               ;;
        -none)
                ;;
        *)
@@ -1472,6 +1500,15 @@ case $basic_machine in
         c4x-* | tic4x-*)
                os=-coff
                ;;
+       tic54x-*)
+               os=-coff
+               ;;
+       tic55x-*)
+               os=-coff
+               ;;
+       tic6x-*)
+               os=-coff
+               ;;
        # This must come before the *-dec entry.
        pdp10-*)
                os=-tops20
index d8149b07ac3e20180f34e13871730c435a94f1fd..d4a7592e44a0b64903cb634271d81935bc6a76a7 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,11 +1,11 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65.
+# Generated by GNU Autoconf 2.68.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -89,6 +89,7 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -214,11 +215,18 @@ IFS=$as_save_IFS
   # We cannot yet assume a decent shell, so we have to provide a
        # neutralization value for shells without unset; and this also
        # works around shells that cannot unset nonexistent variables.
+       # Preserve -v and -x to the replacement shell.
        BASH_ENV=/dev/null
        ENV=/dev/null
        (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
        export CONFIG_SHELL
-       exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+       case $- in # ((((
+         *v*x* | *x*v* ) as_opts=-vx ;;
+         *v* ) as_opts=-v ;;
+         *x* ) as_opts=-x ;;
+         * ) as_opts= ;;
+       esac
+       exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -316,7 +324,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -356,19 +364,19 @@ else
 fi # as_fn_arith
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -530,7 +538,7 @@ test -n "$DJDIR" || exec 7<&0 </dev/null
 exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
@@ -740,8 +748,9 @@ do
   fi
 
   case $ac_option in
-  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)   ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -786,7 +795,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -812,7 +821,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1016,7 +1025,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1032,7 +1041,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1062,8 +1071,8 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
@@ -1071,7 +1080,7 @@ Try \`$0 --help' for more information."
     # Reject names that are not valid shell variable names.
     case $ac_envvar in #(
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
     esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
@@ -1081,7 +1090,7 @@ Try \`$0 --help' for more information."
     $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -1089,13 +1098,13 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error "missing argument to $ac_option"
+  as_fn_error $? "missing argument to $ac_option"
 fi
 
 if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
-    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
@@ -1118,7 +1127,7 @@ do
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1132,8 +1141,8 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1148,9 +1157,9 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error "working directory cannot be determined"
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error "pwd does not report name of working directory"
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
@@ -1189,11 +1198,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
        pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1233,7 +1242,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1377,9 +1386,9 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 configure
-generated by GNU Autoconf 2.65
+generated by GNU Autoconf 2.68
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1423,7 +1432,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_compile
@@ -1449,7 +1458,7 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } >/dev/null && {
+  test $ac_status = 0; } > conftest.i && {
         test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
        }; then :
@@ -1460,7 +1469,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_cpp
@@ -1506,7 +1515,7 @@ fi
   # interfere with the next link command; also delete a directory that is
   # left behind by Apple's compiler.  We do this before executing the actions.
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_link
@@ -1519,10 +1528,10 @@ fi
 ac_fn_c_check_header_mongrel ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  if eval \${$3+:} false; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 fi
 eval ac_res=\$$3
@@ -1558,7 +1567,7 @@ if ac_fn_c_try_cpp "$LINENO"; then :
 else
   ac_header_preproc=no
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
 $as_echo "$ac_header_preproc" >&6; }
 
@@ -1585,7 +1594,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
 esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=\$ac_header_compiler"
@@ -1594,7 +1603,7 @@ eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_mongrel
 
@@ -1635,7 +1644,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_run
@@ -1649,7 +1658,7 @@ ac_fn_c_check_header_compile ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1667,7 +1676,7 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
 
@@ -1680,7 +1689,7 @@ ac_fn_c_check_type ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=no"
@@ -1721,7 +1730,7 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_type
 
@@ -1733,7 +1742,7 @@ ac_fn_c_check_func ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1788,7 +1797,7 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
 cat >config.log <<_ACEOF
@@ -1796,7 +1805,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
 
@@ -1906,11 +1915,9 @@ trap 'exit_status=$?
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -1944,11 +1951,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
@@ -1961,11 +1966,9 @@ _ASBOX
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
@@ -1979,11 +1982,9 @@ _ASBOX
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
       cat confdefs.h
       echo
@@ -2038,7 +2039,12 @@ _ACEOF
 ac_site_file1=NONE
 ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  ac_site_file1=$CONFIG_SITE
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
   ac_site_file1=$prefix/share/config.site
   ac_site_file2=$prefix/etc/config.site
@@ -2053,7 +2059,11 @@ do
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
 
@@ -2129,7 +2139,7 @@ if $ac_cache_corrupted; then
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -2146,16 +2156,22 @@ ac_config_headers="$ac_config_headers config.h"
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  for ac_t in install-sh install.sh shtool; do
-    if test -f "$ac_dir/$ac_t"; then
-      ac_aux_dir=$ac_dir
-      ac_install_sh="$ac_aux_dir/$ac_t -c"
-      break 2
-    fi
-  done
+  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
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
 done
 if test -z "$ac_aux_dir"; then
-  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
 fi
 
 # These three variables are undocumented and unsupported,
@@ -2169,27 +2185,27 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
 $as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+if ${ac_cv_build+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_build_alias=$build_alias
 test "x$ac_build_alias" = x &&
   ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
 test "x$ac_build_alias" = x &&
-  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
 $as_echo "$ac_cv_build" >&6; }
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
 esac
 build=$ac_cv_build
 ac_save_IFS=$IFS; IFS='-'
@@ -2207,14 +2223,14 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
 $as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
+if ${ac_cv_host+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "x$host_alias" = x; then
   ac_cv_host=$ac_cv_build
 else
   ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
 fi
 
 fi
@@ -2222,7 +2238,7 @@ fi
 $as_echo "$ac_cv_host" >&6; }
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
 esac
 host=$ac_cv_host
 ac_save_IFS=$IFS; IFS='-'
@@ -2238,8 +2254,8 @@ IFS=$ac_save_IFS
 case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
-VERSION=2.13
-UPDATED='March 30, 2010'
+VERSION=2.17
+UPDATED='November 16, 2013'
 
 DEVICE="posix"
 
@@ -2264,7 +2280,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -2304,7 +2320,7 @@ if test -z "$ac_cv_prog_CC"; then
 set dummy gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -2357,7 +2373,7 @@ if test -z "$CC"; then
 set dummy ${ac_tool_prefix}cc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -2397,7 +2413,7 @@ if test -z "$CC"; then
 set dummy cc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -2456,7 +2472,7 @@ if test -z "$CC"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -2500,7 +2516,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -2554,8 +2570,8 @@ fi
 
 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -2669,9 +2685,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -2713,8 +2728,8 @@ done
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -2771,9 +2786,9 @@ $as_echo "$ac_try_echo"; } >&5
     else
        { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
+as_fn_error $? "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
@@ -2784,7 +2799,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
 ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
 $as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2824,8 +2839,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
@@ -2835,7 +2850,7 @@ OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2872,7 +2887,7 @@ ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
@@ -2950,7 +2965,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
@@ -3062,7 +3077,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
 $as_echo_n "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
+if ${ac_cv_path_install+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3150,7 +3165,7 @@ if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then :
+  if ${ac_cv_prog_CPP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
@@ -3180,7 +3195,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -3196,11 +3211,11 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
   break
 fi
@@ -3239,7 +3254,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -3255,18 +3270,18 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
 
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -3350,7 +3365,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printw in -lcurses" >&5
 $as_echo_n "checking for printw in -lcurses... " >&6; }
-if test "${ac_cv_lib_curses_printw+set}" = set; then :
+if ${ac_cv_lib_curses_printw+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -3384,7 +3399,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_printw" >&5
 $as_echo "$ac_cv_lib_curses_printw" >&6; }
-if test "x$ac_cv_lib_curses_printw" = x""yes; then :
+if test "x$ac_cv_lib_curses_printw" = xyes; then :
   FSED_CPM=fsed.cpm LIBS="-lcurses $LIBS"
 else
   FSED_CPM=
@@ -3393,7 +3408,7 @@ fi
 if test x"$FSED_CPM" = x""; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printw in -lncurses" >&5
 $as_echo_n "checking for printw in -lncurses... " >&6; }
-if test "${ac_cv_lib_ncurses_printw+set}" = set; then :
+if ${ac_cv_lib_ncurses_printw+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -3427,7 +3442,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_printw" >&5
 $as_echo "$ac_cv_lib_ncurses_printw" >&6; }
-if test "x$ac_cv_lib_ncurses_printw" = x""yes; then :
+if test "x$ac_cv_lib_ncurses_printw" = xyes; then :
   FSED_CPM=fsed.cpm LIBS="-lncurses $LIBS"
 else
   FSED_CPM=
@@ -3442,7 +3457,7 @@ if test "$LIBDSK" != ""; then
   LDFLAGS="$LDFLAGS -L$LIBDSK/lib"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dsk_open in -ldsk" >&5
 $as_echo_n "checking for dsk_open in -ldsk... " >&6; }
-if test "${ac_cv_lib_dsk_dsk_open+set}" = set; then :
+if ${ac_cv_lib_dsk_dsk_open+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -3476,7 +3491,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dsk_dsk_open" >&5
 $as_echo "$ac_cv_lib_dsk_dsk_open" >&6; }
-if test "x$ac_cv_lib_dsk_dsk_open" = x""yes; then :
+if test "x$ac_cv_lib_dsk_dsk_open" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBDSK 1
 _ACEOF
@@ -3488,7 +3503,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
 $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$GREP"; then
@@ -3537,7 +3552,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_GREP"; then
-    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_GREP=$GREP
@@ -3551,7 +3566,7 @@ $as_echo "$ac_cv_path_GREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -3603,7 +3618,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_EGREP=$EGREP
@@ -3618,7 +3633,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3735,8 +3750,7 @@ do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -3749,7 +3763,7 @@ done
 for ac_header in libdsk.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "libdsk.h" "ac_cv_header_libdsk_h" "$ac_includes_default"
-if test "x$ac_cv_header_libdsk_h" = x""yes; then :
+if test "x$ac_cv_header_libdsk_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBDSK_H 1
 _ACEOF
@@ -3766,7 +3780,7 @@ if test x"$DEVICE" = x"win32"; then
   for ac_header in windows.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
-if test "x$ac_cv_header_windows_h" = x""yes; then :
+if test "x$ac_cv_header_windows_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_WINDOWS_H 1
 _ACEOF
@@ -3784,7 +3798,7 @@ do :
 #endif
 
 "
-if test "x$ac_cv_header_winioctl_h" = x""yes; then :
+if test "x$ac_cv_header_winioctl_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_WINIOCTL_H 1
 _ACEOF
@@ -3799,7 +3813,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3913,8 +3927,7 @@ for ac_header in fcntl.h sys/types.h sys/stat.h limits.h unistd.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -3926,7 +3939,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if test "${ac_cv_c_const+set}" = set; then :
+if ${ac_cv_c_const+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4005,7 +4018,7 @@ $as_echo "#define const /**/" >>confdefs.h
 fi
 
 ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = x""yes; then :
+if test "x$ac_cv_type_mode_t" = xyes; then :
 
 else
 
@@ -4016,7 +4029,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
-if test "x$ac_cv_type_off_t" = x""yes; then :
+if test "x$ac_cv_type_off_t" = xyes; then :
 
 else
 
@@ -4027,7 +4040,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = x""yes; then :
+if test "x$ac_cv_type_pid_t" = xyes; then :
 
 else
 
@@ -4038,7 +4051,7 @@ _ACEOF
 fi
 
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = x""yes; then :
+if test "x$ac_cv_type_size_t" = xyes; then :
 
 else
 
@@ -4050,7 +4063,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
-if test "${ac_cv_struct_tm+set}" = set; then :
+if ${ac_cv_struct_tm+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4094,7 +4107,7 @@ if test "$enable_largefile" != no; then
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
 $as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if test "${ac_cv_sys_largefile_CC+set}" = set; then :
+if ${ac_cv_sys_largefile_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_sys_largefile_CC=no
@@ -4145,7 +4158,7 @@ $as_echo "$ac_cv_sys_largefile_CC" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then :
+if ${ac_cv_sys_file_offset_bits+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   while :; do
@@ -4214,7 +4227,7 @@ rm -rf conftest*
   if test $ac_cv_sys_file_offset_bits = unknown; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if test "${ac_cv_sys_large_files+set}" = set; then :
+if ${ac_cv_sys_large_files+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   while :; do
@@ -4290,7 +4303,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
 $as_echo_n "checking for working memcmp... " >&6; }
-if test "${ac_cv_func_memcmp_working+set}" = set; then :
+if ${ac_cv_func_memcmp_working+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -4353,7 +4366,7 @@ esac
 for ac_func in strftime
 do :
   ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
-if test "x$ac_cv_func_strftime" = x""yes; then :
+if test "x$ac_cv_func_strftime" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_STRFTIME 1
 _ACEOF
@@ -4362,7 +4375,7 @@ else
   # strftime is in -lintl on SCO UNIX.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
 $as_echo_n "checking for strftime in -lintl... " >&6; }
-if test "${ac_cv_lib_intl_strftime+set}" = set; then :
+if ${ac_cv_lib_intl_strftime+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -4396,7 +4409,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
 $as_echo "$ac_cv_lib_intl_strftime" >&6; }
-if test "x$ac_cv_lib_intl_strftime" = x""yes; then :
+if test "x$ac_cv_lib_intl_strftime" = xyes; then :
   $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
 
 LIBS="-lintl $LIBS"
@@ -4409,8 +4422,7 @@ for ac_func in mktime strerror
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -4494,10 +4506,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+       cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+         mv -f confcache "$cache_file"$$ &&
+         mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+         mv -f confcache "$cache_file" ;;
+       esac
+      fi
+    fi
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -4513,6 +4536,7 @@ DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -4528,7 +4552,7 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -4629,6 +4653,7 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -4674,19 +4699,19 @@ export LANGUAGE
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -4882,7 +4907,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -4936,7 +4961,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # values after options handling.
 ac_log="
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.65.  Invocation command line was
+generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -4998,10 +5023,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.65,
+configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -5017,11 +5042,16 @@ ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -5043,6 +5073,7 @@ do
     $ac_shift
     case $ac_optarg in
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -5055,7 +5086,7 @@ do
     ac_need_defaults=false;;
   --he | --h)
     # Conflict between --help and --header
-    as_fn_error "ambiguous option: \`$1'
+    as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
     $as_echo "$ac_cs_usage"; exit ;;
@@ -5064,7 +5095,7 @@ Try \`$0 --help' for more information.";;
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) as_fn_error "unrecognized option: \`$1'
+  -*) as_fn_error $? "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
 
   *) as_fn_append ac_config_targets " $1"
@@ -5125,7 +5156,7 @@ do
     "fsed.cpm.1") CONFIG_FILES="$CONFIG_FILES fsed.cpm.1" ;;
     "mkfs.cpm.1") CONFIG_FILES="$CONFIG_FILES mkfs.cpm.1" ;;
 
-  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -5147,9 +5178,10 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -5157,12 +5189,13 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
@@ -5179,12 +5212,12 @@ if test "x$ac_cr" = x; then
 fi
 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\r'
+  ac_cs_awk_cr='\\r'
 else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -5193,18 +5226,18 @@ _ACEOF
   echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
   echo "_ACEOF"
 } >conf$$subs.sh ||
-  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
 
   ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
   if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -5212,7 +5245,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -5260,7 +5293,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = "\a"
 
@@ -5292,21 +5325,29 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
   sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
 else
   cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
-  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[         ]*VPATH[        ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[    ]*\):*/\1/
+  ac_vpsub='/^[         ]*VPATH[        ]*=[    ]*/{
+h
+s///
+s/^/:/
+s/[     ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[  ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[      ]*$//
 }'
 fi
@@ -5318,7 +5359,7 @@ fi # test -n "$CONFIG_FILES"
 # No need to generate them if there are no CONFIG_HEADERS.
 # This happens for instance with `./config.status Makefile'.
 if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
 BEGIN {
 _ACEOF
 
@@ -5330,11 +5371,11 @@ _ACEOF
 # handling of long lines.
 ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_t"; then
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -5419,7 +5460,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
 _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
 fi # test -n "$CONFIG_HEADERS"
 
 
@@ -5432,7 +5473,7 @@ do
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -5451,7 +5492,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
         # (if the path is not absolute).  The absolute path cannot be DOS-style,
         # because $ac_f cannot contain `:'.
@@ -5460,7 +5501,7 @@ do
           [\\/$]*) false;;
           *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
           esac ||
-          as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+          as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
@@ -5486,8 +5527,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -5617,23 +5658,24 @@ s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
+which seems to be undefined.  Please make sure it is defined" >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
+which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
   :H)
   #
@@ -5642,21 +5684,21 @@ which seems to be undefined.  Please make sure it is defined." >&2;}
   if test x"$ac_file" != x-; then
     {
       $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
-    } >"$tmp/config.h" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
 $as_echo "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
-      mv "$tmp/config.h" "$ac_file" \
-       || as_fn_error "could not create $ac_file" "$LINENO" 5
+      mv "$ac_tmp/config.h" "$ac_file" \
+       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
     $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error "could not create -" "$LINENO" 5
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
   fi
  ;;
 
@@ -5671,7 +5713,7 @@ _ACEOF
 ac_clean_files=$ac_clean_files_save
 
 test $ac_write_fail = 0 ||
-  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
 # configure is writing to config.log, and then calls config.status.
@@ -5692,7 +5734,7 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit $?
+  $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
index 3a9b985c3d857e5a901340085ab02e6b96931d19..0632ff7a87827295df3bba32ba21fa12b583da3e 100644 (file)
@@ -1,8 +1,8 @@
 AC_INIT(cpmfs.c)
 AC_CONFIG_HEADER(config.h)
 AC_CANONICAL_HOST
-VERSION=2.13
-UPDATED='March 30, 2010'
+VERSION=2.17
+UPDATED='November 16, 2013'
 
 DEVICE="posix"
 
diff --git a/cpm.5 b/cpm.5
index 8a9e1c4ee2aae4d8c20c76b8cd3dea9fcda5cc58..684f5da33bf10ae908f88b775d764e87bc716bce 100644 (file)
--- a/cpm.5
+++ b/cpm.5
@@ -1,7 +1,7 @@
 .\" Believe it or not, reportedly there are nroffs which do not know \(en
 .if n .ds en -
 .if t .ds en \(en
-.TH CPM 5 "March 30, 2010" "CP/M tools" "File formats"
+.TH CPM 5 "November 16, 2013" "CP/M tools" "File formats"
 .SH NAME \"{{{roff}}}\"{{{
 cpm \- CP/M disk and file system format
 .\"}}}
@@ -22,7 +22,9 @@ Number of directory entries
 .br
 Logical sector skew
 .br
-Number of reserved system tracks
+Number of reserved system tracks (optional)
+.br
+Offset to start of volume (optional)
 .sp
 .RE
 A block is the smallest allocatable storage unit.  CP/M supports block
@@ -35,6 +37,8 @@ are stored with the given software skew.
 A CP/M disk contains three areas:
 .RS
 .sp
+Volume offset (optional)
+.br
 System tracks (optional)
 .br
 Directory
@@ -47,6 +51,18 @@ disk space, there are non-bootable formats which omit those system tracks.
 The term \fIdisk capacity\fP always excludes the space for system tracks.
 Note that there is no bitmap or list for free blocks.  When accessing a
 drive for the first time, CP/M builds this bitmap in core from the directory.
+.LP
+A hard disk can have the additional notion of a \fIvolume offset\fP to
+locate the start of the drive image (which may or may not have system
+tracks associated with it). The base unit for volume offset is byte
+count from the beginning of the physical disk, but specifiers of
+\fIK\fP, \fIM\fP, \fIT\fP or \fIS\fP may be appended to denote
+kilobytes, megabytes, tracks or sectors.  If provided, a specifier
+must immediately follow the numeric value with no whitespace.  For
+convenience upper and lower case are both accepted and only the first
+letter is significant, thus 2KB, 8MB, 1000trk and 16sec are valid
+values. Offset must appear subsequent to track, sector and sector
+length values.
 .\"}}}
 .SS "Directory entries" \"{{{
 The directory is a sequence of directory entries (also called extents),
@@ -131,21 +147,25 @@ blocksize of 1024 byte with two-byte block pointers is not allowed).
 Rc stores the number of 128 byte records of the last used logical extent.
 Bc stores the number of bytes in the last used record.  The value 0 means
 128 for backward compatibility with CP/M 2.2, which did not support Bc.
+ISX records the number of unused instead of used bytes in Bc.
 .\"}}}
 .LP
 .\"{{{ Al     = allocated blocks
-\fBAl\fP stores block pointers.  If the disk capacity is less than 256 blocks,
-Al is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
-A block pointer of 0 marks a hole in the file.  If a hole
-covers the range of a full extent, the extent will not be allocated.  In particular,
-the first extent of a file does not neccessarily have extent number 0.
-A file may not share blocks with other files, as its blocks would be freed
-if the other files is erased without a following disk system reset.  CP/M returns
-EOF when it reaches a hole, whereas UNIX returns zero-value bytes, which makes
-holes invisible.
+\fBAl\fP stores block pointers.  If the disk capacity minus boot
+tracks but including the directory area is less than 256 blocks, Al
+is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
+Since the directory area is not subtracted, the directory area starts
+with block 0 and files can never allocate block 0, which is why this
+value can be given a new meaning: A block pointer of 0 marks a hole in
+the file.  If a hole covers the range of a full extent, the extent will
+not be allocated.  In particular, the first extent of a file does not
+neccessarily have extent number 0.  A file may not share blocks with other
+files, as its blocks would be freed if the other files is erased without
+a following disk system reset.  CP/M returns EOF when it reaches a hole,
+whereas UNIX returns zero-value bytes, which makes holes invisible.
 .\"}}}
 .\"}}}
-.SS "Time stamps" \"{{{
+.SS "Native time stamps" \"{{{
 P2DOS and CP/M Plus support time stamps, which are stored in each fourth
 directory entry.  This entry contains the time stamps for
 the extents using the previous three directory entries.  Note that you
@@ -180,6 +200,42 @@ time stamp.
 .sp
 .RE
 .\"}}}
+.SS "DateStamper time stamps" \"{{{
+The DateStamper software added functions to the BDOS to manage
+time stamps by allocating a read only file with the name "!!!TIME&.DAT"
+in the very first directory entry, covering the very first data
+blocks.  It contains one entry per directory entry with the
+following structure of 16 bytes:
+.RS
+.sp
+5 bytes create datefield
+.br
+5 bytes access datefield
+.br
+5 bytes modify datefield
+.br
+1 byte checksum
+.sp
+.RE
+The checksum is only used on every 8th entry (last entry in 128-byte
+record) and is the sum of the first 127 bytes of the record.
+Each datefield has this structure:
+.RS
+.sp
+1 byte BCD coded year (no century, so it is sane assuming any year < 70
+means 21st century)
+.br
+1 byte BCD coded month
+.br
+1 byte BCD coded day
+.br
+1 byte BCD coded hour or, if the high bit is set, the high byte of a
+counter for systems without real time clock
+.br
+1 byte BCD coded minute, or the low byte of the counter
+.sp
+.DE
+.\"}}}
 .SS "Disc labels" \"{{{
 CP/M Plus support disc labels, which are stored in an arbitrary directory
 entry.
index 89371f6c0892fdcffd15c8aab45dcc52eb3aafbd..ce7779df200f4a350e28e769c027edcf1795bbdc 100644 (file)
--- a/cpm.5.in
+++ b/cpm.5.in
@@ -22,7 +22,9 @@ Number of directory entries
 .br
 Logical sector skew
 .br
-Number of reserved system tracks
+Number of reserved system tracks (optional)
+.br
+Offset to start of volume (optional)
 .sp
 .RE
 A block is the smallest allocatable storage unit.  CP/M supports block
@@ -35,6 +37,8 @@ are stored with the given software skew.
 A CP/M disk contains three areas:
 .RS
 .sp
+Volume offset (optional)
+.br
 System tracks (optional)
 .br
 Directory
@@ -47,6 +51,18 @@ disk space, there are non-bootable formats which omit those system tracks.
 The term \fIdisk capacity\fP always excludes the space for system tracks.
 Note that there is no bitmap or list for free blocks.  When accessing a
 drive for the first time, CP/M builds this bitmap in core from the directory.
+.LP
+A hard disk can have the additional notion of a \fIvolume offset\fP to
+locate the start of the drive image (which may or may not have system
+tracks associated with it). The base unit for volume offset is byte
+count from the beginning of the physical disk, but specifiers of
+\fIK\fP, \fIM\fP, \fIT\fP or \fIS\fP may be appended to denote
+kilobytes, megabytes, tracks or sectors.  If provided, a specifier
+must immediately follow the numeric value with no whitespace.  For
+convenience upper and lower case are both accepted and only the first
+letter is significant, thus 2KB, 8MB, 1000trk and 16sec are valid
+values. Offset must appear subsequent to track, sector and sector
+length values.
 .\"}}}
 .SS "Directory entries" \"{{{
 The directory is a sequence of directory entries (also called extents),
@@ -131,21 +147,25 @@ blocksize of 1024 byte with two-byte block pointers is not allowed).
 Rc stores the number of 128 byte records of the last used logical extent.
 Bc stores the number of bytes in the last used record.  The value 0 means
 128 for backward compatibility with CP/M 2.2, which did not support Bc.
+ISX records the number of unused instead of used bytes in Bc.
 .\"}}}
 .LP
 .\"{{{ Al     = allocated blocks
-\fBAl\fP stores block pointers.  If the disk capacity is less than 256 blocks,
-Al is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
-A block pointer of 0 marks a hole in the file.  If a hole
-covers the range of a full extent, the extent will not be allocated.  In particular,
-the first extent of a file does not neccessarily have extent number 0.
-A file may not share blocks with other files, as its blocks would be freed
-if the other files is erased without a following disk system reset.  CP/M returns
-EOF when it reaches a hole, whereas UNIX returns zero-value bytes, which makes
-holes invisible.
+\fBAl\fP stores block pointers.  If the disk capacity minus boot
+tracks but including the directory area is less than 256 blocks, Al
+is interpreted as 16 byte-values, otherwise as 8 double-byte-values.
+Since the directory area is not subtracted, the directory area starts
+with block 0 and files can never allocate block 0, which is why this
+value can be given a new meaning: A block pointer of 0 marks a hole in
+the file.  If a hole covers the range of a full extent, the extent will
+not be allocated.  In particular, the first extent of a file does not
+neccessarily have extent number 0.  A file may not share blocks with other
+files, as its blocks would be freed if the other files is erased without
+a following disk system reset.  CP/M returns EOF when it reaches a hole,
+whereas UNIX returns zero-value bytes, which makes holes invisible.
 .\"}}}
 .\"}}}
-.SS "Time stamps" \"{{{
+.SS "Native time stamps" \"{{{
 P2DOS and CP/M Plus support time stamps, which are stored in each fourth
 directory entry.  This entry contains the time stamps for
 the extents using the previous three directory entries.  Note that you
@@ -180,6 +200,42 @@ time stamp.
 .sp
 .RE
 .\"}}}
+.SS "DateStamper time stamps" \"{{{
+The DateStamper software added functions to the BDOS to manage
+time stamps by allocating a read only file with the name "!!!TIME&.DAT"
+in the very first directory entry, covering the very first data
+blocks.  It contains one entry per directory entry with the
+following structure of 16 bytes:
+.RS
+.sp
+5 bytes create datefield
+.br
+5 bytes access datefield
+.br
+5 bytes modify datefield
+.br
+1 byte checksum
+.sp
+.RE
+The checksum is only used on every 8th entry (last entry in 128-byte
+record) and is the sum of the first 127 bytes of the record.
+Each datefield has this structure:
+.RS
+.sp
+1 byte BCD coded year (no century, so it is sane assuming any year < 70
+means 21st century)
+.br
+1 byte BCD coded month
+.br
+1 byte BCD coded day
+.br
+1 byte BCD coded hour or, if the high bit is set, the high byte of a
+counter for systems without real time clock
+.br
+1 byte BCD coded minute, or the low byte of the counter
+.sp
+.DE
+.\"}}}
 .SS "Disc labels" \"{{{
 CP/M Plus support disc labels, which are stored in an arbitrary directory
 entry.
diff --git a/cpm.ps b/cpm.ps
new file mode 100644 (file)
index 0000000..6c63133
--- /dev/null
+++ b/cpm.ps
@@ -0,0 +1,478 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.19
+%%CreationDate: Sun Feb  3 19:48:55 2013
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Bold
+%%+ font Times-Italic
+%%DocumentSuppliedResources: procset grops 1.19 0
+%%Pages: 4
+%%PageOrder: Ascend
+%%DocumentMedia: Default 595 842 0 () ()
+%%Orientation: Portrait
+%%EndComments
+%%BeginDefaults
+%%PageMedia: Default
+%%EndDefaults
+%%BeginProlog
+%%BeginResource: procset grops 1.19 0
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/MANUAL{
+statusdict begin/manualfeed true store end
+}bind def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/Fr{
+setrgbcolor fill
+}bind def
+/setcmykcolor where{
+pop
+/Fk{
+setcmykcolor fill
+}bind def
+}if
+/Fg{
+setgray fill
+}bind def
+/FL/fill load def
+/LW/setlinewidth load def
+/Cr/setrgbcolor load def
+/setcmykcolor where{
+pop
+/Ck/setcmykcolor load def
+}if
+/Cg/setgray load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+/setpagedevice{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%BeginFeature: *PageSize Default
+<< /PageSize [ 595 842 ] /ImagingBBox null >> setpagedevice
+%%EndFeature
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Bold
+%%IncludeResource: font Times-Italic
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72
+def/PL 841.89 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron
+/Zcaron/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent
+/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen
+/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon
+/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O
+/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex
+/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y
+/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft
+/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl
+/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen
+/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft
+/logicalnot/minus/registered/macron/degree/plusminus/twosuperior
+/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior
+/ordmasculine/guilsinglright/onequarter/onehalf/threequarters
+/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE
+/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
+/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn
+/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash
+/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def
+/Times-Italic@0 ENC0/Times-Italic RE/Times-Bold@0 ENC0/Times-Bold RE
+/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF 174.415(CPM\(5\) File)72 48 R 174.415
+(formats CPM\(5\))2.5 F/F1 10.95/Times-Bold@0 SF -.219(NA)72 84 S(ME)
+.219 E F0(cpm \255 CP/M disk and \214le system format)108 96 Q F1
+(DESCRIPTION)72 112.8 Q/F2 10/Times-Bold@0 SF(Characteristic sizes)87
+124.8 Q F0(Each CP/M disk format is described by the follo)108 136.8 Q
+(wing speci\214c sizes:)-.25 E(Sector size in bytes)144 160.8 Q
+(Number of tracks)144 172.8 Q(Number of sectors)144 184.8 Q(Block size)
+144 196.8 Q(Number of directory entries)144 208.8 Q(Logical sector sk)
+144 220.8 Q -.25(ew)-.1 G(Number of reserv)144 232.8 Q
+(ed system tracks \(optional\))-.15 E(Of)144 244.8 Q(fset to start of v)
+-.25 E(olume \(optional\))-.2 E 2.848(Ab)108 268.8 S .348
+(lock is the smallest allocatable storage unit.)-2.848 F .347
+(CP/M supports block sizes of 1024, 2048, 4096, 8192 and)5.348 F .207
+(16384 bytes.)108 280.8 R(Unfortunately)5.207 E 2.707(,t)-.65 G .208(hi\
+s format speci\214cation is not stored on the disk and there are lots o\
+f formats.)-2.707 F(Accessing a block is performed by accessing its sec\
+tors, which are stored with the gi)108 292.8 Q -.15(ve)-.25 G 2.5(ns).15
+G(oftw)-2.5 E(are sk)-.1 E -.25(ew)-.1 G(.)-.4 E F2(De)87 309.6 Q
+(vice ar)-.15 E(eas)-.18 E F0 2.5(AC)108 321.6 S
+(P/M disk contains three areas:)-2.5 E -1.29(Vo)144 345.6 S(lume of)1.29
+E(fset \(optional\))-.25 E(System tracks \(optional\))144 357.6 Q
+(Directory)144 369.6 Q(Data)144 381.6 Q .058
+(The system tracks store the boot loader and CP/M itself.)108 405.6 R
+.058(In order to sa)5.058 F .358 -.15(ve d)-.2 H .057
+(isk space, there are non-bootable).15 F 1.55
+(formats which omit those system tracks.)108 417.6 R 1.55(The term)6.55
+F/F3 10/Times-Italic@0 SF 1.55(disk capacity)4.05 F F0(al)4.05 E -.1(wa)
+-.1 G 1.55(ys e).1 F 1.55(xcludes the space for system)-.15 F 2.748
+(tracks. Note)108 429.6 R .248
+(that there is no bitmap or list for free blocks.)2.748 F .248
+(When accessing a dri)5.248 F .548 -.15(ve f)-.25 H .248
+(or the \214rst time, CP/M).15 F -.2(bu)108 441.6 S
+(ilds this bitmap in core from the directory).2 E(.)-.65 E 3.15(Ah)108
+458.4 S .65(ard disk can ha)-3.15 F .95 -.15(ve t)-.2 H .65
+(he additional notion of a).15 F F3 .65(volume of)3.15 F(fset)-.18 E F0
+.65(to locate the start of the dri)3.15 F .95 -.15(ve i)-.25 H .65
+(mage \(which).15 F .531(may or may not ha)108 470.4 R .831 -.15(ve s)
+-.2 H .531(ystem tracks associated with it\). The base unit for v).15 F
+.53(olume of)-.2 F .53(fset is byte count from)-.25 F 1.224(the be)108
+482.4 R 1.224(ginning of the ph)-.15 F 1.224(ysical disk, b)-.05 F 1.225
+(ut speci\214ers of)-.2 F F3(K)3.725 E F0(,)A F3(M)3.725 E F0(,)A F3(T)
+3.725 E F0(or)3.725 E F3(S)3.725 E F0 1.225
+(may be appended to denote kilobytes,)3.725 F(me)108 494.4 Q -.05(ga)
+-.15 G .806(bytes, tracks or sectors.).05 F .806(If pro)5.806 F .805
+(vided, a speci\214er must immediately follo)-.15 F 3.305(wt)-.25 G .805
+(he numeric v)-3.305 F .805(alue with no)-.25 F 2.881(whitespace. F)108
+506.4 R .381(or con)-.15 F -.15(ve)-.4 G .381(nience upper and lo).15 F
+.381(wer case are both accepted and only the \214rst letter is signi\
+\214cant,)-.25 F .02(thus 2KB, 8MB, 1000trk and 16sec are v)108 518.4 R
+.019(alid v)-.25 F .019(alues. Of)-.25 F .019
+(fset must appear subsequent to track, sector and sec-)-.25 F
+(tor length v)108 530.4 Q(alues.)-.25 E F2(Dir)87 547.2 Q
+(ectory entries)-.18 E F0 .408
+(The directory is a sequence of directory entries \(also called e)108
+559.2 R .409(xtents\), which contain 32 bytes of the follo)-.15 F(w-)
+-.25 E(ing structure:)108 571.2 Q 4.16(St F0)144 595.2 R 1.94
+(F1 F2 F3 F4 F5 F6 F7 E0)4.44 F 1.39(E1 E2 Xl)3.89 F 1.39(Bc Xh)5 F(Rc)
+2.78 E 2.5(Al Al Al Al Al Al Al Al Al Al Al Al Al Al Al Al)144 607.2 R
+F2(St)108 631.2 Q F0(is the status; possible v)2.5 E(alues are:)-.25 E
+(0\21115: used for \214le, status is the user number)144 655.2 Q .795(1\
+6\21131: used for \214le, status is the user number \(P2DOS\) or used f\
+or passw)144 667.2 R .794(ord e)-.1 F .794(xtent \(CP/M 3 or)-.15 F
+(higher\))144 679.2 Q(32: disc label)144 691.2 Q
+(33: time stamp \(P2DOS\))144 703.2 Q(0xE5: unused)144 715.2 Q
+(CP/M tools)72 768 Q(February 18, 2012)151.35 E(1)192.2 E 0 Cg EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF 174.415(CPM\(5\) File)72 48 R 174.415
+(formats CPM\(5\))2.5 F/F1 10/Times-Bold@0 SF(F0\211E2)108 84 Q F0 .412
+(are the \214le name and its e)2.912 F 2.913(xtension. The)-.15 F 2.913
+(ym)-.15 G .413(ay consist of an)-2.913 F 2.913(yp)-.15 G .413
+(rintable 7 bit ASCII character b)-2.913 F(ut:)-.2 E F1(<)2.913 E 3.362
+(>.,;:=?*[])108 96 S F0 5.862(.T)-3.362 G .862
+(he \214le name must not be empty)-5.862 F 3.361(,t)-.65 G .861(he e)
+-3.361 F .861(xtension may be empty)-.15 F 5.861(.B)-.65 G .861
+(oth are padded with)-5.861 F 2.831(blanks. The)108 108 R .331
+(highest bit of each character of the \214le name and e)2.831 F .331
+(xtension is used as attrib)-.15 F 2.832(ute. The)-.2 F(attrib)2.832 E
+(utes)-.2 E(ha)108 120 Q .3 -.15(ve t)-.2 H(he follo).15 E
+(wing meaning:)-.25 E(F0: requires set wheel byte \(Backgrounder II\))
+144 144 Q(F1: public \214le \(P2DOS, ZSDOS\), for)144 156 Q
+(ground-only command \(Backgrounder II\))-.18 E
+(F2: date stamp \(ZSDOS\), background-only commands \(Backgrounder II\))
+144 168 Q(F7: wheel protect \(ZSDOS\))144 180 Q(E0: read-only)144 192 Q
+(E1: system \214le)144 204 Q(E2: archi)144 216 Q -.15(ve)-.25 G(d).15 E
+.338(Public \214les \(visible under each user number\) are not supporte\
+d by CP/M 2.2, b)108 240 R .338(ut there is a patch and some)-.2 F
+(free CP/M clones support them without an)108 252 Q 2.5(yp)-.15 G
+(atches.)-2.5 E .827(The wheel byte is \(by def)108 268.8 R .828
+(ault\) the memory location at 0x4b)-.1 F 5.828(.I)-.4 G 3.328(fi)-5.828
+G 3.328(ti)-3.328 G 3.328(sz)-3.328 G .828(ero, only non-pri)-3.328 F
+(vile)-.25 E .828(ged commands)-.15 F(may be e)108 280.8 Q -.15(xe)-.15
+G(cuted.).15 E F1(Xl)108 297.6 Q F0(and)2.546 E F1(Xh)2.546 E F0 .046
+(store the e)2.546 F .046(xtent number)-.15 F 5.046(.A)-.55 G .045
+(\214le may use more than one directory entry)-2.5 F 2.545(,i)-.65 G
+2.545(fi)-2.545 G 2.545(tc)-2.545 G .045(ontains more blocks)-2.545 F
+.21(than an e)108 309.6 R .21(xtent can hold.)-.15 F .21
+(In this case, more e)5.21 F .21
+(xtents are allocated and each of them is numbered sequentially)-.15 F
+.457(with an e)108 321.6 R .457(xtent number)-.15 F 5.457(.I)-.55 G
+2.957(fap)-5.457 G -.05(hy)-2.957 G .457(sical e).05 F .456
+(xtent stores more than 16k, it is considered to contain multiple logi-)
+-.15 F .234(cal e)108 333.6 R .234
+(xtents, each pointing to 16k data, and the e)-.15 F .234
+(xtent number of the last used logical e)-.15 F .235(xtent is stored.)
+-.15 F(Note:)5.235 E 1.55(Some formats decided to al)108 345.6 R -.1(wa)
+-.1 G 1.549(ys store only one logical e).1 F 1.549(xtent in a ph)-.15 F
+1.549(ysical e)-.05 F 1.549(xtent, thus w)-.15 F 1.549(asting e)-.1 F
+(xtent)-.15 E 2.81(space. CP/M)108 357.6 R .31(2.2 allo)2.81 F .31
+(ws 512 e)-.25 F .31(xtents per \214le, CP/M 3 and higher allo)-.15 F
+2.811(wu)-.25 G 2.811(pt)-2.811 G 2.811(o2)-2.811 G 2.811(048. Bit)
+-2.811 F .311(5\2117 of Xl are 0, bit)2.811 F .577(0\2114 store the lo)
+108 369.6 R .577(wer bits of the e)-.25 F .576(xtent number)-.15 F 5.576
+(.B)-.55 G .576
+(it 6 and 7 of Xh are 0, bit 0\2115 store the higher bits of the)-5.576
+F -.15(ex)108 381.6 S(tent number).15 E(.)-.55 E F1(Rc)108 398.4 Q F0
+(and)2.946 E F1(Bc)2.946 E F0 .446
+(determine the length of the data used by this e)2.946 F 2.946
+(xtent. The)-.15 F(ph)2.947 E .447(ysical e)-.05 F .447(xtent is di)-.15
+F .447(vided into logical)-.25 F -.15(ex)108 410.4 S .156
+(tents, each of them being 16k in size \(a ph).15 F .156(ysical e)-.05 F
+.156(xtent must hold at least one logical e)-.15 F .156
+(xtent, e.g. a block-)-.15 F .053(size of 1024 byte with tw)108 422.4 R
+.054(o-byte block pointers is not allo)-.1 F 2.554(wed\). Rc)-.25 F .054
+(stores the number of 128 byte records of)2.554 F .457
+(the last used logical e)108 434.4 R 2.957(xtent. Bc)-.15 F .456
+(stores the number of bytes in the last used record.)2.957 F .456(The v)
+5.456 F .456(alue 0 means 128)-.25 F .654(for backw)108 446.4 R .654
+(ard compatibility with CP/M 2.2, which did not support Bc.)-.1 F .655
+(ISX records the number of unused)5.655 F(instead of used bytes in Bc.)
+108 458.4 Q F1(Al)108 475.2 Q F0 .9(stores block pointers.)3.4 F .899(I\
+f the disk capacity is less than 256 blocks, Al is interpreted as 16 by\
+te-v)5.9 F(alues,)-.25 E .243(otherwise as 8 double-byte-v)108 487.2 R
+2.743(alues. A)-.25 F .243
+(block pointer of 0 marks a hole in the \214le.)2.743 F .243
+(If a hole co)5.243 F -.15(ve)-.15 G .243(rs the range).15 F .341
+(of a full e)108 499.2 R .341(xtent, the e)-.15 F .341
+(xtent will not be allocated.)-.15 F .34(In particular)5.341 F 2.84(,t)
+-.4 G .34(he \214rst e)-2.84 F .34
+(xtent of a \214le does not neccessarily)-.15 F(ha)108 511.2 Q .479 -.15
+(ve ex)-.2 H .179(tent number 0.).15 F 2.679<418c>5.179 G .18
+(le may not share blocks with other \214les, as its blocks w)-2.679 F
+.18(ould be freed if the other)-.1 F .822
+(\214les is erased without a follo)108 523.2 R .822
+(wing disk system reset.)-.25 F .822
+(CP/M returns EOF when it reaches a hole, whereas)5.822 F
+(UNIX returns zero-v)108 535.2 Q(alue bytes, which mak)-.25 E
+(es holes in)-.1 E(visible.)-.4 E F1(Nati)87 552 Q .2 -.1(ve t)-.1 H
+(ime stamps).1 E F0 1.053(P2DOS and CP/M Plus support time stamps, whic\
+h are stored in each fourth directory entry)108 564 R 6.054(.T)-.65 G
+1.054(his entry)-6.054 F 1.3(contains the time stamps for the e)108 576
+R 1.299(xtents using the pre)-.15 F 1.299
+(vious three directory entries.)-.25 F 1.299(Note that you really)6.299
+F(ha)108 588 Q 1.294 -.15(ve t)-.2 H .994(ime stamps for each e).15 F
+.994(xtent, no matter if it is the \214rst e)-.15 F .994
+(xtent of a \214le or not.)-.15 F .995(The structure of time)5.994 F
+(stamp entries is:)108 600 Q 2.5(1b)144 624 S(yte status 0x21)-2.5 E 2.5
+(8b)144 636 S(ytes time stamp for third-last directory entry)-2.5 E 2.5
+(2b)144 648 S(ytes unused)-2.5 E 2.5(8b)144 660 S
+(ytes time stamp for second-last directory entry)-2.5 E 2.5(2b)144 672 S
+(ytes unused)-2.5 E 2.5(8b)144 684 S
+(ytes time stamp for last directory entry)-2.5 E 2.872(At)108 708 S .372
+(ime stamp consists of tw)-2.872 F 2.872(od)-.1 G .372(ates: Creation a\
+nd modi\214cation date \(the latter being recorded when the \214le)
+-2.872 F .935(is closed\).)108 720 R .936(CP/M Plus further allo)5.935 F
+.936(ws optionally to record the access instead of creation date as \
+\214rst time)-.25 F(CP/M tools)72 768 Q(February 18, 2012)151.35 E(2)
+192.2 E 0 Cg EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF 174.415(CPM\(5\) File)72 48 R 174.415
+(formats CPM\(5\))2.5 F(stamp.)108 84 Q 2.5(2b)144 108 S
+(ytes \(little-endian\) days starting with 1 at 01-01-1978)-2.5 E 2.5
+(1b)144 120 S(yte hour in BCD format)-2.5 E 2.5(1b)144 132 S
+(yte minute in BCD format)-2.5 E/F1 10/Times-Bold@0 SF
+(DateStamper time stamps)87 160.8 Q F0 .552(The DateStamper softw)108
+172.8 R .552(are added functions to the BDOS to manage time stamps by a\
+llocating a read only)-.1 F .441(\214le with the name "!!!TIME&.D)108
+184.8 R -1.11(AT)-.4 G 2.941("i)1.11 G 2.941(nt)-2.941 G .441(he v)
+-2.941 F .441(ery \214rst directory entry)-.15 F 2.941(,c)-.65 G -.15
+(ove)-2.941 G .441(ring the v).15 F .442(ery \214rst data blocks.)-.15 F
+(It)5.442 E(contains one entry per directory entry with the follo)108
+196.8 Q(wing structure of 16 bytes:)-.25 E 2.5(5b)144 220.8 S
+(ytes create date\214eld)-2.5 E 2.5(5b)144 232.8 S
+(ytes access date\214eld)-2.5 E 2.5(5b)144 244.8 S
+(ytes modify date\214eld)-2.5 E 2.5(1b)144 256.8 S(yte checksum)-2.5 E
+.237(The checksum is only used on e)108 280.8 R -.15(ve)-.25 G .236(ry \
+8th entry \(last entry in 128-byte record\) and is the sum of the \214r\
+st 127).15 F(bytes of the record.)108 292.8 Q
+(Each date\214eld has this structure:)5 E 2.5(1b)144 316.8 S
+(yte BCD coded year \(no century)-2.5 E 2.5(,s)-.65 G 2.5(oi)-2.5 G 2.5
+(ti)-2.5 G 2.5(ss)-2.5 G(ane assuming an)-2.5 E 2.5(yy)-.15 G
+(ear < 70 means 21st century\))-2.5 E 2.5(1b)144 328.8 S
+(yte BCD coded month)-2.5 E 2.5(1b)144 340.8 S(yte BCD coded day)-2.5 E
+2.608(1b)144 352.8 S .108(yte BCD coded hour or)-2.608 F 2.608(,i)-.4 G
+2.608(ft)-2.608 G .108(he high bit is set, the high byte of a counter f\
+or systems without real)-2.608 F(time clock)144 364.8 Q 2.5(1b)144 376.8
+S(yte BCD coded minute, or the lo)-2.5 E 2.5(wb)-.25 G
+(yte of the counter)-2.5 E F1(Disc labels)87 405.6 Q F0 .258(CP/M Plus \
+support disc labels, which are stored in an arbitrary directory entry)
+108 417.6 R 5.257(.T)-.65 G .257(he structure of disc labels)-5.257 F
+(is:)108 429.6 Q 2.5(1b)144 453.6 S(yte status 0x20)-2.5 E F1(F0\211E2)
+144 465.6 Q F0(are the disc label)2.5 E 2.886(1b)144 477.6 S .386
+(yte mode: bit 7 acti)-2.886 F -.25(va)-.25 G .386(tes passw).25 F .387
+(ord protection, bit 6 causes time stamps on access, b)-.1 F .387
+(ut 5 causes)-.2 F .874(time stamps on modi\214cations, bit 4 causes ti\
+me stamps on creation and bit 0 is set when a label)144 489.6 R -.15(ex)
+144 501.6 S 2.5(ists. Bit).15 F 2.5(4a)2.5 G(nd 6 are e)-2.5 E(xclusi)
+-.15 E -.15(ve)-.25 G(ly set.).15 E 3.45(1b)144 513.6 S .95(yte passw)
+-3.45 F .95(ord decode byte: T)-.1 F 3.45(od)-.8 G .951(ecode the passw)
+-3.45 F .951(ord, xor this byte with the passw)-.1 F .951(ord bytes in)
+-.1 F(re)144 525.6 Q -.15(ve)-.25 G(rse order).15 E 5(.T)-.55 G 2.5(oe)
+-5.8 G(ncode a passw)-2.5 E
+(ord, add its characters to get the decode byte.)-.1 E 2.5(2r)144 537.6
+S(eserv)-2.5 E(ed bytes)-.15 E 2.5(8p)144 549.6 S(assw)-2.5 E(ord bytes)
+-.1 E 2.5(4b)144 561.6 S(ytes label creation time stamp)-2.5 E 2.5(4b)
+144 573.6 S(ytes label modi\214cation time stamp)-2.5 E F1 -.1(Pa)87
+602.4 S(ssw).1 E(ords)-.1 E F0 1.484(CP/M Plus supports passw)108 614.4
+R 1.484(ords, which are stored in an arbitrary directory entry)-.1 F
+6.484(.T)-.65 G 1.484(he structure of these)-6.484 F(entries is:)108
+626.4 Q 2.5(1b)144 650.4 S(yte status \(user number plus 16\))-2.5 E F1
+(F0\211E2)144 662.4 Q F0(are the \214le name and its e)2.5 E(xtension.)
+-.15 E 3.171(1b)144 674.4 S .671(yte passw)-3.171 F .671
+(ord mode: bit 7 means passw)-.1 F .672
+(ord required for reading, bit 6 for writing and bit 5 for)-.1 F
+(deleting.)144 686.4 Q 3.451(1b)144 698.4 S .951(yte passw)-3.451 F .951
+(ord decode byte: T)-.1 F 3.451(od)-.8 G .951(ecode the passw)-3.451 F
+.95(ord, xor this byte with the passw)-.1 F .95(ord bytes in)-.1 F(re)
+144 710.4 Q -.15(ve)-.25 G(rse order).15 E 5(.T)-.55 G 2.5(oe)-5.8 G
+(ncode a passw)-2.5 E(ord, add its characters to get the decode byte.)
+-.1 E 2.5(2r)144 722.4 S(eserv)-2.5 E(ed bytes)-.15 E(CP/M tools)72 768
+Q(February 18, 2012)151.35 E(3)192.2 E 0 Cg EP
+%%Page: 4 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF 174.415(CPM\(5\) File)72 48 R 174.415
+(formats CPM\(5\))2.5 F 2.5(8p)144 84 S(assw)-2.5 E(ord bytes)-.1 E/F1
+10.95/Times-Bold@0 SF(SEE ALSO)72 112.8 Q/F2 10/Times-Italic@0 SF
+(mkfs.cpm)108 124.8 Q F0(\(1\),).32 E F2(fsc)2.5 E(k.cpm)-.2 E F0
+(\(1\),).32 E F2(fsed.cpm)2.5 E F0(\(1\),).32 E F2(cpmls)2.5 E F0(\(1\))
+.27 E(CP/M tools)72 768 Q(February 18, 2012)151.35 E(4)192.2 E 0 Cg EP
+%%Trailer
+end
+%%EOF
index 39a37c1470ad355372c9dc3033fea106bd299077..1b9e6d4d3c10594483a1ff287e3fec8bdf382c51 100644 (file)
@@ -1,4 +1,4 @@
-.TH CPMCHATTR 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH CPMCHATTR 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 cpmchattr \- change file attributes on CP/M files
 .\"}}}
@@ -57,12 +57,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT    Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de> and copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de> and copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 77c2b4ca4e8aca280176e4fda8ea09f6f4c5af51..fcd12f868bb56e4dc11c9f474df4ca3d37faa7a4 100644 (file)
@@ -57,12 +57,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT    Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de> and copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de> and copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index cf337e21b496a66c94eba8c4271fb7df8216455b..dc55c3300660954a97467c3d8577246545277721 100644 (file)
@@ -21,7 +21,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,i,usage=0,exitcode=0;
   struct cpmSuperBlock drive;
@@ -32,6 +32,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?"))!=EOF) switch(c)
   {
     case 'T': devopts=optarg; break;
index 8cc605cc822e537d675375ec304bf027911f524a..1915563c576b48dbe81b7c764730fb4a48e8e764 100644 (file)
@@ -1,4 +1,4 @@
-.TH CPMCHMOD 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH CPMCHMOD 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 cpmchmod \- change file mode on CP/M files
 .\"}}}
@@ -28,12 +28,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de> and copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de> and copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 05a4224571ffb463a7247fd0b9f7ae253b2f7fbd..644ce15f44635424ad434841cd981613bdbdd210 100644 (file)
@@ -28,12 +28,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de> and copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de> and copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 701d3b384605ca309d80ce6632710ad74c59db76..76b70a96011257fda2a518be45d0b0da7ad8d719 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,i,usage=0,exitcode=0;
   struct cpmSuperBlock drive;
@@ -33,6 +33,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?"))!=EOF) switch(c)
   {
     case 'T': devopts=optarg; break;
diff --git a/cpmcp.1 b/cpmcp.1
index 310f339c9f1cd11add8abf7aac71c776bc5cbd03..9649e8b1fb402f3b41106e0788b0920f6b47e082 100644 (file)
--- a/cpmcp.1
+++ b/cpmcp.1
@@ -1,4 +1,4 @@
-.TH CPMCP 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH CPMCP 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 cpmcp \- copy files from and to CP/M disks
 .\"}}}
@@ -64,12 +64,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 2d7dec8236575b71fb935716f4d794fffff44a5b..de1e6c6ad22f64df78922df91005cd4b3d406f26 100644 (file)
@@ -64,12 +64,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
diff --git a/cpmcp.c b/cpmcp.c
index f840f598bbb7bdfd3f0581a116cd19bcf90ce6ad..590e702aa887177c06e7d39599a2b05dd7335162 100644 (file)
--- a/cpmcp.c
+++ b/cpmcp.c
@@ -32,7 +32,7 @@ static int preserve=0;
 static int userNumber(const char *s) /*{{{*/
 {
   if (isdigit(*s) && *(s+1)==':') return (*s-'0');
-  if (isdigit(*s) && isdigit(*(s+1)) && *(s+2)==':') return (10*(*s-'0')+(*(s+1)));
+  if (isdigit(*s) && isdigit(*(s+1)) && *(s+2)==':') return (10*(*s-'0')+(*(s+1)-'0'));
   return -1;
 }
 /*}}}*/
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,readcpm=-1,todir=-1;
   struct cpmInode root;
@@ -135,6 +135,7 @@ int main(int argc, char *argv[])
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?pt"))!=EOF) switch(c)
   {
     case 'T': devopts=optarg; break;
@@ -226,15 +227,18 @@ int main(int argc, char *argv[])
       {
         struct cpmInode ino;
         char cpmname[2+8+1+3+1]; /* 00foobarxy.zzy\0 */
+        struct stat st;
+
+        stat(argv[i],&st);
 
         if (todir)
         {
           if ((dest=strrchr(argv[i],'/'))!=(char*)0) ++dest; else dest=argv[i];
-          sprintf(cpmname,"%02d%s",userNumber(argv[argc-1]),dest);
+          snprintf(cpmname,sizeof(cpmname),"%02d%s",userNumber(argv[argc-1]),dest);
         }
         else
         {
-          sprintf(cpmname,"%02d%s",userNumber(argv[argc-1]),strchr(argv[argc-1],':')+1);
+          snprintf(cpmname,sizeof(cpmname),"%02d%s",userNumber(argv[argc-1]),strchr(argv[argc-1],':')+1);
         }
         if (cpmCreat(&root,cpmname,&ino,0666)==-1) /* just cry */ /*{{{*/
         {
@@ -273,6 +277,13 @@ int main(int argc, char *argv[])
             exitcode=1;
           }
           /*}}}*/
+          if (preserve && !ohno)
+          {
+            struct utimbuf times;
+            times.actime=st.st_atime;
+            times.modtime=st.st_mtime;
+            cpmUtime(&ino,&times);
+          }
         }
         fclose(ufp);
       }
diff --git a/cpmfs.c b/cpmfs.c
index 1d4524ed87aed0b5177c65e788cbbd475622df47..760c9ab3a1a9d27f46bce5b2742bb1e8de1724c6 100644 (file)
--- a/cpmfs.c
+++ b/cpmfs.c
 
 #define INTBITS ((int)(sizeof(int)*8))
 
-/* There are four reserved entries: ., .., [passwd] and [label] */
+/* Convert BCD datestamp digits to binary */
+
+#define BCD2BIN(x) ((((x)>>4)&0xf)*10 + ((x)&0xf))
+
+#define BIN2BCD(x) (((((x)/10)&0xf)<<4) + (((x)%10)&0xf))
+
+/* There are four reserved directory entries: ., .., [passwd] and [label].
+The first two of them refer to the same inode. */
 
 #define RESERVED_ENTRIES 4
 
 /* CP/M does not support any kind of inodes, so they are simulated.
-Inode 0-(maxdir-1) are used by files which lowest extent is stored in
-the respective directory entry.  Inode maxdir is the root directory
-and inode maxdir+1 is the passwd file, if any. */
+Inode 0-(maxdir-1) correlate to the lowest extent number (not the first
+extent of the file in the directory) of a file.  Inode maxdir is the
+root directory, inode maxdir+1 is the optional passwd file and inode
+maxdir+2 the optional disk label. */
 
 #define RESERVED_INODES 3
 
@@ -74,7 +82,7 @@ static int splitFilename(const char *fullname, int type, char *name, char *ext,
   }
   *user=10*(fullname[0]-'0')+(fullname[1]-'0');
   fullname+=2;
-  if ((fullname[0]=='\0') || (type==CPMFS_DR22 && *user>=16) || (type==CPMFS_P2DOS && *user>=32))
+  if ((fullname[0]=='\0') || *user>=((type&CPMFS_HI_USER) ? 32 : 16))
   {
     boo="illegal CP/M filename";
     return -1;
@@ -193,6 +201,56 @@ static void unix2cpm_time(time_t now, int *days, int *hour, int *min)
   *days += tms->tm_yday+1;
 }
 /*}}}*/
+/* ds2unix_time       -- convert DS to Unix time                 */ /*{{{*/
+static time_t ds2unix_time(const struct dsEntry *entry) 
+{
+  struct tm tms;
+  int yr;
+
+  if (entry->minute==0 &&
+      entry->hour==0 &&
+      entry->day==0 &&
+      entry->month==0 &&
+      entry->year==0) return 0;
+  
+  tms.tm_isdst = -1;
+  tms.tm_sec = 0;
+  tms.tm_min = BCD2BIN( entry->minute );
+  tms.tm_hour = BCD2BIN( entry->hour );
+  tms.tm_mday = BCD2BIN( entry->day );
+  tms.tm_mon = BCD2BIN( entry->month ) - 1;
+  
+  yr = BCD2BIN(entry->year);
+  if (yr<70) yr+=100;
+  tms.tm_year = yr;
+  
+  return mktime(&tms);
+}
+/*}}}*/
+/* unix2ds_time       -- convert Unix to DS time                 */ /*{{{*/
+static void unix2ds_time(time_t now, struct dsEntry *entry) 
+{
+  struct tm *tms;
+  int yr;
+
+  if ( now==0 )
+  {
+    entry->minute=entry->hour=entry->day=entry->month=entry->year = 0;
+  }
+  else
+  {
+    tms=localtime(&now);
+    entry->minute = BIN2BCD( tms->tm_min );
+    entry->hour = BIN2BCD( tms->tm_hour );
+    entry->day = BIN2BCD( tms->tm_mday );
+    entry->month = BIN2BCD( tms->tm_mon + 1 );
+    
+    yr = tms->tm_year;
+    if ( yr>100 ) yr -= 100;
+    entry->year = BIN2BCD( yr );
+  }
+}
+/*}}}*/
 
 /* allocation vector bitmap functions */
 /* alvInit            -- init allocation vector                  */ /*{{{*/
@@ -209,7 +267,7 @@ static void alvInit(const struct cpmSuperBlock *d)
   /*}}}*/
   for (i=0; i<d->maxdir; ++i) /* mark file blocks as used */ /*{{{*/
   {
-    if (d->dir[i].status>=0 && d->dir[i].status<=(d->type==CPMFS_P2DOS ? 31 : 15))
+    if (d->dir[i].status>=0 && d->dir[i].status<=(d->type&CPMFS_HI_USER ? 31 : 15))
     {
 #ifdef CPMFS_DEBUG
       fprintf(stderr,"alvInit: allocate extent %d\n",i);
@@ -332,7 +390,7 @@ static int findFileExtent(const struct cpmSuperBlock *sb, int user, const char *
   {
     if
     (
-      ((unsigned char)sb->dir[start].status)<=(sb->type==CPMFS_P2DOS ? 31 : 15)
+      ((unsigned char)sb->dir[start].status)<=(sb->type&CPMFS_HI_USER ? 31 : 15)
       && (extno==-1 || (EXTENT(sb->dir[start].extnol,sb->dir[start].extnoh)/sb->extents)==(extno/sb->extents))
       && isMatching(user,name,ext,sb->dir[start].status,sb->dir[start].name,sb->dir[start].ext)
     ) return start;
@@ -364,7 +422,7 @@ static void updateTimeStamps(const struct cpmInode *ino, int extent)
 #endif
   unix2cpm_time(ino->sb->cnotatime ? ino->ctime : ino->atime,&ca_days,&ca_hour,&ca_min);
   unix2cpm_time(ino->mtime,&u_days,&u_hour,&u_min);
-  if ((ino->sb->type==CPMFS_P2DOS || ino->sb->type==CPMFS_DR3) && (date=ino->sb->dir+(extent|3))->status==0x21)
+  if ((ino->sb->type&CPMFS_CPM3_DATES) && (date=ino->sb->dir+(extent|3))->status==0x21)
   {
     ino->sb->dirtyDirectory=1;
     switch (extent&3)
@@ -406,7 +464,200 @@ static void updateTimeStamps(const struct cpmInode *ino, int extent)
   }
 }
 /*}}}*/
+/* updateDsStamps     -- set time in datestamper file            */ /*{{{*/
+static void updateDsStamps(const struct cpmInode *ino, int extent)
+{
+  int yr;
+  struct tm *cpm_time;
+  struct dsDate *stamp;
+  
+  if (!S_ISREG(ino->mode)) return;
+  if ( !(ino->sb->type&CPMFS_DS_DATES) ) return;
+
+#ifdef CPMFS_DEBUG
+  fprintf(stderr,"CPMFS: updating ds stamps for inode %d (%d)\n",extent,extent&3);
+#endif
+  
+  /* Get datestamp struct */
+  stamp = ino->sb->ds+extent;
+  
+  unix2ds_time( ino->mtime, &stamp->modify );
+  unix2ds_time( ino->ctime, &stamp->create );
+  unix2ds_time( ino->atime, &stamp->access );
+
+  ino->sb->dirtyDs = 1;
+}
+/*}}}*/
+/* readTimeStamps     -- read CP/M time stamp                    */ /*{{{*/
+static int readTimeStamps(struct cpmInode *i, int lowestExt) 
+{
+  /* variables */ /*{{{*/
+  struct PhysDirectoryEntry *date;
+  int u_days=0,u_hour=0,u_min=0;
+  int ca_days=0,ca_hour=0,ca_min=0;
+  int protectMode=0;
+  /*}}}*/
+  
+  if ( (i->sb->type&CPMFS_CPM3_DATES) && (date=i->sb->dir+(lowestExt|3))->status==0x21 )
+  {
+    switch (lowestExt&3)
+    {
+      case 0: /* first entry of the four */ /*{{{*/
+      {
+        ca_days=((unsigned char)date->name[0])+(((unsigned char)date->name[1])<<8);
+        ca_hour=(unsigned char)date->name[2];
+        ca_min=(unsigned char)date->name[3];
+        u_days=((unsigned char)date->name[4])+(((unsigned char)date->name[5])<<8);
+        u_hour=(unsigned char)date->name[6];
+        u_min=(unsigned char)date->name[7];
+        protectMode=(unsigned char)date->ext[0];
+        break;
+      }
+      /*}}}*/
+      case 1: /* second entry */ /*{{{*/
+      {
+        ca_days=((unsigned char)date->ext[2])+(((unsigned char)date->extnol)<<8);
+        ca_hour=(unsigned char)date->lrc;
+        ca_min=(unsigned char)date->extnoh;
+        u_days=((unsigned char)date->blkcnt)+(((unsigned char)date->pointers[0])<<8);
+        u_hour=(unsigned char)date->pointers[1];
+        u_min=(unsigned char)date->pointers[2];
+        protectMode=(unsigned char)date->pointers[3];
+        break;
+      }
+      /*}}}*/
+      case 2: /* third one */ /*{{{*/
+      {
+        ca_days=((unsigned char)date->pointers[5])+(((unsigned char)date->pointers[6])<<8);
+        ca_hour=(unsigned char)date->pointers[7];
+        ca_min=(unsigned char)date->pointers[8];
+        u_days=((unsigned char)date->pointers[9])+(((unsigned char)date->pointers[10])<<8);
+        u_hour=(unsigned char)date->pointers[11];
+        u_min=(unsigned char)date->pointers[12];
+        protectMode=(unsigned char)date->pointers[13];
+        break;
+      }
+      /*}}}*/
+    }
+    if (i->sb->cnotatime)
+    {
+      i->ctime=cpm2unix_time(ca_days,ca_hour,ca_min);
+      i->atime=0;
+    }
+    else
+    {
+      i->ctime=0;
+      i->atime=cpm2unix_time(ca_days,ca_hour,ca_min);
+    }
+    i->mtime=cpm2unix_time(u_days,u_hour,u_min);
+  }
+  else
+  {
+    i->atime=i->mtime=i->ctime=0;
+    protectMode=0;
+  }
+  
+  return protectMode;
+}
+/*}}}*/
+/* readDsStamps       -- read datestamper time stamp             */ /*{{{*/
+static void readDsStamps(struct cpmInode *i, int lowestExt) 
+{
+  struct dsDate *stamp;
+  
+  if ( !(i->sb->type&CPMFS_DS_DATES) ) return;
+
+  /* Get datestamp */
+  stamp = i->sb->ds+lowestExt;
+  
+  i->mtime = ds2unix_time(&stamp->modify);
+  i->ctime = ds2unix_time(&stamp->create);
+  i->atime = ds2unix_time(&stamp->access);
+}
+/*}}}*/
+
+/* match              -- match filename against a pattern        */ /*{{{*/
+static int recmatch(const char *a, const char *pattern)
+{
+  int first=1;
+
+  while (*pattern)
+  {
+    switch (*pattern)
+    {
+      case '*':
+      {
+        if (*a=='.' && first) return 1;
+        ++pattern;
+        while (*a) if (recmatch(a,pattern)) return 1; else ++a;
+        break;
+      }
+      case '?':
+      {
+        if (*a) { ++a; ++pattern; } else return 0;
+        break;
+      }
+      default: if (tolower(*a)==tolower(*pattern)) { ++a; ++pattern; } else return 0;
+    }
+    first=0;
+  }
+  return (*pattern=='\0' && *a=='\0');
+}
+
+int match(const char *a, const char *pattern) 
+{
+  int user;
+  char pat[255];
+
+  assert(strlen(pattern)<255);
+  if (isdigit(*pattern) && *(pattern+1)==':') { user=(*pattern-'0'); pattern+=2; }
+  else if (isdigit(*pattern) && isdigit(*(pattern+1)) && *(pattern+2)==':') { user=(10*(*pattern-'0')+(*(pattern+1)-'0')); pattern+=3; }
+  else user=-1;
+  if (user==-1) sprintf(pat,"??%s",pattern);
+  else sprintf(pat,"%02d%s",user,pattern);
+  return recmatch(a,pat);
+}
+
+/*}}}*/
+/* cpmglob            -- expand CP/M style wildcards             */ /*{{{*/
+void cpmglob(int optin, int argc, char * const argv[], struct cpmInode *root, int *gargc, char ***gargv)
+{
+  struct cpmFile dir;
+  int entries,dirsize=0;
+  struct cpmDirent *dirent=(struct cpmDirent*)0;
+  int gargcap=0,i,j;
 
+  *gargv=(char**)0;
+  *gargc=0;
+  cpmOpendir(root,&dir);
+  entries=0;
+  dirsize=8;
+  dirent=malloc(sizeof(struct cpmDirent)*dirsize);
+  while (cpmReaddir(&dir,&dirent[entries]))
+  {
+    ++entries;
+    if (entries==dirsize) dirent=realloc(dirent,sizeof(struct cpmDirent)*(dirsize*=2));
+  }
+  for (i=optin; i<argc; ++i)
+  {
+    int found;
+
+    for (j=0,found=0; j<entries; ++j)
+    {
+      if (match(dirent[j].name,argv[i]))
+      {
+        if (*gargc==gargcap) *gargv=realloc(*gargv,sizeof(char*)*(gargcap ? (gargcap*=2) : (gargcap=16)));
+        (*gargv)[*gargc]=strcpy(malloc(strlen(dirent[j].name)+1),dirent[j].name);
+        ++*gargc;
+        ++found;
+      }
+    }
+  }
+  free(dirent);
+}
+/*}}}*/
+
+/* superblock management */
 /* diskdefReadSuper   -- read super block from diskdefs file     */ /*{{{*/
 static int diskdefReadSuper(struct cpmSuperBlock *d, const char *format)
 {
@@ -414,9 +665,10 @@ static int diskdefReadSuper(struct cpmSuperBlock *d, const char *format)
   FILE *fp;
   int insideDef=0,found=0;
 
-  if ((fp=fopen(DISKDEFS,"r"))==(FILE*)0 && (fp=fopen("diskdefs","r"))==(FILE*)0)
+  d->type=0;
+  if ((fp=fopen("diskdefs","r"))==(FILE*)0 && (fp=fopen(DISKDEFS,"r"))==(FILE*)0)
   {
-    fprintf(stderr,"%s: Neither " DISKDEFS " nor diskdefs could be opened.\n",cmd);
+    fprintf(stderr,"%s: Neither `diskdefs' nor `" DISKDEFS "' could be opened.\n",cmd);
     exit(1);
   }
   while (fgets(line,sizeof(line),fp)!=(char*)0)
@@ -473,12 +725,77 @@ static int diskdefReadSuper(struct cpmSuperBlock *d, const char *format)
           }
         }
         else if (strcmp(argv[0],"boottrk")==0) d->boottrk=strtol(argv[1],(char**)0,0);
+        else if (strcmp(argv[0],"offset")==0)  
+        {
+          off_t val;
+          unsigned int multiplier;
+          char *endptr;
+
+          errno=0;
+          multiplier=1;
+          val = strtoul(argv[1],&endptr,10);
+          if ((errno==ERANGE && val==ULONG_MAX)||(errno!=0 && val==0))
+          {
+            fprintf(stderr,"%s: invalid offset value \"%s\" - %s\n",cmd,argv[1],strerror(errno));
+            exit(1);
+          }
+          if (endptr==argv[1])
+          {
+            fprintf(stderr,"%s: offset value \"%s\" is not a number\n",cmd,argv[1]);
+            exit(1);
+          }
+          if (*endptr!='\0')
+          {
+            /* Have a unit specifier */
+            switch (toupper(*endptr))
+            {
+            case 'K':
+              multiplier=1024;
+              break;
+            case 'M':
+              multiplier=1024*1024;
+              break;
+            case 'T':
+              if (d->sectrk<0||d->tracks<0||d->secLength<0)
+              {
+                fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
+                exit(1);
+              }
+              multiplier=d->sectrk*d->secLength;
+              break;
+            case 'S':
+              if (d->sectrk<0||d->tracks<0||d->secLength<0)
+              {
+                fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
+                exit(1);
+              }
+              multiplier=d->secLength;
+              break;
+            default:
+              fprintf(stderr,"%s: unknown unit specifier \"%c\"\n",cmd,*endptr);
+              exit(1);
+            }
+          }
+          if (val*multiplier>INT_MAX)
+          {
+            fprintf(stderr,"%s: effective offset is out of range\n",cmd);
+            exit(1);
+          }
+          d->offset=val*multiplier;
+        }
         else if (strcmp(argv[0],"logicalextents")==0) d->extents=strtol(argv[1],(char**)0,0);
         else if (strcmp(argv[0],"os")==0)
         {
-          if (strcmp(argv[1],"2.2")==0) d->type=CPMFS_DR22;
-          else if (strcmp(argv[1],"3")==0) d->type=CPMFS_DR3;
-          else if (strcmp(argv[1],"p2dos")==0) d->type=CPMFS_P2DOS;
+          if      (strcmp(argv[1],"2.2"  )==0) d->type|=CPMFS_DR22;
+          else if (strcmp(argv[1],"3"    )==0) d->type|=CPMFS_DR3;
+          else if (strcmp(argv[1],"isx"  )==0) d->type|=CPMFS_ISX;
+          else if (strcmp(argv[1],"p2dos")==0) d->type|=CPMFS_P2DOS;
+          else if (strcmp(argv[1],"zsys" )==0) d->type|=CPMFS_ZSYS;
+          else 
+          {
+            fprintf(stderr, "%s: invalid OS type `%s'\n", cmd, argv[1]);
+            exit(1);
+          }
         }
       }
       else if (argc>0 && argv[0][0]!='#')
@@ -492,8 +809,10 @@ static int diskdefReadSuper(struct cpmSuperBlock *d, const char *format)
       insideDef=1;
       d->skew=1;
       d->extents=0;
-      d->type=CPMFS_DR3;
+      d->type|=CPMFS_DR3;
       d->skewtab=(int*)0;
+      d->offset=0;
+      d->boottrk=d->secLength=d->sectrk=d->tracks=-1;
       if (strcmp(argv[1],format)==0) found=1;
     }
   }
@@ -503,6 +822,26 @@ static int diskdefReadSuper(struct cpmSuperBlock *d, const char *format)
     fprintf(stderr,"%s: unknown format %s\n",cmd,format);
     exit(1);
   }
+  if (d->boottrk<0)
+  {
+    fprintf(stderr, "%s: boottrk parameter invalid or missing from diskdef\n",cmd);
+    exit(1);
+  }
+  if (d->secLength<0)
+  {
+    fprintf(stderr, "%s: secLength parameter invalid or missing from diskdef\n",cmd);
+    exit(1);
+  }
+  if (d->sectrk<0)
+  {
+    fprintf(stderr, "%s: sectrk parameter invalid or missing from diskdef\n",cmd);
+    exit(1);
+  }
+  if (d->tracks<0)
+  {
+    fprintf(stderr, "%s: tracks parameter invalid or missing from diskdef\n",cmd);
+    exit(1);
+  }
   return 0;
 }
 /*}}}*/
@@ -512,7 +851,7 @@ static int amsReadSuper(struct cpmSuperBlock *d, const char *format)
   unsigned char boot_sector[512], *boot_spec;
   const char *err;
 
-  Device_setGeometry(&d->dev,512,9,40);
+  Device_setGeometry(&d->dev,512,9,40,0);
   if ((err=Device_readSector(&d->dev, 0, 0, (char *)boot_sector)))
   {
     fprintf(stderr,"%s: Failed to read Amstrad superblock (%s)\n",cmd,err);
@@ -543,7 +882,8 @@ static int amsReadSuper(struct cpmSuperBlock *d, const char *format)
               [6] = Block shift
               [7] = No. of directory blocks
    */
-  d->type = CPMFS_DR3; /* Amstrads are CP/M 3 systems */
+  d->type = 0;
+  d->type |= CPMFS_DR3;        /* Amstrads are CP/M 3 systems */
   d->secLength = 128 << boot_spec[4];
   d->tracks    = boot_spec[2];
   if (boot_spec[1] & 3) d->tracks *= 2;
@@ -553,110 +893,59 @@ static int amsReadSuper(struct cpmSuperBlock *d, const char *format)
   d->skew      = 1; /* Amstrads skew at the controller level */
   d->skewtab   = (int*)0;
   d->boottrk   = boot_spec[5];
+  d->offset    = 0;
   d->size      = (d->secLength*d->sectrk*(d->tracks-d->boottrk))/d->blksiz;
   d->extents   = ((d->size>=256 ? 8 : 16)*d->blksiz)/16384;
  
   return 0;
 }
 /*}}}*/
-
-/* match              -- match filename against a pattern        */ /*{{{*/
-static int recmatch(const char *a, const char *pattern)
+/* cpmCheckDs         -- read all datestamper timestamps         */ /*{{{*/
+int cpmCheckDs(struct cpmSuperBlock *sb)
 {
-  int first=1;
+  int dsoffset, dsblks, dsrecs, off, i;
+  unsigned char *buf;
 
-  while (*pattern)
-  {
-    switch (*pattern)
-    {
-      case '*':
-      {
-        if (*a=='.' && first) return 1;
-        ++pattern;
-        while (*a) if (recmatch(a,pattern)) return 1; else ++a;
-        break;
-      }
-      case '?':
-      {
-        if (*a) { ++a; ++pattern; } else return 0;
-        break;
-      }
-      default: if (tolower(*a)==tolower(*pattern)) { ++a; ++pattern; } else return 0;
-    }
-    first=0;
-  }
-  return (*pattern=='\0' && *a=='\0');
-}
+  if (!isMatching(0,"!!!TIME&","DAT",sb->dir->status,sb->dir->name,sb->dir->ext)) return -1;
 
-int match(const char *a, const char *pattern) 
-{
-  int user;
-  char pat[255];
+  /* Offset to ds file in alloc blocks */
+  dsoffset=(sb->maxdir*32+(sb->blksiz-1))/sb->blksiz;
 
-  assert(strlen(pattern)<255);
-  if (isdigit(*pattern) && *(pattern+1)==':') { user=(*pattern-'0'); pattern+=2; }
-  else if (isdigit(*pattern) && isdigit(*(pattern+1)) && *(pattern+2)==':') { user=(10*(*pattern-'0')+(*(pattern+1)-'0')); pattern+=3; }
-  else user=-1;
-  if (user==-1) sprintf(pat,"??%s",pattern);
-  else sprintf(pat,"%02d%s",user,pattern);
-  return recmatch(a,pat);
-}
+  dsrecs=(sb->maxdir+7)/8;
+  dsblks=(dsrecs*128+(sb->blksiz-1))/sb->blksiz;
 
-/*}}}*/
-/* cpmglob            -- expand CP/M style wildcards             */ /*{{{*/
-void cpmglob(int optin, int argc, char * const argv[], struct cpmInode *root, int *gargc, char ***gargv)
-{
-  struct cpmFile dir;
-  int entries,dirsize=0;
-  struct cpmDirent *dirent=(struct cpmDirent*)0;
-  int gargcap=0,i,j;
+  /* Allocate buffer */
+  sb->ds=malloc(dsblks*sb->blksiz);
 
-  *gargv=(char**)0;
-  *gargc=0;
-  cpmOpendir(root,&dir);
-  entries=0;
-  dirsize=8;
-  dirent=malloc(sizeof(struct cpmDirent)*dirsize);
-  while (cpmReaddir(&dir,&dirent[entries]))
+  /* Read ds file in its entirety */
+  off=0;
+  for (i=dsoffset; i<dsoffset+dsblks; i++)
   {
-    ++entries;
-    if (entries==dirsize) dirent=realloc(dirent,sizeof(struct cpmDirent)*(dirsize*=2));
+    if (readBlock(sb,i,((char*)sb->ds)+off,0,-1)==-1) return -1;
+    off+=sb->blksiz;
   }
-  for (i=optin; i<argc; ++i)
-  {
-    int found;
 
-    for (j=0,found=0; j<entries; ++j)
-    {
-      if (match(dirent[j].name,argv[i]))
-      {
-        if (*gargc==gargcap) *gargv=realloc(*gargv,sizeof(char*)*(gargcap ? (gargcap*=2) : (gargcap=16)));
-        (*gargv)[*gargc]=strcpy(malloc(strlen(dirent[j].name)+1),dirent[j].name);
-        ++*gargc;
-        ++found;
-      }
-    }
-    if (found==0)
+  /* Verify checksums */
+  buf = (unsigned char *)sb->ds;
+  for (i=0; i<dsrecs; i++)
+  {
+    unsigned cksum, j;
+    cksum=0;
+    for (j=0; j<127; j++) cksum += buf[j];
+    if (buf[j]!=(cksum&0xff))
     {
-      char pat[255];
-      char *pattern=argv[i];
-      int user;
-
-      if (isdigit(*pattern) && *(pattern+1)==':') { user=(*pattern-'0'); pattern+=2; }
-      else if (isdigit(*pattern) && isdigit(*(pattern+1)) && *(pattern+2)==':') { user=(10*(*pattern-'0')+(*(pattern+1)-'0')); pattern+=3; }
-      else user=-1;
-      if (user==-1) sprintf(pat,"??%s",pattern);
-      else sprintf(pat,"%02d%s",user,pattern);
-
-      if (*gargc==gargcap) *gargv=realloc(*gargv,sizeof(char*)*(gargcap ? (gargcap*=2) : (gargcap=16)));
-      (*gargv)[*gargc]=strcpy(malloc(strlen(pat)+1),pat);
-      ++*gargc;
+#ifdef CPMFS_DEBUG
+      fprintf( stderr, "!!!TIME&.DAT file failed cksum at record %i\n", i );
+#endif
+      free(sb->ds);
+      sb->ds = (struct dsDate *)0;
+      return -1;
     }
+    buf += 128;
   }
-  free(dirent);
+  return 0;
 }
 /*}}}*/
-
 /* cpmReadSuper       -- get DPB and init in-core data for drive */ /*{{{*/
 int cpmReadSuper(struct cpmSuperBlock *d, struct cpmInode *root, const char *format)
 {
@@ -666,7 +955,7 @@ int cpmReadSuper(struct cpmSuperBlock *d, struct cpmInode *root, const char *for
   assert(s_ifreg);
   if (strcmp(format, "amstrad")==0) amsReadSuper(d,format);
   else diskdefReadSuper(d,format);
-  Device_setGeometry(&d->dev,d->secLength,d->sectrk,d->tracks);
+  Device_setGeometry(&d->dev,d->secLength,d->sectrk,d->tracks,d->offset);
   if (d->skewtab==(int*)0) /* generate skew table */ /*{{{*/
   {
     int        i,j,k;
@@ -725,7 +1014,7 @@ int cpmReadSuper(struct cpmSuperBlock *d, struct cpmInode *root, const char *for
   }
   /*}}}*/
   alvInit(d);
-  if (d->type==CPMFS_DR3) /* read additional superblock information */ /*{{{*/
+  if (d->type&CPMFS_CPM3_OTHER) /* read additional superblock information */ /*{{{*/
   {
     int i;
 
@@ -805,21 +1094,91 @@ int cpmReadSuper(struct cpmSuperBlock *d, struct cpmInode *root, const char *for
     d->labelLength=0;
   }
   d->root=root;
+  d->dirtyDirectory = 0;
   root->ino=d->maxdir;
   root->sb=d;
   root->mode=(s_ifdir|0777);
   root->size=0;
   root->atime=root->mtime=root->ctime=0;
+
+  d->dirtyDs=0;
+  if (cpmCheckDs(d)==0) d->type|=CPMFS_DS_DATES;
+  else d->ds=(struct dsDate*)0;
+
+  return 0;
+}
+/*}}}*/
+/* syncDs             -- write all datestamper timestamps        */ /*{{{*/
+static int syncDs(const struct cpmSuperBlock *sb)
+{
+  if (sb->dirtyDs)
+  {
+    int dsoffset, dsblks, dsrecs, off, i;
+    unsigned char *buf;
+    
+    dsrecs=(sb->maxdir+7)/8;
+
+    /* Re-calculate checksums */
+    buf = (unsigned char *)sb->ds;
+    for ( i=0; i<dsrecs; i++ )
+    {
+      unsigned cksum, j;
+      cksum=0;
+      for ( j=0; j<127; j++ ) cksum += buf[j];
+      buf[j] = cksum & 0xff;
+      buf += 128;
+    }
+    dsoffset=(sb->maxdir*32+(sb->blksiz-1))/sb->blksiz;
+    dsblks=(dsrecs*128+(sb->blksiz-1))/sb->blksiz;
+
+    off=0;
+    for (i=dsoffset; i<dsoffset+dsblks; i++)
+    {
+      if (writeBlock(sb,i,((char*)(sb->ds))+off,0,-1)==-1) return -1;
+      off+=sb->blksiz;
+    }
+  }
   return 0;
 }
 /*}}}*/
+/* cpmSync            -- write directory back                    */ /*{{{*/
+int cpmSync(struct cpmSuperBlock *sb)
+{
+  if (sb->dirtyDirectory)
+  {
+    int i,blocks,entry;
+
+    blocks=(sb->maxdir*32+sb->blksiz-1)/sb->blksiz;
+    entry=0;
+    for (i=0; i<blocks; ++i) 
+    {
+      if (writeBlock(sb,i,(char*)(sb->dir+entry),0,-1)==-1) return -1;
+      entry+=(sb->blksiz/32);
+    }
+    sb->dirtyDirectory=0;
+  }
+  if (sb->type&CPMFS_DS_DATES) syncDs(sb);
+  return 0;
+}
+/*}}}*/
+/* cpmUmount          -- free super block                        */ /*{{{*/
+void cpmUmount(struct cpmSuperBlock *sb)
+{
+  cpmSync(sb);
+  if (sb->type&CPMFS_DS_DATES) free(sb->ds);
+  free(sb->alv);
+  free(sb->skewtab);
+  free(sb->dir);
+  if (sb->passwdLength) free(sb->passwd);
+}
+/*}}}*/
+
 /* cpmNamei           -- map name to inode                       */ /*{{{*/
 int cpmNamei(const struct cpmInode *dir, const char *filename, struct cpmInode *i)
 {
   /* variables */ /*{{{*/
   int user;
   char name[8],extension[3];
-  struct PhysDirectoryEntry *date;
   int highestExtno,highestExt=-1,lowestExtno,lowestExt=-1;
   int protectMode=0;
   /*}}}*/
@@ -898,7 +1257,14 @@ int cpmNamei(const struct cpmInode *dir, const char *filename, struct cpmInode *
       if (dir->sb->dir[highestExt].pointers[2*block] || dir->sb->dir[highestExt].pointers[2*block+1]) break;
     }
     if (dir->sb->dir[highestExt].blkcnt) i->size+=((dir->sb->dir[highestExt].blkcnt&0xff)-1)*128;
-    i->size+=dir->sb->dir[highestExt].lrc ? (dir->sb->dir[highestExt].lrc&0xff) : 128;
+    if (dir->sb->type & CPMFS_ISX)
+    {
+      i->size += (128 - dir->sb->dir[highestExt].lrc);
+    }
+    else
+    {
+      i->size+=dir->sb->dir[highestExt].lrc ? (dir->sb->dir[highestExt].lrc&0xff) : 128;
+    }
 #ifdef CPMFS_DEBUG
     fprintf(stderr,"cpmNamei: size=%ld\n",(long)i->size);
 #endif
@@ -907,70 +1273,9 @@ int cpmNamei(const struct cpmInode *dir, const char *filename, struct cpmInode *
   i->ino=lowestExt;
   i->mode=s_ifreg;
   i->sb=dir->sb;
-  /* set timestamps */ /*{{{*/
-  if 
-  (
-    (dir->sb->type==CPMFS_P2DOS || dir->sb->type==CPMFS_DR3)
-    && (date=dir->sb->dir+(lowestExt|3))->status==0x21
-  )
-  {
-    /* variables */ /*{{{*/
-    int u_days=0,u_hour=0,u_min=0;
-    int ca_days=0,ca_hour=0,ca_min=0;
-    /*}}}*/
 
-    switch (lowestExt&3)
-    {
-      case 0: /* first entry of the four */ /*{{{*/
-      {
-        ca_days=((unsigned char)date->name[0])+(((unsigned char)date->name[1])<<8);
-        ca_hour=(unsigned char)date->name[2];
-        ca_min=(unsigned char)date->name[3];
-        u_days=((unsigned char)date->name[4])+(((unsigned char)date->name[5])<<8);
-        u_hour=(unsigned char)date->name[6];
-        u_min=(unsigned char)date->name[7];
-       protectMode=(unsigned char)date->ext[0];
-        break;
-      }
-      /*}}}*/
-      case 1: /* second entry */ /*{{{*/
-      {
-        ca_days=((unsigned char)date->ext[2])+(((unsigned char)date->extnol)<<8);
-        ca_hour=(unsigned char)date->lrc;
-        ca_min=(unsigned char)date->extnoh;
-        u_days=((unsigned char)date->blkcnt)+(((unsigned char)date->pointers[0])<<8);
-        u_hour=(unsigned char)date->pointers[1];
-        u_min=(unsigned char)date->pointers[2];
-        protectMode=(unsigned char)date->pointers[3];
-        break;
-      }
-      /*}}}*/
-      case 2: /* third one */ /*{{{*/
-      {
-        ca_days=((unsigned char)date->pointers[5])+(((unsigned char)date->pointers[6])<<8);
-        ca_hour=(unsigned char)date->pointers[7];
-        ca_min=(unsigned char)date->pointers[8];
-        u_days=((unsigned char)date->pointers[9])+(((unsigned char)date->pointers[10])<<8);
-        u_hour=(unsigned char)date->pointers[11];
-        u_min=(unsigned char)date->pointers[12];
-        protectMode=(unsigned char)date->pointers[13];
-        break;
-      }
-      /*}}}*/
-    }
-    if (i->sb->cnotatime)
-    {
-      i->ctime=cpm2unix_time(ca_days,ca_hour,ca_min);
-      i->atime=0;
-    }
-    else
-    {
-      i->ctime=0;
-      i->atime=cpm2unix_time(ca_days,ca_hour,ca_min);
-    }
-    i->mtime=cpm2unix_time(u_days,u_hour,u_min);
-  }
-  else i->atime=i->mtime=i->ctime=0;
+  /* read timestamps */ /*{{{*/
+  protectMode = readTimeStamps(i,lowestExt);
   /*}}}*/
 
   /* Determine the inode attributes */
@@ -990,6 +1295,9 @@ int cpmNamei(const struct cpmInode *dir, const char *filename, struct cpmInode *
   i->mode|=0444;
   if (!(dir->sb->dir[lowestExt].ext[0]&0x80)) i->mode|=0222;
   if (extension[0]=='C' && extension[1]=='O' && extension[2]=='M') i->mode|=0111;
+
+  readDsStamps(i,lowestExt);
+  
   return 0;
 }
 /*}}}*/
@@ -1001,7 +1309,7 @@ void cpmStatFS(const struct cpmInode *ino, struct cpmStatFS *buf)
 
   d=ino->sb;
   buf->f_bsize=d->blksiz;
-  buf->f_blocks=(d->tracks*d->sectrk*d->secLength)/d->blksiz;
+  buf->f_blocks=d->size;
   buf->f_bfree=0;
   buf->f_bused=-(d->maxdir*32+d->blksiz-1)/d->blksiz;
   for (i=0; i<d->alvSize; ++i)
@@ -1178,7 +1486,7 @@ int cpmReaddir(struct cpmFile *dir, struct cpmDirent *ent)
     {
       int first=dir->pos-RESERVED_ENTRIES;
 
-      if ((cur=dir->ino->sb->dir+(dir->pos-RESERVED_ENTRIES))->status>=0 && cur->status<=(dir->ino->sb->type==CPMFS_P2DOS ? 31 : 15))
+      if ((cur=dir->ino->sb->dir+(dir->pos-RESERVED_ENTRIES))->status>=0 && cur->status<=(dir->ino->sb->type&CPMFS_HI_USER ? 31 : 15))
       {
         /* determine first extent for the current file */ /*{{{*/
         for (i=0; i<dir->ino->sb->maxdir; ++i) if (i!=(dir->pos-RESERVED_ENTRIES))
@@ -1354,7 +1662,9 @@ int cpmWrite(struct cpmFile *file, const char *buf, int count)
         file->ino->sb->dir[extent].extnoh=EXTENTH(extentno);
         file->ino->sb->dir[extent].blkcnt=0;
         file->ino->sb->dir[extent].lrc=0;
+        time(&file->ino->ctime);
         updateTimeStamps(file->ino,extent);
+        updateDsStamps(file->ino,extent);
       }
       findext=0;
       findblock=1;
@@ -1374,6 +1684,9 @@ int cpmWrite(struct cpmFile *file, const char *buf, int count)
         start=0;
         end=(blocksize-1)/file->ino->sb->secLength;
         memset(buffer,0,blocksize);
+        time(&file->ino->ctime);
+        updateTimeStamps(file->ino,extent);
+        updateDsStamps(file->ino,extent);
       }
       /*}}}*/
       else /* read existing block and set start/end to cover modified parts */ /*{{{*/
@@ -1399,6 +1712,7 @@ int cpmWrite(struct cpmFile *file, const char *buf, int count)
       --count;
     }
     (void)writeBlock(file->ino->sb,block,buffer,start,end);
+    time(&file->ino->mtime);
     if (file->ino->sb->size<256) for (last=15; last>=0; --last)
     {
       if (file->ino->sb->dir[extent].pointers[last])
@@ -1418,8 +1732,16 @@ int cpmWrite(struct cpmFile *file, const char *buf, int count)
     file->ino->sb->dir[extent].extnol=EXTENTL(extentno);
     file->ino->sb->dir[extent].extnoh=EXTENTH(extentno);
     file->ino->sb->dir[extent].blkcnt=((file->pos-1)%16384)/128+1;
-    file->ino->sb->dir[extent].lrc=file->pos%128;
+    if (file->ino->sb->type & CPMFS_EXACT_SIZE)
+    {
+      file->ino->sb->dir[extent].lrc = (128 - (file->pos%128)) & 0x7F;
+    }
+    else
+    {
+      file->ino->sb->dir[extent].lrc=file->pos%128;
+    }
     updateTimeStamps(file->ino,extent);
+    updateDsStamps(file->ino,extent);
     /*}}}*/
     if (file->pos==nextextpos) findext=1;
     else if (file->pos==nextblockpos) findblock=1;
@@ -1463,14 +1785,17 @@ int cpmCreat(struct cpmInode *dir, const char *fname, struct cpmInode *ino, mode
   ino->ino=extent;
   ino->mode=s_ifreg|mode;
   ino->size=0;
+
   time(&ino->atime);
   time(&ino->mtime);
   time(&ino->ctime);
   ino->sb=dir->sb;
   updateTimeStamps(ino,extent);
+  updateDsStamps(ino,extent);
   return 0;
 }
 /*}}}*/
+
 /* cpmAttrGet         -- get CP/M attributes                     */ /*{{{*/
 int cpmAttrGet(struct cpmInode *ino, cpm_attr_t *attrib)
 {
@@ -1523,39 +1848,20 @@ int cpmAttrSet(struct cpmInode *ino, cpm_attr_t attrib)
 /* cpmChmod           -- set CP/M r/o & sys                      */ /*{{{*/
 int cpmChmod(struct cpmInode *ino, mode_t mode)
 {
-       /* Convert the chmod() into a chattr() call that affects RO */
-       int newatt = ino->attr & ~CPM_ATTR_RO;
+  /* Convert the chmod() into a chattr() call that affects RO */
+  int newatt = ino->attr & ~CPM_ATTR_RO;
 
-       if (!(mode & (S_IWUSR|S_IWGRP|S_IWOTH))) newatt |= CPM_ATTR_RO;
-       return cpmAttrSet(ino, newatt);
-}
-/*}}}*/
-/* cpmSync            -- write directory back                    */ /*{{{*/
-int cpmSync(struct cpmSuperBlock *d)
-{
-  if (d->dirtyDirectory)
-  {
-    int i,blocks,entry;
-
-    blocks=(d->maxdir*32+d->blksiz-1)/d->blksiz;
-    entry=0;
-    for (i=0; i<blocks; ++i) 
-    {
-      if (writeBlock(d,i,(char*)(d->dir+entry),0,-1)==-1) return -1;
-      entry+=(d->blksiz/32);
-    }
-    d->dirtyDirectory=0;
-  }
-  return 0;
+  if (!(mode & (S_IWUSR|S_IWGRP|S_IWOTH))) newatt |= CPM_ATTR_RO;
+  return cpmAttrSet(ino, newatt);
 }
 /*}}}*/
-/* cpmUmount          -- free super block                        */ /*{{{*/
-void cpmUmount(struct cpmSuperBlock *sb)
+/* cpmUtime           -- set timestamps                          */ /*{{{*/
+void cpmUtime(struct cpmInode *ino, struct utimbuf *times)
 {
-  cpmSync(sb);
-  free(sb->alv);
-  free(sb->skewtab);
-  free(sb->dir);
-  if (sb->passwdLength) free(sb->passwd);
+  ino->atime = times->actime;
+  ino->mtime = times->modtime;
+  time(&ino->ctime);
+  updateTimeStamps(ino,ino->ino);
+  updateDsStamps(ino,ino->ino);
 }
 /*}}}*/
diff --git a/cpmfs.h b/cpmfs.h
index acf050f9f2a8f3af43134c35cd750a9a402f7800..2f519a1c628205d7aa10226f6e0944a85f7261d1 100644 (file)
--- a/cpmfs.h
+++ b/cpmfs.h
@@ -3,6 +3,7 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <utime.h>
 
 #ifdef _WIN32
     #include <windows.h>
@@ -99,9 +100,34 @@ struct cpmStat
   time_t ctime;
 };
 
+#define CPMFS_HI_USER    (0x1<<0) /* has user numbers up to 31    */
+#define CPMFS_CPM3_DATES (0x1<<1) /* has CP/M+ style time stamps  */
+#define CPMFS_CPM3_OTHER (0x1<<2) /* has passwords and disc label */
+#define CPMFS_DS_DATES   (0x1<<3) /* has datestamper timestamps   */
+#define CPMFS_EXACT_SIZE (0x1<<4) /* has exact file size          */
+
 #define CPMFS_DR22  0
-#define CPMFS_P2DOS 1
-#define CPMFS_DR3   2
+#define CPMFS_P2DOS (CPMFS_CPM3_DATES|CPMFS_HI_USER)
+#define CPMFS_DR3   (CPMFS_CPM3_DATES|CPMFS_CPM3_OTHER|CPMFS_HI_USER)
+#define CPMFS_ISX   (CPMFS_EXACT_SIZE)
+#define CPMFS_ZSYS  (CPMFS_HI_USER)
+
+struct dsEntry
+{
+  char year;
+  char month;
+  char day;
+  char hour;
+  char minute;
+};
+          
+struct dsDate
+{
+  struct dsEntry create;
+  struct dsEntry access;
+  struct dsEntry modify;
+  char checksum;
+};
 
 struct cpmSuperBlock
 {
@@ -114,7 +140,8 @@ struct cpmSuperBlock
   int maxdir;
   int skew;
   int boottrk;
-  int type;
+  off_t offset;
+  unsigned int type;
   int size;
   int extents; /* logical extents per physical extent */
   struct PhysDirectoryEntry *dir;
@@ -128,6 +155,8 @@ struct cpmSuperBlock
   size_t passwdLength;
   struct cpmInode *root;
   int dirtyDirectory;
+  struct dsDate *ds;
+  int dirtyDs;
 };
 
 struct cpmStatFS
@@ -164,8 +193,10 @@ int cpmRead(struct cpmFile *file, char *buf, int count);
 int cpmWrite(struct cpmFile *file, const char *buf, int count);
 int cpmClose(struct cpmFile *file);
 int cpmCreat(struct cpmInode *dir, const char *fname, struct cpmInode *ino, mode_t mode);
+void cpmUtime(struct cpmInode *ino, struct utimbuf *times);
 int cpmSync(struct cpmSuperBlock *sb);
 void cpmUmount(struct cpmSuperBlock *sb);
+int cpmCheckDs(struct cpmSuperBlock *sb);
 
 #ifdef __cplusplus
        }
diff --git a/cpmls.1 b/cpmls.1
index 8084a3c006bc16be022b74415dcff752ebf9ec5c..e74e0983cc739685f4184f0feb5eee75de600d12 100644 (file)
--- a/cpmls.1
+++ b/cpmls.1
@@ -1,4 +1,4 @@
-.TH CPMLS 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH CPMLS 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 cpmls \- list sorted contents of directory
 .\"}}}
@@ -39,12 +39,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index f57c3bf0e2e92c3c7e631972b888e5228287f8e5..a75019cb18786b9814d5fbf5abe7a02bb581c231 100644 (file)
@@ -39,12 +39,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
diff --git a/cpmls.c b/cpmls.c
index 983817a0bf033de357b04d4bf7ca199974f9e943..fa100e9d5e80fdfdf81cc29a11ad99c944680141 100644 (file)
--- a/cpmls.c
+++ b/cpmls.c
@@ -116,6 +116,10 @@ static void oldddir(char **dirent, int entries, struct cpmInode *ino)
           {
             tmp=localtime(&statbuf.mtime);
             printf("  %02d-%s-%04d %02d:%02d",tmp->tm_mday,month[tmp->tm_mon],tmp->tm_year+1900,tmp->tm_hour,tmp->tm_min);
+          }
+          else if (statbuf.ctime) printf("                   ");
+          if (statbuf.ctime)
+          {
             tmp=localtime(&statbuf.ctime);
             printf("  %02d-%s-%04d %02d:%02d",tmp->tm_mday,month[tmp->tm_mon],tmp->tm_year+1900,tmp->tm_hour,tmp->tm_min);
           }
@@ -189,10 +193,17 @@ static void old3dir(char **dirent, int entries, struct cpmInode *ino)
           else if (attrib & CPM_ATTR_PWWRITE) printf("Write  ");
           else if (attrib & CPM_ATTR_PWDEL)   printf("Delete "); 
           else printf("None   ");
-          tmp=localtime(&statbuf.mtime);
-          printf("%02d/%02d/%02d %02d:%02d  ",tmp->tm_mon+1,tmp->tm_mday,tmp->tm_year%100,tmp->tm_hour,tmp->tm_min);
-          tmp=localtime(&statbuf.ctime);
-          printf("%02d/%02d/%02d %02d:%02d",tmp->tm_mon+1,tmp->tm_mday,tmp->tm_year%100,tmp->tm_hour,tmp->tm_min);
+          if (statbuf.mtime)
+          {
+            tmp=localtime(&statbuf.mtime);
+            printf("%02d/%02d/%02d %02d:%02d  ",tmp->tm_mon+1,tmp->tm_mday,tmp->tm_year%100,tmp->tm_hour,tmp->tm_min);
+          }
+          else if (statbuf.ctime) printf("                ");
+          if (statbuf.ctime)
+          {
+            tmp=localtime(&statbuf.ctime);
+            printf("%02d/%02d/%02d %02d:%02d",tmp->tm_mon+1,tmp->tm_mday,tmp->tm_year%100,tmp->tm_hour,tmp->tm_min);
+          }
           putchar('\n');
           ++l;
         }
@@ -325,7 +336,7 @@ int main(int argc, char *argv[])
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,usage=0;
   struct cpmSuperBlock drive;
@@ -340,6 +351,7 @@ int main(int argc, char *argv[])
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"cT:f:ih?dDFlA"))!=EOF) switch(c)
   {
     case 'f': format=optarg; break;
diff --git a/cpmrm.1 b/cpmrm.1
index 7ebf973126ea53a9706800424bce7692af5894b4..9d0365e8ee8a20a0bcde93f5cf7c98a3e8b58522 100644 (file)
--- a/cpmrm.1
+++ b/cpmrm.1
@@ -1,4 +1,4 @@
-.TH CPMRM 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH CPMRM 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 cpmrm \- remove files on CP/M disks
 .\"}}}
@@ -25,12 +25,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 46c0d189fe76d22f1f0428392a19ad5d3c542c80..870f68a1b93750647d17fde393e956d2f91724a7 100644 (file)
@@ -25,12 +25,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
diff --git a/cpmrm.c b/cpmrm.c
index d6639532b7af888a8890f9e0adcc057cb6ed9f9d..fb4bcffcac3a06d8af1254840c7f86e7e2e1426b 100644 (file)
--- a/cpmrm.c
+++ b/cpmrm.c
@@ -22,7 +22,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /* variables */ /*{{{*/
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,i,usage=0,exitcode=0;
   struct cpmSuperBlock drive;
@@ -32,6 +32,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?"))!=EOF) switch(c)
   {
     case 'T': devopts=optarg; break;
index 19bdf5e47c74fe21a5c4c51512669e005e76eb1b..474dd5956ec6b684674e7efbfb88bcfb7f725276 100644 (file)
--- a/device.h
+++ b/device.h
@@ -15,6 +15,7 @@ struct Device
   int secLength;
   int tracks;
   int sectrk;
+  off_t offset;
 #if HAVE_LIBDSK_H
   DSK_PDRIVER   dev;
   DSK_GEOMETRY geom; 
@@ -27,7 +28,7 @@ struct Device
 };
 
 const char *Device_open(struct Device *self, const char *filename, int mode, const char *deviceOpts);
-void Device_setGeometry(struct Device *self, int secLength, int sectrk, int tracks);
+void Device_setGeometry(struct Device *self, int secLength, int sectrk, int tracks, off_t offset);
 const char *Device_close(struct Device *self);
 const char *Device_readSector(const struct Device *self, int track, int sector, char *buf);
 const char *Device_writeSector(const struct Device *self, int track, int sector, const char *buf);
index b0d58b5651f4c8c2dcb921c2cb730d854b919931..739a3acb14b3c07315795a6af0459695eb264921 100644 (file)
@@ -25,12 +25,15 @@ const char *Device_open(struct Device *this, const char *filename, int mode, con
 }
 /*}}}*/
 /* Device_setGeometry    -- Set disk geometry                       */ /*{{{*/
-void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks)
+void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset)
 {
   this->secLength=secLength;
   this->sectrk=sectrk;
   this->tracks=tracks;
-
+  /* Must be an even multiple of sector size */
+  assert(offset%secLength==0);
+  this->offset=offset;
+  
   this->geom.dg_secsize   = secLength;
   this->geom.dg_sectors   = sectrk;
   /* Did the autoprobe guess right about the number of sectors & cylinders? */
@@ -62,7 +65,7 @@ const char *Device_close(struct Device *this)
 const char *Device_readSector(const struct Device *this, int track, int sector, char *buf)
 {
   dsk_err_t e;
-  e = dsk_lread(this->dev, &this->geom, buf, (track * this->sectrk) + sector);
+  e = dsk_lread(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength);
   return (e?dsk_strerror(e):(const char*)0);
 }
 /*}}}*/
@@ -70,7 +73,7 @@ const char *Device_readSector(const struct Device *this, int track, int sector,
 const char *Device_writeSector(const struct Device *this, int track, int sector, const char *buf)
 {
   dsk_err_t e;
-  e = dsk_lwrite(this->dev, &this->geom, buf, (track * this->sectrk) + sector);
+  e = dsk_lwrite(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength);
   return (e?dsk_strerror(e):(const char*)0);
 }
 /*}}}*/
index 6362a9aa53f9aa5d61469309f99dde239487b0e6..0393eed716f39ae3c0edc9634c10d465166a7570 100644 (file)
@@ -22,11 +22,12 @@ const char *Device_open(struct Device *this, const char *filename, int mode, con
 }
 /*}}}*/
 /* Device_setGeometry    -- Set disk geometry                       */ /*{{{*/
-void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks)
+void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset)
 {
   this->secLength=secLength;
   this->sectrk=sectrk;
   this->tracks=tracks;
+  this->offset=offset;
 }
 /*}}}*/
 /* Device_close          -- Close an image file                     */ /*{{{*/
@@ -45,7 +46,7 @@ const char *Device_readSector(const struct Device *this, int track, int sector,
   assert(sector<this->sectrk);
   assert(track>=0);
   assert(track<this->tracks);
-  if (lseek(this->fd,(off_t)(sector+track*this->sectrk)*this->secLength,SEEK_SET)==-1) 
+  if (lseek(this->fd,(off_t)(((sector+track*this->sectrk)*this->secLength)+this->offset),SEEK_SET)==-1) 
   {
     return strerror(errno);
   }
@@ -67,7 +68,7 @@ const char *Device_writeSector(const struct Device *this, int track, int sector,
   assert(sector<this->sectrk);
   assert(track>=0);
   assert(track<this->tracks);
-  if (lseek(this->fd,(off_t)(sector+track*this->sectrk)*this->secLength, SEEK_SET)==-1)
+  if (lseek(this->fd,(off_t)(((sector+track*this->sectrk)*this->secLength)+this->offset),SEEK_SET)==-1)
   {
     return strerror(errno);
   }
index b8aef9b3e584d0eb98f96de5910a07ab766ecd61..339eb340a1c76cb9c91c1d5c28db6d1dbb980799 100644 (file)
@@ -385,13 +385,18 @@ const char *Device_open(struct Device *sb, const char *filename, int mode, const
 }
 /*}}}*/
 /* Device_setGeometry    -- Set disk geometry                       */ /*{{{*/
-void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks)
+void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset)
 {
   int n;
 
   this->secLength=secLength;
   this->sectrk=sectrk;
   this->tracks=tracks;
+  // Bill Buckels - add this->offset
+  this->offset=offset;
+
+
+  // Bill Buckels - not sure what to do here
   if (this->drvtype == CPMDRV_WIN95)
   {
       DRIVEPARAMS drvp;
@@ -484,7 +489,8 @@ const char *Device_readSector(const struct Device *drive, int track, int sector,
         LPVOID iobuffer;
         DWORD  bytesread;
     
-        if (SetFilePointer(drive->hdisk, offset, NULL, FILE_BEGIN) == INVALID_FILE_SIZE)
+        // Bill Buckels - add drive->offset
+        if (SetFilePointer(drive->hdisk, offset+drive->offset, NULL, FILE_BEGIN) == INVALID_FILE_SIZE)
         {
             return strwin32error();
         }
@@ -511,6 +517,7 @@ const char *Device_readSector(const struct Device *drive, int track, int sector,
         return NULL;
   }
 
+  // Bill Buckels - not sure what to do here
   if (drive->drvtype == CPMDRV_WIN95)
   {
         DIOC_REGISTERS reg;
@@ -552,7 +559,8 @@ const char *Device_readSector(const struct Device *drive, int track, int sector,
         return 0;
   }
 
-  if (lseek(drive->fd,offset,SEEK_SET)==-1)
+  // Bill Buckels - add drive->offset
+  if (lseek(drive->fd,offset+drive->offset,SEEK_SET)==-1)
   {
     return strerror(errno);
   }
@@ -585,7 +593,8 @@ const char *Device_writeSector(const struct Device *drive, int track, int sector
         LPVOID iobuffer;
         DWORD  byteswritten;
 
-        if (SetFilePointer(drive->hdisk, offset, NULL, FILE_BEGIN) == INVALID_FILE_SIZE)
+        // Bill Buckels - add drive->offset
+        if (SetFilePointer(drive->hdisk, offset+drive->offset, NULL, FILE_BEGIN) == INVALID_FILE_SIZE)
         {
             return strwin32error();
         }
@@ -607,6 +616,7 @@ const char *Device_writeSector(const struct Device *drive, int track, int sector
         return NULL;
   }
 
+  // Bill Buckels - not sure what to do here
   if (drive->drvtype == CPMDRV_WIN95)
   {
         DIOC_REGISTERS reg;
@@ -648,7 +658,8 @@ const char *Device_writeSector(const struct Device *drive, int track, int sector
         return NULL;
   }
 
-  if (lseek(drive->fd,offset, SEEK_SET)==-1)
+  // Bill Buckels - add drive->offset
+  if (lseek(drive->fd,offset+drive->offset, SEEK_SET)==-1)
   {
     return strerror(errno);
   }
index fd14a19b5a31766e10509297b7fbfca598550210..c57e6168951529fa7bed9282e8396c70326f26d9 100644 (file)
--- a/diskdefs
+++ b/diskdefs
@@ -6,7 +6,7 @@ diskdef ibm-3740
   maxdir 64
   skew 6
   boottrk 2
-  os p2dos
+  os 2.2
 end
 
 diskdef 4mb-hd
@@ -55,6 +55,18 @@ diskdef cpm86-144feat
   os 3
 end
 
+# CP/M 86 on 720KB floppies
+diskdef cpm86-720
+  seclen 512
+  tracks 160
+  sectrk 9 
+  blocksize 2048
+  maxdir 256
+  skew 1
+  boottrk 2
+  os 3
+end
+
 diskdef cf2dd
   seclen 512
   tracks 160
@@ -248,12 +260,62 @@ diskdef p112-old
   os 3
 end
 
+diskdef gide-cfa
+  seclen 512
+  tracks 1000
+  sectrk 16
+  blocksize 4096
+  maxdir 1024
+  skew 0
+  boottrk 2
+  os 3
+end
+
+diskdef gide-cfb
+  seclen 512
+  tracks 1000
+  sectrk 16
+  blocksize 4096
+  maxdir 1024
+  skew 0
+  boottrk 0
+# Start of second partition
+  offset 1000trk
+  os 3
+end
+
+# AT&T/Olivetti Word Processor
+diskdef attwp
+   seclen 256
+   tracks 80
+   sectrk 32
+   blocksize 2048
+   maxdir 128
+   boottrk 1
+   logicalextents 1
+   skewtab 0,2,4,6,8,10,12,14,1,3,5,7,9,11,13,15,16,18,20,22,24,26,28,30,17,19,21,23,25,27,29,31
+   os 2
+end
+
+# Kaypro II
 diskdef kpii
   seclen 512
   tracks 40
   sectrk 10
   blocksize 1024
-  maxdir 32
+  maxdir 64
+  skew 0
+  boottrk 1
+  os 2.2
+end
+
+# Kayro IV
+diskdef kpiv
+  seclen 512
+  tracks 80
+  sectrk 10
+  blocksize 2048
+  maxdir 64
   skew 0
   boottrk 1
   os 2.2
@@ -367,10 +429,206 @@ end
 
 diskdef rc759
   seclen 1024
-  tracks 160
+  tracks 154
   sectrk 8
   blocksize 2048
   maxdir 512
   boottrk 4
   os 3
 end
+
+# ICL Comet: 40 track 5.25" Single Sided
+#
+diskdef icl-comet-525ss
+   seclen 512
+   tracks 40
+   sectrk 10
+   blocksize 1024
+   maxdir 64
+   skewtab 0,3,6,9,2,5,8,1,4,7
+   boottrk 2
+   os 2.2
+end
+
+diskdef z80pack-hd
+  seclen 128
+  tracks 255
+  sectrk 128
+  blocksize 2048
+  maxdir 1024
+  skew 0
+  boottrk 0
+  os 2.2
+end
+
+diskdef z80pack-hdb
+  seclen 128
+  tracks 256
+  sectrk 16384
+  blocksize 16384
+  maxdir 8192
+  skew 0
+  boottrk 0
+  os 2.2
+end
+
+# Bondwell 12 and 14 disk images in IMD raw binary format
+diskdef bw12
+  seclen 256
+  tracks 40
+  sectrk 18
+  blocksize 2048
+  maxdir 64
+  skew 1
+  boottrk 2
+  os 2.2
+end
+
+diskdef bw14
+  seclen 256
+  tracks 80
+  sectrk 18
+  blocksize 2048
+  maxdir 64
+  skew 1
+  boottrk 2
+  os 2.2
+end
+
+############################
+# north star cp/m  disks
+############################
+
+#North Star floppy 360K
+
+diskdef nsfd
+  seclen 512
+  tracks 70 
+  sectrk 10 
+  blocksize 2048
+  maxdir 64
+  skew 5  
+  boottrk 2
+  os 2.2   
+end
+
+
+#North Star CP/M Virtual-Disk file on Hard Disk
+# prepared with allocation factor = 4
+# as in "CR CPMB 4000 4"
+# needs to be copied off hard drive before you can 
+# work on it with cpmtools
+
+diskdef nshd4
+  seclen 512
+  tracks 512
+  sectrk 16 
+  blocksize 4096
+  maxdir 256
+  skew 0  
+  boottrk 0
+  os 2.2   
+end
+
+
+#North Star CP/M Virtual-Disk file on Hard Disk
+# prepared with allocation factor = 8
+# as in "CR CPMB 6000 8"
+# needs to be copied off hard drive before you can
+# work on it with cpmtools
+
+diskdef nshd8
+  seclen 512
+  tracks 1024
+  sectrk 16 
+  blocksize 8192
+  maxdir 256
+  skew 0  
+  boottrk 0
+  os 2.2   
+end
+
+# Northstar Micro-Disk System MDS-A-D 175
+diskdef mdsad175
+    seclen 512
+    blocksize 1024
+    tracks 35
+    maxdir 64
+    boottrk 2
+    sectrk 10
+    skew 5
+    os 2.2
+end
+
+
+# Northstar Micro-Disk System MDS-A-D 350
+diskdef mdsad350
+   seclen 512
+   blocksize 2048
+   tracks 70
+   maxdir 64
+   boottrk 2
+   sectrk 10
+   skew 5
+   os 2.2
+end
+
+
+# Osborne 1
+diskdef osborne1
+   seclen 1024
+   tracks 40
+   sectrk 5
+   blocksize 1024
+   maxdir 64
+   boottrk 3
+   os 2
+end
+
+# Osborne Nuevo/Vixen/4
+diskdef osborne4
+   seclen 1024
+   tracks 80
+   sectrk 5
+   blocksize 2048
+   maxdir 128
+   skew 2
+   boottrk 2
+   os 2
+end
+
+# Lobo Max-80 8" CP/M 2
+diskdef lobo2
+  seclen 256
+  tracks 77
+  sectrk 30
+  blocksize 2048
+  maxdir 64
+  skew 0
+  boottrk 2
+  os 2.2
+end
+
+#Lobo Max-80 8" CP/M 3
+diskdef lobo3
+  seclen 512
+  tracks 77
+  sectrk 17
+  blocksize 2048
+  maxdir 64
+  skew 0
+  boottrk 2
+  os 3
+end
+
+# PRO CP/M RZ50 DZ format, experimental
+diskdef dec_pro
+  seclen 512
+  tracks 80
+  sectrk 10
+  blocksize 2048
+  maxdir 128
+  skew 2
+  boottrk 2
+  os 2.2
+end
index ab39ead3ad05ac0f965a7d4b301c61db1a91a13c..de0eadaf38c44e157c475448aeea067bcf39d7b4 100644 (file)
@@ -1,4 +1,4 @@
-.TH FSCK.CPM 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH FSCK.CPM 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME ..\"{{{roff}}}\"{{{
 fsck.cpm \- check a CP/M file system
 .\"}}}
@@ -37,6 +37,9 @@ Any errors are indicated by exit code 1.
 .SH FILES .\"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH DIAGNOSTICS .\"{{{
 .IP "\fIimage\fP: \fIused\fP/\fItotal\fP files (\fIn\fP.\fIn\fP% non-contiguos), \fIused\fP/\fItotal\fP blocks"
 No inconsistencies could be found.  The number of used files actually
@@ -49,8 +52,8 @@ The number of used blocks includes the blocks used for system tracks
 and the directory.
 .\"}}}
 .SH AUTHORS .\"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 3a1dbc031bf52dffc0a684488c104e844b468c3d..929074d95d25ca358d82cf4a23da7ac64748a236 100644 (file)
@@ -37,6 +37,9 @@ Any errors are indicated by exit code 1.
 .SH FILES .\"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH DIAGNOSTICS .\"{{{
 .IP "\fIimage\fP: \fIused\fP/\fItotal\fP files (\fIn\fP.\fIn\fP% non-contiguos), \fIused\fP/\fItotal\fP blocks"
 No inconsistencies could be found.  The number of used files actually
@@ -49,8 +52,8 @@ The number of used blocks includes the blocks used for system tracks
 and the directory.
 .\"}}}
 .SH AUTHORS .\"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index c7e9048e44f94900456dc0340af8a47db19fb52d..c1458037fcb1b2660c621f68258e05861c48729e 100644 (file)
@@ -571,13 +571,14 @@ int main(int argc, char *argv[])
 {
   const char *err;
   const char *image;
-  const char *format=FORMAT;
+  const char *format;
   const char *devopts=NULL;
   int c,usage=0;
   struct cpmSuperBlock sb;
   struct cpmInode root;
   enum Result ret;
 
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:nh?"))!=EOF) switch(c)
   {
     case 'f': format=optarg; break;
index f2f08406a57a19a380fa9633df0449289b018dfb..b08ad479577aa1f4ec4072c1f3eaf830f7db4768 100644 (file)
@@ -1,4 +1,4 @@
-.TH FSED.CPM 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH FSED.CPM 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME ..\"{{{roff}}}\"{{{
 fsed.cpm \- edit a CP/M file system
 .\"}}}
@@ -26,12 +26,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS .\"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES .\"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index aee1b1a68fe61ced9ab602e3475a86d517a629a2..596dfcf9ea3adc08078cef3ea4c489273942f78c 100644 (file)
@@ -26,12 +26,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS .\"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES .\"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 5a606cb30b9de76756aea89396059141a02de57d..0c3f03f8ea5a3e418ff195e40d047be0c8a13cfb 100644 (file)
@@ -166,7 +166,7 @@ int main(int argc, char *argv[]) /*{{{*/
   const char *err;
   struct cpmSuperBlock drive;
   struct cpmInode root;
-  const char *format=FORMAT;
+  const char *format;
   int c,usage=0;
   unsigned long pos;
   chtype ch;
@@ -175,6 +175,7 @@ int main(int argc, char *argv[]) /*{{{*/
   /*}}}*/
 
   /* parse options */ /*{{{*/
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"T:f:h?"))!=EOF) switch(c)
   {
     case 'f': format=optarg; break;
index 6781b987bdbcbc23efe6bbe1654a1e3637b9af07..3f83ce9b555a535ca90c450882953554c7e4ded5 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2010-02-06.18; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -200,7 +200,11 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  trap '(exit $?); exit' 1 2 13 15
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
index 726c00afc19e61a4cddbf28fb77ab7a2a2a38fe0..f0d1bfd922c94ad151cf8c99cf6fbf2de3137d25 100644 (file)
@@ -1,4 +1,4 @@
-.TH MKFS.CPM 1 "March 30, 2010" "CP/M tools" "User commands"
+.TH MKFS.CPM 1 "November 16, 2013" "CP/M tools" "User commands"
 .SH NAME \"{{{roff}}}\"{{{
 mkfs.cpm \- make a CP/M file system
 .\"}}}
@@ -34,12 +34,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 ${prefix}/share/diskdefs       CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 966088db7eefbdca9107f0562b906631d1927f26..7161d849d0d3d1ab0f7db4c3f413176a9e274c91 100644 (file)
@@ -34,12 +34,15 @@ Upon successful completion, exit code 0 is returned.
 .SH ERRORS \"{{{
 Any errors are indicated by exit code 1.
 .\"}}}
+.SH ENVIRONMENT \"{{{
+CPMTOOLSFMT     Default format
+.\"}}}
 .SH FILES \"{{{
 @DATADIR@/diskdefs     CP/M disk format definitions
 .\"}}}
 .SH AUTHORS \"{{{
-This program is copyright 1997\(en2010 Michael Haardt
-<michael@moria.de>.  The Windows port is copyright 2000, 2001 John Elliott
+This program is copyright 1997\(en2012 Michael Haardt
+<michael@moria.de>.  The Windows port is copyright 2000, 2001, 2011 John Elliott
 <jce@seasip.demon.co.uk>.
 .PP
 This program is free software; you can redistribute it and/or modify
index 3e97a89a505ed5800475ede7b91aa982801265c4..0e0ac55c9da8eb32248ffce39e7b5c7a1c64b7a0 100644 (file)
@@ -103,7 +103,7 @@ const char cmd[]="mkfs.cpm";
 int main(int argc, char *argv[]) /*{{{*/
 {
   char *image;
-  const char *format=FORMAT;
+  const char *format;
   int c,usage=0;
   struct cpmSuperBlock drive;
   struct cpmInode root;
@@ -112,6 +112,7 @@ int main(int argc, char *argv[]) /*{{{*/
   char *bootTracks;
   const char *boot[4]={(const char*)0,(const char*)0,(const char*)0,(const char*)0};
 
+  if (!(format=getenv("CPMTOOLSFMT"))) format=FORMAT;
   while ((c=getopt(argc,argv,"b:f:L:h?"))!=EOF) switch(c)
   {
     case 'b':