;D:KPRO.ACT›; KERMIT protocol section››; RInit()›;›; Receive Initialization››BYTE FUNC RINIT(STRING FSPEC)› INT LEN, NUM, T› IF DEBUG = 1 THEN› PRINTE("RInit")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI›› IF FSPEC(0) > 0 THEN› FOR T = 1 TO FSPEC(0)› DO› PACKET(T-1) = FSPEC(T)› OD› SPACK('R, 0, T-1, PACKET)› FI›› T = RPACK(@LEN, @NUM, PACKET)› IF T = 'S THEN› RPAR(PACKET)› SPAR(PACKET)› SPACK('Y, N, 6, PACKET)› OLDTRY = NUMTRY› NUMTRY = 0› N = (N + 1) MOD 64› RETURN('F)›› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI››; RFile()›;›; Receive File Header››BYTE FUNC RFile()› INT LEN, NUM, T› BYTE W› IF DEBUG = 1 THEN› PRINTF("RFile%E")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI›› T = RPACK(@LEN, @NUM, PACKET+1)› PACKET(0) = LEN› IF T = 'S THEN› OLDTRY ==+ 1› IF OLDTRY > MAXTRY THEN RETURN('A) FI› IF (N = 0 AND NUM = 63)› OR (N <> 0 AND NUM = N-1)› THEN› SPACK('Y, NUM, 0, 0)› NUMTRY = 0› RETURN(STATE)› ELSE› RETURN('A)› FI›› ELSEIF T = 'F THEN› IF NUM <> N THEN RETURN('A) FI› STOPR()› NORMALIZE(PACKET)› ERRORNUM = 0› OPEN(3, PACKET, 8, 0)› STARTR()› IF ERRORNUM >= 128› THEN› PRINTF("Couldn't create %S; error %D%E",› PACKET, ERRORNUM)› RETURN('A)› FI› PRINTF("Receiving %S%E",› PACKET)› SPACK('Y, N, 0, 0)› OLDTRY = NUMTRY› NUMTRY = 0› N = (N+1) MOD 64› RETURN('D)›› ELSEIF T = 'B THEN› IF NUM <> N THEN RETURN('A) FI› SPACK('Y, N, 0, 0)› ;WAIT 1 SECOND FOR ACK TO DRAIN› W = RTCLOCK+60› WHILE W <> RTCLOCK DO OD› RETURN('C)›› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI››; RData()›;›; Receive Data››BYTE FUNC RData()› INT NUM, LEN, T› IF DEBUG = 1 THEN› PRINTF("RData%E")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI›› T = RPACK(@LEN, @NUM, PACKET)› IF T = 'D THEN› IF NUM <> N› THEN› OLDTRY ==+ 1› IF OLDTRY > MAXTRY THEN RETURN('A) FI› IF (N = 0 AND NUM = 63)› OR (N <> 0 AND NUM = N-1)› THEN› SPACK('Y, NUM, 0, 0)› NUMTRY = 0› RETURN(STATE)› ELSE› RETURN('A)› FI› FI›› BUFEMP(PACKET, LEN)› SPACK('Y, N, 0, 0)› OLDTRY = NUMTRY› NUMTRY = 0› N = (N+1) MOD 64› RETURN('D)›› ELSEIF T = 'F THEN› OLDTRY ==+ 1› IF OLDTRY > MAXTRY THEN› RETURN('A)› FI› IF (N = 0 AND NUM = 63)› OR (N <> 0 AND NUM = N-1)› THEN› SPACK('Y, NUM, 0, 0)› NUMTRY = 0› RETURN(STATE)› ELSE› RETURN('A)› FI›› ELSEIF T = 'Z THEN› IF NUM <> N THEN RETURN('A) FI› IF DEBUG = 1 THEN› PRINTE("End-of-File")› FI› STOPR()› CLOSE(3)› STARTR()› SPACK('Y, N, 0, 0)› N = (N+1) MOD 64› RETURN('F)›› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI ››; RecSw()›;›; This is the state table switcher›; for receiving files››PROC RECSW()› STRING FSPEC(20)› INT NUM, LEN, T›› STARTR()› PUT(125)› PRINTE("Type the file to receive, or just")› PRINTE("RETURN if the other computer is not")› PRINTE("in Server mode.")› PUTE()› PRINT("File Spec -> ")› INPUTMD(0, FSPEC, 19)›› PRINTE("Receiving File(s)")› PRINTE("type any key to abort")›› STATE = 'R› N = 0› NUMTRY = 0› DO› IF CH <> 255 THEN› PRINTE("User Aborting")› CH = 255› EXIT› FI› IF STATE = 'D THEN STATE = RDATA()› ELSEIF STATE = 'F THEN STATE = RFILE()› ELSEIF STATE = 'R THEN STATE = RINIT(FSPEC)› ELSEIF STATE = 'A THEN› PRINTE("Aborting")› EXIT› ELSE› EXIT› FI› OD› STOPR()› Close(3)› RETURN››; SInit›;›; Send Initiate:›; Send my parameters, get other›; side's back››BYTE FUNC SINIT()› INT NUM, LEN› BYTE T›› IF DEBUG <> 0 THEN› PRINTF("SInit%E")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI› SPAR(PACKET)› IF DEBUG <> 0 THEN› PRINTF("n = %D%E", N)› FI› ;Clear out any junk in the input› ;buffer› WHILE NCIB() > 0 DO GETD(2) OD›› SPACK('S, N, 6, PACKET)› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N THEN RETURN(STATE)› ELSEIF T = 'Y THEN› IF N <> NUM THEN› RETURN(STATE)› FI› RPAR(RECPKT)› IF EOL = 0 THEN› EOL = 13› FI› IF QUOTE = 0 THEN› QUOTE = '#› FI› NUMTRY = 0› N = (N + 1) MOD 64› IF FILNAM = 0 THEN› RETURN('A)› FI› ;Open a file› STOPR()› ERRORNUM = 0› Close(3)› OPEN(3, FILNAM, 4, 0)› STARTR()› IF ERRORNUM >= 128 THEN› PRINTF("Error %D; couldn't read %S",› ERRORNUM, FILNAM)› RETURN('A)› FI› PRINTF("Sending %S%E", FILNAM)› RETURN('F)›› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI› ›; SFile›;›; Send File Header››BYTE FUNC SFILE()› INT NUM, LEN, T, I› STRING STFNAME(20)› IF DEBUG = 1 THEN› PRINTE("SFile")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN RETURN('A) FI›› I = 1 ;STANDARD FILE NAMES DON'T HAVE D1:› WHILE FILNAM(I) <> ': DO I ==+ 1 OD› LEN = FILNAM(0)-I› FOR T = 0 TO LEN-1 DO› STFNAME(T) = FILNAM(I+T+1)› OD›› SPACK('F, N, LEN, STFNAME)› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N OR T = 'Y THEN› IF T = 'N› THEN› NUM ==- 1› IF NUM < 0 THEN NUM = 63 FI› FI›› IF N <> NUM› THEN› RETURN(STATE)› FI› NUMTRY = 0› N = (N + 1) MOD 64› SIZE = BUFILL(PACKET)› IF SIZE = EOF THEN› RETURN('Z)› ELSE› RETURN('D)› FI› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI››; SData›;›; Send File Data››BYTE FUNC SData()› INT NUM, LEN, T›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI› SPACK('D, N, SIZE, PACKET)› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N OR T = 'Y THEN› IF T = 'N› THEN› NUM ==- 1› IF NUM < 0 THEN NUM = 63 FI› FI›› IF N <> NUM› THEN› RETURN(STATE)› FI› NUMTRY = 0› N = (N + 1) MOD 64› SIZE = BUFILL(PACKET)› IF SIZE = EOF THEN› RETURN('Z)› FI› RETURN('D)› ELSEIF T = FALSE THEN› RETURN(STATE)› ELSE RETURN('A)› FI››; SEOF()›;›; Send End-Of-File››BYTE FUNC SEOF()› INT NUM, LEN, T›› IF DEBUG = 1 THEN› PRINTF("SEOF%E")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI› SPACK('Z, N, 0, PACKET)›› IF DEBUG = 1 THEN› PRINT("SEOF1 ")› FI›› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N OR T = 'Y THEN› IF T = 'N› THEN› NUM ==- 1› IF NUM < 0 THEN NUM = 63 FI› IF N <> NUM THEN RETURN(STATE) FI› FI›› IF DEBUG = 1 THEN› PRINTF("SEOF2 ")› FI› IF N <> NUM› THEN› RETURN(STATE)› FI› NUMTRY = 0› N = (N + 1) MOD 64› IF DEBUG = 1 THEN› PRINTF("Closing %S%E", FILNAM)› FI› STOPR()› IF DEBUG = 1 THEN› PRINTF("getting next file%E")› FI› DO› FILNAM = GETNEXT(6)› IF FILNAM = 0 THEN EXIT FI› CLOSE(3)› ERRORNUM = 0› OPEN(3,FILNAM, 4, 0)› IF ERRORNUM < 128 THEN› EXIT› ELSE› PRINTF("Can't read %S; Error %D%E",› FILNAM, ERRORNUM)› FI› OD› › STARTR()› IF FILNAM = 0 THEN› RETURN('B)› FI› PRINTE(FILNAM)› RETURN('F)› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI››; SBreak()›;›; Send Break (End-of-Text)››BYTE FUNC SBreak()› INT NUM, LEN, T›› IF DEBUG = 1 THEN› PRINTF("SBreak%E")› FI›› NUMTRY ==+ 1› IF NUMTRY > MAXTRY THEN› RETURN('A)› FI› SPACK('B, N, 0, PACKET)›› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N OR T = 'Y THEN› IF T = 'N› THEN› NUM ==- 1› IF NUM < 0 THEN NUM = 63 FI› IF N <> NUM THEN› RETURN(STATE)› FI› FI›› IF N <> NUM› THEN› RETURN(STATE)› FI›› NUMTRY = 0› N = (N + 1) MOD 64› RETURN('C)›› ELSEIF T = FALSE THEN RETURN(STATE)› ELSE RETURN('A)› FI››;MAIN SEND FILE ROUTINE››PROC SENDSW()› STRING FSpec(20)› DO› Print("File spec -> ")› INPUTMD(0, FSPEC, 19)› IF FSPEC(0) = 0 THEN RETURN FI› Normalize(FSPEC)› FILNAM = GETFIRST(6, FSPEC)› IF FILNAM = 0 THEN› PRINTE("Invalid file name")› FI› UNTIL› FILNAM <> 0› OD› Put(125)› PRINTF("Sending %S%E", FSpec)› PRINTE("Type any key to abort.")› STARTR()›› STATE = 'S› N = 0› NUMTRY = 0› DO› IF CH <> 255 THEN› PRINTE("User Abort")› CH = 255› EXIT› FI› IF STATE = 'D THEN STATE = SDATA()› ELSEIF STATE = 'F THEN STATE = SFILE()› ELSEIF STATE = 'Z THEN STATE = SEOF()› ELSEIF STATE = 'S THEN STATE = SINIT()› ELSEIF STATE = 'B THEN STATE = SBREAK()› ELSEIF STATE = 'A THEN› PRINTE("Aborting")› EXIT› ELSE EXIT› FI› OD› STOPR()› CLOSE(3)› RETURN››;Tell Server to quit››PROC Finish()› INT NUM, LEN, T›› IF DEBUG = 1 THEN› PRINTE("Finish")› FI› STARTR()› FOR NUMTRY = 0 TO 3› DO› PACKET(0) = 'F› SPACK('G, 0, 1, PACKET)›› T = RPACK(@LEN, @NUM, RECPKT)› IF T = 'N OR T = 'Y THEN› IF T = 'N› THEN› NUM ==- 1› IF NUM < 0 THEN NUM = 63 FI› IF 0 <> NUM THEN› EXIT› FI› FI›› IF 0 = NUM› THEN› STOPR()› RETURN› FI› FI› OD›› STOPR()› PRINTE("Server didn't respond")› RETURN› ›;--------------------------›;Kermit Protocol code ends here›;--------------------------››; --- END OF D:KPRO.ACT ---›