[alt.sources] [comp.sys.mac.programmer] Convert among Apple file formats

jeff@tc.fluke.COM (Jeff Stearns) (01/07/90)

Archive-name: macbinconvert/release
Original-posting-by: jeff@tc.fluke.COM (Jeff Stearns)
Original-subject: Re: need Apple-Double format help
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[This is an experimental alt.sources re-posting from the newsgroup(s)
comp.sys.mac.programmer. Comments on this service to emv@math.lsa.umich.edu 
(Edward Vielmetti).]


In article <SCOTTH.90Jan3150218@harlie.corp.sgi.com> scotth@sgi.com (Scott Henry) writes:

> ...  Where can I get the structure of the resource fork of Apple-Double
> format? I have been able to reverse engineer parts of it ...


AppleSingle and AppleDouble specs are available from Apple or Cayman.
I'll dig them up and post them myself in a few days if they don't show
up in somebody else's posting by then.

Creating the resource fork isn't totally sufficient to make a double-clickable
file, since the GatorBox stores some needed information in the .DESKTOP file.
Creating a file behind the GatorBox's back won't result in a document that's
directly launchable until the GatorBox knows what you've done.  I don't
know the exact details of what's necessary to make it work.  Certainly
rebuilding the desktop is sufficient; maybe unmounting and remounting the
volume.  Maybe just closing and reopening the folder.

To the fellow who wants to write a program to convert zmodem <-> AppleDouble
<-> macbinary, here's a start I hacked out recently:


::::::::::::::
macbintogator
::::::::::::::
#! /bin/sh
#
#  Convert a MacBinary three-pronged file into an AppleDouble file suitable
#  for a GatorBox.  The .info file is retained in case a subsequent
#  reconversion is attempted.
#
#  The pathnames should be in "basename" form, without any trailing .info or
#  .rsrc or .data extension.
#
#	Jeff Stearns			jeff@tc.fluke.COM
#	John Fluke Mfg. Co, Inc.	(206) 356-5064

for file do
    (
    : do nothing with $file.info &&
    mv $file.rsrc `dirname $file`/%`basename $file` &&
    mv $file.data $file
    ) || exit 1
done

exit 0


::::::::::::::
macbintoz
::::::::::::::
#! /bin/sh
#
#  Convert three UNIX files representing the 3 MacBinary forks
#  into one Zmodem file.
#
#  The three forks are concatenated as info, data, rsrc.
#
#  Each fork begins on a 128-byte boundary.  Holes are padded
#  with zeros.
#
#	Jeff Stearns			jeff@tc.fluke.COM
#	John Fluke Mfg. Co, Inc.	(206) 356-5064

    (
    dd if=$1.info bs=128 conv=sync
    dd if=$1.data bs=128 conv=sync
    dd if=$1.rsrc bs=128 conv=sync
    )


::::::::::::::
ztomacbin
::::::::::::::
#! /bin/sh
#
#  Convert one Zmodem file into three UNIX files representing its 3 MacBinary
#  forks
#
#  The three forks produced are info, data, rsrc.
#
#  Within the info "fork" is encoded the length of the data and
#  rsrc forks:
#
#       bytes 53-56 = data length
#       bytes 57-60 = rsrc length
#
#  Each fork begins on a 128-byte boundary; that leaves some
#  padding after the data and rsrc forks.
#
#  N.B. Our use of adb presumes that this host uses Macintosh byte order;
#  that's true for a Sun.
#
#  Byte positions are numbered BETWEEN bytes; byte 0 lies just to the left
#  of the first byte in the file.  Thus we call byte N what you'd get if you
#  did seek(N, ...); read( ...)
#
#	Jeff Stearns			jeff@tc.fluke.COM
#	John Fluke Mfg. Co, Inc.	(206) 356-5064

dd if=$1 bs=128        count=1 of=$1.info

DataStart=128
DataLength=`echo '53?D' | adb $1.info | awk '{print $2}'`

RsrcStart=`expr 128 + '(' '(' $DataLength + 127 ')' / 128 '*' 128 ')'`
RsrcLength=`echo '57?D' | adb $1.info | awk '{print $2}'`

echo 1>&2 "DataLength=$DataLength  RsrcLength=$RsrcLength"

dd if=$1 ibs=1 skip=$DataStart count=$DataLength of=$1.data
dd if=$1 ibs=1 skip=$RsrcStart count=$RsrcLength of=$1.rsrc


::::::::::::::
ztogator
::::::::::::::
#! /bin/sh
#
#  Convert one Zmodem file into two UNIX files representing its rsrc and data
#  forks.
#
#  Within the zmodem info "fork" is encoded the length of the data and
#  rsrc forks:
#
#       bytes 53-56 = data length
#       bytes 57-60 = rsrc length
#
#  Each fork begins on a 128-byte boundary; that leaves some
#  padding after the data and rsrc forks.
#
#  N.B. Our use of adb presumes that this host uses Macintosh byte order;
#  that's true for a Sun.
#
#  Byte positions are numbered BETWEEN bytes; byte 0 lies just to the left
#  of the first byte in the file.  Thus we call byte N what you'd get if you
#  did seek(N, ...); read( ...)
#
#	Jeff Stearns			jeff@tc.fluke.COM
#	John Fluke Mfg. Co, Inc.	(206) 356-5064

Backup=$1.original

echo "To avoid overwriting your file $1, a backup copy is made at $Backup"
cp $1 $Backup

dd if=$Backup bs=128 count=1 of=$1.info 2>&-

DataStart=128
DataLength=`echo '53?D' | adb $1.info | awk '{print $2}'`

RsrcStart=`expr 128 + '(' '(' $DataLength + 127 ')' / 128 '*' 128 ')'`
RsrcLength=`echo '57?D' | adb $1.info | awk '{print $2}'`

rm $1.info

echo 1>&2 "DataLength=$DataLength  RsrcLength=$RsrcLength"

dd if=$Backup ibs=1 skip=$RsrcStart count=$RsrcLength of=`dirname
$1`/%`basename $1`
dd if=$Backup ibs=1 skip=$DataStart count=$DataLength of=$1


::::::::::::::
gatortoz
::::::::::::::
#! /bin/sh
#
#  gatortoz - Convert an AppleDouble file (actually a file and %file pair)
#             to a file in zmodem format.
#
#  Within the zmodem info "fork" is encoded the length of the data and
#  rsrc forks:
#
#       bytes 53-56 = data length
#       bytes 57-60 = rsrc length
#
#  Each fork begins on a 128-byte boundary.
#
#  N.B. Our use of adb presumes that this host uses Macintosh byte order;
#  that's true for a Sun.
#
#  Byte positions are numbered BETWEEN bytes; byte 0 lies just to the left
#  of the first byte in the file.  Thus we call byte N what you'd get if you
#  did seek(N, ...); read( ...)
#
#	Jeff Stearns			jeff@tc.fluke.COM
#	John Fluke Mfg. Co, Inc.	(206) 356-5064


for file do
    #
    #  The data fork is found in file.
    #  The resource fork is found in %file.
    #  A temporary info fork is synthesized in /tmp/file.info.
    #
    Data="$1"
    Rsrc="`dirname $1`/%`basename $1`"
    TempInfo="/tmp/`basename $1`.info"

    MacFileName="$Data"
    MacFileNameLength=`echo -n "$MacFileName" | wc -c`
    DataLength=`ls -l $Data | awk '{print $4}'`
    RsrcLength=`ls -l $Rsrc | awk '{print $4}'`

    echo 1>&2 "$file:   Data length = $DataLength   Resource length = $RsrcLength"

    #
    #  Create the info fork as size 128 bytes.
    #  Insert the Macintosh filename at byte 2.
    #  In a minute, we'll use adb to patch in the byte count that
    #  must precede the filename (these are Pascal-type strings).
    #
    echo -n "XX$MacFileName" | dd bs=128 conv=sync of=$TempInfo 2>&-
    (
        echo "0?w $MacFileNameLength"
        echo "53?W $DataLength"
        echo "57?W $RsrcLength"
    ) | adb -w $TempInfo 1>&-

    #
    #  Each fork begins on a 128-byte boundary.  Gaps are NULL-padded:
    #
    dd if=$TempInfo bs=128 conv=sync 2>&-
    dd if=$Data     bs=128 conv=sync 2>&-
    dd if=$Rsrc     bs=128 conv=sync 2>&-

    rm $TempInfo
done

-- 
    Jeff Stearns        John Fluke Mfg. Co, Inc.               (206) 356-5064
    jeff@tc.fluke.COM   {uw-beaver,microsoft,sun}!fluke!jeff