[comp.sys.mac.programmer] need Apple-Double format help

scotth@corp.sgi.com (Scott Henry) (01/03/90)

I am fairly new at programming for the Mac, so I don't know where to look.
We are using Unix boxes as AppleShare servers. Our interface (a GatorBox)
maps AppleShare <-> nfs/Apple-Double. I am writing a program to convert
ASCII reports to a format readable by programs on the Mac -- we just want
the users to be able to double-click on the icon. Where can I get the
structure of the resource fork of Apple-Double format? I have been able to
reverse engineer parts of it (it does work as is), but I expect that I
could do other neat things if I knew more.  Specifically, I'd like to be
able to mark the files as readonly/shareable.

Please send E-mail, as I only read this group irregularly. Thanks for your
help.

--
    Scott Henry <scotth@sgi.com>	| Tardis Express -- when it
    Information Services,		| absolutely, positively
    Silicon Graphics, Inc		| has to be there -- yesterday.

des7f@ra.cs.Virginia.EDU (David Sappington) (01/05/90)

scotth@corp.sgi.com (Scott Henry) writes:
> We are using Unix boxes as AppleShare servers. Our interface (a GatorBox)
> maps AppleShare <-> nfs/Apple-Double. I am writing a program to convert
> ASCII reports to a format readable by programs on the Mac -- we just want
> the users to be able to double-click on the icon. Where can I get the
> structure of the resource fork of Apple-Double format? I have been able to
> reverse engineer parts of it (it does work as is), but I expect that I
> could do other neat things if I knew more.  Specifically, I'd like to be
> able to mark the files as readonly/shareable.

A while back I had similar requirements.  All I really wanted was to have my
unix box generate binary files with a specific creator/type so that they
would show up on the desktop with their own icons and not be subjected to
the automatic TEXT conversion (CR <-> LF) that is so handy with text files. 
Unfortunately the docs on the Apple-Double format available from sumex
didn't seem to jibe with Cayman GatorSoftware's Apple-Double.

My problem was easily solved by creating a blank file, 'xxx', on the mac
with the desired creator/type and flags then copying the file to the
AppleShare/nfs volume.  GatorSoftware automatically generated a %xxx file in
addition to the blank xxx file.  Anytime I wanted the Unix box to create a
file, 'yyy', with the same finder stuff all I had to do was copy %xxx to
%yyy.  As I recall the % file was only 256 bytes so I eventually just hard
coded it into my Unix src.

BTW, I've noticed posts from people at Cayman -- wouldn't it be nice if someone
posted (or E-mailed to me) the docs on their Apple-Double format.  I'm
interested in writing a Unix program to convert between Cayman Apple-Double
and MacBinary so that I can use zmodem from home to xfer files that were
written by a Mac to an AppleShare/nfs volume.  Sort of like (x and %x) <=>
x.bin.

> Please send E-mail, as I only read this group irregularly. Thanks for your
> help.

I've sent E-mail too but I believe that this might be of general interest to
the net.

Dave Sappington
Inst. for Parallel Computation
U. of Virginia
des7f@virginia.edu
des7f@virginia.bitnet

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

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