MODULE KermitGlobals; (*) * 1-Dec-83. * Split the Kermit program file into: KermitGlobals which contains all * global information, and Kermit.Pas which is the main program file. * this allow all the kermit modules to be used by any other program. (*) EXPORTS IMPORTS CmdParse FROM CmdParse ; IMPORTS SystemDefs FROM SystemDefs ; CONST (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*) KermitWindow = 1 ; (* Window numbers - See SysInit for their creation -pt*) ErrorWindow = 2 ; (* An error window for all messages and errors -pt*) FF = Chr(#014) ; (* A form feed to clear the windows -pt*) PromptChar = Chr(#032) ; (* PERQ character set: grey arrow head -pt*) OK_to_Pop = True ; (* Allow pop-up menus -pt*) MaxPopCmds = 10 ; (* Maximum pop-up commands -pt*) SetCount = 7 ; (* Number of SET commands [pgt001]*) SetNot = SetCount+1 ; (* Non-SET command index *) SetAmbig = SetCount+2; (* Ambiguous SET command *) ShowCount = SetCount+1;(* SET commands plus 'ALL' *) ShowNot = ShowCount+1 ; ShowAmbig = ShowCount+2 ; MainCount = 9 ; MainNot = MainCount+1 ; MainAmbig = MainCount+2 ; (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*) return = #015 ; formfeed = #014 ; controlbar = 28; { universal manifest constants } ENDSTR = -1; (* End-of-string value [pgt001] *) MAXSTR = 100; { longest possible string } MsgLength = 20; { length of message string -pt} { ascii character set in decimal } BACKSPACE = 8; TAB = 9; lf = #012 ; (* Line feed/new line *) BLANK = 32; EXCLAM = 33; { ! } DQUOTE = 34; { " } SHARP = 35; { # } DOLLAR = 36; { $ } PERCENT = 37; { % } AMPER = 38; { & } SQUOTE = 39; { ' } ACUTE = SQUOTE; LPAREN = 40; { ( } RPAREN = 41; { ) } STAR = 42; { * } PLUS = 43; { + } COMMA = 44; { , } MINUS = 45; { - } DASH = MINUS; PERIOD = 46; { . } SLASH = 47; { / } COLON = 58; { : } SEMICOL = 59; { ; } LESS = 60; { < } EQUALS = 61; { = } GREATER = 62; { > } QUESTION = 63; { ? } ATSIGN = 64; { @ } LBRACK = 91; { [ } BACKSLASH = 92; { \ } ESCAPE = BACKSLASH; { changed - used to be @ } RBRACK = 93; { ] } CARET = 94; { ^ } UNDERLINE = 95; { _ } GRAVE = 96; { ` } LETA = 97; { lower case ... } LETB = 98; LETC = 99; LETD = 100; LETE = 101; LETF = 102; LETG = 103; LETH = 104; LETI = 105; LETJ = 106; LETK = 107; LETL = 108; LETM = 109; LETN = 110; LETO = 111; LETP = 112; LETQ = 113; LETR = 114; LETS = 115; LETT = 116; LETU = 117; LETV = 118; LETW = 119; LETX = 120; LETY = 121; LETZ = 122; LBRACE = 123; { left brace } BAR = 124; { | } RBRACE = 125; { right brace } TILDE = 126; { ~ } SOH = 1; (* ascii SOH character *) CR = 13; (* CR *) DEL = 127; (* rubout *) DEFEOL = CR ; (* default eoln *) DEFTRY = 10; (* default for number of retries *) DEFTIMEOUT = 12; (* default time out *) MAXPACK = 94; (* max is 94 ~ - ' ' *) DEFDELAY = 1; (* delay before sending first init *) NUMPARAM = 6; (* number of parameters in init packet *) DEFQUOTE = SHARP; (* default quote character *) DEFPAD = 0; (* default number OF padding chars *) DEFPADCHAR = 0; (* default padding character *) NumBuffers = 5; (* Number of packet buffers *) (* packet types *) TYPEB = 66; (* ord('B') *) TYPED = 68; (* ord('D') *) TYPEE = 69; (* ord('E') *) TYPEF = 70; (* ord('F') *) TYPEN = 78; (* ord('N') *) TYPES = 83; (* ord('S') *) TYPET = 84; (* ord('T') *) TYPEY = 89; (* ord('Y') *) TYPEZ = 90; (* ord('Z') *) TYPE CharBytes = -2..255; (* full 8-bits, with -1 == end-of-string [pgt001]*) istring = ARRAY [1..MAXSTR] OF CharBytes; MsgString = String[ MsgLength ]; (* String for various messages -pt*) (* Data Types for Kermit *) Packet = RECORD mark : CharBytes; (* SOH character *) count: CharBytes; (* # of bytes following this field *) seq : CharBytes; (* sequence number modulo 64 *) ptype: CharBytes; (* d,y,n,s,b,f,z,e,t packet type *) data : istring; (* the actual data *) (* chksum is last validchar in data array *) (* eol is added, not considered part of packet proper *) END; KermitCommand = (Transmit,Receive,SetParm,Invalid); KermitStates = (FileData,Init,Break,FileHeader,EOFile,Complete,Abort); Stats = Real ; (* Statistic counting -pt*) Ppack = 1..NumBuffers; CType = RECORD check: Integer; PacketPtr : Integer; i : Integer; fld : Integer; t : CharBytes; finished : Boolean; restart : Boolean; control : Boolean; good : Boolean; END; InType = (abortnow,nothing,CRin); (* Data types for pop-up menus *) MyCmds = ARRAY [1..MaxPopCmds] OF String[25] ; (* Menu strings *) MyMenu = RECORD Head: String[25] ;(* Heading *) numcmds: Integer ;(* Number of commands *) cmd: MyCmds (* The actual commands *) END ; MyMenuPtr = ^MyMenu ; VAR done:Boolean; bufferoverflow, finis, XOFFState:Boolean; ch:Char; XON, XOFF:Char; (* Variables for commands *) CmdSpelling, CmdLine: CString ; (* the command and rest of line *) CmdIndex: Integer ; (* Index from command parser *) Inf: pCmdList ; (* Command file pointer *) firstPress: Boolean ;(* Inital call to command parser *) (* Variables for pop-up menus *) MainMenu, (* Main Kermit menu *) SetMenu: MyMenuPtr ; (* SET commands *) OnOff: CmdArray ; (* For the SET feature ON/OFF *) (* SET variables *) EscapeChr: Char ; (* CONNECT 'escape' character -pt*) EscPrint : Char ; (* Printable verion of this character -pt*) BaudRate : String ; FileWarning: Boolean ; HalfDuplex:Boolean; Verbosity: Boolean; (* true to print verbose messages *) Debug : Boolean; EightBitFile: Boolean ; (* 8-bit flag [pgt001]*) (* Varibles for Kermit *) dumStr : String ;(* Dummy string -pt*) dumCh: Char ; (* A dummy character -pt*) aline : istring; DiskFile : Integer;(* Should be "filedesc" -pt*) SaveState: kermitstates; MaxTry : Integer; n,J : Integer; (* packet number *) NumTry : Integer; (* times this packet retried *) OldTry : Integer; NumPad : Integer; (* padding to send *) MyPad : Integer; (* number of padding characters I need *) PadChar : CharBytes; MyPadChar: CharBytes; RunType : KermitCommand; State : kermitstates; (* current state of the automaton *) MyTimeOut: Integer; (* when i want to be timed out *) TheirTimeOut : Integer; Delay : Integer; SizeRecv, SizeSend : Integer; SendEOL, SendQuote : CharBytes; myEOL,myQuote: CharBytes; NumSendPacks : Integer; NumRecvPacks : Integer; NumACK : Integer; NumNAK : Integer; NumACKrecv : Integer; NumNAKrecv : Integer; NumBADrecv : Integer; RunTime: Integer; ChInFile, ChInPack : Stats; Buf : ARRAY [1..NumBuffers] OF packet; ThisPacket : Ppack; (* current packet being sent *) LastPacket : Ppack; (* last packet sent *) CurrentPacket : Ppack; (* current packet received *) NextPacket : Ppack; (* next packet being received *) InputPacket : Ppack; (* save input to do debug *) TOPacket : packet; (* Time_Out Packet *) OldTime : Double ; (* Clock time -pt*) TimeLeft : Integer; (* until Time_Out *) FromConsole : InType;(* Input from Console during receive *) PackControl : CType; (* variables for receive packet routine *) PROCEDURE SYSinit; (* special initialization *) PROCEDURE SYSfinish; (* System dependent *) PROCEDURE KermitInit;(* initialize various parameters & defaults *) PROCEDURE ErrorPack(c:MsgString); (* Send the other host the an error packet with mesage -pt*) EXCEPTION GotErrorPacket(VAR ErrorMsg: istring) ; (*) * This is used when procedure "BuildPacket" receives an error packet * from the other Host. Handlers in procedures "RecvSwitch" and * "SendSwitch" are used to abort the current RECEIVE/SEND command * and close any disk files open. (*) PRIVATE IMPORTS Screen FROM Screen ; IMPORTS PopCmdParse FROM PopCmdParse ; IMPORTS IO_Others FROM IO_Others ; IMPORTS RS232Baud FROM RS232Baud ; IMPORTS Stdio FROM Stdio ; IMPORTS KermitUtils FROM KermitUtils ; IMPORTS KermitSend FROM KermitSend ; PROCEDURE SYSinit; (* special initialization *) BEGIN Writeln( FF ) ; (* Clear the entire screen *) (*---------- PERQ ----------*) (* Create the windows *) CreateWindow(KermitWindow, 0, 0, 767, 700, 'PERQ Kermit, Version 2.0') ; (* A cursor for the Kermit window *) SCurChr( Chr(#177) ) ; (* A black rectangle *) SCurOn ; (* Turn it on *) CreateWindow(ErrorWindow, 0, 701, 767, 322, 'Error and Message Window') ; ChangeWindow( KermitWindow ) ; (* Create pop-up menus *) New(MainMenu) ; WITH MainMenu^ DO BEGIN Head := 'Kermit' ; numcmds := MainCount ; cmd[1] := 'CONNECT' ; cmd[2] := 'EXIT' ; cmd[3] := 'HELP' ; cmd[4] := 'QUIT' ; cmd[5] := 'RECEIVE' ; cmd[6] := 'SEND' ; cmd[7] := 'SET' ; cmd[8] := 'SHOW' ; cmd[9] := 'STATISTICS' ; END ; (* with main menu *) (* ON or OFF *) OnOff[1] := 'ON' ; OnOff[2] := 'OFF' ; New(SetMenu) ; WITH SetMenu^ DO BEGIN Head := 'SET commands' ; numcmds := SetCount ; (* 7 if we include "ALL" for SHOW cmd *) cmd[1] := 'SPEED' ; cmd[2] := 'DEBUG' ; cmd[3] := 'ESCAPE' ; cmd[4] := 'WARNING' ; cmd[5] := 'LOCAL' ; cmd[6] := 'VERBOSE' ; cmd[7] := 'EIGHT-BIT' ; (* [pgt001] *) cmd[8] := 'ALL' ; (* <<<< *) END ; (* with SET menu *) (* other initialisation *) InitCmdFile(Inf, 0) ; InitPopUp ; IOCursorMode( TrackCursor ) ; firstPress := True ; (*---------- KERMIT ----------*) finis:=False; XOFFState:=False; XON:=Chr(#021); XOFF:=Chr(#023); (* SET values -pt*) EscapeChr := Chr(#034) ; (* CONNECT escape character ^\ *) EscPrint := '\' ; (* Printable version *) BaudRate := '9600' ; SetBaud( '9600', True ) ; HalfDuplex:=False ; Verbosity := False; (* default to false / only valid if local *) Debug := False; EightBitFile := False ; (* [pgt001] *) FileWarning := False ; (* Statistic counters *) NumSendPacks := 0; NumRecvPacks := 0; NumACK := 0; NumNAK := 0; NumACKrecv := 0; NumNAKrecv := 0; NumBADrecv := 0; ChInFile := 0.0; (* Statsistics are now reals. -pt*) ChInPack := ChInFile; (* Other values *) NumPad := DEFPAD; (* set defaults *) MyPad := DEFPAD; PadChar := DEFPADCHAR; MyPadChar := DEFPADCHAR; TheirTimeOut := DEFTIMEOUT; MyTimeOut := DEFTIMEOUT; Delay := DEFDELAY; SizeRecv := MAXPACK; SizeSend := MAXPACK; SendEOL := DEFEOL; MyEOL := DEFEOL; SendQuote := DEFQUOTE; MyQuote := DEFQUOTE; MaxTry := DEFTRY; END; PROCEDURE SYSfinish; (* System dependent *) BEGIN Writeln( FF ) ; Dispose( MainMenu ) ; Dispose( SetMenu ) ; DstryCmdFile( Inf ) ; END; PROCEDURE KermitInit; (* initialize various parameters & defaults *) BEGIN n := 0; RunType := invalid; DiskFile := StdIOError; (* to indicate not open yet *) ThisPacket := 1; LastPacket := 2; CurrentPacket := 3; NextPacket := 4; InputPacket := 5; WITH TOPacket DO BEGIN count := 3; seq := 0; ptype := TYPEN; data[1] := ENDSTR; END; FROMCONSOLE:=NOTHING; END; PROCEDURE CtoS(x:MsgString; VAR s:istring); (* convert constant to STIP string *) VAR i : Integer; BEGIN FOR i:=1 TO Length(x) DO s[i] := Ord(x[i]); s[Length(x)+1] := ENDSTR; END; PROCEDURE ErrorPack(c:MsgString); (* output Error packet if necessary -- then exit *) BEGIN WITH Buf[ThisPacket] DO BEGIN seq := n; ptype := TYPEE; CtoS(c,data); count := ilength(data); END; SendPacket; Writeln('%Message to other Host: ', c) END.