module KermitParameters; exports imports KermitGlobals from KermitGlobals; imports MenuUtils from MenuUtils; imports FileDefs from FileDefs; const MaxParts = 30; { NBNBNB!! These type definitions MUST ALWAYS correspond to the sequence of the menu items in the Kermit.MENU file } type MainCommType = (NoMainComm, MainHelp, MainSend, MainReceive, MainGet, MainExit, MainQuit, MainPush, MainTake, MainConnect, MainBye, MainFinish, MainRemote, MainLocal, MainServer, MainSet, MainShow, MainStatus, MainUsage, MainNotFound, MainNotUnique, MainEmptyLine, MainSwitch, MainIllegChar); TermCommType = (NoTermComm, TermHelp, TermQuit, TermSetBaud, TermSetStop, TermSetParity, TermSaveFile, TermOnSave, TermOffSave, TermOnXonXoff, TermOffXonXoff); SetCommType = (NoSetComm, SetHelp, SetBaud, SetParity, SetStop, SetSend, SetReceive, SetFileHeader, Set8BitQuote, SetUse8BitQuote, SetRepFix, SetUseRepFix, SetFileWarning, SetRetry, SetLogFile, SetLog, SetDebugging, SetBreakTime, SetEscape, SetNotFound, SetNotUnique, SetEmptyLine, SetSwitch, SetIllegChar); SendRecType = (NoSendRec, SRHelp, SRPacketLength, SRCtlQuote, SRStartOfPacket, SRTimeOut, SREndOfLine, SRPadding, SRPadChar); FHeaderType = (NoFHeader, FHHelp, FHNord, FHNoTrunc, FHTrunc, FHTrans); TransType = (NoTrans, TransHelp, TransLower, TransUpper, TransOff); RetryType = (NoRetryType, RetryHelp, RetryInitial, RetryPacket, RetryCommand); OnOffType = (NoOnOff, OnOffHelp, On, Off, OnOfNotFound, OnOfNotUnique, OnOfEmptyLine, OnOfSwitch, OnOfIllegChar); EmptyType = (NoEmpty, EmptyHelp, EmptyAndVoid, EmpNotFound, EmpNotUnique, EmptyLine, EmptySwitch, EmptyIllegChar); SpeedType = (NoSpeed, SpHelp, Sp110, Sp150, Sp300, Sp600, Sp1200, Sp2400, Sp4800, Sp9600, SpNotFound, SpNotUnique, SpEmptyLine, SpSwitch, SpIllegChar); ParityType = (NoParComm, ParHelp, NoKParity, EvenKParity, OddKParity, MarkKParity, SpaceKParity, ParNotFound, ParNotUnique, ParEmptyLine, ParSwitch, ParIllegChar); StopType = (NoStopComm, StopHelp, SyncrCmd, Stop1Cmd, Stop1x5Cmd, Stop2Cmd, StopNotFound, StopNotUnique, StopEmptyLine, StopSwitch, StopIllegChar); TruncPart = 1..MaxParts; TListType = array [TruncPart] of integer; const NMainComm = ord(MainNotFound)-1; NTermComm = ord(TermOffXonXoff); NSetComm = ord(SetNotFound)-1; NOnOff = ord(OnOfNotFound)-1; NSpeeds = ord(SpNotFound)-1; NParityComm = ord(ParNotFound)-1; NStopComm = ord(StopNotFound)-1; NEmptyComm = ord(EmpNotFound)-1; var RootMenu : pMenuEntry; { Pointer to root of menu structure } Parity : ParityType; { Current parity setting } Baud : SpeedType; { Current baud rate setting } StopBits : StopType; { Current number of stop bits } SendSOH : char; { Start-Of-Packet to send } SendPSize : integer; { Packet size he wants } SendTimeOut : integer; { Time-out he wants } SendNPad : integer; { Number of padding-characters he wants } SendPadChar : char; { The padding character he wants } SendEOL : char; { The EOL he wants } SendQuote : char; { The Quote char he wants } RecSOH : char; { Start-Of-Packet I want } RecPSize : integer; { Max packet size I can handle } RecTimeOut : integer; { time-out I want } RecNPad : integer; { Padding I want } RecPadChar : char; { Padchar I want } RecEOL : char; { End-Of-Line I propose } RecQuote : char; { Control quote I propose } Use8Quote : boolean; { Is 8-bit quoting in use? } Bit8Quote : char; { 8-bit Quote character to be used } UseRepFix : boolean; { Is repeat prefixing in use? } RepFix : char; { Repeat prefix to be used } NowUse8Quote, NowUseRepFix : boolean; { - enabled during this transfer?? } Debug : boolean; { Enable debug output } FileWarning : boolean; { Avoid overwriting existing file if TRUE} XonXoff : boolean; { use XonXoff handshaking } FileSave : boolean; { Log terminal session to file } SaveFile : PathName; Nord : boolean; { Translate file names for NORD } NumTrunc, OldTrunc : integer; { Truncation list } TruncList : TListType; Translate : TransType; { Case translation } MaxTryPack : Integer; { Retry limits before giving up } MaxTryInit : Integer; MaxTryComm : Integer; LongWait : Integer; LocalKermit : boolean; { Is this Kermit a local one? } DisableTimOut : boolean; { TRUE if timeout is disabled } Idev,Odev : integer; { Which devices to use for line } LegalPackets, { valid packet types } CtlMapping, { Control character mapping } OkQuote, { Valid quote characters } Quotes : set of char; { Quotes presently in use } EscKey : char; { Char to type to escape CONNECT } procedure SetInitPars( var Pack : Packet ); procedure ReadPars ( VAR Pack : Packet ); procedure InitParameters; procedure CleanupParameters; procedure SetCommand( PList : pPListEntry ); procedure ShowCommand( PList : pPListEntry ); procedure StatusCommand; procedure ShowKey( Ch : char ); {================} private {=================} imports KermitLineIO from KermitLineIO; imports KermitConnect from KermitConnect; imports IOErrors from IOErrors; imports IO_Unit from IO_Unit; imports IO_Others from IO_Others; exception NotInt; procedure EatSpaces( var S : String ); begin if S<>'' then while (S[1]=' ') and (length(S)>1) do Delete( S, 1, 1); if S=' ' then S := ''; end; function StrToInt( VAR S : String ):integer; var I :integer; done : boolean; begin I := 0; done := false; EatSpaces( S ); if S='' then raise NotInt else begin if not (S[1] in ['0'..'9']) then raise NotInt else repeat if not (S[1] in ['0'..'9']) then done := true else begin I := I*10 + ord(S[1]) - ord('0'); Delete( S, 1, 1); Done := S=''; end; until done; end; StrToInt := I; end; function CtrlChar( S:String ):integer; handler NotInt; begin CtrlChar := -1; exit( CtrlChar ); end; var R : integer; begin if length( S )=0 then R := -1 else if length( S )=1 then R := ord( S[1] ) else if S[1]='#' then begin Delete( S, 1, 1); R := StrToInt( S ); end else if S[1]='^' then if S[2] in ['@'..'^'] then R := ord( Ctl(S[2]) ) else R := -1; CtrlChar := R; end; procedure DoSetRetry( PList : pPListEntry ); var Val : integer; handler NotInt; begin writeln('Number of retries not numeric!'); exit( DoSetRetry ); end; begin Val := StrToInt( PList^.NextPList^.Arg ); if not (Val in [1..30]) then writeln('Illegal number of retries!') else case recast( PList^.Selection, RetryType ) of RetryInitial: MaxTryInit := Val; RetryPacket: MaxTryPack := Val; RetryCommand: MaxTryComm := Val; otherwise: ; end; end; procedure SetPSize( Arg : String; var PSize : integer ); var Val : integer; handler NotInt; begin writeln('Packet length not numeric!'); exit( SetPSize ); end; begin Val := StrToInt( Arg ); if not (Val in [10..94]) then writeln( 'Illegal packet length!') else PSize := Val; end; procedure SetQuote( Arg : String; var Quote : char ); var Val : integer; begin Val := CtrlChar( Arg ); if Val=-1 then writeln( 'Control quote ordinal value is not numeric!' ) else if not ( chr(Val) in OkQuote ) then writeln( 'Illegal quote character') else if chr(Val) in Quotes then writeln( 'Character is already in use as another quote' ) else Quote := chr( Val ); end; procedure SetSOH( Arg : String; var SOH : char ); var Val : integer; begin Val := CtrlChar( Arg ); if Val=-1 then writeln( 'Start-of-packet ordinal value is not numeric!' ) else if not ( Val in [0..31,127,128..159,255]) then writeln ('Start-of-packet character must be a control character!') else SOH := chr( Val ); end; procedure SetTimeOut( Arg : String; var TimeOut : integer ); var Val : integer; handler NotInt; begin writeln('Timeout interval not numeric!'); exit( SetTimeOut ); end; begin if Arg='' then TimeOut := 0 else begin Val := StrToInt( Arg ); if not (Val in [0..94]) then writeln( 'Illegal timeout interval!') else TimeOut := Val; end; end; procedure SetEOL( Arg : String; var EOL : char ); var Val : integer; begin Val := CtrlChar( Arg ); if Val=-1 then writeln( 'End-of-line ordinal value is not numeric!' ) else EOL := chr( Val ); end; procedure SetNPad( Arg : String; var NPad : integer ); var Val : integer; handler NotInt; begin writeln('Padding value not numeric!'); exit( SetNPad ); end; begin Val := StrToInt( Arg ); if not (Val in [0..94]) then writeln( 'Illegal padding value!') else NPad := Val; end; procedure SetPadChar( Arg : String; var PadChar : char ); var Val : integer; begin Val := CtrlChar( Arg ); if Val=-1 then writeln( 'Pad character ordinal value is not numeric!' ) else PadChar := chr( Val ); end; procedure ShowKey( Ch : char ); begin if Land( ord( Ch ), #200 ) <>0 then begin write( 'CTRL-' ); ch := chr( land( ord( ch ), #177 ) ); end; if Ch='' then write('OOPS') else if Ch='' then write('INS') else if Ch=' ' then write('TAB') else if Ch='' then write('HELP') else if Ch='' then write('DEL') else if Ch='' then write('BACKSPACE') else begin if Ch in ['A'..'Z'] then write( 'SHIFT-' ); write( Ch ); end; end; procedure SetEscChar( Arg : String ); var Val : integer; begin if Arg='' then begin IOKeyClear; write( 'Press the key which you want as escape character:' ); while IOCRead( KeyBoard, EscKey ) <> IOEIOC do ; writeln; write( 'Escape character set as: '); ShowKey( EscKey ); writeln; end else begin Val := CtrlChar( Arg ); if Val=-1 then writeln( 'Escape character ordinal value is not numeric!') else EscKey := chr( Val ); end; end; procedure DoSetSend( PList : pPListEntry ); var TempQuote : set of char; begin with PList^ do case recast( Selection, SendRecType ) of SRPacketLength: SetPSize( NextPList^.Arg, SendPSize ); SRCtlQuote: begin TempQuote := Quotes; Quotes := []; { SendQuote may be same as 8-bi or repeat } SetQuote( NextPList^.Arg, SendQuote ); Quotes := TempQuote; end; SRStartOfPacket:SetSOH( NextPList^.Arg, SendSOH ); SRTimeOut: SetTimeOut( NextPList^.Arg, SendTimeOut ); SREndOfLine: SetEOL( NextPList^.Arg, SendEOL ); SRPadding: SetNPad( NextPList^.Arg, SendNPad ); SRPadChar: SetPadChar( NextPList^.Arg, SendPadChar ); otherwise: ; end; end; procedure DoSetReceive( PList : pPListEntry ); begin with PList^ do case recast( Selection, SendRecType ) of SRPacketLength: SetPSize( NextPList^.Arg, RecPSize ); SRCtlQuote: begin Quotes := Quotes - [RecQuote]; SetQuote( NextPList^.Arg, RecQuote ); Quotes := Quotes + [RecQuote]; end; SRStartOfPacket:SetSOH( NextPList^.Arg, RecSOH ); SRTimeOut: SetTimeOut( NextPList^.Arg, RecTimeOut ); otherwise: ; end; end; procedure DoTruncation( PList : pPListEntry ); var NewTrunc : integer; NewTList : TListType; handler NotInt; begin writeln('Truncation value must be an integer!'); exit( DoTruncation ); end; begin with PList^ do if Arg='' then NumTrunc := OldTrunc else begin NewTrunc := 0; EatSpaces( Arg ); while Arg<>'' do begin NewTrunc := NewTrunc + 1; NewTList[NewTrunc] := StrToInt( Arg ); EatSpaces( Arg ); if Arg<>'' then if Arg[1]=',' then Delete( Arg, 1, 1 ); EatSpaces( Arg ); end; NumTrunc := NewTrunc; OldTrunc := NewTrunc; TruncList := NewTList; end; end; procedure DoSetFHeader( PList : pPListEntry ); Const NordWarning = 'Warning: NORD transformation is ON!'; AsLongAs = 'is temporarily active for as long as NORD is ON in any case!'; begin with PList^ do case recast( Selection, FHeaderType ) of FHNord: Nord := recast( NextPList^.Selection, OnOffType) =On; FHNoTrunc: begin OldTrunc := NumTrunc; NumTrunc := 0; if Nord then begin writeln( NordWarning ); writeln(' NO-TRUNCATE ', AsLongAs ); writeln; end; end; FHTrunc: begin DoTruncation( NextPList ); if Nord then begin writeln( NordWarning ); write (' TRUNCATE will not take effect until'); writeln(' NORD is turned OFF!'); writeln; end; end; FHTrans: begin Translate := recast( NextPList^.Selection, TransType ); if Nord then begin writeln( NordWarning ); writeln( ' CONVERT UPPER ', AsLongAs ); writeln; end; end; otherwise: ; end; end; procedure DoSet8Quote( PList : pPListEntry ); var ch : char; begin Quotes := Quotes - [Bit8Quote]; if PList^.Arg='' then Bit8Quote := '&' else begin ch := PList^.Arg[1]; if ch in OkQuote then begin if ch in Quotes then writeln ('Character is already in use as another quote' ) else Bit8Quote := ch; end else writeln('Illegal quote character!'); end; Quotes := Quotes + [Bit8Quote]; end; procedure DoSetRepFix( PList : pPListEntry ); var ch : char; begin Quotes := Quotes - [RepFix]; if PList^.Arg='' then RepFix := '&' else begin ch := PList^.Arg[1]; if ch in OkQuote then begin if ch in Quotes then writeln ('Character is already in use as another quote' ) else RepFix := ch; end else writeln('Illegal quote character!'); end; Quotes := Quotes + [RepFix]; end; procedure SetCommand( PList : pPListEntry ); var SetParm : SetCommType; begin SetParm := recast( PList^.Selection, SetCommType ); PList := PList^.NextPList; case SetParm of SetStop: begin StopBits := recast( PList^.Selection, StopType ); RefreshStopBits; end; SetParity: begin Parity := recast( PList^.Selection, ParityType ); RefreshParity; end; SetBaud: begin Baud := recast( PList^.Selection, SpeedType); RefreshBaud; end; SetFileWarning: begin FileWarning := recast( PList^.Selection, OnOffType ) = On; end; SetLog: begin FileSave := recast( PList^.Selection, OnOffType ) = On; end; SetLogFile: begin SetSaveFile( PList^.Arg ); end; SetDebugging: begin Debug := recast( PList^.Selection, OnOffType ) = On; end; SetSend: DoSetSend( PList ); SetReceive: DoSetReceive( PList ); SetFileHeader: DoSetFHeader( PList ); Set8BitQuote: DoSet8Quote( PList ); SetUse8BitQuote: Use8Quote := recast( PList^.Selection, OnOffType ) = On; SetRepFix: DoSetRepFix( PList ); SetUseRepFix: UseRepFix := recast( PList^.Selection, OnOffType ) = On; SetRetry: DoSetRetry( PList ); SetBreakTime: writeln('Send break is not implemented!'); SetEscape: SetEscChar( PList^.Arg ); otherwise: writeln('Bad SET alternative: ', ord( SetParm ) ); end; end; procedure ShowOnOff( OnValue : boolean ); begin if OnValue then write('ON') else write('OFF'); end; procedure ShowStop; begin if StopBits=SyncrCmd then writeln( 'SYNCHRONOUS mode, no stop bits' ) else begin write('Number of STOP-BITS = '); case StopBits of Stop1Cmd: writeln('1'); Stop1x5Cmd: writeln('1.5'); Stop2Cmd: writeln('2'); otherwise: writeln('invalid, code: ',ord(StopBits)); end; end; end; procedure ShowParity; begin write( 'PARITY check/generation = ' ); case Parity of NoKParity: writeln('NONE'); EvenKParity: writeln('EVEN'); OddKParity: writeln('ODD'); MarkKParity: writeln('MARK (1)'); SpaceKParity: writeln('SPACE (0)'); otherwise: writeln('invalid, code: ',ord(Parity)); end; end; procedure ShowBaud; begin write( 'BAUDrate = ' ); case Baud of SP110: write('110'); SP150: write('150'); SP300: write('300'); SP600: write('600'); SP1200: write('1200'); SP2400: write('2400'); SP4800: write('4800'); SP9600: write('9600'); otherwise: writeln('invalid, code: ',ord(Baud)); end; if Baud in [SP110..SP9600] then writeln(' bps'); end; procedure ShowFWarning; begin write( 'FILE-WARNING = '); ShowOnOff( FileWarning ); writeln; end; procedure ShowDebug; begin write( 'DEBUG output = '); ShowOnOff( Debug ); writeln; end; procedure ShowUse8Quote; begin write( 'USE-8-BIT-QUOTE = '); if Use8Quote then write('AUTO') else write('OFF'); writeln; end; procedure ShowUseRepFix; begin write( 'USE-REPEAT-PREFIX = '); if UseRepFix then write('AUTO') else write('OFF'); writeln; end; procedure ShowLog; begin write( 'LOG session to file = ' ); ShowOnOff( FileSave ); writeln; end; procedure ShowLFile; begin if SaveFile='' then writeln('No log file active') else writeln('LOG-FILE = ',SaveFile); end; procedure DisplayChar( Ch : Char ); var Ch1 : char; begin Ch1 := Chr( LAnd( Ord( Ch ), #177 ) ); if ch1<' ' then write( 'Ctrl-', Ctl( Ch1 ) ) else if ord(Ch1)=177 then write( 'DEL' ) else write('''',Ch1,''''); if Ch<>Ch1 then write(' (Hi bit=1)'); end; procedure Show8Quote; begin write('8-BIT-QUOTE = '); DisplayChar( Bit8Quote ); writeln; end; procedure ShowRepFix; begin write('REPEAT-PREFIX = '); DisplayChar( RepFix ); writeln; end; procedure ShowEscChar; begin write('ESCAPE-CHARACTER = '); ShowKey( EscKey ); writeln; end; procedure ShowPSize( PSize : integer ); begin writeln(' max. PACKET-LENGTH = ', PSize:2 ); end; procedure ShowTOut( TimeOut : integer ); begin writeln(' TIME-OUT after ',TimeOut:2,' seconds'); end; procedure ShowQuote( Quote : char ); begin writeln(' control QUOTE = ''',Quote,''''); end; procedure ShowSOH( SOH : char ); begin write(' START-OF-PACKET = '); DisplayChar( SOH ); writeln; end; procedure ShowEOL( EOL : char ); begin write(' END-OF-LINE = '); DisplayChar( EOL ); writeln; end; procedure ShowPad( Padding : integer ); begin writeln(' PADDING between packets = ', Padding:2,' characters'); end; procedure ShowPChar( PadChar : char ); begin write(' PADCHAR = '); DisplayChar( PadChar ); writeln; end; procedure ShowSend; begin writeln( 'SEND parameters:'); ShowPSize( SendPSize ); ShowTOut( SendTimeOut ); ShowQuote( SendQuote ); ShowSOH( SendSOH ); ShowEOL( SendEOL ); ShowPad( SendNPad ); ShowPChar( SendPadChar ); end; procedure ShowReceive; begin writeln( 'RECEIVE parameters:'); ShowPSize( RecPSize ); ShowTOut( RecTimeOut ); ShowQuote( RecQuote ); ShowSOH( RecSOH ); end; procedure ShowFHeader; var I : integer; begin writeln( 'FILE-HEADER transformations: '); write( ' NORD transformation = '); if Nord then begin writeln( ' ON'); writeln( ' (temporary NO-TRUNCATE and CONVERT UPPER)'); end else begin writeln( ' OFF'); if NumTrunc=0 then writeln(' NO-TRUNCATE of file name') else begin write(' TRUNCATE file name '); write( TruncList[1]:1 ); for i := 2 to NumTrunc do write( ',', TruncList[I]:1 ); writeln; end; if Translate=TransOff then writeln(' CONVERT OFF') else begin write(' CONVERT file name into '); case Translate of TransUpper: writeln('UPPER case'); TransLower: writeln('LOWER case'); otherwise: writeln(''); end; end; end; end; procedure ShowRetry; begin writeln( 'RETRY limits:'); writeln( ' INITIAL-CONNECTION = ',MaxTryInit:2); writeln( ' PACKET = ',MaxTryPack:2); writeln( ' COMMANDS = ',MaxTryComm:2); end; procedure ShowCommand( PList : pPListEntry ); var SetParm : SetCommType; begin SetParm := recast( PList^.Selection, SetCommType ); PList := PList^.NextPList; writeln; case SetParm of SetStop: ShowStop; SetParity: ShowParity; SetBaud: ShowBaud; SetFileWarning: ShowFWarning; SetLog: ShowLog; SetLogFile: ShowLFile; SetDebugging: ShowDebug; SetSend: ShowSend; SetReceive: ShowReceive; SetFileHeader: ShowFHeader; Set8BitQuote: Show8Quote; SetUse8BitQuote: ShowUse8Quote; SetRepFix: ShowRepFix; SetUseRepFix: ShowUseRepFix; SetRetry: ShowRetry; SetBreakTime: writeln('Send break is not implemented!'); SetEscape: ShowEscChar; SetNotFound: begin ShowStop; ShowParity; ShowBaud; ShowFWarning; ShowLog; ShowLFile; ShowDebug; ShowSend; ShowReceive; ShowFHeader; Show8Quote; ShowUse8Quote; ShowRepFix; ShowUseRepFix; ShowRetry; ShowEscChar; end; otherwise: writeln('Bad SHOW alternative: ', ord( SetParm ) ); end; writeln; end; procedure StatusCommand; begin end; procedure SetInitPars( var Pack : Packet ); { Build SendInit packet } var PackLen : integer; begin with Pack do begin adjust( Data, 100 ); data[1] := ToChar(chr(RecPSize )); { Max. packet length I handle } data[2] := ToChar(chr(RecTimeOut)); { When I want to be timed out } data[3] := ToChar(chr(RecNPad )); { How much padding I need } data[4] := ctl (chr(RecPadChar)); { My padding character } data[5] := ToChar(chr(RecEOL) ); { End-of-line I want } data[6] := RecQuote ; { control-quote char I want } data[8] := '1'; { Only 1-char checksum } if (not Use8Quote) or (Parity=NoKParity) then data[7] := 'N' { No need to use 8-bit quote } else data[7] := Bit8Quote ; { 8-bit-quote char I want } if not UseRepFix then data[9] := ' ' { Won't use repeat prefix } else data[9] := RepFix; { Repeat prefix I want } PackLen := 9; if Data[9]=' ' then begin PackLen := 8; if Data[8]='1' then begin PackLen := 7; if Data[7] in [' ','N'] then begin PackLen := 6; end; end; end; Count := ToChar ( chr( PackLen + 3 ) ); adjust( Data, PackLen + 1 ); ptype:= PackToCh( SInitPack ); end; end; procedure ReadPars ( VAR Pack : Packet ); { Set parameters according to Pack (Which is SendInit or Acknowledge packet) and build the corresponding Acknowledge packet } VAR i,PackLen : integer; begin with Pack do if not ( ChToPack(Ptype) IN [SInitPack,ACKPack] ) then begin CurrState := AbortAll; LocalError ( '?Attempted to read parameters from non-send-init packet' ); end else begin adjust( Data, 100 ); PackLen := ord( UnChar( count ) ) - 3; for i := PackLen + 1 to MaxString do Data[i] := ' '; { Don't have to agree on the following parameters } if UnChar( Data[1] ) = chr(0) then SendPSize := 96 else SendPSize := ord ( UnChar ( Data[1] ) ); data[1] := ToChar( chr( RecPSize ) ); SendTimeOut := ord ( UnChar ( Data[2] ) ); data[2] := ToChar( chr(RecTimeOut) ); { SendNPad := ord ( UnChar ( Data[3] ) ); } data[3] := ToChar( chr(RecNPad) ); if UnChar(Data[4])=chr(0) then SendPadChar := chr(0) else SendPadChar := Ctl ( Data[4] ) ; data[4] := ctl( RecPadChar ); if UnChar(Data[5])=chr(0) then SendEOL := chr(13) else SendEOL := UnChar ( Data[5] ) ; data[5] := ToChar( RecEOL ); if UnChar(Data[5])=chr(0) then SendQuote := '#' else SendQuote := Data[6] ; data[6] := RecQuote; { On this one, we have to agree, else there will be no 8-bit quoting } if not ( (Data[7] in (OkQuote + ['Y'])) and Use8Quote ) then begin { Default, if not acceptable 8-bit quote character } NowUse8Quote := FALSE; Data[7] := 'N'; { I agree NOT to do 8-bit quoting } end else begin NowUse8Quote := TRUE; { Only if this Kermit is sending: } if Data[7]<>'Y' then { 'Y' means my request to use } Bit8Quote := Data[7]; { 8-bit quoting is accepted } { Else: use proposed quote char } Data[7] := 'Y'; { I agree to do 8-bit quoting } end; { Checksum type : Default is 1-character checksum } Data[8] := '1'; { Not supporting 2 or 3-character checksums yet } { Repeat prefix : have to agree, else no repeat prefixing } if not ( (Data[9] in OkQuote) and UseRepFix ) then begin { Default, if not acceptable repeat prefix } NowUseRepFix := FALSE; Data[9] := ' '; { I won't do repeat prefixing } end else begin NowUseRepFix := TRUE; { repeat prefix is accepted } RepFix := Data[9]; { agree by returning same value } end; if (Bit8Quote=SendQuote) and NowUse8Quote then begin LocalError('?Cant send same 8-bit quote and control quote'); LocalError(' Denies 8-bit quoting!' ); Data[7] := ' '; NowUse8Quote := false; end; if (RepFix=SendQuote) and NowUseRepFix then begin LocalError('?Cant send same repeat prefix and control quote'); LocalError(' Denies repeat prefixing!'); Data[9] := ' '; NowUseRepFix := false; end; if (RepFix=Bit8Quote) and NowUseRepFix and NowUse8Quote then begin LocalError('?Cant send same repeat prefix and 8-bit quote'); LocalError(' Denies repeat prefixing!'); Data[9] := ' '; NowUseRepFix := false; end; PackLen := 9; if Data[9]=' ' then begin PackLen := 8; if Data[8]='1' then begin PackLen := 7; if Data[7] in [' ','N'] then begin PackLen := 6; end; end; end; Count := ToChar ( chr( PackLen + 3 ) ); adjust( Data, PackLen + 1 ); Ptype := PackToCh ( ACKPack ); end; end; procedure InitParameters; { Abstract: This procedure initializes various global Kermit variables: "Constants", Transmission parameters, Kermit state variables. NB! This procedure is to be called only ONCE during the run! } begin SaveFile := ''; LegalPackets := ['D','Y','N','S','B','F','Z','E','R','C','G','X']; { What I expect he will want } SendSOH := chr(1); SendPSize := 94; { - max. packet size } SendTimeOut := 5; { - 5 seconds timeout } SendNPad := 0; { - no padding } SendPadChar := chr(0); { - ASCII NUL as padchar } SendEOL := chr(13); { - carriage return as eol } SendQuote := '#'; { - sharp as control quote } { What I want from him (parameters which will be used when I send-initiate) } RecSOH := chr(1); RecPSize := 59; { for a Perq with standard buffersize } RecTimeOut := 5; { time-out I want } RecNPad := 0; { Need no padding } RecPadChar := chr(0); RecEOL := chr(13); { Standard End-Of-Line } RecQuote := '#'; { Standard control quote } { What to do about 8-bit quoting } Use8Quote := FALSE; { 8-bit quoting disabled } NowUse8Quote := Use8Quote; Bit8Quote := '&'; UseRepFix := FALSE; { Repeat prefixing disable } NowUseRepFix := UseRepFix; RepFix := '~'; LongWait := 4; { Multiplication factor for TimeOut } { during SendFileHeader (to allow for opening file) } LocalKermit := FALSE; { This frog is born a remote kermit } DisableTimOut := FALSE; { Allow partner to enable timeout } FileWarning := TRUE; { Do not write over existing files } FileSave := FALSE; Debug := FALSE; Nord := FALSE; { Not NORD transformation } TruncList[1] := 8; TruncList[2] := 3; NumTrunc := 2; { Truncate file name 8+3 } OldTrunc := NumTrunc; Translate := TransUpper; { Translate file names to upper case } CurrState := Complete; { Avoid starting out in a bad state } N := 0; { Start out with packet zero } NumTry := 0; OldTry := 0; MaxTryInit := 8; { Retries before giving up } MaxTryPack := 5; MaxTryComm := 3; EscKey := chr( ord(']')+128 ); { Control - ] } { Then some useful character sets : NB! they are recomputed by ReadPars } { This is the set which the set of control characters is mapped into by the Ctl function } CtlMapping := [ ctl( chr( 0) )..ctl( chr( 31) ), ctl( chr(127) ), ctl( chr(128) )..ctl( chr(31+128) ), ctl( chr(255) )]; { Valid quote characters, i.e all printable characters which Ctl does not map a control character into } OkQuote := ['!'..'~'] - CtlMapping; Quotes := [RecQuote, Bit8Quote, RepFix]; end; {=============================================================================} procedure CleanupParameters; begin SetSaveFile( '' ); { force close of previous SaveFile } end.