[comp.sources.unix] v10i004: Crypt Breaker's Workbench, Part04/11

rs@uunet.UUCP (06/18/87)

Submitted by: Robert W. Baldwin <BALDWIN@XX.LCS.MIT.EDU>
Mod.sources: Volume 10, Issue 4
Archive-name: cbw/Part04


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 11)."
# Contents:  UU.test UU.test1 autotri.c dline.c specs.h test.txt user.c
# Wrapped by rs@uunet on Wed Jun 17 18:17:13 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f UU.test -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"UU.test\"
else
echo shar: Extracting \"UU.test\" \(8718 characters\)
sed "s/^X//" >UU.test <<'END_OF_UU.test'
Xbegin 644 test.cipher
XMK^D=OM^/7]Q/RL"9_4AY*RCP`/[KZHU"6Z5:W(U05KF^@U%0-+PS8[6OL_^F
XM.4\,B+%AZ"3`@N&T\3#<LMVP!/'#]*C7-6"V5?!3-^4.!I$`^OXT!\L53\O9
XMPL&FC'**K^/D\$#7[28E!:7SHS0&E'GW!$CJ7/A:.?$JE-`5%1,76RXB[6-?
XM`9.9[^J6F)25KZZQ3.-*\LERQ^0TQ=^;YW-%_D/AJT!@9M;;"`(&(?D/?^[D
XMJ#^_5(*(7/RT%%"8L'VJ2"[Y=-S;#I]O=I)_?F7QKG_>8)O;LOYUKT97YZW2
XMZ.>VI0LD"5B&G^[[G.;@/9CQIJ"4!:D,FZVLW_DU/K.4D/'-R1A.)0HYG]#:
XM]4N/?-@RN;R`ZE+DA14):'B&.(%K!A<2`]V<`(5_#TR6T(`P7P(7INO;.,WE
XM%54-WW-1"9[S,-IJ!)B#U;[^'U*7R949&4T7K$*4ED:;L))W[0_YP,[<YV_1
XM([%7?HFNM,G+E-J2*73(Z7[OCD9HHH@$N%GQ"5:J!H:(HL[0V-E[J;$L^HGH
XM4$D'P_S71!+93T<.7_]=#:WC'AXN\1J(JLJ%3,PF+OT2498I;R\PF'<U2=LJ
XM)ADORXU9T'9[>WI#N-X9;"@QD/NN_-`_9TK3]C`E4U244NL_8NSKA63%V<.[
XM$%YL.&H,;@:)&U72T9NF9^0WP\*[1\A%\M;U*,WE\8"OU+W2H#(S%!=Y94O!
XML.CI;^T=%A4W"8[-Y5Q-L@RDW\61)F<E.JWOR&?:A\EU@QJ)HA)7A`\>$`L6
XMF;*Q5F@F3R2<(V)?"E\0!S_/SQG>1/Z;I4)KL0Z):0MSO[V9PQ_4B\=>.1D2
XM%^34TZ.JB-#S`-6)[[KK%/:<0B)!(%8]]HL,E."'%ZJ$Q\F8#])]U7LU[#>9
XMFH(AU,3?_O=N%Y3Z;[N<7.@DMHP,LQ>:AV_0!8*`;))+#\RX%R93"+NQY4Z7
XM6ZNPLZYY[)+42+P%&GJ4F=!0,-:[I[JYJ]?/)W6)(?RPJ=8T7<O2;,B-""#$
XM]<KZ(A8]%)U8<+1Q4O<A0#T*I6:J9/-G9J#:?[TNPC^X=A3;:JUE)/!#:6%K
XM]I+BT;;Y"M]%@KYW'#%E,&/Y._(7]`2/SM:LW1#J5E'_4OTC)$ID/_R3Q1D=
XMWIRL><=_IW6U.:0WVPJGN!R,WW0[]WL5'K>@7.;2;8?/)#GO!B`8+[@R3&H_
XMO+M*\8ZT??3SC:X^Q'X!6LR^U,]!C]#%`_50+"#9'O9>U76+>8D(6>.8$=1S
XM:G%/`Q+7J:TAA_881,9=XIA:8!%S#Y6"=P"YXSH;TX\'^-'0[9$^F;`\)=Q0
XM@;S5J]RFY_QX!D73@&JTD/D9N0LI3#K1!`4'7Z`$)K$D.HT]9&1_O-/ID>$T
XMWW=4F]+CA-B=_&-H2F#6@-1\`'S46%@J(TT78M:#>5Y3Z0_GU$G\&XT]5>$[
XM95`3RLGX>Q<)12?4[+KJQ9CTW^A3HPX5(UFMW1K;(,TG`YH!7YYP<<2LJXZ.
XMK8(RM!CK%NN,A$36]W^7[`*PC<0.#G*S!;"D5J(Q5=SRQV9C^?J8FX1Q=L<\
XMO3B%=Q8U@`@;0S#V^&*CGY8\O@5S#H%5COVHT(O.<*(70CJB_**T*Z@F6B0P
XM191N#0!*71NE]92/\J/K[PS(/8LJZ7MZ>"7%RT.T@IU&13!52OM`I$Z^H:DR
XMNGJ8Y3M1V"IS-HJ]#_>Z`SES\N&RA-Z*L$0'[4KW%G()TUY=<P0S[=Q7A^D^
XMI8DN20021/E6$C5'O+<Q>/S]5C5AT)F`0=[J>?)Q)/VP]8TVEA85C(@G6!F.
XMYQM)BOU""$0<&M.*>G;/=HJ4_6')@X"!G6/*=!M21FR*C\%-FG%6*V-;6O:/
XMME+&XHW.O2[+"DW%>W5T+'3<F&>"<AZM?FPR%.:^NRV^KJVLC]G6,:_DN`C9
XM](OUB?[K?!HJ_30[P=B:]O/#T]*H(9,:4LQY"K%537[>F8+@MA%&O.1QS[AN
XMK4$8.[<1,"\0LE$9!$N(*4@)GYC<&_^R)!GMKA85S0:"!+[(`3NC7'M5-E\E
XM)&I]OF"\:!MP2)H!(MGEE!!?.&'I6U?Y:VKK.GA5YU$$3I13DS6@;=WP30H\
XMSCB(/SHMZDTJC68J+>QDUFI#9H2J((&IIJ4G*:1U'_K/&4"T.9T(!_PV!`.=
XM>GKU:$Y::G7YEST+1](X*$SA-(J[)>!9T7G>=]_`=//92+9D:B@HTN30^?@C
XM8EFN_5Y=K"6R42E`+RUQ]_8Q2#<F\D&!I4>*+[8E/L]QN^22@%ZO-6+L+_2P
XM3GKFO.;B\HETMG"FN;+<5VKA2SP4)R>2D3!I'^LOXG7@(.S=0]`*9]0;':%Z
XM%#R9A(,8X+7H_+JYP:]+LEJ.Y&1AZ>@KJ:M;-UGG62)F'O\\>Y1T8(2'R^N^
XM/EE?8I19:?F.IBPK6[NW7,6W'964LAP;._-**?`>U^35`M.``+'/XMO[LW;?
XM2^CUWF)Q:T0A0DA`XREF8K^%#%N[*KGCK2:D&]:HY>31%^^.3;=R#>Y6QVC7
XM2W!VKP0%G.*RBZ(-NJB<MRV4_BHTC]D1?-\OD+57W5B@^NW;7,0.5C283"AK
XM2BS:((UA63NQH>*+__=3'E&TF#[?@H+?8"DL-@XH6++N"H#@$F'^_2/H*K9<
XMC4'AU(6ORV"<17_9Q7S4PK5N[>]+:DE?!;W\6HVF-28FI%#@NK<QJ=D[LG*:
XM7"EY%FKG>:FL@TUAWSQ)Z5HW>EMZB5'*M4J\79WG<(;!"?3,5-;)?H]*3,3D
XMESI9<=O$6])_VHVW%>-]E68X'40_7:(-$#X'ZO?X%.@$PWT+EI.K!X@JRI7.
XMVO[8@LF5U_<#@O(V@DMZM2B\,1BW!DJ]65QG:3#*4$_NW%]4A?(S%*.Y1/(0
XM?$`.2ZU)I7Q@*BZZ4J<L&P$,YPA_K@74JZH.;\WTDHDIBYK#`Q8OK$:=>WHU
XM_\?%8_F[Y@(*O::Z$L'-@RS^>^[6LSJOE1F%";]&3`5#&^]`_9&MV[3?^@^3
XM553?6<7LB\^8.`R51ORT.U;"Q*9:M;3]H:E4ZY[I1OV):N2(&Q5@M?Y_3<I\
XM[]#M4]C,#'139PP_!XV%!;`I\JOP)^WY/=&/"GI6C51OV.ZJN[BNK;B(2,3[
XM`E<7I"Z?I='8W_:J!S?2=?+ASB#>T7.4P*X,)2ST*9E)M?!V)!7XE,+Q;\!:
XMO1J[3$0WL7WAM$7>+V9".;]EQ]N[C_R5*^/%VUHS5,5Z7NW@B%A\)D^40]DA
XM;73@:0EN!])2:O7O`8GFP>3NG+X-?@L%?]M`/W\]6QRG;P<ZXE1[),A7^U]_
XM"4SV+T]'AQ@3%J#*$Q3>65@0ANC2200.WRLJE;Q@TU[3.M6E6IT/!<\OZ^8)
XME7#F*]5U^0$?`M'^%6-5:P0%!(-DP??%>'.RNQG`>?4S1>*-C&GGJM.@KAP!
XMJ\L)$OA5]DJ"?\*M7CL9MMY7MC).==YEZ=LX\P!JH))>.%I.'CMFJS6!Y&&[
XM>KG>#)"PGRP[J"HQX0A+F+6#3'Q3M"NRI.7BX3HVTJ596'W2S(8.&ND2Y-X6
XMVDL>ZL/S&86EP,QVG\P)+0A>:9J_PL.1D*F]_;V^;(!C8LE,:C;EB>,^,,9S
XM"X^5-BDIPJ2/(/SHW-M,I8^3LJQ4"E*;IRL"5T7VB@P/)NJYL)KN;0C')DG&
XM!QR^4AF8%`H5%'<B&@2/;A7S`/V\A!HV%[%^M:CLM!4Y=P]K=.GJ)'!O0!%L
XM7/XE762\G1EG!<@[K*X]&/]IH@_5%00(HY%T5!,I=WI;ABN^#KQ<QEWI^(:U
XM9U>JS<6G&>07G(/@Z9\_A%:_M_"N#OU/^R`#2])U8$=&G2ZC`O^"NA!F=7LE
XMR6%/"/A\4U*@@'E<5EH[K4\,F+^\FJ&8ES['TW/WM'Z.<N:4@#D6QUC>P%5W
XMEPX&%O^/=IP>?ETFXIRPZ:Y''@PY.+TV`[S+^$.AAJYH@R;CR3(!Q@1@O.8.
XM<ALJ9ACE+>.CKRE1$-XPRY5H4"#`ULB#G)LZJK<TP%IZN0Y6Q%7="LG($F-[
XMBHKASEW77B.[JK&X[6V[RWY+&#W/R,>J]EW6<]0.NZ@%_\U'#BT,N\,IX`T(
XM)7$OGI5X=!VQHQ6K33N=/YW(CE`23@)T#C.FYS/D#):<X"KDL2H1"?69\\<A
XMXA\HCXS^[!`(ZN@FEL9%:FENDM#WDI4,C,H>,Y\&$R+`(.8)'2P-I)\8#@3-
XMS@%/(0\8#:W]%)#7>Q#@[)1.]APPYTDF;T6&+%6GWHS#?UZDD^>1%#'\_,&=
XMBIB!R'^&OJVIGN?=26MCKWEY[&XP/NB]$MXD[V9/6$UF]#+<ZP6[[\)9>(@O
XMA5[-PZ4VWF,9X!>!7!F,"\?J'`X^^+X'10CX4DSDH$6WDFM46UH,$-I58RDX
XM&%GZ-A2&M+NZW>GT?>^MV7^I(SB,7>V)VR'9/1L=RH&H3%[D6_X?X'GM[(\(
XM7Q*O$-M-(X<;*PGG!G8I_TO"</7ALVNOUZ;X0&=Q8]#7!LWZ3"S)R`BLQ;\`
XM;8P1A@E&#<I$S+Z(L9PGGOUN(CB.)!()4QQ<C]X8"DI#2M(-.R$YNCYQN?Q#
XM,K<[\3D=9S]`FY(%+86PZ]C7$T"7J]+XT%:$SG99T@UAA9F#0JQ5N*F\2BJ`
XM<2=YSKL76$`@Q8/W@57?NI'Z8>IK>`RP)ES68=0\N=F_G:K`R:>FH53=S<Q^
XMW9[W):9MF=;":="39F@&A_>"A84P@Q@7R!>HL?CW62P%@@T<J']2N5`>%X24
XM!,>32/X6Y0V9.&P--L(**T(G?!,$(RR](.+/LI0T.4^4\S8&UP06,=#NDE96
XM5\E3N_.YA'_O(DMSYRSOKJ+0#X"H0FCUB1YDI0$%8!0N#-&$`H95]GE&*)HF
XMYF3:EI_FT8#TUS_;&6__[7'F=JAT9S=49,4-,FS1:#3(S5!`@J4=75$!&:(A
XMU>#O0\@?IXTTE6";9*"2UGO4<H`+?WY2-<`RI2QLZ1-HS"EIDE5Q#!5OPV-'
XM:UK6:+KG0+)TLSC@23-L#0Q4(0&C?97]XH!T"E@O!W-YYP9O!C0MZQ*^77:%
XM*7/9;#G09=Q=U'8#T\F"R-!>79.6]_..).GBQ!F>$O-(Z]68^==<-HJ0M_"&
XMV!V3=(*!XH[0N9J!>MW[DB/4UKFJA@M$9V-!\.P4T:O,&ZU3E^.2'!OK57"S
XMT":%A*4\(4QT(Y#<[G=NW5*V=U086I1<5ZV/8AJ]`]&LJSFC(4`TJIG'TG3H
XM_LZS&WXSCN#_^")^+;%P3"NHT2MN9"C\0U1>?/?P:VK-]`]_#;6J[KX9D/R)
XMHSX4+[O'H36O,.@RSU>I>P;'95''7?3D+__P+/8^`PFN4"LJ^"64(!#T)XV:
XMN)B7-0<2K6T7R*Y&"EMV&B@;:A&4C2T55BDG1T&DCA?3@5@/M.Q*?.]EV]X&
XM;GALQM+-N[$2!A^V;P+K`$6;%[^B(7,K08F#\>@,<W/L<7SV(9LSVH`!?F8O
XM_;MM;$9J`-8$7;LZ$SACH461!N.*]?DWFMIU>_.UC/H_^"J?.VJ%A&R".X'5
XM:EL%1@.0"&O;ZUEO^Y"?65C[BZ251.]&A37ZIB&QRK;T&B`:X1[2Z>@>6\B/
XM.0^-4T:)I^`79[4FSS^!/?/SA4$AN=TXJ4^T0H2Q4DZ6J"WC=)7-8GT%!(E$
XM1F0HM*`%7S"U*UO;>WJ%E=71DD3V6^A=T[:%\<C#@</&#4L#;ZK8Q'W4S?%J
XM*``9P?[&E+6$#U@0X?A#&8Q-4D^RUY0@]/?HSU_O=N#O6NTT<'L2R#J;3:B:
XM#X,-,U(^8`-^]JV!&\^6\/'P%S!-HN*#$[MV&1]7%$H.05N`YJ<]G"PQF7AX
XMEA'UBZ&7;*L#BE3UQB-LWY4=+Z3:G7U&BXB87P70BB^8/'^I%[E+AF,W-6`/
XM$5VV02Z$V^(`5T7%LWQO;DPR30E^?3IBH&0[3'Q@27,'POXT3*BGI*\,#9>A
XM5YB>59H@&J]2!0+.;ZJL%AS(?A+=$-"NV`A:L-#3)G$D,=W<75K&N&#V*O,+
XM);R:+CP_>"4\=2+KTG]<C<Y9<(.##S.N^?@I;AI3%S11Q?N=N'N/)R&@N8;<
XM]25^D+=65>,L0\@1`L*!K/^0>ZB-O%R#G66#P\(C6?IP.AXU9;6&L[(X.M$X
XM,NK0W-9MAX9J]_8+;9LOA_#.[TDH53PCB/V5E*;03'>8K$A0<J8Y9X5%6"!S
XM@F@_L6!EFZ&;B<'.267(!4-@F,6WKI4%L\HZ?1OWO[==^R;Y-TXU"/.LU-L\
XMJ)$9T"4)0*A^:0&M[8<\/8>>$YS\@G`5KS#)33URW$`\5E6`Q4D`ON#479-C
XMKA6LXZ8HRWJF3#.?$O_^32W#F^)4.-A!8)X@75L(LS"-COY.2.8NPY4]*K&(
XM59N1XJN$KSK=M$,NM[>@P.+-SHGT$*ZOKMS$(T>.*4CC1DA:0PGMS?,Z[<KR
XMG2U^`#:JZSR;'%N2AV$U`&F`,RX2^8.X;9074Q4]$E59PUN$'8A+A8^0ZV2]
XM`$V]YB^,S5FO1%K]>_C12L_;-;]A)[[WBF=$<$*=:DXW$0[+XH\5XF>1N9'N
XM6P0X=24D=HC6;V!MGBV-%Y9!DAP2E2*O;I&:^/0Q/A9$=]'MHFR,R,>O>-N"
XMAKFU_"C*)K-%MI;R/E%S=CJE8:?]?"C\.<SHK8M2`G)3U^%EWQ@KT0KWQ\>B
XMIDZF+$%`L\2@1:=58W8W>2U,JTJBVC$PP[3(LES>NKO-(QO?UR(PWSDVZO[H
XMR!8S=,K=ZD5ENRP?:I=CS,N8FI%I#;K+N(VIXLS@>:0:4W`"XW44%A,>V\XR
XM934T<&W/.O1=3^8KY$D#SZ]#6LM$FQ'P#;V`N[I[<=\I!K[G4&C->[$TKQ"K
XM#D3A1-D%6N[V[ST5H%!.-V'F-!<$,>CRWU.G[T6KHV],]IJ9\P\<1)3?%0DU
XM5;IO$1!(RC_3GW]@^S4`-CVG],(Q^]#8O2+*==H-U#Q'/FIIWRM!&C^-%V7@
XM9*A`ILYR/+YYVVV-C#2(QJS!0U842H*SRE9.K]),)DI>P>TE@<I_R3A1M"%M
XML5?&XW>/PGX7XL(4;;P<48-/CTQ4@=XA<2H]\-63$E\0G?-%!\S2-#/,!N$`
XMEU`^4S0R*,3$H@9[FK!'EH1U[2(CDNMB'4P$EP]-F9-*20Y4H<`*Y4\,PAX-
XM&!>@Q2H43\Z:.TB9WWFK.9*R&P"V#VEH.:_#I(>]7S`T7JAR?KA6!J:DLTLS
XM@A8PU'I*$QLJS.AH"UC:Y$X(!5(,OVSGX,NY?-AZQ5.,&0]TX,^9D(78/]/"
XME,`1>1EWW>.M<LNO2@8;ZY<8T1AOP%=`V,H\VJO&%C45/'M(K)BTV>AS<INS
XM.N+_X.;.(+%K,><SQ]TA(G^XWTB%.=0:L8@(IH!_`&;;D(<8*:LJU&.Y,C#W
XM8&)C9OZ9INJD59FDZG-0[S_8O%UAEU\(>P:@77P*KE'_F:O0R@*CQ[D8X!!)
XMJ$O$?NJ`?SKGTPHV2RYWO#.8P'*T'#X^,(&2!]J#"P<A7@_'!>5+IY^E?EI&
XMW33I^;%SAMDQ(8<>0S3*U!F6FLT<BG9UKQ"E%>Z"]`(=UT:$F1Q2^,"[/N!]
XM0FY%JGRR\+"QPW3!L,QF>6*[R*;&@IZ30D4P1F++#2D/2^#?2$';Y;9:]3LR
XM7=H-Y^;.+<T'G07;S].*/,1-X,C2"NO"1GYVN-G)X]"'>*F4D^B<31[Z9AOA
XM0=G8VA%X%D?F?=9`D8/<\S0;&D(]X78T/M,[B4EO'`T*,2<_L6O%6^%,`.;E
XM"EZO"F"KX0N5J'.A"0]]5B80WY;@U/329?ED</A@`83ZD/8]Q3L4^Q(Y#>OM
XMH.H+,CV6YB::&6[9=(\ERG54!QP(!RE\ZC(#E?IGU.?!JJGX?0"C=W:,(IAR
XMB'/H.%PO7'^Q7FAY?&DZ-C)AEPF5<80@[0,*"OZ:+Z*A/AD&=CIJ))E&7@>M
XME(!)XGSJ=SB\O0Z`%24J/$5ZD3$Z5CC@?,6)$S-N(F"3J0R-GZ:*J4<;H:/@
XM]3R'MK6(^:592#\[.N::Y\L2:E-_/,PZZ$(O;=HI3^$KKV9U-Y;6CK"A1"[]
XMXB=K7EW8.UX@06-<=N7,,QPZ=BRH2BQ&OD09>ZZJ<V979`W!>[^3L[R[:KF-
XMP[;*R>7G6M38"C"KS`TG?=V56=K1H:FL(XK_FPXO_*NJ&JAG">S'TSM+19O=
XMW#"#BR/,#`N/_*?!DO=/O0Y_%12!+0BZ19-*1[^9F"BF$"IG;X(XCQ_[!,7$
XM97F<,BM5J!LU"86<2)JEM7\.E1RA%0(N+8A+MCS$\D::)'_%$*RK[GV6F#^3
XME3R0%`_G^;&P!(CA=NO9"`VG"]G4,V@R2<]$.U]3*[S4N+>VD3:&QC30LJX(
XMZ!!85W(6Q'?^47>+WQ>(8+HLAF.P);1V<>UY>"X`37J:)E=#^6Y>(L2`ET,S
X%A:$T1XP6
X`
Xend
END_OF_UU.test
if test 8718 -ne `wc -c <UU.test`; then
    echo shar: \"UU.test\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f UU.test1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"UU.test1\"
else
echo shar: Extracting \"UU.test1\" \(8715 characters\)
sed "s/^X//" >UU.test1 <<'END_OF_UU.test1'
Xbegin 644 test1.cipher
XMUOK1$>_\&3%/P4O]]LZ;JN[MM6#C+3$&?J4MLCT;V=B=?5&/]*CR5I1/N(ON
XM1_Q5C1[H,X1(`*;%6L.1I]Q=ZD3#Y=AB.6!YF]-ZU=?VU0;,OW[400:*B3@T
XMES+W1/+3V!70X^+7[8WKW]T#(9:A?H1^RGR8P<+<0Q:P%"!4Z\VE42_N`,S<
XM`<DGQUHV-3[JK^C?C^B-M8_(W.1LUNEGYRB"Y(D'N")`9CY\]>S85^T6.-9)
XM5.U3".(V\3C>HJ4]FH%&!`.[3T&D<4Q+:P]_3R5F4R+>JVC;>6<*%1E85]!E
XMZ)KF;A-?.D-<KSM'6";`"U3G$B4&GIVO1,GO,A```9*RC!)0<%BU)=#=QHI-
XM.-S>@:7OH#Z`B[P!G6H?&CPYU9<V3P4S%)7-!__GIU*4>G>)+@(=+&Y[BN9)
XM$(;B;@4*8Y%D:!U>*=<Y,57V4X<S<#'QC=>W)96&LR[[:W33&0KU)I2+*(.[
XM6R;'C(FNZ*R:L4WT>),G<D$KYZ9[B.JOA?*L"5:4M>I<_N9L,=F@Z,#IM>/=
XMASJP3=0K!4E0(DZ#-EH\^/G]..&I3MZKWBAB<\R;35WC;/YRT#?BY_@#;C'%
XM$!5X."6<FQ%['U;#<:,485-V,'/G_6)P@I<>S(_*+L]19F6<KNSWZKXGJ)$9
XMC_T"9?^!GVQK5KAT^6DY./QC\6',/9[CDT":Y]L>UQP0*:(X$7(6LGYH$QC6
XMV!>_ON@#@^+0$URUM9/*VBVDZO8H["EF\\HCCNIEZUSAI=H6HLNK?##8L;"3
XM)+)5L!5!'L\6&PH331+S-QR![O%\PH6F1D*80S`"R<2K9B+A<(VY8(Q>E1,2
XM4>1-^C+%B+XN`+J7,+J[KM:LE;8?Y\[./..CWN#A_TH_Q\DQQW^5_=?@)C/J
XM%5GS,+J:&F;]#,;X;^H'[X\$1C;J21>(",UX+N?;Q6E^1\6K$WVPP"@UY4X+
XM3,"4!%0M"G?J^/"[,P()74=0=72XN58`JP)_M&NGJ2/`K:49JN4"S:8BG=00
XMZ6?G=@Q6])UV;I,DOOR-3.I*9`<&"JBQ,_;,8PN?U@1YTGCL_&[;AI1N?2K!
XM0N-%2G[4%Y)4@KY;O'9T98RVE/<Y,SG(].@@W1"K#@OGR$RQF"$B,6'!&GWH
XMLIS0Y/.W=;7[(HXKH0JG:)YI:YI=;VD5S&R@M6ETY!IU<%[OZ-T"Y`$R,;)V
XM(TBZ9&,)UO01/NK`K9[H`%]YY*;2?5.A"7T'=%IY_=N]V;."BNA>6>/RX4N5
XMK!:*)DT!](Z[]Z%\?I[09*QB/@/MBNJ"=S9MF[^"D(^O"TJUU=%9O?^-X2?M
XM-\M<?;YL]$B4W]E_:P,00;'P?\DI._.Y+/`11@\7(4+AZ&Z7-['L:V!I9N8$
XM3D_88M*%LXC<L'?==?<;V4"H_8)?6<?A\$WEW7-=OUN+[GEI<TG\%PFUD&%F
XM9?*&_^SX]0HI42?9>EI#O\1K&K3>\T0:(QB1BD</*0TK>:^W@?_^FFFLY(WR
XMNONXZF5?F1+MBZ9#W>7(='V-Z4=T[ORG^H9L,\T5W2-H_/!0O@@2QL+V1T^+
XMT1P"28.Q%Q,@*YR@W`)HGSUVY0/4G+H,=@KEIR(_(Z&A0B6W4J*9H!F`I@(F
XM7P^<EQ9>42];S(-8@$,"2$12\.^Q/P;UVH>2XQP;:A_'P19+2,!(QDV\-$L\
XMGI-(12V9XV7(OV*Q,_.ZP^MEGF=PA(L#+A6N1$Z89&/^244+WEUW!^S25VYE
XM>H+([`02XE?XX=X=8\T9B%;3>3].4T/DPNM1M69&;4/5;6Q/+5-/*<UYV?')
XMA9U?[`I&[,D]&^B.3]?[EN)^AGP(6I]P[7S728Q0MV!@=TW=0*:E"3*L9T6/
XM4Y#L?XU_F,$M'!NI@P+Q3D0DF#1`<F-)^V&U7@/)R,=>5%I)@$*VDHODU$C2
XM,S@$?U6'+^D/_)+IP13W]D:8T_>)\!P:_Z6LZ`1Q#*YKB()'1^>T0^1B\IB:
XMO0%^?2>X9Z$NL@QFKXDC2BC_L,WFV[/)V-<8[`;J*1/GS;ZGI,#(9SHYAKDE
XM>B.\M[.B]QIQ[Q[H(I9^:1"2ZET='/HZ5:+VB/JQCV17>/M*[(YNGZ^D"TRB
XMP61R=V&%L],`,$HPBFV,ING)HP;EY.*I`5SR!,1U]#[/<DQ+(^M(1X-6J!Q[
XM5]*;/3UKH4*M-&%Q1UU=*%0"Z(JQA5^#W[^`=S)`VWF]2$$KMRDU-,Q>;JW)
XM6ED.!>1FM^]9*DG\^^Y=]R.<YH_L+R3OB^*;YPB#Z;8:9F&2^ZV1Q7@P&*>4
XMT+7[T/J.OY6$BL:FN;+D5Y^G)"HI5VB9TE=Z3'BI%G6)>;HI:H?SH;V=!ASW
XM]D&Z`J@2X-_H_"K#)8[L0U1W=A*ZT4Y33%XXF<(PX3![=E5&8G=L9/L.LER-
XMVYNGM90=H:![7)Y95EC'4E'QG)NKX,TSW>51Q4\)3;?3&DDTO,Y]+S3E!<AB
XMVJAWWO?<*-I`BQ]N@JPEH7[>?`DKVEI]XB:@GP]"O[U9"5D*+.H%X9+)P&B<
XMIHA?()FPI,2,;QB):2+<9J:A5W^A,&:.4R0.D*HDK,JD`NV4_304S>^"3#PP
XMOVG:\-(#0/.Q<7<^=:/Z]1G`CI;NWI3ME?4SH466_X-/RE13%2_^'",-"QU.
XMM!6/_(M:KB")J]J&Q7P5N$YX3+\]8!79!4Q<4O*T6H!LOH8B5FVYVM2+?JGB
XM^$^N5`.*<FFLG&YA<[:!Z;AITV=-E,]VT4HQCF\)GX)M57^&$OH/>@7A?&J4
XMK7X<W(7[UVW1S[.WD/M)3.P1U8P]1L,0%N6=L8,5T@E]QMD%EM>^2,"CX*''
XMN]FB@OBU_:ARBL':CJ[<#WYSPK$FG&F'66@(!S#*87;9RP=4:DG\/H[0^,=!
XMC#_+!!:BBW&%PJJK%1V4#MT`"UC]_`7!JPA=S\_'1WMHBU>;!###PB73`G7!
XMB2#%U?9=Y$:>D*:^`[D9%/'NG4^(.XTOF`MQ*PCR.P7S+?=+B!@@@T,:&50Z
XM.W@/4M*-H,^"!-ZSP,A'03)(1[L\TRS2$-!S3:X[RWG<0)>(%O;8]?,_%3V1
XMX!'-ZQB;R<P:RB^&3HV%!(-=`KI.7`\EZP(7`);2K]-O"U%00+WC#+@=YJ%'
XMB<U+5#6F3*`L1R^J#9<KH)2GT#I#R"(`QJX1);K*""B^3\K2Y4`AF9/@M-[,
XM+:CG.WC7Q75\CS<BNTE_0;<>FMB7VR>./BB%?Y01YD[+S12S?;=70*Z'#-FL
XMW#':4L<MD=+4!#1J,HJBM_>%]4=8*;6TH+)@)..2)8,A613^X/K=E?C'NMAE
XM\DQFR47'!W#$GQWM[)M%2P]U^<%I#`O:U/>N]6`,7X+3^>*-6=)-P]SQ!4C]
XMB5:!U)1U/(D?;\-,9,W,FP:OQ(.(3B.IO!E95>V4;B8EP;12>Q"*4GOM!XU;
XMJ\NIU#/W_DH?C"2MQ\L*>'@F`S*Y`-Y(]B<X0X0=)Q%>.#Z$'J\Y.:H!J,$U
XM^%YX*3W`"U[62!5EJ>O7RG_K_>E;MBTL%YC21>+AN:7,5N_L68:DSC"+U,4J
XMVIG1ZA$:3<#Q>,RV*GB[!IMR;^'@GVT?:8!2)5]>#V:0T,-\P:;[Y!@^/(]B
XM],.."HD9\X_V]9YEQ630HPN3"8J>G)G\:Y$".+17W"KHD>JZ#IK'!'['#ASH
XM"R)%`0<&.72G^QD>!9#?M8S)``8'UXJ%#>%^.QR#\JN`0:(6?'LZI'A/0.A]
XM,/YMZ1B\5D;17E;;DJ%[A:B9OX)3'`1<3Y$:/B,I4@)W`"QBC>*<SOGIA_[L
XM'_OH\N:4;NZ-\XALRMX1TFTZX,/>N%"_VT`?N[KL8.3SG6W+*P#@!B@A^PXC
XM>P.'AM,?<U+P4,.-071@]E?KB^GHAMB[Q[7KE*@.PW[HYLBO.N\1-Y:3P(!<
XMPYB^-[:/4M/=?AQ(&D`+X*6D\:)T+E/'J@TUHX$RU8!M@P-J./S4Q@2]_37K
XM^C5:,T`W5NWRJU.KS<<P3?"CV6=P;U2\',[1N5Z9$[40N<K;Q,/=VMJ*$MX<
XMU/#*P28L_2//S#H`TX2V+,S]_!NU9<?(Q>*F:`0;KPR/7HT_+EHOR;I6`BOL
XM.+VDAIV.=*B9HX]YP#N6<YEQ=C25%<%T_TK;YTY&#&IC]BI^:X!I#&OV:;HC
XM=G.0G^Q.C.P(ITTF)<:RM3]N]I&LKY4Q=XO9_3+[6P?X%ZA$I_.%Z%0&Y:,,
XM"H\(W1F+F"VLAU:1.+?W)%$+LFV@\[>6G@<">Z>PWMGOVNVE+#0$_D;F_,%_
XMOYF:2?$BXH2\VP.^7M5UXGF^<6YZR6*]33:,--CBL^L7;>,Q#$#[>C^20L=+
XM&N&RP\LBR2?XF8)JA[,LP&#2#*"ANN6'Z#74N7=X)_-=7`98<MT?G:P[]0SD
XM-ZZ)3DW]Q=5#`9N'\WZM@-\IX=RWT[5*C\]XU!="Y;SV-*:X(?[]Q@OZ&[`*
XMM<)-6?6+`X<(Y!9Z&3'G4@O"P).Y`_H.U4.XLE09K_]C/ZNJIYRG>@BQTT(`
XMJ#X^"D>.Z&9LS$(9G'A',+>89%4D-[L)\3-<")8;"@+N@>PU=DIDX<_EN?P]
XM^@)`Y'G;"AME!:G0.CF.%K`\-'\R++[1]E;U*(**RX@@=44)<@RK;6:K:CO1
XM]G8)H6,7K[&M=D,-5L3.U5&D#_R4#5W96T5`5#/+H-8MG9SCS#`'!@2NE,VF
XM+<F/I_S%H@C"DA6JMFBO06H_`@$W?H@7!P8B?%UU'^@.@EHH6#Y!3?BURG-0
XM$,?3-Q!27^00K^$VT?E_&-OU!FOR8[HA9=W/B;3'61?W%<Q4!6H6T9/[P9!V
XM*W2/,R=%B),6S,!CLUOGKD?FB&O%1X1T'XB``@:H`$HL16`4M88^MSPEX$M:
XM):**Z.*QT1HOM=3;KZWU4?.MK>JJ<HBHZ_\-]N;[-<GNW0%E@J7]LY?Y(PL8
XM\C\T0R&;ZX1<+:,`B/YO([`U-*#[KF,8%L!]JK]!RFD!YG&L1"LX#(0GL4PD
XM"UY]0^F%=)[0X[)D8Q2KQ;\4:L'B!Y(K_)LH"@!KDP8.JP9O4)%'+^K1+%WZ
XM.<-X"_1O(.<!U+G4W>SKU$K&J,TW3G[RC=[MMW>ZE-A(<T^;3ZR0%4OR]"6/
XMY>0>(.H0<9W=$G>9A7S[DG@LDVFXEF92M]9\,DK5Z,D[KK^CHH2F%HRGZW!O
XM^//F)(#5A74.J7K<6^1EA,IX74%UV^)S@C42/T9%)M&8"O^'834_33$D.]&5
XM._U6*5<=\,Z1)]UWQ@`.^"MF]1YN2<1L&=Z[NI-*:X]I6`A$:3<I\Z<!>8R>
XM%J+PO2[K.RS_HB@5?OU"G/?WI17G_:'DT:G]B<>X__Z,<-W8_<F4]=:%U-.S
XM]&>;'1D&>SN1/0W9IG<>?B=`5'$-([.$V])ID8,TI_J0Z%CS1$]*._$8(A;7
XM>3GBC"A>G-T"6JQ8O5R4*QDTZVGE-WQ"A8GJWSW=S4(``M=%$F,0W>E?EI^>
XMWPO*4@;8]IL]F0NG908Q-',Y1N.Z?TX)0#.F[&WJ$F]I0]_>Z]S=>,N#+>4(
XMXV#*DDNBK17;0`=.3;8[#P3O.J(UWZQP"IC"CJ9RP0,LDT144QY[=1^E^,I9
XMJ!DZDGP7IQ0WPK[`^(+I3OKR5>;R'^T:6^H"-@:^VT&?$47'83(Q8O0FKXA$
XM94VJ@6^?ILA44UU:>Y)7G#[H7D3J]AY=.)8:A+.(3-='ZD[;@[\Y>9&I>\QJ
XM7@!`*C/&(L.22?B:X_A]&>]>(],]!TBX<#C]]'AK=KKW6EU0!$027M<[)3E7
XMA)%.ME'2<VXN[@S,[.M;@Z=HCBT5-AX1BW=MP1^:?_S(%VS=Q@3:/$[7`Q\9
XM+.W:H"E?.Q2+J9*L("-WF*>24ANU[XV%#H]#=1\1YB^-D]UR2*I5184B0F/3
XM3NB)JP;8VSQZX,;%J#_E,D].K3U-NPH^>K<[1"M/I`M9R<CA@1E2.<+^'K]*
XMUWI`/-SF'["RX&1PM*H>;,!J,KQ\L_JNW7=^$7REX-\17-.(S/*E8<29'(2U
XMO80($8$%#EXX&X)W-'\L[=9U8!D)""7[8GV"`(ZH%R2I%5]J3B1&X6`[\9`7
XM@"4D.X1B8#X[;@AUJ0+#<?_%8LD8?PJSLA*7W=`)#?H@0_E!0"[RA?#.<+QR
XM-%WZ^5I/3C6@]X)=2&0O1X:`CK?Z)]#/?H"@#?J]G#,('_4WU11KS5J]_@Y4
XM]!K<;GR<+;1<3&#D))9.$B-`$)<?[09QOM:E3SB-FHO%P,,IM#@\"*TTU(T7
XM<KFR/B4)J65$I_41_S2W,E#Z%QC\<3,EQ4/1+Y]Z>:I."^&L0C4`?S2N#ZQC
XMD00U-::;RXJCFIF+Q7`9+L`-3,$6!@\3"Y0=I0OG3KH:"OZ1INWZ+8?KW)`C
XM)^X_L!Z"K][6ZP(-MO$YRBG/XE-2!N@70THI(Q0A`44>29;E=39F](6)G+'+
XM$3E^8KP"*GX=LEN2`]TU^T1E)X`>9,^DS3P!G/.W.Q+J6)U?B5B^M4PI;LYP
XMC!:MYKUVL5W+J7UF>_C1#H9P(65\1%3W4I:(^&0>G+I#-DU*B(HV5W=Y$6S=
XM$1`+3O_7Y]4R87QA:O^"3%PIDC+")90/)_S9];UVXR`E4S@2$6`VM(MLH\$8
XMM\&UG0T"3A^'LWPB@]@_D4ZW!Z:BA1@S5]VDK3%K,XLQGY1ECIG#B<>CV<G,
XM<7#*6,,ILY9&)F>Z`IL1F=5,*RJBFX&9^RHZ(T2P\'HC'/55)3(>%1QDH]1W
XM%GPS^2Y$#4?&;Z+M[.J&:3&8ZVKICR2J@ZAU'PEX>+B&4P,^(4KAJ0!MD(]7
XM`9@#%V6ZUH;4#8R3`B2,CZ\4<=QNRTO)R)<LBX5F<=\S!C!`4+)./^(]![(/
XMVD1!A298"/<_)Z*MQYBJ342G&$R1>%8NTOM2W'%$9F5!I[]#8/*CH<*B;I=;
XM6AR_,N8VR@"3VW\W$0<`U#+)Z"K/OQ*BX=T*8W1T)R9=:VY$;%Y!DMY>%P85
XM?T$"]+3-/!L:\U_)_W)EU6$'$,(2+YV^RLM.R2P)5\_\Q?H)I-#^CF;[5`9M
XMB5<";(3CPX$(X#FF%*1^P;9TL\W?2R(+"7I./$Q@N:<=`+N:F:9""0,#+>&2
XM/J6.K309.C!.%J&/?"KP'99$G3@8<8'5#!R8T1D83)A'`D@TDP>!$T4='.T@
XM3`+!&>?A5!%).X:7W])*HRO-1D70Q3WAL&VXEKSR,6YD,E18Y:DMMV?6-60`
XMF4A<@5YY5Q(JK^E:@5$DJ6/SP)F4Z=(C?R$5N<<#SQN:=@<G-5;)A;R2NB]"
XMX4#!`M3E#<Y$)&USRVJUJ^D"<-ZIKC9`4JH\I.O+TG!U$1(+,$-"$<P[*J4H
XMTP#Q8-TRY%OYRN>F$1G<T_NLP9X2K1O7O+N\4*7O3E$%%#J>K-;\NPQ_VVR&
XMQ%TWIC6>`B3_T9F(=7.&[TDH1UUT6Q%`-P8"XU0*W>VP_ORMM>3MPC$GG>&I
XM!9^>NL]!UK:J>I8.Q:<SD<=ELN`8!38]ZK5C_:'O6)9=4P_[7?G]>79+N,!1
XM_#23(B"PZ8=,M$&X@D+W$9>5,"^K>::0=(UKN:2^(S`GG$;HHTD;2!7^6J1\
XMW4"Y/GA([D:/=J^!;4`Z;3@YMJFXE?.YW$D55-%!&!<^QR%R'D?5P8)EJ<27
XMEJM%$[XTO-2>V>8&"MG`E\M-]@S2-I25XL+NQ:7D+!X=]@I+;$^$:>^.:VHD
XM_2S8OA&,Y!7N743ID;^^?;0VV@G)079%/=,WL:UDNQYS11B.M,:C?7QMPO\E
XMX/7LMA'X#*I`H\IT1(>I>VVO5ZW^I+6]1?D($/C@`:^@K?8X]/1=?!(O]>WM
XMU#0+!_F:9S8&Y)<BR3[+;C$PGMO.C5\&%[?;72P'!G(!JL+Z^8R]>7TXA&D(
XML"Y")%KL<#0L?VAP/&FK4:D6%PQ72Y.3;@O1*BEXZ5X)=%P:(64.1S<<?MV&
XM6C(M]>'Q2!9'7\C06A"'/&%Y7VD$$W\IF@1Q$PIB(K^&KKS@8R:IB;DOI#:'
XMAF7R0I^NLUI9B'],QN:/D>:B>Z!TE*-6/T@L;>OC3SR)3;Q5\"IV<5B'+W\?
XM'F1MV2A<=[[)1$I]7T@],\8N=M\?W4EVZMPP@"!^/]EBU^0QU--YT=ZBSH6$
XMPP:+R;WGDA*;<%+.S"'TR=T(4(NB(``"(ZU?A829@@1HT;;1N@74E;JYU+ZJ
XM7=U`/R/@UY]:">R;KXI/3I>\J<LYO@A/3:JI-XN7(3</2RV@+CDC.SKP0L5\
XMIZ\V!"F;*?"O[EGY(P7IF'_/DT1#*-83_\N[T6`Z'YL_"0A.>JP=!:D:`J;M
XME>>086!\GN$C!'[A`E<`V31'G4L]+UHQ+V)$)>VAH)\4V+O510#?EP>SB["O
XMRBHXP;6IBG?U,'2++KP#NTKD*&/0I,/"822/4S_&U((=N/2J94&,REO#T7BD
X!&"HX
X`
Xend
END_OF_UU.test1
if test 8715 -ne `wc -c <UU.test1`; then
    echo shar: \"UU.test1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f autotri.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"autotri.c\"
else
echo shar: Extracting \"autotri.c\" \(7624 characters\)
sed "s/^X//" >autotri.c <<'END_OF_autotri.c'
X/*
X * Automatic guessing based on trigrams.
X *
X * Bob Baldwin, January 1985.
X */
X
X#include	<stdio.h>
X#include	<math.h>
X#include	"window.h"
X#include	"terminal.h"
X#include	"layout.h"
X#include	"specs.h"
X#include	"cipher.h"
X#include	"autotri.h"
X
X
X#define	DEBUGP	FALSE		/* Perm building */
X#define	DEBUGB	FALSE		/* Best guess */
X
X#define	ATRLABEL1  \
X"Auto Trigram, max SD: %4.2f total: %d wire: %d -- Please Wait"
X#define	ATRLABEL2  \
X"Auto Trigram, max SD: %4.2f total: %d wire: %d -- Done"
X#define	ATRHELP		 "F3 enters guess, ^G undoes it."
X
X
Xextern	char	mcbuf[];
Xextern	ecinfo	gecinfo;
Xextern	atrdraw(), atrfirst(), atrenter(), atrundo();
X
X/* Gloabal State. */
Xchar	*trigramstats;		/* Filename for statistics. */
Xatrinfo	gatrinfo;
Xkeyer	atrktab[] = {
X		{CACCEPT, atrenter},
X		{CUNDO, atrundo},
X		{CGO_UP, jogup},
X		{CGO_DOWN, jogdown},
X		{CGO_LEFT, jogleft},
X		{CGO_RIGHT, jogright},
X		{0, NULL},
X		};
X
X/* Routine invoked by user to put up the equivalence class
X * guessing window.
X * The window is drawn empty, and then filled in with the guess.
X * Return NULL if command completes ok.
X */
Xchar	*atrguess(str)
Xchar	*str;			/* Command line */
X{
X	gwindow	*atr;
X	atrinfo	*atri;
X	ecinfo	*ecbi;
X	int		*dbsperm;
X	int		i, c;
X	int		classpos;
X	int		x, y;
X
X	atr = &gbstore;
X	atri = &gatrinfo;
X	dbsperm = refperm(dbsgetblk(&dbstore));
X	atr_init(mcbuf, dbsperm, atri);
X	ecbi = atri->eci;
X	atri->min_total_chars = 123;
X	atri->min_wire_chars = 456;
X
X	if ((i = sscanf(str, "%*[^:]: %f %*[^:]: %d %*[^:]: %d",
X		&atri->max_score, &atri->min_total_chars,
X		&atri->min_wire_chars)) != 3)  {
X			return("Could not parse all three arguments.");
X		}
X
X	gbsswitch(atr, ((char *) atri), atrktab, atrfirst, wl_noop, atrdraw);
X
X	sprintf(statmsg, ATRLABEL1,
X	        atri->max_score, atri->min_total_chars, atri->min_wire_chars);
X	gblset(&gblabel, statmsg);
X	atrdraw(atr);
X	fflush(stdout);
X
X	atr_autoguess(atri);
X	decode(ecbi->ciphertext, ecbi->plaintext, ecbi->perm);
X
X	sprintf(statmsg, ATRLABEL2,
X	        atri->max_score, atri->min_total_chars, atri->min_wire_chars);
X	gblset(&gblabel, statmsg);
X	atrdraw(atr);
X
X	return(NULL);
X}
X
X
X/*  (re) Draw the window.
X */
Xatrdraw(atr)
Xgwindow	*atr;
X{
X	int			i;
X	int			row, col;
X	atrinfo		*atri;
X	ecinfo		*ecbi;
X
X	atri = ((atrinfo *) atr->wprivate);
X	ecbi = atri->eci;
X	row = 1;
X	col = 1;
X
X	for (i = 0 ; i < BLOCKSIZE ; i++)  {
X		if (i%LINELEN == 0) {
X			wl_setcur(atr, gbspos2row(i), gbspos2col(i));
X			}
X		plnchars(1, char2sym(ecbi->plaintext[i]));
X		}
X
X	for (i = gbspos2row(BLOCKSIZE) ; i <= GBHEIGHT ; i++) {
X		wl_setcur(atr, i, 1);
X		plnchars(LINELEN, ' ');
X		}
X
X	for (i = 1 ; i <= GBHEIGHT ; i++) {
X		wl_setcur(atr, i, LINELEN+1);
X		plnchars(atr->wwidth - LINELEN, ' ');
X		}
X
X	wl_setcur(atr, row, col);
X}
X
X
X/* First time cursor enters window.
X */
Xatrfirst(atr, row, col)
Xgwindow	*atr;
Xint			row, col;
X{
X	usrhelp(&user, ATRHELP);
X	wl_setcur(atr, row, col);
X}
X
X
X/* Enter the guess into the decryption block.
X */
Xatrenter(atr)
Xgwindow	*atr;
X{
X	atrinfo		*atri;
X
X	atri = ((atrinfo *) atr->wprivate);
X	dbsmerge(&dbstore, atri->eci->perm);
X	wl_rcursor(atr);
X}
X
X
X/* Undo the last guess.
X */
Xatrundo(atr)
Xgwindow	*atr;
X{
X	dbsundo(&dbstore);
X	wl_rcursor(atr);
X}
X
X
X/* Fill in auto-trigram info from given ciphertext block.
X * The filter parameters are not set by this routine.
X */
Xatr_init(cipher, perm, atri)
Xchar	cipher[];
Xint		perm[];
Xatrinfo	*atri;
X{
Xextern	int	*trig_loaded;
X	int		i;
X
X	atri->eci = &gecinfo;
X	if (!trig_loaded)
X		load_tri_from(trigramstats);
X	ec_init(cipher, perm, atri->eci);
X	atr_guess_init(atri);
X}
X
X
X/* Per guess initialization.
X */
Xatr_guess_init(atri)
Xatrinfo	*atri;
X{
X	atri->best_trigram = NULL;
X	atri->best_score = 10.0;
X	atri->gcount = 0;
X	atri->total_score = 0;
X	atri->best_pvec[0] = NONE;
X	atri->best_permvec[0].x = NONE;
X}
X
X
X
X/* Score a trigram at a given position.
X * It also looks in atri for filtering parameters (total number
X * of chars must not be less than min_total_chars, and the minimum number
X * of chars deduced per wire must not be less than min_wire_chars).
X * This routine fills in permvec and pvec.
X * Returns -1.0 if guess is unacceptable.
X */
Xfloat	atr_score(atri, trigent, pos, permvec, pvec)
Xatrinfo		*atri;
Xtrig_ent	*trigent;
Xint			pos;
Xperment		permvec[];
Xint			pvec[];
X{
X	int		length;
X	int		i, x, y;
X	int		ccount;
X	int		added;
X	extern	float	logvar;
X	float	score;
X	ecinfo	*eci;
X	int		butfirst;
X	int		butlast;
X
X	for (length = 0 ; trigent->trigram[length] != 0 ; length++);
X	eci = atri->eci;
X	added = permvec_from_string(atri->eci, trigent->trigram, pos, permvec);
X	if (added < 0)  return(-1.0);
X
X	butfirst = pos;
X	butlast = pos + length -1;
X	ccount = 0;
X
X	for (i = 0 ; i < PERMSZ  &&  permvec[i].x != NONE ; i++)  {
X		if (ccount >= BLOCKSIZE-1)  break;
X		x = permvec[i].x;
X		y = permvec[i].y;
X/*		added = decode_wire_but(eci, x, y, &pvec[ccount], -1, -1);*/
X		added = decode_wire_but(eci, x, y, &pvec[ccount], butfirst, butlast);
X		if (added < 0)  {
X			ccount = 0;
X			break;
X			}
X		if (added < atri->min_wire_chars)  {
X			ccount = 0;
X			break;
X			}
X		ccount += added;
X		}
X	pvec[ccount] = -1;
X
X	if (ccount <= 0)  return(-1.0);
X	if (ccount < atri->min_total_chars)  return(-1.0);
X
X	score = pvec_1score(pvec);
X	if (score < 0.0)  return(-1.0);
X/*
X	score = exp(-(score * score) / 2.0);
X	score = score / sqrt(2*PI*logvar/ccount);
X	score = score * trigent->prob;
X*/
X	return(score);
X}
X
X
X/* Select the best trigram for a given position.
X * Returns pointer to trigram string, or NULL.
X * Fills in atri with additional information.
X * Filtering parameters are in atri.
X */
Xchar	*atr_best(atri, pos)
Xatrinfo	*atri;
Xint		pos;
X{
X	int		tgram;
X	float	score;
X	perment	permvec[PERMSZ];
X	int		pvec[BLOCKSIZE+1];
X#if DEBUGB
X	char	str[BLOCKSIZE+1];
X#endif
X
X	atr_guess_init(atri);
X
X	for (tgram = 0 ; trig_tab[tgram].trigram != NULL ; tgram++)  {
X		score = atr_score(atri, &trig_tab[tgram], pos, permvec, pvec);
X		if (score < 0.0)  continue;
X		atri->total_score += score;
X		atri->gcount++;
X		if (score < atri->best_score) {
X			atri->best_score = score;
X			atri->best_trigram = trig_tab[tgram].trigram;
X			pvec_copy(pvec, atri->best_pvec);
X			permvec_copy(permvec, atri->best_permvec, PERMSZ);
X			}
X		}
X
X#if DEBUGB
X	if (atri->best_score < atri->max_score) {
X		printf("\nTrigram '%s' at %d", atri->best_trigram, pos);
X		pvec2str(str, atri->best_pvec);
X		printf(" deduces '%s'", str);
X		printf(" which scores as %g", atri->best_score);
X		printf(".\n");
X		}
X#endif
X
X	if (atri->best_score < atri->max_score)
X		{return(atri->best_trigram);}
X	else
X		{return(NULL);}
X}
X
X
X/* Merge the given permvector into the permutation table.
X * Return ERROR if there is a conflict, otherwise TRUE.
X */
Xint	accept_permvec(atri, permvec)
Xatrinfo	*atri;
Xperment	permvec[];
X{
X	int		i, x, y;
X	ecinfo	*ecbi;
X
X	ecbi = atri->eci;
X	for (i = 0 ; i < PERMSZ  &&  permvec[i].x != NONE ; i++)  {
X		x = MODMASK & permvec[i].x;
X		y = MODMASK & permvec[i].y;
X		if (perm_conflict(ecbi->perm, x, y)) {
X#if DEBUGP
X			printf("CONFLICT trying to wire %d to %d.\n", x, y);
X#endif
X			return(ERROR);
X			}
X		}
X
X
X	/* Now know that there are no conflicts. */
X	for (i = 0 ; i < PERMSZ  &&  permvec[i].x != NONE ; i++)  {
X#if DEBUGP
X		printf("ACCEPTING wiring of %d to %d.\n", x, y);
X#endif
X		x = MODMASK & permvec[i].x;
X		y = MODMASK & permvec[i].y;
X		ecbi->perm[x] = y;
X		ecbi->perm[y] = x;
X		}
X
X	return(TRUE);
X}
X
X
X
X/* Perform automatic guessing given a set of
X * filter parameters in an atrinfo structure.
X */
Xatr_autoguess(atri)
Xatrinfo	*atri;
X{
X	int		pos;
X	char	*trigram;
X
X	for (pos = 0 ; pos < BLOCKSIZE ; pos++) {
X		trigram = atr_best(atri, pos);
X		if (trigram != NULL) {
X			accept_permvec(atri, atri->best_permvec);
X			}
X		}
X}
END_OF_autotri.c
if test 7624 -ne `wc -c <autotri.c`; then
    echo shar: \"autotri.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dline.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dline.c\"
else
echo shar: Extracting \"dline.c\" \(6929 characters\)
sed "s/^X//" >dline.c <<'END_OF_dline.c'
X/*
X * Library of display line routines.
X *
X * Robert W. Baldwin, December 1984.
X */
X
X#include	<stdio.h>
X#include	"window.h"
X#include	"specs.h"
X
X
X/* After clrdline is called the routines assume that there is
X * a null character terminating the string at index w->wwidth.
X * That is, the length of the display string is always equal
X * the the (fixed) width of the line.
X * The dl_length field behaves like the apparent string length.
X * It is the column location of the last non-blank character.
X * That is, an all blank line has a length of zero.
X */
X
X/* INTERNAL PROCEDURES */
X
X/* Set the range of positions between firstcol and lastcol (inclusive) to
X * the given string.  The string is padded on the right with spaces
X * or truncated to make it fill the interval.
X */
Xsetarange(line, str, firstcol, lastcol)
Xdispline	*line;
Xchar		*str;
Xint			firstcol, lastcol;
X{
X	int		i;
X
X	line->dl_length = 0;
X	for (i = firstcol-1 ; i < lastcol ; i++)  {
X		if (*str == 0)  break;
X		if (*str != ' ')  line->dl_length = i+1;
X		line->dl_chars[i] = *str++;
X		}
X
X	for ( ; i < lastcol ; i++)  {
X		line->dl_chars[i] = ' ';
X		}
X
X	line->dl_chars[i] = '\000';
X}
X
X
X
X/* PUBLIC PROCEDURES */
X
X
X
X/* Set the line from column, col, onward to the given string,
X * padding with blanks if needed.  Note col = 1, set the whole line.
X * This cannot be used to initialize a display line.  It does not
X * set the character preceeding col.
X */
Xsetnadline(line, str, col)
Xdispline	*line;
Xchar		*str;
Xint			col;
X{
X	setarange(line, str, col, line->wwidth);
X}
X
X
X/* Blank out all the characters in a displine.
X */
Xclrdline(line)
Xdispline	*line;
X{
X	line->dl_length = 0;
X	setarange(line, "", 1, line->wwidth);
X}
X
X
X/* Set the entire displine to the given string, padding with blanks.
X * This fills in the null termination, so it can be used to initialize
X * a display line.
X */
Xsetadline(line, str)
Xdispline	*line;
Xchar		*str;
X{
X	line->dl_length = 0;
X	setarange(line, str, 1, line->wwidth);
X}
X
X
X/* Set characters in the given range to the string, truncating 
X * if necessary.  Do not pad with blanks, just avoid overflowing
X * the range.
X */
Xsetrange(line, str, firstcol, lastcol)
Xdispline	*line;
Xchar		*str;
Xint			firstcol, lastcol;		/* Inclusive interval. */
X{
X	int		i;
X	int		newlength;
X
X	newlength = 0;
X	for (i = firstcol-1 ; i < lastcol ; i++)  {
X		if (*str == 0)  return;
X		if (*str != ' ')  newlength = i+1;
X		line->dl_chars[i] = *str++;
X		}
X
X	if (newlength > line->dl_length)  line->dl_length = newlength; 
X}
X
X
X
X/* Starting at column, col, set the characters in the display line, line,
X * to the given string, str.
X * This differs from setnadline because it does not pad the line with blanks.
X * Overflows are avoided by truncation.
X * Note that col is a one-based position, not zero-based as strings are.
X * This cannot be used to initialize a line, since it does not set the
X * characters before column col.
X */
Xsetndline(line, str, col)
Xdispline	*line;
Xchar		*str;
Xint			col;
X{
X	setrange(line, str, col, line->wwidth);
X}
X
X
X/* Set the variable part of the line (between min and max_col) to
X * the given string.  Pad with blanks.
X */
Xdlsetvar(line, str)
Xdispline	*line;
Xchar		*str;
X{
X	setarange(line, str, line->dl_min_col, line->dl_max_col);
X}
X
X
X
X/* Fill the given buffer from the given range of column positions.
X * Trailing blanks are not removed.
X */
Xgetrange(line, buf, firstcol, lastcol)
Xdispline	*line;
Xchar		*buf;
Xint			firstcol, lastcol;
X{
X	int		i;
X
X	for (i = firstcol-1 ; i < lastcol ; i++)  {
X		*buf++ = line->dl_chars[i];
X		}
X	*buf = '\000';
X}
X
X
X/* Fill the given character buffer with a null terminated string
X * corresponding to the part of the dline between the min and max
X * column positions.  Trailing blanks are not removed.
X */
Xdlgetvar(line, buf)
Xdispline	*line;
Xchar		*buf;
X{
X	getrange(line, buf, line->dl_min_col, line->dl_max_col);
X}
X
X
X
X/* EDITING PROCEDURES */
X
X
X/* Insert the given character at the current cursor position.
X * Do nothing if the line would become too long.
X * Do nothing if the character is not printable.
X * The cursor moves to the right one column, provided it doesn't
X * move past dl_max_col.
X */
Xdlinsert(line, k)
Xdispline	*line;
Xkey			k;
X{
X	char	restbuf[MAXWIDTH+1];		/* Char from cursor to end. */
X	char	insbuf[2];					/* Char to insert. */
X
X	if (line->dl_length >= line->wwidth)  return;
X	if (!printable(k))  return;
X
X	getrange(line, restbuf, line->wcur_col, line->wwidth);
X
X	insbuf[0] = k;
X	insbuf[1] = '\000';
X	setrange(line, insbuf, line->wcur_col, line->wcur_col);
X
X	setrange(line, restbuf, line->wcur_col+1, line->wwidth);
X
X	dlright(line);
X}
X
X
X/* Delete the character at the current cursor position and
X * shuffle down the rest of the line.
X * The cursor doesn't move.
X * The non-blank length is correctly maintained.
X */
Xdldelete(line)
Xdispline	*line;
X{
X	char	*p;
X	char	linebuf[MAXWIDTH+1];		/* Rebuild whole line here. */
X
X	getrange(line, linebuf, 1, line->wcur_col-1);
X
X	for (p = linebuf ; *p != '\000' ; p++);	/* p pts to end of line. */
X	getrange(line, p, line->wcur_col+1, line->wwidth);
X	
X	setadline(line, linebuf);
X}
X
X
X/* Move the cursor right within min and max column.
X */
Xdlright(line)
Xdispline	*line;
X{
X	if (line->wcur_col+1 <= line->dl_max_col)
X		line->wcur_col++;
X}
X
X
X/* Move the cursor left within min and max column.
X */
Xdlleft(line)
Xdispline	*line;
X{
X	if (line->wcur_col-1 >= line->dl_min_col)
X		line->wcur_col--;
X}
X
X
X
X/* DISPLAY UPDATING PROCEDURES */
X
X
X/* Redraw routine for a display line.
X */
Xwl_dldraw(dline)
Xdispline	*dline;
X{
X	int		oldcolumn;
X
X	oldcolumn = dline->wcur_col;
X
X	wl_setcur(dline, 1, 1);
X	plstring(dline->dl_chars);
X	wl_setcur(dline, 1, oldcolumn);
X}
X
X
X/* Insert a character an redisplay the line.
X */
Xwl_dlinsert(line, k)
Xdispline	*line;
Xkey			k;
X{
X	dlinsert(line, k);
X	wl_dldraw(line);
X}
X
X
X/* Delete the current character an redisplay the line.
X */
Xwl_dlfdel(line, k)
Xdispline	*line;
Xkey			k;
X{
X	dldelete(line, k);
X	wl_dldraw(line);
X}
X
X
X/* Delete the previous character an redisplay the line.
X * The cursor moves backwards one position.
X */
Xwl_dlbdel(line, k)
Xdispline	*line;
Xkey			k;
X{
X	if (line->wcur_col == line->dl_min_col)  return;
X
X	dlleft(line);
X	dldelete(line, k);
X	wl_dldraw(line);
X}
X
X
X/* Move cursor right and update display.
X */
Xwl_dlright(line)
Xdispline	*line;
X{
X	dlright(line);
X	wl_rcursor(line);
X}
X
X
X/* Move cursor left and update display.
X */
Xwl_dlleft(line)
Xdispline	*line;
X{
X	dlleft(line);
X	wl_rcursor(line);
X}
X
X
X/* Clear the variable part of the display line and update the display.
X */
Xwl_dlclr(line)
Xdispline	*line;
X{
X	dlsetvar(line, "");
X	line->wcur_col = line->dl_min_col;
X	wl_dldraw(line);
X}
X
X
X/* Scan for the first argument place holder, '%',
X * position the cursor there, and delete it.
X * Do nothing if the line doesn't contain a '%'.
X */
Xwl_nxtarg(line)
Xdispline	*line;
X{
X	int		i;
X
X	for (i = line->dl_min_col-1 ; i < line->dl_max_col ; i++) {
X		if (line->dl_chars[i] != '%') continue;
X		wl_setcur(line, 1, i+1);
X		wl_dlfdel(line);
X		break;
X		}
X}
END_OF_dline.c
if test 6929 -ne `wc -c <dline.c`; then
    echo shar: \"dline.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f specs.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"specs.h\"
else
echo shar: Extracting \"specs.h\" \(6537 characters\)
sed "s/^X//" >specs.h <<'END_OF_specs.h'
X/*
X * Specifications of inter-module dependencies.
X *
X * Robert W. Baldwin, December 1984.
X */
X
X
X/* General Information. */
X
X/* A pvec is an 'string' of integers that represent plaintext
X *    characters.  The string is terminated by a -1.
X * A pbuf is a fixed length array of integers that represent plaintext
X *    characters.  A value of -1 means that the characters is unknown.
X * A cbuf is a fixed length array of bytes that represent ciphertext chars.
X * A perm is a mapping from shifted ciphertext characters to shifted
X *    plaintext characters.  Each character is shifted (incremented) by
X *    its offset in the block of 256 characters that contain it.
X * A gsi is a data structure about a guess that includes information
X *    on the characters that are assumed to be right.
X * An eci is a data structure that descibes a block of cipher and
X *    plain text.
X * A string is a null terminated vector of bytes.
X */
X
X
Xextern	twindow	banner;
Xextern	twindow	webster;
Xextern	twindow	dblabel;
Xextern	gwindow	dbstore;
Xextern	twindow	gblabel;
Xextern	gwindow	gbstore;
Xextern	twindow	user;
X
Xextern	gwindow	*ibanner();
Xextern	gwindow	*iwebster();
Xextern	gwindow	*idblabel();
Xextern	gwindow	*idbstore();
Xextern	gwindow	*igblabel();
Xextern	gwindow	*igbstore();
Xextern	gwindow	*iuser();
X
Xextern	char	*savestr();
Xextern	int	substrp(/* big, little */);
Xextern	int	read_slashed(/* *string */);
X
Xextern	char *(quitcmd(/* arg-string */));
Xextern	char *(lpbguess(/* arg-string */));
Xextern	char *(atrguess(/* arg-string */));
Xextern	char *(kntguess(/* arg-string */));
Xextern	char *(ecbguess(/* arg-string */));
Xextern	char *(pwdguess(/* arg-string */));
Xextern	char *(permsave(/* arg-string */));
Xextern	char *(permload(/* arg-string */));
Xextern	char *(webmatch(/* arg-string */));
Xextern	char *(clearzee(/* arg-string */));
Xextern	char *(pgate(/* arg-string */));
X
Xextern	char *(cmddo(/* cmdtab, string */));
Xextern	char *(cmdcomplete(/* cmdtab, string */));
Xextern	gblset(/* w, string */);
Xextern	gbsswitch(/* w, private, keytable, firsttime, lasttime, draw */);
Xextern	gbsclear(/* w */);
Xextern	hstadd(/* w, string */);
Xextern	usrstatus(/* w, string */);
Xextern	usrhelp(/* w, string */);
Xextern	dblbnum(/* w, int */);
Xextern	int	dbsmerge(/* w, perm */);
Xextern	dbssetblk(/* w, int */);
Xextern	int	dbsgetblk(/* w */);
Xextern	dbstrypq(/* ecbi, pque_hdr, pos */);
X
Xextern	float	score(/* pbuf */);
Xextern	float	gsi_1score(/* gsi */);		/* Uses 1st order stats. */
Xextern	float	gsi_2score(/* gsi */);		/* Uses 2nd order stats. */
Xextern	float	var_1score(/* pvec */);		/* Uses first order stats. */
Xextern	float	prob_1score(/* pvec */);	/* Uses first order stats. */
Xextern	float	pvec_1score(/* pvec */);	/* Uses first order stats. */
Xextern		load_1stats();			/* Loads first order stats. */
Xextern		print_1stats();
X
Xextern	int	decode(/* cbuf, pbuf, perm */); /* FALSE if has bad chars. */
X/* Return -1 if	bad chars, otherwise # of chars added to pvec. */
Xextern	int	decode_wire(/* eci, x, y, pvec */);
X/* Returns -1 if bad chars, otherwise # of chars added to pvec. */
Xextern	int	decode_class(/* eci, firstpos, firstplain, pvec */);
X/* Returns number of wires added to permvec assuming that plaintext
X * str occurs at pos.  Fills in permvec.  Returns -1 if conflict. */
Xextern	int	perm_from_string(/* eci, str, pos, permvec */);
X/* Fills in pvec with the plaintext characters deduced
X * from the wires in permvec that are not in the positions
X * ranging from butfirst to butlast.  Returns -1 if any
X * non-ascii chars are deduced, else count of chars. */
Xextern	int	permvec2pvec(/* eci, permvec, pvec, butfirst, butlast */);
Xextern		permvec_copy(/* from, to, maxnum */);
Xextern		pvec_copy(/* from, to, maxnum */);
Xextern		print_pvec(/* stream, pvec */);
Xextern		char2buf(/* cbuf, pbuf, length */);	/* Fills in pbuf. */
Xextern		buf2char(/* cbuf, pbuf, length, nonechar */); /* Fill cbuf. */
Xextern		str2pvec(/* string, pvec */);		/* Fills in pvec. */
Xextern		pvec2str(/* string, pvec */);		/* Fills in string. */
X
Xextern	int	fillcbuf(/* blocknum, *cbuf */);   /* Ret TRUE if sucessful. */
Xextern	int	*refperm(/* blocknum */);	   /* Ret NULL if fails. */
Xextern	copyperm(/* src, dst */);
Xextern	readperm(/* fd, permbuffer */);	/* Gets chars from fd to fill perm. */
Xextern	writeperm(/* fd, permbuffer */);	   /* Writes perm to file. */
Xextern	multperm(/* left, right, result = (left)(right) */);
Xextern	expperm(/* src, dst, k */);		   /* dst = src ** k. */
Xextern	int	permcount(/* perm */);		   /* Return # values != -1. */
Xextern	int	permwcount(/* perm */);		   /* Return # of wires. */
X
Xextern		approx_init();		/* Call before fexp or isqrt. */
Xextern	float	fexp(/* float */);	/* Fast exp func. */
Xextern	float	isqrt[];		/* Sqrts of integers < BLOCKSIZE */
X
X
X/* Globals State */
Xextern	char	*cipherfile;		/* Ciphertext file name. */
Xextern	char	*permfile;		/* Permutation save file name. */
Xextern	char	*letterstats;		/* Single letter stat file name. */
Xextern	char	*bigramstats;		/* Letter pair statistics file name. */
Xextern	char	*trigramstats;		/* Trigram statistics file name. */
Xextern	int	permchgflg;	        /* TRUE if perms chged since save. */
Xextern	char	statmsg[];		/* Buffer to build status messages. */
X
X
X/* Extensions to C */
X#ifndef reg
X#define	reg		register
X#endif
X#define	abs(x)	(((x) > 0) ? x : (0 - x))
X
X
X/* Macros */
X#define graphic(c)	(c & SYMBOL)
X#define notascii(c)	(c>127)
X#define printable(c)	((32 <= c) && (c <= 126))
X#define lletter(c)	(('a'<= (c)) && ((c) <= 'z'))
X#define uletter(c)	(('A'<= (c)) && ((c) <= 'Z'))
X#define isspace(c)	( ((c) == ' ') || ((c) == '\t') || ((c) == '\n') )
X#define isletter(c)	(lletter(c) || uletter(c))
X#define tolower(c)	( uletter(c) ? ((c) - 'A' + 'a') : (c) )
X
X
X/* Constants */
X#define	BLOCKSIZE	256	/* Number of chars in a cipher block. */
X#define MODMASK		0377	/* Arithmetic mod 256. */
X#define	CHARMASK	0177	/* ASCII char mask. */
X#define	MAXCHAR		127	/* Highest ASCII value. */
X#define MXBIINDEX	40	/* Num different chars in a bigram. */
X#define LINELEN		64	/* Number of characters per line. */
X#define	NLINES		4	/* Number of line pairs. */
X#define	NONE		(-1)	/* No info on something. */
X#define	ERROR		(-1)	/* Procedure can't meet normal case specs. */
X#define	EOL		(-37)	/* A hack used by read_char() */
X#define	PI		(3.1415926)
X#define	NPERMS		15	/* Max number of blocks in a file. */
X
X#ifndef	TRUE
X#define	TRUE		1	/* The whole truth. */
X#endif
X#ifndef	FALSE
X#define	FALSE		0	/* Lies, falsehoods, etc. */
X#endif
X#ifndef NULL
X#define	NULL		0	/* A zero by any other name ... */
X#endif
END_OF_specs.h
if test 6537 -ne `wc -c <specs.h`; then
    echo shar: \"specs.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f test.txt -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"test.txt\"
else
echo shar: Extracting \"test.txt\" \(6305 characters\)
sed "s/^X//" >test.txt <<'END_OF_test.txt'
XThe data may be passed to the procedure through value
Xparameters, and return values obtained through reference parameters.
XThe caller is suspended pending the return of the callee.  However,
Xinvocations differ from local procedure calls in several important
Xways.  The first, which is particular to Eden, is the requirement of
Xan accompanying capability to name to the target Eject.  Therefore,
Xthe Eject programmer is quite aware of the fact that an invocation is
Xnot "just another procedure call".  A second difference is
Xperformance.  Invocations will be far slower than a local procedure
Xcall simply because there is more going on.  The Eden kernel must
Xlocal the target Eject; network traffic may be necessary if the target
XEject is not on the same machine; parameters must be packaged into a
Xmessage to be sent to the target Eject; the target Eject must
Xunpackage the message and call the desired procedure with the
Xparameter values; the target Eject must package the results into a
Xmessage to be sent to the invoking Eject; finally, the invoking Eject
Xmust unpackage the results and return them to the calling procedure.
XIn light of such a performance deficit, Eject programmers may be
Xreluctant to structure a particular collection of Ejects in novel ways
Xin order to avoid the invocation overhead.
X
XThe thesis of this paper is to demonstrate that acceptable performance
Xfor invocations can be obtained in the Eden environment by paying
Xclose attention to the design and implementation of modules that
Xsupport remote procedure calls.  For the purposes of this thesis, the
Xscope will be limited to the Ejects' point of view.  The Eden kernel
Xwill not be considered.
X
X\section{Some Background}\label{introbck}
X
XEden has had a long history of improvements to its invocation
Xmechanism.  Previous work has concentrated on removing extraneous {\it
Xinter-process communication} (IPC) messages.  Particularly in Eden's
Xcase, IPC messages are very expensive.  Eden is built on top of Unix;
Xtherefore, each IPC message from an Eject to the Eden kernel, and vice
Xversa, involves at least a Unix process switch and copying the IPC
Xmessage into and out of the Unix kernel.
X
XThe first versions of Eden required 14 IPC messages to be sent per
Xlocal invocation.  A local invocation occurs when the invoking Eject
Xand the target Eject reside on the same physical machine.
XWhat was 2-process kernel's role in this setup?
X
XThe 2-process Eden kernel was finally replaced by a 1-process Eden
Xkernel, immediately reducing the number of messages required for an
Xinvocation by eliminating the IPC messages between the two kernel
Xprocesses.
X
XThe final reduction in IPC messages sent per invocation occurred
Xduring the summer of 1984.  Two more IPC messages were eliminated.
XOne of the messages eliminated was the IPC message from the Eden
Xkernel to the invoking Eject that communicated the {\it invocation
Xhandle} assigned to that particular call.  It was replaced by a scheme
Xwhere the invoking Eject was allowed to generate its own {\it local
Xinvocation handle} to communicate with the Eden kernel, and the Eden
Xkernel would generate its own unique handle in order to communicate
Xwith another Eden kernel or the target Eject.  The Eden kernel
Xguarantees that the reply message to an invocation will be stamped
Xwith the invoking Eject-generated handle.  The other IPC message
Xeliminated was the status message from the Eden kernel to the target
XEject confirming the kernel's approval of the reply message (format,
Xor contents if capabilities were contained in the reply).  The more
Xlogical scheme of notifying the invoking Eject of the failure status
Xof the reply, or the actual reply if the status was success, is now
Xbeing used.  The result of all these improvements is shown in figure
X\ref{oldfig}.  (See section \ref{oldexp} for an explanation of figure
X\ref{oldfig}.)
X
X\section{Related Work}\label{introrel}
X
XNelson's thesis thoroughly examines remote procedure calls.  He
Xstudies a number of implementations, and proposes a design for
XEmmisary(?), a new RPC mechanism with excellent transparency and
Xexceptional performance.  To attain exceptional performance, Nelson
Xgives a list of "lessons" that an RPC mechanism must have.  The
Xlessons are summarized here for the reader:
X
X\begin{itemize}
X\end{itemize}
X
XIn designing an RPC mechanism, it is convenient to use a layer model.
XHowever, strict adherance to the layer model often results in poor
Ximplementations.  There is a prohibitive cost associated with highly
Xmodular implementations that cannot be tolerated in RPC
Ximplementations.  In proposing a solution to the asynchrony
Xproblem, Cooper\cite{soft} advocates "soft layering".  The idea of soft
Xlayering may be applied to any naturally layered system whose layers
Xmust work well together.
X
X\section{Structure of Thesis}\label{introstruct}
X
XChapter \ref{old} examines the deficiencies of the current Eden
Xinvocation mechanism.  The reader is taken on a tour through the
Xprocess of initiating an invocation and receiving its reply, and
Xreceiving a new invocation and replying to the invocation.
X
XChapter \ref{new} proposes restructuring the dispatcher module for
Xsynchronous invocations (by far the most heavily used form of
Xcommunication within Eden) and breaking down the "hard layering" that
Xcurrently exists between the various layers that support invocations,
Xfrom the Eject's point of view, in order to obtain significant
Xperformance gains.
X
X\chapter{A Closer Look at the Eden Invocation Mechanism}\label{old}
X
X\section{The Dispatcher -- Interface and Internals}\label{olddis}
X
X\section{Flow of Data -- CIP, Stub, and ESCII}\label{olddat}
X
X\section{Summary}\label{oldsum}
X
X\chapter{An Alternative Synchronous Invocation Mechanism}\label{new}
X
X\section{Assumptions and Limitations}\label{newass}
X
X\section{The Dispatcher -- Interface and Internals}\label{newdis}
X
X\section{A Word About Buffer Management}\label{newbuf}
X
X\section{Flow of Data -- CIP, Stub, and ESCII}\label{newdat}
X
X\section{Results and Timings}\label{newres}
X
X\section{Summary}\label{newsum}
X
X\chapter{Conclusions and Further Work}\label{concl}
X
X\section{Lessons Re-learned}\label{conles}
X
X\section{Soft Layering}\label{conlay}
X
X\section{Modularization and Interfaces}\label{conmod}
X
X\section{Further Work}\label{confur}
X
X\end{document}
X
END_OF_test.txt
if test 6305 -ne `wc -c <test.txt`; then
    echo shar: \"test.txt\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f user.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"user.c\"
else
echo shar: Extracting \"user.c\" \(7027 characters\)
sed "s/^X//" >user.c <<'END_OF_user.c'
X/*
X * User status and command window.
X *
X * Robert W. Baldwin, December 1984.
X *
X * Bob Baldwin 10/86.
X *  Formatting changes.
X *  Change usrdown to fix screen fall off bug.
X *  Change usrfirst to fix cursor pos so jumpcmd() works.
X */
X
X
X#include	<stdio.h>
X#include	"window.h"
X#include	"terminal.h"
X#include	"layout.h"
X#include	"specs.h"
X#include	"parser.h"
X
X
X#define	DONEMSG	 "Command completed."
X#define	USRHLP	1		/* Offset for help line. */
X#define	USRSTAT	2		/* Offset for status line. */
X#define	USRCMD	3		/* Offset for command line. */
X
X
X/* Global space to build status messages. */
Xchar	statmsg[MAXWIDTH+1];
X
X
Xextern	int	usrfirst();	/* Defined below. */
Xextern	int	usrdokey();	/* Defined below. */
Xextern	int	usrdraw();	/* Defined below. */
Xextern	int	usrup();	/* Defined below. */
Xextern	int	usrdown();	/* Defined below. */
X
X
X/* Command table. */
X#define USRHTEXT \
X"bigram, knit, prop, load, save, lookup, clear, equiv, auto-tri, pword"
X
Xcmdent	usrcmdtab[] = {
X		{"quit-program permanently", quitcmd},
X{"auto-trigram max_dev: % min_total_chars: % min_wire_chars: %", atrguess},
X		{"knitting using blocks from: % to: %  Min show count: %", kntguess},
X		{"lookup-pattern: % in dictionary", webmatch},
X		{"equivalence-class guess, use accept level: % (try 2.0)", ecbguess},
X		{"pwords-from file: %  Max dev: % (try 1.0)", pwdguess},
X		{"load-permutations", permload},
X		{"save-permutations", permsave},
X		{"clear-zee permutation", clearzee},
X		{"propagate-info from: % to: % using Zee", pgate},
X		{"bigram-guess level: % (2.0), min_prob: % (0.15)", lpbguess},
X		{0, NULL},
X		};
X
X
X/* Keystroke table for the user area. */
Xextern	usrdocmd();
X
X/* Keystroke table for the whole user window.
X * The editing on the command line is handled by a sub-window.
X */
Xkeyer	usrktab[] = {
X		{CGO_UP, usrup},	/* Keep off help and status lines. */
X		{CGO_DOWN, usrdown},	/* Normal behavior ok. */
X		{CEXECUTE, usrdocmd},	/* Interprete a command. */
X		{0, NULL},		/* Handle other chars elsewhere. */
X		};
X
X/* Keystroke table for the command line sub-window.
X */
Xkeyer	cmdktab[] = {
X                {CNEXTARG, wl_nxtarg},
X		{CGO_LEFT, wl_dlleft},	/* Stay withing variable area. */
X		{CGO_RIGHT, wl_dlright},/* Stay withing variable area. */
X		{CDELF, wl_dlfdel},	/* Delete forward within var area. */
X		{CDELB, wl_dlbdel},	/* Delete backward within var area. */
X		{CCLRLINE, wl_dlclr},	/* Clear variable area. */
X		{CINSERT, wl_dlinsert},	/* All other chars self-insert. */
X		};
X
X
X/* Window for the user commands and program status. */
X
Xdispline usraline[USRHEIGHT];		/* Display lines for the user. */
Xdispline *usrlines[USRHEIGHT+1];	/* Pointers to them plus NULL. */
X
Xtwindow	user = {
X		USRROW,1,		/* Origin. */
X		USRHEIGHT, USRWIDTH,	/* Height and width. */
X		USRCMD+1, USRSCOL,	/* Initial (relative) cursor pos. */
X		NULL,			/* No private data. */
X		usrfirst,		/* Firstime = restore cursor pos. */
X		wl_noop,		/* Lasttime = do nothing. */
X		usrdraw,		/* Default draw routine. */
X		usrdokey,		/* Custom keystroke handler. */
X		usrktab,		/* Keystroke table. */
X		usrlines,
X};
X
X
X
X/* Display a string in the status area.
X * If the string is empty, this will clear the status area.
X * Put the cursor back where it was.
X *
X * The empty string is special case.  If the status line is
X * empty, then wcur_col = 1.  A second request to clear
X * the line is ignored.
X * If the line is not empty, wcur_col = dl_min_col.
X */
Xusrstatus(w, str)
Xtwindow	*w;
Xchar	*str;
X{
X	displine *line;
X	int	 row, col;
X	
X	row = rowcursor();
X	col = colcursor();
X
X	line = w->dlines[USRSTAT];
X	if (*str == 0  &&  line->wcur_col == 1)
X	  	return;
X
X	dlsetvar(line, str);
X	(*(line->wredraw))(line);
X	setcursor(row, col);
X
X	line->wcur_col = (*str == 0) ? 1 : 2;
X}
X
X
X
X/* Display a string in the help area.
X * If the string is empty, this will clear the help area.
X * Put the cursor back where it was.
X */
Xusrhelp(w, str)
Xtwindow	*w;
Xchar	*str;
X{
X	displine *line;
X	int	 row, col;
X	
X	row = rowcursor();
X	col = colcursor();
X
X	line = w->dlines[USRHLP];
X	dlsetvar(line, str);
X	(*(line->wredraw))(line);
X
X	setcursor(row, col);
X}
X
X
X
X/* Draw the user area.
X * Leaves the cursor on the command line.
X */
Xusrdraw(w)
Xtwindow	*w;
X{
X	wl_twdraw(w);
X}
X
X
X
X/* Make a window with a title and partial outline.
X */
Xgwindow *(iuser())
X{
X	int	 i;
X	displine *line, *lines;
X	twindow	 *w;
X
X	w = &user;
X	lines = usraline;
X	for (i = 0 ; i < w->wheight ; i++)  {
X		line = &lines[i];
X		line->worg_row = w->worg_row + i;
X		line->worg_col = w->worg_col;
X		line->wheight = 1;
X/* Fix bug on terminals that autowrap. */
X		line->wwidth = (i == USRCMD) ? w->wwidth - 1 : w->wwidth;
X		line->wcur_row = 1;
X		line->wcur_col = USRSCOL;
X		line->wfirst = wl_rcursor;
X		line->wlast = wl_noop;
X		line->wredraw = wl_dldraw;
X		line->wkey = dokey;
X		line->wkeyprocs = arwktab;
X		line->dl_min_col = USRSCOL;
X		line->dl_max_col = line->wwidth;
X		clrdline(line);
X		w->dlines[i] = line;
X		}
X	w->dlines[i] = NULL;
X
X	line = &lines[USRHLP];
X	setadline(line, "Help   : This feature not implemented");
X	line = &lines[USRSTAT];
X	setadline(line, "Status : ");
X	dlsetvar(line, "Just barely working");
X	line = &lines[USRCMD];
X	setadline(line, "Command: ");
X	line->wkeyprocs = cmdktab;
X
X	return((gwindow *) w);
X}
X
X
X/* Behavior of the up arrow key.
X * Move up to the window above us staying in the same column.
X */
Xusrup(w, k)
Xtwindow	*w;		/* The user window. */
Xkey	k;
X{
X	wl_setcur(w, 1, w->dlines[USRCMD]->wcur_col);
X	jogup(w, k);
X}
X
X
X/* Behavior of the down arrow key.
X * Move to command line.
X */
Xusrdown(w, k)
Xtwindow	*w;		/* The user window. */
Xkey	k;
X{
X	wl_setcur(w, USRHEIGHT, w->dlines[USRCMD]->wcur_col);
X}
X
X
X/* Behavior when cursor first enters the user window.
X * Move to the command line.
X */
Xusrfirst(w, row, col)
Xtwindow	*w;
Xint	row, col;	/* Place in window when cursor currently is. */
X{
X	displine *cmdline;
X
X	wl_setcur(w, USRHEIGHT, w->dlines[USRCMD]->wcur_col);
X	usrhelp(w, USRHTEXT);
X	cmdline = w->dlines[USRCMD];
X	(*(cmdline->wfirst))(cmdline, 1, col);
X}
X
X
X/* Keystroke handler for user window.
X * If it is not an up-arrow or down-arrow, pass it to the command line.
X */
Xusrdokey(w, k)
Xtwindow	*w;		/* The user window. */
Xkey	k;
X{
X	char	 *expanded;	/* Expanded command line. */
X	char	 cmdbuf[MAXWIDTH+1];
X	displine *cmdline;
X
X	cmdline = w->dlines[USRCMD];
X	usrstatus(&user, "");
X	if (ddokey(w, k, w->wkeyprocs))  {  /* If handled by top window. */
X		return;			    /* Includes doit key. */
X	}
X
X	if (k == ((CINSERT << CMDSHIFT) | SPACE))  {
X		dlgetvar(cmdline, cmdbuf);
X		expanded = cmdcomplete(usrcmdtab, cmdbuf);
X		if (expanded != NULL)  {
X			dlsetvar(cmdline, expanded);
X			wl_dldraw(cmdline);
X			return;
X			}
X		}
X	(*(cmdline->wkey))(cmdline, k);	/* Else pass to sub-window. */
X}
X
X
X/* Interprete a command.
X */
Xusrdocmd(usr)
Xtwindow	*usr;
X{
X	char	 cmdbuf[MAXWIDTH+1];
X	char	 *errmsg;
X	displine *cmdline;
X
X	cmdline = usr->dlines[USRCMD];
X	wl_setcur(usr, usr->wcur_row, cmdline->wcur_col);
X	dlgetvar(cmdline, cmdbuf);
X	if ((errmsg = cmddo(usrcmdtab, cmdbuf)) == NULL)
X		errmsg = DONEMSG;
X	usrstatus(&user, errmsg);
X}
END_OF_user.c
if test 7027 -ne `wc -c <user.c`; then
    echo shar: \"user.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 11\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Rich $alz			rsalz@pineapple.bbn.com
Cronus Project, BBN Labs	"Anger is an energy"