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 *)∑ 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...