[net.sources.mac] macintosh/Unix sources

chuqui@nsc.UUCP (Chuqui Q. Koala) (01/20/85)

I've now seen about 4 requests for BinHex and company, so it looks like it
is time to post this again. This shar contains the stuff you will need to
get your Mac to talk to a Unix system for file transfer (except
MacTerminal) and to convert to and from the major protocols used to
transfer data across the networks. See the README for details.

chuq
----

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	BinHex.hex
#	README
#	README.xbin
#	fromhexu.c
#	macget.c
#	macput.c
#	macsend
#	tohexu.c
#	xbin.c
# This archive created: Sat Jan 19 17:13:12 1985
# By:	Chuqui Q. Koala (The Warlocks Cave)
echo shar: extracting BinHex.hex '(7887 characters)'
sed 's/^XX//' << \SHAR_EOF > BinHex.hex
XX#APPLBNHX$2000
XX***COMPRESSED
XX***RESOURCE FORK
XX(    0   !2!   3@0   3+M_,Y"J  ,0^P "B%) !(Q
XX(&P !@ 6$6P "0 :3G5AX!%  !LA2@ <H  P*  8/B@ 
XX(!!.=6'*$4  &R%* !R@"C H !@^*  03G5![?S.0J@ 
XX( PQ0  8H $^*  09@ ! $*H !(Q;  & !:@$SXH !!F
XX(   [$YU88B@"#XH !!F  #>3G5A /]Z0F@ '* ,/B@ 
XX(!!G"@Q'_]5G'&   ,(^//_3""@ !P H9@  M* )/B@ 
XX(!!F  "J3G5A /]&0F@ '* ,/B@ $&8  )9.=4'M_,Y"
XX(*@ ##%M_=8 %C%\  ( +$*H "Z@1#XH !!F  !R3G5*
XX(    !@70FEN2&5X(%8R+C @+2T@,3 O,CDO.#0   $ 
XX( ___@ (  , "  "@ @ 0D ( &(@"'_R$ A_^_@(?_ (
XX( AP8 @(<$ ("'  " AP  @(<  ("'  " AP/P@)_$"(
XX( CX@$@(<3 H""'(& @.?P\$ C ' @$ !P$ @ < @& '
XX( ! '^< ( (? ! $!P ("   !!    (@   !0    (  
XX( ___@ /__\ #___@ ___\ /___@#___\ ____@/___X
XX( ____@/___X#___^ ____@/___X#___^ ____@/___X
XX( ____@/___X#___^ ____\'____ ____P'___\ ____
XX( !___\ /_X? !_\!P /^   !_    /@   !P    (  
XX(     =!4%!,        '$).2%@    !24-.(P      
XX((!&4D5&      "     *0 !          #____[ 10-
XX($%B;W5T($)I;DAE>,D      2T          )8  @  
XX(        /___M<$1FEL915!<'!L:6-A=&EO;B M/B!5
XX('!L;V%D     !55<&QO860@+3X@07!P;&EC871I;VX 
XX(     $M      M415A4(&9I;'1E<@  $@ !+0     *
XX($-O;7!R97-S960  !( #U-E;F0@;&EN92!F965D<P  
XX(    2T     !%%U:70 40       !4 9  R ,@!S  !
XX(             $    ! @ $      !& 50 6@&0! )/
XX($L       H "@ : 9"(.$)I;DAE>" R+C L("!W<FET
XX('1E;B!B>2!9=F5S($QE;7!E<F5U<B![0TE3(#<T,#$V
XX("PQ-S0Q?2       !H "@ J 9"(-'=I=&@@36%C05--
XX(*HL(&%N($5D:71O<B]!<W-E;6)L97(@9F]R('1H92!-
XX(&%C:6YT;W-H+@      .@ * $H!+(@J1F]R(&9U<G1H
XX(&5R(&EN9F]R;6%T:6]N(&-O;G1A8W0@36%I;G-T87DL
XX("       $H "@!: 2R((GM#25,@-S W-C4L-S,T?2!O
XX('(@*#@Q."D@.3DQ+38U-# N    %0!D &0 O@&0  $ 
XX(            @     J  $      #P Y@!0 2($ D]+
XX(       %  4 #L!&(@*7C @97)R;W(N(    !4 9 !D
XX( "^ 9   0            ,     =  !       \ .8 
XX(% !(@0"3TL       H "@ Z 2*(5$-O;G9E<G-I;VX@
XX(&]F($%P<&QI8V%T:6]N(&1O8W5M96YT('1O(&%N(%5P
XX(&QO860@9F]R;6%T(&1O8W5M96YT(&AA<R!B965N(&-O
XX(&UP;&5T960A(    !4 9 !D +@!F@ !            
XX( 0     D  #       V /  2@$L! )/2P      "@ *
XX(  J 2R(4$-O;G9E<G-I;VX@;V8@57!L;V%D(&9O<FUA
XX('0@9&]C=6UE;G0@=&\@07!P;&EC871I;VX@9&]C=6UE
XX(&YT(&AA<R!B965N(&-O;7!L971E9"$      "H "@ Z
XX( #FB )>,       .@ * $H YH@"7C$    3 &0 9 #8
XX( &5  $!              Z4     4AM__RH;JC^J1*I
XX(#!"IZE[80 , B \  #__Z R/SP  JGI/SP  ZEY/SP 
XX( 2I>6$ # H;?  !_?P;?  !_?^H4"M/_<*IM$(G/SS_
XX(/](;?VRJ7 0'V?N,"W]LM! ,#L !D[[  +_X  R_^  
XX(!C_X/_@_^ !8/_@_^#_X/_@,"W]P @   AGOD*G("W]
XX(+0_ *D^(!]@   R0F<O+?V\2&W]QJDL,!_00# [  9.
XX(/L  O^6  X!"/^6_Y;_EO^60J<O+?V\J3T@'RM _<HP
XX("W]RM! ,#L !D[[  ( !@ . &9"9ZDX8 #_8# M_<P,
XX($   68P0J<_/  !0J<O//____^I?"M7_<ZI%4*G2&W]
XX(-*ID3 M_=(,0  !9NXO+?W.J8-@OD*G/SP  :E)/RW]
XX(,Q(;?O.J49"9TAM^\ZIMC ?8* P+?W,T$ P.P &3OL 
XX( +_D@": ^3_D@ 4_Y( , !,_Y( : HM  ']_$*G/SP 
XX( *I23\\  0?+?W\J45@ /]D"BT  ?W_0J<_/  "J4D_
XX(#P !A\M_?^I16  _T@*+0 !_?U"IS\\  *I23\\  <?
XX("W]_:E%8 #_+*GT2&W]LB\M_<:ILV  _H(P+?VT9P#^
XX('I"9S\\ &0_/ !D+RW]M#\\  "IZ3 ?8 #^8#\\ $8_
XX(#P 1DAZ"F!"IS\\__]"IT*G2&W]'C\\  *IZDHM_1YG
XX( #^TC\\ $8_/ !&2'H, TAZ"C1"ITAM_6@_/  !J>I*
XX("W]:&< _JY)[?UH80 (AF$ "'1A  BR(7Q415A4 " A
XX('P@(" @ "2@#3XH !!F  D^< ))[?UH1>WYQ&$ !_ [
XX($#]UAM\  ']^TI'9@ )(&$ !DA)[?T>80 (;BMH "#]
XX(. K:  D_>0P*  H D#P #M _>@K: ! _=@K:  V_=QA
XX(  !\$HM_?]G"$'Z"<UA  &X80 '*$)M_?)"+?WT/SP 
XX( H_/ !&J)-*K?W89RA"K?W82&W]<JB$2'H*;JB$0?H)
XX(*=A  &$< %)[?T>1?@  &$ !W)@+$JM_=QG8D*M_=Q(
XX(&W]<JB$2'H*,ZB$0?H)BF$  59P 4GM_1Y%^   80 '
XX("X[0/W4&WP  ?WZ2D=F  A>80 !M$HM^\YG!F$  )A@
XX(/!!^@EA80 !($GM_1XP+?W480 ')D(M_?I@ /]B2BW]
XX(/]F$D'Z"59A  $6$"W]]&$  61@$$'Z"3QA  $$,"W]
XX(/)A  %(80  Y&$ !/A)[?UH,"W]UF$ !N)"+?W[+RW]
XX(,:I%$*G/SP  T*G+SS_____J7PK5_W.J15"ITAM_=*I
XX()$P+?W2#$   6;N+RW]SJF#8 #] $'M^\Y"01(82BW]
XX(/]G+D('$ %A   X8"1"0! 8T2W]]#0M_?+40.=:.T+]
XX(/)*+?W_9@9A  #,8 1A   24<G_VDHM_?]G!&$  "I@
XX($IT!PP'  9F$@(& #\&!@ @P49A  0TP49"!^,0XQ92
XX( =1RO_@3G5*!V<:# < !F<&XPY2!V#T @8 /P8& " 0
XX( 9A  0&3G5A   6< UA  /Z2BW]_6<&< IA  /N3G5"
XX($$2&& &$!AA  /@4<G_^$YU0?H'LV'0<"-A  /.("W]
XX(.!A   :("W]Y&$  !)P)&$  [@P+?WH80  $F"N<@/A
XX()AA  .F4<G_^$YU/P#@2&$   0P'Q\ Z AA   $$!]A
XX(  $.&   X1![?S.0J@ ##%M_=0 &$/M^\\A20 @(7P 
XX(   (  D0F@ +$*H "Z@ CXH !!G" Q'_]EF  9R&V@ 
XX("O[SDYU/SP 1C\\ $9(>@<60J=*+?W\9@@_//__0J=@
XX( @_/  !2'H&^D*G2&W]'C\\  *IZDHM_1YG /MX/SP 
XX($8_/ !&2'H(J4AZ!MI"ITAM_6@_/  !J>I*+?UH9P#[
XX(%1)[?T>80 %8' !1?@  &$ !+P[0/W4&WP  ?WZ2D=F
XX(  %[$(M_?XK?%1%6%3]X"M\(" @(/WD0FW]Z$)M_?)"
XX("W]]&$ !8A"04'M^\X2&&<  ?Y@!@P8 "-G!E')__A@
XX(.(,00 (929A  +>*T#]X&$  M8K0/WD#$$ !640#!@ 
XX("1F"F$  M!E!#M _>AA  -Z2>W]:&$ !)QA  2*80 $
XX(,@A;?W@ " A;?WD "0P+?WH@6@ ** -/B@ $&8 !5!A
XX(  %#$/Z!C-A  +X9@H;?  !_?YA  3X/SP "C\\ $:H
XX()-(;?URJ(1#^@8N80 "U&8,2'H&QZB$80 $U& D0_H&
XX( =A  *^9AI(>@:^J(1A  2^< ))[?UH1>WYQ&$  \9@
XX( YP DGM_6A%[?G$80 #H#M _=8;?  !_?M*1V8 !-!A
XX(  $.F$  ?1@!&$ !()*+?O.9QY#^@6?80 ":&<&80 !
XX( 1@YD/Z!;]A  )89@1A  1>80 !D$GM_6@P+?W680 #
XX('I"+?W[0_H%D&$  C9G /](0_H%<V$  BIG /\\2>W]
XX(!XP+?W480 #4D(M_?HO+?W&J11"IS\\  1"IR\\____
XX(/^I?"M?_<Y#^@5R80 !]&8.0_H&%Q-8 !,36  48#1#
XX(/H%4F$  =QF)D/Z!>T36  .$U@ #Q-8 ! 36  11?H&
XX(!U'Z@ 1,"W]\F$  7A@%$/Z!>Y%^@8<1^H %A M_?1A
XX(  !:B\)+PI"IT*GJ8LO+?W.J15"ITAM_=*ID3 M_=(,
XX($   6;N+RW]SJF#8 #Y!DGM_1XP+?W480 "H$(M_?I@
XX( #X\F$  49*+?W^9B0, 0 "94A"0&$  .)E0-$M_?0T
XX("W]\M1 YUH[0OWR80  7&#<0@=A   H92(R & :80  
XX(!YE&-$M_?0T+?WRU$#G6CM"_?)A   T4<G_Y$YU= =*
XX( =F%AP8! 8 ( P& $!E!@ \  %.=>4.?@;C%N,04P=1
XX(,K_W@(\ /Y.=2)M_>H2P"M)_>I2K?WN#*T  "  _>YD
XX( ).=4CGPX!![?S.0J@ ##%M_=8 &$/MV<0A20 @(6W]
XX(.X )$)H "Q"J  NH ,^*  09@ "VDS? <-#[=G$*TG]
XX(.I"K?WN3G5T ^&($!A305'*__A.=6$   )A   "%!A3
XX($$* @ P# ( "F4*!@( B0P" /IE# ("  _I2( " CP 
XX(/Y.=3\ X$AA C ?'P#H"&$"$!]A!!; 3G4"   /    
XX(# ,   Z90)> $YU0>W[SA(89PP,$  *9@92B%,!9O1.
XX('5AZ$)"%!FR F4,8 2S"&8&4<K_^D) 3G5"IS\\  %"
XX(*<O//____^IO2M7_<:H<S\\  "HAS\\  RHBC\\  "H
XX((@_/   J(E.=6'./SP "C\\ !:HDTAZ S&HA!M\  3]
XX(/4K;?W@_?9(;?WUJ(0_/  */SP )JB32'H#-:B$*VW]
XX(.3]]DAM_?6HA#\\  H_/ !FJ)-(>@,\J(1.=6$ _WP_
XX(#P "C\\ !:HDTAZ ]ZHA!M\  3]]2MM_>#]]DAM_?6H
XX((0_/  */SP )JB32'H#WJB$*VW]Y/WV2&W]]:B$/SP 
XX( H_/ !FJ)-(>@+HJ(1.=4'M_,Y"J  ,0^P "B%) !(Q
XX(&P !@ 6$6P "0 :3G5AX!%  !LA2@ <H  P*  8/B@ 
XX(!!.=6'*$4  &R%* !R@"C H !@^*  03G5![?S.0J@ 
XX( PQ0  8H $^*  09@ ! $*H !(Q;  & !:@$SXH !!F
XX(   [$YU88B@"#XH !!F  #>3G5A /]Z0F@ '* ,/B@ 
XX(!!G"@Q'_]5G'&   ,(^//_3""@ !P H9@  M* )/B@ 
XX(!!F  "J3G5A /]&0F@ '* ,/B@ $&8  )9.=4'M_,Y"
XX(*@ ##%M_=8 %C%\  ( +$*H "Z@1#XH !!F  !R3G5*
XX("W]^F<00BW]^DGM_1XP+?W480#_1DHM_?MG$$(M_?M)
XX(.W]:# M_=9A /\P3G5![?S.0J@ ##%M_=0 &$/M^\\A
XX($D ("%\    _P D,7P-@  L0J@ +J "/B@ $&<(#$?_
XX(-EF   *&V@ *_O.3G4_!V&.0J>I)" ?9PJPK?W&9@0O
XX( "I%$*G/SP  D*G+SS_____J7PK7_W./A]A   N+RW]
XX(,ZI%3\\  2IR$*G2&W]TJF1,"W]T@Q   %F[B\M_<ZI
XX((,N;?W"8 #T[$'Z C="0! 89PJ^ &<&$!C0P&#R+PA"
XX(*="IT*GJ8M.=4*G/SP  :F_+Q="9ZDU+SQ$4E92J4U"
XX(*<_/  "J;]"9ZDUJ3=.=4'MV<0P/"0\8 )"&%'(__Q.
XX('5415A4 "TH5&AI<R!F:6QE(&UU<W0@8F4@8V]N=F5R
XX('1E9"!W:71H($)I;DAE>"Y(97@I RHJ*@TJ*BI#3TU0
XX(%)%4U-%1! J*BI215-/55)#12!&3U)+#"HJ*D1!5$$@
XX($9/4DL.*BHJ14Y$($]&($1!5$$'*BHJ0U)#.@PJ*BI#
XX($A%0TM354TZ)5194$4@;V8@;F5W(&9I;&4@:7,N+BXN
XX("XN+BXN+BXN+BXN+CH@(D-214%43U(@;V8@;F5W(&9I
XX(&QE(&ES+BXN+BXN+BXN+CH@*$-O;G9E<G-I;VX@:6X@
XX('!R;V-E<W,@+2!0;&5A<V4@<W1A;F0@8GG)#" Z($1A
XX('1A($9O<FL0(#H@4F5S;W5R8V4@1F]R:Q%#4D,@:6X@
XX(&9I;&4Z(# P,# 40VAE8VMS=6T@:6X@9FEL93H@,# <
XX($YO(&-H96-K<W5M('!R97-E;G0@:6X@9FEL9<D40V%L
XX(&-U;&%T960@0U)#.B P,# P%T-A;&-U;&%T960@0VAE
XX(&-K<W5M.B P,"%465!%(&]F($%P<&QI8V%T:6]N(&1O
XX(&-U;65N="!I<SH@)$-214%43U(@;V8@07!P;&EC871I
XX(&]N(&1O8W5M96YT(&ES.B 14V%V92!D;V-U;65N="!A
XX(',ZWPY$:7)E8W1O<GD@9G5L;-X)1&ES:R!F=6QLW -)
XX("]/U!A7<FET92!P<F]T96-T960@9&ES:V5T=&73"T9I
XX(&QE(&QO8VME9-(-5F]L=6UE(&QO8VME9  +1FEL92!S
XX('ES=&5M    &    "@  "8\    "    "   #\\  &I
XX(/    $    4@0  $X$   $R  !.' !<    ' $R  A"
XX($Y(6    $I)0TXC    5D92148   !B0DY$3    &Y-
XX($5.50 ! 'I$3$]'  , DD1)5$P  P#"5TE.1    /)#
XX($]$10 ! /X  /__        3=@ @/__    '   3=0 
XX((#__P   2   $W0 (#__P   2L  $W,  +__P   7@ 
XX( !-Q  !__\   %+  !-R  $__\   0)  !-J  #__\ 
XX(  #>   3;   O__   #,0  3;@  ?__   "$@  3<  
XX( 3__P  !"(  $VD  /__P   Y$  $VL  +__P   TH 
XX( !-M  !__\   (K  !-O  !__\   2V  !-H   __\@
XX$P 390  39@  ?__-  $S0  39P
XX***END OF DATA
XX***CRC:609E
XX
SHAR_EOF
if test 7887 -ne "`wc -c BinHex.hex`"
then
echo shar: error transmitting BinHex.hex '(should have been 7887 characters)'
fi
echo shar: extracting README '(1714 characters)'
sed 's/^XX//' << \SHAR_EOF > README
XXThis directory contains the following files:
XX
XX
XXBinHex.hex -- binhex version of binhex. This should be converted by xbin
XXinto a .rsrc file and downloaded to the mac. It can be used to convery
XXbinhex format files to their component parts on the mac and to generate
XXbinhex format files for uploading to unix and transport through the net.
XX
XXREADME - this file
XX
XXREADME.xbin - description of the xbin program.
XX
XXfromhexu.c - unix based program to decode .dl (an alternate form of network
XXtransmission) format files into .rsrc files for downloading. It is a
XXfilter, use it in the form 'fromhexu <file.dl >file.rsrc'
XX
XXmacget.c- unix side of the download program. Set up macterminal to be an 8
XXbit path, no XON/XOFF, and that the computer on the other side is another
XXMac and then type macget on unix. Use the mouse to
XXexecute 'send file' from the 'File' menu. by default macget will get all
XXthree parts of the file (data, rsrc and info), but the -d -r and -i flags 
XXoverride that. The -u flag is used to download a text file (.data part)
XXwhile doing neccessary translation of \r to \n to make it useful on a unix
XXsite.
XX
XXmacput.c- unix side of the upload program. Same setup and option flags as
XXmacget, simply type 'macput <file>' to start, and macterminal will
XXrecognize it automatically.  'macput -u <file>' will do carriage return
XXmapping from unix to the mac for you.
XX
XXtohexu.c - opposite of fromhexu. takes a .rsrc file and converts it to a
XX.dl format for transmission.
XX
XXxbin.c - converts a BinHex format file to the component parts on the unix
XXend. Equivalent to BinHex on the Macintosh end-- useful for bootstrapping
XXBinHex to the Mac and doing the conversions before downloading (which
XXshrinks the files somewhat).
XX
SHAR_EOF
if test 1714 -ne "`wc -c README`"
then
echo shar: error transmitting README '(should have been 1714 characters)'
fi
echo shar: extracting README.xbin '(1919 characters)'
sed 's/^XX//' << \SHAR_EOF > README.xbin
XXThis program will convert a file in BinHex format
XXinto binary files suitable for downloading via
XXMacterminal / macput from a un*x host.  It creates
XXall three forks (.info, .data, and .rsrc), so that
XXthe filetype, author, create/modify times and eventually
XXthe file flags (ie the Bundle Bit) are all passed on
XXto MacTerminal when the file is created on the Mac.
XX
XXWhen you receive a BinHex file in the mail or news,
XXsave the message in a file with extension ".hex" --
XXfor example "freeware.hex".  Then invoke "xbin freeware".
XXThis reads freeware.hex and creates freeware.data,
XXfreeware.rsrc, and freeware.info.  When this is done,
XXyou can download through MacTerminal by running
XX"macput freeware".
XX
XXThe compressed data format is almost identical to
XXthat used by uuencode/uudecode.  They both store 6
XXbits of data per byte, both offset the binary data
XXby 0x20 (' '), and both have the number of bytes in
XXthe record at the beginning of each record.  The
XXdifference is exactly 2 bits.  In uuencode format
XXthe first byte contains the entire (6 bit) byte count,
XXbut in BinHex format the byte count is 8 bits -- 6 from
XXthe first byte, and 2 from the second.
XX
XXNote that the problem of trailing spaces has been worked
XXaround in this program -- short buffers are filled out
XXwith spaces as needed.  So there is no need to manually
XXrestore lost spaces as before.
XX
XXAs soon as I can figure out how the crc is computed
XXI will post a new version of xbin which actually verifies
XXthe crc value.  For now the crc line is ignored completely.
XXGiven the crc formula, it will be straightforward to write
XXthe complementary encoding program.  How about calling it bhex?
XX
XXAs usual, I'm open to suggestions and bug reports.  I hope
XXthis will save a lot of people the trouble I went through
XXto figure out the format . . . enjoy!
XX
XX	Dave Johnson
XX	Brown University Computer Science
XX	ddj%brown@csnet-relay.ARPA
XX	{ihnp4,decvax,allegra,linus}!brunix!ddj
SHAR_EOF
if test 1919 -ne "`wc -c README.xbin`"
then
echo shar: error transmitting README.xbin '(should have been 1919 characters)'
fi
echo shar: extracting fromhexu.c '(535 characters)'
sed 's/^XX//' << \SHAR_EOF > fromhexu.c
XX/* fromhex.c, UNIX version */
XX
XX#include <stdio.h>
XX
XXint bytes,sum;
XX
XXmain()
XX{
XX	register i,v;
XX	register n;
XX
XX	n = 0;
XX	v = 0;
XX	while ((i = getchar()) != EOF) {
XX		i &= 0177;
XX		if (i == '|') 
XX			break;
XX		if (i < 0100 || i > 0117)
XX			continue;
XX		v = (v << 4) | (i & 0xF);
XX		if ((++n & 1) == 0) {
XX			putchar(v);
XX			sum += v;
XX			v = 0;
XX			bytes++;
XX		}
XX	}
XX	n = 0;
XX	for (i = 0 ; i < 8 ; i++)
XX		n = (n << 4) | (getchar() & 0xF);
XX	if (n != (bytes + sum))
XX		fprintf(stderr, "bad checksum\n");
XX	else
XX		fprintf(stderr, "checksum good!\n");
XX	exit(0);
XX}
SHAR_EOF
if test 535 -ne "`wc -c fromhexu.c`"
then
echo shar: error transmitting fromhexu.c '(should have been 535 characters)'
fi
echo shar: extracting macget.c '(7827 characters)'
sed 's/^XX//' << \SHAR_EOF > macget.c
XX#include <stdio.h>
XX#include <signal.h>
XX#include <setjmp.h>
XX#include <sgtty.h>
XX
XX#ifdef NO_RENAME
XX#define rename(old, new)	link(old, new); unlink(old)
XX#endif
XX
XX/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
XX#define TIMEDIFF 0x7c25b080
XX
XX#define RECORDBYTES 132
XX#define DATABYTES 128
XX#define NAMEBYTES 63
XX
XX#define RETRIES 10
XX#define SOHTIMO 10
XX#define LINTIMO 20
XX#define CHRTIMO 2
XX
XX#define MAXRECNO 0xff
XX#define BYTEMASK 0xff
XX
XX#define TMO -1
XX#define DUP '\000'
XX#define SOH '\001'
XX#define EOT '\004'
XX#define ACK '\006'
XX#define NAK '\025'
XX#define CAN '\030'
XX#define EEF '\032'
XX#define ESC '\033'
XX
XX#define H_NLENOFF 1
XX#define H_NAMEOFF 2
XX/* 65 <-> 80 is the FInfo structure */
XX#define H_TYPEOFF 65
XX#define H_AUTHOFF 69
XX
XX#define H_LOCKOFF 81
XX#define H_DLENOFF 83
XX#define H_RLENOFF 87
XX#define H_CTIMOFF 91
XX#define H_MTIMOFF 95
XX
XX#define H_OLD_DLENOFF 81
XX#define H_OLD_RLENOFF 85
XX
XX#define TEXT 0
XX#define DATA 1
XX#define RSRC 2
XX#define FULL 3
XX
XXchar *textension;
XXint mode, txtmode;
XXint pre_beta;	/* -o flag; for compatibility with MacTerminal Version -0.15X */
XX
XXstruct macheader {
XX	char m_name[NAMEBYTES+1];
XX	char m_type[4];
XX	char m_author[4];
XX	long m_datalen;
XX	long m_rsrclen;
XX	long m_createtime;
XX	long m_modifytime;
XX} mh;
XX
XXstruct filenames {
XX	char f_info[256];
XX	char f_data[256];
XX	char f_rsrc[256];
XX} files;
XX
XXchar tmpname[16];
XX
XXint lastack;
XXchar buf[DATABYTES];
XX
XX/*
XX * macget -- receive file from macintosh using xmodem protocol
XX * Dave Johnson, Brown University Computer Science
XX *
XX * (c) 1984 Brown University 
XX * may be used but not sold without permission
XX *
XX * created ddj 5/22/84 
XX * revised ddj 6/29/84 -- added [-rdu] options
XX * revised ddj 7/16/84 -- protocol changes for MacTerminal Beta Version 0.5X
XX * revised ddj 7/31/84 -- pre-4.2 signal bugs fixed in timedout()
XX * revised ddj 11/7/84 -- renamed send_sync() -> get_sync()
XX * revised wi/ss 12/6/84 -- take off .text extension option "-U"
XX */
XXchar usage[] = "usage: \"macget [-o] [-rduU] [filename]\"\n";
XX
XXmain(ac, av)
XXchar **av;
XX{
XX	char *name;
XX
XX	mode = FULL;
XX	name = "";
XX	ac--; av++;
XX	while (ac) {
XX		if (av[0][0] == '-') {
XX			switch (av[0][1]) {
XX			case 'r':
XX				mode = RSRC;
XX				break;
XX			case 'd':
XX				mode = DATA;
XX				break;
XX			case 'u':
XX				mode = TEXT;
XX				textension = ".text";
XX				break;
XX			case 'U':
XX				mode = TEXT;
XX				textension = "";
XX				break;
XX			case 'o':
XX				pre_beta++;
XX				break;
XX			default:
XX				fprintf(stderr, usage);
XX				exit(1);
XX			}
XX		}
XX		else {
XX			name = av[0];
XX		}
XX		ac--; av++;
XX	}
XX
XX	setup_tty();
XX	if (get_sync() == ACK) {
XX		txtmode = 0;
XX		recv_hdr(name);
XX		if (mode == TEXT) txtmode++;
XX		recv_file(files.f_data, mh.m_datalen, 1);
XX		txtmode = 0;
XX		recv_file(files.f_rsrc, mh.m_rsrclen, 0);
XX	}
XX	reset_tty();
XX}
XX
XXrecv_hdr(name)
XXchar *name;
XX{
XX	long get4();
XX	int n;
XX	FILE *fp;
XX	char *np;
XX
XX	strcpy(tmpname, "#machdrXXXXXX");
XX	mktemp(tmpname);
XX	recv_file(tmpname, (long)DATABYTES, 1);
XX
XX	fp = fopen(tmpname, "r");
XX	if (fp == NULL) {
XX		perror("temp file");
XX		cleanup(-1);
XX	}
XX	fread(buf, 1, DATABYTES, fp);
XX	fclose(fp);
XX
XX	if (name && *name) {
XX		n = strlen(name);
XX		if (n > NAMEBYTES) n = NAMEBYTES;
XX		strncpy(mh.m_name, name, n);
XX		mh.m_name[n] = '\0';
XX	}
XX	else {
XX		n = buf[H_NLENOFF] & BYTEMASK;
XX		if (n > NAMEBYTES) n = NAMEBYTES;
XX		strncpy(mh.m_name, buf + H_NAMEOFF, n);
XX		mh.m_name[n] = '\0';
XX	}
XX	for (np = mh.m_name; *np; np++)
XX		if (*np == ' ') *np = '_';
XX
XX	if (mode == FULL) {
XX		sprintf(files.f_info, "%s.info", mh.m_name);
XX		rename(tmpname, files.f_info);
XX		tmpname[0] = '\0';
XX		sprintf(files.f_data, "%s.data", mh.m_name);
XX		sprintf(files.f_rsrc, "%s.rsrc", mh.m_name);
XX	}
XX	else {
XX		unlink(tmpname);
XX		tmpname[0] = '\0';
XX		switch (mode) {
XX		case RSRC:
XX			sprintf(files.f_data, "/dev/null");
XX			sprintf(files.f_rsrc, "%s.rsrc", mh.m_name);
XX			break;
XX
XX		case DATA:
XX			sprintf(files.f_data, "%s.data", mh.m_name);
XX			sprintf(files.f_rsrc, "/dev/null");
XX			break;
XX
XX		case TEXT:
XX			sprintf(files.f_data, "%s%s", mh.m_name, textension);
XX			sprintf(files.f_rsrc, "/dev/null");
XX			break;
XX		}
XX	}
XX
XX	strncpy(mh.m_type, buf + H_TYPEOFF, 4);
XX	strncpy(mh.m_author, buf + H_AUTHOFF, 4);
XX	if (pre_beta) {
XX		mh.m_datalen = get4(buf + H_OLD_DLENOFF);
XX		mh.m_rsrclen = get4(buf + H_OLD_RLENOFF);
XX	}
XX	else {
XX		mh.m_datalen = get4(buf + H_DLENOFF);
XX		mh.m_rsrclen = get4(buf + H_RLENOFF);
XX		mh.m_createtime = get4(buf + H_CTIMOFF);
XX		mh.m_modifytime = get4(buf + H_MTIMOFF);
XX	}
XX}
XX
XXrecv_file(fname, bytes, more)
XXchar *fname;
XXlong bytes;
XXint more;
XX{
XX	register int status, n;
XX	FILE *outf;
XX	int naks = 0;
XX
XX	lastack = 0;
XX	outf = fopen(fname, "w");
XX	if (outf == NULL) {
XX		perror(fname);
XX		cleanup(-1);
XX	}
XX	for (;;) {
XX		status = rec_read(buf, DATABYTES);
XX		switch (status) {
XX		case EOT:
XX			if (!pre_beta)
XX				tputc(ACK);
XX			if (more)
XX				tputc(NAK);
XX			fclose(outf);
XX			return;
XX		case ACK:
XX			tputc(ACK);
XX			naks = 0;
XX			n = (bytes > DATABYTES) ? DATABYTES : bytes;
XX			bytes -= n;
XX			fwrite(buf, n, 1, outf);
XX			break;
XX		case DUP:
XX			tputc(ACK);
XX			naks = 0;
XX			break;
XX		case NAK:
XX			purge(CHRTIMO);
XX			if (naks++ < RETRIES) {
XX				tputc(NAK);
XX				break;
XX			}
XX			/* fall through */
XX		case CAN:
XX			tputc(CAN);
XX			fclose(outf);
XX			/* unlink fname? */
XX			cleanup(-1);
XX			/* NOTREACHED */
XX		}
XX	}
XX}
XX
XXget_sync()
XX{
XX	int c;
XX
XX	for (;;) {
XX		c = tgetc(60);
XX		switch (c) {
XX		case ESC:
XX			break;
XX		case CAN:
XX		case EOT:
XX		case TMO:
XX			return c;
XX		default:
XX			continue;
XX		}
XX		c = tgetc(1);
XX		if (c != 'a')
XX			continue;
XX		tputc(ACK);
XX		return ACK;
XX	}
XX}
XX
XXrec_read(buf, recsize)
XXchar buf[];
XXint recsize;
XX{
XX	int c, rec, rec_bar, cksum;
XX
XX	c = tgetc(SOHTIMO);
XX	switch (c) {
XX	case TMO:
XX	default:
XX		return NAK;
XX	case EOT:
XX		return EOT;
XX	case CAN:
XX		return CAN;
XX	case SOH:
XX		/* read header */
XX		rec = tgetc(CHRTIMO);
XX		if (rec == TMO)
XX			return NAK;
XX		rec_bar = tgetc(CHRTIMO);
XX		if (rec_bar == TMO)
XX			return NAK;
XX
XX		/* check header */
XX		if (rec != MAXRECNO - rec_bar) return NAK;
XX
XX		/* fill buffer */
XX		cksum = tgetrec(buf, recsize, LINTIMO);
XX		if (cksum == TMO)
XX			return NAK;
XX
XX		/* get checksum */
XX		c = tgetc(CHRTIMO);
XX		if (c == TMO)
XX			return NAK;
XX		if (c != (cksum & BYTEMASK))
XX			return NAK;
XX
XX		/* check record number */
XX		if (rec == lastack)
XX			return DUP;
XX		if (rec != ((lastack + 1) & MAXRECNO))
XX			return CAN;
XX		else {
XX			lastack = rec;
XX			return ACK;
XX		}
XX	}
XX	/* NOTREACHED */
XX}
XX
XXpurge(timeout)
XXint timeout;
XX{
XX	int c;
XX
XX	do {
XX		c = tgetc(timeout);
XX	} while (c != TMO);
XX}
XX
XXstatic int ttyfd;
XXstatic FILE *ttyf;
XXjmp_buf timobuf;
XX
XXtgetrec(buf, count, timeout)
XXchar *buf;
XXint count, timeout;
XX{
XX	char *bp;
XX	int i, cksum;
XX
XX	if (setjmp(timobuf))
XX		return TMO;
XX	
XX	alarm(timeout);
XX	i = fread(buf, 1, count, ttyf);
XX	alarm(0);
XX	if (i != count)
XX		return TMO;
XX	
XX	cksum = 0;
XX	bp = buf;
XX	for (i = 0; i < count; bp++, i++) {
XX		cksum += *bp;
XX		if (txtmode && *bp == '\r')
XX			*bp = '\n';
XX	}
XX	return cksum;
XX}
XX
XXtgetc(timeout)
XXint timeout;
XX{
XX	int c;
XX
XX	if (setjmp(timobuf))
XX		return TMO;
XX
XX	alarm(timeout);
XX	c = getc(ttyf);
XX	alarm(0);
XX
XX	if (c == -1)	/* probably hung up or logged off */
XX		return EOT;
XX	else
XX		return c & BYTEMASK;
XX}
XX
XXtputc(c)
XXchar c;
XX{
XX	write(ttyfd, &c, 1);
XX}
XX
XXtimedout()
XX{
XX	signal(SIGALRM, timedout);	/* for pre-4.2 systems */
XX	longjmp(timobuf, 1);
XX}
XX
XXstatic struct sgttyb otty, ntty;
XX/* should turn messages off */
XX
XXsetup_tty()
XX{
XX	int cleanup();
XX	int timedout();
XX
XX	ttyf = stdin;
XX	ttyfd = fileno(stdout);
XX	ioctl(ttyfd, TIOCGETP, &otty);
XX	signal(SIGHUP, cleanup);
XX	signal(SIGINT, cleanup);
XX	signal(SIGQUIT, cleanup);
XX	signal(SIGTERM, cleanup);
XX	signal(SIGALRM, timedout);
XX	ntty = otty;
XX	ntty.sg_flags = RAW|ANYP;
XX	ioctl(ttyfd, TIOCSETP, &ntty);
XX}
XX
XXreset_tty()
XX{
XX	sleep(2);	/* should wait for output to drain */
XX	ioctl(ttyfd, TIOCSETP, &otty);
XX}
XX
XXcleanup(sig)
XXint sig;
XX{
XX	if (tmpname[0] != '\0')
XX		unlink(tmpname);
XX	reset_tty();
XX	exit(sig);
XX}
XX
XXlong
XXget4(bp)
XXchar *bp;
XX{
XX	register int i;
XX	long value = 0;
XX
XX	for (i = 0; i < 4; i++) {
XX		value <<= 8;
XX		value |= (*bp & BYTEMASK);
XX		bp++;
XX	}
XX	return value;
XX}
SHAR_EOF
if test 7827 -ne "`wc -c macget.c`"
then
echo shar: error transmitting macget.c '(should have been 7827 characters)'
fi
echo shar: extracting macput.c '(8781 characters)'
sed 's/^XX//' << \SHAR_EOF > macput.c
XX/*
XX
XXHere is the source for the current incarnation of macput . . . .
XXIt is compatible with the 1.1 Release version of MacTerminal,
XXthough in case you still need to use the -0.15X version, there's
XXthe "-o" option to provide compatibility.  Versions 0.5 and 0.9
XXhave a bug in the record checksum calculation which will break
XXfile transfers, so 1.1 is recommended.
XX
XXPlease pass any improvements/bug fixes on to me, and
XXif you know of any good protocols for use on a flow-controlled
XXline, let me know.
XX
XX	Dave Johnson
XX	ddj%brown@csnet-relay.arpa
XX	Brown University Computer Science
XX
XX*/
XX#include <stdio.h>
XX#include <signal.h>
XX#include <setjmp.h>
XX#include <sgtty.h>
XX#include <time.h>
XX#include <sys/types.h>
XX#include <sys/stat.h>
XX#include <sys/timeb.h>
XX
XX/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
XX#define TIMEDIFF 0x7c25b080
XX
XX#define RECORDBYTES 132
XX#define DATABYTES 128
XX#define NAMEBYTES 63
XX
XX#define RETRIES 10
XX#define ACKTIMO 10
XX
XX#define MAXRECNO 0xff
XX#define BYTEMASK 0xff
XX
XX#define TMO -1
XX#define DUP '\000'
XX#define SOH '\001'
XX#define EOT '\004'
XX#define ACK '\006'
XX#define NAK '\025'
XX#define CAN '\030'
XX#define EEF '\032'
XX#define ESC '\033'
XX
XX#define H_NLENOFF 1
XX#define H_NAMEOFF 2
XX/* 65 <-> 80 is the FInfo structure */
XX#define H_TYPEOFF 65
XX#define H_AUTHOFF 69
XX
XX#define H_LOCKOFF 81
XX#define H_DLENOFF 83
XX#define H_RLENOFF 87
XX#define H_CTIMOFF 91
XX#define H_MTIMOFF 95
XX
XX#define H_OLD_DLENOFF 81
XX#define H_OLD_RLENOFF 85
XX
XX#define TEXT 0
XX#define DATA 1
XX#define RSRC 2
XX#define FULL 3
XX
XXint mode, txtmode;
XXint pre_beta;	/* -o flag; for compatibility with MacTerminal Version -0.15X */
XX
XXstruct macheader {
XX	char m_name[NAMEBYTES+1];
XX	char m_type[4];
XX	char m_author[4];
XX	long m_datalen;
XX	long m_rsrclen;
XX	long m_createtime;
XX	long m_modifytime;
XX} mh;
XX
XXstruct filenames {
XX	char f_info[256];
XX	char f_data[256];
XX	char f_rsrc[256];
XX} files;
XX
XXint recno;
XXchar buf[DATABYTES];
XX
XX/*
XX * macput -- send file to macintosh using xmodem protocol
XX * Dave Johnson, Brown University Computer Science
XX *
XX * (c) 1984 Brown University 
XX * may be used but not sold without permission
XX *
XX * created ddj 6/17/84 
XX * revised ddj 7/16/84 -- protocol changes for MacTerminal Beta Version 0.5X
XX * revised ddj 7/31/84 -- pre-4.2 signal bugs fixed in timedout()
XX * revised ddj 7/31/84 -- moved forge_info() call ahead of send_sync()
XX * revised ddj 11/6/84 -- added sleep(5) after send_sync to give mac time to
XX *	turn off xon mode, set up sio chip, and put up progress indicator
XX */
XXchar usage[] =
XX    "usage: \"macput [-o] [-rdu] [-t type] [-a author] [-n name] filename\"\n";
XX
XXmain(ac, av)
XXchar **av;
XX{
XX	int n;
XX	char *filename;
XX
XX	if (ac == 1) {
XX		fprintf(stderr, usage);
XX		exit(1);
XX	}
XX
XX	mode = FULL;
XX	ac--; av++;
XX	while (ac) {
XX		if (av[0][0] == '-') {
XX			switch (av[0][1]) {
XX			case 'r':
XX				mode = RSRC;
XX				strncpy(mh.m_type, "APPL", 4);
XX				strncpy(mh.m_author, "CCOM", 4);
XX				break;
XX			case 'u':
XX				mode = TEXT;
XX				strncpy(mh.m_type, "TEXT", 4);
XX				strncpy(mh.m_author, "MACA", 4);
XX				break;
XX			case 'd':
XX				mode = DATA;
XX				strncpy(mh.m_type, "TEXT", 4);
XX				strncpy(mh.m_author, "????", 4);
XX				break;
XX			case 'n':
XX				if (ac > 1) {
XX					ac--; av++;
XX					n = strlen(av[0]);
XX					if (n > NAMEBYTES) n = NAMEBYTES;
XX					strncpy(mh.m_name, av[0], n);
XX					mh.m_name[n] = '\0';
XX					break;
XX				}
XX				else goto bad_usage;
XX			case 't':
XX				if (ac > 1) {
XX					ac--; av++;
XX					strncpy(mh.m_type, av[0], 4);
XX					break;
XX				}
XX				else goto bad_usage;
XX			case 'a':
XX				if (ac > 1) {
XX					ac--; av++;
XX					strncpy(mh.m_author, av[0], 4);
XX					break;
XX				}
XX				else goto bad_usage;
XX			case 'o':
XX				pre_beta++;
XX				break;
XX			default:
XXbad_usage:
XX				fprintf(stderr, usage);
XX				exit(1);
XX			}
XX		}
XX		else {
XX			filename = av[0];
XX		}
XX		ac--; av++;
XX	}
XX
XX	setup_tty();
XX	find_files(filename, mode);
XX	if (mode != FULL)
XX		forge_info();
XX
XX	if (send_sync() == ACK) {
XX		txtmode = 0;
XX		sleep(5);
XX		send_file(files.f_info, 1);
XX
XX		if (mode != FULL)
XX			unlink(files.f_info);
XX
XX		if (mode == TEXT) txtmode++;
XX		send_file(files.f_data, 1);
XX
XX		txtmode = 0;
XX		send_file(files.f_rsrc, 0);
XX	}
XX	reset_tty();
XX}
XX
XXfind_files(filename, mode)
XXchar *filename;
XX{
XX	int n, tdiff;
XX	struct tm *tp;
XX	struct timeb tbuf;
XX	struct stat stbuf;
XX
XX	sprintf(files.f_data, "%s.data", filename);
XX	sprintf(files.f_rsrc, "%s.rsrc", filename);
XX
XX	if (mode == FULL) {
XX		sprintf(files.f_info, "%s.info", filename);
XX		if (stat(files.f_info, &stbuf) != 0) {
XX			perror(files.f_info);
XX			cleanup(-1);
XX		}
XX		return;
XX	}
XX	else {
XX		strcpy(files.f_info, "#machdrXXXXXX");
XX		mktemp(files.f_info);
XX	}
XX
XX	if (mode == RSRC) {
XX		strcpy(files.f_data, "/dev/null");
XX		if (stat(files.f_rsrc, &stbuf) != 0) {
XX			strcpy(files.f_rsrc, filename);
XX			if (stat(files.f_rsrc, &stbuf) != 0) {
XX				perror(files.f_rsrc);
XX				cleanup(-1);
XX			}
XX		}
XX		mh.m_datalen = 0;
XX		mh.m_rsrclen = stbuf.st_size;
XX	}
XX	else {
XX		strcpy(files.f_rsrc, "/dev/null");
XX		if (stat(files.f_data, &stbuf) != 0) {
XX			sprintf(files.f_data, "%s.text", filename);
XX			if (stat(files.f_data, &stbuf) != 0) {
XX				strcpy(files.f_data, filename);
XX				if (stat(files.f_data, &stbuf) != 0) {
XX					perror(files.f_data);
XX					cleanup(-1);
XX				}
XX			}
XX		}
XX		mh.m_datalen = stbuf.st_size;
XX		mh.m_rsrclen = 0;
XX	}
XX
XX	if (!pre_beta) {
XX		ftime(&tbuf);
XX		tp = localtime(&tbuf.time);
XX		tdiff = TIMEDIFF - tbuf.timezone * 60;
XX		if (tp->tm_isdst)
XX			tdiff += 60 * 60;
XX		mh.m_createtime = stbuf.st_mtime + tdiff;
XX		mh.m_modifytime = stbuf.st_mtime + tdiff;
XX	}
XX
XX	if (mh.m_name[0] == '\0') {
XX		n = strlen(filename);
XX		if (n > NAMEBYTES) n = NAMEBYTES;
XX		strncpy(mh.m_name, filename, n);
XX		mh.m_name[n] = '\0';
XX	}
XX}
XX
XXforge_info()
XX{
XX	int n;
XX	char *np;
XX	FILE *fp;
XX
XX	for (np = mh.m_name; *np; np++)
XX		if (*np == '_') *np = ' ';
XX
XX	buf[H_NLENOFF] = n = np - mh.m_name;
XX	strncpy(buf + H_NAMEOFF, mh.m_name, n);
XX	strncpy(buf + H_TYPEOFF, mh.m_type, 4);
XX	strncpy(buf + H_AUTHOFF, mh.m_author, 4);
XX	if (pre_beta) {
XX		put4(buf + H_OLD_DLENOFF, mh.m_datalen);
XX		put4(buf + H_OLD_RLENOFF, mh.m_rsrclen);
XX	}
XX	else {
XX		put4(buf + H_DLENOFF, mh.m_datalen);
XX		put4(buf + H_RLENOFF, mh.m_rsrclen);
XX		put4(buf + H_CTIMOFF, mh.m_createtime);
XX		put4(buf + H_MTIMOFF, mh.m_modifytime);
XX	}
XX	fp = fopen(files.f_info, "w");
XX	if (fp == NULL) {
XX		perror("temp file");
XX		cleanup(-1);
XX	}
XX	fwrite(buf, 1, DATABYTES, fp);
XX	fclose(fp);
XX}
XX
XXsend_sync()
XX{
XX	int c, i;
XX
XX	for (i = 0; i < 3; i++) {
XX		tputc(ESC);
XX		tputc('a');
XX		while ((c = tgetc(ACKTIMO)) != TMO) {
XX			switch (c) {
XX			case CAN:
XX			case EOT:
XX			case ACK:
XX				return c;
XX			default:
XX				continue;
XX			}
XX		}
XX		fprintf(stderr, "starting handshake timeout\r\n");
XX	}
XX	fprintf(stderr, "giving up\r\n");
XX	return CAN;
XX}
XX
XXsend_file(fname, more)
XXchar *fname;
XXint more;
XX{
XX	register int status, i, n;
XX	FILE *inf;
XX
XX	inf = fopen(fname, "r");
XX	if (inf == NULL) {
XX		perror(fname);
XX		cleanup(-1);
XX	}
XX	recno = 1;
XX	for (;;) {
XX		n = fread(buf, 1, DATABYTES, inf);
XX		if (n > 0) {
XX			for (i = 0; i < RETRIES; i++) {
XX				send_rec(buf, DATABYTES);
XX				status = tgetc(ACKTIMO);
XX				if (status != NAK)
XX					break;
XX			} 
XX			if (status == NAK || status == CAN) {
XX				fclose(inf);
XX				cleanup(-1);
XX				/* NOTREACHED */
XX			}
XX		}
XX		if (n < DATABYTES) {
XX			tputc(EOT);
XX			if (!pre_beta) {
XX				status = tgetc(ACKTIMO);
XX			}
XX			if (more) {
XX				status = tgetc(ACKTIMO);
XX			}
XX			return;
XX		}
XX		recno++;
XX		recno &= MAXRECNO;
XX	}
XX}
XX
XXsend_rec(buf, recsize)
XXchar buf[];
XXint recsize;
XX{
XX	int i, cksum;
XX	char *bp;
XX
XX	cksum = 0;
XX	bp = buf;
XX	for (i = 0; i < recsize; i++, bp++) {
XX		if (txtmode && *bp == '\n')
XX			*bp = '\r';
XX		cksum += *bp;
XX	}
XX
XX	tputc(SOH);
XX	tputc((char)recno);
XX	tputc((char)(MAXRECNO - recno));
XX	tputrec(buf, recsize);
XX	tputc((char)cksum);
XX}
XX
XXstatic int ttyfd;
XXstatic FILE *ttyf;
XXstatic jmp_buf timobuf;
XX
XXtgetc(timeout)
XXint timeout;
XX{
XX	int c;
XX
XX	if (setjmp(timobuf))
XX		return TMO;
XX
XX	alarm(timeout);
XX	c = getc(ttyf);
XX	alarm(0);
XX
XX	if (c == -1)	/* probably hung up or logged off */
XX		return EOT;
XX	else
XX		return c & BYTEMASK;
XX}
XX
XXtputrec(buf, count)
XXchar *buf;
XXint count;
XX{
XX	write(ttyfd, buf, count);
XX}
XX
XXtputc(c)
XXchar c;
XX{
XX	write(ttyfd, &c, 1);
XX}
XX
XXtimedout()
XX{
XX	signal(SIGALRM, timedout);	/* for pre-4.2 systems */
XX	longjmp(timobuf, 1);
XX}
XX
XXstatic struct sgttyb otty, ntty;
XX/* should turn messages off */
XX
XXsetup_tty()
XX{
XX	int cleanup();
XX	int timedout();
XX
XX	ttyf = stdin;
XX	ttyfd = fileno(stdout);
XX	ioctl(ttyfd, TIOCGETP, &otty);
XX	signal(SIGHUP, cleanup);
XX	signal(SIGINT, cleanup);
XX	signal(SIGQUIT, cleanup);
XX	signal(SIGTERM, cleanup);
XX	signal(SIGALRM, timedout);
XX	ntty = otty;
XX	ntty.sg_flags = RAW|ANYP;
XX	ioctl(ttyfd, TIOCSETP, &ntty);
XX}
XX
XXreset_tty()
XX{
XX	if (ttyf != NULL) {
XX		sleep(2);	/* should wait for output to drain */
XX		ioctl(ttyfd, TIOCSETP, &otty);
XX	}
XX}
XX
XXcleanup(sig)
XXint sig;
XX{
XX	reset_tty();
XX	exit(sig);
XX}
XX
XXput4(bp, value)
XXchar *bp;
XXlong value;
XX{
XX	register int i, c;
XX
XX	for (i = 0; i < 4; i++) {
XX		c = (value >> 24) & BYTEMASK;
XX		value <<= 8;
XX		*bp++ = c;
XX	}
XX}
XX
SHAR_EOF
if test 8781 -ne "`wc -c macput.c`"
then
echo shar: error transmitting macput.c '(should have been 8781 characters)'
fi
echo shar: extracting macsend '(1040 characters)'
sed 's/^XX//' << \SHAR_EOF > macsend
XX#! /bin/sh
XX# Shellscript for transmitting groups of files to a Macintosh via macput.
XX# Invokes /bin/sh upon entry.
XX# Files with the extension .rsrc will be sent as resource files using
XX#	the -r option.
XX# Files with the extension .data will be sent as data files using
XX#	the -d option.
XX# All other files will be sent as text files using the -u option.
XX# This shellscript will ignore directories and files that are unreadable.
XX# Wildcards may be used.  Thus, to transmit all files beginning with
XX#	a capital letter, use "macsend [A-Z]*"
XX# Upon termination of the operation, the Macintosh bell will ring
XX#	three times.  This is your clue to leave the TV and get
XX#	back to work.
XX# Be sure that macput is in your path, otherwise the shellscript won't work!
XX#
XXmesg n
XXbiff n
XXfor f in $*
XXdo
XX	if [ -f $f ]  && [ -r $f ] 
XX	then 
XX		case $f in
XX		*.data)
XX			echo " macput -d $f"
XX			macput -d $f
XX		;;
XX		*.rsrc)
XX			echo " macput -r $f"
XX			macput -r $f
XX		;;
XX		*)
XX			echo " macput -u $f"
XX			macput -u $f
XX		;;
XX		esac
XX	fi
XXdone
XXecho 
XXecho 
XXecho 
XXmesg y
XXbiff y
SHAR_EOF
if test 1040 -ne "`wc -c macsend`"
then
echo shar: error transmitting macsend '(should have been 1040 characters)'
fi
echo shar: extracting tohexu.c '(1108 characters)'
sed 's/^XX//' << \SHAR_EOF > tohexu.c
XX#include <stdio.h>
XX
XXchar hex[] = "@ABCDEFGHIJKLMNO";
XXint bytes,sum;
XXunsigned long htonl();
XX
XXmain(argc,argv)
XX	char **argv;
XX{
XX	register i,len;
XX	register char *cp;
XX
XX	len = 0;
XX	while ((i = getchar()) != EOF) {
XX		bytes++;
XX		sum += i;
XX		putchar(hex[i>>4]);
XX		putchar(hex[i&0xF]);
XX		if (++len > 32) {
XX			putchar('\n');
XX			len = 0;
XX		}
XX	}
XX	fprintf(stderr, "bytes %d, sum %d\n", bytes, sum);
XX	putchar('|');
XX	sum += bytes;
XX	sum = htonl(sum);
XX	cp = (char *)&sum;
XX	for (len = 0 ; len < 4 ; len++) {
XX		i = (*cp++ & 0xff);
XX		putchar(hex[i>>4]);
XX		putchar(hex[i&0xF]);
XX	}
XX	putchar('\n');
XX	exit(0);
XX}
XX
XX#define nohtonl
XX#ifdef nohtonl	/* if not in library */
XX/*
XX * "Host" to "net" byte order swappers.
XX */
XXunsigned short htons(a)
XX	unsigned short a;
XX{
XX	unsigned short result;
XX	register char *sp = (char *)&a;
XX	register char *dp = (char *)&result;
XX
XX	dp[1] = *sp++;
XX	dp[0] = *sp;
XX	return (result);
XX}
XX
XX
XXunsigned long htonl(a)
XX	unsigned long a;
XX{
XX	unsigned long result;
XX	register char *sp = (char *)&a;
XX	register char *dp = (char *)&result;
XX
XX	dp[3] = *sp++;
XX	dp[2] = *sp++;
XX	dp[1] = *sp++;
XX	dp[0] = *sp;
XX	return (result);
XX}
XX#endif
SHAR_EOF
if test 1108 -ne "`wc -c tohexu.c`"
then
echo shar: error transmitting tohexu.c '(should have been 1108 characters)'
fi
echo shar: extracting xbin.c '(6392 characters)'
sed 's/^XX//' << \SHAR_EOF > xbin.c
XX#include <stdio.h>
XX#include <time.h>
XX#include <sys/types.h>
XX#include <sys/stat.h>
XX#include <sys/timeb.h>
XX
XX/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
XX#define TIMEDIFF 0x7c25b080
XX
XX#define DATABYTES 128
XX
XX#define BYTEMASK 0xff
XX
XX#define NAMEBYTES 63
XX#define H_NLENOFF 1
XX#define H_NAMEOFF 2
XX
XX/* 65 <-> 80 is the FInfo structure */
XX#define H_TYPEOFF 65
XX#define H_AUTHOFF 69
XX#define H_FLAGOFF XXX
XX
XX#define H_LOCKOFF 81
XX#define H_DLENOFF 83
XX#define H_RLENOFF 87
XX#define H_CTIMOFF 91
XX#define H_MTIMOFF 95
XX
XX#define H_OLD_DLENOFF 81
XX#define H_OLD_RLENOFF 85
XX
XXstruct macheader {
XX	char m_name[NAMEBYTES+1];
XX	char m_type[4];
XX	char m_author[4];
XX	long m_flags;
XX	long m_datalen;
XX	long m_rsrclen;
XX	long m_createtime;
XX	long m_modifytime;
XX} mh;
XX
XXstruct filenames {
XX	char f_info[256];
XX	char f_data[256];
XX	char f_rsrc[256];
XX} files;
XX
XXFILE *ifp;
XXint pre_beta;
XXint compressed;
XX
XX/*
XX * xbin -- unpack BinHex style .HEX file into suitable
XX * format for downloading with macput
XX * Dave Johnson, Brown University Computer Science
XX *
XX * (c) 1984 Brown University
XX * may be used but not sold without permission
XX *
XX * created ddj 12/16/84
XX */
XXchar usage[] = "usage: \"xbin [-o] [-n name] filename\"\n";
XX
XXmain(ac, av)
XXchar **av;
XX{
XX	char *filename, *macname;
XX
XX	filename = ""; macname = "";
XX	ac--; av++;
XX	while (ac) {
XX		if (av[0][0] == '-') {
XX			switch (av[0][1]) {
XX			case 'o':
XX				pre_beta++;
XX				break;
XX			case 'n':
XX				if (ac > 1) {
XX					ac--; av++;
XX					macname = av[0];
XX					break;
XX				}
XX				else
XX					goto bad_usage;
XX			default:
XX				goto bad_usage;
XX			}
XX		}
XX		else {
XX			if (*filename == '\0')
XX				filename = av[0];
XX			else
XX				goto bad_usage;
XX		}
XX		ac--; av++;
XX	}
XX	if (*filename == '\0') {
XXbad_usage:
XX		fprintf(stderr, usage);
XX		exit(1);
XX	}
XX
XX	setup_files(filename, macname);
XX	parse_file();
XX	forge_info();	/* now that we know the size of the forks */
XX}
XX
XXsetup_files(filename, macname)
XXchar *filename;		/* input file name -- .hex extension optional */
XXchar *macname;		/* name to use on the mac side of things */
XX{
XX	char namebuf[256];
XX	int n, tdiff;
XX	struct tm *tp;
XX	struct timeb tbuf;
XX	struct stat stbuf;
XX
XX	/* find input .hex file and open it */
XX	sprintf(namebuf, "%s.hex", filename);
XX	if (stat(namebuf, &stbuf) != 0) {
XX		strcpy(namebuf, filename);
XX		if (stat(namebuf, &stbuf) != 0) {
XX			perror(namebuf);
XX			exit(-1);
XX		}
XX	}
XX	ifp = fopen(namebuf, "r");
XX	if (ifp == NULL) {
XX		perror(namebuf);
XX		exit(-1);
XX	}
XX
XX	/* set up names for output files and create them */
XX	if (macname[0] == '\0') {
XX		macname = filename;
XX	}
XX	n = strlen(macname);
XX	if (n > NAMEBYTES) n = NAMEBYTES;
XX	strncpy(mh.m_name, macname, n);
XX	mh.m_name[n] = '\0';
XX
XX	sprintf(files.f_data, "%s.data", mh.m_name);
XX	close(creat(files.f_data, 0666));
XX	sprintf(files.f_rsrc, "%s.rsrc", mh.m_name);
XX	close(creat(files.f_rsrc, 0666));
XX	sprintf(files.f_info, "%s.info", mh.m_name);
XX	/* info file gets created later */
XX
XX	/* get file times and convert to mac time format */
XX	ftime(&tbuf);
XX	tp = localtime(&tbuf.time);
XX	tdiff = TIMEDIFF - tbuf.timezone * 60;
XX	if (tp->tm_isdst)
XX		tdiff += 60 * 60;
XX
XX	mh.m_createtime = stbuf.st_mtime + tdiff;
XX	mh.m_modifytime = stbuf.st_mtime + tdiff;
XX}
XX
XXforge_info()
XX{
XX	char buf[DATABYTES];
XX	char *np;
XX	FILE *fp;
XX	int n;
XX
XX	for (np = mh.m_name; *np; np++)
XX		if (*np == '_') *np = ' ';
XX
XX	buf[H_NLENOFF] = n = np - mh.m_name;
XX	strncpy(buf + H_NAMEOFF, mh.m_name, n);
XX	strncpy(buf + H_TYPEOFF, mh.m_type, 4);
XX	strncpy(buf + H_AUTHOFF, mh.m_author, 4);
XX	/* put4(buf + H_FLAGOFF, mh.m_flag);	XXX */
XX	if (pre_beta) {
XX		put4(buf + H_OLD_DLENOFF, mh.m_datalen);
XX		put4(buf + H_OLD_RLENOFF, mh.m_rsrclen);
XX	}
XX	else {
XX		put4(buf + H_DLENOFF, mh.m_datalen);
XX		put4(buf + H_RLENOFF, mh.m_rsrclen);
XX		put4(buf + H_CTIMOFF, mh.m_createtime);
XX		put4(buf + H_MTIMOFF, mh.m_modifytime);
XX	}
XX	fp = fopen(files.f_info, "w");
XX	if (fp == NULL) {
XX		perror("info file");
XX		exit(-1);
XX	}
XX	fwrite(buf, 1, DATABYTES, fp);
XX	fclose(fp);
XX}
XX
XXparse_file()
XX{
XX	char ibuf[BUFSIZ];
XX	int compressed = 0;
XX	int forks = 0;
XX	int n;
XX
XX	while (fgets(ibuf, BUFSIZ, ifp) != NULL) {
XX		n = strlen(ibuf);
XX		if (n >= 7 && ibuf[0] == '#' || ibuf[n-6] == '$') {
XX			if (n >= 11)
XX				strncpy(mh.m_type, &ibuf[1], 4);
XX			if (n >= 15)
XX				strncpy(mh.m_author, &ibuf[5], 4);
XX			sscanf(&ibuf[n-5], "%4x", &mh.m_flags);
XX			break;
XX		}
XX	}
XX	while (forks < 2 && fgets(ibuf, BUFSIZ, ifp) != NULL) {
XX		if (forks == 0 && strncmp(ibuf, "***COMPRESSED", 13) == 0) {
XX			compressed++;
XX			continue;
XX		}
XX		if (strncmp(ibuf, "***DATA", 7) == 0) {
XX			mh.m_datalen = make_file(files.f_data, compressed);
XX			forks++;
XX			continue;
XX		}
XX		if (strncmp(ibuf, "***RESOURCE", 11) == 0) {
XX			mh.m_rsrclen = make_file(files.f_rsrc, compressed);
XX			forks++;
XX			continue;
XX		}
XX	}
XX}
XX
XXstatic int crc;
XX
XXmake_file(fname, compressed)
XXchar *fname;
XXint compressed;
XX{
XX	register int n;
XX	char ibuf[BUFSIZ];
XX	FILE *outf;
XX	int nbytes = 0;
XX
XX	outf = fopen(fname, "w");
XX	if (outf == NULL) {
XX		perror(fname);
XX		exit(-1);
XX	}
XX
XX	while (fgets(ibuf, BUFSIZ, ifp) != NULL) {
XX		if (strncmp(ibuf, "***END", 6) == 0)
XX			break;
XX		if (compressed)
XX			nbytes += comp_to_bin(ibuf, outf);
XX		else
XX			nbytes += hex_to_bin(ibuf, outf);
XX	}
XX	/* XXX read crc record and do crc check */
XX
XX	return nbytes;
XX}
XX
XX#define SIXB(c) (((c)-0x20) & 0x3f)
XX
XXcomp_to_bin(ibuf, outf)
XXchar ibuf[];
XXFILE *outf;
XX{
XX	char obuf[BUFSIZ];
XX	register char *ip = ibuf;
XX	register char *op = obuf;
XX	register int n, outcount;
XX	int numread, incount;
XX
XX	numread = strlen(ibuf);
XX	ip[numread-1] = ' ';		/* zap out the newline */
XX	outcount = (SIXB(ip[0]) << 2) | (SIXB(ip[1]) >> 4);
XX	incount = ((outcount / 3) + 1) * 4;
XX	for (n = numread; n < incount; n++)	/* restore lost spaces */
XX		ibuf[n] = ' ';
XX
XX	n = 0;
XX	while (n <= outcount) {
XX		*op++ = SIXB(ip[0]) << 2 | SIXB(ip[1]) >> 4;
XX		*op++ = SIXB(ip[1]) << 4 | SIXB(ip[2]) >> 2;
XX		*op++ = SIXB(ip[2]) << 6 | SIXB(ip[3]);
XX		ip += 4;
XX		n += 3;
XX	}
XX	fwrite(obuf+1, 1, outcount, outf);
XX	return outcount;
XX}
XX
XXhex_to_bin(ibuf, outf)
XXchar ibuf[];
XXFILE *outf;
XX{
XX	register char *ip = ibuf;
XX	register int n, outcount;
XX	int c;
XX
XX	n = strlen(ibuf) - 1;
XX	outcount = n / 2;
XX	for (n = 0; n < outcount; n++) {
XX		c = hexit(*ip++);
XX		c = (c << 4) | hexit(*ip++);
XX		fputc(c , outf);
XX	}
XX	return outcount;
XX}
XX
XXhexit(c)
XXint c;
XX{
XX	if ('0' <= c && c <= '9')
XX		return c - '0';
XX	if ('A' <= c && c <= 'F')
XX		return c - 'A' + 10;
XX}
XX
XXput4(bp, value)
XXchar *bp;
XXlong value;
XX{
XX	register int i, c;
XX
XX	for (i = 0; i < 4; i++) {
XX		c = (value >> 24) & BYTEMASK;
XX		value <<= 8;
XX		*bp++ = c;
XX	}
XX}
SHAR_EOF
if test 6392 -ne "`wc -c xbin.c`"
then
echo shar: error transmitting xbin.c '(should have been 6392 characters)'
fi
#	End of shell archive
exit 0
-- 
From the ministry of silly talks:               Chuq Von Rospach
{allegra,cbosgd,hplabs,ihnp4,seismo}!nsc!chuqui nsc!chuqui@decwrl.ARPA

National Semiconductor does not require useless disclaimers on posted
material that is obviously not posted by company spokesmen...