;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 ---