! ********************************************************************** ! ! ! ! Program: SNDRCV ! ! Date: April 27, 1984 ! ! Author: Robin Miller ! ! ! ! Description: ! ! This program is used to transfer ASCII files with the RSXNET or ! ! VAXNET programs when the normal FORTRAN SNDRCV program is unavailable. ! ! ! ! Restrictions/Notes: ! ! o Reads do not timeout. You must CTRL/C to abort SNDRCV. ! ! ! ! o Teco looses characters if line > 80 and 9600 baud. ! ! To avoid this on VMS, enable the alternate typeahead buffer. ! ! ! ! o If the file contains tabs, formfeeds, lowercase, or long ! ! lines, set the appropriate terminal settings. If this is not ! ! done, tabs are converted to spaces, formfeeds are converted ! ! to line feeds, lowercase may be converted to uppercase, and ! ! long lines may get wrapped by the terminal driver. ! ! ! ! RT11: .SET TT: WIDTH=255. .SET TT: TAB ! ! .SET TT: FORM ! ! RSX11M: >SET /BUF=TI:255. >SET /HHT=TI: ! ! >SET /FORMFEED=TI: >SET /LOWER=TI: ! ! VMS: $ SET TERMINAL/WIDTH=255/TAB/FORMFEED/LOWERCASE ! ! ! ! o If you abort RSXNET/VAXNET while transferring a file, the ! ! CANcel code (^X) sent to the SNDRCV program gets interpreted ! ! by the terminal driver on RSX-11M and VMS to clear the type- ! ! ahead buffer. Thus, you must type CTRL/C to abort SNDRCV. ! ! ! ! o The file to be transmitted cannot have control characters in ! ! it that the terminal driver interprets. The typical control ! ! characters are CTRL/C, CTRL/Q, CTRL/S, and CTRL/X. ! ! On RSX-11M and VMS systems, set passall mode to disable this ! ! interprtation. I don't know if this can be done from RT11. ! ! ! ! RT11: Can this be done ??? ! ! RSX11M: >SET /RPA=TI: ! ! VMS: $ SET TERMINAL/PASSALL ! ! ! ! ********************************************************************** ! ! ! ! Control codes used: ! ! ETX = 3 Control/C aborts TECO. ^C ! ! EOT = 4 End Of Transmission. ^D ! ! ENQ = 5 Enquire (same as NAK). ^E ! ! ACK = 6 Acknowlegment. ^F ! ! CR = 13 Carriage Return. ^M ! ! NAK = 21 Negative Acknowlegment ^U ! ! SYN = 22 Synchronize. ^V ! ! EOF = 26 End of file. ^Z ! ! ! ! --------------------------------------------- ! ! ! ! The format of the data records: ! ! ! ! bbbbcccrrr...rrr ! ! ! ! Where: b = bytecount, ! ! c = checksum, ! ! r = record (data bytes). ! ! ! ! --------------------------------------------- ! ! ! ! Q-register Usage (%=numeric, $=text): ! ! ! ! %0 = the last input character. ! ! %1 = the data record byte count. ! ! %2 = the data record checksum. ! ! %3 = the calculated checksum. ! ! %4 = the total record count. ! ! %5 = the total byte count. ! ! %6 = the current retry count. ! ! %7 = the maximum retry limit. ! ! %d = the retry exceeded status. ! ! %g = the field width used with $G. ! ! %h = the number to format by $G macro. ! ! %i = scratch register for all macros. ! ! ! ! $a = routine to read a line. ! ! $b = routine to wait until idle. ! ! $c = routine to send a control byte. ! ! $d = routine to send a NAK to host. ! ! $e = routine to read a line from file. ! ! $f = routine to send an ACKnowlegment. ! ! $g = routine to format # with width. ! ! $i = the main line routine. ! ! $r = routine to receive a file. ! ! $s = routine to send a file. ! ! $z = last buffer received/transmitted. ! ! ! ! --------------------------------------------- ! ! ! ! Macro to read input until is detected. ! ! The buffer is cleared before reading and the ! ! pointer is left at the beginning of the ! ! buffer when we are finished. If CTRL/C was ! ! typed, we insert CAN to abort transmission. ! ! ! @^ua_hk < ^Tu0 et; q0-13"e ^T^[ 0; | q0@i// ' > et"g hk 24@i// ' 0j_ ! ! ! Macro used to wait until we are idle. This is ! ! used after a transmission error to discard ! ! any remaining characters coming in. ! ! ! @^ub_et#32et < ^T:; > et-32et_ ! ! ! Macro to send a control code & to the ! ! host. Also saves last code in Q-register C. ! ! ! @^uc_uc qc^t 13^t_ ! ! ! Macro to adjust the retry limit and send a ! ! NAK to the host if not exceeded, else send a ! ! CAN to abort the transmission. Passes back ! ! status in %d (-1/0 = continue/abort). ! ! ! @^ud_mb -1%6^[ q6"g -1ud 21mc | 0ud 24^T @^a%Retry limit exceeded, aborting transmission ...% 13^t ' qd_ ! ! ! Macro to read a line from the input file. The ! ! buffer is cleared, a line is read, and a ! ! is inserted if the ^E flag is true. The CR/LF ! ! appended to each record by Teco are deleted. ! ! ! @^ue_hk 1:a ^E"t zj 12@i// ' 0j @:fs/ //^[ 0j_ ! ! ! Macro to send an ACKnowlegment to the host. ! ! The retry count is reset to the retry limit. ! ! ! @^uf_6mc q7u6_ ! ! ! Macro to format a number with a width. The ! ! number is right justified padded with spaces. ! ! The field width is the input parameter. ! ! ! @^ug_uh ug qh\^[ ^sc -^sui qg-qi<32@i//> qic_ ! ! ! Main line macro ! ! ! @^ui_ @^a%SNDRCV.TEC Version 1.1 started ... Type CTRL/C to abort ... % ! Image mode typeout / read lower case / read with no echo ! 0,1#4#8#16#32768et 0u4 0u5 ! Clear record and byte counts. ! 10u7 q7u6 ! Setup the retry limit & retry count. ! hk 0,16et @i% SNDRCV Status Report: Total records: % 6,q4mg @i%, total bytes: % 6,q5mg @i% % ht hk ex_ ! ! ! Macro to receive a file from the host. ! ! ! @^ur_mf ! ACK the direction (TOREM). ! !r.read! ma ! Read the file name to write. ! 0a-21"e mf @o!r.read! ' ! Resend the last control code. ! 0a-24"e @o!r.end! ' ! Check for CANcel transmission. ! !r.open! ! Open the output file. ! hxz @:ew/^Eqz/"u mb 21^T @^a%Unable to open file % :gz 13^T @o!r.read! ' mf ! ACK the output file name. ! !r.loop! ma ! Read the next data record. ! 0a-5"e qcmc @o!r.loop! ' ! ENQ - resend last control code. ! 0a-21"e qcmc @o!r.loop! ' ! NAK - resend last control code. ! 0a-24"e ef @o!r.end! ' ! CAN - close file and exit. ! 0a-26"e ! EOF - end of current file. ! ef mf ! Close file and send ACK. ! ma ! Wait for the next control byte. ! 0a-4"e ! EOT - end of this transmission. ! mf @o!r.end! ! Send an ACK and finish up. ! | @o!r.open! ! Else presume the next file. ! ' ' z-7"l md"t @o!r.loop! | @o!r.end! ' ' ! NAK, not enough bytes received. ! hxz ! Save the last buffer received. ! ! Data record format: bbbbcccrrr...rrr ! 4c @i% % 3c @i% % ! Separate byte count & checksum. ! ! Q1 = the byte count, Q2 = the checksum, Q3 = calculated checksum. ! 0j @::s/^Es/^[ \u1^[ ! Skip spaces and pick up byte count. ! l @::s/^Es/^[ \u2^[ ! Skip spaces and pick up checksum. ! l b,.k ! Delete the byte count & checksum. ! q1-z"n md"t @o!r.loop! | @o!r.end! '' ! NAK, byte count & data count wrong. ! 0u3 q1<0a%3^[ c> ! Calculate the received data checksum ! ^o q3&777u3 ^d ! Clear the high bits of the checksum. ! q2-q3"n md"t @o!r.loop! | @o!r.end!'' ! NAK, the checksum is wrong. ! %4^[ q1%5^[ ! Adjust record and byte counts. ! zj @i% % hpw mf @o!r.loop! ' ! Write the record and send an ACK. ! !r.end! ef_ ! ! ! Macro to send a file to the host. ! ! ! @^us_mf ! ACK the direction (TOVAX). ! !s.read! ma ! Read the file name to read. ! 0a-24"e @o!s.end! ' ! CAN, cancel the transmission. ! ! Open the input file. ! hxz @:er/^Eqz/"u mb 21^T @^a%Unable to open file % :gz 13^T @o!s.read! ' mf ! ACK the input file name. ! ! Else, send NAK & wait for SYN byte. ! mf ! ACK the SYN byte we received. ! !s.loop! ! Data record format: bbbbcccrrr...rrr ! me ! Read a line from the input file. ! ^N"t @o!s.eof! ' ! EOF, do end of file processing. ! <.-z; 0a-13"e d | c '>0j ! Delete any embedded carriage returns. ! zu1 ! Save the byte count in Q-reg. 1. ! 0u2 z<0a%2^[ c> 0j ^o q2&777u2 ^d ! Calculate the checksum. ! 4,q1mg 3,q2mg ! Prepare the ASCII byte & checksum. ! zj 13@i// ! Terminate the record with a . ! hxz hk ! Save the buffer to transmit to Host. ! !s.send! :gz ! Send this data record to the host. ! !s.wait! ma ! Wait for the response. ! 0a-6"e %4^[ q1%5^[ @o!s.loop! ' ! ACK, adjust counts and send the next. ! 0a-5"e @o!s.send! ' ! ENQ, resend the last data record. ! 0a-21"e @o!s.send! ' ! NAK, resend the last data record. ! 0a-24"e @o!s.eof! ' ! CAN, cancel the transmission. ! 5mc @o!s.wait! ! Send ENQ, and wait for the response. ! !s.eof! 26mc ! Tell host this is end of file. ! ! Wait for ACK to the EOF message. ! 4mc ! Tell host end of transmission. ! ! Wait for ACK to the EOT message. ! !s.end!_ ! ! ! Execute the main line macro. ! ! ! @ei// mi ex