IMD 1.16: 1/06/2007 9:48:07 FOGCPM.157 --FOGCPM157KERMIT DOC KERMIT DOC-01-00 87 K PQSKCMD PQSKDIR PQSKDISPLAYPQS KERMIT PQS !"#$%&'()*+,-KERMIT PQS./0123456789:;<=KERMIT PQS>?@-CPM157 DOCKHELP PQSABCDKINIT PQSEFGHKOPEN PQSIJKKREC PQSLMNOKREC1 PQS1PQRSTUVKSEND PQSFWXYZ[\]^_KTERM PQS`abKERMIT HLPcKRMTEXECCOMdefghijklmnopqrsKRMTEXECCOMLtuvwxyz{|}KERMIT C ~KERMIT C KERMIT C 'This is the disk name.  Turbo Pascal Kermit CP/M-80 Author: Jeff Duncan Language: Turbo Pascal Version: 1.1 Date: 29 December 1984 Turbo Kermit Capabilities at a Glance Local Operation Yes Remote Operation No Transfers Text Files Yes Transfers Binary Files Yes Wildcard Send No (planned feature) ^X/^Y Interruption No Filename Collision Avoidance Yes Can Time Out No 8th Bit Prefixing Yes Repeat Count Prefixing No Alternate Block Checks No Terminal Emulation No Communications Settings Yes (parity) Transmit Break No IBM Communication No Transaction Logging No Session Logging No Raw Upload No Act as Server No Talk to Server Yes Advanced Commands for Server No Local File Management Yes (dir) Command/Init Files No Printer Control Yes This is a third release of Turbo Pascal Kermit for CP/M 80. It is not complete or fully debugged. Comments, fixes, bug reports, etc. are welcome. I am available at (617) 839-5673 evenings, or at 3 Anderson Lane No. Grafton, Ma. 01536 Much thanks go to Bernie Eiben for help and encouragement, and to Columbia University for creating Kermit. Thanks also to those who have offered comments, fixes, and enhancements. Modification History: 29-DEC-84 Jeff Duncan - Extensively remodeled Turbo Kermit. Major areas changed were: V1.1 1. Binary files will now be transmitted and received correctly. 2. Added more extensive comments to entire program. 3. Added section in documentation to list operating system dependent code. 4. Announce procedure added by Alan Hull temporarily eliminated to keep basic release generic. (but I liked the logo) Limited/no testing has been done in the following areas: 1. 8'th bit quoting. 2. Generating parity. 3. Printer logging. V1.0 08-DEC-84 Alan Hull - Corrected Directory function to work on all drives. Version 0 was hardcoded to drive C only. Enhanced the directory display to 5 columns, better filename display. Added Sign-on logo for DEC Robin. Easily changed for other systems by recoding announce procedure. Added file delete option (any drive). Updated Help, command prompt, and all routines affected by the above enhancements. V0.0 05-DEC-84 Jeff Duncan - Initial release of Turbo Pascal Kermit for CP/M-80. Turbo Pascal Kermit Description The motivation behind writing a Kermit implementation in Turbo Pascal was principally to have a generic Kermit that would run on a variety of systems without any modification. Turbo Pascal has turned out to be a popular language because of its speed, ease of use, and features. It seemed logical therefore to write a Kermit in Pascal that could be transported without difficulty to many machines. This program is still in its developmental stage. There are still some bugs that have to be worked out, and there are features that should be added, but I hope this is a good starting point! The original goal of this project was to produce a Kermit that could compete speed-wise with an assembly language version, but be written in a higher level language that would be easier to maintain and could be used in a variety of systems. It would also be easily adaptable to other operating systens that can run Turbo Pascal such as MS-DOS and CP/M-86. To a large extent, this is true. There is more operating system dependent code than I originally intended, but most of it is in a few routines that could be rewritten easily for another operating system. The performance is good considering that it is written in Pascal. Connect mode appears to be glitch-free at 9600 baud, and I have had no problems with file tranfer due to speed at 9600 baud as well, using two DEC VT-180's, running both normal CP/M and ZCPR2. The degree of buffering on various computers could affect this. Command Summary ***************************************************************************** IMPORTANT NOTE To abort form send or receive use -- ^D -- NOT ^C. This is because of testing problems using ^C. ***************************************************************************** I have no intention in this preliminary documentation to provide detailed descriptions of all the commands in this version of Kermit. They are well documented in the Kermit Users Manual and the Protocol manual provided by Columbia. I hope that the following will help show what features are available and any bugs or unresolved issues there are in the implemented commands. A note about the command parser: This parser will not allow ? and escape as in DEC-20 and others. However, the minimum unique abbreviation will be recognized as a valid command. A good portion of the parser to do this has been written, and may be added to Turbo Kermit at a later time. Both upper and lower case letters are acceptable as input. Connect - Establish a virtual terminal connection to a host connected to a serial port on the computer. The current version supports the reader/punch port and the UC1: port, because it was written on a VT180. Selection of port is done by the SET command, and port switching is done by manipulating the CP/M standard IOBYTE at location 3. I/O is done by calls to BIOS via Turbo Pascal standard functions and procedures. Escape from CONNECT mode is done with ^\-C. Operation, as mentioned before, appears correct at 9600 baud on a VT180. Send - Send the selected file to the remote Kermit. At present wildcards are not supported, but hooks are there to add this feature. Receive - Receive file(s) from the remote Kermit. Files will be received and stored in the same names that the remote Kermit specifies in its file header packet(s). Multiple files may be received. This command does not request files from the remote Kermit. It waits until the remote Kermit initiated the file transfer. If the filename being sent already exists, Turbo Kermit will attempt to create a unique filename for the file. If this is successful, a message to this effect will be printed on the screen. Get - Request from a remote server that certain file(s) be sent. The filespec as typed is sent exactly to the remote Kermit. Files will be received and stored as in receive mode. Bye - When sent to a remote server, log out the server, and log out the host. If the logout of the server is successful, exit to CP/M. If it is unable to logout the remote host, Turbo Kermit returns to the prompt level. This is to allow reconnection to the remote system for further action without having to reload Kermit. Finish - Log out the remote server. If this is unsuccessful, a message is displayed at the terminal. Logout - Logout the remote server and the remote system and remain in Kermit. Dir - Print a directory listing for any drive. Wildcards are allowed in the filespec following the Dir command. Era - Erase any file(s) specified on any drive. Wildcards are allowed in the filespec following the Era command. Set - Set a Turbo Pascal Kermit parameter. The following are valid parameters: PRINTER - on of off. WIll turn the printer on for logging a virtual terminal connection only. PARITY - mark, space, even, odd, or none. this will convert the 8th bit of a file transfer to the appropriate parity for file transfer. Parity is stripped on receive. Any parity except none will attempt 8th bit quoting if binary files are selected. FILE - Binary or Ascii. If ASCII is selected, all files transmitted will be terminated on the first ^Z detected in the file. Receiving will continue until an end of file packet is received. When binary is selected, the files will be sent until CP/M signals the last sector. As mentioned above, binary file transfer will be attempted using 8th bit quoting if parity other than none is selected. PORT - Currently only reader/punch and UC1: are supported using the CP/M standard IOBYTE. Program Organization Because the program is not fully documented, the following is a description of the organization of the program to help find what's where. Because Turbo will only handle a limited size file, there are a number of include files. This was also done so that the program will compile in memory to speed up debug. The files required are: K.PAS - program header, include's, and main procedure KINIT.PAS - type, const, and var declarations, and general utilities KDIR.PAS - directory listing procedures KOPEN.PAS - open a file on the micro KDISPLAY.PAS - display procedures for send and receive KHELP.PAS - help displays and set parameter procedures KREC.PAS - general receive procedures KTERM.PAS - virtual terminal mode KSEND.PAS - sending a file to remote KREC1.PAS - receiving a file from remote KCMD.PAS - command parser The following is a list of procedures and functions by file: File - K.PAS none File - KINIT.PAS Tab generates a string of spaces Ctl conversion to/from control character Char40 adds 40 hex to integer to produce character Unchar subtracts 40 hex from character to produce integer Ltrim removes leading spaces from string Rtrim removes trailing spaces from string File - KDIR.PAS Adjust_Fn expands string to CP/M filename format also inserts wildcard characters Init_Fcb sets up FCB for filename search Searchfirst calls bdos for searching for filename Searchnext calls bdos for searching for filename Dir generates directory listing Delfile delete specified file(s) Deletefile calls BDOS for the delete File - KOPEN.PAS Open_File tries to open a file Open_For_Write tries to open a file for Writing File - KDISPLAY.PAS Displayt base display for send mode Displayr base display for receive mode Update update the display File - KHELP.PAS Show show local parameters Help display help message Set_Param sets up local parameter File - KREC.PAS Get_Char tries to get a character form port also monitors crt for abort or retry Receive_Packet get a complete packet from remote File - KTERM.PAS Send_Char send a character to port Term virtual terminal mode FILE - KSEND.PAS Check_Init sets up parameters from send init dialogue Check_Ack checks ack packet for correctness Send_Packet send a packet to remote Build_Packet put checksum and parity on packet Quit return to CP/M unconditionally Finish handle bye, finish, and logout commands Send send a file to remote host Get_File_Data build a data packet Sinit send init state handler Sheader send file header handler Sfile send file data handler Seof send end of file handler Sbreak send break handler Send_Ack send an ack packet Send_Nak send a nak packet File - KREC1.PAS Rheader receive file header packet Get send server get command Rinit receive send init packet Expand_Packet disect received data packet Rfile receive file data File - KCMD.PAS Parse parse the command line Prompt display a prompt Get_Command_Line dispatch command per typed command line System Dependent Code The original intent of Turbo Pascal Kermit was to produce a version of Kermit that would be written with a minimal need for system dependent code. Turbo Pascal provides general procedures for screen handling that obviate the need for much system (or terminal dependent) code, but there are some areas that must be written with the target system in mind. Somethings just can't be done without these routines, and speed is enhanced by using them. However, Turbo Pascal is quite fast. In this implementation, I have had no need to add assembly language routines to implement the most critical speed related routines, terminal mode and send/receive packets. I have, though, had to add system dependent code. This version of Kermit is designed to run on CP/M-80 only. In all the terminal and communications port routines I have used BIOS calls. These have allowed a terminal mode that will operate at 9600 baud. BIOS calls have also been used to send and receive data packets. These are not quite as fast, but appear to limited to slightly less than 4800 baud with no buffering of data in the basic operating system. The other area of this program that uses CP/M-80 system calls is the directory printing routines. I was planning to separate all the system dependent code into one module, but decided against that because there is too much of it and the routines span several blocks that do not logically fit together. Instead, this section of the manual for Turbo Kermit is intended to detail those areas that have system dependent code for those who may be interested in modifying this version for other operating systems. 1. Directory Listings The directory listing code of Turbo Kermit are almost entirely system dependent. The directory information is extracted via BIOS calls, and the directory mask is converted to upper case and expanded to be readable by CP/M-80. This will probably be different for most other operating systems. 2. IOBYTE All communications (terminal mode and send/receive packets) are done with CP/M Bios calls. In order to interrogate the various ports, the CP/M IOBYTE is changed to reflect the desired communications port desired. This version presumes that the IOBYTE is located in RAM at 0003 hex. Three variables are used to set the IOBYTE. They are 'iobyte', 'base_iobyte', and 'port_iobyte'. 'base_iobyte' is a copy of 'iobyte' when the program is entered. 'port_iobyte' is initially set to point at the reader/punch port. This variable can be changed using the 'SET PORT' command (procedure located in file 'khelp.pas'. Additional ports can be added in this routine. 3. Sending characters to communications port The include file 'kterm.pas' includes the virtual terminal mode, and the only procedure that transmits to the remote ports, 'send_char'. This procedure resets the IOBYTE to point at the appropriate port and sends the character using a BIOS call. This routine could be easily replaced to send a character on another type of system. 4. Receiving packet data When receiving packet data from a communications port, a procedure located in the include file 'krec.pas' is used. This procedure, called 'get_char' performs the same type of port switching required by CP/M to check status as virtual terminal mode. This routine can be replaced by something a different operating system can understand. 5. Virtual terminal mode Virtual terminal mode is riddled with CP/M BIOS calls. Because CP/M does not allow port status to be read except when the port is the logical console, termianl mode is a loop that changes the ports to be the console, and checks the status. When the status indicates a character is available at the communications port, it is fetched and sent to the screen. When a character is typed at the keyboard, it is sent to the communications port via the 'send_char' procedure above. Terminal mode would have to be rewritten for any other type of system. There is no terminal emulation package in this version of Kermit. This would be difficult to accomplish and still maintain any reasonable speed. 6. Opening files File opening and closing is all done with Turbo Pascal procedures. However, the size of the the filenames is hard encoded into the routines so some messing around will be required for systems that handle different length filenames. Note also that the procedure 'adjust_fn' located in 'kdir.pas' is used to find places to insert characters in the filename if a naming conflict occurs when opening a file for writing. If you change the directory listing routines, leave that one in there, or implement the filename conflict routine differently. 7. Deleting files Deleting files is done with CP/M BIOS routines. This will also have to be rewritten for another system. vK.PASw  !"#$%&'o()*+,-./0123456789:;<=>?@AB6CDEFGHIJKLMNOPQR{STUVWXYZ[\]^_`abcdecZ=2|njg[><-fghijklmnopqrstuvzsKJHFA@5*%. Y`KPtEViN4+[if"`#(ʅE*ܟFiV., KJ4Jrao4FiV., DqY74Jrao4ܜFiV., CaO4+\UG!\@6/VLɤ lI0  q 3.enPo.J`1,֔ [l>] uXl>] uY ,bRC\@6q.s{G~xr|%fP Q Y 3.enP/^PV. ϸ`B#nJ`a) +g\^_)A-ެ\@6q.s{GNώ?R=Zl^ VLɤi F%>P =*]@6G)Oliz(OQ f CMLL+3"&*H3 a>u@ipaIw. ElRú9CeBvɠsl&= aJ'B 4E) ࡒC|\@6[:Z= =,W- n ʀ7 |9 -LJQ(͐x*B\@67*#i= =4GHsl*%=ּi%F(f(%&npd㪝 n u5ouqբ`PE̒;ͅ|u7%FKC!* EsdHl7zvIhxJt(,0  9,1w. E9lMF]J+6E9lMF]SуWY%(-1uM v"ItG#G!S `^30H! j#[d;E0zl`^3h"(U\@Ң1,xѕ=+`,6k J sٮOQIW%F \ i(UEAFsَx3% uW%Fzi`dAڂ7HJr`$; i;O{ܼ*1zl)aR0[w. W4,@c`]bجSBelI*1W|}MPX?YcN !%R# NJ;+ΔnQhd2TqŰ54[4\@1T:18VZ=-Pl߹l/"+1zQ"2d4vJJSуP1GxQHm;͕f*rMDE%F_pMP! ~_ %!q;= 4|wy?ϟ}߻o'G_{ŝ4r[y~?{_w?}ɑ$Q?_'?nOG=ovvW/NG뿴'lWr>:->'->_'w~/s(Wv@KCMD.PASI o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH>1֔ўiXʃqSAPyXQ& 36+h:ƚpvyXQ&lwfclwfcP1_ݡ/aiS9]6DGPUQAb e KPUQ1%8$<wb(c[A{cxP mR9xPʃaYK,TN8;cc 1o]6#q{>;cc`LS ;ռLU BH ò2!!1[A{cKqJҦ Tsl  d/6蝣'ʃV1֔ykB B<,(חo1UΊ %%_06J A_& Tò2} 3_Ѩ0Qr!Q6hUle6%2X3ɔGmF&m/ڨSlpAB}dcU ڃÿ)su9펝ʅD5LIl CᠴfcS^>jQ=1b=l ZcI4S f ?P6L2ecK ڃÿcMHAeeg h05!jeo1mTj)ibCMeq\1I<ք3C>dhOcM8;c$SF{bkB3Rwc()I&ò25(?(pCD uaevI<ք3Ld[y~?{_w?}ɑ$Q?_'?nO aVM BU;GO1ulwMA*z(6/:ԭBwb3c?`#蝣o$S6u[6HA*z(vx 1M6蝣ؼ4P mvKDIR.PAST o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS ތ:t'M(/IĎ4%Y-F|MXEZv5u]4;ReCXEZvO\Ď4VxѬfKmIIGj+ २\t5Su{V#)(aG芧-`Iǫ[LY- Gv+:{BhQ4!Ie/re Os-d&xѬ=ʔX:(0Q+u;Gc,+LPeCW EFW:` B̄ĎT|EW@wW]Pפ2$/?6Xx.+OZoхI VZHXxC ]`=c pkbGRP[tA]H4Ohk 'Ď4.LJ w}鯮 d&e mbG]&%Xf]5#M EeϩA RypEؑ*jߑj!L !Yft6 ĎT3;ReCxD~pEؑFjEˆ̄Ď4DؑFzFbGr  ^HE̤P[5 AfBb!5=-A<5 95Xx8jrYS'A )h[QS54XezZ5 Z<̤P[5 AfBb!5=-A<5 95Xx8jrYS'A )h[QvKDISPLAY.PASY o !"#$%&'()*+,-./60123456789:;<=>?@ABCDEFGHIJKLnjgc=MNOPQRSTUVWXKJH>@ņ oZ!; 3=n\\G o \)g+) X- gLQO_c5joH41VG!U[)) #{N81ingWm2Zםjh ) #{N2.)2@+dGa`u; vvxC\ ԑ='hvL2_Q,U>TGaXI8ݹIY meD?2N1eF\Wy?ܧ |= ˔g 0OE,UyOEz)*& `ޒЧ |H*TGarSb(ԧ |H*}*ףLN,,OE ( QX!Xήy`u; !h.Ȟ4;&]RF56*_7ᘊ2(,sb+;7=3x Vz: |H*TGarb`ޒ&(_7:eQX߸X9ud)L}*׍d~ا |= ˔’T2E68ܺXh<;%'+0FD*;,mpL !Xή.) Ŋr]ۻ:eQXܺXh<=ME,U(_2ud4eF\WnOEz)ղݒ8v8(A1K;zoI}omR}իOg}|9ؿxGss?]]~/4+OqfGcombGl˷x UFQ'm#=D5'-౞HIJKLnjgc=MNOPQRSTUVWXKJH>@ņ oZ!; 3=n\\G o \)g+) X- gLQO_c5joH41VG!U[)) #{N81ingWm2Zםjh ) #{N2.)2@+dGa`u; vvxC\ ԑ='hvL2_Q,U>TGaXI8ݹIY meD?2N1eF\Wy?ܧ |= ˔g 0OE,UyOEz)*& `ޒЧ |H*TGarSb(ԧ |H*}*ףLN,,OE ( QX!Xήy`u; !h.Ȟ4;&]RF56*_7ᘊ2(,sb+;7=3x Vz: |H*TGarb`ޒ&(_7:eQX߸X9ud)L}*׍d~ا |= ˔’T2E68ܺXh<;%'+0FD*;,mpL !Xή.) Ŋ vKERMIT.PASz o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy팛7o~sׯcq g6,љ?<%[3xt/Hљ?<%TzGg6m,Bm,L3xtK""O78 팍 s i6A8lI o j`NBmۂc-X|ShA8-pۂc-XfSLJF͠llJ(0Z!I~U *Scc] n )Jڐbʘ;gNc4-F;@ZrۂpS\S47ׂO53Db=CaCD5fűǒPyF[4 V`stԉ-V;X?nj3`eKX?n0w ^hg^6!s i-V;NX?nUƣ*v hg$b^֏[&̝3a.hgd56>l*̝3XVڡeBb~j s ieKj|A *]&P-)0w b7 &_USvF!V16>UkT^z9pigjWTiLH,VQyAs F_abLJF_a!K s3Biv᨝'T,5 -zCL Ho6Ze̝3G qj,7 q SQ#7sH Vڡe팍^i,[PeX9p b q٫2 Uk̝3GX{i/v5n#یSA+s f:7j`8x51Bl*)%(1e̝3Gr㫦^v])(2eJע#`A8JrCj{5D"X `9ptgLM`өF;T{BJ%0w Ū˵3%Cbj}UgCbj}˵3%'Cbj}U듋Cbj}˵3%LͱD*7VY#MeKjzҙdD*7-iD*7䫽3Kr3 eH,!Sӓ${ET3Kr3ni5qSْka-kXK _!Xt*[RShcJ˶A%5-;hTْB\XZ_:xvBmSh*Z,ohYBБBtL)XAϹ)Xv3Z,o^*X6 _!Xtrr wn -zU%fO / ERᅛB\XZ_vr w qShЎBzi =f:.{q٣'IBe J/MG"BeDrL)t\qi 3?MǠAj6>S΍/HqTW;]$!ZjgWA8=&I+pr~RRcd6# q*dv8F;MP1@-<$H Ag(9pZْĂ*[RۂC;=iViN] iI,Xby NiZiE#M{LIM{LAxy-I ab~c-lI-+$gzP!DI8A#XU=!VYKǿ=*/ B|ZAo*/Ͱ ,1 NVV%N)9[؃{Bbj [{9j /PAeX Ū3*]='$ְ t*SFHP:RUj oUٲ' ֫=A S"h!a'll%W {BeKRzC{s:3&DI2ccDsgg8pfU"iX*5I3G#rXp(Io+[P!{3W$ Q'9`l% U_U4|z3]=)g.T$RX{i䶲% U_Uƣ\u3gBS;O{T$IТ=%A A s -I aCŶlIB'{>GeK:jڣ%)Oq \TS[ْ'{>jڣ%)A`+T$7 ܓrHkAUْV;LT;p% vv\;`HegΨL b OSvF6-u9*/( g- mS;Ӿ%)7bΨjipeZr9`FZ[ *pSO4O{T$7hgTVepOHg̝3&SILmeKRzC{XH)|㤫vƚb3|s 9$%5meKRzCnYAΰ*0aJ-I &T,)g=<9-KT,=!X#yh`'(!lYb$g~$ 2RG8XZs`y%Frѫc !-09paA`U"viʖ*pS ʵ3gޖ§v}eKmAn^EdvFPyʖۂ0w V9pDMV;>N:giFw]vF"P{Bh蜅R9pHK++[4@;~A*+Pd/[bbA8~Pk3W */l~b`XOP0w Bi(7LPYIʖ0w XR 2Y^(mb֨`CA8;e*U YVem+1޵Wqҁ=V( %cƽk7w26o%2]u3gLt>u3gX V;PJƌ{:\ѶBi(3]p':d …X6捾dU+v E?(jŸ#RS*9ptTvR-ij3ȞĠ+61CoKB+q:ݿ!{gFZ[ Y"-Wt[4hg,DJ֘;gl4q}pO3*g.D?(jŸqm*JEb̝3*/*vhP2fܻ*Nm+1޵W;p y/Y宫ApNSW;p2]jJCɘqZ8؁=V( %cƽkZAq^ڼїtr \6A16>~.v37bJ *9p ʵ3r A,SjgRv)BTVL%1{B"SFeKJ;gA8= ‘PJ V1Ijg*[PU3 #AJblId`ӚqhU dvO{{蜥u3Gr3#B;#SYْ0w  Z'a=)gFZ[ 9e*U 9ejIPْԁ=Htv\VA8#kgTqlOL%1UV( %w3GPJUtepOXR׶6uTS>:gL A,Sk[R:(Ϩ 2vTTV$̝3igܼyopׯci9 P!TSْʖl|&P5)ըlIBVH,VOw3 36)B̴)8=|A - IJUkxVA;$HU֒`NQ(GʃP:nWPْ`|A3w#T e& ZeT`xE,9p:w8pz{BGj ULk,Bbj}R;pĴ)Jabҵkg*[ Ūkg*[o Ū{kgA8-Gʃ|A4LmeKBbj}rƱT0z_V]3Go/HX=lD )j(PْK! M8&I֫=E$8h`LoMlV=ʖB̤A8;gA8im3g:%V%QْF;Cd -`A8ãOv #֘;g΄qlI]v Rsn_#,$X^k0w dܼQy/H<"*/PQAe̝3fU@;%)!ET=|A 1w \:ej-APْ%'vlIɾ\ْ51'$+pOlI;g.Tv`F;*:Ҫ5 sBeKj|A XA0UEҨak3-PYIq* Y9`HegΨL /XP2QvƃPْK!+61e̝3Gr3#B;ʖs(DlIgA8ҹ)0*g~Sk+[-Ij3X`_BeK9?< X(~ʖ n_3?JC"'vƖAWlℹsHkA`@3Wځe+[R#-)7+[RW;ڳm_]hgdRoQْ}CJ BvXlIPf\{֭^u3ߏCU4j`3?2Έ~( ʖsHkA`CD3߯=+dA %aڣ% U{LȞg|jg^ʵ3"kgb_ #r_j*/A,S[ْ=|AKWW Ų9<{R |ږ] ])<4%X`qev읁Pْ*/PْU/H{ڋ3t*6WChCd8زW,[wU1d*aPlKAU,);1Ztd>Y^%X -I A aH1 ||صUDeKRzC8ز.z0 DϝA~qHkAx˴)JaCeKjg :󐸩T˴)J-I Qْx[PW;iS4jʖplI-vᣭn^iA Ӧh*Y1*Մ`Mjg>BGj ڡ06ESvᣭ )|I9V9)SIL-Ӧh*O>OOV%nL>:RS |:$ >=Ӧh*u\D 4SIL-Ӧh*/|j'L{MT۟t3|A4L-Ӧh*/H5~jg~B* /H5~m*t ;\jgޮ=+dv᭭ R_=)3 =A-I aAh+Ln^GeK:pO2׶$7i_ْ=&^5e_aڃiS4 |23?9ejmIJohiϴ)Ju 23bk[´GeKPf( E|r \;#RvTΈ:SRF;ʖs3팛7o~?qu̝3@;AOBB^PMlIc-+pOD?#9]*{2:!MQ{p[T^x݃{JDp; ٦ۄ  2"cgCȚ){B(bg(t\a)Eǔϝg lSQ-hgdRo=!*C(=&$L s3 ge۞OXRӃAF:E]e;I^a$YVV'] ڳmjgb[RE"Wge>A8:ejo؃ET0u3Gkʶ 2cx5u3Gkʶ 2kbVSW;pJ*8#A٦[6ނ{B"UP${LHgNGZ[ ڳmO'] A,S c. 2$Y0qLW{vh_ٶ_u3GL-SV"+L] ڳmu3GLXDž85EǔWSW;pl] A,S;&Ki5u3r3@!>R0Y3 qj):.ĩu V1I팡Ț ME;gA8im3GkʶdA8:ej $Rz =+ړv -t\S3z =+ړW] A,SێCU4j`ɵgUW;pJ*\pqo>>1wHyBF;# q!( 1I9 i;Ao &NRĚ BEoI*/dczM(-sI%i5`a ZH*/ ܭ@W Ze$!lYb$MQ҆Sơ'w>v%9p7FBK"M )| 9 HkH?`A8:e*U;=DH1k& !&IBA8:e*U A,SZc{cږۂ~mKmA -I,*[Rۂc- 2e=׺=Z,o>~. &\*X6-9ry?O] A,SZc{czWh+ܭ= /$Knx[Ps~:XRZ>E]HEBJw+>ŗOGTc:ptT^#7}C  qOSW;ptT^> B3bEG&Ih?:w+L{Bt>u3GLjYnΈHeVv:|jgbJղkÞaOqmA >Kۂ 2e=׺=w4kl|&h al|=󩫝A8:e*Uzlu{LH_ARZaclΧv T-뱽1= V1I´G!VqΧv T3GLjjM( 1-hfEoI.>u3GLjץ( 1IBA*ZHqO9бlJB 5̝38#A=E3M(GʃyH&NpKfUN^3V -(+<d dcӹsӑV9pKIQjgbJNzBZC X6#FVSW;ptTϷWA_|jgbJղ~z蕢x^) x&>1Б4dc.ϧv T-뱽W,)^SW;ptTV)^#3!O] A,SZc{OHGbpOHE[YʨlImP߀{BO] A,SZc{OBexgSQ- =6^ 2e=eRBhg$bh7$;gA8mgR`Q'Bbʹ! ke=lHqrV,[<$B$d8زD!~cH *J)C34J$`!,xkx[l($= {,8زH^e({Ēe Ź3s3ZA8b{D +XŴ&qtUhg$Т7;gN-K'+gΦwSHkAjY_ӷ^jY_WSI9HkAiX2P —Ln6>V;L^M3? D 0*gd5V;TLT;%8τvRvGLjw4kl|&4f3u3#kgΦ=j #rGQ'K'+g~O{Lz -mAͱv)Z[;iiBeKjx[PsFlkg~23_bJN - -|jg~D*hgDs bJN_ےx[1دiʖ$K-mAͱ] HTLXaU (Dв>t2| i? +FZ.\AacRV(X6-9ւ7M6V(X6-9ւ-KShAbcJV(X6-9ւБBm ϦMXbyX V;1by[;iOXbyX V;Bm ϨL bJNXނaCg TΈ:2kE"= -MbThmAD* hvO~ #rSԉe}eN=&HkAXxᆷ5Z!ͦvbᅱZ 7֏[&v \kG~2AGUA8'kg~:ݴ4LXaU \,pۂc-X0ēj{3 /X?nڡuq 52U^vTA)AA,S:֥(0zu>u3H패aAtTvz셑n˥ 7-9rʵ3?^OI&0*g> 50}a50y5u3?im3?+*j, LX0y5 TvAHkAY!VUkvtvgXgjWT;SRvA,SX(zm6A= TA\u"̝3#kgΦLXaU X=6gjg~d+D 7"' LjIJEbL{hY_c ]@|AAaU |+,[v`3_bJNeH`i! @* TA823fU \8e*U;=֢7$в>c ]@|jg \;pD*hgDs )\B`L;͛߼~ׯ_9d Bf(GʃPB*po*[gB|<aM^K{ע#`$] i;cM `Uֈ 4 b̝3 kqiS!Y!ĚULkgNGZ[ Ӧj3Gע#`#=zavtvHe.8p$TfgάLXPxqT{{-ol,#Z)*1w &fvOIW;pf+&fܼܓlF$(He֘;gPxᆷ5ZC 'vFU. o68X!3 ~,1w \FSsP ע#`h}ju5C"D/ WxI3-V;:QceΈ=h^LJ mG%cA8cX0fWGU L7"' im3NM_9p VУjj3~z (9pŌXX2PvFT^"% b̝3H패aA0r Ѡؖh[$֌q X]vF*[^bs ‘Phmx[Ps7Cby pOkёI!Ztdh諪F;# --cA8%kg HBDžvᴝ&F$&:.9 gb{-{0m `Ӛv(&Z`M`kA8=ť V/IS\Ұ#AVebZ8 Q!>R &n$vvI&f=ka ]a^LpO(I=q!>6)B8b(KWAF[HP!F/ , أ* E:. %UkX*/ PYeSOm$ Oq3m&ZA(6 ŗk3lQyA!VUk̝3miS4ׂ눽'׾:pO gcDsO#rLNBbL`q213m&Z!z-ӦhbVb ];'RFe;CJ%?{̝3miS4ׂ0uXň\"Zp;gtNp˖iS4u |23:ej6E{-]vfHPUǒ0w "kg.ʵ3VPG/ IQ'ĞCB zq!9paU ܈=% v=% g*MB?_jg>g*MB/IobSwv\;pVhcOqiAq!nx[n^ǠAU7~jjgn a I9pkU |^{WYW; bei_7~jgnʵ3H3RvTMBs3팛7o~ߟ?~;gios3@!>RH&ZkёIULkvvƃ&#ATNЈ~`  /TPq ] *=Ul$b[LfU>8r 4 'h!LbPVdu< ~b`!IA[ *(0l±0ZuY=A~sAol{/r9pw$$0ZF֬gNH6 K0*]b3ro-(C3'0*]:p&$R R\nȔQx=j˽UkpO(3w"cJ ='0*];pAO`UM(0~a2'dP2 / կ݇չ3w_G/= l%6>9$6!{ET[.KgF݋L`'XU q*h蕢+_| eۿ6!{E8 Qe:>xZ,o{U_%[VaWt in[ ɪ5tn;hqv +BĪ5 /Ě =ŪoVEjkёI6zP=m<# B C80,#j^5~P=ܞ; ۪x;pہΝAZKJUE)sgNgN8pT3L+XŴ&A8^)Xa$jgqtUhg0s QJQ䆮XjJjg6V;\A8:e*U;=JQd`gB <ŗOGT#=x5u3GLj'(}%!X>#-V;^~2 z[Ԟty;d3bIZ=b`CU`A8OvH Y?nڡ㖩vVOIqܓr Bko637Jb&jԾA@e"gnL \~2aè5֏[ GI$] [ت5' >٣$fvʵ3G֏[&vuqT ! B8$QJ$̝3Gh}jO:ܼ3g#rL \:Jb&Έ=P $3s jb+_ L;P&Z=)gH&ZZJQ^K /L 6V;P&ZjgJ* x^ #V$ EA2J Aԉᄹs᭭) jbܓrcJQ䆮XjAxKe"g>&R$fv-Ӧj3_HT&rHkAl+0m @)ꂚkAHkAq"ki)E]P{-] b#eW;'Rvs"kiKb&jg~̴)b ŸH rvFԉ0w RvhPlKDEn#-V;:Qce腐!h¨xSRF;I6;g.8θy7/xwׯcA8-GʃbOqikA)._}IZu5 ʰ2 b̝3 36)B(_4{B"ae:. :.+rZel4Ǟ'd쑈`+Q+D Ft~D0 keD`+F =&,8=sOA+Nmd&v1 -lۈZsv=%51lj oocBNilJ^3R2C? fP6j^sgg8pV7%5X*5I3G# k(t\q Dp`9pf+Ŧq!n԰ q 6>pO{Kv`vq!nJRkڡ$MB qSZs;{R V9pVT쵴B)t\/\`.=9?͓37 &7V(6 ˝3L S\`CD5 qM]MOXaUhgh*K ۄ;gB`A;gX2P Փܓr᭎Kv`F;C(° :. "s r :.XaUhg͐#a(14cC;gޮ=+dvA,S+BDžAxG/, |!kg.P:._ڡe [򔠕-,[BT VA^MElmMyq`Xv?TN(F]cA0rvFԉ0w Q3/XP2Q ‘i3g#r=+d򪫝A0Lei/ (t\5lV q  BDžQfi/BDžQæA8#kgl/ءe"pOBDž85XPfWqR;pJ*8#ATn gNzpeD*Cq!넑H*PƸ82q!;p7{J', Ν3 kqiS4ׂbvӑVHq!9pdejq2U^F;#˜;g- =p:."{gFS{Έ%iU"Nxa3Z 7R9aA8~2aCkeV Nj31 / ^0w  ELmBD(t\S3hg ELm*JrEXUy̝3GBqX{R lۓW] 9ej:.(I_aڣ$-t\q*A0kʶ=ٟjgA,S;BeA0D?(jGIj}[7PU$wHkA)kjBDž"rvF/Rpg\!ă(ǿ9gNGZ[vƝ2ge۞j3Ĉ$/u\0R6bA8uɵ3rvƝ2gB|<ʦF;ʦ=1 bU6{~#F0w8pz#-ViMR; HkΨ9pu"VQfUtrrlzOՄ fɚ5V;LT;p6|O㴟uO fɚ5V;LS \u"̝3G q V;\A8bbqen #4;pƲj-v,MB\;p{KR;p4(%Z=z^4~-ױWX] ‘вlq}e =)gFZ[ Y{W7] 9e*U;cI`үH$$SW;pF*;pFe"gLԉPZEMVe @;@ܢ%V-M*@(zM~` \~>q .v5Q'9plۓ{]vƚq F*٦[̝3rvFeM=gi9 P!$RF;#ШlI`gBcq4z#UScߦQH/MBO3 kqebZ %R^V/IgN 5qSْYhg =%!k֘;gA8: Y4ULk3MbviS4Y Ūk/ ʍʖFKҪvV9pV7PU$M֬az7 ^KNjgHWMeKjJjg- 3ڶlIIpPU$ɾZeZ?peK:xqD?(BDžI )tTn|T;`FZ[ _l%*&uCU$:pO7*g~=>.B:~ʖGeK"㤫AueK*UL'3"i԰jq*F \I #kg´)ڡ%CU\lII. %*&jʖTxWqR;[[M:}Uu*٪5' im3.t\q*&kXP7PU$M֬qw 8ejp61RYv3Hc+ CLA0*gn=+d򬫝AqTvz>zaDeUVSW;p T5 VG/N+L{$LMbX3]jgn2slVwV r \;plۓ{] )\He̝3δs)BHrR; g4ZB8p:*3`A8Ě ;EXe5vX7-A8im3V3xj I9pNs y 234Za0 BDž"ifiU^˓mB$:\E<زݐs'W{-O.йUD.BW{-O.r㫦:g~rw^ NsWmA3 QBDž"if?M3G`:.ĵ3GTn SRF;#ʍ gi9 P!$RQzqtU :.8TI5kv>L3G`:.ĵ3GTn SRv3팛7o~Ó_\~sL;? ;g IggNzP!EǔP'hQz$T^=%'IA[+hϨlIIg:.İ T243m N` ]_ʖtܮ=%&e!j(k&g^5%P${LMeK:nWPْR1|A2ZpO ܭlI)#A[̴)44e ʖ`+grOHTD[YʨlIХ[8u $ 1l(;p='(Uk,$&#ALVD** -t\BDž8A',eX ߐl,xї V.ϝA8;gA8= +XŴ&qtU  3HBDžvV(t\{R q!nx[| …t&i 0*g RMeKjb_C(6 qW;W[{R rU %*&j'^A3FZ[ZW "9BDžQbS7j `_ٶO.u38ej[>??0u3HrR;Ě "cj*[R /IegJe"g~9*gP7PU$X0 _BeKjg0MB\;D*7 q 腱ځe=+dvLjZ))TPl vᗤr r …D*7 Vim3:.č6X BDžQævD*7:.3/I ^B+ q V;Ŧq!n԰AxHFǥv0V; T;v_ٶ.OLo ]{WbW;TA@*7 Vim3_ F vMBܨaS;%ʍK r …A-Vim3/腱ځe q V;Ŧq!n԰AxY7PU$X0;(P(t\ۂΧ`:.ĵ3/:.ĵ3/מmAxyNG/L|jg^=+drA1\;`He3NsD V9pe,[\I …BDž85XPfWqR;p!ʍK [e6 ܓrHkAG/, *t\5lb ­BDž"jCgQْГ$S ­qen [Tn [kʶ=AuTvz51*[zҙ|jgnʵ3TA8z6fB15-A8%kg 5qvUfB"9&A"1w8pxۄB|<A3ӦʲLH$$H9pqeD*;pW+L':.8X=%)!,eX-k -(c܂{rH΁4ui3 ,q!Md)=!fBZSrP${LMO:+hf$RVYFB S;pW+:.İ ='xI 2t$ AH_AR:wtqX3G,[`Ӛv*ˍ_}IZ8p:*gb))J Q(Vjg F vX;pT7PU$M֬az=*Ojg)t\kgXXpvH %R)t\kg΄"cj 3[q!n2BDžmA!Mҁ{R V9pq!n԰j:.č65VA k(t\ sB).U[,7~jg. VYnI9pcU JrR;p+fjHt&AA* RvV(t\HKS踀{R V9pa_ٶ't3bJ Ŧq!jg. c@3TA8gVYn/У=)gHkAPf Ԍ:*Njg.lځe8AHFvʵ3gB۲lF_av w3fU \Уjjg.:.8TI5kv?JyƚTUQO3)t\kg.$R)t\kg.=+dvA,SV3Hrce:.SW;`HA-G/ /hk& Sӓ$] )\; P!UkgA8mgRpЖ*/H2BDžͰ CCO B1!F ۂ2-' xГPM(Gʃ3w,kFOBǺTUQ&EǔC"pB|P߀{Bk Ν3 kqebZ Ye V/IgNGZ[ Q,%EA86J .  3HBDžvV(t\@q!nx[vHrSt3fU \(t\5lA(6 qM …S\,VYn \ܓrHkAHFǥvVb̈́B15=LR;pTA03gT&r qjFڡq!Nͨ3vB" ,[v`*Njg. ,[WX37FZ[ -=zav`vVB܌CU4YjCgHeXe T;pklBDžvV"BDžvڳmOjgn2ju37HC*  m =zaxAX3aHt&jgNIgB|<Zq!qᴝ Hy &A-W$z(FJI^{rP${L 1f}<J2*(_*/Ab% Z#Ztdh{֔=!ZtdT,5,;p='ȃ.b%bEG&9n36z@W 2ehFl7%A ͈~PUu=F˸3xj} i=\ Y)&H2f=&$b=9FZ[ZWPsංL1{Bbj +IG"yұbEG&M^Eͤ4SCyv U$"e[XN(|lUXZ; ۪x:.hץu9pہWd)7YF.ӹsc- YUbZ8p:*g"cM֬ajg*|jCoKUOCIj}+BDžC c+B)t\/YUt;aUO EǔYcP${Lɚ5:6zɭPl KV>]]? ܠ23"cM֬A(=dW!BDžUOkgnXUV>*Njg. *9paU ܰZ/MB|ɪ§xUa/mj"͝3u3FZ[ g '\I g[[:.ė*|AG_Uvަ&rS? EǔYcP${Lɚ5"r Ŧq!dUv *9pkU |d)7YjHr5k\Pl KV>]AE* ܰ *|U \ kgHCoK9pJ*8#ARْjgA8mgR SBeKB֬Q߀{3s6;p`+j m QH/(t\ +h66% 3w@+ jQP&Eǔρ'!h!hw.B|<`z{hH blYb$$R A'7$ Ν3 kq(A,[`ӚvӑV9p$Tfg΄"cj 3-V;\A8: /3e"0*gIJj-vO;l-' GZ[ K=zav`veB܌CU`ht> [q!AxHq!A1 ŸL ( |&kg @XaU V(t\5lPl F pO%RqqwT&rG#rBDžQbS7j u":. o A5q#r#])MB\;Xp(Io"cM֬;d OFZ[ '[%*&uCU$=)g~:*g~6>.L%+[8TAYeK*UL'3?"i԰jq*F \I OIO-iReK*ULr"cM֬/E?( §ʖTx*[Rb\I OHTnt\jgޒʵ3_Hq#rᣭPْ_H2JBK9V9VlI o j`3?*[Rba$7I9ʖ4UEr%*&Ocr+[Ҿ%CUOOZ?peKjg>Uڡeʵ3 |LA(=*˵3oI/^B+gގBeKj|A ܓB; N %cAHkAd+T5ZNZpO -V1 n0UEAYeK"Tْ o\j_[ §q9ej-i_ْơH'] §XD%u3*[R RXP2Q OHTnt\jg> EdXAxK* |ԢAaV9D*7J/3?%kgPc]ڌq`ī52|BDžs ۑV9Q^XAxK* @*hgDs H?ʵ3grvFԉ0w  m =zaxP${LMjgNIgB|<A(= HX3!,Ǟs3M "cBb̈́t{s6`N +_='gRL(GʃtB&&XEcB|<AΝA8;gA8im3G qj)j3G qjFb 8TI V;\k3*/0n٦[̝3GB15+jJjg YԉX3W 5qSْšvEXe+UkgP${LMO:`Ig#SSْT3RF;#D;gŶDG/ /d^QW;pl'׺#[A(=&{E3gLo99pDe"gb)#M] A,Sjg֞m{?hg=!`qH?{B(s )\!Ι δ3n޼߿;1w8#AD5 - ^rWfUFiaqtUhgZaA8*&FT;pe}T;pe} vHV;LS Qb7mi5PU$] ‘PZsߖVQ3UE:.{R ݴUԌCUt3GBIj}[ZE8TII9p6*gPNUԌCUt3J~*cCŶ-fd/|j'L*jơHCe"g.VQfUj*jơHjgH#[0K"p=)g2ԖVQ3UE?>}i5PU$] A8+fvdq*vV(IoK"p=)gFZ[  Ӿq*qܓr႖ V;D_l*jơH'§v´/fA0T&r႖ V;VQ3UER;pF*  Oi*jơH:\EpOL%1UԌCUOOi_ZE8TI9pDe"gJ"jiA8*Y-fA8JRk*jơH:\EpOV9`l§v´/fu\Ae} /mi5PU$}S;aڗVQ3UEu *9pAV;VQ3UER;pF*  Oi*jơH:\EpOL%1UԌCUOOi_ZE8TI9pDe"gJ"jiA8*Y-fA8JRk*jơH:\EpOV9`l§v´/fu\Ae}/mi5PU$}S;aڗVQ3UEu *9pAV;VQ3UER;pF* 5D;gios3@!>RP\q MPJzM;gA8im3GLSW;pJ*8OgB|<aMMnJF;CHgpO~*0w8p:*gt.U[ZE8TIW;pd+ܷUԌCUt3g#rZ 73~V`M …ݴ i?фFZ[ ˨7k+g^OI&lI3O;+V3XAxI*hgDs I ϧ4N_TNi?UVA0㴟Vim3/c))J Ě MeKAx)S I ӿLBOeQ;pai?ݙr …d #re,%EAxX3aP${LUkg^ ET;cRvbOi #reԉPZEMVҵ3ODV:J~*_wr~RVHr OVHMEojg5Q'9/~'zAxI*hgDs I패!aA@e"gn2NMQ҆SFVy@M _!F'g \u"̝3gr )\;}u:\EpOV9`l§v´/fu\Ae} /mi5PU$}S;aڗVQ3UEu *9pAV;VQ3UER;pF*  Oi*jơH:\EpOvKHELP.PAS] o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\@-qv'crD^&L;2ZI2w!<(G<_یZDNf5aډadVL{J@LHˋwI6C!YD)m5PBq (!x~Zl2-rM =u SqM //O7<'ALa:@]CxpAO+kP8Xyp2%SN #bBܣVb %Ua˔La˔La՗SAx MsM&f{hsM۳w^txp2%SXTuwJ,(w/\m;J,Vby\]]5!FLV}9U<;2LdV \2{5I5zUa˔La՗SAߩ 1PTm;jzCG;()ª/~z=jbZ+Qdgj tSӋXd NJ$LE{q_m0ժt0eJ˩/45\izsMo-jC8b)+Ȟ xE3Aaoa/q]5!FLV}yXu׸"Bao#Ȅu̼0eJêW/WHqR Q+Q1ɢ;()ª/N_}G\jG0D0j%j &ɋXd <:}ɒ`Q&I]5!FL4!FLV}])Q^lh2:`Re$/jCx@mߎwĉڝ2VL Z@Lcw68Qt&Q ʄ̊i V !Ղ%@wi2#T]fP+Q1I(54/ѦZb4' IMB1b5_^^nyN)2-j%C0Cx?5(o0ڔh2LS"e`z;g%![0HCx#2V+%۷!|n56iewE Gt((JV'\@G+wOzZY‡ CKnbK\@GiCxL)wOzZY‡ Ux~%l.~ib) Cl 6CKnbKUW2mYw{ zZYIe;ĽwO A+ 6і皶g%\@;';Am-5mJ@o L!|2%S?GMkZtxL۠1L8V!<2%Sg皐q{hYm-5mJUw_ɴw_k zZYIe;ĽwO iAO+kC8LP:}~;hA幦Y 60q[+<7!<՟t=hlP+b)N7j%mfy[+TN[=~75b)̘0t%S *8R;ǔ2y𤧕5!|,36`;Xd~E,33L XzU2mW2mJCp=ᏣXdSbJV4LdH;GmC8i#& ;dLʻ?o{G^\u7xg^.߽ꖛ67޽Z.}ꖛ͍wGw͍w]>z\>-ƻW.=[]vWo|iAiae SݬTM~r -p!cwO A+ 6і皶g%\@;';Am-5mJ@o L!|2%S?GMkZtxL۠1L8V!<2%Sg皐q{hYm-5mJUw_ɴw_k zZYIe;ĽwO iAO+kC8LP:}~;hA幦Y 60q[+<7!<՟t=hlP+b)N7j%mfy[+TN[=~75b)̘0t%S *8R;ǔ2y𤧕5!|,36`;Xd~E,33L XzUvKINIT.PASL  !"o#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKz)xYY|Ư#+;߾Q|degwܑo__m(> Ʒ/6xY|Y#(U;LVVΜdeչ$ʪs deEGLVVz0%r9=:HJL܃5 I54*J^j,T= CVv6}}\CU-,X%'zl΄/S<5T&!ry\CU-, CVv6=_m(>jawZ |jaDU-҃dU-_bYVvzRfN/U-, CVv6=_m(>jI7ҪwܪZҭG)*U-փ#W[$jI>x4U[LVV[L%zHU[x2%rAR_{\s ]{\3YB>x\Cש B9IMU:qǟ@ln|`Gl4 iUKVp-g& MZҍ]d(eu6bx<%r=;!bI4gJ#quHF, )x;<biQ0=g{+vdeg_^-CdB%\C&aG4Ψή#Ǝl|jG;k(a!dk]d 5DŽ&ENѐJDS" ԒnQ,^ΔF6xK6f=뿿;l.m"tA<b)a󧟞߿;lrlg1R LR"2>٩aG0%rh[ Xgd74zJL܃0ӒhP\KΔF ;{|(u?.;-X2Yو!ג(. FLGxF33T6S() 5;6xߺH4~kIQQPjw( 5+m(lP6x YbaNK!iCXcG:'Hp|(u?.;-eE2oM96H$%<x;-!CXcG:'p4Xܔ%)~~GL* :!,IEF .6I7ha#<x昨<(a}qFؑ_ާ6Q, !>(!)ȵ$84]d=)XaŲ F Q|<\Ch;QRCJkgQ,deuFS5DVvFvdeg >x:iP8kIq FhD- zR3<imQߐz3b!+[3X ~cm?6x Ybn< '+QpU;e"C:AQFgl'm-FZmgW`YTd%9E-FzmGSݬTM~r -p!cو!ג(. FLGxF33T6S() 5;6xߺH4~kIQQPjw( 5+m(lP6x YbaNK!iCXcG:'Hp|(u?.;-eE2oM96H$%<x;-!CXcG:'p4Xܔ%)~~GL* :!,IEF .6I7ha#<x昨<(a}qFؑ_ާ6Q, !>(!)ȵ$84]d=)XaŲ F Q|<\Ch;QRCJkgQ,deuFS5DVvFvdeg >x:iP8kIq FhD- zR3<?@ABCDEFGHIJKLMNOPQRSTS%y+7_5ȦMA"-C7Д""H|j,.yW?|0U #.yWw M{qp 1_?ΠpQtC5_I82G/ ̑~ pB Pgܬ-.yd& DjR<#H WKيaf$G$r<8n$lDv ̑(=̑K=tcgNlYE7TlgK ]ȟDRq3?]hGn2p&K4H:@ 6%mȯ GRG B ';A"D˦o|WnJDbG=49.%\HeӎRq•hRd&H 0*A"1t#۷?<;Bӻ?&NY9HE?²B Z)䑿rMUq3DRq3Dgۂ DMnJnsƽyG7J Hd,ue) ]wg+}$r<8 xnJ:@;t)yom ~ͱU*DbGM4y;W{Sw3XV Db_$2:3k)M#CmLm_Rq•hȿs:gdz>HeX*ut݄~8 .yI:W{9RG|H4Ѳi/k)p#8\g-gDHm"8 s$DRay&|oo: ,.Wbp4^`%|/Zh ?(iF"aĬAbd<`hQ]#N DaDHm\boGH8+h$R8Kh⹹\jYMwC|ȿrMRǠ8 HeG~oY٘s1cpc'A"ͥG7\f!>`DK<V/s&RǠ8ݠD|~KN#ߗ8VWpAu߱KvSPjsX]_HM+7?oi.u 8VWևnJsBkj1ZjsX]??%Օ~Ǿ.u /%זRǠku߱KvC7%18;Kp:nJ3j;%~V#=vp}́cu7xoθחag7%^\HE?ZQs$gf!.y{ :_"He`?;[1BkH˰bƝ0\K0yV Dj}5\K=cag+Q"Y}EH˰bͱ:+*훽G=G GC<3p:%v$nYmEK>y+7Q`G=%Q_=|Ѻ_4(ׇG~XY0t'TlgKXce(ۯ/ݔ|=FR u cE7B#qph(J ]#?_`C<(*R7s(q;Z<򫖑}9QM#?S k,GƟ~~Q,de|@wZRRq•hȿs:gdz>HeX*ut݄~8 .yI:W{9RG|H4Ѳi/k)p#8\g-gDHm"8 s$DRay&|oo: ,.Wbp4^`%|/Zh ?(iF"aĬAbd<`hQ]#N DaDHm\boGH8+h$R8Kh⹹\jYMwC|ȿrMRǠ8 HeG~oY٘s1cpc'A"ͥG7\f!>`DK<V/s&RǠ8ݠD|~KN#ߗ8VWpAu߱KvSPjsX]_HM+7?oi.u 8VWևnJsBkj1ZjsX]??%Օ~Ǿ.u /%זRǠku߱KvZKREC.PAST o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSC# Li5FMfƮ9;lEhZՆ'jdCz>tXMoj*L=Y5FNz #igVƆ&0-dw!=? F$0!c;aF.Na;2){ң3+c; 4Lx# &t!=6;I;23pG2B3C!QMɐ)LMX!=dNs1~Rތxa쑋{ ǩ~ݮn!D5̬YCJˁ{x )xفi /vHT L kQ×Wj _CzdNd0CHj _pl]s w@"4F0jPU*B }>J%tw!=ҝnlN"Im%݂i[j QmN"ImKņc)0zt'RhDo L w!e+Bjq;ǡ÷a!&,P|veRo-C ae=L8wH8(;p$dJKlfd+Bj@(;p$> 0ji5ܐ @P"Tb>H7aAp]1GB9L(kB3G0HTSa2-Gc{㑖&xBa z,(#K0tk+&4xAd!==V`$D~JXdz%yc;HZj#fD5pD:{twHRN0VCkTQVCV8PX8CzJaCz0yHK0t06TbtwHwIlaf5ƵP ]ҝYc;|1t *]ҝDږ턝f1thv>pf,* C4G R&twHwYb;aF f"C3ʤ b|q!n% FJTG`$D5УXQ Fl~n!ns{p1tP|JD8(;p$dJ!Ơbb0bH;#-MeRBJT֏:̱ GBVK&h0)+;FJT HC0]1U*1;#-M@:ȁPVf6]ҍYc;|CY(,G b@aሮS: 8T ]&xtc$mVN06Tb|D֏:4 J%F{t# IFJT1tiB ]ҍ50#ў#A A ]=iɭ=`vA1 R8Y?zJ%ۙc;!T⹝)0>aahf(ʞ !f0tcq%,!==ex}؏!_aΖUs?zt+)k`l'< Y ٚH*]͑&xi[jN06TRoF u`W ٚMX!hvWh)`GL둖&x5L9=G 5q̱\GLOLJTvDM>zh]?b05,# CJa>t0a8ZYEϭD5|)`萭 $p'twH_0 Og|a`VZ{3yj ϭD~aΌ#![XB{tCaCzJaCr0XI*QWh*]#-M^"I=$y;6b0G6:{HTC{t/հ Q׳aHRu$u^0{LC0ᷟ}DuG :̱\ 60M0HyB;#-MR G^\aMB ~HڬR_(,#iJ%z3MiD: [H$D~4zt pY>PX8FfJܿG !H$mN`[ia)eD:{twHFfJ܆u5HT*Û~Q0U*1;{љ`$mVį?Ayts36dJ%FZ۬RGn~ƆR[dv¤mVwH78cCV-_2a;̊Y!ݜ Y|ɄH:Y!ݜ Y|Ʉ턠*u?gl*K&l'6;_ؐU*q˗LN0ɞf:zts36dJ%TjUؐU*q˗LN0Y!a&dJ%PC;{ ӈLzYxHC9 Y##٭wHϲJ%_2B$u^zn4;i06Tۇۏҋ4IU*q06TC0!7; Ij[j R[d—WXC zpMVmN`[ia㺀#n4;K2<>я!Z4J%FηYwH7;;G s ӈY*]wC#iJ%F{wwHO)LwH;C#iJ%F{ ]FXxLϰQ5 Z<PX8FfJܿG !H$mN`[ia)eD:{twHFfJ܆u5HT*Û~Q0U*1;{љ`$mVį?Ayts36dJ%FZ۬RGn~ƆR[dv¤mVwH78cCV-_2a;̊Y!ݜ Y|ɄH:Y!ݜ Y|Ʉ턠*u?gl*K&l'6;_ؐU*q˗LN0ɞf:zts36dJ%TjUؐU*q˗LN0Y!a&dJ%PC;{ ӈLzYxvKREC1.PASi o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh??Zm5P|̣'LFl*OygٱQ*R*!3ћ2gŎr<ᰤћ2=O0'C IV#B <@TQH~d&8gqvja$xF <@DTLD*T@fZp֛H ŧSd=ᆚ0;VT XpV\(NeLCqTZMoad&~?$)jtjtù[F9o5©=V0J7V[p=q1jSB'V#4;ŎXp(.v6uj]%}!Ro5Lb&.FYT ܜx#lSgleX+#6ujoF@odce1JbL\RF-H:}O(.vVmqj<4V#`In?߹'7Ge86V#RŮU5<#͎mo6V#|V#C&.FYbGiZ3TB E(#V#\o|6ŧӳOT"i5ىN-QsɨTFAqTxF̴lpSR!3Q|OLtO|n5jw[p*~.FiS:Xm5(Nk2oF8j;NFivlQ\(mTƦQZbJbTV#艋QV#\;JVkxƶQZ5صFeMݶ0H:Le5‹QV#ܭTukF[ Z3tUnFTj[*FF*.vN.cFqvrqXpUr\Xp%~j+Ck܍=d()yj #;J;}Of'5?sJ%BA0娱4!ŎXpR嶸Q.I~syiXp6GϜRIPPrk;ѶUnFTtTb)yATqBivlgLmFʍVŧ;=Jƫ1 [8jLbF8e5™Q%U0ۗgglQ%Xc62$TV#<e5JXaTI/-.v{FT(;z}tq/GG8FxivmvZ3o7glQ%[$lFx¡j7ff'5<#͎Nn[&ʰ$7-.v{FTo<>~6V#~mF8V#qlbOLMybGgTINe|kglfS(CjL-d(gI>odff'5<#͎Nn3ŎrϨ},JivmvZ36 ;=JoO8TZ3ag1ىmxƶQURXpF>URj J}X*7d6*77ũ;OV[ " ߛV#\o|6ŧQGqxk5ÉQV#QGqxk5ÉQV#?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklpr '[h"wV)TX002CqVdDEيE y\>v(>Xʍ'!T{BG&#(VP`H We2mO'd !ָ$Xe`~ߘhc_whbDUXe0ǻ=.{']sĥ2= s`-p_/apD(VGo`AOsA=!́4.#}}]T51+FׇfP.a~ߘh`ZE ZNEي8dvcA4L;-pvK:%C([`e.#X-pXÓMEي8f Eي8f}xܓ''[PaV ܩ([̎{,f2;GO6e+w5qǓ 8hX1W~dSQ"`@4{2Zne+eCclɦlE|掴ݶ=* ˆZWe+C(?b* tu'drk؞lB`\1:dq+FOT;8hX([̎{<ܓb=VcSQ9feCclɦlE|݃Ÿ4Kt LX6jSZ^ܑ}9j l*V_>h&ܑ}9j l|&(Vi&O6dݶ#x([ b[Mhv tL*VZd*,j5wj{qW\r0Uq gth A ܋9<~|xr>LJ?`Dh0<}p LX-ps  ZV3,%_ƎZΞ,Żqke+*(1PS<{2ZN'VulEXwll*V4{l(V4{CˇV)TX6oŸ03yLz,#p;CX-p7FU([aDh}5d|8{2Z~([Pa *#Fl:x{2uV y|*VX0.+z¾)1cOX-p?vãxqshidSQ"Z-p?v||aD]hL0]j~u'drqUad-pg;wRJ²VsGsijvDh.pxt//^8i<([P-8\C*e+duQ"N_k9l*V4kO6e+dj;ɭslB ;dq&l(V]T.Z-pV`)7Бɩ([ZW.<#PbDdP<)c:bjQqGk>tP{ec-pA{wwfڗd{ʷZݛh 1A ܹ)Y1EيKFQ"Ҥb\є=!Ǯ= ]":`cLSd&ENvãxq}zhɥLߔ1qp̎([kj]8^\_Z-pr#x芲Ղj:xƲ0q?e+45uM~@Zn&E6Ӿ$+eCQ"NSS~b\W!7w:hkG}IW~\<} "#:h{1.-p%^y,lȴ/P&zh1ǂgcuG -0p{LLFzdrv/8h{q#x+XG}IW~ݦ#\42KCLnV ܹ64ldv܏Eي8MM]SG&'+?ǢlE߷1`Z-p㊎LNEيE˸u-@Rn!T|Ăvh:xƲ0q?e+45uM~@Z0.-pɆ0 wZ-p%e+,q&jTh2=²9h<.-p`ڗT~e|%e64 Zk{\ 8cydڗT~0@Ww.bd9Ʋalh drSrɆe2Ƣ|cctWylZ>]2(8{2Z>e+45uM X6-pcQ"NSS~0 xzvgh}5F!qlh 򑏉]irNEܓ([kmh ?i|q&߆ճ;Cdr?ɭb\aUGX-pg2ŸbjSQ":h2o/E P|ODn1č7?ch7.+n5Zλq~nh16 &%rʬX-p^jG&Wj"chr u4[+hb2r]xHר]9BװaW&wX-ZU^ ܙ aڑoh7.+hbcs4l/ ZN? q&be_|hw>Lÿ q&be_j;-Vuuw.V4{,ZX6i&9e+V S!ZNX6? SG&lEj;ٞlZ-pp1)x DsGZĪ0GCɆ^|B `\qIf>W3#8LG:@Kv; cp}XЫ[-pB&WXA y8<:O -;bwcRDsD]b\QGE˸u-@Rn<#[+:2 u iЇZݳtLNEيph'OJEيwhhwWy-pgG,iGw䔃!,BIV{KqL)+V-TF4PǙ+-pk;^dCc aڑo l|Ĵ/)+VXбfwB8L!̤LE y]4ZNEي8MM]OY²O64lhTǙlQtǙ`c:TB4LO05uMi214\Ǚk'xa,Vĩ op<TǙN&EC1qaxk]|O'NOF iLרLSSq1ZqaX6\ZOM]Oc05uM>f+\Z4j/X6qk8S 0uh< uh.Z-pϙ1<2e2^WtcAw=X-pLnᾌ+ɨ<{]u!#Ӿ P&z|8 8=.-pϋq&be([k)+V­&0%++XG}Z-pm|1eO64q8M&k@sGZDh=5ȴ/x!e W`ڗV s+lh c`{ a\V ܇XcL]Au6ܓc }ܓ|]4Zྑ)ԩ3aV ܷL31Eي8MM]OYq&b5-.th}Wd LFQZɭb\qǙZNH&P:΄1uh<`j|e2(ch3 hvhL)CX6owcLCNd-p';'u)`ˆZZdrE ⃥ܽxBMБɈ&21ADhq2ˆ;# wZ-pXc,G>&>JwT|LXǙ cܓws L 9㊙Ёp L.#xvSdtX-pЫ5. ^nS4ZN4wNn5)=òW7=.e +^wƢlE\?3rShx W\<\?3)i-p_p L  irO'+j;MMs*VĭBU  ;j1P] ;L*1gRFeNq:2eCQ"RGqV tdr*Vĭ8d)ޥT[-pkd'f]4ZnGӡwG hlGCQ"> 2'XSLX aU*VM`)xpOF ܍V)ȣU jG,qV ܩ1g([P!x)xFa?SlBh 8SIeZN4w5X6ow&[+h"chW|OzR|qEG&3'ch;OF ܩ(['l(V4{\Ÿ#FQ":h;e+45uM>e ˆßV ijSQ"nlj;y*X tdr*Vĭ8=*)[ZG\wj V)Tj Xʍ'tuŸ#=3!+VX-Zw;OV Gdr4ǏV S!Z(['l(V4{\';TǙRVZ-pkdv܏Eي8MM]OY Eي+DX-p7w{jSQ"nfIJNBT[-p/lOJVX6? ۍ8C* CM3 {qhݐɭSc8ΨL)Cj sthݾi2f<&p4;\nV8j![-p'2wwCb\ёX-Zehr Z-ZU^ V<^V{#A 9;VLRK)رb†qL'4.-pkjGdJwDzV3-pBsGZnncpjlEɧXaـ_p+XSӀ+^wF{ Z\?3+XǢ+^wF29:Рn5)^y\V<`*PE ܉Lw#-plEɧXapC<5qΩ([Zqb\ёI E˸u-@Rn<#QUE ܽvh;e+45uM>e ˆïV yjSQ"n;29e+V =2Ѳw8T[-pLNEيwLnhѢl8zh&9e+V ܹ#SQ"n#[-Z#SQ"n#[-ZZS眊qܑɩ([Zɭ-pb\QGE˸u-@Rn<#[+:2 u iЇZݳtLNEيph'OJEيwhhwMd,袉jݑɩ3T&]O*oTǙL(XQ[-p;29MTIU2ŸªZ1g)xF䔃V r0hhۻq|xj}#x/31ppyhݐZ掴LF ]8>sthݾi?@ABCDEFGHIJKLMNOPQRSTU۷gΆ:YP.yg I{epƙy g& I{Z<6am0 335IAXvI%5_+/N7%V~XOpu`RI ozzlhkg/_+/N7%Vg[vUV[#83o?ng:2dB+i?8̼ug&  ^LM4(Am0 +VРtƙTِY'Kj-8-JګoCFo'IOHgP9]q>3.Xyq/:aUac`OEhc8՗Xqa*II uvXfpU6w o}v+/N%Vg> *l̂,->\;x삕3NpeY$X `{߮A3[M6>,3[MC}'_7bcC%U"UfA*Wepxk &aKBr{}<,3[M(  B' " om6 upgvq!N~S2>Tb8 qk@F)Y|I}C*'}1б d$O3ϩP #ч]r^dLD23= 8,2B''uR #LAhw8YIVРs$$XA_M~X7fa]Avq㓷 ^Eh!;TA,;I!4zqK̲$Xpp";θA$l:>UfaXA1)ޮ}~U/#2$R&eprk|om ^,;zq6 V^Kx8m?2Rq6ȣȾ'bcC-)AO FZ*Xyq/̀=IsGo66õ35}2P+Eh!9h ~Lt6$CF*5}2ળII6P^;xg/iu e~}p?@F*RGZB#-,}}ďk:hEh:c]C_ߟ6e=$v (BE_a,XNLlg߱dqGoš .m ;}]TgQuGog; A:% }3Xˣ o92ˎo`u؉ >:[]EhGaau :8qz{>)FSkE Ⱦp c@w8%P.bn]g}73S e5Iq5z` > }3Xˣ&]̲멓3l(ԺˣEhGaauAZgA|V 'u״pKwy2RAv}Rg+Ժˣ3KwyvA&ᜃc֖oupBUfaXA1)ޮ}~U/#2$R&eprk|om ^,;zq6 V^Kx8m?2Rq6ȣȾ'bcC-)AO FZ*Xyq/̀=IsGo66õ35}2P+Eh!9h ~Lt6$CF*5}2ળII6P^;xg/iu e~}p?@F*RGZB#-,}}ďk:hEh:c]C_ߟ6e=$v (BE_a,XNLlg߱dqGoš .m ;}]TgQuGog; A:% }3Xˣ o92ˎo`u؉ >:[]EhGaau :8qz{>)FSkE Ⱦp c@w8%P.bn]g}73S e5IThis is a test version of Turbo Pascal Kermit, contributed by Jeff Duncan. This version (1.1) runs only on the DEC-VT180 under CP/M-80. It is hoped that the program will be adapted to run on other systems that have Turbo Pascal. Jeff may be reached as LSM.DUNCAN@DEC-MARLBORO (Intenet) or at 617-839-5637 (evenings). The Turbo Pascal Kermit files have been grouped together for distribution purposes into a file called TURBO.PAS. This file contains 11 files, each preceded by a comment showing its real name, e.g. (* <<>> *) The internal files are separated by formfeeds (Control-L): K.PAS KINIT.PAS KDIR.PAS KOPEN.PAS KDISPLAY.PAS KHELP.PAS KREC.PAS KTERM.PAS KSEND.PAS KREC1.PAS KCMD.PAS  ͫCopyright (C) 1985 BORLAND IncB Osborne 1ixenle CP/MP)(= *ERT()~7#~= oͦkԄ!!"~#(}:$= +*!5!*!!:(2!5:(>2!!!:O::O:!*! !45(! +/ 0y0( d!k5!{5__o&  :(͠|(  *"x2y( >28!"9!! og2"">~22 9/4*9 Co&ͦͣ} [ (!e{ͦA8Q0G: x@!\w# (͂ ?(*( .( w^. ^!h6# (?( *( ͂( w#>?> w#ͦ 8 !ɿ .,;:=?*[]<>{}a{ |ʹ}ͽƐ'@'7||}>2ͯ*Bڨ  "og"2>2! ""*B"[Ru*"^#V#^#V#N#FO/o&9O/o&9!9(> (G!9 w#Eͺw}8' RB0 >' RqRR!+ Ͱ R!+ Ͱ r!+ Ͱ r!+ Ͱ r!# Ͱ r!+ Ͱ T]KB!z> S>))0 = | |̀̀DMgo>jB0 7?= H͒<z5a)a<z {0Gɯgo||~}||/g}/o#}o&K[xAJSJDM!b"!6J"DM'd } ) W _}8(8J`9{T]=o`9y ) >' ́ ͬ͗ }>' xˆ }} ˸T}ٕ(0D=z ,= ( ͒ 0%{ , 7 ?(8ͬ x ͆ - r 8˸x ͏  ,-xG}r }مM 9r .>#n0͒ { = - nx ͇ ,-(-˸G,-r }ٕ?M 9.> 8ͬ ?= u+-(>͆ 0ͬ ͆ 8 ?x ͇ , 78ƀ8ƀ8ox٨!دoGOW_gɷɷ|لg{ً_zيWyىOxوG|ٔg{ٛ_zٚWyٙOx٘Gxٸyٹzٺ{ٻ|ټx٨ xx( ?}ٽ }ցr <(r 7{ = |٤g{٣_z٢Wy١Ox٠G{ ͬ ́ }x>' ͬ}ƀ/ƀo -́ }0͎-́ ͎,}l˸ 8 4 ͗ x( - 8́ - 8,́ }l8;*!͗ ! >4ͬ͗ ͗ ͬ--- ́ ,,,-xGg?+2n*8t z~,->' x' ͘}. ͆́ , ! >4,͢- o&0%,͗ }gr }؉}颋.:}8c~I$I~L*͢ٷx˸ }0G,<},-(-́ !>I0 ͗͘ o8 ͆ >' m.`1pF,t6|!wS<.z}[|%FXc~ur1}͆ٯx(<˸ 8 !~J 0.O!>s 8 =  n s͗ ͆ .n 0 ͎-́ OT0 j oD,:j !I}袋.}8c~I$I~L! >ͬ͗ I× nn ͗ = ͆ nf^VNF!DLT\I!!53!r1!͒!> x #-= o˸x͆(- }(x>8(z ,z `iÃ!>' |r |̀>)=|(DMbo˸88x(0 8> ̀x(>-{(ay( z(>. ( {>E>+|(|Dg>-|/ 0:p# ~# +>0w#,-  60#}˸}րogM| .(z = ~> x0w#xG%͇ %͇ ZJDM%͇ = _~65+~hìx-Sx9?+{Η@}|z z gZJDM0{ ,7}o˸? #yO!@9i&?  #?w#?/w#?w#!9! E9!!9~(+Fͺ!"9!(#>2*"| >"2:( Ͷ *w*6 !\$![ (ͦ( #:~CONTRMKBDLSTCAUXUSR>2i:*ˮ~0:*:(@q##pZ* :(  ~* < >26"!"""~>2""v>2>"!"ˮ(!~8>~O6~*"w(6(2(-()(6 (8 0 :(* y(~#+ (( 66 #6 #"*: y~o p .##~ͺ(.6w4._~ =*##55= *[R8*~#"= ͣ}== ͯ}͵}*#w+#~+>*~('k!0(ˮ]k!8ˮ!]~-#8~>27kˮw>O$6̃s #r$ͣ6̏ k ( (ˮ qk(ˮ ( k ˮ*O:~ ##~._q4((=ʦ==ʩ=ʬò*:4^q*##~6ͺ>2}*|(̓|( ̓6-#[RM8( G> A~#*'C! !TRUEFALSE!9N#Y~#( G~#> >    "~(kѻ(( !0 (ˮ!!>2Sz:0:*6##ww#w$w#w:  ##N#F*B>2w#w#[s#r> "~ͮ*-w#ww##> ͮÁ""~>2:ZR0 *4#4>2:ZR> *4 #4(> >22*f(/˦:G(##~++ :O x yC!ͺ Q*:G(##~._.͚f<\=<͚*##w ͮ +4 #4x >>2:G("ͮ"*nˮ*0 SZѷR8@* N#F#s#r, 0})jS\*##w+ N#FB ͮr+s>2!T]>)j)0 0= ]R!#]*^#V#N#F#^#V>2Ͱ:0:*6 #-Nw#Fwq#p#6#w#w#w"~Á>">!DM!":*B:!>(>2>">!"2"~ʰ*w#wx(9* :O *-4 #4!*4 #4 *-N#Fq#pV+^Bq#pSZѷR&* s#r$ s#rL <?*L!\  <( !\$>2>2L:>!(* \$\<(!3: [1ð\!(7"~> 2"S"Ns#FrB(Z#\: \<(?*"}K\! !*}#"}! x \* *>) 2""{_!"*nf}(HR0nf" ^VMDnfutqp*s#r*s#r"* uKB!0>' ~#fo{_"*R0RnfR0KqputsrNF( ^VNF^V*SutKqp R*R(~w~wnf ut"6#K*K*!""*NFy(* "*B0Cnf* [R*"*RS[s#r^#V""6#>O"w2x2*"!F"" &y*"*>2"*"!F"""!\*: Nr!~6go(\R*s#r_2x( s x(T]DMx(R0 U(͝O/o&9q# (!>F0#( ~ ( #]( ~ ( (#}(  i&T-a%â}ͦo*!~6o&|:2 2}:__zѯ2*|KB " z ^C User break+=  I/O Run-time error {ʹ, PC=*ͯNot enough memory Program aborted :ʎ'1!d!f>xeASCIIBinaryNoneMarkSpaceEvenOdd send initsend file header send filesend eof send break receive initreceive header receive filesend byeget file"MP!O!*fz""!O:! e.=P!O*#á"!O:P!!:}2M*M&!@|g}o}2N*N&"B*B! }2D*D&}27*7&! R"8*8"-*-!n&! Er#*-!!H#"#*#*#:ͣn&! Eʱ#*#*#:ͣ!{#""" ! !! :ͣfz3$"! *n&́!a!z͛OE*$! *! *n&!|g}os*##!.e.! :Ͳ!͒Eʬ$! :!!.e.! :Ͳ!Rk*! :!.e.! :Ͳ!!k*$! :*M*!:e.*:Ͳ!͒E_%*:!!:e.*:Ͳ!Rk* *!!:e.*:Ͳ*:M͍E\%!*e.*!*e.*n%!!e.* !*e.*:Ͳ!͒E%!*e.*:Ͳ"**!*:ͣ!E%!?e.** ì%n%!*e.*:Ͳ!͒EH&!*e.*:Ͳ"**!*:ͣ!EE&!?e.** &%*:ͣ!Ey&*:! e.=*H&*:ͣ!Eʪ&*:! e.=*y&!!:!ݩ!ͩ!ɩͲ#!ݩ:͖ ́!A!P͛OE'!!+!ݩ:͖ !@Rs'!!+!s!!fz\'"ߩ!!*ߩ+!ͩ*ߩn&s*ߩ#*'!!fzʙ'"ߩ!! *ߩ+!ɩ*ߩn&s*ߩ#g'! !$fz'"ߩ!*ߩ+!s*ߩ#ä'"ǩ!!o&*ǩs#r"!!o&*s#r!>:M͍E'(M*.*!>!>:ͫ&!!!'!"*!͒E`)͛ ͛ͺDirectory listing for !>:!ͪ ͛ *! !*! ! fz("͛!*+n&" *#(͛!." *! ! *! ! fzD)"͛!*+n&" *#)͛ͺ :  *!"t)͛ͺno file *!͒Eʅ*!'*!͒Eʂ**!"*! !*! ! fz)"͛!*+n&" *#)͛!." *! ! *! ! fzQ*"͛!*+n&" *#)**!E!Eu*͛ Â*͛ͺ :  t)͛ ñ*"w!!o&*ws#r!>:M͍E*͛ ͛ͺEnter file(s) to erase:  !>͎ !>:ͫ&!͒**́!!͛OEE+͛ͺFile(s) deleted. d+͛ͺFile(s) not found. ͛ +"!!!:p!p!͒E+!o !]"!*s!}2!"+!*s!^}2n*n&Rž,!!^:p!p!E[,!}2߬!}2!]"!>!͛*!!& !"Û,!}2߬!!͛ͺFile !^:!ͪͺ does not exist. å.R¥.!^:!߬q+*߬&}oEʥ.!^:!;!;:!P!+!'Ͳ#!+:!.e.=!':=!;!P:!!e.͠E=-!P:!:e.=!;:=!;! e.!;:Ͳ"R*R!͒E-!;*R!!&e.!;*R ! e.!;:Ͳ!͒Eʼ-!;! e.!;:Ͳ!Á-!;:!߬q+*߬&*R!}oE,!! *߬&Em.!;:!^:͠EJ.͛ͺ Filename !^:!ͪͺ changed to: !;:!ͪ j.͛ͺ Filename: !;:!ͪ å.͛ͺ Filename !^:!ͪͺ could not be opened. !!͛ͺTurbo Pascal Kermit Version ! !!y !!͛ͺBytes transferred:  !(!͛ͺBytes to transfer:  !!͛ͺ Packets Sent: !!͛ͺRetries: !!͛ͺTurbo Pascal Kermit Version ! !!y !!͛ͺBytes transferred:  !!͛ͺPackets Received: !!͛ͺRetries: ""!!*͛!& !!*͛!& !!͛*!!& ͛ͺ Current state of parameters are: ͛ ͛!͂"!ͪͺFiletype (Filetype): ! *&))):!ͪ!." ͛!͂"!ͪͺParity (PArity): !!*&))):!ͪ!." ͛!͂"!ͪͺ:Escape sequence (constant): ^\ - C (Control-backslash 'C'. ͛!͂"!ͪͺPacket size (Size): *!&!." ͛!͂"!ͪͺ!Number of pad characters (Npad): *!&!." ͛!͂"!ͪͺ"Pad character to send (PAD): char(*&"ͺ). ͛!͂"!ͪͺCheck type (Checktype): *&"!." ͛!͂"!ͪͺDebug mode (Debug): !+:!ͪ!." ͛!͂"!ͪͺNumber of retries: *(!&!." ͛!͂"!ͪͺPrinter mode (PRinter): !7:!ͪ!." ͛ ͛ͺ4To change a parameter, type: SET  ͛ͺIValid parameters are shown in parentheses. Abbreviations are capitalized. >͛ͺ!The following are valid commands: ͛!͂"!ͪͺ"Bye - Logout host, return to CP/M. ͛!͂"!ͪͺ7Connect - Connect to remote host and act as a terminal. ͛!͂"!ͪͺExit - Return to CP/M. ͛!͂"!ͪͺ!Finish - Shut down remote server. ͛!͂"!ͪͺ.Get - Get the specified file(s) from the host. ͛!͂"!ͪͺ!Help - Display this help message. ͛!͂"!ͪͺQuit - Return to CP/M. ͛!͂"!ͪͺ*Receive - Receive a file from remote host. ͛!͂"!ͪͺ"SENd - Send a file to remote host. ͛!͂"!ͪͺ!SET - Set local Kermit parameter. ͛!͂"!ͪͺ#SHow - Show the current parameters. ͛!͂"!ͪͺCtrl-D to abort transfer. ͛ ͛!͂"!ͪͺ5Allowable abbreviations are shown in capital letters. !>!n&DRʮ7dR28!$:MON͍!$:Mon͍}oE7!}2/Mon!+8!}2/Moff!+͛ͺDebug mode is now !+:!ͪ è;FRF8fR8!$!n&ARe8aRo8!}2ì8BRʃ8bR8!}2ì8͛ͺUnknown file type. ͛ͺFiletype set to: ! *&))):!ͪ è;PR8pR:!>!n&AR9aR1:!$!n&NR=9nRG9!}29MR[9mRe9!}29SRy9sRƒ9!}29ERʗ9eR¡9!}29ORʵ9oR¿9!}29͛ͺ Parity type !$:!ͪͺ not allowed. ͛ͺParity set to: !!*&))):!ͪ :RRE:rR:!$:MON͍!$:Mon͍}oEʅ:!}2;Mon!7Û:!}2;Moff!7͛ͺPrint logging is now !7:!ͪ è;RR:rRt;!$:!ר!ը*ը!͒E9;͛ͺ Retry count !$:!ͪͺ not allowed. q;*ר"(͛ͺRetry count set to **&!͋!." è;͛ͺ Parameter !>:!ͪͺ not allowed. "Ө!"ɨ!*Өs#r!}2ݬ!}2*! Mh!|g}o"Ũ*Ũ!͒E!! ͛ͺrpack:  !!:ͣfzʰ>"!*n&}2*&!Ea>͛!'" *&!|g}o}2*&! Eʙ>͛!^*&"e.͢ =!ͪ ç>*&͛" *#>*ݬ&}oE@**R"**!|g}o!@!?|g}o#}2*/&Ed?!!͛ͺReceived checksum: !!:ͣn&"ͺ Calculated checksum: *&" *&!!:ͣn&Eʌ?!}2!!n&"#"٬!!n&BR¾?!}2e@DR?!}2e@ER?!}2e@FR?!}2e@NR@!}2e@SR"@!}2e@TR6@!}2e@YRJ@!}2e@ZR^@!}2e@! }2!:ͣ!Eʝ@!!!!!:ͣ!*&*&! ͒}oE@!}2*/&E@!!͛ͺ packet ok: *&!͋ "! Mh!|g}o!͒E@! *i! !i! !i!,! !i! !i͛ͺ6****************************************************** ͛ͺ,commands available from inside connect mode: ͛ ͛ͺc return to command mode ͛ͺ.b send a break to remote terminal or computer ͛ͺ6****************************************************** !}2!"͛ͺ:͢ =!y.I!"GxF*!"*&*ݬ&}o**(}oEʖQ*&EQ!}2Q!}2ݬ!(!͛ͺ Sending... *۬!"۬lM!y:ͣ!EjR.I!"GxF*!"*&*ݬ&}o**(}oE4R*ެ&*ݬ&}o**(}oER*ެ&EʢR!}2éR!}2ݬ*۬!!@E"۬!Ze.!y.I!"GxF*!"*&*ݬ&}o**(}oER*&E S!}2'S!}2ݬ!}2*۬!!@E"۬!Be.!y.I!"GxF*!"*&*ݬ&}o**(}oE[S*&EʥS!}2ìS!}2ݬ>!"׬!"լ!}2ͦ.!!>:n+*߬&EdU!!"!}2*&RTͼOATRTiQATR$TQATR4TͪRATRAT(S*ݬ&*&}oES*&EʋT!(!͛ͺCompleted. !" ôT!(!͛ͺAborted !" *ݬ&*/&}oEdU!!͛ͺAbort conditions were: ͛ͺState during abort was: !L!*&)))):!ͪ ͛ͺ Quoting was: *=&!͋ !!*&!*&! }oE.V*=&EʩU*&}2ðU!N}2!Y*#e.͢ =*#e.=*#e.=*&"e.=*#e.=*&e.=*&e.=*&e.=!y=V!Ye.!y.IG!Ne.!y.IGͶ<*&EX*&R*W!!:n+*߬&EV!"*٬"۬!(!͛ͺReceiving...  oU!}2'WMECannot open file!.IG!}2ݬ!! ͛ͺCannot open file: !:!ͪ WR@W*٬"۬oUWR…W*٬"۬oU!}2ݬ!<!͛ͺ Completed. !! WR›W*٬"۬oUW RW!}2ݬ*٬"۬MEUnknown packet type.!.IG!<!͛ͺAborted. !! ÒX*ئ!"ئ*լ!"լDV*ئ*(EʒX!}2ݬ!"۬MECannot get file header.!.IG!! ͛ͺCannot get file header. *ݬ&*&!}oEZV>{/!"۬!R!>:͢ =!y.I!"ΦGͶ<*&*&!}oEY*"۬!ͦ͊D*ͦ&EYoU!}2*&!EWY!! !:͛!ͪ !}2ݬ*ͦ&*ݬ&}o}oEʊY*լ!"լ*Φ!"ΦDV*Φ*(*ݬ&}oE Z!}2ݬMECannot get send init packet!y.IG!! ͛ͺCannot get send_init packet. *ݬ&*&!}oEX>{/!"æͶ<*&*&!}oExZ*٬"۬!¦͊D*¦&EuZoU!}2 [*լ!"լDV*æ!"æ*æ*(E [!}2ݬMECannot get send init packet!y.IG!! ͛ͺCannot get send_init packet. *ݬ&*&!}oE5ZMd!>!"*!:ͣ͸E4]!*n&*&*=&}oEc\*!"!*n&*5&E4\*!"!*n&́!#͑!&͑!~͑OE\!>:!*n&!|g}oe.=d!>1\!>:!*n&!|g}o"e.=d!>`\!>:!*n&!|g}oe.=d!>%]!*n&!|g}o*5&E]!*n&!|g}ó!#͑!~͑OE\!>:!*n&e.=d!>]!>:!*n&"e.=d!>%]!>:!*n&e.=d!>*!":[Ͷ:ͣfzO^"*!E ^!!!ͺ !"*!"!*+!>*n&s*!"*#]oUV_R^*&Eʽ^*&!Eʜ^*!͸Eʜ^!*+!s!!!ͺ !Ͱ !}2oU!}2V_R?_*&E2_*&!E_*!͸E_!*+!s!!!ͺ !Ͱ !}2oU!}2V_ RO_DVV_!}2ݬ*ݬ&*&}oE5]!"׬!"լ!"!}2*& R˜_ͯX_R¨_)Z_R¸_ZV_R_5]*ݬ&*&}oEʄ_!(!*&E `͛ͺCompleted.  $`͛ͺAborted.  ͛!" !! M!XM!>M!$M! !@#!:ͣ!Eʏ`!s#!:ͣ!E`! e.!:Ͳ!E`!:!! e.!:Ͳk!X`!:!X! e.!:Ͳ!E3a!!! e.!:Ͳ?aMP!!@#!:ͣ!Eʯa! e.!:Ͳ!Eʡa!:!! e.!:Ͳk!>ïa!:!>! e.!:Ͳ!Ea!!! e.!:ͲaMP!!@#!:ͣ!Efb! e.!:Ͳ!EXb!:!! e.!:Ͳk!$fb!:!$! e.!:Ͳ!Eʡb!!! e.!:ͲíbMP!!@#!:ͣ!Ec! e.!:Ͳ!Ec!:!! e.!:Ͳk! c!:! ͛ͺTKermit> !P͎ !:ͣ!Ewe;`!X!n&CRwccR}c̀BweDRʑcdR—c(weERʫceRc!X!n&RRcrRc͏*cXRcxRc7LweBR&dbR&dLR&dlR&dFR&dfR,dELweGR@dgRPd>! }2k_weHRddhRjd/4weQR~dqR„d7LweRRʘdrR¨d>!}2k_weSRʼdsR4e!X!n&ERdeRe!X!n&NRdnReiMeTRetRe͏71eHR.ehR1e͐0we͛ͺ6Unimplemented command, type Help for list of commands. ! !i! !i! !i! !i! !Di! !i! !i! !i! !i!}2!}2!"!1}2!~}2!}2!}2/!}2;!}2Moff!7Moff!+!"(!("!}2 !P͎ !:ͣ!Ewe;`!X!n&CRwccR}c̀BweDRʑcdR—c(weERʫceRc!X!n&RRcrRc͏*cXRcxRc7LweBR&dbR&dLR&dlR&dFR&dfR,dELweGR@dgRPd>! }2k_weHRddhRjd/4weQR~dqR„d7LweRRʘdrR¨d>!}2k_weSRʼdsR4e!X!n&ERdeRe!X!n&NRdnReiMe/* * K e r m i t File Transfer Utility * * UNIX Kermit, Columbia University, 1981, 1982, 1983 * Bill Catchings, Bob Cattani, Chris Maio, Frank da Cruz, Alan Crosswell * * Also: Jim Guyton, Rand Corporation * Walter Underwood, Ford Aerospace * * usage: kermit c [lbe line baud escapechar] to connect * kermit s [d..iflb line baud] file ... to send files * kermit r [d..iflb line baud] to receive files * * where c=connect, s=send, r=receive, * d=debug, i=image mode, f=no filename conversion, l=tty line, * b=baud rate, e=escape char. * * For remote Kermit, format is either: * kermit r to receive files * or kermit s file ... to send files * */ /* * Modification History: * * Oct. 17 Included fixes from Alan Crosswell (CUCCA) for IBM_UTS: * - Changed MYEOL character from \n to \r. * - Change char to int in bufill so getc would return -1 on * EOF instead of 255 (-1 truncated to 8 bits) * - Added read() in rpack to eat the EOL character * - Added fflush() call in printmsg to force the output * NOTE: The last three changes are not conditionally compiled * since they should work equally well on any system. * * Changed Berkeley 4.x conditional compilation flag from * UNIX4X to UCB4X. * Added support for error packets and cleaned up the printing * routines. */ #include /* Standard UNIX definitions */ /* Conditional compilation for different machines/operating systems */ /* One and only one of the following lines should be 1 */ #define UCB4X 1 /* Berkeley 4.x UNIX */ #define TOPS_20 0 /* TOPS-20 */ #define IBM_UTS 0 /* Amdahl UTS on IBM systems */ #define VAX_VMS 0 /* VAX/VMS (not yet implemented) */ /* Conditional compilation for the different Unix variants */ /* 0 means don't compile it, nonzero means do */ #if UCB4X #define V6_LIBS 0 /* Dont't use retrofit libraries */ #define NO_FIONREAD 0 /* We have ioctl(FIONREAD,...) for flushinput() */ #define NO_TANDEM 0 /* We have TANDEM line discipline (xon/xoff) */ #endif #if IBM_UTS #define V6_LIBS 0 /* Don't use retrofit libraries */ #define NO_FIONREAD 1 /* No ioctl(FIONREAD,...) for flushinput() */ #define NO_TANDEM 1 /* No TANDEM line discipline (xon/xoff) */ #endif #if V6_LIBS #include #include #include #else #include #include #include #endif #if NO_TANDEM #define TANDEM 0 /* define it to be nothing if it's unsupported */ #endif /* Symbol Definitions */ #define MAXPACKSIZ 94 /* Maximum packet size */ #define SOH 1 /* Start of header */ #define CR 13 /* ASCII Carriage Return */ #define SP 32 /* ASCII space */ #define DEL 127 /* Delete (rubout) */ #define ESCCHR '^' /* Default escape character for CONNECT */ #define MAXTRY 10 /* Times to retry a packet */ #define MYQUOTE '#' /* Quote character I will use */ #define MYPAD 0 /* Number of padding characters I will need */ #define MYPCHAR 0 /* Padding character I need (NULL) */ #if IBM_UTS #define MYEOL '\r' /* End-Of-Line character for UTS systems */ #else #define MYEOL '\n' /* End-Of-Line character I need */ #endif #define MYTIME 10 /* Seconds after which I should be timed out */ #define MAXTIM 60 /* Maximum timeout interval */ #define MINTIM 2 /* Minumum timeout interval */ #define TRUE -1 /* Boolean constants */ #define FALSE 0 /* Macro Definitions */ /* * tochar: converts a control character to a printable one by adding a space. * * unchar: undoes tochar. * * ctl: converts between control characters and printable characters by * toggling the control bit (ie. ^A becomes A and A becomes ^A). */ #define tochar(ch) ((ch) + ' ') #define unchar(ch) ((ch) - ' ') #define ctl(ch) ((ch) ^ 64 ) /* Global Variables */ int size, /* Size of present data */ rpsiz, /* Maximum receive packet size */ spsiz, /* Maximum send packet size */ pad, /* How much padding to send */ timint, /* Timeout for foreign host on sends */ n, /* Packet number */ numtry, /* Times this packet retried */ oldtry, /* Times previous packet retried */ ttyfd, /* File descriptor of tty for I/O, 0 if remote */ remote, /* -1 means we're a remote kermit */ image, /* -1 means 8-bit mode */ debug, /* indicates level of debugging output (0=none) */ filnamcnv, /* -1 means do file name case conversions */ filecount; /* Number of files left to send */ char state, /* Present state of the automaton */ padchar, /* Padding character to send */ eol, /* End-Of-Line character to send */ escchr, /* Connect command escape character */ quote, /* Quote character in incoming data */ **filelist, /* List of files to be sent */ *filnam, /* Current file name */ recpkt[MAXPACKSIZ], /* Receive packet buffer */ packet[MAXPACKSIZ]; /* Packet buffer */ FILE *fp, /* File pointer for current disk file */ *log; /* File pointer for Logfile */ jmp_buf env; /* Environment ptr for timeout longjump */ /* * m a i n * * Main routine - parse command and options, set up the * tty lines, and dispatch to the appropriate routine. */ main(argc,argv) int argc; /* Character pointers to and count of */ char **argv; /* command line arguments */ { char *ttyname, /* tty name for LINE argument */ *cp; /* char pointer */ int speed, /* speed of assigned tty, */ cflg, rflg, sflg; /* flags for CONNECT, RECEIVE, SEND */ struct sgttyb rawmode, /* Controlling tty raw mode */ cookedmode, /* Controlling tty cooked mode */ ttymode; /* mode of tty line in LINE option */ if (argc < 2) usage(); /* Make sure there's a command line */ cp = *++argv; argv++; argc -= 2; /* Set up pointers to args */ /* Initialize these values and hope the first packet will get across OK */ eol = CR; /* EOL for outgoing packets */ quote = '#'; /* Standard control-quote char "#" */ pad = 0; /* No padding */ padchar = NULL; /* Use null if any padding wanted */ speed = cflg = sflg = rflg = 0; /* Turn off all parse flags */ ttyname = 0; /* Default is remote mode */ #if UCB4X /* Default to 7-bit masking, CRLF */ image = FALSE; /* translation and filename case */ filnamcnv = TRUE; /* conversion for UNIX systems */ #else image = TRUE; /* Default to no processing for */ filnamcnv = FALSE; /* non-UNIX systems */ #endif escchr = ESCCHR; /* Default escape character */ while ((*cp) != NULL) /* Parse characters in first arg. */ switch (*cp++) { case 'c': cflg++; break; /* C = Connect command */ case 's': sflg++; break; /* S = Send command */ case 'r': rflg++; break; /* R = Receive command */ case 'd': /* D = Increment debug mode count */ debug++; break; case 'f': filnamcnv = FALSE; /* F = don't do case conversion */ break; /* on filenames */ case 'i': /* I = Image (8-bit) mode */ image = TRUE; break; /* (this is default for non-UNIX) */ case 'l': /* L = specify tty line to use */ if (argc--) ttyname = *argv++; else usage(); if (debug) printf("Line to remote host is %s\n",ttyname); break; case 'e': /* E = specify escape char */ if (argc--) escchr = **argv++; else usage(); if (debug) printf("Escape char is \"%c\"\n",escchr); break; case 'b': /* B = specify baud rate */ #if UCB4X if (argc--) speed = atoi(*argv++); else usage(); if (debug) printf("Line speed to remote host is %d\n",speed); break; #else printmsg("Speed setting implemented for Unix only."); exit(1); #endif } /* Done parsing */ if ((cflg+sflg+rflg) != 1) /* Only one command allowed */ usage(); if (ttyname) /* If LINE was specified, we */ { /* operate in local mode */ ttyfd = open(ttyname,2); /* Open the tty line */ if (ttyfd < 0) { printmsg("Cannot open %s",ttyname); exit(1); } remote = FALSE; /* Indicate we're in local mode */ } else /* No LINE specified so we operate */ { /* in remote mode (ie. controlling */ ttyfd = 0; /* tty is the communications line) */ remote = TRUE; } /* Put the proper tty into the correct mode */ if (remote) /* If remote, use controlling tty */ { gtty(0,&cookedmode); /* Save current mode so we can */ gtty(0,&rawmode); /* restore it later */ rawmode.sg_flags |= (RAW|TANDEM); rawmode.sg_flags &= ~(ECHO|CRMOD); stty(0,&rawmode); /* Put tty in raw mode */ } else /* Local, use assigned line */ { gtty(ttyfd,&ttymode); ttymode.sg_flags |= (RAW|TANDEM); ttymode.sg_flags &= ~(ECHO|CRMOD); #if UCB4X /* Speed changing for UNIX only */ if (speed) /* User specified a speed? */ { switch(speed) /* Get internal system code */ { case 110: speed = B110; break; case 150: speed = B150; break; case 300: speed = B300; break; case 1200: speed = B1200; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; default: printmsg("Bad line speed."); exit(1); } ttymode.sg_ispeed = speed; ttymode.sg_ospeed = speed; } #endif /* UCB4X */ stty(ttyfd,&ttymode); /* Put asg'd tty in raw mode */ } /* All set up, now execute the command that was given. */ if (debug) { printf("Debugging level = %d\n\n",debug); if (cflg) printf("Connect command\n\n"); if (sflg) printf("Send command\n\n"); if (rflg) printf("Receive command\n\n"); } if (cflg) connect(); /* Connect command */ if (sflg) /* Send command */ { if (argc--) filnam = *argv++; /* Get file to send */ else { if (remote) stty(0,&cookedmode); /* Restore controlling tty's modes */ usage(); /* and give error */ } fp = NULL; /* Indicate no file open yet */ filelist = argv; /* Set up the rest of the file list */ filecount = argc; /* Number of files left to send */ if (sendsw() == FALSE) /* Send the file(s) */ printmsg("Send failed."); /* Report failure */ else /* or */ printmsg("done."); /* success */ } if (rflg) /* Receive command */ { if (recsw() == FALSE) /* Receive the file(s) */ printmsg("Receive failed."); else /* Report failure */ printmsg("done."); /* or success */ } if (remote) stty(0,&cookedmode); /* Restore controlling tty's modes */ } /* * s e n d s w * * Sendsw is the state table switcher for sending files. It loops until * either it finishes, or an error is encountered. The routines called * by sendsw are responsible for changing the state. * */ sendsw() { char sinit(), sfile(), sdata(), seof(), sbreak(); state = 'S'; /* Send initiate is the start state */ n = 0; /* Initialize message number */ numtry = 0; /* Say no tries yet */ while(TRUE) /* Do this as long as necessary */ { if (debug) printf("sendsw state: %c\n",state); switch(state) { case 'S': state = sinit(); break; /* Send-Init */ case 'F': state = sfile(); break; /* Send-File */ case 'D': state = sdata(); break; /* Send-Data */ case 'Z': state = seof(); break; /* Send-End-of-File */ case 'B': state = sbreak(); break; /* Send-Break */ case 'C': return (TRUE); /* Complete */ case 'A': return (FALSE); /* "Abort" */ default: return (FALSE); /* Unknown, fail */ } } } /* * s i n i t * * Send Initiate: send this host's parameters and get other side's back. */ char sinit() { int num, len; /* Packet number, length */ if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */ spar(packet); /* Fill up init info packet */ flushinput(); /* Flush pending input */ spack('S',n,6,packet); /* Send an S packet */ switch(rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': return(state); /* NAK, try it again */ case 'Y': /* ACK */ if (n != num) /* If wrong ACK, stay in S state */ return(state); /* and try again */ rpar(recpkt); /* Get other side's init info */ if (eol == 0) eol = '\n'; /* Check and set defaults */ if (quote == 0) quote = '#'; numtry = 0; /* Reset try counter */ n = (n+1)%64; /* Bump packet count */ return('F'); /* OK, switch state to F */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: return(state); /* Receive failure, try again */ default: return('A'); /* Anything else, just "abort" */ } } /* * s f i l e * * Send File Header. */ char sfile() { int num, len; /* Packet number, length */ char filnam1[50], /* Converted file name */ *newfilnam, /* Pointer to file name to send */ *cp; /* char pointer */ if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */ if (fp == NULL) /* If not already open, */ { if (debug) printf(" Opening %s for sending.\n",filnam); fp = fopen(filnam,"r"); /* open the file to be sent */ if (fp == NULL) /* If bad file pointer, give up */ { error("Cannot open file %s",filnam); return('A'); } } strcpy(filnam1, filnam); /* Copy file name */ newfilnam = cp = filnam1; while (*cp != '\0') /* Strip off all leading directory */ if (*cp++ == '/') /* names (ie. up to the last /). */ newfilnam = cp; if (filnamcnv) /* Convert lower case to upper */ for (cp = newfilnam; *cp != '\0'; cp++) if (*cp >= 'a' && *cp <= 'z') *cp ^= 040; len = cp - newfilnam; /* Compute length of new filename */ printmsg("Sending %s as %s",filnam,newfilnam); spack('F',n,len,newfilnam); /* Send an F packet */ switch(rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': /* NAK, just stay in this state, */ num = (--num<0 ? 63:num); /* unless it's NAK for next packet */ if (n != num) /* which is just like an ACK for */ return(state); /* this packet so fall thru to... */ case 'Y': /* ACK */ if (n != num) return(state); /* If wrong ACK, stay in F state */ numtry = 0; /* Reset try counter */ n = (n+1)%64; /* Bump packet count */ size = bufill(packet); /* Get first data from file */ return('D'); /* Switch state to D */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: return(state); /* Receive failure, stay in F state */ default: return('A'); /* Something else, just "abort" */ } }  /* * s d a t a * * Send File Data */ char sdata() { int num, len; /* Packet number, length */ if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */ spack('D',n,size,packet); /* Send a D packet */ switch(rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': /* NAK, just stay in this state, */ num = (--num<0 ? 63:num); /* unless it's NAK for next packet */ if (n != num) /* which is just like an ACK for */ return(state); /* this packet so fall thru to... */ case 'Y': /* ACK */ if (n != num) return(state); /* If wrong ACK, fail */ numtry = 0; /* Reset try counter */ n = (n+1)%64; /* Bump packet count */ if ((size = bufill(packet)) == EOF) /* Get data from file */ return('Z'); /* If EOF set state to that */ return('D'); /* Got data, stay in state D */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: return(state); /* Receive failure, stay in D */ default: return('A'); /* Anything else, "abort" */ } } /* * s e o f * * Send End-Of-File. */ char seof() { int num, len; /* Packet number, length */ if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */ spack('Z',n,0,packet); /* Send a 'Z' packet */ switch(rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': /* NAK, just stay in this state, */ num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */ if (n != num) /* which is just like an ACK for */ return(state); /* this packet so fall thru to... */ case 'Y': /* ACK */ if (n != num) return(state); /* If wrong ACK, hold out */ numtry = 0; /* Reset try counter */ n = (n+1)%64; /* and bump packet count */ if (debug) printf(" Closing input file %s, ",filnam); fclose(fp); /* Close the input file */ fp = NULL; /* Set flag indicating no file open */ if (debug) printf("looking for next file...\n"); if (gnxtfl() == FALSE) /* No more files go? */ return('B'); /* if not, break, EOT, all done */ if (debug) printf(" New file is %s\n",filnam); return('F'); /* More files, switch state to F */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: return(state); /* Receive failure, stay in Z */ default: return('A'); /* Something else, "abort" */ } } /* * s b r e a k * * Send Break (EOT) */ char sbreak() { int num, len; /* Packet number, length */ if (numtry++ > MAXTRY) return('A'); /* If too many tries "abort" */ spack('B',n,0,packet); /* Send a B packet */ switch (rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': /* NAK, just stay in this state, */ num = (--num<0 ? 63:num); /* unless NAK for previous packet, */ if (n != num) /* which is just like an ACK for */ return(state); /* this packet so fall thru to... */ case 'Y': /* ACK */ if (n != num) return(state); /* If wrong ACK, fail */ numtry = 0; /* Reset try counter */ n = (n+1)%64; /* and bump packet count */ return('C'); /* Switch state to Complete */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: return(state); /* Receive failure, stay in B */ default: return ('A'); /* Other, "abort" */ } } /* * r e c s w * * This is the state table switcher for receiving files. */ recsw() { char rinit(), rfile(), rdata(); /* Use these procedures */ state = 'R'; /* Receive-Init is the start state */ n = 0; /* Initialize message number */ numtry = 0; /* Say no tries yet */ while(TRUE) { if (debug) printf(" recsw state: %c\n",state); switch(state) /* Do until done */ { case 'R': state = rinit(); br eak; /* Receive-Init */ case 'F': state = rfile(); break; /* Receive-File */ case 'D': state = rdata(); break; /* Receive-Data */ case 'C': return(TRUE); /* Complete state */ case 'A': return(FALSE); /* "Abort" state */ } } } /* * r i n i t * * Receive Initialization */ char rinit() { int len, num; /* Packet length, number */ if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */ switch(rpack(&len,&num,packet)) /* Get a packet */ { case 'S': /* Send-Init */ rpar(packet); /* Get the other side's init data */ spar(packet); /* Fill up packet with my init info */ spack('Y',n,6,packet); /* ACK with my parameters */ oldtry = numtry; /* Save old try count */ numtry = 0; /* Start a new counter */ n = (n+1)%64; /* Bump packet number, mod 64 */ return('F'); /* Enter File-Receive state */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: /* Didn't get packet */ spack('N',n,0,0); /* Return a NAK */ return(state); /* Keep trying */ default: return('A'); /* Some other packet type, "abort" */ } } /* * r f i l e * * Receive File Header */ char rfile() { int num, len; /* Packet number, length */ char filnam1[50]; /* Holds the converted file name */ if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */ switch(rpack(&len,&num,packet)) /* Get a packet */ { case 'S': /* Send-Init, maybe our ACK lost */ if (oldtry++ > MAXTRY) return('A'); /* If too many tries "abort" */ if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */ { /* Yes, ACK it again with */ spar(packet); /* our Send-Init parameters */ spack('Y',num,6,packet); numtry = 0; /* Reset try counter */ return(state); /* Stay in this state */ } else return('A'); /* Not previous packet, "abort" */ case 'Z': /* End-Of-File */ if (oldtry++ > MAXTRY) return('A'); if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */ { /* Yes, ACK it again. */ spack('Y',num,0,0); numtry = 0; return(state); /* Stay in this state */ } else return('A'); /* Not previous packet, "abort" */ case 'F': /* File Header (just what we want) */ if (num != n) return('A'); /* The packet number must be right */ strcpy(filnam1, packet); /* Copy the file name */ if (filnamcnv) /* Convert upper case to lower */ for (filnam=filnam1; *filnam != '\0'; filnam++) if (*filnam >= 'A' && *filnam <= 'Z') *filnam |= 040; if ((fp=fopen(filnam1,"w"))==NULL) /* Try to open a new file */ { error("Cannot create %s",filnam1); /* Give up if can't */ return('A'); } else /* OK, give message */ printmsg("Receiving %s as %s",packet,filnam1); spack('Y',n,0,0); /* Acknowledge the file header */ oldtry = numtry; /* Reset try counters */ numtry = 0; /* ... */ n = (n+1)%64; /* Bump packet number, mod 64 */ return('D'); /* Switch to Data state */ case 'B': /* Break transmission (EOT) */ if (num != n) return ('A'); /* Need right packet number here */ spack('Y',n,0,0); /* Say OK */ return('C'); /* Go to complete state */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: /* Didn't get packet */ spack('N',n,0,0); /* Return a NAK */ return(state); /* Keep trying */ default: return ('A'); /* Some other packet, "abort" */ } } /* * r d a t a * * Receive Data */ char rdata() { int num, len; /* Packet number, length */ if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */ switch(rpack(&len,&num,packet)) /* Get packet */ { case 'D': /* Got Data packet */ if (num != n) /* Right packet? */ {  /* No */ if (oldtry++ > MAXTRY) return('A'); /* If too many tries, abort */ if (num == ((n==0) ? 63:n-1)) /* Else check packet number */ { /* Previous packet again? */ spack('Y',num,6,packet); /* Yes, re-ACK it */ numtry = 0; /* Reset try counter */ return(state); /* Don't write out data! */ } else return('A'); /* sorry, wrong number */ } /* Got data with right packet number */ bufemp(packet,len); /* Write the data to the file */ spack('Y',n,0,0); /* Acknowledge the packet */ oldtry = numtry; /* Reset the try counters */ numtry = 0; /* ... */ n = (n+1)%64; /* Bump packet number, mod 64 */ return('D'); /* Remain in data state */ case 'F': /* Got a File Header */ if (oldtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */ if (num == ((n==0) ? 63:n-1)) /* Else check packet number */ { /* It was the previous one */ spack('Y',num,0,0); /* ACK it again */ numtry = 0; ! /* Reset try counter */ return(state); /* Stay in Data state */ } else return('A'); /* Not previous packet, "abort" */ case 'Z': /* End-Of-File */ if (num != n) return('A'); /* Must have right packet number */ spack('Y',n,0,0); /* OK, ACK it. */ fclose(fp); /* Close the file */ n = (n+1)%64; /* Bump packet number */ return('F'); /* Go back to Receive File state */ case 'E': /* Error packet received */ prerrpkt(recpkt); /* Print it out and */ return('A'); /* abort */ case FALSE: /* Didn't get packet */ spack('N',n,0,0); /* Return a NAK */ return(state); /* Keep trying */ default: return('A'); /* Some other packet, "abort" */ } } /* * c o n n e c t * * Establish a virtual terminal connection with the remote host, over an * assigned tty line. */ connect() { int pid, /* Holds process id of child */ connected; /* Boolean connect flag */ char bel = '\07', c;  struct sgttyb rawmode, /* Controlling tty raw mode */ cookedmode; /* Controlling tty cooked mode */ if (remote) /* Nothing to connect to in remote */ { /* mode, so just return */ printmsg("No line specified for connection."); return; } gtty(0,&cookedmode); /* Save current mode so we can */ gtty(0,&rawmode); /* restore it later */ rawmode.sg_flags |= (RAW|TANDEM); rawmode.sg_flags &= ~(ECHO|CRMOD); stty(0,&rawmode); /* Put tty in raw mode */ pid = fork(); /* Start fork to get typeout from remote host */ if (pid) /* Parent: send type-in to remote host */ { printmsg("connected...\r"); connected = TRUE; /* Put us in "connect mode" */ while (connected) { read(0,&c,1); /* Get a character */ if ((c&0177) == escchr) /* Check for escape character */ { read(0,&c,1); if ((c&0177) == escchr) write(ttyfd,&c,1); else switch (c&0177) { case 'c': case 'C': connected = FALSE; write(0,"\r\n",2); break; case 'h': case 'H': write(0,"\r\nYes, I'm still here...\r\n",26); break; default: write(0,&bel,1); break; } } else { /* If not escape charater, */ write(ttyfd,&c,1); /* write it out */ c = NULL; /* Nullify it (why?) */ } } kill(pid,9); /* Done, kill the child */ wait(0); /* and bury him */ stty(0,&cookedmode); /* Restore tty mode */ printmsg("disconnected."); return; /* Done */ } else /* Child does the reading from the remote host */ { while(1) /* Do this forever */ { read(ttyfd,&c,1); write(1,&c,1); } } } /* * KERMIT utilities. */ clkint() /* Timer interrupt handler */ { longjmp(env,TRUE); /* Tell rpack to give up */ } /* * s p a c k * * Send a Packet */ spack(type,num,len,data) char type, *data; int num, len; { int i; /* Character loop counter */ char chksum, buffer[100]; /* Checksum, packet buffer */ register char *bufp; /* Buffer pointer */ if (debug>1) /* Display outgoing packet */ { if (data != NULL) data[len] = '\0'; /* Null-terminate data to print it */ printf(" spack type: %c\n",type); printf(" num: %d\n",num); printf(" len: %d\n",len); if (data != NULL) printf(" data: \"%s\"\n",data); } bufp = buffer; /* Set up buffer pointer */ for (i=1; i<=pad; i++) write(ttyfd,&padchar,1); /* Issue any padding */ *bufp++ = SOH; /* Packet marker, ASCII 1 (SOH) */ *bufp++ = tochar(len+3); /* Send the character count */ chksum = tochar(len+3); /* Initialize the checksum */ *bufp++ = tochar(num); /* Packet number */ chksum += tochar(num); /* Update checksum */ *bufp++ = type; /* Packet type */ chksum += type; /* Update checksum */ for (i=0; i> 6)+chksum)&077; /* Compute final checksum */ *bufp++ = tochar(chksum); /* Put it in the packet */ *bufp = eol; /* Extra-packet line terminator */ write(ttyfd, buffer,bufp-buffer+1); /* Send the packet */ } /* * r p a c k * * Read a Packet */ rpack(len,num,data) int *len, *num; /* Packet length, number */ char *data; /* Packet data */ { int i, done; /* Data character number, loop exit */ char t, /* Current input character */ type, /* Packet type */ cchksum, /* Our (computed) checksum */ rchksum; /* Checksum received from other host */ #if UCB4X /* TOPS-20 can't handle timeouts... */ if (setjmp(env)) return FALSE; /* Timed out, fail */ signal(SIGALRM,clkint); /* Setup the timeout */ if ((timint > MAXTIM) || (timint < MINTIM)) timint = MYTIME; alarm(timint); #endif /* UCB4X */ while (t != SOH) /* Wait for packet header */ { read(t"tyfd,&t,1); t &= 0177; /* Handle parity */ } done = FALSE; /* Got SOH, init loop */ while (!done) /* Loop to get a packet */ { read(ttyfd,&t,1); /* Get character */ if (!image) t &= 0177; /* Handle parity */ if (t == SOH) continue; /* Resynchronize if SOH */ cchksum = t; /* Start the checksum */ *len = unchar(t)-3; /* Character count */ read(ttyfd,&t,1); /* Get character */ if (!image) t &= 0177; /* Handle parity */ if (t == SOH) continue; /* Resynchronize if SOH */ cchksum = cchksum + t; /* Update checksum */ *num = unchar(t); /* Packet number */ read(ttyfd,&t,1); /* Get character */ if (!image) t &= 0177; /* Handle parity */ if (t == SOH) continue; /* Resynchronize if SOH */ cchksum = cchksum + t; /* Update checksum */ type = t; /* Packet type */ for (i=0; i<*len; i++) /* The data itself, if any */ { /* Loop for character count */ read(ttyfd,&t,1); /* Get character */ if (!image) t &= 0177; /* Handle parity */ if (t == SOH) continue; /* Resynch if SOH */ cchksum = cchksum + t; /* Update checksum */ data[i] = t; /* Put it in the data buffer */ } data[*len] = 0; /* Mark the end of the data */ read(ttyfd,&t,1); /* Get last character (checksum) */ rchksum = unchar(t); /* Convert to numeric */ read(ttyfd,&t,1); /* get EOL character and toss it */ if (!image) t &= 0177; /* Handle parity */ if (t == SOH) continue; /* Resynchronize if SOH */ done = TRUE; /* Got checksum, done */ } #if UCB4X alarm(0); /* Disable the timer interrupt */ #endif if (debug>1) /* Display incoming packet */ { if (data != NULL) data[*len] = '\0'; /* Null-terminate data to print it */ printf(" rpack type: %c\n",type); printf(" num: %d\n",*num); printf(" len: %d\n",*len); if (data != NULL) printf(" data: \"%s\"\n",data); } /* Fold in bits 7,8 to compute */ cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */ if (cchksum != rchksum) return(FALSE); return(type); /* All OK, return packet type */ } /* * b u f i l l * * Get a bufferful of data from the file that's being sent. * Only control-quoting is done; 8-bit & repeat count prefixes are * not handled. */ bufill(buffer) char buffer[]; /* Buffer */ { int i, /* Loop index */ t; /* Char read from file */ char t7; /* 7-bit version of above */ i = 0; /* Init data buffer pointer */ while((t = getc(fp)) != EOF) /* Get the next character */ { t7 = t & 0177; /* Get low order 7 bits */ if (t7 < SP || t7==DEL || t7==quote) /* Does this char require */ { /* special handling? */ if (t=='\n' && !image) { /* Do LF->CRLF mapping if !image */ buffer[i++] = quote; buffer[i++] = ctl('\r'); } buffer[i++] = quote; /* Quote the character */ if (t7 != quote) { t = ctl(t); /* and uncontrolify */ t7 = ctl(t7); } } if (image) buffer[i++] = t; /* Deposit the character itself */ else buffer[i++] = t7; if (i >= spsiz-8) return(i); /* Check length */ } if (i==0) return(EOF); /* Wind up here only on EOF */ return(i); /* Handle partial buffer */ } /* * b u f e m p * * Put data from an incoming packet into a file. */ bufemp(buffer,len) char buffer[]; /* Buffer */ int len; /* Length */ { int i; /* Counter */ char t; /* Character holder */ for (i=0; i as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. More Kermit. Filename Description -01-00 .87 This is the release date of the disk. -CPM157 .DOC This is t$he description of the disk contents. KRMTEXEC.COM 8720 26K [Executive Kermit 1 of 15] Turbo Pascal version of Kermit for the Osborne Executive. All source code is included and is squeezed. KERMIT .DOC 9594 17K [Executive Kermit 2 of 15] K .PQS 4EA4 2K [Executive Kermit 3 of 15] KCMD .PQS 2FB5 2K [Executive Kermit 4 of 15] KDIR .PQS 654C 4K [Executive Kermit 5 of 15] KDISPLAY.PQS 2A03 2K [Executive Kermit 6 of 15] KERMIT .PQS 0A23 35K [Executive Kermit 7 of 15] KHELP .PQS 7A86 4K [Executive Kermit 8 of 15] KINIT .PQS C26C 4K [Executive Kermit 9 of 15] KOPEN .PQS DFC4 3K [Executive Kermit 10 of 15] KREC .PQS 36AE 4K [Executive Kermit 11 of 15] KREC1 .PQS 67F8 7K [Executive Kermit 12 of 15] KSEND .PQS 1945 9K [Executive Kermit 13 of 15] KTERM .PQS 4692  3K [Executive Kermit 14 of 15] KERMIT .HLP 4B46 1K [Executive Kermit 15 of 15] KERMIT .C 546D 37K C source for Kermit File Transfer Utility. M3 SYSFOG-CPM1581CBA 25K [C128 CPM+ 1 of 2] 30 CPM3 SYSFOG-CPM158A new operating system for the Commodore 128. Modifications 31 CPM3 SYSFOG-CPM158include the ability to read Otrona Attache disk format. 32 CPM3 SYSFOG-CPM158Rename this file to CPM+.SYS before attempting to use%&'