home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
d
/
vmeker.sou
< prev
Wrap
Text File
|
1988-08-16
|
340KB
|
9,378 lines
VME KERMIT VERSION 1.01
=======================
The source files contained in this file are:
KERMIT : SCL interface procedure
KMT_DATA_MODULE : S3 modules
KMT_DH_MODULE
KMT_EH_MODULE
KMT_FH_MODULE
KMT_MAIN_MODULE
KMT_PH_MODULE
KMT_PP_MODULE
KMT_SP_MODULE
KMT_UI_MODULE
KMT_HELP_MTM : Message Text Modules
KMT_SP_MTM
Each file is preceded by $$$$ <filename>
$$$$ KERMIT
@******************************************************************************@
@ @
@ VME Kermit User Interface Procedure. @
@ ------------------------------------ @
@ @
@ Installation instructions: @
@ @
@ 1. The BOOL value ASG should be set to TRUE if terminal connection @
@ to VME is via ASG, otherwise set to FALSE (for CSC, NIC etc). @
@ @
@ 2. The default option may be changed from "COMMAND" to "SERVER" if @
@ desired. @
@ @
@******************************************************************************@
PROC KERMIT IS (
LITERAL (OPTION) OPT := "COMMAND", @ "SERVER" is a valid alternative @
LITERAL (VME_FILE) VF := "",
LITERAL (REM_FILE) RF := "",
RESPONSE (RESPONSE) R := RESULT)
PROCBEGIN
EXT PROC KERMIT_THE_FROG IS (
LITERAL OPTION := "COMMAND", @ DON'T change this to "SERVER" @
LITERAL VME_FILE := "",
LITERAL REM_FILE := "",
RESPONSE RESPONSE := RESULT)
BOOL ASG IS FALSE @ TRUE : comms route is via ASG, FALSE : via CSC or NIC @
KERMIT_THE_FROG(VAL OPT,VAL VF,VAL RF,R)
PROCEND
$$$$ KMT_DATA_MODULE
MODULE KMT_DATA_MODULE;
(<GSDATA (KMT_DATA_AREA);
STATUS 5>)
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
KMT_FH_RECORD_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
NEW_RECORD,
END_OF_FILE,
WORD TEXT_TYPE, @ 0 = EBCDIC @
@ 1 = IA5 @
@ 2 = BINARY @
INT MAX_RECORD_LENGTH,
RECORD_LENGTH,
(4098) BYTE RECORD); @ Maximum record size of @
@ 4096 + 2 bytes for CRLF @
@ pair when constructing @
@ output records @
MODE
KMT_FH_FILE_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
INT OUTPUT_TOTAL);
MODE
KMT_DH_DEVICE_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
WORD MAX_INPUT_LENGTH,
MAX_OUTPUT_LENGTH,
INPUT_PARITY,
OUTPUT_PARITY,
PAUSE);
MODE
KMT_PP_CONFG_PARAMS_S IS STRUCT (
BYTE MARK,
MAXL,
TIME,
NPAD,
PADC,
EOL,
QCTL,
QBIN,
CHKT,
REPT,
4-BYTE CAPAS);
MODE
KMT_PP_PACKET_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
OUTPUT_TOTAL);
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT (
BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE
KMT_STATISTICS_FLAGS_S IS WORD STRUCT (
BIT PP_STATISTICS,
FH_STATISTICS,
30-BIT SPARE);
MODE
KMT_STATISTICS_S IS STRUCT (
REF KMT_FH_FILE_STATISTICS_S FH_FILE_STATISTICS,
REF KMT_PP_PACKET_STATISTICS_S PACKET_STATISTICS);
MODE KMT_BUFFER IS (96)BYTE;
MODE KMT_STRING IS REF()BYTE;
MODE KMT_WORD IS REF()BYTE;
MODE KMT_MTM_VALUES IS ANY
(LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF()BYTE RVB_VALUE,
REF()REF()BYTE RVRVB_VALUE);
***PAGE
@******************************************************************************@
@* *@
@* Global data declarations *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
GLOBAL STATIC
(256) BYTE ASCII_TO_EBCDIC IS X"00010203 372D2E2F 1605250B 0C0D0E0F"
X"10111213 3C3D3226 18193F27 1C1D1E1F"
X"404F7F7B 5B6C507D 4D5D5C4E 6B604B61"
X"F0F1F2F3 F4F5F6F7 F8F97A5E 4C7E6E6F"
X"7CC1C2C3 C4C5C6C7 C8C9D1D2 D3D4D5D6"
X"D7D8D9E2 E3E4E5E6 E7E8E94A E05A5F6D"
X"79818283 84858687 88899192 93949596"
X"979899A2 A3A4A5A6 A7A8A9C0 6AD0A107"
X"00010203 372D2E2F 1605250B 0C0D0E0F"
X"10111213 3C3D3226 18193F27 1C1D1E1F"
X"404F7F7B 5B6C507D 4D5D5C4E 6B604B61"
X"F0F1F2F3 F4F5F6F7 F8F97A5E 4C7E6E6F"
X"7CC1C2C3 C4C5C6C7 C8C9D1D2 D3D4D5D6"
X"D7D8D9E2 E3E4E5E6 E7E8E94A E05A5F6D"
X"79818283 84858687 88899192 93949596"
X"979899A2 A3A4A5A6 A7A8A9C0 6AD0A107";
GLOBAL STATIC
(256) BYTE EBCDIC_TO_ASCII IS X"00010203 1A091A7F 1A1A1A0B 0C0D0E0F"
X"10111213 1AFB081A 18191A1A 1C1D1E1F"
X"FFFEFDFC 1A0A171B 1A1A1A1A 1A050607"
X"1A1A161A 1A1A1A04 1A1A1A1A 14151A1A"
X"201A1A1A 1A1A1A1A 1A1A5B2E 3C282B21"
X"261A1A1A 1A1A1A1A 1A1A5D24 2A293B5E"
X"2D2F1A1A 1A1A1A1A 1A1A7C2C 255F3E3F"
X"1A1A1A1A 1A1A1A1A 1A603A23 40273D22"
X"1A616263 64656667 68691A1A 1A1A1A1A"
X"1A6A6B6C 6D6E6F70 71721A1A 1A1A1A1A"
X"1A7E7374 75767778 797A1A1A 1A1A1A1A"
X"1A1A1A1A 1A1A1A1A 1A1A1A1A 1A1A1A1A"
X"7B414243 44454647 48491A1A 1A1A1A1A"
X"7D4A4B4C 4D4E4F50 51521A1A 1A1A1A1A"
X"5C1A5354 55565758 595A1A1A 1A1A1A1A"
X"30313233 34353637 38391A1A 1A1A1A1A";
GLOBAL STATIC INT
UNSET IS -1, @ Kermit exit states @
EXIT IS 0,
LOGOUT IS 1,
FATAL_ERROR IS 999;
GLOBAL STATIC INT EOF IS 9034;
GLOBAL STATIC BOOL NOREADINT IS FALSE,
READINT IS TRUE;
GLOBAL STATIC INT
SERVER_MODE IS 0, @ Kermit modes @
RECEIVE_MODE IS 1,
SEND_MODE IS 2,
COMMAND_MODE IS 3;
GLOBAL STATIC INT
REC_SERVER_IDLE IS 0, @ Protocol Handler states @
REC_INIT IS 1,
REC_FILE IS 2,
REC_DATA IS 3,
SEND_INIT IS 4,
SEND_FILE IS 5,
SEND_DATA IS 6,
SEND_EOF IS 7,
SEND_BREAK IS 8,
COMPLETE IS 9,
ABORT IS 10;
GLOBAL STATIC INT
ENTRY IS 0, @ Packet codes @
BREAK_PKT IS 1,
DATA_PKT IS 2,
ERROR_PKT IS 3,
FILE_HDR_PKT IS 4,
GEN_CMD_PKT IS 5,
INIT_PARAM_PKT IS 6,
KMT_CMD_PKT IS 7,
NAK_PKT IS 8,
REC_INIT_PKT IS 9,
SEND_INIT_PKT IS 10,
ACK_PKT IS 11,
EOF_PKT IS 12,
BAD_PKT IS 13,
INVALID_PKT IS 14;
GLOBAL STATIC INT
UNS_PKT IS -80251, @ Unsupported packet @
NON_PKT IS -80252; @ Non-existant packet type @
GLOBAL STATIC () INT PACKET_CODES := (UNS_PKT,
BREAK_PKT, @ B packet @
UNS_PKT,
DATA_PKT, @ D packet @
ERROR_PKT, @ E packet @
FILE_HDR_PKT, @ F packet @
GEN_CMD_PKT, @ G packet @
NON_PKT,
INIT_PARAM_PKT, @ I packet @
NON_PKT,
KMT_CMD_PKT, @ K packet @
NON_PKT,
NON_PKT,
NAK_PKT, @ N packet @
NON_PKT,
NON_PKT,
NON_PKT,
REC_INIT_PKT, @ R packet @
SEND_INIT_PKT, @ S packet @
UNS_PKT,
NON_PKT,
NON_PKT,
NON_PKT,
UNS_PKT,
ACK_PKT, @ Y packet @
EOF_PKT); @ Z packet @
GLOBAL STATIC INT
VME_TERM IS 0, @ VME terminal file name @
VME_STD IS 1, @ VME standard file name @
KMT_STD IS 2; @ Kermit standard name @
***LINES(4)
@ Variables: @
@ ********** @
GLOBAL
STATIC (<STATUS 5>)
KMT_FH_RECORD_DETAILS_S KMT_FH_RECORD_DETAILS;
GLOBAL
STATIC (<STATUS 5>)
KMT_FH_FILE_STATISTICS_S KMT_FH_FILE_STATISTICS;
GLOBAL
STATIC (<STATUS 5>)
KMT_DH_DEVICE_DETAILS_S KMT_DH_DEVICE_DETAILS;
***LINES(4)
GLOBAL
STATIC (<STATUS 5>)
KMT_PP_CONFG_PARAMS_S KMT_PP_LOCAL_CONFG_PARAMS;
GLOBAL
STATIC (<STATUS 5>)
KMT_PP_CONFG_PARAMS_S KMT_PP_REMOTE_CONFG_PARAMS;
GLOBAL
STATIC (<STATUS 5>)
KMT_PP_PACKET_STATISTICS_S KMT_PP_PACKET_STATISTICS;
***LINES(4)
GLOBAL
STATIC (<STATUS 5>)
REF () BYTE KMT_PH_INPUT_PACKET_DATA;
***LINES(4)
GLOBAL
STATIC (<STATUS 5>)
KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
GLOBAL
STATIC (<STATUS 5>)
KMT_STATISTICS_FLAGS_S KMT_STATISTICS_FLAGS;
GLOBAL
STATIC (<STATUS 5>)
KMT_STATISTICS_S KMT_STATISTICS := (KMT_FH_FILE_STATISTICS,
KMT_PP_PACKET_STATISTICS);
GLOBAL STATIC () BYTE KMT_VERSION := "1.01";
GLOBAL STATIC BOOL ASG_ROUTE;
GLOBAL STATIC (15)KMT_MTM_VALUES KMT_MTM_AREA;
GLOBAL STATIC (80)BYTE MTM_TEXT;
GLOBAL STATIC INT MTM_TEXT_LEN;
GLOBAL STATIC (2)REF()BYTE MTM_RECALL_DATA;
GLOBAL STATIC INT RC_IGNORED; @ ignored result code @
GLOBAL STATIC INT PKT_SEQ; @ packet sequence number @
GLOBAL STATIC INT PKT_NO; @ number of packet received @
GLOBAL STATIC INT PKT_TYPE; @ packet type @
GLOBAL STATIC INT RETRY_COUNT; @ retry count @
GLOBAL STATIC INT RETRY_TOTAL; @ total retries during xfer @
GLOBAL STATIC INT TIMEOUT_TOTAL; @ total timeouts during xfer @
GLOBAL STATIC INT MAXTRY; @ max retries @
GLOBAL STATIC INT EXIT_STATE; @ controls main Kermit loop @
GLOBAL STATIC INT KMT_CURRENT_MODE; @ server/send/receive/command @
GLOBAL STATIC INT KMT_PH_STATE; @ state in protocol handler @
GLOBAL STATIC INT FILE_OPTION; @ create or replace receive files @
GLOBAL STATIC WORD DELAY; @ time delay before SEND_INIT packet@
GLOBAL STATIC BOOL DELAY_TIMER; @ set delay timer before get packet @
GLOBAL STATIC BOOL SAVE_INCOMPLETE_FILE; @ save action for incomplete files @
GLOBAL STATIC BOOL TRANSLATE_FILENAME; @ file names to be translated @
GLOBAL STATIC KMT_BUFFER KMT_VME_FILE_BUF, @ buffer for VME filename @
KMT_REM_FILE_BUF; @ buffer for remote filename @
GLOBAL STATIC KMT_WORD KMT_VME_FILE, @ pointer to VME filename @
KMT_REM_FILE; @ pointer to remote filename @
GLOBAL STATIC KMT_BUFFER KMT_INPUT_BUF; @ command line buffer@
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
ENDMODULE @ KMT_DATA_MODULE @
$$$$ KMT_DH_MODULE
MODULE KMT_DH_MODULE;
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
PFI_REPORTS IS LONG WORD STRUCT (
4-BIT ALWAYS_ZERO,
12-BIT USER_FILE_IDENT,
TRANSFER_IDENTIFIER,
4-BIT REASON,
BYTE QUALIFIER_1,
QUALIFIER_2,
2-BYTE CHARACTER_OUTPUT);
MODE
PFI_FLAGS_1S IS BYTE STRUCT (
BIT MEDIUM_LOW,
DATA_LOST,
FORMAT_DISTURBED,
PERMANENTLY_UNAVAILABLE,
TEMPORARILY_UNAVAILABLE,
NOT_IMPLEMENTED,
GENERAL_FILE_FREEZE,
CHARACTER_OUTPUT_VALID);
MODE
PFI_FLAGS_2S IS BYTE STRUCT (
BIT PROPERTIES_LOST,
LONG_LINE,
ILLEGAL_DATA,
FILE_TIMEOUT,
4-BIT SPARE);
MODE
PFI_INPUT_FLAGS IS 2-BYTE STRUCT (
BIT QUALIFIED,
15-BIT SPARE);
MODE
PFI_INPUT_RETURNS IS WORD STRUCT (
PFI_INPUT_FLAGS INPUT_FLAGS,
2-BYTE DATA_LENGTH);
MODE
PFI_QUEUE_CONTROLS IS WORD STRUCT (
BIT BREAK_IN,
DATA_LOST,
FORMAT_DISTURBED,
BREAK_IN_ACK,
GENERAL_FILE_FREEZE,
RESET,
26-BIT RESERVED);
MODE
PFI_OUTPUT_CONTROLS IS WORD STRUCT (
BIT EXPIDITED_DATA,
REPORT_NORMAL_TERMINATION,
PROMPT,
CANCEL_OUTSTANDING_PROMPT,
OVERRIDE_MY_READ_INTEREST,
SPARE_2,
QUALIFIED,
SEQUENCE,
BYTE COMMAND,
2-BYTE SPARE5);
MODE
PFI_FILE_FLAGS IS WORD STRUCT (
BIT FORMAT_SENSITIVE,
ACTION_KEY_IS_DATA,
AUTOPAGING,
AUTOMATIC_NEW_LINE,
BADGE_REQUIRED,
PAUSING_REQUIRED,
INHIBIT_SPACE_TRUNCATION,
INHIBIT_SPACE_COMPRESSION,
FE_AT_START_OF_RECORD,
REJECT_ILLEGAL_DATA,
ALLOW_COMPRESSION,
21-BIT RESERVED);
MODE
PFI_PARAMETER_VALUES IS ANY (
INT INT_VALUE,
PFI_FILE_FLAGS FILE_FLAGS,
REF REF () BYTE RRRB_VALUE,
REF () BYTE STRING_VALUE);
MODE
PFI_PARAMETER_PAIRS IS STRUCT (
WORD TYPE,
PFI_PARAMETER_VALUES VALUE);
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT (
BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE
KMT_DH_DEVICE_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
WORD MAX_INPUT_LENGTH,
MAX_OUTPUT_LENGTH,
INPUT_PARITY,
OUTPUT_PARITY,
PAUSE);
MODE
KMT_DH_FILE_DETAILS_S IS STRUCT (
LONG INT FILE_CURRENCY,
WORD PFM_CURRENCY,
CONNECTION_CURRENCY,
TIMER_CHANNEL,
BOOL READ_INTEREST,
(2) WORD EVENT_LIST,
BOOL LONG_SUSPEND);
MODE
KMT_PP_CONFG_PARAMS_S IS STRUCT (
BYTE MARK,
MAXL,
TIME,
NPAD,
PADC,
EOL,
QCTL,
QBIN,
CHKT,
REPT,
4-BYTE CAPAS);
MODE
KMT_MTM_VALUES IS ANY (
LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF () BYTE RVB_VALUE,
REF () REF () BYTE RVRVB_VALUE);
***PAGE
@******************************************************************************@
@* *@
@* External procedure references *@
@* *@
@******************************************************************************@
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_NAME @
REF () BYTE, @ FULL_FILE_NAME @
REF () WORD, @ PROPERTIES @
RESPONSE @ RESPONSE @
) CTM_READ_DESC;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ TIME_INTERVAL @
RESPONSE @ RESPONSE @
) CTM_WAIT_TIME;
EXT (<PREFIX "ICLCTM">)
PROC
(REF () BYTE, @ NAME @
REF LONG INT, @ LNAME @
REF () BYTE, @ ACCESS @
REF () BYTE, @ LEVEL @
REF () BYTE, @ LOCK @
REF () BYTE, @ REUSE @
LONG INT, @ STARTSECT @
LONG INT, @ ENDSECT @
LONG INT, @ LOAD @
REF () REF () BYTE, @ DNAMES @
RESPONSE @ RESPONSE @
) ASSIGN_FILE;
EXT (<PREFIX "ICLCTM">)
PROC
(INT, @ EVENT_NODE_CURRENCY @
BYTE, @ ACCESS @
BYTE, @ SHARABILITY @
REF WORD, @ EVENT_CURRENCY @
LONG WORD, @ INTERRUPT_PROC @
WORD, @ SPARE @
RESPONSE @ RESPONSE @
) CONNECT_EVENT;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ EVENT_CURRENCY @
LONG WORD, @ MESSAGE @
INT, @ REPLY @
RESPONSE @ RESPONSE @
) READ_EVENT;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF WORD, @ PFM_CURRENCY @
REF WORD, @ CONNECTION_CURRENCY @
REF () BYTE, @ DETAILS_SUPPLIED @
REF () BYTE, @ DETAILS_REQUIRED @
REF () BYTE, @ DETAILS_RETURNED @
RESPONSE @ RESPONSE @
) BI_CONNECT_FILE;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ CONNECTION_CURRENCY @
REF () BYTE, @ DETAILS_SUPPLIED @
REF () BYTE, @ DETAILS_REQUIRED @
REF () BYTE, @ DETAILS_RETURNED @
RESPONSE @ RESPONSE @
) BI_MODIFY_CONNECTION;
EXT (<PREFIX "ICLCTM">)
PROC
(REF () WORD, @ EVENT_LIST @
REF WORD, @ EVENT_CURRENCY @
REF LONG WORD, @ MESSAGE @
BOOL, @ LONG_SUSPEND @
RESPONSE @ RESPONSE @
) WAIT_FOR_EVENTS;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ EVENT_CURRENCY @
REF WORD, @ TIMER_CHANNEL @
RESPONSE @ RESPONSE @
) CREATE_TIMER_CHANNEL;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ TIMER_CHANNEL @
LONG WORD, @ MESSAGE @
LONG INT, @ TIME @
BOOL, @ REAL_TIME @
BOOL, @ PERIODIC @
RESPONSE) @ RESPONSE @
ESTABLISH_TIMER_NOTIFICATION;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ TIMER_CHANNEL @
RESPONSE @ RESPONSE @
) CANCEL_TIMER_NOTIFICATION;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ PFM_CURRENCY @
WORD, @ START_OF_INPUT @
REF () BYTE, @ BUFFER @
REF PFI_INPUT_RETURNS, @ INPUT_RETURN @
RESPONSE @ RESPONSE @
) DH_INPUT;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ PFM_CURRENCY @
WORD, @ TRANSFER_IDENTIFIER @
REF () BYTE, @ OUTPUT_DATA @
PFI_OUTPUT_CONTROLS, @ CONTROL @
RESPONSE @ RESPONSE @
) DH_OUTPUT;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ PFM_CURRENCY @
REF () PFI_PARAMETER_PAIRS, @ PARAMS @
RESPONSE @ RESPONSE @
) DH_DEFINE_FILE_PROPERTIES;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ PFM_CURRENCY @
WORD, @ QUEUE_ACTION @
PFI_QUEUE_CONTROLS, @ CONTROL @
REF () BYTE, @ ADDITIONAL_DATA @
RESPONSE @ RESPONSE @
) DH_DO_QUEUE_ACTION;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ PFM_CURRENCY @
REF () BYTE, @ DETAILS_REQUIRED @
REF () BYTE, @ DETAILS_AREA @
REF WORD, @ DETAILS_LENGTH_AREA @
RESPONSE @ RESPONSE @
) DH_GIVE_FILE_DETAILS;
EXT
PROC
(INT, @ TYPE @
REF () KMT_MTM_VALUES @ PARAMS @
) KMT_SP_LOG_TRACE_MESSAGE;
EXT
PROC
(INT, @ RESULT_CODE @
WORD, @ DESTINATION @
REF () KMT_MTM_VALUES, @ PARAMS @
LONG WORD, @ PE_CONTINGENCY_MESSAGE @
BOOL, @ DUMP @
BOOL @ UNRECOVERABLE @
) KMT_EH_LOG_ERROR;
***PAGE
@******************************************************************************@
@* *@
@* External data references *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
***LINES(4)
@ Variables: @
@ ********** @
EXT (<CASCADE>)
REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
EXT (<CASCADE>)
REF KMT_DH_DEVICE_DETAILS_S KMT_DH_DEVICE_DETAILS;
EXT (<CASCADE>)
REF KMT_PP_CONFG_PARAMS_S KMT_PP_REMOTE_CONFG_PARAMS;
EXT (<CASCADE>)
REF BOOL DELAY_TIMER;
EXT (<CASCADE>)
REF WORD DELAY;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Static data declarations *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
***LINES(4)
@ Variables: @
@ ********** @
STATIC
KMT_DH_FILE_DETAILS_S KMT_DH_FILE_DETAILS;
***PAGE
@******************************************************************************@
@* *@
@* Procedure declarations *@
@* *@
@******************************************************************************@
STATIC
PROC
KMT_DH_PROCESS_RESPONSE IS (
INT RESULTCODE,
BOOL PROMPT,
REF BOOL RETRY,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to process resultcodes returned from COSMAN and to *@
@* handle CDH events. *@
@* RETRY is set TRUE if a recoverable I/O error occurs indicating that the *@
@* I/O operation should be repeated. *@
@* PROMPT should be set TRUE if this is an output request and read interest *@
@* is required. *@
@* *@
@******************************************************************************@
BEGIN
INT PFI_REQUEST_ACCEPTED IS -31008,
PFI_FILE_FROZEN IS -38982,
PFI_DELAYED_TRANSFER IS -38983,
PFI_FILE_UNAVAILABLE IS 30978,
PFI_OVERLOAD IS 37560,
PFI_TEMPORARILY_UNAVAILABLE IS 37561,
PFI_TIMED_OUT IS 39854;
INT KMT_DH_EVENT_MSG IS 152,
KMT_DH_UNEXPECTED_BREAKIN IS 80150,
KMT_DH_UNEXPECTED_EVENT IS 80151,
KMT_DH_INPUT_AVAILABLE IS -80152,
KMT_DH_QUEUE_EMPTY IS -80153;
REF BOOL READ_INTEREST IS KMT_DH_FILE_DETAILS.READ_INTEREST;
BOOL TRACING IS KMT_TRACE_FLAGS.DH_TRACING;
UNLESS
READ_INTEREST
OR
RESULTCODE EQ PFI_REQUEST_ACCEPTED
OR
RESULTCODE EQ PFI_FILE_FROZEN
OR
RESULTCODE EQ PFI_DELAYED_TRANSFER
OR
RESULTCODE EQ PFI_OVERLOAD
OR
RESULTCODE EQ PFI_TEMPORARILY_UNAVAILABLE
THEN @ Unrecoverable I/O error or @
@ REPORT NORMAL TERMINATION @
@ not set @
READ_INTEREST := FALSE;
RESULT := RESULTCODE
ELSE
REF () WORD EVENT_LIST IS KMT_DH_FILE_DETAILS.EVENT_LIST;
BOOL LONG_SUSPEND IS KMT_DH_FILE_DETAILS.LONG_SUSPEND;
PFI_REPORTS EVENT_MESSAGE;
REF PFI_FLAGS_1S QUALIFIER_1 IS EVENT_MESSAGE.QUALIFIER_1;
REF PFI_FLAGS_2S QUALIFIER_2 IS EVENT_MESSAGE.QUALIFIER_2;
REF WORD PFM_CURRENCY IS KMT_DH_FILE_DETAILS.PFM_CURRENCY;
READ_INTEREST := FALSE;
RESULT := 0;
WHILE @ Process CDH event @
(
INT RC_DISCARDED;
WORD EVENT_CURRENCY;
BOOL SUSPEND := FALSE;
RETRY := FALSE;
WAIT_FOR_EVENTS (EVENT_LIST(SIZE 1),
EVENT_CURRENCY,
EVENT_MESSAGE,
LONG_SUSPEND,
RC_DISCARDED);
IF
TRACING
THEN (<RARELY>)
(
() KMT_MTM_VALUES PARAMS := DISPLAY(EVENT_MESSAGE
AS KMT_MTM_VALUES.RLW_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (KMT_DH_EVENT_MSG,
PARAMS)
)
FI;
IF
QUALIFIER_1.DATA_LOST
THEN
DH_DO_QUEUE_ACTION (PFM_CURRENCY,
0, @ Unfreeze @
X'40000000',
NIL,
RC_DISCARDED);
RETRY := TRUE
FI;
IF
QUALIFIER_1.FORMAT_DISTURBED
THEN
DH_DO_QUEUE_ACTION (PFM_CURRENCY,
0, @ Unfreeze @
X'20000000',
NIL,
RC_DISCARDED);
RETRY := TRUE
FI;
IF
QUALIFIER_1.PERMANENTLY_UNAVAILABLE
THEN
RESULT := PFI_FILE_UNAVAILABLE
FI;
IF
QUALIFIER_1.TEMPORARILY_UNAVAILABLE
THEN
SUSPEND := TRUE
FI;
IF
QUALIFIER_1.GENERAL_FILE_FREEZE
THEN
DH_DO_QUEUE_ACTION (PFM_CURRENCY,
0, @ Unfreeze @
X'08000000',
NIL,
RC_DISCARDED);
RETRY := TRUE
FI;
IF
QUALIFIER_2.FILE_TIMEOUT
THEN
RESULT := PFI_TIMED_OUT
FI;
UNLESS
RETRY OR RESULT NE 0
THEN
CASE
EVENT_MESSAGE.REASON
THEN @ 0 - PFI_NORMAL_TERM @
READ_INTEREST := PROMPT
ELSE @ 1 - PFI_ABNORMAL_TERM @
RETRY := TRUE
ELSE @ 2 - PFI_ATTENTION @
SUSPEND := TRUE
ELSE @ 3 - PFI_FILE_AVAILABLE @
RETRY := (RESULTCODE NE PFI_DELAYED_TRANSFER);
SUSPEND := NOT(RETRY)
ELSE @ 4 - PFI_INPUT_AVAILABLE @
RESULT := KMT_DH_INPUT_AVAILABLE
ELSE (<RARELY>) @ 5 - PFI_ACTION_KEY @
(
RESULT := KMT_DH_UNEXPECTED_BREAKIN;
KMT_EH_LOG_ERROR (RESULT,
2,
NIL,
0,
TRUE, @ Produce UCG dump @
FALSE) @ Recoverable @
)
ELSE @ 6 - PFI_PROMPT_CANCELLED @
RETRY := TRUE
ELSE @ 7 - PFI_QUEUE_EMPTY @
RETRY := FALSE;
RESULT := KMT_DH_QUEUE_EMPTY
DEFAULT (<RARELY>) @ Unexpected event from CDH @
(
RESULT := KMT_DH_UNEXPECTED_EVENT;
KMT_EH_LOG_ERROR (RESULT,
2,
NIL,
0,
TRUE, @ Produce UCG dump @
FALSE) @ Recoverable @
)
ESAC
FI;
SUSPEND AND RESULT EQ 0
)
DO
SKIP
REPEAT
FI
END; @ KMT_DH_PROCESS_RESPONSE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_DH_OPEN_FILE IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to assign, connect and open an interactive file *@
@* with read and write capability. *@
@* The interactive file is assigned to the slow file description :STD.STDMAC *@
@* and uses code set 255 (transparent 7-bit ISO). *@
@* The file will be used for the exchange of KERMIT packets. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
REF LONG INT FILE_CURRENCY IS KMT_DH_FILE_DETAILS.FILE_CURRENCY;
REF WORD PFM_CURRENCY IS KMT_DH_FILE_DETAILS.PFM_CURRENCY;
REF () WORD EVENT_LIST IS KMT_DH_FILE_DETAILS.EVENT_LIST;
IF
(
() BYTE NAME := ":STD.STDMAC",
ACCESS := "W",
LEVEL := "R",
LOCK := "",
REUSE := "NO",
DNAME := "ICL9NINTDEVICE";
() REF () BYTE DNAMES := DISPLAY (DNAME);
ASSIGN_FILE (NAME,
FILE_CURRENCY,
ACCESS,
LEVEL,
LOCK,
REUSE,
-5,
-5,
0,
DNAMES,
RESULT);
RESULT LE 0
)
AND
(
CONNECT_EVENT (0,
X"C0",
X"C0",
EVENT_LIST(0),
0,
0,
RESULT);
RESULT LE 0
)
AND
(
() BYTE DETAILS_SUPPLIED := X"CE080000000000000000";
EVENT_LIST(1) := EVENT_LIST(0);
DETAILS_SUPPLIED(2 SIZE 4) := 4-BYTE: EVENT_LIST(0);
DETAILS_SUPPLIED(6 SIZE 4) := 4-BYTE: EVENT_LIST(1);
BI_CONNECT_FILE (FILE_CURRENCY,
PFM_CURRENCY,
KMT_DH_FILE_DETAILS.CONNECTION_CURRENCY,
DETAILS_SUPPLIED,
NIL,
NIL,
RESULT);
RESULT LE 0
)
AND
(
INT FILE_CLASS IS 11, @ PFI_INTERACTIVE @
CODE_SET IS 255, @ Transparent 7-bit ISO @
TIME_OUT IS 0; @ No TIMEOUT ie indefinite @
@ wait @
PFI_FILE_FLAGS FILE_FLAGS IS X'03000000';
@ Inhibit space truncation @
@ Inhibit space compression @
() PFI_PARAMETER_PAIRS PARAMS :=
((X'00', FILE_CLASS AS PFI_PARAMETER_VALUES.INT_VALUE),
(X'01', CODE_SET AS PFI_PARAMETER_VALUES.INT_VALUE),
(X'02', FILE_FLAGS AS PFI_PARAMETER_VALUES.FILE_FLAGS),
(X'18', TIME_OUT AS PFI_PARAMETER_VALUES.INT_VALUE)
);
KMT_DH_FILE_DETAILS.READ_INTEREST := FALSE;
WHILE
(
BOOL RETRY;
DH_DEFINE_FILE_PROPERTIES (PFM_CURRENCY,
PARAMS,
RESULT);
KMT_DH_PROCESS_RESPONSE (RESULT,
FALSE,
RETRY,
RESULT);
RETRY
)
DO
SKIP
REPEAT;
RESULT LE 0
)
AND @ Timeout intervals may be @
@ set in multiples of 2 @
@ minutes using the PFI. @
@ We need to be able to set @
@ timeout intervals in the @
@ order of 5 to 30 seconds. @
@ Therefore we must set up @
@ our own timer channel. @
(
CREATE_TIMER_CHANNEL (EVENT_LIST(0),
KMT_DH_FILE_DETAILS.TIMER_CHANNEL,
RESULT);
RESULT LE 0
)
THEN @ File opened successfully @
() WORD PROPERTIES := (104, @ Maximum record size @
0,
0);
() BYTE DETAILS_REQUIRED := X"49" @ Line length @
X"51"; @ Suspension advice @
(6) BYTE DETAILS_AREA;
KMT_DH_DEVICE_DETAILS.MAX_INPUT_LENGTH := IF
(
CTM_READ_DESC (FILE_CURRENCY,
NIL,
NIL,
PROPERTIES,
RESULT);
RESULT EQ 0
)
THEN
PROPERTIES(1)
ELSE
80
FI;
DH_GIVE_FILE_DETAILS (PFM_CURRENCY,
DETAILS_REQUIRED,
DETAILS_AREA,
NIL,
RESULT);
IF
RESULT EQ 0
THEN
KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH := DETAILS_AREA(2);
KMT_DH_FILE_DETAILS.LONG_SUSPEND := BIT:DETAILS_AREA(5)
ELSE
KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH := 80;
KMT_DH_FILE_DETAILS.LONG_SUSPEND := TRUE
FI
FI;
IF
RESULT GT 0
THEN (<RARELY>) @ Open error @
(
() BYTE PROC_NAME := "KMT_DH_OPEN_FILE";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_DH_DEVICE_DETAILS.FILE_OPEN := FALSE;
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE @ Ignore warnings @
KMT_DH_DEVICE_DETAILS.FILE_OPEN := TRUE;
RESULT := 0
FI
END; @ KMT_DH_OPEN_FILE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_DH_CLOSE_FILE IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to close the file previously opened by the *@
@* procedure KMT_DH_OPEN_FILE. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
REF BOOL FILE_OPEN IS KMT_DH_DEVICE_DETAILS.FILE_OPEN;
RESULT := 0;
IF
FILE_OPEN
THEN @ File open, close it @
INT RC_DISCARDED;
IF
(
() BYTE DETAILS_SUPPLIED := DISPLAY (181,@ FC_TI_ACTION_TYPE @
1, @ Length @
40);@ FC_DI_DISCONNECT @
BI_MODIFY_CONNECTION (KMT_DH_FILE_DETAILS.CONNECTION_CURRENCY,
DETAILS_SUPPLIED,
NIL,
NIL,
RESULT);
RESULT GT 0
)
THEN (<RARELY>) @ Close error @
(
() BYTE PROC_NAME := "KMT_DH_CLOSE_FILE";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE @ Ignore warnings @
RESULT := 0
FI;
FILE_OPEN := FALSE;
FI
END; @ KMT_DH_CLOSE_FILE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_DH_OUTPUT IS (
REF () BYTE OUTPUT_PACKET,
BOOL PROMPT,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to send a KERMIT packet to the remote end. The *@
@* end of line terminating character and any padding characters are added and *@
@* the required parity is set. *@
@* OUTPUT_PACKET references an area containing the packet to be output. *@
@* If the length of the output packet is zero then a single 'PAD' character *@
@* is output. If PROMPT is set true then the procedure will set read *@
@* interest on the file for the next call to KMT_DH_INPUT. *@
@* *@
@******************************************************************************@
BEGIN
***PAGE
SIM
PROC
KMT_DH_SET_PARITY IS (
REF () BYTE BUFFER):
@******************************************************************************@
@* *@
@* This procedure is used to set the required parity for each byte contained *@
@* in BUFFER. *@
@* *@
@******************************************************************************@
BEGIN
WORD PARITY IS KMT_DH_DEVICE_DETAILS.OUTPUT_PARITY;
IF
PARITY LE 1
THEN @ Even or odd parity required @
BYTE INITIAL_PARITY_MASK IS IF
PARITY EQ 0
THEN @ Even parity @
X"80"
ELSE @ Odd parity @
X"00"
FI;
FOR I
TO BOUND BUFFER
DO
BYTE PARITY_MASK := INITIAL_PARITY_MASK;
WORD THIS_BYTE := BUFFER(I) & X"7F";
WHILE
(
INT NUM_BITS_SHIFTED;
THIS_BYTE := SHWZ (THIS_BYTE,
NUM_BITS_SHIFTED);
THIS_BYTE NE 0
)
DO
PARITY_MASK := PARITY_MASK NEQ X"80";
THIS_BYTE := THIS_BYTE & X'7F000000'
REPEAT;
BUFFER(I) := BUFFER(I) ! PARITY_MASK
REPEAT
ELSF
PARITY EQ 2
THEN @ Mark parity @
ORBYTE (X"80",
BUFFER,
0,
NIL)
ELSF
PARITY EQ 3
THEN @ Space parity @
ANDBYTE (X"7F",
BUFFER,
0,
NIL)
FI
END; @ KMT_DH_SET_PARITY @
***PAGE
INT PFI_REQUEST_ACCEPTED IS -31008,
PFI_TIMED_OUT IS 39854;
INT KMT_DH_DATA_OUT_MSG IS 151,
KMT_DH_INPUT_AVAILABLE IS -80152,
KMT_DH_QUEUE_EMPTY IS -80153;
INT KMT_EH_SOFTWARE_ERROR IS 80101;
INT NPAD IS KMT_PP_REMOTE_CONFG_PARAMS.NPAD;
INT OUTPUT_PACKET_LENGTH IS IF
OUTPUT_PACKET IS NIL
THEN
0
ELSE
LENGTH OUTPUT_PACKET
FI;
INT OUTPUT_BUFFER_LENGTH IS IF
OUTPUT_PACKET_LENGTH EQ 0
THEN
1
ELSE
OUTPUT_PACKET_LENGTH + NPAD + 1
FI;
PFI_OUTPUT_CONTROLS CONTROL IS IF
PROMPT
THEN @ Report normal termination @
@ Prompt @
X'60000000'
ELSE @ Report normal termination @
X'40000000'
FI;
WORD PFM_CURRENCY IS KMT_DH_FILE_DETAILS.PFM_CURRENCY;
(OUTPUT_BUFFER_LENGTH) BYTE OUTPUT_BUFFER;
BOOL TRACING IS KMT_TRACE_FLAGS.DH_TRACING;
INT RC_DISCARDED;
IF
OUTPUT_PACKET_LENGTH EQ 0
THEN @ No packet supplied, @
@ output single PAD character @
OUTPUT_BUFFER := KMT_PP_REMOTE_CONFG_PARAMS.PADC;
ELSE @ Build output data buffer @
@ consisting of the required @
@ number of PAD characters, @
@ the packet and the @
@ end of line terminating @
@ character @
INT EOL IS IF KMT_PP_REMOTE_CONFG_PARAMS.EOL = X"0D" @ ASG converts CR @
THEN X"0A" @ to NULL, LF to CRLF - fix also works via NIC @
ELSE KMT_PP_REMOTE_CONFG_PARAMS.EOL
FI;
MOVEBYTE (KMT_PP_REMOTE_CONFG_PARAMS.PADC,
OUTPUT_BUFFER(SIZE NPAD),
0,
NIL);
OUTPUT_BUFFER(NPAD SIZE OUTPUT_PACKET_LENGTH) := OUTPUT_PACKET;
OUTPUT_BUFFER(OUTPUT_BUFFER_LENGTH - 1) := EOL
FI;
KMT_DH_SET_PARITY (OUTPUT_BUFFER);
CTM_WAIT_TIME (KMT_DH_DEVICE_DETAILS.PAUSE, @ Wait before sending packet @
RC_DISCARDED);
WHILE
(
BOOL RETRY;
@ Ensure no I/O requests are @
@ outstanding @
DH_DO_QUEUE_ACTION (PFM_CURRENCY,
5, @ PFI_ABORT_QUEUE @
0,
NIL,
RESULT);
WHILE
(
KMT_DH_PROCESS_RESPONSE (RESULT,
FALSE,
RETRY,
RESULT);
RETRY
OR
(RESULT EQ KMT_DH_INPUT_AVAILABLE)
OR
(RESULT EQ PFI_TIMED_OUT)
)
DO
RESULT := PFI_REQUEST_ACCEPTED
REPEAT;
IF
RESULT EQ KMT_DH_QUEUE_EMPTY
THEN @ File queue empty @
RESULT := 0
FI;
IF
RESULT LE 0
THEN @ File queue emptied @
@ successfilly @
IF
TRACING
THEN (<RARELY>)
(
() KMT_MTM_VALUES PARAMS := DISPLAY(OUTPUT_BUFFER
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (KMT_DH_DATA_OUT_MSG,
PARAMS)
)
FI;
DH_OUTPUT (PFM_CURRENCY, @ Send output data @
0,
OUTPUT_BUFFER,
CONTROL,
RESULT);
KMT_DH_PROCESS_RESPONSE (RESULT, @ Check if successful @
PROMPT,
RETRY,
RESULT);
FI;
RETRY
)
DO
SKIP
REPEAT;
IF
RESULT GT 0
THEN (<RARELY>) @ I/O error @
(
() BYTE PROC_NAME := "KMT_DH_OUTPUT";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE @ Ignore warnings @
RESULT := 0
FI
END; @ KMT_DH_OUTPUT @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_DH_INPUT IS (
REF () BYTE INPUT_BUFFER,
REF INT INPUT_BUFFER_LENGTH,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to receive an input buffer from the remote end. *@
@* The input buffer may or may not contain a valid KERMIT packet. *@
@* The input buffer and length are returned in the areas referenced by *@
@* INPUT_BUFFER and INPUT_BUFFER_LENGTH respectively. *@
@* *@
@******************************************************************************@
BEGIN
***PAGE
SIM
PROC
KMT_DH_REMOVE_PARITY IS (
REF () BYTE BUFFER):
@******************************************************************************@
@* *@
@* This procedure is used to remove the parity bit (if present) for each byte *@
@* in BUFFER. *@
@* *@
@******************************************************************************@
BEGIN
@ Clear parity bit @
ANDBYTE (X"7F", @ 7 bit IA5 @
BUFFER,
0,
NIL)
END; @ KMT_DH_REMOVE_PARITY @
***PAGE
INT TIM_NO_NOTIFICATIONS IS -32156,
PFI_MESSAGE_CANCELLED IS 38575,
PFI_TIMED_OUT IS 39854;
INT KMT_DH_DATA_IN_MSG IS 150,
KMT_EH_SOFTWARE_ERROR IS 80101,
KMT_DH_INPUT_AVAILABLE IS -80152;
PFI_INPUT_RETURNS INPUT_RETURN;
BOOL TRACING IS KMT_TRACE_FLAGS.DH_TRACING;
WORD TIMER_CHANNEL IS KMT_DH_FILE_DETAILS.TIMER_CHANNEL;
WORD TIME IS IF DELAY_TIMER
THEN DELAY
ELSE KMT_PP_REMOTE_CONFG_PARAMS.TIME
FI;
IF
(
RESULT := 0;
UNLESS
KMT_DH_FILE_DETAILS.READ_INTEREST
THEN @ Read interest not set. @
@ Set read interest @
KMT_DH_OUTPUT (NIL,
TRUE,
RESULT)
FI;
RESULT LE 0
)
AND
(
IF
TIME NE 0
THEN @ Timeout intervals may be @
@ set in multiples of 2 @
@ minutes using the PFI. @
@ We need to be able to set @
@ timeout intervals in the @
@ order of 5 to 30 seconds. @
@ Therefore we must set up @
@ our own timer channel. @
LONG INT TIME_IN_MSECS IS (L'I'TIME) * 1000000;
ESTABLISH_TIMER_NOTIFICATION (TIMER_CHANNEL,
X'00000000 00100000',
@ File timeout @
@ Make it look like a PFI @
@ timeout @
TIME_IN_MSECS + I'CLOCKTIME (),
TRUE,
FALSE,
RESULT)
FI;
RESULT LE 0
)
AND
(
INT RC_DISCARDED;
BOOL RETRY;
KMT_DH_PROCESS_RESPONSE (RESULT, @ Wait for PFI event @
FALSE,
RETRY,
RESULT);
IF
(TIME NE 0) AND (RESULT NE PFI_TIMED_OUT)
AND @ Timeout set but timeout @
( @ event did not occur. @
@ Turn off timer. @
CANCEL_TIMER_NOTIFICATION (TIMER_CHANNEL,
RC_DISCARDED);
RC_DISCARDED EQ TIM_NO_NOTIFICATIONS
)
THEN @ Timeout event occurred @
@ after PFI event but before @
@ the timer could be @
@ cancelled. @
@ Read the timeout event and @
@ discarded it. @
LONG WORD EVENT_MESSAGE;
INT REPLY;
READ_EVENT (KMT_DH_FILE_DETAILS.EVENT_LIST(0),
EVENT_MESSAGE,
REPLY,
RC_DISCARDED)
FI;
RESULT EQ KMT_DH_INPUT_AVAILABLE
)
AND
(
WORD PFM_CURRENCY IS KMT_DH_FILE_DETAILS.PFM_CURRENCY;
DH_INPUT (PFM_CURRENCY, @ Get input data @
0,
INPUT_BUFFER,
INPUT_RETURN,
RESULT);
RESULT LE 0
)
THEN @ Input data read @
INPUT_BUFFER_LENGTH := INPUT_RETURN.DATA_LENGTH;
IF
(INPUT_BUFFER(INPUT_BUFFER_LENGTH - 1) & X"7F") EQ X"1E"
THEN @ Via a PAD and using @
@ code set 255 RS (X1E) is @
@ appended to the end of the @
@ record by VME. Ignore it. @
INPUT_BUFFER_LENGTH := INPUT_BUFFER_LENGTH - 1
FI;
IF
TRACING
THEN (<RARELY>)
(
() KMT_MTM_VALUES PARAMS := DISPLAY(INPUT_BUFFER(SIZE
INPUT_BUFFER_LENGTH)
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (KMT_DH_DATA_IN_MSG,
PARAMS)
)
FI;
KMT_DH_REMOVE_PARITY (INPUT_BUFFER(SIZE INPUT_BUFFER_LENGTH));
ELSE
INPUT_BUFFER_LENGTH := 0
FI;
IF
RESULT EQ PFI_MESSAGE_CANCELLED
THEN @ 'CANCEL' key, ignore RC @
RESULT := 0
FI;
IF
(RESULT GT 0) AND (RESULT NE PFI_TIMED_OUT)
THEN (<RARELY>) @ I/O error @
(
() BYTE PROC_NAME := "KMT_DH_INPUT";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSF
RESULT LE 0
THEN @ Ignore warnings @
RESULT := 0
FI
END; @ KMT_DH_INPUT @
ENDMODULE @ KMT_DH_MODULE @
$$$$ KMT_EH_MODULE
MODULE KMT_EH_MODULE;
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
KMT_MTM_VALUES IS ANY (
LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF () BYTE RVB_VALUE,
REF () REF () BYTE RVRVB_VALUE);
***PAGE
@******************************************************************************@
@* *@
@* External procedure references *@
@* *@
@******************************************************************************@
EXT (<PREFIX "ICLCTM">)
PROC
(INT, @ ERROR_NUMBER @
REF () BYTE, @ ERROR_MESSAGE @
REF INT, @ MESSAGE_LENGTH @
RESPONSE @ RESPONSE @
) CTM_GIVE_ERROR_MSG;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ TYPE @
WORD, @ DESTINATION @
REF () BYTE, @ MESSAGE @
RESPONSE @ RESPONSE @
) CTM_LOG;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG LONG WORD, @ TARGET_RESPONSE @
INT @ RESPONSE_TO_CTM_JS_CALL @
) CTM_STOP;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ MESSAGE @
WORD, @ FRAMES @
WORD, @ PLTS @
REF () LONG WORD, @ ADDRESSES @
REF () REF () BYTE, @ AREAS @
WORD, @ OPTIONS @
RESPONSE @ RESPONSE @
) CTM_DUMP;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ CONTINGENCY_CLASS @
LONG WORD, @ INTERRUPT_PROCEDURE @
RESPONSE @ RESPONSE @
) CTM_INFORM;
EXT
PROC
(INT, @ TEXT_NUMBER @
REF () KMT_MTM_VALUES @ AREA @
) INT KMT_SP_MTM;
***PAGE
@******************************************************************************@
@* *@
@* External data references *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
***LINES(4)
@ Variables: @
@ ********** @
EXT
REF () BYTE KMT_DATA_AREA;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Procedure declarations *@
@* *@
@******************************************************************************@
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_EH_LOG_ERROR IS (
INT RESULTCODE,
WORD DESTINATION,
REF () KMT_MTM_VALUES PARAMS,
LONG WORD PE_CONTINGENCY_MESSAGE,
BOOL DUMP,
BOOL UNRECOVERABLE):
@******************************************************************************@
@* *@
@* This procedure is used to log failing resultcodes to the job journal *@
@* and/or to the MAC screen and to produce UCG dumps. *@
@* If RESULTCODE is non zero then a failure message will be generated using *@
@* the parameters in the list referenced by PARAMS and logged to the job *@
@* journal. *@
@* If DUMP is set TRUE then a UCG dump is produced. PE_CONTINGENCY_MESSAGE is *@
@* used in conjunction with DUMP and must contain either zero or a program *@
@* error contingency message. *@
@* If UNRECOVERABLE is set TRUE then the program will exit. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101,
KMT_EH_ICL_RESULT IS 80102;
INT RC_DISCARDED,
MESSAGE_LENGTH;
(120) BYTE ERROR_MESSAGE;
REF () BYTE MESSAGE_REM;
UNLESS
RESULTCODE EQ 0
THEN
INT RC IS IF
RESULTCODE LT 0
THEN
-RESULTCODE
ELSE
RESULTCODE
FI;
BOOL ICL_RESULTCODE IS ((RC LT 80000) OR (RC GT 89999));
INT PARAMS_LENGTH IS IF
PARAMS IS NIL
THEN
0
ELSE
LENGTH PARAMS
FI;
INT MTM_AREA_LENGTH IS PARAMS_LENGTH + IF
ICL_RESULTCODE
THEN
5
ELSE
4
FI;
(MTM_AREA_LENGTH) KMT_MTM_VALUES MTM_AREA;
INT MTM_TEXT_NUMBER,
MTM_REPLY,
MTM_MESSAGE_LENGTH;
(100) BYTE MTM_MESSAGE;
(2) REF () BYTE MTM_RECALL_DATA;
MTM_AREA (SIZE 4) := (MTM_MESSAGE
AS KMT_MTM_VALUES.RVB_VALUE,
MTM_MESSAGE_LENGTH
AS KMT_MTM_VALUES.RI_VALUE,
MTM_RECALL_DATA
AS KMT_MTM_VALUES.RVRVB_VALUE,
(L'PARAMS_LENGTH)
AS KMT_MTM_VALUES.LI_VALUE);
IF
ICL_RESULTCODE
THEN @ Use MTM text number @
@ KMT_EH_ICL_RESULT to expand @
@ the error message passing @
@ the RESULTCODE as a @
@ parameter @
MTM_TEXT_NUMBER := KMT_EH_ICL_RESULT;
MTM_AREA(4) := (L'RESULTCODE) AS KMT_MTM_VALUES.LI_VALUE;
IF
PARAMS_LENGTH GT 0
THEN
MTM_AREA(5::) := PARAMS
FI
ELSE @ Use RESULTCODE as the MTM @
@ text number to expand the @
@ error message @
MTM_TEXT_NUMBER := RC;
IF
PARAMS_LENGTH GT 0
THEN
MTM_AREA(4::) := PARAMS
FI
FI;
WHILE
(
MTM_REPLY := KMT_SP_MTM (MTM_TEXT_NUMBER,
MTM_AREA);
IF
MTM_REPLY NE -2
THEN @ Expanded message returned @
REF () BYTE MESSAGE IS IF
MTM_REPLY EQ -3
THEN @ Returned in recall data @
MTM_TEXT_NUMBER := 0;
MTM_RECALL_DATA(0)
ELSE @ Returned in message buffer @
MTM_TEXT_NUMBER := MTM_REPLY;
MTM_MESSAGE(SIZE MTM_MESSAGE_LENGTH)
FI;
CTM_LOG (3,
DESTINATION,
MESSAGE,
RC_DISCARDED)
ELSE
MTM_TEXT_NUMBER := 0
FI;
MTM_TEXT_NUMBER NE 0
)
DO
SKIP
REPEAT;
IF
ICL_RESULTCODE
@ Get ICL message text @
AND
(
CTM_GIVE_ERROR_MSG (RC,
ERROR_MESSAGE,
MESSAGE_LENGTH,
RC_DISCARDED);
RC_DISCARDED EQ 0
)
AND
MESSAGE_LENGTH GT 10
@ Skip "**** ERROR " @
AND
(
MESSAGE_REM := ERROR_MESSAGE(10 SIZE MESSAGE_LENGTH - 10);
NOT SCANUNQ (X'40', @ Look for start of text @
MESSAGE_REM,
0,
MESSAGE_REM)
)
THEN @ Message text exists for @
@ resultcode. Log to journal. @
CTM_LOG (3,
DESTINATION,
MESSAGE_REM,
RC_DISCARDED)
FI
FI;
IF
DUMP
THEN
() LONG WORD ADDRESSES := DISPLAY (BDESC KMT_DATA_AREA);
CTM_DUMP (PE_CONTINGENCY_MESSAGE,
10,
10,
ADDRESSES,
NIL,
4, @ Dump in character and hex @
RC_DISCARDED)
FI;
IF
UNRECOVERABLE
THEN
CTM_STOP (L'L'W' RESULTCODE,
-KMT_EH_SOFTWARE_ERROR)
FI
END; @ KMT_EH_LOG_ERROR @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_EH_PE_CONTINGENCY_HANDLER IS (
REF LONG WORD PE_CONTINGENCY_MESSAGE):
@******************************************************************************@
@* *@
@* This procedure is used to handle program error contingencies. The procedure*@
@* calls KMT_EH_LOG_ERROR to produce a UCG dump. All programs are treated as *@
@* unrecoverable. *@
@* PE_CONTINGENCY_MESSAGE references an area containing the program error *@
@* contingency message. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
KMT_EH_LOG_ERROR (KMT_EH_SOFTWARE_ERROR,
2,
NIL,
PE_CONTINGENCY_MESSAGE,
TRUE, @ Produce UCG dump @
TRUE) @ Unrecoverable - Exit @
END; @ KMT_EH_PE_CONTINGENCY_HANDLER @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_EH_INFORM_PE_CONTINGENCY IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to associate the contingency procedure: *@
@* KMT_EH_PE_CONTINGENCY_HANDLER with the the program error contingcy class. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
CTM_INFORM (X'80000000', @ PE contingencies @
PDESC KMT_EH_PE_CONTINGENCY_HANDLER,
RESULT);
IF
RESULT GT 0
THEN (<RARELY>)
(
() BYTE PROC_NAME := "KMT_EH_INFORM_PE_CONTINGENCY";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE @ Ignore warnings @
RESULT := 0
FI
END; @ KMT_EH_INFORM_PE_CONTINGENCY @
ENDMODULE @ KMT_EH_MODULE @
$$$$ KMT_FH_MODULE
MODULE KMT_FH_MODULE;
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
CTM_ACCESS_1 IS GPROC (
REF () CTM_PARAMETER_PAIRS,
RESPONSE);
MODE
CTM_ACCESS_2 IS GPROC (
RESPONSE);
MODE
CTM_PARAMETER_VALUES IS ANY (
INT INT_VALUE,
LONG WORD LONG_WORD_VALUE,
REF INT REF_INT_VALUE,
REF () BYTE STRING_VALUE,
REF CTM_ACCESS_1 REF_ACCESS_1_VALUE,
REF CTM_ACCESS_2 REF_ACCESS_2_VALUE);
MODE
CTM_PARAMETER_PAIRS IS WSTRUCT (
INT TYPE,
CTM_PARAMETER_VALUES VALUE);
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT (
BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE
KMT_FH_FILE_OPTIONS_S IS BYTE STRUCT (
BIT APPEND_CREATE,
APPEND,
REPLACE_CREATE,
REPLACE,
CREATE_APPEND,
CREATE_REPLACE,
CREATE,
READ);
MODE
KMT_FH_RECORD_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
NEW_RECORD,
END_OF_FILE,
WORD TEXT_TYPE, @ 0 = EBCDIC @
@ 1 = IA5 @
@ 2 = BINARY @
INT MAX_RECORD_LENGTH,
RECORD_LENGTH,
(4098) BYTE RECORD); @ Maximum record size of 4096 @
@ plus 2 bytes for CRLF pair @
@ when constructing output @
@ records @
MODE
KMT_FH_FILE_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
INT OUTPUT_TOTAL);
MODE
KMT_FH_FILE_DETAILS_S IS STRUCT (
LONG WORD FILE_CURRENCY,
BOOL NEW_FILE,
KMT_FH_FILE_OPTIONS_S FILE_OPTION,
CTM_ACCESS_1 ACCESS_1,
CTM_ACCESS_2 ACCESS_2);
MODE
KMT_MTM_VALUES IS ANY (
LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF () BYTE RVB_VALUE,
REF () REF () BYTE RVRVB_VALUE);
***PAGE
@******************************************************************************@
@* *@
@* External procedure references *@
@* *@
@******************************************************************************@
EXT (<PREFIX "ICLCTM">)
PROC
(REF LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_NAME @
REF () BYTE, @ FULL_FILE_NAME @
RESPONSE @ RESPONSE @
) CTM_ASSIGN_FILE;
EXT (<PREFIX "ICLCTM">)
PROC
(REF LONG WORD, @ NEW_FILE_CURRENCY @
REF () BYTE, @ NEW_FILE_LOCAL_NAME @
LONG WORD, @ FILE_CURRENCY, @
REF () BYTE, @ FILE_LOCAL_NAME @
REF () BYTE, @ FULL_FILE_NAME @
LONG WORD, @ DESCRIPTION_CURRENCY @
REF () BYTE, @ DESCRIPTION_LOCAL_NAME @
REF () BYTE, @ FULL_DESCRIPTION_NAME @
INT, @ INITIAL_SIZE @
INT, @ MAXIMUM_SIZE @
INT, @ OPTION @
RESPONSE @ RESPONSE @
) CTM_GET_FILE;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_NAME @
RESPONSE @ RESPONSE @
) CTM_SAVE_FILE;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_NAME @
REF () BYTE, @ FULL_FILE_NAME @
REF () WORD, @ PROPERTIES @
RESPONSE @ RESPONSE @
) CTM_READ_DESC;
EXT (<PREFIX "ICLCTM">)
PROC
(RESPONSE @ RESPONSE @
) CTM_SCHEDULE;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_NAME @
REF () CTM_PARAMETER_PAIRS, @ PARAMETER_PAIRS @
RESPONSE @ RESPONSE @
) CTM_SELECT_RAM;
EXT (<PREFIX "ICLCTM">)
PROC
(LONG WORD, @ FILE_CURRENCY @
REF () BYTE, @ FILE_LOCAL_CURRENCY @
REF () BYTE, @ FULL_FILE_NAME @
REF INT, @ NAME_LENGTH @
RESPONSE @ RESPONSE @
) CTM_GIVE_NAME;
EXT
PROC
(INT, @ TYPE @
REF () KMT_MTM_VALUES @ PARAMS @
) KMT_SP_LOG_TRACE_MESSAGE;
EXT
PROC
(INT, @ RESULT_CODE @
WORD, @ DESTINATION @
REF () KMT_MTM_VALUES, @ PARAMS @
LONG WORD, @ PE_CONTINGENCY_MESSAGE @
BOOL, @ DUMP @
BOOL @ UNRECOVERABLE @
) KMT_EH_LOG_ERROR;
***PAGE
@******************************************************************************@
@* *@
@* External data references *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
***LINES(4)
@ Variables: @
@ ********** @
EXT (<CASCADE>)
REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
EXT (<CASCADE>)
REF KMT_FH_RECORD_DETAILS_S KMT_FH_RECORD_DETAILS;
EXT (<CASCADE>)
REF KMT_FH_FILE_STATISTICS_S KMT_FH_FILE_STATISTICS;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Static data declarations *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
***LINES(4)
@ Variables: @
@ ********** @
STATIC
KMT_FH_FILE_DETAILS_S KMT_FH_FILE_DETAILS;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Procedure declarations *@
@* *@
@******************************************************************************@
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_OPEN_FILE IS (
REF () BYTE FILE_NAME,
WORD OPTION,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to create (if required), assign and open the data *@
@* file specified by FILE_NAME for read or write access depending upon the *@
@* value of OPTION. *@
@* *@
@******************************************************************************@
BEGIN
INT FC_CTM_FILE_ALREADY_EXISTS IS 9113,
FC_CTM_FILE_DOES_NOT_EXIST IS 9114,
FC_CTM_NEW_FILE_WARNING IS -44900;
INT KMT_EH_SOFTWARE_ERROR IS 80101;
REF LONG WORD FILE_CURRENCY IS KMT_FH_FILE_DETAILS.FILE_CURRENCY;
REF KMT_FH_FILE_OPTIONS_S FILE_OPTION IS KMT_FH_FILE_DETAILS.FILE_OPTION;
FILE_OPTION := (WORD: X'01') SCALE OPTION;
IF
(
IF
FILE_OPTION.READ
THEN @ Read @
CTM_ASSIGN_FILE (FILE_CURRENCY,
NIL,
FILE_NAME,
RESULT)
ELSE @ Write @
CTM_GET_FILE (FILE_CURRENCY,
NIL,
0,
NIL,
FILE_NAME,
0,
NIL,
NIL,
-1,
-1,
(IF
(FILE_OPTION & X"0E") NE 0
THEN @ Create, create_replace or @
@ create_append @
0
ELSE @ Replace, replace_create, @
@ append or append_create @
2
FI),
RESULT);
IF
(RESULT EQ 0) AND FILE_OPTION.CREATE
THEN @ Create but file already @
@ exists @
RESULT := FC_CTM_FILE_ALREADY_EXISTS
ELSF
(RESULT EQ FC_CTM_NEW_FILE_WARNING) AND (FILE_OPTION & X"50" NE 0)
THEN @ Replace or append but file @
@ does not exist @
RESULT := FC_CTM_FILE_DOES_NOT_EXIST
FI
FI;
KMT_FH_FILE_DETAILS.NEW_FILE := (RESULT EQ FC_CTM_NEW_FILE_WARNING);
RESULT LE 0
)
AND
(
CTM_SCHEDULE (RESULT);
RESULT LE 0
)
AND
(
() CTM_PARAMETER_PAIRS PARAMETER_PAIRS :=
((7, KMT_FH_RECORD_DETAILS.RECORD
AS CTM_PARAMETER_VALUES.STRING_VALUE),
(9, KMT_FH_RECORD_DETAILS.RECORD_LENGTH
AS CTM_PARAMETER_VALUES.REF_INT_VALUE),
(12, (IF
FILE_OPTION.READ
THEN @ Read @
1 @ Select and read @
ELSE @ Write @
2 @ Select and new write @
FI)
AS CTM_PARAMETER_VALUES.INT_VALUE),
(19, KMT_FH_FILE_DETAILS.ACCESS_2
AS CTM_PARAMETER_VALUES.REF_ACCESS_2_VALUE),
(24, KMT_FH_FILE_DETAILS.ACCESS_1
AS CTM_PARAMETER_VALUES.REF_ACCESS_1_VALUE),
(29, (IF
(FILE_OPTION & X"C8") NE 0
THEN @ Append @
3 @ End of file @
ELSE @ Read, create or replace @
2 @ Beginning of file @
FI)
AS CTM_PARAMETER_VALUES.INT_VALUE)
);
CTM_SELECT_RAM (FILE_CURRENCY,
NIL,
PARAMETER_PAIRS,
RESULT);
RESULT LE 0
)
AND
(
IF
(FILE_OPTION & X"34") NE 0
THEN @ Replacing file, @
@ destroy file contents @
() CTM_PARAMETER_PAIRS PARAMETER_PAIRS :=
DISPLAY((0, 11 @ Extended destroy @
AS CTM_PARAMETER_VALUES.INT_VALUE)
);
KMT_FH_FILE_DETAILS.ACCESS_1 (PARAMETER_PAIRS,
RESULT)
FI;
RESULT LE 0
)
THEN
WORD R_LEN IS LENGTH KMT_FH_RECORD_DETAILS.RECORD - 2;
@ Allows for CRLF end of @
@ record terminator @
() WORD PROPERTIES := (104, @ Maximum record size @
0,
0);
KMT_FH_RECORD_DETAILS.MAX_RECORD_LENGTH := IF
(
CTM_READ_DESC (
FILE_CURRENCY,
NIL,
NIL,
PROPERTIES,
RESULT);
RESULT EQ 0
)
AND
PROPERTIES(1) LT R_LEN
THEN
PROPERTIES(1)
ELSE
R_LEN
FI
FI;
IF
RESULT LE 0
THEN @ File opened successfully @
KMT_FH_RECORD_DETAILS.FILE_OPEN := TRUE;
KMT_FH_RECORD_DETAILS.NEW_RECORD := TRUE;
KMT_FH_RECORD_DETAILS.END_OF_FILE := FALSE;
KMT_FH_FILE_STATISTICS := (0,0);
RESULT := 0 @ Ignore warnings @
ELSE (<RARELY>) @ Open error @
(
() BYTE PROC_NAME := "KMT_FH_OPEN_FILE";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_FH_RECORD_DETAILS.FILE_OPEN := FALSE;
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
FI
END; @ KMT_FH_OPEN_FILE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_CLOSE_FILE IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to close the file previously opened by the *@
@* KMT_FH_OPEN_FILE. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
REF BOOL FILE_OPEN IS KMT_FH_RECORD_DETAILS.FILE_OPEN;
RESULT := 0;
IF
FILE_OPEN
THEN @ File open, close it @
INT RC;
() CTM_PARAMETER_PAIRS PARAMETER_PAIRS :=
DISPLAY((0, 12 @ Deselect RAM @
AS CTM_PARAMETER_VALUES.INT_VALUE)
);
@ When receiving a binary @
@ file, must output last @
@ record to file @
IF
KMT_FH_FILE_DETAILS.FILE_OPTION.READ
OR
KMT_FH_RECORD_DETAILS.TEXT_TYPE NE 2
OR
KMT_FH_RECORD_DETAILS.NEW_RECORD
THEN @ File open for reading, not @
@ a binary file or @
RC := 0 @ no record to output @
ELSE @ Flush remaining buffer @
KMT_FH_WRITE (RC)
FI;
IF
(
KMT_FH_FILE_DETAILS.ACCESS_1 (PARAMETER_PAIRS,
RESULT);
RESULT GT 0
)
THEN (<RARELY>) @ Close error @
(
() BYTE PROC_NAME := "KMT_FH_CLOSE_FILE";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE
RESULT := RC
FI;
FILE_OPEN := FALSE
FI
END; @ KMT_FH_CLOSE_FILE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_READ IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to read a record from the file previously opened *@
@* (for read access) by the procedure KMT_FH_OPEN_FILE. *@
@* The record and length are returned in the areas *@
@* KMT_FH_RECORD_DETAILS.RECORD and KMT_FH_RECORD.DETAILS.RECORD_LENGTH *@
@* respectively. *@
@* *@
@******************************************************************************@
BEGIN
INT DML_READ_PSEUDO_NODE IS 9034;
INT KMT_FH_RECORD_IN_MSG IS 200,
KMT_EH_SOFTWARE_ERROR IS 80101,
KMT_FH_RECORD_TOO_BIG IS 80200;
REF INT RECORD_LENGTH IS KMT_FH_RECORD_DETAILS.RECORD_LENGTH;
REF () BYTE RECORD IS KMT_FH_RECORD_DETAILS.RECORD;
IF
(
KMT_FH_FILE_DETAILS.ACCESS_2 (RESULT);
RESULT LE 0
)
THEN @ Read successful @
REF INT MAX_RECORD_LENGTH IS KMT_FH_RECORD_DETAILS.MAX_RECORD_LENGTH;
BOOL TRACING IS KMT_TRACE_FLAGS.FH_TRACING;
REF INT STATISTICS IS KMT_FH_FILE_STATISTICS.INPUT_TOTAL;
STATISTICS := STATISTICS + 1;
IF
RECORD_LENGTH GT MAX_RECORD_LENGTH
THEN (<RARELY>) @ Record exceeds buffer size @
(
() KMT_MTM_VALUES PARAMS := (RECORD_LENGTH
AS KMT_MTM_VALUES.RI_VALUE,
MAX_RECORD_LENGTH
AS KMT_MTM_VALUES.RI_VALUE);
RESULT := KMT_FH_RECORD_TOO_BIG;
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RECORD_LENGTH := MAX_RECORD_LENGTH
)
ELSE @ Ignore warnings @
RESULT := 0
FI;
IF
TRACING
THEN (<RARELY>)
(
() KMT_MTM_VALUES PARAMS := DISPLAY(RECORD(SIZE RECORD_LENGTH)
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (KMT_FH_RECORD_IN_MSG,
PARAMS)
)
FI
ELSF
(
RECORD_LENGTH := 0;
RESULT EQ DML_READ_PSEUDO_NODE
)
THEN @ End of file reached @
SKIP
ELSE (<RARELY>) @ Read error @
(
() BYTE PROC_NAME := "KMT_FH_READ";
() BYTE ERROR_TEXT := " WHILST READING FROM FILE";
() KMT_MTM_VALUES PARAMS := (PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE,
ERROR_TEXT
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
FI
END; @ KMT_FH_READ @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_WRITE IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to write a record to the file previously opened *@
@* (for write access) by the procedure KMT_FH_OPEN_FILE. *@
@* The record to be output and length are contained in the areas *@
@* KMT_FH_RECORD_DETAILS.RECORD and KMT_FH_RECORD_DETAILS.RECORD_LENGTH *@
@* respectively. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_FH_RECORD_OUT_MSG IS 201,
KMT_EH_SOFTWARE_ERROR IS 80101;
IF
(
KMT_FH_FILE_DETAILS.ACCESS_2 (RESULT);
RESULT LE 0
)
THEN @ Write successful @
BOOL TRACING IS KMT_TRACE_FLAGS.FH_TRACING;
REF INT STATISTICS IS KMT_FH_FILE_STATISTICS.OUTPUT_TOTAL;
STATISTICS := STATISTICS + 1;
IF
TRACING
THEN (<RARELY>)
(
() KMT_MTM_VALUES PARAMS := DISPLAY(
KMT_FH_RECORD_DETAILS.RECORD(SIZE
KMT_FH_RECORD_DETAILS.RECORD_LENGTH)
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (KMT_FH_RECORD_OUT_MSG,
PARAMS)
)
FI;
RESULT := 0 @ Ignore warnings @
ELSE (<RARELY>) @ Write error @
(
() BYTE PROC_NAME := "KMT_FH_WRITE";
() BYTE ERROR_TEXT := " WHILST WRITING TO FILE";
() KMT_MTM_VALUES PARAMS := (PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE,
ERROR_TEXT
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
FI
END; @ KMT_FH_WRITE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_SAVE_FILE IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to save the file previously opened by the procedure *@
@* KMT_FH_OPEN_FILE. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
IF
KMT_FH_FILE_DETAILS.NEW_FILE
AND
(
CTM_SAVE_FILE (KMT_FH_FILE_DETAILS.FILE_CURRENCY,
NIL,
RESULT);
RESULT GT 0
)
THEN (<RARELY>) @ Save error @
(
() BYTE PROC_NAME := "KMT_FH_SAVE_FILE";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSE @ Ignore warnings @
RESULT := 0
FI
END; @ KMT_FH_SAVE_FILE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_FH_GIVE_NAME IS (
REF () BYTE NAME,
REF INT NAME_LENGTH,
BOOL FULL_NAME,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to obtain either the full file name or the terminal *@
@* file name of the file previously opened by KMT_FH_OPEN_FILE. *@
@* The name of the file and length are returned in the areas referenced by *@
@* NAME and NAME_LENGTH respectively. *@
@* If FULL_NAME is set TRUE then the full file name will be returned, *@
@* otherwise the terminal file name will be returned. *@
@* If the area referenced by NAME is too small to contain the file name then *@
@* the file name will be truncated and resultcode FC_CTM_BUFFER_TOO_SHORT *@
@* returned. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_EH_SOFTWARE_ERROR IS 80101;
IF
(
CTM_GIVE_NAME (KMT_FH_FILE_DETAILS.FILE_CURRENCY,
NIL,
NAME,
NAME_LENGTH,
RESULT);
RESULT GT 0
)
THEN (<RARELY>) @ Error @
(
() BYTE PROC_NAME := "KMT_FH_GIVE_NAME";
() KMT_MTM_VALUES PARAMS := DISPLAY(PROC_NAME
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE);
RESULT := KMT_EH_SOFTWARE_ERROR
)
ELSF
FULL_NAME
THEN @ Full file name required @
@ Exit @
SKIP
ELSF
NAME_LENGTH EQ 0
THEN @ No file name returned, exit @
SKIP
ELSE @ Terminal file name required @
() BYTE NAME_COPY := NAME(SIZE NAME_LENGTH);
REF () BYTE TERMINAL_NAME,
REM;
TERMINAL_NAME := NAME_COPY;
REM := TERMINAL_NAME;
UNTIL @ Search for part of name @
SCANUNQ (".", @ after last dot @
REM,
0,
REM)
DO
REM := REM(1::);
TERMINAL_NAME := REM
REPEAT;
SCANUNQ ("(", @ Remove generation number @
TERMINAL_NAME,
0,
REM);
NAME_LENGTH := LENGTH TERMINAL_NAME - LENGTH REM;
NAME(SIZE NAME_LENGTH) := TERMINAL_NAME(SIZE NAME_LENGTH);
RESULT := 0
FI;
END; @ KMT_FH_GIVE_NAME @
ENDMODULE @ KMT_FH_MODULE @
$$$$ KMT_MAIN_MODULE
MODULE KMT_MAIN_MODULE; @ Version 1.01 @
@------------------------------------------------------------------------------@
@ @
@ @
@ ----- S W U R C C V M E K E R M I T ----- @
@ @
@ @
@ ---------------------------------------------------------------- @
@ @
@ @
@ Version 1.00 (February 1986) @
@ @
@ Written by : Richard Andrews and David Lord, @
@ South West Universities Regional Computer Centre, @
@ Claverton Down, Bath BA2 7AY, U.K. @
@ @
@ @
@ ---------------------------------------------------------------- @
@ @
@ @
@ Version 1.01 (October 1986) @
@ @
@ Fixes by : Dave Allum and David Lord, SWURCC. @
@ @
@ 1. The BOOL variable ASG_ROUTE is set by reading the BOOL ASG @
@ set in the interface procedure KERMIT. (If the BOOL ASG is @
@ not found ASG_ROUTE is set FALSE). ASG_ROUTE is used when @
@ checking valid characters for START-OF-PACKET etc. VME I/O @
@ cannot handle all control characters, the ASG can handle @
@ more than other communications controllers (eg NIC and CSC). @
@ @
@ 2. A warning message informs the user that VME KERMIT doesn't @
@ use the standard Kermit START-OF-PACKET character. @
@ @
@ 3. Attempts to set START-OF-PACKET, END-OF-LINE or PAD-CHARACTER @
@ to a character that cannot be handled by VME I/O are trapped. @
@ @
@ 4. VME KERMIT now does 8th bit prefixing correctly. @
@ @
@ 5. The EOF packet sent by VME KERMIT no longer contains the @
@ data field from the last Data packet sent. @
@ @
@ 6. The DELAY timer now works properly. Previously if the micro @
@ Kermit sent a Nak before the DELAY timer had expired a VME @
@ break-in occurred. @
@ @
@ 7. VME KERMIT in SERVER mode no longer sends the name of the @
@ first file sent in the File_Hdr packet for second (and @
@ subsequent) files requested via GET command on the remote @
@ Kermit. @
@ @
@ 8. VME KERMIT can now receive a batch of files sent by a micro @
@ Kermit using a wildcard send. Previously VME Kermit output @
@ several generations of the same filename. @
@ @
@ 9. The way VME KERMIT standardises filenames has been improved. @
@ (VME filenames don't conform to the form 'name.type' as @
@ in the Kermit protocol: see KMT_SP_STANDARDISE_FILENAME) @
@ @
@ 10. Resources are released after each transfer so that a file @
@ that has just been sent to VME can be accessed by other users. @
@ @
@ 11. The DEBUG information at PACKET level is now in a more @
@ readable form. @
@ @
@------------------------------------------------------------------------------@
@ Mode declarations: @
MODE KMT_BUFFER IS (96)BYTE;
MODE KMT_STRING IS REF()BYTE;
MODE KMT_WORD IS REF()BYTE;
MODE KMT_MTM_VALUES IS ANY
(LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF()BYTE RVB_VALUE,
REF()REF()BYTE RVRVB_VALUE);
MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
(INT INPUT_TOTAL,
OUTPUT_TOTAL);
@ External procedures @
EXT PROC (RESPONSE) KMT_UI;
EXT PROC (REF INT,INT,RESPONSE) KMT_PH;
EXT PROC (REF INT,REF INT,RESPONSE) KMT_PP_GET_PACKET,
PROC (INT,INT,BOOL,RESPONSE) KMT_PP_SEND_PACKET,
PROC (REF()BYTE,RESPONSE) KMT_PP_BUILD_STRING_PACKET_DATA;
EXT PROC (RESPONSE) KMT_DH_OPEN_FILE,
PROC (RESPONSE) KMT_DH_CLOSE_FILE;
EXT PROC (RESPONSE) KMT_EH_INFORM_PE_CONTINGENCY;
EXT PROC (RESPONSE) KMT_FH_CLOSE_FILE,
PROC (RESPONSE) KMT_FH_SAVE_FILE;
EXT PROC (INT,REF()KMT_MTM_VALUES) INT KMT_SP_MTM;
EXT PROC (REF KMT_STRING) KMT_WORD KMT_SP_GET_WORD;
EXT PROC () KMT_SP_SET_DEFAULTS;
EXT PROC (INT,REF()KMT_MTM_VALUES) KMT_SP_LOG_TRACE_MESSAGE;
EXT (<PREFIX "ICLCTM">)
PROC () ENDJOB;
EXT (<PREFIX "ICLCTM">)
PROC (WORD,WORD,REF()BYTE,RESPONSE) CTM_LOG;
EXT (<PREFIX "ICLCTM">)
PROC (RESPONSE) CTM_JS_BEGIN;
EXT (<PREFIX "ICLCTM">)
PROC (RESPONSE) CTM_JS_END;
EXT (<PREFIX "ICLCTM">)
PROC (REF () BYTE,LONG WORD,REF () WORD,REF LONG LONG WORD,RESPONSE)
CTM_JS_CALL;
EXT (<PREFIX "ICLCTM">)
PROC (REF () BYTE,REF LONG INT,REF () BYTE,REF BOOL,RESPONSE)
CTM_JS_READ;
@ External constants: @
EXT INT UNSET,EXIT,LOGOUT,FATAL_ERROR; @ Miscellaneous constants @
EXT INT SERVER_MODE,COMMAND_MODE;
EXT INT REC_SERVER_IDLE,REC_INIT,SEND_INIT,ENTRY,ABORT,COMPLETE;
EXT INT ERROR_PKT;
@ External variables @
EXT REF () BYTE KMT_VERSION;
EXT REF BOOL ASG_ROUTE;
EXT REF()KMT_MTM_VALUES KMT_MTM_AREA;
EXT REF()BYTE MTM_TEXT;
EXT REF INT MTM_TEXT_LEN;
EXT REF ()REF ()BYTE MTM_RECALL_DATA;
EXT REF INT RC_IGNORED;
EXT REF INT PKT_SEQ,PKT_NO,PKT_TYPE;
EXT REF BOOL SAVE_INCOMPLETE_FILE;
EXT REF INT RETRY_COUNT,TIMEOUT_TOTAL;
EXT REF INT EXIT_STATE,KMT_CURRENT_MODE,KMT_PH_STATE;
EXT REF KMT_BUFFER KMT_VME_FILE_BUF,KMT_REM_FILE_BUF;
EXT REF KMT_WORD KMT_VME_FILE,KMT_REM_FILE;
GLOBAL STATIC PROC KMT_MESSAGE IS (INT MSG_NO,RESPONSE RESULT):
@ outputs messages to terminal and journal file @
@ if error returned from protocol handler, an error packet is sent @
BEGIN
INT REPLY := UNSET,
M := IF MSG_NO > 0
THEN MSG_NO
ELSE -MSG_NO @ warning message codes are negative @
FI;
RESULT := 0;
WHILE REPLY = UNSET
DO @ expand message @
REPLY := KMT_SP_MTM(M,KMT_MTM_AREA);
IF REPLY = -1 OR REPLY = 0
THEN
CTM_LOG(3,6,MTM_TEXT(SIZE MTM_TEXT_LEN),RC_IGNORED);
IF M = MSG_NO @ 1st message text from error number @
THEN @ protocol handler error, send 1st message in error pkt @
KMT_PP_BUILD_STRING_PACKET_DATA(MTM_TEXT(SIZE MTM_TEXT_LEN),
RC_IGNORED);
KMT_PP_SEND_PACKET(ERROR_PKT,PKT_SEQ,FALSE,RC_IGNORED);
IF RC_IGNORED > 0
THEN @ fatal error sending packet! - continue expansion @
@ of current message, but ensure abort afterwards @
KMT_PH_STATE := ABORT; @ set abort state @
EXIT_STATE := FATAL_ERROR;
RESULT := -89061
FI
FI;
IF REPLY = 0 AND RESULT NE 0
THEN @ error sending packet, record message @
M := -RESULT; RESULT := 0 @ zero result always returned @
ELSE
M := REPLY @ continue message text expansion @
FI
FI
REPEAT
END
; @ KMT_MESSAGE @
STATIC PROC KERMIT_SUPPORT IS (REF () BYTE OPTION,REF () BYTE VME_FILE,
REF () BYTE REM_FILE,RESPONSE RESULT):
BEGIN
INT KMT_OPTION; @ mode supplied on entry to Kermit @
PROC VALIDATE_ARGS IS (RESPONSE RESULT):
@ checks Kermit option and verifies that file arguments are @
@ present for Receive or Send options @
@ sets initial protocal handler state (where appropriate) @
BEGIN @ remove leading and trailing spaces from filenames @
()BYTE VME_BUF := VME_FILE;
KMT_WORD VME_PTR := VME_BUF;
()BYTE REM_BUF := REM_FILE;
KMT_WORD REM_PTR := REM_BUF;
KMT_VME_FILE := KMT_SP_GET_WORD(VME_PTR);
KMT_REM_FILE := KMT_SP_GET_WORD(REM_PTR);
KMT_MTM_AREA(3) := OPTION AS KMT_MTM_VALUES.RVB_VALUE;
KMT_OPTION := KMT_CURRENT_MODE :=
KMT_SP_MTM(5000,KMT_MTM_AREA(SIZE 4)); @ validate option @
RESULT := 0;
CASE KMT_OPTION
THEN @ Server - no file args should be present @
KMT_PH_STATE := REC_SERVER_IDLE;
UNLESS KMT_VME_FILE REF NIL AND KMT_REM_FILE REF NIL
DO
KMT_VME_FILE := NIL;
KMT_REM_FILE := NIL;
RESULT := -85000 @ warning @
FI
ELSE @ Receive - VME_FILE may be present but not REM_FILE @
KMT_PH_STATE := REC_INIT;
UNLESS KMT_VME_FILE REF NIL
DO
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE
FI;
UNLESS KMT_REM_FILE REF NIL
DO
KMT_REM_FILE := NIL;
RESULT := -85001 @ warning @
FI
ELSE @ Send - VME_FILE must be present, REM_FILE is optional @
KMT_PH_STATE := SEND_INIT;
IF KMT_VME_FILE REF NIL
THEN
EXIT_STATE := FATAL_ERROR;
RESULT := -85010 @ error @
ELSE
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH VME_FILE):=
KMT_VME_FILE;
UNLESS KMT_REM_FILE REF NIL
DO
KMT_REM_FILE :=
KMT_REM_FILE_BUF(SIZE LENGTH KMT_REM_FILE) :=
KMT_REM_FILE
FI
FI
ELSE @ Command - no file arguments should be present @
KMT_PH_STATE := UNSET;
UNLESS KMT_VME_FILE REF NIL AND KMT_REM_FILE REF NIL
DO
KMT_VME_FILE := NIL;
KMT_REM_FILE := NIL;
RESULT := -85000 @ warning @
FI
DEFAULT @ invalid entry mode @
EXIT_STATE := FATAL_ERROR;
RESULT := -85020
ESAC
END
; @ VALIDATE_ARGS @
PROC CLOSE_FILES IS (RESPONSE RESULT):
@ close Kermit Send/Receive files when aborting @
BEGIN
INT RC;
KMT_FH_CLOSE_FILE(RC);
RESULT := IF RC <= 0
THEN 0 @ ignore -ve warnings @
ELSE 89042 @ error closing file @
FI;
IF SAVE_INCOMPLETE_FILE
THEN
KMT_FH_SAVE_FILE(RC);
IF RC > 0
THEN RESULT := 89044 @ error saving file @
FI
FI;
KMT_VME_FILE := NIL;
KMT_REM_FILE := NIL
END
; @ CLOSE_FILES @
@ main Kermit segment @
EXIT_STATE := UNSET;
KMT_SP_SET_DEFAULTS();
@ initialise message text area @
KMT_MTM_AREA(SIZE 3) :=
(MTM_TEXT AS KMT_MTM_VALUES.RVB_VALUE,
MTM_TEXT_LEN AS KMT_MTM_VALUES.RI_VALUE,
MTM_RECALL_DATA AS KMT_MTM_VALUES.RVRVB_VALUE);
KMT_MTM_AREA(3 SIZE 2) := (1 AS KMT_MTM_VALUES.LI_VALUE,
KMT_VERSION AS KMT_MTM_VALUES.RVB_VALUE);
KMT_MESSAGE(-1,RC_IGNORED); @ output banners @
KMT_SP_LOG_TRACE_MESSAGE(2,NIL);
VALIDATE_ARGS(RESULT);
IF RESULT NE 0
THEN @ output message & continue (n.b. exit state may be fatal_error) @
KMT_MESSAGE(RESULT,RESULT)
FI;
KMT_DH_OPEN_FILE(RESULT);
IF RESULT NE 0
THEN
KMT_MESSAGE(RESULT,RESULT);
EXIT_STATE := FATAL_ERROR
FI;
IF CTM_JS_BEGIN(RESULT); @ start new SCL block @
RESULT > 0
THEN
EXIT_STATE := FATAL_ERROR
FI;
IF EXIT_STATE = UNSET
THEN @ notify user of non-standard START-OF-PACKET @
KMT_MESSAGE(-3,RC_IGNORED)
FI;
WHILE EXIT_STATE = UNSET
DO
RESULT := 0; @ everything ok at this point @
IF KMT_CURRENT_MODE = COMMAND_MODE
THEN @ get command from user, if command is SERVER, SEND or RECEIVE @
@ then KMT_CURRENT_MODE and KMT_PH_STATE will be reset @
KMT_UI(RESULT);
IF RESULT NE 0
THEN
KMT_MESSAGE(RESULT,RESULT)
FI
ELSE @ sending or receiving, carry out action on entry to protocol @
@ handler state, wait for a packet, then carry out action in @
@ response to type of packet received @
KMT_PH(KMT_PH_STATE,ENTRY,RESULT);
IF RESULT = 0
THEN
KMT_PP_GET_PACKET(PKT_TYPE,PKT_NO,RESULT);
IF RESULT = 39854 @ timeout @
THEN
TIMEOUT_TOTAL := TIMEOUT_TOTAL + 1;
RESULT := 0
FI;
IF RESULT <= 0
THEN @ warning message already ouput, continue @
RESULT := 0;
KMT_PH(KMT_PH_STATE,PKT_TYPE,RESULT)
FI
FI;
IF RESULT NE 0
THEN
KMT_MESSAGE(RESULT,RESULT)
FI;
IF KMT_PH_STATE = ABORT
THEN
CLOSE_FILES(RESULT);
IF RESULT NE 0
THEN
KMT_MESSAGE(RESULT,RESULT)
FI;
KMT_PH_STATE := COMPLETE
FI;
IF KMT_PH_STATE = COMPLETE
THEN
IF CTM_JS_END(RESULT); @ close current SCL block @
RESULT > 0
THEN
EXIT_STATE := FATAL_ERROR
ELSF CTM_JS_BEGIN(RESULT); @ open new SCL block @
RESULT > 0
THEN
EXIT_STATE := FATAL_ERROR
ELSE
PKT_SEQ := 0; @ zero packet sequence @
IF KMT_CURRENT_MODE = SERVER_MODE
THEN @ remain in Server mode until EXIT_STATE is set @
@ (may already have been set by Server Generic command) @
KMT_PH_STATE := REC_SERVER_IDLE;
RETRY_COUNT := 0
ELSF KMT_OPTION = COMMAND_MODE
THEN @ resume Command mode on completion of Send/Receive @
KMT_CURRENT_MODE := COMMAND_MODE
ELSE @ Send or Receive specified in VME command, exit on @
EXIT_STATE := EXIT @ completion @
FI
FI
FI
FI
REPEAT;
CTM_JS_END(RC_IGNORED); @ close current SCL block @
KMT_DH_CLOSE_FILE(RC_IGNORED); @ close logging files @
IF EXIT_STATE = FATAL_ERROR
THEN
KMT_MESSAGE(-85030,RC_IGNORED) @ tell user @
ELSF EXIT_STATE = LOGOUT
THEN @ log out Kermit after receiving Generic Logout command @
KMT_MESSAGE(-85031,RC_IGNORED);
ENDJOB()
ELSE
KMT_MESSAGE(-85032,RC_IGNORED) @ output newline @
FI
END
; @ KERMIT_SUPPORT @
GLOBAL STATIC (<STATUS 5;PSPACE 10001; TEMPLATE>) PROC KERMIT_THE_FROG IS
((<LIT "COMMAND">) REF()BYTE OPTION,
(<LIT "" >) REF()BYTE VME_FILE,
(<LIT "" >) REF()BYTE REM_FILE,
(<KEY RESPONSE;DEF N'RESULT>) RESPONSE RESULT):
BEGIN
()BYTE JSV_NAME := "ASG"; @ obtain value for ASG_ROUTE bool @
CTM_JS_READ(JSV_NAME,NIL,NIL,ASG_ROUTE,RC_IGNORED);
IF RC_IGNORED NE 0 THEN ASG_ROUTE := FALSE FI;
@ verify parameter references (parameter values validated later): @
@ OPTION must be of mode REF () BYTE, may not be ZLR or NIL @
@ VME_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL @
@ REM_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL @
UNLESS (VERIFY OPTION AND VALIDR OPTION)
AND (VERIFY VME_FILE AND (VALIDR VME_FILE OR NOT(VME_FILE IS NIL)))
AND (VERIFY REM_FILE AND (VALIDR REM_FILE OR NOT(REM_FILE IS NIL)))
THEN @ invalid parameter reference @
RESULT := 10002 @ ARCH_INACCESSIBLE_PARAMETER @
ELSF @ create resource block @
CTM_JS_BEGIN(RESULT);
RESULT <= 0
THEN @ resource block created @
LONG LONG WORD KERMIT_RESULT;
ANY((3)LONG WORD AS_LW,(6) WORD AS_W) PARAMS;
PARAMS.AS_LW := (BDESC OPTION,BDESC VME_FILE,BDESC REM_FILE);
@ set up program error handler @
IF KMT_EH_INFORM_PE_CONTINGENCY(RESULT);
RESULT > 0
THEN @ failed to set error handler @
SKIP
ELSF CTM_JS_CALL(NIL,PDESC KERMIT_SUPPORT,PARAMS.AS_W,KERMIT_RESULT,
RESULT); @ create firewall @
RESULT <= 0
THEN @ either exited normally or via CTM_STOP @
RESULT := IF (S'S'KERMIT_RESULT) <= 0
THEN 0 @ ignore warnings @
ELSE 52000 @ error return common resultcode @
FI
FI;
CTM_JS_END(RC_IGNORED) @ end resource block @
FI
END
; @ KERMIT_THE_FROG @
ENDMODULE @ KMT_MAIN_MODULE @
$$$$ KMT_PH_MODULE
MODULE KMT_PH_MODULE;
@ VME KERMIT PROTOCOL HANDLER @
@ GLOBAL VARIABLES @
@ PKT_TYPE : packet type of current packet @
@ KMT_PH_INPUT_PACKET_DATA : pointer to packet data buffer @
@ (translated to EBCDIC and decoded) @
@ PKT_SEQ : current packet number (expected) @
@ PKT_NO : current packet number (received) @
@ RETRY_COUNT : current retry count @
@ Mode declarations: @
MODE KMT_BUFFER IS (96)BYTE;
MODE KMT_STRING IS REF()BYTE;
MODE KMT_WORD IS REF()BYTE;
MODE KMT_MTUP_VALUES IS ANY
(LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF()BYTE RVB_VALUE,
REF()REF()BYTE RVRVB_VALUE);
MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
(INT INPUT_TOTAL,
OUTPUT_TOTAL);
MODE KMT_TRACE_FLAGS_S IS WORD STRUCT
(BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
@ External procedures @
EXT PROC (INT,RESPONSE) KMT_MESSAGE;
EXT PROC (RESPONSE) KMT_UI;
EXT PROC (REF()BYTE,INT,RESPONSE) KMT_FH_OPEN_FILE,
PROC (RESPONSE) KMT_FH_CLOSE_FILE,
PROC (RESPONSE) KMT_FH_SAVE_FILE,
PROC (REF()BYTE,REF INT,BOOL,RESPONSE) KMT_FH_GIVE_NAME;
EXT PROC () KMT_PP_TRANSLATE_TO_EBCDIC,
PROC (REF()BYTE,RESPONSE) KMT_PP_BUILD_STRING_PACKET_DATA,
PROC (RESPONSE) KMT_PP_PROCESS_PARAM_PACKET_DATA,
PROC () KMT_PP_BUILD_PARAM_PACKET_DATA,
PROC (RESPONSE) KMT_PP_BUILD_FILE_RECORD,
PROC (RESPONSE) KMT_PP_BUILD_FILE_PACKET_DATA,
PROC (REF INT,REF INT,RESPONSE) KMT_PP_GET_PACKET,
PROC (INT,INT,BOOL,RESPONSE) KMT_PP_SEND_PACKET;
@ Any error returned by KMT_PP_SEND_PACKET is fatal and Kermit will exit; @
@ warnings will have been logged already and are ignored @
EXT PROC (REF KMT_STRING) KMT_WORD KMT_SP_GET_WORD,
PROC (REF KMT_WORD,INT) KMT_SP_STANDARDISE_FILENAME,
PROC (INT,REF()KMT_MTUP_VALUES) KMT_SP_LOG_TRACE_MESSAGE;
EXT REF INT PKT_SEQ,PKT_NO,MAXTRY,RETRY_COUNT,RETRY_TOTAL,TIMEOUT_TOTAL,
RC_IGNORED;
EXT REF KMT_STRING KMT_PH_INPUT_PACKET_DATA;
EXT REF KMT_BUFFER KMT_VME_FILE_BUF,KMT_REM_FILE_BUF;
EXT REF KMT_WORD KMT_VME_FILE,KMT_REM_FILE;
EXT INT ENTRY,BREAK_PKT,DATA_PKT,FILE_HDR_PKT,NAK_PKT,SEND_INIT_PKT,ACK_PKT,
EOF_PKT;
EXT INT VME_TERM,VME_STD,KMT_STD; @ forms of name standardisation @
EXT INT REC_SERVER_IDLE,REC_INIT,REC_FILE,REC_DATA,SEND_INIT,SEND_FILE,
SEND_DATA,SEND_EOF,SEND_BREAK,COMPLETE,ABORT;
EXT INT EXIT,LOGOUT,FATAL_ERROR; @ exit states @
EXT INT EOF; @ eof on file data @
EXT INT SERVER_MODE;
EXT REF INT KMT_CURRENT_MODE;
EXT BOOL READ_INT,NO_READ_INT; @ set/don't set read interest after send @
EXT REF INT FILE_OPTION;
EXT REF BOOL DELAY_TIMER;
EXT REF BOOL SAVE_INCOMPLETE_FILE;
EXT REF INT EXIT_STATE;
EXT REF()KMT_MTUP_VALUES KMT_MTM_AREA;
EXT REF KMT_PP_PACKET_STATISTICS_S KMT_PP_PACKET_STATISTICS;
EXT REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
STATIC REF KMT_STRING PKT_DATA IS KMT_PH_INPUT_PACKET_DATA;
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PH IS (REF INT STATE,INT EVENT,RESPONSE RESULT):
BEGIN
@ procedures for state entry @
SIM PROC KMT_PH_REC_SERVER_IDLE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Server idle, waiting for message @
BEGIN
RETRY_COUNT := 0; @ try for ever in Rec_Server_Idle state @
RETRY_TOTAL := TIMEOUT_TOTAL := 0;
KMT_PP_PACKET_STATISTICS := (0,0);
PKT_SEQ := 0; @ initialise packet sequence @
RESULT := 0
END
; @ KMT_PH_REC_SERVER_IDLE @
SIM PROC KMT_PH_REC_INIT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Entry point for non-server RECEIVE command @
BEGIN
PKT_SEQ := 0; @ initialise packet sequence @
RESULT := 0
END
; @ KMT_PH_REC_INIT @
SIM PROC KMT_PH_REC_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Look for a file header or EOT message @
RESULT := 0 @ nothing to do on entry to Rec_File state @
; @ KMT_PH_REC_FILE @
SIM PROC KMT_PH_REC_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Receive data up to end of file @
RESULT := 0 @ nothing to do on entry to Rec_Data state @
; @ KMT_PH_REC_DATA @
SIM PROC KMT_PH_SEND_INIT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Server Send Init, also entry for non-server SEND command @
BEGIN
PKT_SEQ := 0; @ initialise packet sequence @
IF KMT_CURRENT_MODE NE SERVER_MODE AND RETRY_COUNT LE 1
THEN @ wait for user to set up remote KERMIT @
INT KMT_EH_SOFTWARE_ERROR IS 80101;
INT X_TYPE,X_NO;
DELAY_TIMER := TRUE; @ set delay timer @
KMT_PP_GET_PACKET(X_TYPE,X_NO,RESULT);@ attempt to read packet @
@ if we get a packet then they're ready to receive @
@ if the timer expires then we send regardless @
DELAY_TIMER := FALSE;
UNLESS RESULT = KMT_EH_SOFTWARE_ERROR
DO
RESULT := 0
FI
ELSE
RESULT := 0
FI;
IF RESULT = 0
THEN
KMT_PP_BUILD_PARAM_PACKET_DATA(); @ send S(0) with parameters @
KMT_PP_SEND_PACKET(SEND_INIT_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
FI
END
; @ KMT_PH_SEND_INIT @
SIM PROC KMT_PH_SEND_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send file or text header (we don't send text packets!) @
BEGIN @ send F(n) - packet made by KMT_PH_READY_FILE @
KMT_PP_SEND_PACKET(FILE_HDR_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
END
; @ KMT_PH_SEND_FILE @
SIM PROC KMT_PH_SEND_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send contents of file or textual information @
@ (we don't send text packets!) @
BEGIN @ send D(n) with current buffer (pkt made by KMT_PH_READY_DATA) @
KMT_PP_SEND_PACKET(DATA_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
END
; @ KMT_PH_SEND_DATA @
SIM PROC KMT_PH_SEND_EOF IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send end of file indicator (we don't do interrupts) @
BEGIN
KMT_VME_FILE := NIL; @ file has been closed @
KMT_REM_FILE := NIL;
@ send Z(n) - packet made by KMT_PH_READY_DATA @
KMT_PP_SEND_PACKET(EOF_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
END
; @ KMT_PH_SEND_EOF @
SIM PROC KMT_PH_SEND_BREAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ End of Transmission @
BEGIN @ send B(n) - packet made by KMT_PH_SENT_FILE @
KMT_PP_SEND_PACKET(BREAK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
END
; @ KMT_PH_SEND_BREAK @
@ procedures for expected packets @
SIM PROC KMT_PH_INIT_PARAMS IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ A Send_Init or Init packet has arrived. If the packet sequence is @
@ correct, process their parameters and ack with our parameters. @
@ If it's a repeat of their last packet, ack it again with our @
@ parameters. Otherwise, report error and in non-Server modes, abort @
IF (STATE = REC_SERVER_IDLE OR STATE = REC_INIT) AND PKT_NO = 0
THEN @ got right packet, reset retry count @
RETRY_COUNT := 0;
KMT_PP_PROCESS_PARAM_PACKET_DATA(RESULT);
IF RESULT = 0
THEN
KMT_PP_BUILD_PARAM_PACKET_DATA();
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
IF RESULT = 0 AND EVENT = SEND_INIT_PKT
THEN @ increment packet sequence @
PKT_SEQ := PKT_SEQ+1 MOD 64;
STATE := REC_FILE
FI
ELSE @ their params unacceptable @
RESULT := 89070
FI
ELSF STATE = REC_FILE AND PKT_NO+1 MOD 64 = PKT_SEQ @ i.e. P = N-1 @
THEN @ we've picked up their Send_init again, so send ack @
KMT_PP_BUILD_PARAM_PACKET_DATA();
KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
ELSE @ wrong packet sequence, error (abort if non-server) @
RESULT := 89000
FI
; @ KMT_PH_INIT_PARAMS @
SIM PROC KMT_PH_GEN_CMD IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Generic command received - some are implemented and will be @
@ executed and acknowledged - an error packet is sent for the rest @
IF PKT_NO = 0
THEN
BYTE GEN_CMD;
KMT_PP_TRANSLATE_TO_EBCDIC();
GEN_CMD := PKT_DATA(0);
RETRY_COUNT := 0; @ got right packet, reset retry count @
@ check if Generic Command implemented @
IF GEN_CMD = "F" OR GEN_CMD = "L"
THEN @ GF (Finish command): exit Server mode and terminate @
@ GL (Logout command): exit Server mode and log out @
EXIT_STATE := IF GEN_CMD = "F" THEN EXIT ELSE LOGOUT FI;
STATE := COMPLETE;
@ Generic Command successful, ack it @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
ELSE @ this Generic Command not implemented (or doesn't exist) @
RESULT := 89011
FI
ELSE @ wrong packet number, wait for their next try @
RESULT := 89000
FI
; @ KMT_PH_GEN_CMD @
SIM PROC KMT_PH_KMT_CMD IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Packet contains Kermit command, pass it to user interface (KMT_UI) @
@ for processing @
IF PKT_NO = 0
THEN
RETRY_COUNT := 0; @ got right packet, reset retry count @
@ pass command (in packet) to KMT_UI @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_TRANSLATE_TO_EBCDIC();
KMT_UI(RESULT);
IF RESULT = 0
THEN @ command has been executed successfully so ack it @
@ if there is a reply, KMT_UI has put it into packet @
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
FI
ELSE @ wrong packet number, wait for their next try @
RESULT := 89000
FI
; @ KMT_PH_KMT_CMD @
SIM PROC KMT_PH_GOT_FILENAME IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Packet contains name of file to be sent @
IF PKT_NO = 0
THEN @ got right packet, reset retry count @
RETRY_COUNT := 0;
KMT_PP_TRANSLATE_TO_EBCDIC();
KMT_VME_FILE := KMT_SP_GET_WORD(PKT_DATA); @ obtain filename @
IF NOT (KMT_VME_FILE REF NIL) @ must be present @
THEN
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE;
STATE := SEND_INIT;
RESULT := 0
ELSE @ no filename, error and abort @
RESULT := 89030
FI
ELSE @ wrong packet number, wait for their next try @
RESULT := 89000
FI
; @ KMT_PH_GOT_FILENAME @
SIM PROC KMT_PH_BREAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ End of Transmission received @
IF PKT_NO = PKT_SEQ
THEN @ correct sequence, ack it and complete @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,NO_READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
STATE := COMPLETE
ELSE @ wrong packet sequence, error abort @
RESULT := 89000
FI
; @ KMT_PH_BREAK @
SIM PROC KMT_PH_FILE_HDR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Packet contains name of file to be received @
IF PKT_NO = PKT_SEQ
THEN @ obtain filename (may have been specified in Receive command)@
KMT_PP_TRANSLATE_TO_EBCDIC();
IF KMT_VME_FILE REF NIL
THEN @ not already set @
KMT_VME_FILE := KMT_SP_GET_WORD(PKT_DATA);
IF KMT_VME_FILE REF NIL
THEN
RESULT := 80931
ELSE
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE;
RESULT := 0
FI
ELSE @ already set but verify packet contains filename @
KMT_REM_FILE := KMT_SP_GET_WORD(PKT_DATA);
RESULT := IF KMT_REM_FILE REF NIL THEN 80931 ELSE 0 FI
FI;
IF RESULT = 0
THEN @ open file @
KMT_REM_FILE := @ save copy of VME filename @
KMT_REM_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE;
@ assume filename is name.type, remove type @
KMT_SP_STANDARDISE_FILENAME(KMT_VME_FILE,VME_STD);
KMT_FH_OPEN_FILE(KMT_VME_FILE,FILE_OPTION,RESULT);
IF RESULT <= 0
THEN @ file open, log full name @
INT NAME_LENGTH;
RESULT := 0;
KMT_FH_GIVE_NAME(KMT_VME_FILE_BUF,NAME_LENGTH,TRUE,RESULT);
IF RESULT <= 0
THEN @ set VME filename to full name @
RESULT := 0;
KMT_VME_FILE := KMT_VME_FILE_BUF(SIZE NAME_LENGTH);
KMT_MTM_AREA(3) := KMT_REM_FILE AS
KMT_MTUP_VALUES.RVB_VALUE;
KMT_MTM_AREA(4) := KMT_VME_FILE AS
KMT_MTUP_VALUES.RVB_VALUE;
KMT_MESSAGE(-87002,RC_IGNORED); @ log filename @
@ ack file header including VME filename @
KMT_PP_BUILD_STRING_PACKET_DATA(KMT_VME_FILE,
RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
IF RESULT <= 0
THEN
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
STATE := REC_DATA;
RESULT := 0
ELSE
RESULT := -89061
FI
FI
ELSE @ unable to open file, reset result and abort @
RESULT := 89040
FI
FI
ELSE @ wrong packet number, abort @
RESULT := 89000
FI
; @ KMT_PH_FILE_HDR @
SIM PROC KMT_PH_GOT_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Received data packet @
IF PKT_NO = PKT_SEQ
THEN @ write data to file @
KMT_PP_BUILD_FILE_RECORD(RESULT);
IF RESULT <= 0
THEN @ ack data packet @
RESULT := 0;
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
IF RESULT <= 0
THEN
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
RESULT := 0
ELSE
RESULT := -89061
FI
ELSE @ error writing data to file, abort @
RESULT := 89046
FI
ELSF PKT_NO+1 MOD 64 = PKT_SEQ @ i.e. P = N-1 @
THEN @ we've picked up their last data packet again, so ack it @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
ELSE @ wrong packet number, error abort @
RESULT := 89000
FI
; @ KMT_PH_GOT_DATA @
SIM PROC KMT_PH_GOT_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ End of file packet received @
IF PKT_NO = PKT_SEQ
THEN
KMT_PP_TRANSLATE_TO_EBCDIC();
KMT_FH_CLOSE_FILE(RESULT); @ close file we've just rec'd @
RESULT := IF RESULT <= 0
THEN 0 @ ignore -ve warning code @
ELSE 89042 @ error closing file, abort @
FI;
IF (RESULT = 0 OR SAVE_INCOMPLETE_FILE)
AND (LENGTH PKT_DATA = 0 OR PKT_DATA(0) NE "D")
THEN @ no discard signal in packet so save file @
INT RC;
KMT_FH_SAVE_FILE(RC);
IF RC > 0
THEN RESULT := 89044 @ error saving file, abort @
FI
FI;
IF RESULT = 0
THEN
KMT_VME_FILE := NIL;
KMT_REM_FILE := NIL;
@ no problems closing file, so ack eof @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
IF RESULT <= 0
THEN
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
STATE := REC_FILE;
RESULT := 0
ELSE
RESULT := -89061
FI
FI
ELSE @ wrong packet number, abort @
RESULT := 89000
FI
; @ KMT_PH_GOT_FILE @
SIM PROC KMT_PH_READY_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send Init has been acknowledged, open file for transfer @
IF PKT_NO = 0
THEN
KMT_PP_PROCESS_PARAM_PACKET_DATA(RESULT);
IF RESULT = 0
THEN @ open file in READ mode @
@ assume filename is name.type, remove type @
KMT_SP_STANDARDISE_FILENAME(KMT_VME_FILE,VME_STD);
KMT_FH_OPEN_FILE(KMT_VME_FILE,0,RESULT);
IF RESULT <= 0
THEN @ set up filename for file hdr packet @
INT NAME_LENGTH;
RESULT := 0;
KMT_FH_GIVE_NAME(KMT_VME_FILE_BUF,NAME_LENGTH,TRUE,RESULT);
IF RESULT <= 0
THEN
KMT_VME_FILE := KMT_VME_FILE_BUF(SIZE NAME_LENGTH);
IF KMT_REM_FILE REF NIL
THEN @ set remote filename to VME terminal name @
KMT_REM_FILE :=
KMT_REM_FILE_BUF(SIZE NAME_LENGTH) :=
KMT_VME_FILE;
KMT_SP_STANDARDISE_FILENAME(KMT_REM_FILE,VME_TERM)
ELSE @ set remote filename to Kermit Normal-Form @
KMT_SP_STANDARDISE_FILENAME(KMT_REM_FILE,KMT_STD)
FI;
@ log filenames @
KMT_MTM_AREA(3) :=
KMT_VME_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
KMT_MTM_AREA(4) :=
KMT_REM_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
KMT_MESSAGE(-87003,RC_IGNORED);
@ put filename in file header packet @
KMT_PP_BUILD_STRING_PACKET_DATA(KMT_REM_FILE,RC_IGNORED);
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
STATE := SEND_FILE;
RESULT := 0
FI
ELSE @ unable to open file, reset result and abort @
RESULT := 89041
FI
ELSE @ their params unacceptable @
RESULT := 89070
FI
FI
; @ KMT_PH_READY_FILE @
SIM PROC KMT_PH_READY_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Get data ready for transfer @
IF (EVENT = ACK_PKT AND PKT_NO = PKT_SEQ)
OR (EVENT = NAK_PKT AND PKT_NO = PKT_SEQ+1 MOD 64)
THEN
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
KMT_PP_TRANSLATE_TO_EBCDIC();
IF (LENGTH PKT_DATA = 1 AND STATE = SEND_DATA)
AND (PKT_DATA(0) = "X" OR PKT_DATA(0) = "Z")
THEN @ their ack packet requested interrupt transfer @
KMT_FH_CLOSE_FILE(RESULT); @ closing file shouldn't fail @
RESULT := IF RESULT <= 0 THEN 0 ELSE 89043 FI;
KMT_MESSAGE(-87000,RC_IGNORED); @ log cancellation of xfer @
@ set up eof packet data @
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
STATE := SEND_EOF
ELSE @ check for ack of file header, it may have filename @
IF STATE = SEND_FILE @ used by remote Kermit, if so log it @
THEN
STATE := SEND_DATA;
KMT_MTM_AREA(3) :=
KMT_VME_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
IF LENGTH PKT_DATA > 0
THEN
KMT_MTM_AREA(4) :=
PKT_DATA AS KMT_MTUP_VALUES.RVB_VALUE
ELSE
KMT_MTM_AREA(4) :=
KMT_REM_FILE AS KMT_MTUP_VALUES.RVB_VALUE
FI;
KMT_MESSAGE(-87001,RC_IGNORED)
FI;
@ set up next data packet @
KMT_PP_BUILD_FILE_PACKET_DATA(RESULT);
IF RESULT = EOF
THEN @ all data sent, close file and send eof next @
KMT_FH_CLOSE_FILE(RESULT); @ shouldn't fail @
RESULT := IF RESULT <= 0 THEN 0 ELSE 89043 FI;
STATE := SEND_EOF @ all data sent @
ELSE @ error reading from file? @
RESULT := IF RESULT <= 0 THEN 0 ELSE 89047 FI
FI
FI
ELSE
RESULT := 0
FI
; @ KMT_PH_MAKE_DATA @
SIM PROC KMT_PH_SENT_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ File sent, check ack @
BEGIN
IF (EVENT = ACK_PKT AND PKT_NO = PKT_SEQ)
OR (EVENT = NAK_PKT AND PKT_NO = PKT_SEQ+1 MOD 64)
THEN @ any more files? no - we only allow 1 per send so: @
PKT_SEQ := PKT_SEQ+1 MOD 64;
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RETRY_COUNT := 0;
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED); @ set up break @
STATE := SEND_BREAK @ packet data @
@ (ditto if previous pkt_data(0) was "Z") @
FI;
RESULT := 0
END
; @ KMT_PH_SENT_FILE @
SIM PROC KMT_PH_SEND_DONE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Break sent, check ack @
BEGIN
IF EVENT = ACK_PKT
THEN
IF PKT_NO = PKT_SEQ
THEN
STATE := COMPLETE
FI
ELSF PKT_NO = PKT_SEQ+1 MOD 64 OR PKT_NO = 0
THEN @ they've sent nak(n+1) or nak(0) @
STATE := COMPLETE
FI;
RESULT := 0
END
; @ KMT_PH_SEND_DONE @
@ procedures for unexpected packets @
SIM PROC KMT_PH_REPORT_ERR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ unexpected pkt type, send error pkt and remain in same state @
RESULT := 89000
; @ KMT_PH_REPORT_ERR @
SIM PROC KMT_PH_GOT_ERROR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ they've reported an error to us, log error message and abort @
BEGIN @ decode packet data and set up message text area for logging @
KMT_PP_TRANSLATE_TO_EBCDIC();
KMT_MTM_AREA(3) := PKT_DATA AS KMT_MTUP_VALUES.RVB_VALUE;
RESULT := -87010
END
; @ KMT_PH_GOT_ERROR @
SIM PROC KMT_PH_SEND_NAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ send nak packet @
BEGIN
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(NAK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
END
; @ KMT_PH_SEND_NAK @
SIM PROC KMT_PH_NAK_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send NAK and abort @
BEGIN
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(NAK_PKT,PKT_SEQ,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
STATE := ABORT
END
; @ KMT_PH_NAK_ABORT @
SIM PROC KMT_PH_ACK_LAST IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ if current packet is repeat of last packet then send ack @
IF PKT_NO+1 MOD 64 = PKT_SEQ @ i.e. P = N-1 @
THEN
KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
ELSE @ wrong packet sequence, error abort @
RESULT := 89000
FI
; @ KMT_PH_ACK_LAST @
SIM PROC KMT_PH_ERR_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Send error packet and abort @
RESULT := 89001
; @ KMT_PH_ERR_ABORT @
SIM PROC KMT_PH_SEND_IDLE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ the wrong type of packet (or a bad packet) has arrived while @
@ sending a file - in this case it doesn't matter @
RESULT := 0
; @ KMT_PH_SEND_IDLE @
SIM PROC KMT_PH_SET_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
@ Set ABORT state @
BEGIN
STATE := ABORT;
RESULT := 0
END
; @ KMT_PH_SET_ABORT @
@ protocol handler state event table @
(9)(15)SIM PROC GROUP KMT_PH_GRP(RESPONSE) KMT_PH_ACTION IS
((KMT_PH_REC_SERVER_IDLE , KMT_PH_REPORT_ERR , KMT_PH_REPORT_ERR ,
KMT_PH_GOT_ERROR , KMT_PH_REPORT_ERR , KMT_PH_GEN_CMD ,
KMT_PH_INIT_PARAMS , KMT_PH_KMT_CMD , KMT_PH_REPORT_ERR ,
KMT_PH_GOT_FILENAME , KMT_PH_INIT_PARAMS , KMT_PH_REPORT_ERR ,
KMT_PH_REPORT_ERR , KMT_PH_SEND_NAK , KMT_PH_REPORT_ERR),
(KMT_PH_REC_INIT , KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT ,
KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT ,
KMT_PH_NAK_ABORT , KMT_PH_INIT_PARAMS , KMT_PH_NAK_ABORT ,
KMT_PH_NAK_ABORT , KMT_PH_SEND_NAK , KMT_PH_NAK_ABORT ),
(KMT_PH_REC_FILE , KMT_PH_BREAK , KMT_PH_NAK_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_FILE_HDR , KMT_PH_NAK_ABORT ,
KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT , KMT_PH_NAK_ABORT ,
KMT_PH_NAK_ABORT , KMT_PH_INIT_PARAMS , KMT_PH_NAK_ABORT ,
KMT_PH_ACK_LAST , KMT_PH_SEND_NAK , KMT_PH_NAK_ABORT ),
(KMT_PH_REC_DATA , KMT_PH_ERR_ABORT , KMT_PH_GOT_DATA ,
KMT_PH_GOT_ERROR , KMT_PH_ACK_LAST , KMT_PH_ERR_ABORT ,
KMT_PH_ERR_ABORT , KMT_PH_ERR_ABORT , KMT_PH_ERR_ABORT ,
KMT_PH_ERR_ABORT , KMT_PH_ERR_ABORT , KMT_PH_ERR_ABORT ,
KMT_PH_GOT_FILE , KMT_PH_SEND_NAK , KMT_PH_ERR_ABORT ),
(KMT_PH_SEND_INIT , KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE ,
KMT_PH_GOT_ERROR , KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE ,
KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE ,
KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE , KMT_PH_READY_FILE ,
KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE , KMT_PH_SEND_IDLE ),
(KMT_PH_SEND_FILE , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_READY_DATA ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_READY_DATA ,
KMT_PH_SET_ABORT , KMT_PH_SEND_IDLE , KMT_PH_SET_ABORT ),
(KMT_PH_SEND_DATA , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_READY_DATA ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_READY_DATA ,
KMT_PH_SET_ABORT , KMT_PH_SEND_IDLE , KMT_PH_SET_ABORT ),
(KMT_PH_SEND_EOF , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_SENT_FILE ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_SENT_FILE ,
KMT_PH_SET_ABORT , KMT_PH_SEND_IDLE , KMT_PH_SET_ABORT ),
(KMT_PH_SEND_BREAK , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_GOT_ERROR , KMT_PH_SET_ABORT , KMT_PH_SET_ABORT ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_SEND_DONE ,
KMT_PH_SET_ABORT , KMT_PH_SET_ABORT , KMT_PH_SEND_DONE ,
KMT_PH_SET_ABORT , KMT_PH_SEND_IDLE , KMT_PH_SET_ABORT ));
@ PROTOCOL HANDLER @
IF KMT_TRACE_FLAGS.PH_TRACING
THEN
() KMT_MTUP_VALUES PARAMS := (STATE AS KMT_MTUP_VALUES.RI_VALUE,
(L'EVENT) AS KMT_MTUP_VALUES.LI_VALUE);
KMT_SP_LOG_TRACE_MESSAGE(300,PARAMS)
FI;
IF EVENT = ENTRY
THEN @ increment retry count and test against maximum @
RETRY_COUNT := RETRY_COUNT+1;
IF RETRY_COUNT > MAXTRY
THEN
RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
RESULT := 89050
ELSE
KMT_PH_ACTION(STATE,EVENT)(RESULT)
FI
ELSE
KMT_PH_ACTION(STATE,EVENT)(RESULT)
FI;
IF RESULT NE 0
THEN
IF RESULT = -89061
THEN @ unable to send packet - fatal error @
STATE := ABORT;
EXIT_STATE := FATAL_ERROR
ELSF (RESULT NE 89000) OR (STATE NE REC_SERVER_IDLE)
THEN @ abort unless wrong seq no in Rec_Server_Idle state @
STATE := ABORT
FI
FI
END
; @ KMT_PH @
ENDMODULE @ KMT_PH_MODULE @
$$$$ KMT_PP_MODULE
MODULE KMT_PP_MODULE;
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT (
BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE
KMT_FH_RECORD_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
NEW_RECORD,
END_OF_FILE,
WORD TEXT_TYPE, @ 0 = EBCDIC @
@ 1 = ASCII @
@ 2 = BINARY @
INT MAX_RECORD_LENGTH,
RECORD_LENGTH,
(4098) BYTE RECORD); @ Maximum record size of 4096 @
@ plus 2 bytes for CRLF pair @
@ when constructing output @
@ records @
MODE
KMT_DH_DEVICE_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
WORD MAX_INPUT_LENGTH,
MAX_OUTPUT_LENGTH,
INPUT_PARITY,
OUTPUT_PARITY,
PAUSE);
MODE
KMT_PP_PACKET_DATA_S IS STRUCT (
INT DATA_LENGTH,
(91) BYTE DATA);
MODE
KMT_PP_CONFG_PARAMS_S IS STRUCT (
BYTE MARK,
MAXL,
TIME,
NPAD,
PADC,
EOL,
QCTL,
QBIN,
CHKT,
REPT,
4-BYTE CAPAS);
MODE
KMT_PP_PACKET_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
OUTPUT_TOTAL);
MODE
KMT_MTM_VALUES IS ANY (
LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF () BYTE RVB_VALUE,
REF () REF () BYTE RVRVB_VALUE);
***PAGE
@******************************************************************************@
@* *@
@* External procedure references *@
@* *@
@******************************************************************************@
EXT
PROC
(REF () BYTE, @ OUTPUT_PACKET @
BOOL, @ PROMPT @
RESPONSE @ RESPONSE @
) KMT_DH_OUTPUT;
EXT
PROC
(REF () BYTE, @ INPUT_BUFFER @
REF INT, @ INPUT_BUFFER_LENGTH @
RESPONSE @ RESPONSE @
) KMT_DH_INPUT;
EXT
PROC
(INT, @ RESULT_CODE @
WORD, @ DESTINATION @
REF () KMT_MTM_VALUES, @ PARAMS @
LONG WORD, @ PE_CONTINGENCY_MESSAGE @
BOOL, @ DUMP @
BOOL @ UNRECOVERABLE @
) KMT_EH_LOG_ERROR;
EXT
PROC
(
RESPONSE @ RESPONSE @
) KMT_FH_READ;
EXT
PROC
(
RESPONSE @ RESPONSE @
) KMT_FH_WRITE;
EXT
PROC
(
WORD, @ CHAR @
WORD, @ I/O FLAG @
RESPONSE @ RESPONSE @
) KMT_SP_CHECK_VME_CHAR;
EXT
PROC
(
INT, @ TYPE @
REF () KMT_MTM_VALUES @ PARAMS @
) KMT_SP_LOG_TRACE_MESSAGE;
***PAGE
@******************************************************************************@
@* *@
@* External data references *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
EXT (256) BYTE
EBCDIC_TO_ASCII, @ translation tables @
ASCII_TO_EBCDIC;
EXT (26) INT
PACKET_CODES; @ packet codes to protocol handler state table events @
EXT INT
BAD_PKT,INVALID_PKT,UNS_PKT,NON_PKT;
***LINES(4)
@ Variables: @
@ ********** @
EXT (<CASCADE>)
REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
EXT (<CASCADE>)
REF KMT_FH_RECORD_DETAILS_S KMT_FH_RECORD_DETAILS;
EXT (<CASCADE>)
REF KMT_DH_DEVICE_DETAILS_S KMT_DH_DEVICE_DETAILS;
EXT (<CASCADE>)
REF KMT_PP_CONFG_PARAMS_S KMT_PP_LOCAL_CONFG_PARAMS;
EXT (<CASCADE>)
REF KMT_PP_CONFG_PARAMS_S KMT_PP_REMOTE_CONFG_PARAMS;
EXT (<CASCADE>)
REF KMT_PP_PACKET_STATISTICS_S KMT_PP_PACKET_STATISTICS;
EXT (<CASCADE>)
REF REF () BYTE KMT_PH_INPUT_PACKET_DATA;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Static data declarations. *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
STATIC WORD
EBCDIC IS 0, @ transfer codes @
ASCII IS 1,
BINARY IS 2;
STATIC INT
KMT_PP_PACKET_IN_MSG IS 251,
KMT_PP_PACKET_OUT_MSG IS 252,
KMT_PP_PACKET_DATA_IN_MSG IS 253,
KMT_PP_PACKET_DATA_OUT_MSG IS 254,
KMT_PP_PARAM_OUT_MSG IS 258,
KMT_PP_PARAM_IN_MSG IS 259;
***LINES(4)
@ Variables: @
@ ********** @
STATIC
KMT_PP_PACKET_DATA_S KMT_PP_INPUT_PACKET_DATA;
STATIC
KMT_PP_PACKET_DATA_S KMT_PP_OUTPUT_PACKET_DATA;
STATIC
REF () BYTE KMT_PP_RECALL_DATA;
***LINES(4)
@ Results: @
@ ******** @
***LINES(4)
***PAGE
@******************************************************************************@
@* *@
@* Procedure declarations *@
@* *@
@******************************************************************************@
STATIC
PROC
KMT_PP_CHECK_COMPLETE IS (
INT DATA_LENGTH,
REF REF () BYTE BUFFER) BOOL:
@******************************************************************************@
@* *@
@* This procedure is used to update a buffer pointer and to check if the *@
@* processing of BUFFER is complete. *@
@* The procedure returns TRUE if the processing of BUFFER has been completed, *@
@* FALSE otherwise. *@
@* *@
@******************************************************************************@
BEGIN
IF
LENGTH BUFFER GT DATA_LENGTH
THEN @ Incomplete, update pointer @
BUFFER := BUFFER(DATA_LENGTH::);
FALSE
ELSE @ Complete return ZLR @
BUFFER := BUFFER(SIZE 0);
TRUE
FI
END; @ KMT_PP_CHECK_COMPLETE @
***PAGE
STATIC
PROC
KMT_PP_MOVE IS (
() BYTE SOURCE,
REF REF () BYTE DESTINATION,
REF BOOL COMPLETE) INT:
@******************************************************************************@
@* *@
@* This procedure is used to move the source string into the destination *@
@* buffer and to check if the destination buffer is full. *@
@* The procedure returns the number of characters moved. *@
@* *@
@******************************************************************************@
BEGIN
INT S_LEN IS LENGTH SOURCE,
D_LEN IS LENGTH DESTINATION;
IF
S_LEN GT D_LEN
THEN @ Insufficient space in @
@ buffer for string @
UNLESS
COMPLETE IS NIL
THEN
COMPLETE := TRUE;
FI;
0
ELSE
DESTINATION(SIZE S_LEN) := SOURCE;
UNLESS
COMPLETE IS NIL
THEN
COMPLETE := KMT_PP_CHECK_COMPLETE (S_LEN,
DESTINATION);
FI;
S_LEN
FI
END; @ KMT_PP_MOVE @
***PAGE
STATIC
PROC
KMT_PP_GENERATE_CHECKSUM IS (
REF () BYTE PACKET) BYTE:
@******************************************************************************@
@* *@
@* This procedure is used to generate a checksum for the data contained in *@
@* the packet. *@
@* *@
@******************************************************************************@
BEGIN
WORD SUM := 0;
FOR I
FROM 1 @ 'MARK' character not @
@ included in checksum @
TO PACKET(1) - X"20"
DO
SUM := SUM + PACKET(I)
REPEAT;
((SUM + ((SUM & X'C0') SCALE -6)) & X'3F') + X"20"
END; @ KMT_PP_GENERATE_CHECKSUM @
***PAGE
STATIC
PROC
KMT_PP_LOG_TRACE_MESSAGE IS (
INT TYPE,
REF () BYTE PACKET):
@******************************************************************************@
@* *@
@* This procedure is used to log the packet contents to the job journal. *@
@* *@
@******************************************************************************@
BEGIN
INT PACKET_LENGTH IS LENGTH PACKET;
INT LEN := PACKET(1) - X"20",
SEQ := PACKET(2) - X"20",
TYP := PACKET_CODES(PACKET(3) - X"41");
() KMT_MTM_VALUES PARAMS := (PACKET @ COMPLETE PACKET @
AS KMT_MTM_VALUES.RVB_VALUE,
PACKET(0) @ MARK @
AS KMT_MTM_VALUES.RVB_VALUE,
LEN @ LEN @
AS KMT_MTM_VALUES.RI_VALUE,
SEQ @ SEQ @
AS KMT_MTM_VALUES.RI_VALUE,
TYP @ TYPE @
AS KMT_MTM_VALUES.RI_VALUE,
PACKET(4 SIZE PACKET_LENGTH - 5)
@ DATA @
AS KMT_MTM_VALUES.RVB_VALUE,
PACKET(PACKET_LENGTH - 1)
@ CHECKSUM @
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (TYPE,
PARAMS)
END; @ KMT_PP_LOG_TRACE_MESSAGE @
***PAGE
STATIC
PROC
KMT_PP_DATA_TRACE_MESSAGE IS (
INT TYPE,
INT CODE,
REF () BYTE DATA):
@******************************************************************************@
@* *@
@* This procedure is used to log the packet data to the job journal. *@
@* *@
@******************************************************************************@
BEGIN
INT CHAR_CODE := CODE;
() KMT_MTM_VALUES PARAMS := (CHAR_CODE @ character code of data @
AS KMT_MTM_VALUES.RI_VALUE,
DATA @ data @
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE (TYPE,
PARAMS)
END; @ KMT_PP_DATA_TRACE_MESSAGE @
***PAGE
STATIC
PROC
KMT_PP_BUILD_PACKET_DATA IS (
REF REF () BYTE BUFFER,
REF REF () BYTE DATA,
WORD TEXT_TYPE,
REF BOOL BUFFER_COMPLETE) BOOL:
@******************************************************************************@
@* *@
@* This procedure is used to perform data translation of the data area *@
@* referenced by BUFFER. *@
@* If a binary file transfer is requested then the translation process *@
@* involves control character quoting and 8th bit prefixing. Otherwise (for *@
@* text files) the translation process involves control character quoting and *@
@* EBCDIC to ASCII data translation. *@
@* If the whole of BUFFER has been translated then BUFFER_COMPLETE is set *@
@* TRUE and BUFFER is returned referencing a zero length record. Otherwise *@
@* BUFFER_COMPLETE is returned FALSE and BUFFER is returned referencing the *@
@* untranslated part of the original buffer. *@
@* The translated data is returned in the area referenced by DATA. *@
@* The procedure returns TRUE if there is insufficient space in DATA for more *@
@* of the translated data. *@
@* *@
@******************************************************************************@
BEGIN
STATIC BYTE
SPACE IS X"20", @ ASCII codes @
DEL IS X"7F";
BYTE
QCTL IS KMT_PP_LOCAL_CONFG_PARAMS.QCTL,
QBIN IS KMT_PP_LOCAL_CONFG_PARAMS.QBIN;
() BYTE
QLF IS (QCTL,X"4A"), @ ASCII quoted LF @
QFF IS (QCTL,X"4C"), @ ASCII quoted FF @
QCR IS (QCTL,X"4D"), @ ASCII quoted CR @
QCRLF IS (QCTL,X"4D",QCTL,X"4A"); @ ASCII quoted CRLF @
BOOL
DATA_COMPLETE := FALSE;
SIM PROC PACKETISE IS (() BYTE SOURCE,INT DATA_LENGTH):
BEGIN
IF KMT_PP_MOVE(SOURCE,DATA,DATA_COMPLETE) NE 0
THEN BUFFER_COMPLETE := KMT_PP_CHECK_COMPLETE(DATA_LENGTH,BUFFER)
FI
END @ PACKETISE @ ;
BUFFER_COMPLETE := (LENGTH BUFFER LE 0);
UNTIL DATA_COMPLETE OR BUFFER_COMPLETE
DO
IF TEXT_TYPE GT EBCDIC
THEN @ ASCII or binary data @
INT SEQ_LEN := 0;
(3) BYTE SEQ;
BYTE THIS_CHAR := BUFFER(0);
SIM PROC ADD_TO_SEQ IS (BYTE OCTET):
BEGIN
SEQ(SEQ_LEN) := OCTET;
SEQ_LEN := SEQ_LEN+1
END @ ADD_TO_SEQ @ ;
IF (THIS_CHAR GT DEL) AND (TEXT_TYPE EQ BINARY)
THEN @ need to add 8th bit prefix @
ADD_TO_SEQ(QBIN)
FI;
THIS_CHAR := THIS_CHAR & X"7F";
IF (THIS_CHAR LT SPACE) OR (THIS_CHAR EQ DEL)
THEN @ control character @
ADD_TO_SEQ(QCTL);
THIS_CHAR := THIS_CHAR NEQ X"40"
ELSF (THIS_CHAR EQ QCTL) OR (THIS_CHAR EQ QBIN AND TEXT_TYPE EQ BINARY)
THEN @ special char, quote it @
ADD_TO_SEQ(QCTL)
FI;
ADD_TO_SEQ(THIS_CHAR);
PACKETISE(SEQ(SIZE SEQ_LEN),1)
ELSE @ EBCDIC data @
BYTE THIS_CHAR IS EBCDIC_TO_ASCII(BUFFER(0));
IF THIS_CHAR GT DEL
THEN @ Format effector @
IF (LENGTH BUFFER LT 2) OR (THIS_CHAR EQ X"FB")
THEN @ Newline FE (1 byte) or FE at end of record with no specifier@
IF THIS_CHAR EQ X"FB"
THEN @ End of record so ignore @
BUFFER_COMPLETE := KMT_PP_CHECK_COMPLETE(1,BUFFER)
ELSE @ Newline @
PACKETISE(QCRLF,1)
FI
ELSE @ FE with qualifier @
REF BYTE QUALIFIER IS BUFFER(1);
SIM PROC EXPAND_FE IS (() BYTE EXPANSION):
BEGIN
IF
QUALIFIER :=
QUALIFIER - W'(TO QUALIFIER - 1
UNTIL DATA_COMPLETE
DO
KMT_PP_MOVE(EXPANSION,DATA,
DATA_COMPLETE)
REPEAT);
QUALIFIER EQ 0
THEN
BUFFER_COMPLETE := KMT_PP_CHECK_COMPLETE(2,BUFFER)
FI
END @ EXPAND_FE @ ;
CASE X"FF" - THIS_CHAR
THEN @ multiple space @
EXPAND_FE(SPACE)
ELSE @ multiple newline @
IF QUALIFIER EQ X"00"
THEN @ translate to CR @
PACKETISE(QCR,2)
ELSE @ expand to CRLF pairs @
EXPAND_FE(QCRLF)
FI
ELSE @ vertical position @
IF (QUALIFIER EQ X"00")
THEN
PACKETISE(QFF,2)
ELSE
PACKETISE(QCRLF,2)
FI
ELSE @ horizontal position @
PACKETISE(SPACE,2)
ESAC
FI
ELSF THIS_CHAR EQ QCTL
THEN @ quote character @
PACKETISE((QCTL,THIS_CHAR),1)
ELSF (THIS_CHAR LT SPACE) OR (THIS_CHAR EQ DEL)
THEN @ control character @
PACKETISE((QCTL,THIS_CHAR NEQ X"40"),1)
ELSE @ printable character @
PACKETISE(THIS_CHAR,1)
FI
FI
REPEAT;
DATA_COMPLETE
END @ KMT_PP_BUILD_PACKET_DATA @ ;
***PAGE
STATIC
PROC
KMT_PP_UNQUOTE_CHAR IS (
REF () BYTE DATA,
REF BYTE UNQUOTED_CHAR,
REF INT SEQUENCE_LENGTH):
@******************************************************************************@
@* *@
@* This procedure is used to process a quoted (binary and/or control) *@
@* character sequence. *@
@* The area referenced by DATA contains the character sequence to be *@
@* processed. The area referenced by UNQUOTED_CHAR is returned containing the *@
@* unquoted character (with the control and 8th bit set as appropriate) and *@
@* the area referenced by SEQUENCE_LENGTH is returned containing the length *@
@* of the quoted sequence. If the first character in DATA is not a binary or *@
@* control quote character then UNQUOTED_CHAR is returned containing the *@
@* character and SEQUENCE_LENGTH is returned containing 1. *@
@* *@
@******************************************************************************@
BEGIN
WORD TEXT_TYPE IS KMT_FH_RECORD_DETAILS.TEXT_TYPE;
BYTE QCTL IS KMT_PP_REMOTE_CONFG_PARAMS.QCTL,
QBIN IS KMT_PP_REMOTE_CONFG_PARAMS.QBIN;
BYTE THIS_CHAR := DATA(0);
BYTE OR_MASK IS IF
(TEXT_TYPE EQ BINARY) AND (THIS_CHAR EQ QBIN)
THEN @ Binary file and 8th bit @
@ quoted character found @
THIS_CHAR := DATA(1);
SEQUENCE_LENGTH := 2;
X"80"
ELSE @ Not an 8th bit quoted @
@ character @
SEQUENCE_LENGTH := 1;
X"00"
FI;
IF
THIS_CHAR EQ QCTL
THEN @ Control quoted character @
THIS_CHAR := DATA(SEQUENCE_LENGTH);
SEQUENCE_LENGTH := SEQUENCE_LENGTH + 1;
IF
(THIS_CHAR NE QCTL) AND (THIS_CHAR NE QBIN OR TEXT_TYPE NE BINARY)
THEN @ Control character @
THIS_CHAR := THIS_CHAR NEQ X"40"
FI
FI;
UNQUOTED_CHAR := THIS_CHAR ! OR_MASK
END; @ KMT_PP_UNQUOTE_CHAR @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_TRANSLATE_TO_EBCDIC IS ():
@******************************************************************************@
@* *@
@* This procedure is used to translate the packet data from ASCII to EBCDIC *@
@* and to process any quoted characters. *@
@* The untranslated data is read from, and the translated data is returned in *@
@* the area referenced by KMT_PH_INPUT_PACKET_DATA. *@
@* *@
@******************************************************************************@
BEGIN
() BYTE UNTRANSLATED_DATA := KMT_PH_INPUT_PACKET_DATA;
@ Copy untranslated data @
REF () BYTE DATA := UNTRANSLATED_DATA;
BOOL DATA_COMPLETE := (LENGTH DATA LE 0);
INT T_LEN IS FOR I
UNTIL
DATA_COMPLETE
DO
INT SEQUENCE_LENGTH;
KMT_PP_UNQUOTE_CHAR (DATA,
KMT_PH_INPUT_PACKET_DATA(I),
SEQUENCE_LENGTH);
DATA_COMPLETE := KMT_PP_CHECK_COMPLETE (SEQUENCE_LENGTH,
DATA)
REPEAT;
KMT_PH_INPUT_PACKET_DATA := KMT_PH_INPUT_PACKET_DATA(SIZE T_LEN);
TRANSLATE (ASCII_TO_EBCDIC,
KMT_PH_INPUT_PACKET_DATA,
0,
NIL);
IF KMT_TRACE_FLAGS.PP_TRACING AND LENGTH KMT_PH_INPUT_PACKET_DATA > 0
THEN (<RARELY>)
(
KMT_PP_DATA_TRACE_MESSAGE(KMT_PP_PACKET_DATA_IN_MSG,
EBCDIC,
KMT_PH_INPUT_PACKET_DATA)
)
FI
END; @ KMT_PP_TRANSLATE_TO_EBCDIC @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_GET_PACKET IS (
REF INT TYPE,
REF INT SEQ,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to receive a KERMIT packet from the remote end. *@
@* If a failure is detected whilst attempting to read a packet then TYPE is *@
@* set to BAD_PKT and the failing resultcode is returned. *@
@* If a zero length packet is read or no 'MARK' character is found in the *@
@* packet then TYPE is set to BAD_PKT and resultcode KMT_PP_NO_INPUT_DATA is *@
@* returned. *@
@* If the checksum validation fails then TYPE is set to BAD_PKT and *@
@* resultcode KMT_PP_INVALID_CHECKSUM is returned. *@
@* In all other cases TYPE will be set to either INVALID_PKT or the packet *@
@* type. In the case of an invalid packet then a resultcode of either UNS_PKT *@
@* or NON_PKT will be returned. *@
@* The packet sequence number is returned in the area referenced by SEQ and *@
@* the packet data is returned in the area referenced by *@
@* KMT_PH_INPUT_PACKET_DATA. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_PP_PACKET_IN_MSG IS 251,
KMT_PP_NO_INPUT_PACKET IS -80250,
KMT_PP_INVALID_CHECKSUM IS -80253,
KMT_PP_INVALID_PACKET_LENGTH IS -80254;
INT INPUT_PACKET_LENGTH,
INPUT_BUFFER_LENGTH,
PACKET_POINTER_LENGTH;
INT MAX_INPUT_LENGTH IS KMT_DH_DEVICE_DETAILS.MAX_INPUT_LENGTH;
REF () BYTE INPUT_PACKET,
PACKET_POINTER;
(MAX_INPUT_LENGTH) BYTE INPUT_BUFFER; @ Allows for padding and @
@ 'noise' characters @
IF
(
KMT_DH_INPUT (INPUT_BUFFER,
INPUT_BUFFER_LENGTH,
RESULT);
RESULT GT 0
)
THEN @ I/O error @
TYPE := BAD_PKT
ELSF
INPUT_BUFFER_LENGTH EQ 0
OR
(
BYTE MARK IS KMT_PP_REMOTE_CONFG_PARAMS.MARK;
REF () BYTE REM := INPUT_BUFFER(SIZE INPUT_BUFFER_LENGTH);
PACKET_POINTER := REM(SIZE 0);
UNTIL @ Skip all but last 'MARK' @
SCANUNQ (MARK, @ character @
REM,
0,
REM)
DO
PACKET_POINTER := REM;
REM := REM(1::)
REPEAT;
PACKET_POINTER_LENGTH := LENGTH PACKET_POINTER;
PACKET_POINTER_LENGTH LT 2
)
OR
(
INPUT_PACKET_LENGTH := PACKET_POINTER(1) - X"20" + 2;
PACKET_POINTER_LENGTH LT INPUT_PACKET_LENGTH
)
THEN @ Either 'MARK' character not @
@ found or insufficient data @
@ after 'MARK' character or a @
@ recoverable I/O error @
@ occurred. @
TYPE := BAD_PKT;
RESULT := KMT_PP_NO_INPUT_PACKET
ELSF
(
(INPUT_PACKET_LENGTH LT 5) OR (INPUT_PACKET_LENGTH GT 96)
)
THEN @ Packet length invalid @
TYPE := BAD_PKT;
RESULT := KMT_PP_INVALID_PACKET_LENGTH
ELSF
(
INPUT_PACKET := PACKET_POINTER(SIZE INPUT_PACKET_LENGTH);
IF
KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
KMT_PP_LOG_TRACE_MESSAGE (KMT_PP_PACKET_IN_MSG,
INPUT_PACKET)
)
FI;
INPUT_PACKET(INPUT_PACKET_LENGTH - 1) NE KMT_PP_GENERATE_CHECKSUM (
INPUT_PACKET)
)
THEN @ Checksum error @
TYPE := BAD_PKT;
RESULT := KMT_PP_INVALID_CHECKSUM
ELSE @ Validate packet type @
WORD PACKET_TYPE IS INPUT_PACKET(3) - X"41";
IF
PACKET_TYPE GT 25
THEN @ Not in range A to Z @
TYPE := INVALID_PKT;
RESULT := NON_PKT
ELSF
(
TYPE := PACKET_CODES(PACKET_TYPE);
TYPE LT 0
)
THEN
RESULT := TYPE;
TYPE := INVALID_PKT
ELSE
REF INT DATA_LENGTH IS KMT_PP_INPUT_PACKET_DATA.DATA_LENGTH;
REF () BYTE DATA IS KMT_PP_INPUT_PACKET_DATA.DATA;
REF INT STATISTICS IS
KMT_PP_PACKET_STATISTICS.INPUT_TOTAL;
STATISTICS := STATISTICS + 1;
SEQ := INPUT_PACKET(2) - X"20";
DATA_LENGTH := INPUT_PACKET_LENGTH - 5;
MOVE (INPUT_PACKET(4 SIZE DATA_LENGTH),
DATA,
0,
X"00",
NIL,
NIL);
KMT_PH_INPUT_PACKET_DATA := DATA(SIZE DATA_LENGTH)
FI
FI
END; @ KMT_PP_GET_PACKET @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_SEND_PACKET IS (
INT TYPE,
INT SEQ,
BOOL PROMPT,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to frame and send a KERMIT packet to the remote end.*@
@* TYPE and SEQ specify the packet type and sequence number respectively. *@
@* The packet data and length is read from the areas *@
@* KMT_PP_OUTPUT_PACKET_DATA.DATA and KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH *@
@* respectively. *@
@* If PROMPT is set TRUE then read interest is set at the PFI for the next *@
@* input packet. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_PP_PACKET_OUT_MSG IS 252;
INT DATA_LENGTH IS KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH;
REF () BYTE DATA IS KMT_PP_OUTPUT_PACKET_DATA.DATA;
INT OUTPUT_PACKET_LENGTH IS 5 + DATA_LENGTH;
(OUTPUT_PACKET_LENGTH) BYTE OUTPUT_PACKET;
STATIC () BYTE PACKET_TYPES IS X"00" @ Not used @
X"42" @ B packet @
X"44" @ D packet @
X"45" @ E packet @
X"46" @ F packet @
X"47" @ G packet @
X"49" @ I packet @
X"4B" @ K packet @
X"4E" @ N packet @
X"52" @ R packet @
X"53" @ S packet @
X"59" @ Y packet @
X"5A"; @ Z packet @
OUTPUT_PACKET(0) := KMT_PP_LOCAL_CONFG_PARAMS.MARK;
OUTPUT_PACKET(1) := DATA_LENGTH + 3 + X"20";
OUTPUT_PACKET(2) := SEQ + X"20";
OUTPUT_PACKET(3) := PACKET_TYPES(TYPE);
OUTPUT_PACKET(4 SIZE DATA_LENGTH) := DATA;
OUTPUT_PACKET(OUTPUT_PACKET_LENGTH - 1) := KMT_PP_GENERATE_CHECKSUM (
OUTPUT_PACKET);
IF
KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
KMT_PP_LOG_TRACE_MESSAGE (KMT_PP_PACKET_OUT_MSG,
OUTPUT_PACKET)
)
FI;
KMT_DH_OUTPUT (OUTPUT_PACKET,
PROMPT,
RESULT);
IF
RESULT LE 0
THEN
REF INT STATISTICS IS
KMT_PP_PACKET_STATISTICS.OUTPUT_TOTAL;
STATISTICS := STATISTICS + 1
FI
END; @ KMT_PP_SEND_PACKET @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_BUILD_FILE_PACKET_DATA IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to read file records and to construct data packets *@
@* from the record performing data translation, binary and control character *@
@* character quoting as appropriate. *@
@* The record and length are returned in the data areas *@
@* KMT_FH_RECORD_DETAILS.RECORD and KMT_FH_RECORD_DETAILS.RECORD_LENGTH *@
@* respectively. The processed packet data and length are returned is the *@
@* data areas *@
@* KMT_PP_OUTPUT_PACKET_DATA.DATA and KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH *@
@* respectively. *@
@* End of file is indicated by returning resultcode DML_READ_PSEUDO_NODE. *@
@* *@
@******************************************************************************@
BEGIN
INT DML_READ_PSEUDO_NODE IS 9034;
REF BOOL END_OF_FILE IS KMT_FH_RECORD_DETAILS.END_OF_FILE;
REF INT DATA_LENGTH IS KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH;
RESULT := 0;
IF
END_OF_FILE
THEN @ End of file reached during @
@ previous read @
DATA_LENGTH := 0;
RESULT := DML_READ_PSEUDO_NODE
ELSF
(
REF BOOL NEW_RECORD IS KMT_FH_RECORD_DETAILS.NEW_RECORD;
WORD TEXT_TYPE IS KMT_FH_RECORD_DETAILS.TEXT_TYPE;
REF INT RECORD_LENGTH IS KMT_FH_RECORD_DETAILS.RECORD_LENGTH;
REF () BYTE RECORD IS KMT_FH_RECORD_DETAILS.RECORD;
BYTE QCTL IS KMT_PP_LOCAL_CONFG_PARAMS.QCTL;
BYTE MAXL IS KMT_PP_REMOTE_CONFG_PARAMS.MAXL;
REF () BYTE DATA IS KMT_PP_OUTPUT_PACKET_DATA.DATA(SIZE MAXL - 5);
() BYTE QCRQLF IS (QCTL, X"4D", QCTL, X"4A");
@ Quoted CRLF @
INT D_LEN IS LENGTH DATA;
REF () BYTE DATA_REM := DATA;
(91) BYTE PP_TRACE_BUFFER; @ debug trace area @
REF () BYTE PP_TRACE_PTR := PP_TRACE_BUFFER;
INT PP_TRACE_COUNT := 0;
UNTIL
(
BOOL DATA_COMPLETE;
IF
NEW_RECORD
AND
(
KMT_FH_READ (RESULT);
IF
RESULT LE 0
THEN @ Record read successfully @
KMT_PP_RECALL_DATA := RECORD(SIZE RECORD_LENGTH);
FI;
RESULT GT 0
)
THEN @ Read error or end of file @
END_OF_FILE := TRUE;
DATA_COMPLETE := TRUE
ELSE @ Build packet data from @
@ record @
REF () BYTE TRACE_PTR := KMT_PP_RECALL_DATA;
INT TRACE_CT;
DATA_COMPLETE := KMT_PP_BUILD_PACKET_DATA (KMT_PP_RECALL_DATA,
DATA_REM,
TEXT_TYPE,
NEW_RECORD);
@ copy source to trace buffer @
TRACE_CT := LENGTH TRACE_PTR - LENGTH KMT_PP_RECALL_DATA;
PP_TRACE_PTR(SIZE TRACE_CT) := TRACE_PTR(SIZE TRACE_CT);
PP_TRACE_COUNT := PP_TRACE_COUNT + TRACE_CT;
PP_TRACE_PTR := PP_TRACE_BUFFER(PP_TRACE_COUNT::);
IF
TEXT_TYPE EQ BINARY
THEN @ Binary file transfer don't @
@ add CRLF end of record @
@ marker @
SKIP
ELSF
NEW_RECORD
THEN @ EBCDIC or ASCII file @
@ transfer and end of record. @
@ Move in quote CRLF, end of @
@ record marker @
NEW_RECORD := KMT_PP_MOVE (QCRQLF,
DATA_REM,
DATA_COMPLETE) NE 0;
IF NEW_RECORD @ add new record mark to trace @
THEN
PP_TRACE_PTR(SIZE 4) := IF TEXT_TYPE = EBCDIC
THEN " // "
ELSE X"202F2F20"
FI;
PP_TRACE_COUNT := PP_TRACE_COUNT + 4;
PP_TRACE_PTR := PP_TRACE_BUFFER(PP_TRACE_COUNT::);
FI
FI
FI;
DATA_COMPLETE
)
DO
SKIP
REPEAT;
DATA_LENGTH := D_LEN - LENGTH DATA_REM;
IF KMT_TRACE_FLAGS.PP_TRACING AND PP_TRACE_COUNT > 0
THEN (<RARELY>)
(
IF TEXT_TYPE = ASCII
THEN
TRANSLATE(ASCII_TO_EBCDIC,
PP_TRACE_BUFFER(SIZE PP_TRACE_COUNT),
0,
NIL)
FI;
KMT_PP_DATA_TRACE_MESSAGE(KMT_PP_PACKET_DATA_OUT_MSG,
TEXT_TYPE,
PP_TRACE_BUFFER(SIZE PP_TRACE_COUNT))
)
FI;
(RESULT EQ DML_READ_PSEUDO_NODE) AND (DATA_LENGTH NE 0)
)
THEN @ End of file reached but @
@ packet data remains. @
@ Return end of file on next @
@ call @
RESULT := 0
FI
END; @ KMT_PP_BUILD_FILE_PACKET_DATA @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_BUILD_STRING_PACKET_DATA IS (
REF () BYTE STRING,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to translate the data held in STRING from EBCDIC to *@
@* ASCII. *@
@* The translated data and length is returned in the area *@
@* KMT_PP_OUTPUT_PACKET_DATA.DATA and KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH *@
@* respectively. *@
@* If the translated data length exceeds the maximum packet data length then *@
@* resultcode KMT_PP_STRING_TOO_BIG is returned. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_PP_STRING_TOO_BIG IS 80256;
INT MAXL IS KMT_PP_REMOTE_CONFG_PARAMS.MAXL;
REF INT DATA_LENGTH IS KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH;
REF () BYTE DATA IS KMT_PP_OUTPUT_PACKET_DATA.DATA(SIZE MAXL - 5);
INT STRING_LENGTH IS IF
STRING IS NIL
THEN
0
ELSE
LENGTH STRING
FI;
IF
STRING_LENGTH EQ 0
THEN @ NIL or ZLR supplied @
DATA_LENGTH := 0;
RESULT := 0
ELSE
() BYTE STRING_COPY := STRING; @ Don't want to corrupt @
@ original string @
REF () BYTE STRING_POINTER := STRING_COPY,
DATA_REM := DATA;
RESULT := IF
(
BOOL STRING_COMPLETE := TRUE;
KMT_PP_BUILD_PACKET_DATA (STRING_POINTER,
DATA_REM,
EBCDIC,
STRING_COMPLETE);
STRING_COMPLETE
)
THEN
0
ELSE @ String too big @
KMT_PP_STRING_TOO_BIG
FI;
DATA_LENGTH := LENGTH DATA - LENGTH DATA_REM;
IF KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
KMT_PP_DATA_TRACE_MESSAGE(KMT_PP_PACKET_DATA_OUT_MSG,EBCDIC,
STRING(SIZE (STRING_LENGTH - LENGTH STRING_POINTER)))
)
FI
FI;
END; @ KMT_PP_BUILD_STRING_PACKET_DATA @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_BUILD_FILE_RECORD IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to construct file records from KERMIT data packets *@
@* received. For text files control character quoting and data translation *@
@* from ASCII to EBCDIC is performed. For binary files control character *@
@* quoting and 8th bit quoting is performed. *@
@* The packet data is read from the area referenced by *@
@* KMT_PH_INPUT_PACKET_DATA. The processed record and length is returned in *@
@* the areas KMT_FH_RECORD_DETAILS.RECORD and *@
@* KMT_FH_RECORD_DETAILS.RECORD.LENGTH respectively. *@
@* When the end of record is detected the record is written to the file. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_PP_RECORD_TOO_BIG IS 80255;
REF () BYTE DATA := KMT_PH_INPUT_PACKET_DATA;
INT DATA_LENGTH IS LENGTH DATA;
REF BOOL NEW_RECORD IS KMT_FH_RECORD_DETAILS.NEW_RECORD;
WORD TEXT_TYPE IS KMT_FH_RECORD_DETAILS.TEXT_TYPE;
INT MAX_RECORD_LENGTH := KMT_FH_RECORD_DETAILS.MAX_RECORD_LENGTH;
REF INT RECORD_LENGTH IS KMT_FH_RECORD_DETAILS.RECORD_LENGTH;
INT RECORD_SIZE IS IF
TEXT_TYPE EQ BINARY
THEN @ Binary file transfer. CRLF @
@ end of record terminator @
@ not required @
MAX_RECORD_LENGTH
ELSE @ EBCDIC or ASCII file xfer. @
@ Allow for CRLF pair, end of @
@ record terminator @
MAX_RECORD_LENGTH + 2
FI;
REF () BYTE RECORD IS KMT_FH_RECORD_DETAILS.RECORD(SIZE RECORD_SIZE);
() BYTE LF IS X"0A", @ ASCII LF @
CR IS X"0D"; @ CR @
() BYTE CRLF IS (CR,LF);
BOOL DATA_COMPLETE := (DATA_LENGTH LE 0);
(96) BYTE PP_TRACE_BUFFER; @ packet trace variables @
REF () BYTE PP_TRACE_PTR := PP_TRACE_BUFFER,
TRACE_PTR := KMT_PP_RECALL_DATA;
INT PP_TRACE_COUNT := 0;
RESULT := 0;
UNTIL
DATA_COMPLETE OR (RESULT GT 0)
DO
INT LAST_CHAR_INDEX IS IF
NEW_RECORD
THEN
KMT_PP_RECALL_DATA := RECORD;
TRACE_PTR := RECORD; @ (for trace) @
-1
ELSE
RECORD_SIZE - (LENGTH KMT_PP_RECALL_DATA + 1)
FI;
BYTE UNQUOTED_CHAR;
INT SEQUENCE_LENGTH;
KMT_PP_UNQUOTE_CHAR (DATA,
UNQUOTED_CHAR,
SEQUENCE_LENGTH);
IF
KMT_PP_MOVE (UNQUOTED_CHAR,
KMT_PP_RECALL_DATA,
NEW_RECORD) NE 0
THEN @ Moved in data @
DATA_COMPLETE := KMT_PP_CHECK_COMPLETE (SEQUENCE_LENGTH,
DATA);
FI;
IF
TEXT_TYPE EQ BINARY
THEN @ Binary file transfer @
RECORD_LENGTH := RECORD_SIZE - LENGTH KMT_PP_RECALL_DATA;
IF
NEW_RECORD
THEN @ Record complete, output it @
@ (obtain trace info) @
INT TRACE_CT := LENGTH TRACE_PTR - LENGTH KMT_PP_RECALL_DATA;
PP_TRACE_PTR(SIZE TRACE_CT) := TRACE_PTR(SIZE TRACE_CT);
PP_TRACE_COUNT := PP_TRACE_COUNT + TRACE_CT;
PP_TRACE_PTR := PP_TRACE_BUFFER(PP_TRACE_COUNT::);
KMT_FH_WRITE (RESULT) @ output record @
FI
ELSF
(LAST_CHAR_INDEX GE 0) AND (RECORD(LAST_CHAR_INDEX SIZE 2) EQ CRLF)
THEN @ EBCDIC or ASCII file xfer @
@ end of record, output it @
@ (obtain trace info) @
INT TRACE_CT := LENGTH TRACE_PTR - (LENGTH KMT_PP_RECALL_DATA + 2);
IF TRACE_CT = -1 @ CR LF split between two packets @
THEN
TRACE_CT := 0
ELSE
PP_TRACE_PTR(SIZE TRACE_CT) := TRACE_PTR(SIZE TRACE_CT);
FI;
PP_TRACE_PTR := PP_TRACE_BUFFER((PP_TRACE_COUNT + TRACE_CT)::);
PP_TRACE_PTR(SIZE 4) := X"202F2F20";
PP_TRACE_COUNT := PP_TRACE_COUNT + TRACE_CT + 4;
PP_TRACE_PTR := PP_TRACE_BUFFER(PP_TRACE_COUNT::);
RECORD_LENGTH := RECORD_SIZE - (LENGTH KMT_PP_RECALL_DATA + 2);
@ Don't want CRLF in file @
IF
TEXT_TYPE EQ EBCDIC
THEN @ EBCDIC file transfer @
TRANSLATE (ASCII_TO_EBCDIC,
RECORD(SIZE RECORD_LENGTH),
0,
NIL)
FI;
KMT_FH_WRITE (RESULT);
NEW_RECORD := TRUE
ELSF
(
RECORD_LENGTH := RECORD_SIZE - LENGTH KMT_PP_RECALL_DATA;
NEW_RECORD
)
THEN @ EBCDIC or ASCII file xfer @
@ and record buffer full but @
@ no end of record found. @
() KMT_MTM_VALUES PARAMS := DISPLAY(MAX_RECORD_LENGTH
AS KMT_MTM_VALUES.RI_VALUE);
RESULT := KMT_PP_RECORD_TOO_BIG;
KMT_EH_LOG_ERROR (RESULT,
2,
PARAMS,
0,
FALSE,
FALSE)
FI
REPEAT;
IF KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
IF DATA_COMPLETE AND NOT NEW_RECORD @ (obtain rest of trace info) @
THEN
INT TRACE_CT := LENGTH TRACE_PTR - LENGTH KMT_PP_RECALL_DATA;
PP_TRACE_PTR(SIZE TRACE_CT) := TRACE_PTR(SIZE TRACE_CT);
PP_TRACE_COUNT := PP_TRACE_COUNT + TRACE_CT
FI;
IF PP_TRACE_COUNT > 0
THEN
IF TEXT_TYPE NE BINARY
THEN
TRANSLATE(ASCII_TO_EBCDIC,
PP_TRACE_BUFFER(SIZE PP_TRACE_COUNT),
0,
NIL)
FI;
KMT_PP_DATA_TRACE_MESSAGE(KMT_PP_PACKET_DATA_IN_MSG,
TEXT_TYPE,
PP_TRACE_BUFFER(SIZE PP_TRACE_COUNT))
FI
)
FI
END; @ KMT_PP_BUILD_FILE_RECORD @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_BUILD_PARAM_PACKET_DATA IS ():
@******************************************************************************@
@* *@
@* This procedure is used to construct the packet data from the configuration *@
@* parameters. *@
@* The configuration parameters are read from the area *@
@* KMT_PP_LOCAL_CONFG_PARAMS and the packet data and length is returned in *@
@* the areas KMT_PP_OUTPUT_PACKET_DATA.DATA and *@
@* KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH respectively. *@
@* *@
@******************************************************************************@
BEGIN
REF () BYTE DATA IS KMT_PP_OUTPUT_PACKET_DATA.DATA;
BYTE N IS X"4E"; @ ASCII N @
DATA(0) := KMT_PP_LOCAL_CONFG_PARAMS.MAXL + X"20";
DATA(1) := KMT_PP_LOCAL_CONFG_PARAMS.TIME + X"20";
DATA(2) := KMT_PP_LOCAL_CONFG_PARAMS.NPAD + X"20";
DATA(3) := KMT_PP_LOCAL_CONFG_PARAMS.PADC NEQ X"40";
DATA(4) := KMT_PP_LOCAL_CONFG_PARAMS.EOL + X"20";
DATA(5) := KMT_PP_LOCAL_CONFG_PARAMS.QCTL;
DATA(6) := IF
KMT_FH_RECORD_DETAILS.TEXT_TYPE NE EBCDIC
THEN @ ASCII or binary file xfer @
@ requested, do 8th bit @
@ quoting @
KMT_PP_LOCAL_CONFG_PARAMS.QBIN
ELSE @ EBCDIC file transfer @
@ requested, donot do 8th bit @
@ quoting @
N
FI;
@ We don't support any others @
@ so default them @
KMT_PP_OUTPUT_PACKET_DATA.DATA_LENGTH := 7;
IF KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
() INT P := (KMT_PP_LOCAL_CONFG_PARAMS.MAXL,
KMT_PP_LOCAL_CONFG_PARAMS.TIME,
KMT_PP_LOCAL_CONFG_PARAMS.NPAD);
() KMT_MTM_VALUES PARAMS := (P(0)
AS KMT_MTM_VALUES.RI_VALUE,
P(1)
AS KMT_MTM_VALUES.RI_VALUE,
P(2)
AS KMT_MTM_VALUES.RI_VALUE,
KMT_PP_LOCAL_CONFG_PARAMS.PADC
AS KMT_MTM_VALUES.RVB_VALUE,
KMT_PP_LOCAL_CONFG_PARAMS.EOL
AS KMT_MTM_VALUES.RVB_VALUE,
KMT_PP_LOCAL_CONFG_PARAMS.QCTL
AS KMT_MTM_VALUES.RVB_VALUE,
DATA(6)
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE(KMT_PP_PARAM_OUT_MSG,PARAMS)
)
FI
END; @ KMT_PP_BUILD_PARAM_PACKET_DATA @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_PP_PROCESS_PARAM_PACKET_DATA IS (
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to extract the configuration parameters from the *@
@* packet data. *@
@* The packet data is read from the area referenced by *@
@* KMT_PH_INPUT_PACKET_DATA and the configuration parameters are returned in *@
@* the area KMT_PP_REMOTE_CONFG_PARAMS. *@
@* *@
@******************************************************************************@
BEGIN
***PAGE
SIM
PROC
KMT_PP_LOG_PARAM_ERROR IS (
INT NAME_CODE,
REF () BYTE VALUE,
INT REASON_CODE,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to log configuration parameter validation errors to *@
@* the job journal. *@
@* *@
@******************************************************************************@
BEGIN
INT KMT_PP_INVALID_CONFIG_PARAM IS 80257;
INT NAME := NAME_CODE,
REASON := REASON_CODE;
() KMT_MTM_VALUES PARAMS := (NAME
AS KMT_MTM_VALUES.RI_VALUE,
VALUE
AS KMT_MTM_VALUES.RVB_VALUE,
REASON
AS KMT_MTM_VALUES.RI_VALUE);
RESULT := KMT_PP_INVALID_CONFIG_PARAM;
KMT_EH_LOG_ERROR (RESULT,2,PARAMS,0,FALSE,FALSE)
END; @ KMT_PP_LOG_PARAM_ERROR @
***PAGE
INT KMT_PP_QBIN_AND_QCTL_EQUAL IS 80258,
KMT_PP_QCTL_WARNING IS -80259,
KMT_PP_QBIN_REJECTED IS 80260;
INT MAXL_CODE IS 0,
NPAD_CODE IS 1,
PADC_CODE IS 2,
EOL_CODE IS 3,
QCTL_CODE IS 4,
QBIN_CODE IS 5;
INT INFO_LENGTH IS SIZEOF KMT_PP_CONFG_PARAMS_S;
(INFO_LENGTH) BYTE PACKET_INFO;
WORD MAX_OUTPUT_LENGTH IS KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH;
WORD TEXT_TYPE IS KMT_FH_RECORD_DETAILS.TEXT_TYPE;
WORD MIN_PACKET_LENGTH IS 30;
INT DATA_LENGTH IS LENGTH KMT_PH_INPUT_PACKET_DATA;
REF BYTE MAXL IS KMT_PP_REMOTE_CONFG_PARAMS.MAXL,
TIME IS KMT_PP_REMOTE_CONFG_PARAMS.TIME,
NPAD IS KMT_PP_REMOTE_CONFG_PARAMS.NPAD,
PADC IS KMT_PP_REMOTE_CONFG_PARAMS.PADC,
EOL IS KMT_PP_REMOTE_CONFG_PARAMS.EOL,
QCTL IS KMT_PP_REMOTE_CONFG_PARAMS.QCTL,
QBIN IS KMT_PP_REMOTE_CONFG_PARAMS.QBIN,
CHKT IS KMT_PP_REMOTE_CONFG_PARAMS.CHKT,
REPT IS KMT_PP_REMOTE_CONFG_PARAMS.REPT;
REF 4-BYTE CAPAS IS KMT_PP_REMOTE_CONFG_PARAMS.CAPAS;
REF BYTE LOCAL_MARK IS KMT_PP_LOCAL_CONFG_PARAMS.MARK,
LOCAL_QCTL IS KMT_PP_LOCAL_CONFG_PARAMS.QCTL,
LOCAL_QBIN IS KMT_PP_LOCAL_CONFG_PARAMS.QBIN;
INT RC;
BYTE PARAM;
BYTE NUL IS X"00", @ ASCII NUL @
CR IS X"0D", @ CR @
SPACE IS X"20", @ Space @
HASH IS X"23", @ # @
ONE IS X"31", @ 1 @
RAB IS X"3E", @ > @
CTLNUL IS X"40", @ Controlled NUL @
N IS X"4E", @ N @
Y IS X"59", @ Y @
GRAVE IS X"60", @ ` @
TILDE IS X"7E", @ ~ @
DEL IS X"7F"; @ DEL @
RESULT := 0;
MOVEBYTE (SPACE, @ Set defaults @
PACKET_INFO,
0,
NIL);
PACKET_INFO(3) := CTLNUL; @ PADC default @
PACKET_INFO(SIZE DATA_LENGTH) := KMT_PH_INPUT_PACKET_DATA;
IF KMT_TRACE_FLAGS.PP_TRACING
THEN (<RARELY>)
(
() INT IP := (PACKET_INFO(0) - X"20",
PACKET_INFO(1) - X"20",
PACKET_INFO(2) - X"20",
PACKET_INFO(7) - X"30");
() BYTE BP := (PACKET_INFO(3) NEQ X"40",
PACKET_INFO(4) - X"20");
() KMT_MTM_VALUES PARAMS := (IP(0) @ MAXL @
AS KMT_MTM_VALUES.RI_VALUE,
IP(1) @ TIME @
AS KMT_MTM_VALUES.RI_VALUE,
IP(2) @ NPAD @
AS KMT_MTM_VALUES.RI_VALUE,
BP(0) @ PADC @
AS KMT_MTM_VALUES.RVB_VALUE,
BP(1) @ EOL @
AS KMT_MTM_VALUES.RVB_VALUE,
PACKET_INFO(5) @ QBIN @
AS KMT_MTM_VALUES.RVB_VALUE,
PACKET_INFO(6) @ QCTL @
AS KMT_MTM_VALUES.RVB_VALUE,
IP(3) @ CHKT @
AS KMT_MTM_VALUES.RI_VALUE,
PACKET_INFO(8) @ REPT @
AS KMT_MTM_VALUES.RVB_VALUE,
PACKET_INFO(9 SIZE 4) @ CAPAS @
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_SP_LOG_TRACE_MESSAGE(KMT_PP_PARAM_IN_MSG,PARAMS(SIZE DATA_LENGTH))
)
FI;
PARAM := PACKET_INFO(0) - X"20";
MAXL := IF
(PARAM EQ 0)
OR
(PARAM GE MAX_OUTPUT_LENGTH)
THEN @ Defaulted or greater than @
@ device line length @
MAX_OUTPUT_LENGTH
ELSE
PARAM
FI;
TIME := PACKET_INFO(1) - X"20";
NPAD := PACKET_INFO(2) - X"20";
PADC := PACKET_INFO(3) NEQ X"40";
PARAM := PACKET_INFO(4) - X"20";
EOL := IF
PARAM EQ 0
THEN @ defaulted, set to CR @
CR
ELSE
PARAM
FI;
PARAM := PACKET_INFO(5);
QCTL := IF
PARAM EQ SPACE
THEN @ Defaulted, set to # @
HASH
ELSE
PARAM
FI;
PARAM := PACKET_INFO(6);
QBIN := IF
PARAM EQ N @ ASCII N @
THEN @ 8th bit quoting rejected @
SPACE
ELSF
PARAM EQ Y @ ASCII Y @
THEN @ 8th bit quoting requested @
LOCAL_QBIN
ELSE
PARAM
FI;
@ We donot support any others @
@ so default them @
CHKT := ONE;
REPT := NUL;
CAPAS := NUL;
@ Validate configuration @
@ parameters @
IF MAXL LT MIN_PACKET_LENGTH
THEN @ Invalid MAXL parameter @
KMT_PP_LOG_PARAM_ERROR (MAXL_CODE,MAXL,80270,RESULT)
FI;
IF (MAXL + NPAD) LE MAX_OUTPUT_LENGTH
THEN
SKIP
ELSF @ Device line length exceeded @
( @ Adjust MAXL @
MAXL := MAX_OUTPUT_LENGTH - NPAD;
MAXL LT MIN_PACKET_LENGTH
)
THEN @ NPAD parameter invalid @
KMT_PP_LOG_PARAM_ERROR (NPAD_CODE,NPAD,80271,RESULT)
FI;
IF (PADC GT SPACE) AND (PADC NE DEL)
THEN @ Invalid PADC character @
KMT_PP_LOG_PARAM_ERROR (PADC_CODE,PADC,80272,RESULT)
FI;
IF EOL = LOCAL_MARK
THEN @ EOL conflicts with MARK @
KMT_PP_LOG_PARAM_ERROR (EOL_CODE,EOL,80276,RESULT)
ELSF KMT_SP_CHECK_VME_CHAR(EOL,1,RC);
RC NE 0
THEN @ EOL not acceptable to VME @
KMT_PP_LOG_PARAM_ERROR (EOL_CODE,EOL,80274,RESULT)
FI;
IF NPAD > 0
THEN @ check for PADC conflict @
IF PADC = LOCAL_MARK
THEN @ PADC conflicts with MARK @
KMT_PP_LOG_PARAM_ERROR (PADC_CODE,PADC,80276,RESULT)
ELSF PADC = EOL
THEN @ PADC conflicts with EOL @
KMT_PP_LOG_PARAM_ERROR (PADC_CODE,PADC,80277,RESULT)
ELSF KMT_SP_CHECK_VME_CHAR(PADC,1,RC);
RC NE 0
THEN @ PADC not acceptable to VME @
KMT_PP_LOG_PARAM_ERROR (PADC_CODE,PADC,80274,RESULT)
FI
FI;
IF (QCTL LE SPACE) OR (QCTL GE DEL)
THEN @ Invalid QCTL character @
KMT_PP_LOG_PARAM_ERROR (QCTL_CODE,QCTL,80273,RESULT)
FI;
IF (QCTL GT RAB) AND (QCTL LT GRAVE)
THEN
@ KERMIT protocol permits the QCTL character to be any printable @
@ character. However a QCTL character value in the range X3F to X5F may @
@ result in data corruption. A warning message is logged but the choice @
@ of QCTL is permitted as the protocol allows it. eg Consider a QCTL @
@ character of '?' (X3F) and data containing the character DEL (X7F). @
@ The sender encodes this as a two byte sequence: QCTL (DEL XOR X40) @
@ ie '??' (X3F3F). The quoting rule states that QCTL caharacters @
@ appearing in the data must also be prefixed. Therefore the receiver @
@ will decode the sequence as '?' (X3F) not DEL (X7F) as required. @
BYTE CORRUPTED_CHAR := (QCTL NEQ X"40");
() KMT_MTM_VALUES PARAMS := (QCTL
AS KMT_MTM_VALUES.RVB_VALUE,
CORRUPTED_CHAR
AS KMT_MTM_VALUES.RVB_VALUE);
KMT_EH_LOG_ERROR (KMT_PP_QCTL_WARNING,2,PARAMS,0,FALSE,FALSE)
FI;
IF TEXT_TYPE EQ EBCDIC
THEN @ EBCDIC file transfer @
SKIP
ELSF
(QBIN LT SPACE)
OR
(QBIN GT TILDE)
OR
((QBIN GT RAB) AND (QBIN LT GRAVE))
THEN @ Invalid QBIN character @
KMT_PP_LOG_PARAM_ERROR (QBIN_CODE,QBIN,80275,RESULT)
ELSF
QBIN EQ SPACE
THEN @ QBIN character rejected @
RESULT := KMT_PP_QBIN_REJECTED;
KMT_EH_LOG_ERROR (RESULT,2,NIL,0,FALSE,FALSE)
ELSF
QBIN EQ QCTL OR QBIN EQ LOCAL_QCTL
THEN @ ASCII or binary file xfer, @
@ but QBIN and QCTL characters@
@ are equal @
() KMT_MTM_VALUES PARAMS := (QBIN
AS KMT_MTM_VALUES.RVB_VALUE,
QCTL
AS KMT_MTM_VALUES.RVB_VALUE,
LOCAL_QCTL
AS KMT_MTM_VALUES.RVB_VALUE);
RESULT := KMT_PP_QBIN_AND_QCTL_EQUAL;
KMT_EH_LOG_ERROR (RESULT,2,PARAMS,0,FALSE,FALSE)
ELSE @ IA5 or binary file transfer,@
@ and QCTL and QBIN characters@
@ are acceptable @
LOCAL_QBIN := QBIN
FI
END; @ KMT_PP_PROCESS_PARAM_PACKET_DATA @
ENDMODULE @ KMT_PP_MODULE @
$$$$ KMT_SP_MODULE
MODULE KMT_SP_MODULE;
@******************************************************************************@
@* *@
@* Mode definitions *@
@* *@
@******************************************************************************@
MODE
KMT_DH_DEVICE_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
WORD MAX_INPUT_LENGTH,
MAX_OUTPUT_LENGTH,
INPUT_PARITY,
OUTPUT_PARITY,
PAUSE);
MODE
KMT_FH_RECORD_DETAILS_S IS STRUCT (
BOOL FILE_OPEN,
NEW_RECORD,
END_OF_FILE,
WORD TEXT_TYPE, @ 0 = EBCDIC @
@ 1 = IA5 @
@ 2 = BINARY @
INT MAX_RECORD_LENGTH,
RECORD_LENGTH,
(4098) BYTE RECORD); @ Maximum record size of 4096 @
@ plus 2 bytes for CRLF pair @
@ when constructing output @
@ records @
MODE
KMT_FH_FILE_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
INT OUTPUT_TOTAL);
MODE
KMT_PP_CONFG_PARAMS_S IS STRUCT (
BYTE MARK,
MAXL,
TIME,
NPAD,
PADC,
EOL,
QCTL,
QBIN,
CHKT,
REPT,
4-BYTE CAPAS);
MODE
KMT_PP_PACKET_STATISTICS_S IS STRUCT (
INT INPUT_TOTAL,
OUTPUT_TOTAL);
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT (
BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE
KMT_MTM_VALUES IS ANY (
LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF () BYTE RVB_VALUE,
REF () REF () BYTE RVRVB_VALUE);
MODE
KMT_BUFFER IS (96) BYTE;
MODE
KMT_STRING IS REF () BYTE;
MODE
KMT_WORD IS REF () BYTE;
***PAGE
@******************************************************************************@
@* *@
@* External procedure references *@
@* *@
@******************************************************************************@
EXT (<PREFIX "ICLCTM">)
PROC
(RESPONSE @ RESPONSE @
) CTM_JS_BEGIN;
EXT (<PREFIX "ICLCTM">)
PROC
(RESPONSE @ RESPONSE @
) CTM_JS_END;
EXT (<PREFIX "ICLCTM">)
PROC
(REF () BYTE, @ PROMPT @
REF () BYTE, @ MESSAGE @
REF LONG INT, @ LENGTH_MESSAGE @
RESPONSE @ RESPONSE @
) ASK_MESSAGE;
EXT (<PREFIX "ICLCTM">)
PROC
(WORD, @ TYPE @
WORD, @ DESTINATION @
REF () BYTE, @ MESSAGE @
RESPONSE @ RESPONSE @
) CTM_LOG;
EXT (<PREFIX "ICLMACROS">)
PROC
(REF () REF () BYTE, @ NAMES @
REF () BYTE, @ JOURNAL_LIST @
RESPONSE @ RESPONSE @
) SET_OPTIONS;
EXT
PROC
(INT, @ TEXT_NUMBER @
REF () KMT_MTM_VALUES @ PARAMS @
) INT KMT_SP_MTM;
***PAGE
@******************************************************************************@
@* *@
@* External data references *@
@* *@
@******************************************************************************@
@ Constants: @
@ ********** @
EXT
INT UNSET;
EXT
INT VME_TERM, @ 0 @ @forms of name standardisation @
VME_STD, @ 1 @
KMT_STD; @ 2 @
***LINES(4)
@ Variables: @
@ ********** @
EXT (<CASCADE>)
REF BOOL TRANSLATE_FILENAME;
EXT REF INT EXIT_STATE,
FILE_OPTION,
MAXTRY,
RETRY_COUNT,
RETRY_TOTAL,
TIMEOUT_TOTAL;
EXT REF WORD DELAY;
EXT REF BOOL ASG_ROUTE,
DELAY_TIMER,
SAVE_INCOMPLETE_FILE;
EXT (<CASCADE>)
REF KMT_DH_DEVICE_DETAILS_S KMT_DH_DEVICE_DETAILS;
EXT (<CASCADE>)
REF KMT_FH_RECORD_DETAILS_S KMT_FH_RECORD_DETAILS;
EXT (<CASCADE>)
REF KMT_FH_FILE_STATISTICS_S KMT_FH_FILE_STATISTICS;
EXT (<CASCADE>)
REF KMT_PP_CONFG_PARAMS_S KMT_PP_LOCAL_CONFG_PARAMS;
EXT (<CASCADE>)
REF KMT_PP_CONFG_PARAMS_S KMT_PP_REMOTE_CONFG_PARAMS;
EXT (<CASCADE>)
REF KMT_PP_PACKET_STATISTICS_S KMT_PP_PACKET_STATISTICS;
EXT (<CASCADE>)
REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
***LINES(4)
@ Results: @
@ ******** @
***PAGE
@******************************************************************************@
@* *@
@* Procedure declarations *@
@* *@
@******************************************************************************@
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_SET_DEFAULTS IS ():
@******************************************************************************@
@* *@
@* This procedure is used to set default values for certain global variables. *@
@* *@
@******************************************************************************@
BEGIN
EXIT_STATE := UNSET;
FILE_OPTION := 1; @ create mode @
DELAY := 30;
DELAY_TIMER := FALSE;
SAVE_INCOMPLETE_FILE := FALSE;
TRANSLATE_FILENAME := TRUE;
MAXTRY := 5;
RETRY_COUNT := 0;
RETRY_TOTAL := 0;
TIMEOUT_TOTAL := 0;
KMT_TRACE_FLAGS := 0; @ No tracing @
KMT_DH_DEVICE_DETAILS.FILE_OPEN := FALSE; @ No file open initially @
KMT_DH_DEVICE_DETAILS.INPUT_PARITY := 4; @ No parity @
KMT_DH_DEVICE_DETAILS.OUTPUT_PARITY := 4; @ NO parity @
KMT_DH_DEVICE_DETAILS.PAUSE := 0; @ NO pause @
KMT_FH_RECORD_DETAILS.FILE_OPEN := FALSE; @ No file open initially @
KMT_FH_RECORD_DETAILS.TEXT_TYPE := 0; @ EBCDIC text @
KMT_FH_FILE_STATISTICS := (0,0); @ Zero record transfers @
KMT_PP_LOCAL_CONFG_PARAMS := (X"1E", @ MARK - Record Seperator @
80, @ MAXL @
0, @ TIME - No timeout @
0, @ NPAD - No padding @
X"00", @ PADC - Null @
X"0D", @ EOL - Carriage Return @
X"23", @ QCTL - Hash # @
X"26", @ QBIN - Ampersand & @
X"31", @ CHKT - Single check sum @
X"00", @ REPT - Not supported @
X'00'); @ CAPAS - Not supported @
KMT_PP_REMOTE_CONFG_PARAMS := (X"1E", @ MARK - Record Seperator @
80, @ MAXL @
0, @ TIME - No timeout @
0, @ NPAD - No padding @
X"00", @ PADC - Null @
X"0D", @ EOL - Carriage Return @
X"23", @ QCTL - Hash # @
X"26", @ QBIN - Ampersand & @
X"31", @ CHKT - Single check sum @
X"00", @ REPT - Not supported @
X'00'); @ CAPAS - Not supported @
KMT_PP_PACKET_STATISTICS := (0,0); @ Zero packet transfers @
END; @ KMT_SP_SET_DEFAULTS @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_CHAR_TO_HEX IS (
REF () BYTE HEX_DIGITS,
REF () BYTE HEX_STRING,
REF INT HEX_STRING_LENGTH,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to convert a string representing hexadecimal digits *@
@* from character to the hexadecimal notation. *@
@* The area referenced by HEX_DIGITS contains the string representing the *@
@* hexadecimal digits and HEX_STRING references an area to contain the *@
@* hexadecimal string. *@
@* The number of hexadecimal characters returned in HEX_STRING is returned *@
@* in the area referenced by HEX_STRING_LENGTH. *@
@* If a non hexadecimal digit is detected then HEX_STRING_LENGTH is returned *@
@* zero and resultcode KMT_SP_NOT_HEX is returned. *@
@* If the area referenced by HEX_STRING is not large enough to contain the *@
@* hexadecimal string then HEX_STRING_LENGTH is returned containing the size *@
@* required and resultcode KMT_SP_STRING_TOO_BIG is returned *@
@* *@
@******************************************************************************@
BEGIN
***PAGE
SIM
PROC
KMT_SP_HEX IS (
2-BYTE HEX_DIGITS) BYTE:
@******************************************************************************@
@* *@
@* This procedure is used to return a hexadecimal string from the two byte *@
@* hexadecimal representation supplied in HEX_STRING. *@
@* *@
@******************************************************************************@
BEGIN
(2) BYTE HEX_DIGITS_COPY := HEX_DIGITS;
FOR I
TO 1
DO
REF BYTE HEX_DIGIT IS HEX_DIGITS_COPY (I);
IF
(HEX_DIGIT GE "A") AND (HEX_DIGIT LE "F")
THEN @ In range "A" to "F" @
HEX_DIGIT := HEX_DIGIT + X"09"
FI;
HEX_DIGIT := HEX_DIGIT & X"0F"; @ In range X"00" to X"0F" @
REPEAT;
(W'PACKS (0,
HEX_DIGITS_COPY,
0,
NIL)) SCALE -4
END; @ KMT_SP_HEX @
***PAGE
INT KMT_SP_NOT_HEX IS 80050,
KMT_SP_STRING_TOO_BIG IS 80051;
INT HEX_DIGITS_LENGTH IS LENGTH HEX_DIGITS;
RESULT := UNLESS
(
() BYTE NON_HEX_BIT_MAP IS (X"FFFFFFFF FFFFFFFF"
X"FFFFFFFF FFFFFFFF"
X"81FFFFFF FFFFFFFF"
X"81FFFFFF FFFF003F");
@ Allow lower and upper case @
CHECK (NON_HEX_BIT_MAP,
HEX_DIGITS,
0,
NIL)
)
THEN @ Non hex digit in string @
HEX_STRING_LENGTH := 0;
KMT_SP_NOT_HEX
ELSF
(
HEX_STRING_LENGTH := (HEX_DIGITS_LENGTH + 1) / 2;
HEX_STRING_LENGTH GT LENGTH HEX_STRING
)
THEN @ Return string too small @
KMT_SP_STRING_TOO_BIG
ELSE @ Convert to hex @
INT HEX_DIGITS_INDEX := IF
((WORD:HEX_DIGITS_LENGTH) & 1) EQ 1
THEN @ Odd number of hex digits @
HEX_STRING(0) := KMT_SP_HEX (
HEX_DIGITS(0));
1
ELSE
0
FI;
FOR I
FROM HEX_DIGITS_INDEX
UNTIL
HEX_DIGITS_INDEX GE HEX_DIGITS_LENGTH
DO
HEX_STRING (I) := KMT_SP_HEX (HEX_DIGITS(HEX_DIGITS_INDEX
SIZE 2));
HEX_DIGITS_INDEX := HEX_DIGITS_INDEX + 2
REPEAT;
0
FI
END; @ KMT_SP_CHAR_TO_HEX @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_CONVERT_TO_BINARY IS (REF KMT_WORD W) WORD:
@ Converts Kermit word or string to a binary number @
IF W REF NIL
THEN @ not given @
-1
ELSF
(() BYTE BIT_MAP IS X"FFFFFFFF FFFFFFFF"
X"FFFFFFFF FFFFFFFF"
X"FFFFFFFF FFFFFFFF"
X"FFFFFFFF FFFF003F";
CHECK(BIT_MAP,W,0,NIL)
)
THEN @ numeric @
I'PACKS(0,W,0,NIL)
ELSF
LENGTH W < 2 OR W(0) NE "X"
THEN @ not hex - invalid @
-1
ELSE
(4) BYTE HEX;
INT HEX_LEN,RESULT;
KMT_SP_CHAR_TO_HEX(W(1::),HEX,HEX_LEN,RESULT);
IF RESULT NE 0 OR HEX_LEN < 1
THEN @ invalid hex digits @
-1
ELSE @ VALID HEX NUMBER @
HEX(SIZE HEX_LEN)
FI
FI
; @ KMT_SP_CONVERT_TO_BINARY @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_CONVERT_TO_UPPER_CASE IS (
REF () BYTE BUFFER):
@******************************************************************************@
@* *@
@* This procedure is used to convert lowercase EBCDIC alphabetic characters *@
@* to uppercase EBCDIC. *@
@* The characters to be case converted are read from and the case converted *@
@* characters are written to the area referenced by BUFFER. *@
@* *@
@******************************************************************************@
UNLESS (BUFFER IS NIL) OR (LENGTH BUFFER EQ 0)
DO
(256) BYTE UPPER_CASE_TT IS X"00010203 04050607 08090A0B 0C0D0E0F"
X"10111213 14151617 18191A1B 1C1D1E1F"
X"20212223 24252627 28292A2B 2C2D2E2F"
X"30313233 34353637 38393A3B 3C3D3E3F"
X"40414243 44454647 48494A4B 4C4D4E4F"
X"50515253 54555657 58595A5B 5C5D5E5F"
X"60616263 64656667 68696A6B 6C6D6E6F"
X"70717273 74757677 78797A7B 7C7D7E7F"
X"80C1C2C3 C4C5C6C7 C8C98A8B 8C8D8E8F"
X"90D1D2D3 D4D5D6D7 D8D99A9B 9C9D9E9F"
X"A0A1E2E3 E4E5E6E7 E8E9AAAB ACADAEAF"
X"B0B1B2B3 B4B5B6B7 B8B9BABB BCBDBEBF"
X"C0C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF"
X"D0D1D2D3 D4D5D6D7 D8D9DADB DCDDDEDF"
X"E0E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF"
X"F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFEFF";
TRANSLATE (UPPER_CASE_TT,BUFFER,0,NIL);
FI
; @ KMT_SP_CONVERT_TO_UPPERCASE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_ASK_MESSAGE IS (
REF () BYTE PROMPT,
REF () BYTE MESSAGE,
REF LONG INT LENGTH_MESSAGE,
BOOL LOG_PROMPT,
RESPONSE RESULT):
@******************************************************************************@
@* *@
@* This procedure is used to output a prompt to the users terminal and read a *@
@* reply to the prompt. Logging of the prompt and reply to the journal is *@
@* turned off. *@
@* *@
@******************************************************************************@
BEGIN
INT RC_DISCARDED;
CTM_JS_BEGIN (RESULT);
IF RESULT LE 0
THEN @ Resource block created @
UNLESS LOG_PROMPT
DO
() BYTE NAME := "NOLASKS";
() REF () BYTE NAMES := DISPLAY(NAME);
(0) BYTE ZLR;
SET_OPTIONS (NAMES,ZLR,RC_DISCARDED)
FI;
ASK_MESSAGE (PROMPT,MESSAGE,LENGTH_MESSAGE,RESULT);
CTM_JS_END (RC_DISCARDED) @ End resource block @
FI
END; @ KMT_SP_ASK_MESSAGE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_LOG_TRACE_MESSAGE IS (
INT TYPE,
REF () KMT_MTM_VALUES PARAMS):
@******************************************************************************@
@* *@
@* This procedure is used to log a trace message (printed in hex) to the job *@
@* journal. *@
@* TYPE specifies the type of trace message and PARAMS references a list of *@
@* parameters to be used in the expansion of the message. *@
@* *@
@******************************************************************************@
BEGIN
INT PARAMS_LENGTH IS IF
PARAMS IS NIL
THEN
0
ELSE
LENGTH PARAMS
FI;
INT MTM_AREA_LENGTH IS 4 + PARAMS_LENGTH;
(MTM_AREA_LENGTH) KMT_MTM_VALUES MTM_AREA;
INT MTM_TEXT_NUMBER := TYPE,
MTM_REPLY,
MTM_MESSAGE_LENGTH;
(100) BYTE MTM_MESSAGE;
(2) REF () BYTE MTM_RECALL_DATA;
MTM_AREA(SIZE 4) := (MTM_MESSAGE
AS KMT_MTM_VALUES.RVB_VALUE,
MTM_MESSAGE_LENGTH
AS KMT_MTM_VALUES.RI_VALUE,
MTM_RECALL_DATA
AS KMT_MTM_VALUES.RVRVB_VALUE,
(L'PARAMS_LENGTH)
AS KMT_MTM_VALUES.LI_VALUE);
IF
PARAMS_LENGTH GT 0
THEN
MTM_AREA(4::) := PARAMS
FI;
WHILE
(
INT RC_DISCARDED;
MTM_REPLY := KMT_SP_MTM (MTM_TEXT_NUMBER,MTM_AREA);
IF
MTM_REPLY NE -2
THEN @ Expanded message returned @
REF () BYTE MESSAGE IS IF
MTM_REPLY EQ -3
THEN @ Returned in recall data @
MTM_TEXT_NUMBER := 0;
MTM_RECALL_DATA(0)
ELSE @ Returned in message buffer @
MTM_TEXT_NUMBER := MTM_REPLY;
MTM_MESSAGE(SIZE MTM_MESSAGE_LENGTH)
FI;
CTM_LOG (3,
2, @ Log to journal only @
MESSAGE,
RC_DISCARDED)
ELSE @ No message data @
MTM_TEXT_NUMBER := 0
FI;
MTM_TEXT_NUMBER NE 0
)
DO
SKIP
REPEAT
END; @ KMT_SP_LOG_TRACE_MESSAGE @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_STANDARDISE_FILENAME IS (REF KMT_WORD FILENAME,
INT STD_FORM):
@ standardises filenames (if reqd) according to STD_FORM: @
@ @
@ VME_TERM - terminal name of filename, i.e. part after rightmost dot @
@ VME_STD - remove suffix from filename which should be in Kermit @
@ normal form as sent in packet by remote Kermit @
@ KMT_STD - convert filename to Kermit normal form, i.e. name.type @
@ @
@ in each case any file generation number will be removed and all lower @
@ case alphabetic characters converted to upper case. any non-alphanumeric @
@ characters (except fullstop) will be converted to X @
BEGIN
IF TRANSLATE_FILENAME
THEN @ filename translation required @
REF () BYTE NAME,REM;
NAME := FILENAME;
REM := FILENAME;
UNTIL SCANUNQ(".",REM,0,REM) @ locate fullstop @
DO
INT NAME_LEN IS LENGTH NAME,
REM_LEN IS LENGTH REM;
REM := IF REM_LEN > 1
THEN REM(1::) @ strip off fullstop @
ELSE REM(SIZE 0) @ "." last character @
FI;
NAME := IF NOT SCANUNQ(".",REM,0,NIL) @ if more fullstops @
THEN REM @ continue @
ELSF STD_FORM = VME_TERM
THEN REM @ bit after fullstop @
ELSF STD_FORM = VME_STD
THEN NAME(SIZE(NAME_LEN-REM_LEN)) @ bit before fullstop@
ELSE NAME @ KMT_STD @ @ i.e. name.type @
FI
REPEAT;
SCANUNQ("(",NAME,0,REM); @ locate generation number (if present) @
FILENAME := NAME(SIZE (LENGTH NAME - LENGTH REM)); @ remove gen no @
IF LENGTH FILENAME > 0
THEN @ standardise characters @
(256) BYTE STD_CHAR_TT IS X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E74B E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7C1C2C3 C4C5C6C7 C8C9E7E7 E7E7E7E7"
X"E7D1D2D3 D4D5D6D7 D8D9E7E7 E7E7E7E7"
X"E7E7E2E3 E4E5E6E7 E8E9E7E7 E7E7E7E7"
X"E7E7E7E7 E7E7E7E7 E7E7E7E7 E7E7E7E7"
X"E7C1C2C3 C4C5C6C7 C8C9E7E7 E7E7E7E7"
X"E7D1D2D3 D4D5D6D7 D8D9E7E7 E7E7E7E7"
X"E7E7E2E3 E4E5E6E7 E8E9E7E7 E7E7E7E7"
X"F0F1F2F3 F4F5F6F7 F8F9E7E7 E7E7E7E7";
TRANSLATE(STD_CHAR_TT,FILENAME,0,NIL)
ELSE @ invalid name @
FILENAME := NIL
FI
FI
END
; @ KMT_SP_STANDARDISE_FILENAME @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_GET_WORD IS (REF KMT_STRING S) KMT_WORD:
@ extract word (delimited by spaces) from string, advance pointer over word @
BEGIN
KMT_STRING S1,S2;
IF SCANEQ(" ",S,0,S1) @ skip leading spaces @
THEN NIL @ end of line, return null word @
ELSE
SCANUNQ(" ",S1,0,S2); @ find next space (end of word) @
S := S2; @ advance pointer @
S1(SIZE LENGTH S1 - LENGTH S2) @ return word @
FI
END
; @ KMT_SP_GET_WORD @
***PAGE
GLOBAL
STATIC (<STATUS 5>)
PROC
KMT_SP_CHECK_VME_CHAR IS (WORD CHAR,WORD IO_FLAG,RESPONSE RESULT):
@ check that CHAR is acceptable for VME I/O @
BEGIN
IF CHAR = 127 @ ASCII DEL @
THEN
RESULT := 0
ELSE
()BYTE X := DISPLAY (CHAR);
REF () BYTE B := X;
() BYTE CHECK_BITS IS
IF ASG_ROUTE AND IO_FLAG = 0 THEN X"FFFF0FFF" @ in via ASG @
ELSF ASG_ROUTE THEN X"A7DFFFFF" @ out via ASG @
ELSF IO_FLAG = 0 THEN X"0183087F" @ in via CSC or NIC @
ELSE X"A7DFFFFF" @ out via CSC or NIC @
FI;
RESULT := IF CHECK(CHECK_BITS,B,1,NIL) THEN 85936 ELSE 0 FI
FI
END
; @ KMT_SP_CHECK_VME_CHAR @
ENDMODULE @ KMT_SP_MODULE @
$$$$ KMT_UI_MODULE
MODULE KMT_UI_MODULE;
@ Mode declarations @
MODE KMT_BUFFER IS (96)BYTE;
MODE KMT_STRING IS REF()BYTE;
MODE KMT_WORD IS REF()BYTE;
MODE KMT_MTM_VALUES IS ANY
(LONG WORD LW_VALUE,
LONG INT LI_VALUE,
REF WORD RW_VALUE,
REF INT RI_VALUE,
REF LONG WORD RLW_VALUE,
REF LONG INT RLI_VALUE,
REF()BYTE RVB_VALUE,
REF()REF()BYTE RVRVB_VALUE);
MODE
KMT_DH_DEVICE_DETAILS_S IS STRUCT
(BOOL FILE_OPEN,
WORD MAX_INPUT_LENGTH,
MAX_OUTPUT_LENGTH,
INPUT_PARITY,
OUTPUT_PARITY,
PAUSE);
MODE
KMT_FH_RECORD_DETAILS_S IS STRUCT
(BOOL FILE_OPEN,
NEW_RECORD,
END_OF_FILE,
WORD TEXT_TYPE, @ 0 = EBCDIC @
@ 1 = IA5 @
@ 2 = BINARY @
INT MAX_RECORD_LENGTH,
RECORD_LENGTH,
(4098) BYTE RECORD); @ Maximum record size of 4096 @
@ plus 2 bytes for CRLF pair @
@ when constructing output @
@ records @
MODE
KMT_PP_CONFG_PARAMS_S IS STRUCT
(BYTE MARK,
MAXL,
TIME,
NPAD,
PADC,
EOL,
QCTL,
QBIN,
CHKT,
REPT,
4-BYTE CAPAS);
MODE
KMT_TRACE_FLAGS_S IS WORD STRUCT
(BIT PH_TRACING,
PP_TRACING,
FH_TRACING,
DH_TRACING,
28-BIT SPARE);
MODE KMT_FH_FILE_STATISTICS_S IS STRUCT
(INT INPUT_TOTAL,
INT OUTPUT_TOTAL);
MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
(INT INPUT_TOTAL,
INT OUTPUT_TOTAL);
MODE KMT_STATISTICS_S IS STRUCT
(REF KMT_FH_FILE_STATISTICS_S FH_FILE_STATISTICS,
REF KMT_PP_PACKET_STATISTICS_S PACKET_STATISTICS);
@ External procedures @
EXT PROC (INT,RESPONSE) KMT_MESSAGE;
EXT PROC (INT,REF()KMT_MTM_VALUES) INT KMT_HELP_MTM;
EXT PROC (INT,REF()KMT_MTM_VALUES) INT KMT_SP_MTM;
EXT PROC (REF KMT_STRING) KMT_WORD KMT_SP_GET_WORD,
PROC (REF () BYTE) KMT_SP_CONVERT_TO_UPPER_CASE,
PROC (()BYTE,REF()BYTE,REF LONG INT,BOOL,RESPONSE)
KMT_SP_ASK_MESSAGE,
PROC (REF KMT_WORD) WORD KMT_SP_CONVERT_TO_BINARY,
PROC (WORD,WORD,RESPONSE) KMT_SP_CHECK_VME_CHAR;
EXT PROC (WORD,WORD,REF()BYTE,RESPONSE) CTM_LOG;
@ External constants @
EXT INT UNSET,EXIT; @ miscellaneous constants @
EXT INT SERVER_MODE,RECEIVE_MODE,SEND_MODE,COMMAND_MODE;
EXT INT REC_SERVER_IDLE,REC_INIT,SEND_INIT,COMPLETE,ABORT; @ protocol handler @
@ states @
EXT REF INT EXIT_STATE, @ controls main Kermit loop @
KMT_CURRENT_MODE, @ Server/Receive/Send/Command @
KMT_PH_STATE; @ Protocol Handler state @
EXT (256) BYTE
EBCDIC_TO_ASCII, @ Translation tables @
ASCII_TO_EBCDIC;
EXT REF KMT_STRING KMT_PH_INPUT_PACKET_DATA;
EXT REF KMT_BUFFER KMT_VME_FILE_BUF,KMT_REM_FILE_BUF,KMT_INPUT_BUF;
EXT REF KMT_WORD KMT_VME_FILE,KMT_REM_FILE;
EXT REF()KMT_MTM_VALUES KMT_MTM_AREA;
EXT REF INT MAXTRY,RETRY_COUNT,RETRY_TOTAL,TIMEOUT_TOTAL;
EXT REF INT FILE_OPTION;
EXT REF WORD DELAY;
EXT REF BOOL TRANSLATE_FILENAME;
EXT REF BOOL SAVE_INCOMPLETE_FILE;
EXT REF KMT_DH_DEVICE_DETAILS_S KMT_DH_DEVICE_DETAILS;
EXT REF KMT_FH_RECORD_DETAILS_S KMT_FH_RECORD_DETAILS;
EXT REF KMT_PP_CONFG_PARAMS_S KMT_PP_LOCAL_CONFG_PARAMS,
KMT_PP_REMOTE_CONFG_PARAMS;
EXT REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
EXT REF KMT_STATISTICS_S KMT_STATISTICS;
GLOBAL STATIC (<STATUS 5>) PROC KMT_UI IS (RESPONSE RESULT):
@ requests command from user and executes command @
BEGIN
LONG INT STRLEN; @ length of input @
INT RC_IGNORED; @ response variable @
KMT_STRING KMT_CMD_BUF, @ command input string @
KMT_PARSE; @ pointer for parsing command string @
(10)KMT_MTM_VALUES HELP_MTM_AREA;
(80)BYTE HELP_TEXT;
INT HELP_TEXT_LEN;
(2)REF()BYTE HELP_RECALL_DATA;
INT MARK_PARAM IS 0,
EOL_PARAM IS 1,
PADC_PARAM IS 2;
@ support procs @
SIM PROC CHECK_AND_SET_PARAM IS (INT PARAM_CODE, WORD VALUE, WORD P_FLAG,
RESPONSE RESULT):
@ checks new value for MARK/EOL/PADC doesn't conflict with EOL/PADC/ @
@ MARK (as appropriate) and that the value is acceptable to VME I/O @
BEGIN
IF VALUE > 31 AND VALUE NE 127
THEN @ not a control character @
RESULT := 85935
ELSE
INT PMATCH;
REF KMT_PP_CONFG_PARAMS_S
CONFG_PARAMS IS IF P_FLAG = 0
THEN KMT_PP_REMOTE_CONFG_PARAMS @ receive @
ELSE KMT_PP_LOCAL_CONFG_PARAMS @ send @
FI;
RESULT := UNSET;
IF VALUE = CONFG_PARAMS.MARK @ check if value matches any param @
THEN PMATCH := MARK_PARAM
ELSF VALUE = CONFG_PARAMS.EOL
THEN PMATCH := EOL_PARAM
ELSF VALUE = CONFG_PARAMS.PADC
THEN PMATCH := PADC_PARAM
ELSF KMT_SP_CHECK_VME_CHAR(VALUE,P_FLAG,RESULT);
RESULT = 0
THEN @ character ok for VME I/O so set parameter @
CASE PARAM_CODE
THEN CONFG_PARAMS.MARK := VALUE
ELSE CONFG_PARAMS.EOL := VALUE
ELSE CONFG_PARAMS.PADC := VALUE
ESAC;
RESULT := 0
FI;
IF RESULT = UNSET
THEN
IF PMATCH = PARAM_CODE
THEN @ matched current value, ignore @
RESULT := 0
ELSE @ conflict with another parameter @
KMT_MTM_AREA(7) := PMATCH AS KMT_MTM_VALUES.RI_VALUE;
RESULT := 85937
FI
FI
FI
END
; @ CHECK_AND_SET_PARAM @
SIM PROC EXPAND_HELP IS (INT MSG_NO) INT:
@ expand help text until reply is -2 (no message found) or 0 (halted @
@ at end of message) or > 0 (halt code returned). @
BEGIN
INT M := MSG_NO,
REPLY := UNSET; @ -1 @
WHILE REPLY = UNSET
DO
REPLY := KMT_HELP_MTM(M,HELP_MTM_AREA);
IF REPLY = -1 OR REPLY = 0
THEN
M := REPLY;
CTM_LOG(3,10,HELP_TEXT(SIZE HELP_TEXT_LEN),RC_IGNORED)
FI
REPEAT;
REPLY @ return last reply @
END
; @ EXPAND_HELP @
@ procedures for executing commands @
SIM PROC KMT_UI_SERVER IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ SERVER command, Syntax: SERVER @
@ selects Kermit Server mode @
@ (not implemented in Server mode) @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
KMT_CURRENT_MODE := SERVER_MODE;
KMT_PH_STATE := REC_SERVER_IDLE;
RETRY_COUNT := RETRY_TOTAL := TIMEOUT_TOTAL := 0;
VAL KMT_STATISTICS.PACKET_STATISTICS := (0,0);
RESULT := 0
ELSE
RESULT := 89021 @ not implemented in Server mode @
FI
; @ KMT_UI_SERVER @
SIM PROC KMT_UI_RECEIVE IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ RECEIVE command, Syntax: RECEIVE [VME-filename] @
@ prepares VME kermit for the arrival of a file which will be @
@ saved with VME filename if specified, or with the filename sent @
@ by the remote Kermit @
@ (not implemented in Server mode) @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
@ check for optional filename @
KMT_VME_FILE := KMT_SP_GET_WORD(KMT_PARSE);
@ if present, copy to filename buffer @
UNLESS KMT_VME_FILE REF NIL
DO
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE
FI;
@ set Receive mode and initial protocol handler state @
KMT_CURRENT_MODE := RECEIVE_MODE;
KMT_PH_STATE := REC_INIT;
RETRY_COUNT := RETRY_TOTAL := TIMEOUT_TOTAL := 0;
VAL KMT_STATISTICS.PACKET_STATISTICS := (0,0);
RESULT := 0
ELSE
RESULT := 89021 @ not implemented in Server mode @
FI
; @ KMT_UI_RECEIVE @
SIM PROC KMT_UI_SEND IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ SEND command, Syntax: SEND VME-filename [remote-filename] @
@ sends the VME file to the remote Kermit with remote filename if @
@ specified otherwise with VME filename @
@ (not implemented in Server mode) @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
@ check for mandatory filename @
KMT_VME_FILE := KMT_SP_GET_WORD(KMT_PARSE);
IF NOT (KMT_VME_FILE REF NIL)
THEN
@ copy to filename buffer @
KMT_VME_FILE :=
KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
KMT_VME_FILE;
@ check for optional remote filename @
KMT_REM_FILE := KMT_SP_GET_WORD(KMT_PARSE);
@ if present copy to buffer @
UNLESS KMT_REM_FILE REF NIL
DO
KMT_REM_FILE :=
KMT_REM_FILE_BUF(SIZE LENGTH KMT_REM_FILE) :=
KMT_REM_FILE
FI;
@ set Send mode and initial protocol handler state @
KMT_CURRENT_MODE := SEND_MODE;
KMT_PH_STATE := SEND_INIT;
RETRY_COUNT := RETRY_TOTAL := TIMEOUT_TOTAL := 0;
VAL KMT_STATISTICS.PACKET_STATISTICS := (0,0);
RESULT := 0
ELSE
RESULT := -85010 @ VME filename must be present @
FI
ELSE
RESULT := 89021 @ not implemented in Server mode @
FI
; @ KMT_UI_SEND @
SIM PROC KMT_UI_HELP IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ HELP command, Syntax: HELP [command [argument(s)] ] @
@ provides on-line help for Kermit commands @
@ (not implemented in Server mode) @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
INT HELP_MSG_NO := 1, @ start of help info @
P1 := 0, @ indicates mtm call with command params @
HELP_REPLY;
@ set up message text parameter area @
HELP_MTM_AREA(SIZE 4) :=
(HELP_TEXT AS KMT_MTM_VALUES.RVB_VALUE,
HELP_TEXT_LEN AS KMT_MTM_VALUES.RI_VALUE,
HELP_RECALL_DATA AS KMT_MTM_VALUES.RVRVB_VALUE,
P1 AS KMT_MTM_VALUES.RI_VALUE);
@ obtain any command line parameters @
FOR I FROM 4 TO 9
DO
KMT_WORD HELP_ARG := KMT_SP_GET_WORD(KMT_PARSE);
KMT_SP_CONVERT_TO_UPPER_CASE(HELP_ARG);
HELP_MTM_AREA(I) :=
HELP_ARG AS KMT_MTM_VALUES.RVB_VALUE
REPEAT;
@ expand help until all done (0) or none found (-2) @
WHILE HELP_REPLY := EXPAND_HELP(HELP_MSG_NO);
HELP_REPLY > 0
DO
@ halt code returned, text is prompt, get response @
KMT_SP_ASK_MESSAGE(HELP_TEXT(SIZE HELP_TEXT_LEN),
KMT_INPUT_BUF,STRLEN,FALSE,RC_IGNORED);
P1 := 1; @ indicates mtm call with menu selection @
HELP_MTM_AREA(3) := P1 AS KMT_MTM_VALUES.RI_VALUE;
HELP_MTM_AREA(4) :=
KMT_INPUT_BUF(SIZE S'STRLEN) AS KMT_MTM_VALUES.RVB_VALUE;
HELP_MSG_NO := HELP_REPLY
REPEAT;
RESULT := 0
ELSE
RESULT := 89021 @ not implemented in Server mode @
FI
; @ KMT_UI_HELP @
SIM PROC KMT_UI_EXIT IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ EXIT command, Syntax: EXIT @
@ terminates Kermit execution @
BEGIN
EXIT_STATE := EXIT; @ set exit state @
IF KMT_CURRENT_MODE = SERVER_MODE
THEN
KMT_PH_STATE := COMPLETE
FI;
RESULT := 0
END
; @ KMT_UI_EXIT @
SIM PROC KMT_UI_SET IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ SET command, Syntax: SET [{SEND/RECEIVE}] parameter value @
@ sets Kermit parameters @
BEGIN
KMT_WORD ARG;
WORD P_FLAG,PARAM,OPTION;
RESULT := 0;
ARG := KMT_SP_GET_WORD(KMT_PARSE);
IF ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSF
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(4) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
P_FLAG := KMT_SP_MTM(5100,KMT_MTM_AREA);
P_FLAG NE W'UNSET
THEN @ SET SEND/RECEIVE command @
ARG := KMT_SP_GET_WORD(KMT_PARSE);
IF ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSF
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
PARAM := KMT_SP_MTM(5120,KMT_MTM_AREA);
PARAM = 921
THEN @ invalid SEND/RECEIVE parameter @
RESULT := 85921
ELSF
ARG := KMT_SP_GET_WORD(KMT_PARSE);
ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSE
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(6) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
CASE PARAM
THEN @ 0 - START-OF-PACKET @
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
CHECK_AND_SET_PARAM(MARK_PARAM,OPTION,P_FLAG,RESULT)
ELSE @ 1 - PACKET-LENGTH @
WORD DH_LEN,NPAD;
IF P_FLAG = 0
THEN @ RECEIVE @
DH_LEN := KMT_DH_DEVICE_DETAILS.MAX_INPUT_LENGTH;
NPAD := KMT_PP_LOCAL_CONFG_PARAMS.NPAD
ELSE
DH_LEN := KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH;
NPAD := KMT_PP_REMOTE_CONFG_PARAMS.NPAD
FI;
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION < 30 OR OPTION > 94 OR OPTION > DH_LEN
THEN @ invalid PACKET-LENGTH @
RESULT := 85931
ELSF
(OPTION + NPAD) > DH_LEN
THEN @ padding + packet length exceeds device line length @
RESULT := 85934
ELSF @ set parameter @
P_FLAG = 0
THEN @ RECEIVE @
KMT_PP_LOCAL_CONFG_PARAMS.MAXL := OPTION
ELSE @ SEND @
KMT_PP_REMOTE_CONFG_PARAMS.MAXL := OPTION
FI
ELSE @ 2 - TIMEOUT @
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION > 94
THEN @ invalid TIMEOUT @
RESULT := 85931
ELSF @ set parameter @
P_FLAG = 0
THEN @ RECEIVE @
KMT_PP_REMOTE_CONFG_PARAMS.TIME := OPTION
ELSE @ SEND @
KMT_PP_LOCAL_CONFG_PARAMS.TIME := OPTION
FI
ELSE @ 3 - END-OF-LINE @
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
CHECK_AND_SET_PARAM(EOL_PARAM,OPTION,P_FLAG,RESULT)
ELSE @ 4 - PADDING @
WORD DH_LEN,MAXL;
IF P_FLAG = 0
THEN @ RECEIVE @
DH_LEN := KMT_DH_DEVICE_DETAILS.MAX_INPUT_LENGTH;
MAXL := KMT_PP_LOCAL_CONFG_PARAMS.MAXL
ELSE @ SEND @
DH_LEN := KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH;
MAXL := KMT_PP_REMOTE_CONFG_PARAMS.MAXL
FI;
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION > 94 OR OPTION > DH_LEN
THEN @ invalid PADDING @
RESULT := 85931
ELSF
(OPTION + MAXL) > DH_LEN
THEN @ padding + packet length exceeds device line length @
RESULT := 85934
ELSF @ set parameter @
P_FLAG = 0
THEN @ RECEIVE @
KMT_PP_LOCAL_CONFG_PARAMS.NPAD := OPTION
ELSE @ SEND @
KMT_PP_REMOTE_CONFG_PARAMS.NPAD := OPTION
FI
ELSE @ 5 - PAD-CHARACTER @
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
CHECK_AND_SET_PARAM(PADC_PARAM,OPTION,P_FLAG,RESULT)
ELSE @ 6 - QUOTE @
REF KMT_PP_CONFG_PARAMS_S CONFG_PARAMS IS
IF P_FLAG = 0
THEN @ RECEIVE @
KMT_PP_REMOTE_CONFG_PARAMS
ELSE @ SEND @
KMT_PP_LOCAL_CONFG_PARAMS
FI;
OPTION := IF LENGTH ARG > 1
THEN @ may be decimal or hex @
KMT_SP_CONVERT_TO_BINARY(ARG)
ELSE @ EBCDIC character @
EBCDIC_TO_ASCII(ARG)
FI;
IF OPTION < 32 OR OPTION > 126
THEN @ not a printable character @
RESULT := 85931
ELSF CONFG_PARAMS.QBIN = OPTION
THEN @ QUOTE and EIGTH-BIT-PREFIX characters equal @
RESULT := 85933
ELSE @ set parameter @
CONFG_PARAMS.QCTL := OPTION
FI
ELSE @ 7 - EIGTH-BIT-PREFIX @
REF KMT_PP_CONFG_PARAMS_S CONFG_PARAMS IS
IF P_FLAG = 0
THEN @ RECEIVE @
KMT_PP_REMOTE_CONFG_PARAMS
ELSE @ SEND @
KMT_PP_LOCAL_CONFG_PARAMS
FI;
OPTION := IF LENGTH ARG > 1
THEN @ may be decimal or hex @
KMT_SP_CONVERT_TO_BINARY(ARG)
ELSE @ EBCDIC character @
EBCDIC_TO_ASCII(ARG)
FI;
IF OPTION < 32 OR OPTION > 126
OR (OPTION > 62 AND OPTION < 96)
THEN @ not a printable character @
RESULT := 85931
ELSF CONFG_PARAMS.QCTL = OPTION
THEN @ QUOTE and EIGTH-BIT-PREFIX characters equal @
RESULT := 85933
ELSE @ set parameter @
CONFG_PARAMS.QBIN := OPTION
FI
DEFAULT @ invalid SEND/RECEIVE parameter @
RESULT := 85921
ESAC
FI
ELSF
P_FLAG := KMT_SP_MTM(5110,KMT_MTM_AREA);
P_FLAG = 920
THEN @ invalid SET parameter @
RESULT := 85920
ELSF @ SET DEBUG/DELAY/FILE/RETRY/PAUSE @
ARG := KMT_SP_GET_WORD(KMT_PARSE);
ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSE
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
CASE P_FLAG
THEN @ 0 - DEBUG @
PARAM := KMT_SP_MTM(5130,KMT_MTM_AREA);
IF PARAM = 921
THEN @ invalid DEBUG parameter @
RESULT := 85921
ELSF
ARG := KMT_SP_GET_WORD(KMT_PARSE);
ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSF
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(6) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
OPTION := KMT_SP_MTM(5150,KMT_MTM_AREA);
OPTION = 931
THEN @ invalid option @
RESULT := 85931
ELSE @ set parameter @
CASE PARAM
THEN @ 0 - ALL @
KMT_TRACE_FLAGS := IF OPTION = 0
THEN @ OFF @
0
ELSE @ ON @
-1
FI
ELSE @ 1 - FILE @
KMT_TRACE_FLAGS.FH_TRACING := OPTION
ELSE @ 2 - PROTOCOL @
KMT_TRACE_FLAGS.PH_TRACING := OPTION
ELSE @ 3 - PACKET @
KMT_TRACE_FLAGS.PP_TRACING := OPTION
ELSE @ 4 - DEVICE @
KMT_TRACE_FLAGS.DH_TRACING := OPTION
DEFAULT @ invalid option @
RESULT := 85931
ESAC
FI
ELSE @ 1 - DELAY @
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION < 5 OR OPTION > 300
THEN @ invalid DELAY parameter @
RESULT := 85930
ELSE @ set parameter @
DELAY := I'(OPTION)
FI
ELSE @ 2 - FILE @
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
ARG := KMT_SP_GET_WORD(KMT_PARSE);
IF ARG REF NIL
THEN @ incomplete command @
RESULT := 85932
ELSF
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(6) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
OPTION := KMT_SP_MTM(5140,KMT_MTM_AREA);
OPTION = 921 OR OPTION = 931
THEN @ invalid FILE parameter or option @
RESULT := 85000 + OPTION
ELSF OPTION < 3
THEN @ TYPE - EBCDIC, ASCII, BINARY @
KMT_FH_RECORD_DETAILS.TEXT_TYPE := OPTION
ELSF OPTION < 5
THEN @ NAMING @
TRANSLATE_FILENAME := (OPTION = 4)
ELSF OPTION < 7
THEN @ OVERWRITE @
FILE_OPTION := IF OPTION = 5
THEN @ create mode @
1
ELSE @ create replace mode @
2
FI
ELSF OPTION < 9
THEN @ INCOMPLETE @
SAVE_INCOMPLETE_FILE := (OPTION = 8)
ELSE @ invalid FILE parameter @
RESULT := 85931
FI
ELSE @ 3 - RETRY @
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION > 10
THEN @ invalid RETRY @
RESULT := 85930
ELSE @ set parameter @
MAXTRY := OPTION + 1
FI
ELSE @ 4 - PAUSE @
KMT_SP_CONVERT_TO_UPPER_CASE(ARG);
KMT_MTM_AREA(5) := ARG AS KMT_MTM_VALUES.RVB_VALUE;
OPTION := KMT_SP_CONVERT_TO_BINARY(ARG);
IF OPTION > 50
THEN @ invalid PAUSE @
RESULT := 85930
ELSE @ set parameter @
KMT_DH_DEVICE_DETAILS.PAUSE := (I'OPTION) * 100
FI
DEFAULT @ invalid SET parameter @
RESULT := 85920
ESAC
FI;
IF KMT_CURRENT_MODE NE SERVER_MODE AND RESULT > 0
THEN @ don't send error packet if not in server mode @
RESULT := -RESULT
FI
END
; @ KMT_UI_SET @
SIM PROC KMT_UI_SHOW IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ SHOW command, Syntax: SHOW @
@ displays the current values of all Kermit parameters @
@ (this variant not implemented in Server mode @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
BYTE
REM_QCTL := ASCII_TO_EBCDIC(KMT_PP_REMOTE_CONFG_PARAMS.QCTL),
REM_QBIN := ASCII_TO_EBCDIC(KMT_PP_REMOTE_CONFG_PARAMS.QBIN),
LOC_QCTL := ASCII_TO_EBCDIC(KMT_PP_LOCAL_CONFG_PARAMS.QCTL),
LOC_QBIN := ASCII_TO_EBCDIC(KMT_PP_LOCAL_CONFG_PARAMS.QBIN);
KMT_MTM_AREA(3 SIZE 3) :=
((L'(I'DELAY)) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(I'KMT_DH_DEVICE_DETAILS.PAUSE)/100) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(MAXTRY-1)) AS
KMT_MTM_VALUES.LI_VALUE);
KMT_MESSAGE(-85821,RC_IGNORED);
KMT_MTM_AREA(3 SIZE 8) :=
(KMT_PP_REMOTE_CONFG_PARAMS.MARK AS
KMT_MTM_VALUES.RVB_VALUE,
(L'KMT_PP_LOCAL_CONFG_PARAMS.MAXL) AS
KMT_MTM_VALUES.LW_VALUE,
(L'KMT_PP_REMOTE_CONFG_PARAMS.TIME) AS
KMT_MTM_VALUES.LW_VALUE,
(L'KMT_PP_LOCAL_CONFG_PARAMS.NPAD) AS
KMT_MTM_VALUES.LW_VALUE,
KMT_PP_LOCAL_CONFG_PARAMS.PADC AS
KMT_MTM_VALUES.RVB_VALUE,
KMT_PP_LOCAL_CONFG_PARAMS.EOL AS
KMT_MTM_VALUES.RVB_VALUE,
REM_QCTL AS
KMT_MTM_VALUES.RVB_VALUE,
REM_QBIN AS
KMT_MTM_VALUES.RVB_VALUE);
KMT_MESSAGE(-85822,RC_IGNORED);
KMT_MTM_AREA(3 SIZE 8) :=
(KMT_PP_LOCAL_CONFG_PARAMS.MARK AS
KMT_MTM_VALUES.RVB_VALUE,
(L'KMT_PP_REMOTE_CONFG_PARAMS.MAXL) AS
KMT_MTM_VALUES.LW_VALUE,
(L'KMT_PP_LOCAL_CONFG_PARAMS.TIME) AS
KMT_MTM_VALUES.LW_VALUE,
(L'KMT_PP_REMOTE_CONFG_PARAMS.NPAD) AS
KMT_MTM_VALUES.LW_VALUE,
KMT_PP_REMOTE_CONFG_PARAMS.PADC AS
KMT_MTM_VALUES.RVB_VALUE,
KMT_PP_REMOTE_CONFG_PARAMS.EOL AS
KMT_MTM_VALUES.RVB_VALUE,
LOC_QCTL AS
KMT_MTM_VALUES.RVB_VALUE,
LOC_QBIN AS
KMT_MTM_VALUES.RVB_VALUE);
KMT_MESSAGE(-85823,RC_IGNORED);
KMT_MTM_AREA(3 SIZE 4) :=
(KMT_FH_RECORD_DETAILS.TEXT_TYPE AS
KMT_MTM_VALUES.RW_VALUE,
FILE_OPTION AS
KMT_MTM_VALUES.RI_VALUE,
(L'(WORD: (BIT: SAVE_INCOMPLETE_FILE))) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(WORD: (BIT: TRANSLATE_FILENAME))) AS
KMT_MTM_VALUES.LW_VALUE);
KMT_MESSAGE(-85825,RC_IGNORED);
KMT_MTM_AREA(3 SIZE 2) :=
(KMT_DH_DEVICE_DETAILS.MAX_INPUT_LENGTH AS
KMT_MTM_VALUES.RW_VALUE,
KMT_DH_DEVICE_DETAILS.MAX_OUTPUT_LENGTH AS
KMT_MTM_VALUES.RW_VALUE);
KMT_MESSAGE(-85826,RC_IGNORED);
KMT_MTM_AREA(3 SIZE 4) :=
((L'(WORD: KMT_TRACE_FLAGS.FH_TRACING)) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(WORD: KMT_TRACE_FLAGS.PH_TRACING)) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(WORD: KMT_TRACE_FLAGS.PP_TRACING)) AS
KMT_MTM_VALUES.LW_VALUE,
(L'(WORD: KMT_TRACE_FLAGS.DH_TRACING)) AS
KMT_MTM_VALUES.LW_VALUE);
KMT_MESSAGE(-85827,RC_IGNORED);
RESULT := 0
ELSE
RESULT := 85911 @ not yet implemented in Server mode @
FI
; @ KMT_UI_SHOW @
SIM PROC KMT_UI_STATISTICS IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ STATISTICS command, Syntax: STATISTICS @
@ displays statistics of last file transfer @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
REF KMT_FH_FILE_STATISTICS_S FILE_STATS IS
KMT_STATISTICS.FH_FILE_STATISTICS;
REF KMT_PP_PACKET_STATISTICS_S PACKET_STATS IS
KMT_STATISTICS.PACKET_STATISTICS;
KMT_MTM_AREA(3 SIZE 6) := (PACKET_STATS.INPUT_TOTAL AS
KMT_MTM_VALUES.RI_VALUE,
PACKET_STATS.OUTPUT_TOTAL AS
KMT_MTM_VALUES.RI_VALUE,
RETRY_TOTAL AS
KMT_MTM_VALUES.RI_VALUE,
TIMEOUT_TOTAL AS
KMT_MTM_VALUES.RI_VALUE,
FILE_STATS.INPUT_TOTAL AS
KMT_MTM_VALUES.RI_VALUE,
FILE_STATS.OUTPUT_TOTAL AS
KMT_MTM_VALUES.RI_VALUE);
KMT_MESSAGE(-85820,RC_IGNORED);
RESULT := 0
ELSE
RESULT := 85911 @ not yet implemented in Server mode @
FI
; @ KMT_UI_STATISTICS @
SIM PROC KMT_UI_UNRECOGNISED IS GROUP KMT_UI_EXEC(RESPONSE RESULT):
@ command no recognised @
IF KMT_CURRENT_MODE NE SERVER_MODE
THEN
RESULT := -85910
ELSE
RESULT := 85910
FI
; @ KMT_UI_UNRECOGNISED @
@ command execution procedure selector: @
()SIM PROC GROUP KMT_UI_EXEC(RESPONSE) KMT_UI_CMD IS
(KMT_UI_SERVER,
KMT_UI_RECEIVE,
KMT_UI_SEND,
KMT_UI_HELP,
KMT_UI_EXIT,
KMT_UI_SET,
KMT_UI_SHOW,
KMT_UI_STATISTICS,
KMT_UI_UNRECOGNISED);
KMT_WORD KMT_CMD; @ current command @
INT CMD; @ current command code @
RESULT := 0;
IF KMT_CURRENT_MODE = COMMAND_MODE
THEN
@ prompt for command input @
KMT_SP_ASK_MESSAGE(X"15E5D4C540D285999489A36E40", @ " VME Kermit> " @
KMT_INPUT_BUF,STRLEN,TRUE,RESULT);
KMT_CMD_BUF := KMT_PARSE := KMT_INPUT_BUF(SIZE S'STRLEN);
ELSF LENGTH KMT_PH_INPUT_PACKET_DATA > 0
THEN
@ Server mode, command in packet @
KMT_CMD_BUF := KMT_PARSE := KMT_PH_INPUT_PACKET_DATA
ELSE
RESULT := 89022 @ no command specified in Server mode @
FI;
IF RESULT = 0
THEN
KMT_CMD := KMT_SP_GET_WORD(KMT_PARSE); @ extract command @
UNLESS KMT_CMD REF NIL
DO
@ convert command name to upper case, validate and execute command @
KMT_SP_CONVERT_TO_UPPER_CASE(KMT_CMD);
KMT_MTM_AREA(3) := KMT_CMD AS KMT_MTM_VALUES.RVB_VALUE;
CMD := KMT_SP_MTM(5010,KMT_MTM_AREA(SIZE 4));
KMT_UI_CMD(CMD)(RESULT)
FI
FI
END
; @ KMT_UI @
ENDMODULE @ KMT_UI_MODULE @
$$$$ KMT_HELP_MTM
*@ KERMIT HELP SYSTEM MESSAGE TEXT MODULE @
*@ ====== ==== ====== ======= ==== ====== @
*CREATE(KMTHELPMTM)
*PROC(KMTHELPMTM)
*VERSION(101)
*PARAMS(EXP&ICL)
*LINESPLIT(SPACE)
*@ N.B. NIL IS ASSUMED TO HAVE A VALUE OF -1 @
*1 @ text to validate command for which help required @
<CASE P2 STARTS
<> OR <-1> THEN J20, @ no command specified @
<SERVER> THEN J250,
<RECEIVE> THEN J500,
<SEND> THEN J750,
<HELP> THEN J1000,
<EXIT> THEN J1250,
<SET> THEN J1500,
<SHOW> THEN J1750,
<STATISTICS > THEN J2000,
<START-OF-PACKET> THEN J9000 @ not a command, START-OF-PACKET info @
DEFAULT J10 @ invalid command @
ESAC
>
*10 @ invalid command entry @
<L1><P2> is not a VME Kermit command.
*20 @ no command specified, display menu @
<L1>Help is available for the following VME Kermit commands: <HALT -1>
<L1>(n.b. square brackets enclose optional parameters and should
omitted when entering a command.) <L1><HALT -1>
<S3>(1) SERVER <TAB 35>: select Kermit Server mode <HALT -1>
<S3>(2) RECEIVE [VME-filename] <TAB 35>: prepare to receive file <HALT -1>
<TAB 35>[save as VME-filename] <HALT -1>
<S3>(3) SEND VME-filename [dest-filename] : send file <HALT -1>
<TAB 35>[store as dest-filename] <HALT -1>
<S3>(4) HELP [command] [params] <TAB 35>: obtain help <HALT -1>
<TAB 35>[for command or command and parameters] <HALT -1>
<S3>(5) EXIT <TAB 35>: exit from VME Kermit <HALT -1>
<S3>(6) SET param value <TAB 35>: set Kermit parameter <HALT -1>
<S3>(7) SHOW <TAB 35>: show value of all Kermit parameters <HALT -1>
<S3>(8) STATISTICS <TAB 35>: display details of last transfer <HALT -1,J30>
*30 @ Select command prompt @
<L1>Select command (Enter 1 to 8 or 0 if no further help required): <HALT 40>
*40 @ validate response to Select command @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J250,
<2> THEN J500,
<3> THEN J750,
<4> THEN J1000,
<5> THEN J1250,
<6> THEN J1500,
<7> THEN J1750,
<8> THEN J2000
DEFAULT J50
ESAC
>
*50 @ invalid response to Select command prompt @
<L1>**** Invalid response, please re-select. <HALT -1><J30>
*60 @ more help prompt @
<L1>Any more help required (YES/NO)? <HALT 70>
*70 @ validate more help reply @
<CASE P2 STARTS
<YES> OR <yes> THEN J20,
<NO> OR <no> THEN <>
DEFAULT J60
ESAC
>
*250 @ SERVER command help @
<L1>SERVER command: <HALT -1>
<L1><TAB 15>Syntax: SERVER <HALT -1>
<L1>The SERVER command selects VME Kermit Server mode. All further commands
are sent to VME Kermit by the user Kermit (running on your micro). File
transfers are initiated via commands given to the micro Kermit. VME Kermit
will remain in Server mode until the user Kermit instructs VME Kermit to exit
to VME command level (after you have issued a FINISH command to the micro
Kermit) or the user Kermit tells VME Kermit to log out (after you have issued
a BYE command to the micro Kermit). <HALT -1>
<L1>WARNING: It is inadvisable to select VME Kermit Server mode if your micro
Kermit doesn't have the following commands for communicating with servers:
GET, BYE and FINISH. If in doubt, consult your documentation. <HALT -1>
<CASE P1 <>,J60 ESAC>
*500 @ RECEIVE command help @
RECEIVE command: <HALT -1>
<L1><TAB 15>Syntax: RECEIVE [VME-filename] <HALT -1>
<L1>The RECEIVE command prepares VME Kermit for the arrival of a file from
the micro Kermit. If a VME filename is specified, the file will be saved with
this name. If no filename is specified, a filename will be sent by the micro
Kermit and, if possible, the file will be saved with that name. <HALT -1>
<L1>After issuing the RECEIVE command, escape back to the micro Kermit and
initiate the file transfer by entering a SEND command. <HALT -1>
<CASE P1 <>,J60 ESAC>
*750 @ SEND command help @
<L1>SEND command: <HALT -1>
<L1><TAB 15>Syntax: SEND VME-filename [destination-filename] <HALT -1>
<L1>The VME file is sent to the micro Kermit. If a destination filename
is included, the file will be stored by the micro with this name,
otherwise the VME filename will be used. <HALT -1>
<L1>After issuing the SEND command escape back to the micro Kermit and
prepare the micro for the arrival of the file by issuing a RECEIVE
command. <HALT -1>
<CASE P1 <>,J60 ESAC>
*1000 @ HELP command help @
<L1>HELP command: <HALT -1>
<L1><TAB 15>Syntax: HELP [command] [parameter(s)]
<L1>The HELP command gives information for the specified command, or allows
the user to request information via a menu. If a command is specified,
it may be qualified by appending parameter names. <HALT -1>
<CASE P1 <>,J60 ESAC>
*1250 @ EXIT command help @
<L1>EXIT command: <HALT -1>
<L1><TAB 15>Syntax: EXIT <HALT -1>
<L1>The EXIT command terminates the VME Kermit session, closes any logging
files and returns the user to VME command level. <HALT -1>
<CASE P1 <>,J60 ESAC>
*1500 @ SET command help @
<CASE P3 STARTS
<> OR <-1> THEN J1505, @ no parameter specified @
<DEBUG> THEN J1520,
<DELAY> THEN J1540,
<PAUSE> THEN J1560,
<RETRY> THEN J1580,
<FILE> THEN J1600,
<SEND> THEN J1620,
<RECEIVE> THEN J1640
DEFAULT J1504 @ invalid parameter @
ESAC
>
*1501 @ SET command help exit @
<CASE P1 <>,J1502 ESAC>
*1502 @ more help prompt @
<L1>Any more help required? Select:- <HALT -1>
<S3>(0) No more help <HALT -1>
<S3>(1) More help for this command <HALT -1>
<S3>(2) More help for another command <HALT -1>
<L1>Enter choice (0 to 2): <HALT 1503>
*1503 @ validate more help response @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1505,
<2> THEN J20
DEFAULT J1502 @ invalid response, reprompt @
ESAC
>
*1504 @ invalid SET parameter @
<L1>**** <P3> is not a SET parameter. <HALT -1><J1501>
*1505 @ SET command menu @
<L1>SET command: <HALT -1>
<L1><TAB 15>Syntax: SET parameter value <HALT -1>
<L1>The SET command establishes or modifies various parameters for file
transfer or logging. <HALT -1>
<L1>The following parameters may be set: <L1><HALT -1>
<S3>(1) DEBUG {FILE/PROTOCOL/PACKET/DEVICE/ALL} {ON/OFF} <HALT -1>
<S3>(2) DELAY seconds <HALT -1>
<S3>(3) PAUSE 10th-seconds <HALT -1>
<S3>(4) RETRY maximum-retries <HALT -1>
<S3>(5) FILE parameter value <HALT -1>
<S3> TYPE {EBCDIC/ASCII/BINARY} <HALT -1>
<S3> NAMING {UNTRANSLATED/NORMAL-FORM} <HALT -1>
<S3> OVERWRITE {ON/OFF} <HALT -1>
<S3> INCOMPLETE {DISCARD/KEEP} <HALT-1>
<S3>(6) SEND parameter value <HALT -1>
<S3>(7) RECEIVE parameter value <HALT -1>
<S3> START-OF-PACKET ctl-char <HALT -1>
<S3> PACKET-LENGTH number <HALT -1>
<S3> TIMEOUT number <HALT -1>
<S3> END-OF-LINE ctl-char <HALT -1>
<S3> PADDING number <HALT -1>
<S3> PAD-CHARACTER ctl-char <HALT -1>
<S3> QUOTE char <HALT -1>
<S3> EIGHTH-BIT-PREFIX char <HALT -1>
<J1506>
*1506 @ select SET parameter @
<L1>For further information enter choice (1 to 7) or 0 if no further
information is required: <HALT 1507>
*1507 @ validate selection @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1520,
<2> THEN J1540,
<3> THEN J1560,
<4> THEN J1580,
<5> THEN J1600,
<6> THEN J1620,
<7> THEN J1640
DEFAULT J1508 @ invalid selection @
ESAC
>
*1508 @ invalid selection @
<L1>**** Invalid response, please re-select.<HALT -1><J1506>
*1520 @ SET DEBUG @
<CASE P4 STARTS
<> OR <-1> THEN J1525, @ no parameter specified @
<FILE> THEN J1530,
<PROTOCOL> THEN J1531,
<PACKET> THEN J1532,
<DEVICE> THEN J1533,
<ALL> THEN J1534
DEFAULT J1524 @ invalid parameter @
ESAC
>
*1521 @ SET DEBUG command help exit @
<CASE P1 <>, J1522 ESAC>
*1522 @ more help prompt @
<L1>Any more help required? Select:- <HALT -1>
<S3>(0) No more help <HALT -1>
<S3>(1) More help for this command <HALT -1>
<S3>(2) More help for another command <HALT -1>
<L1>Enter choice (0 to 2): <HALT 1523>
*1523 @ validate more help response @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1525,
<2> THEN J20
DEFAULT J1522 @ invalid response, reprompt @
ESAC
>
*1524 @ invalid SET DEBUG parameter @
<L1>**** <P4> is not a SET DEBUG parameter.<HALT -1><J1521>
*1525 @ SET DEBUG command menu @
<L1>SET DEBUG: <HALT-1>
<L1><TAB 15>Syntax: SET DEBUG parameter option <HALT -1>
<L1>Sets the various debugging facilities on or off.<HALT -1>
<L1>The following parameters may be set:<L1><HALT -1>
<S3>(1) FILE {ON/OFF} <HALT -1>
<S3>(2) PROTOCOL {ON/OFF} <HALT -1>
<S3>(3) PACKET {ON/OFF} <HALT -1>
<S3>(4) DEVICE {ON/OFF} <HALT -1>
<S3>(5) ALL {ON/OFF} <HALT -1>
<J1526>
*1526 @ select SET DEBUG parameter @
<L1>For further information enter choice (1 to 5) or 0 if no further
information is required: <HALT 1527>
*1527 @ validate selection @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1530,
<2> THEN J1531,
<3> THEN J1532,
<4> THEN J1533,
<5> THEN J1534
DEFAULT J1528 @ invalid selection @
ESAC
>
*1528 @ invalid selection @
<L1>**** Invalid response, please re-select.<HALT -1><J1526>
*1530 @ SET DEBUG FILE @
<L1>SET DEBUG FILE: <HALT -1>
<L1><TAB 15>Syntax: SET DEBUG FILE option <HALT -1>
<L1>Turns file record tracing on or off. If option is ON then the contents of
all file records read or written will be logged (in hex) to the job journal.
The default is OFF. <HALT -1>
<L1>e.g. SET DEBUG FILE ON - turns on file record tracing. <HALT -1>
<J1521>
*1531 @ SET DEBUG PROTOCOL @
<L1>SET DEBUG PROTOCOL: <HALT -1>
<L1><TAB 15>Syntax: SET DEBUG PROTOCOL option <HALT -1>
<L1>Turns protocol state/event tracing on or off. If option is ON then the
internal states and events of the protocol handler will be logged to the job
journal. The default is OFF. <HALT -1>
<L1>e.g. SET DEBUG PROTOCOL ON - turns on protocol state/event tracing.<HALT -1>
<J1521>
*1532 @ SET DEBUG PACKET @
<L1>SET DEBUG PACKET: <HALT -1>
<L1><TAB 15>Syntax: SET DEBUG PACKET option <HALT -1>
<L1>Turns packet tracing on or off. If option is ON then the contents of all
packets sent and received will be logged to the job journal. The
default is OFF. <HALT -1>
<L1>e.g. SET DEBUG PACKET ON - turns on packet tracing. <HALT -1>
<J1521>
*1533 @ SET DEBUG DEVICE @
<L1>SET DEBUG DEVICE: <HALT -1>
<L1><TAB 15>Syntax: SET DEBUG DEVICE option <HALT -1>
<L1>Turns device tracing on or off. If option is ON then all the data sent and
received over the terminal link will be logged (in hex) to the job journal. The
default is OFF. <HALT -1>
<L1>e.g. SET DEBUG DEVICE ON - turns on device tracing. <HALT -1>
<J1521>
*1534 @ SET DEBUG ALL @
<L1>SET DEBUG ALL: <HALT -1>
<L1><TAB 15>Syntax: SET DEBUG ALL option <HALT -1>
<L1>Turns all tracing on or off. If option is ON then the contents of all file
records read or written, the internal states and events of the protocol handler,
the contents of all packets sent and received and all the data sent and
received over the terminal link will be logged to the job journal. The default
is OFF. <HALT -1>
<L1>e.g. SET DEBUG ALL ON - turns on all tracing. <HALT -1>
<J1521>
*1540 @ SET DELAY @
<L1>SET DELAY: <HALT -1>
<L1><TAB 15>Syntax: SET DELAY seconds <HALT -1>
<L1>Sets the length of delay before transmitting the first packet after
a SEND command has been issued. The default delay is 30 seconds. The
minimum delay that can be set is 5 seconds and the maximum is 300
seconds. Seconds may be expressed as a decimal value (e.g. 9) or as a
hexadecimal value (e.g. X09). <HALT -1>
<L1>e.g. SET DELAY 15 - sets the delay period to 15 seconds. <HALT -1>
<J1501>
*1560 @ SET PAUSE @
<L1>SET PAUSE: <HALT -1>
<L1><TAB 15>Syntax: SET PAUSE 10ths-second <HALT -1>
<L1>Sets the length of time to pause between receiving a packet from the remote
system and transmitting the next packet to it. The default pause is 0 tenths
of a second. The maximum pause that can be set is 50 tenths of a second.
10ths-second may be expressed as a decimal value (e.g. 9) or as a hexadecimal
value (e.g. X09). <HALT -1>
<L1>e.g. SET PAUSE 10 - sets the pause period to 10 tenths of a second.<HALT -1>
<J1501>
*1580 @ SET RETRY @
<L1>SET RETRY: <HALT -1>
<L1><TAB 15>Syntax: SET RETRY number <HALT -1>
<L1>Sets the maximum number of times to attempt to send or receive a packet
before abandoning the transfer. The default retry is 4. The maximum retry that
can be set is 10. Number may be expressed as a decimal value (e.g. 4) or as a
hexadecimal value (e.g. X04). <HALT -1>
<L1>e.g. SET RETRY 8 - sets the retry limit to 8 retries. <HALT -1>
<J1501>
*1600 @ SET FILE @
<CASE P4 STARTS
<> OR <-1> THEN J1605, @ no parameter specified @
<TYPE> THEN J1610,
<NAMING> THEN J1611,
<OVERWRITE> THEN J1612,
<INCOMPLETE> THEN J1613
DEFAULT J1604 @ invalid parameter @
ESAC
>
*1601 @ SET FILE command help exit @
<CASE P1 <>, J1602 ESAC>
*1602 @ more help prompt @
<L1>Any more help required? Select:- <HALT -1>
<S3>(0) No more help <HALT -1>
<S3>(1) More help for this command <HALT -1>
<S3>(2) More help for another command <HALT -1>
<L1>Enter choice (0 to 2): <HALT 1603>
*1603 @ validate more help response @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1605,
<2> THEN J20
DEFAULT J1602 @ invalid response, reprompt @
ESAC
>
*1604 @ invalid SET FILE parameter @
<L1>**** <P4> is not a SET FILE parameter.<HALT -1><J1601>
*1605 @ SET FILE command menu @
<L1>SET FILE: <HALT-1>
<L1><TAB 15>Syntax: SET FILE parameter option <HALT -1>
<L1>Sets the various file attributes.<HALT -1>
<L1>The following parameters may be set:<L1><HALT -1>
<S3>(1) TYPE {EBCDIC/ASCII/BINARY} <HALT -1>
<S3>(2) NAMING {UNTRANSLATED/NORMAL-FORM} <HALT -1>
<S3>(3) OVERWRITE {ON/OFF} <HALT -1>
<S3>(4) INCOMPLETE {DISCARD/KEEP} <HALT -1>
<J1606>
*1606 @ select SET FILE parameter @
<L1>For further information enter choice (1 to 4) or 0 if no further
information is required: <HALT 1607>
*1607 @ validate selection @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1610,
<2> THEN J1611,
<3> THEN J1612,
<4> THEN J1613
DEFAULT J1608 @ invalid selection @
ESAC
>
*1608 @ invalid selection @
<L1>**** Invalid response, please re-select.<HALT -1><J1606>
*1610 @ SET FILE TYPE @
<L1>SET FILE TYPE: <HALT -1>
<L1><TAB 15>Syntax: SET FILE TYPE option <HALT -1>
<L1>Defines the type of file to be sent, or received.
option may be one of: <HALT -1>
<S3>EBCDIC meaning that the VME file contains, or is to contain EBCDIC <HALT -1>
<S3> text and data conversion between EBCDIC and ASCII is <HALT -1>
<S3> required. <HALT -1>
<S3>ASCII meaning that the VME file contains, or is to contain ASCII <HALT -1>
<S3> text and no data conversion is required. <HALT -1>
<S3>BINARY meaning that the VME file contains, of is to contain binary <HALT -1>
<S3> data and no data conversion is required. Note in this case <HALT -1>
<S3> the record boundaries of the VME file are not significant <HALT -1>
<S3> to KERMIT. <HALT -1>
The default is EBCDIC. <HALT -1>
<L1>e.g. SET FILE TYPE BINARY - sets file transfer is to be binary.<HALT -1>
<J1601>
*1611 @ SET FILE NAMING @
<L1>SET FILE NAMING: <HALT -1>
<L1><TAB 15>Syntax: SET FILE NAMING option <HALT -1>
<L1>Defines how file names are to represented/interpretted. If option is
NORMAL-FORM then the VME and remote file names will be normalised. If option is
UNTRANSLATED then no file name normalisation will take place. The default is
NORMAL-FORM. <HALT -1>
<L1>e.g. SET FILE NAMING UNTRANSLATED - turns off file name normalisation.
<HALT -1>
<J1601>
*1612 @ SET FILE OVERWRITE @
<L1>SET FILE OVERWRITE: <HALT -1>
<L1><TAB 15>Syntax: SET FILE OVERWRITE option <HALT -1>
<L1>Defines the action to be taken when receiving a file and a VME file of the
same name and generation number already exists. If option is ON then the file
will be overwritten. If option is OFF then the file transfer will abandoned.
The default is OFF. <HALT -1>
<L1>e.g. SET FILE OVERWRITE ON - incoming file will be overwritten if it already
exists. <HALT -1>
<J1601>
*1613 @ SET FILE INCOMPLETE @
<L1>SET FILE INCOMPLETE: <HALT -1>
<L1><TAB 15>Syntax: SET FILE INCOMPLETE option <HALT -1>
<L1>Defines the action to be taken when receiving a file and the file transfer
is abandoned. If option is KEEP then the VME file will be saved. If option is
DISCARD then the VME file will not be saved. <HALT -1>
<L1>e.g. SET FILE INCOMPLETE KEEP - file to be saved if transfer abandoned.
<HALT -1>
<J1601>
*1620 @ SET SEND @
<J1650>
*1640 @ SET RECEIVE @
<J1650>
*1650 @ SET SEND/RECEIVE @
<CASE P4 STARTS
<> OR <-1> THEN J1655, @ no parameter specified @
<START-OF-PACKET> THEN J1660,
<PACKET-LENGTH> THEN J1661,
<TIMEOUT> THEN J1662,
<END-OF-LINE> THEN J1663,
<PADDING> THEN J1664,
<PAD-CHARACTER> THEN J1665,
<QUOTE> THEN J1666,
<EIGHTH-BIT-PREFIX> THEN J1667
DEFAULT J1654 @ invalid parameter @
ESAC
>
*1651 @ SET SEND/RECEIVE command help exit @
<CASE P1 <>, J1652 ESAC>
*1652 @ more help prompt @
<L1>Any more help required? Select:- <HALT -1>
<S3>(0) No more help <HALT -1>
<S3>(1) More help for this command <HALT -1>
<S3>(2) More help for another command <HALT -1>
<L1>Enter choice (0 to 2): <HALT 1653>
*1653 @ validate more help response @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1655,
<2> THEN J20
DEFAULT J1652 @ invalid response, reprompt @
ESAC
>
*1654 @ invalid SET SEND/RECEIVE parameter @
<L1>**** <P4> is not a SET SEND/RECEIVE parameter.<HALT -1><J1651>
*1655 @ SET SEND/RECEIVE command menu @
<L1>SET SEND/RECEIVE: <HALT-1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} parameter option <HALT -1>
<L1>Sets the various configuration parameters to allow the tailoring of
dissimilar systems to accomodate the peculiarities of the communication path.
Note a number of the configuration parameters may be modified during the
exchange of S or I packets and the acknowledgements to those packets. <HALT -1>
<L1>The following parameters may be set:<L1><HALT -1>
<S3>(1) START-OF-PACKET ctl_char <HALT -1>
<S3>(2) PACKET-LENGTH number <HALT -1>
<S3>(3) TIMEOUT seconds <HALT -1>
<S3>(4) END-OF-LINE ctl-char <HALT -1>
<S3>(5) PADDING number <HALT -1>
<S3>(6) PAD-CHARACTER ctl-char <HALT -1>
<S3>(7) QUOTE char <HALT -1>
<S3>(8) EIGHTH-BIT-PREFIX char <HALT -1>
<J1656>
*1656 @ select SET SEND/RECEIVE parameter @
<L1>For further information enter choice (1 to 8) or 0 if no further
information is required: <HALT 1657>
*1657 @ validate selection @
<CASE P2 EQUALS
<0> THEN <>,
<1> THEN J1660,
<2> THEN J1661,
<3> THEN J1662,
<4> THEN J1663,
<5> THEN J1664,
<6> THEN J1665,
<7> THEN J1666,
<8> THEN J1667
DEFAULT J1658 @ invalid selection @
ESAC
>
*1658 @ invalid selection @
<L1>**** Invalid response, please re-select.<HALT -1><J1656>
*1660 @ SET SEND/RECEIVE START-OF-PACKET @
<L1>SET SEND/RECEIVE START-OF-PACKET: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} START-OF-PACKET ctl-char <HALT -1>
<L1>Sets the ASCII control character to be used as the start-of-packet marker.
The default is Record Separator (decimal 30, hex 1E). 'Ctl-char' may be
expressed as a decimal value (e.g. 30) or as a hexadecimal value (e.g. X1E).
Note a number of control characters are not accepted by VME as valid
start-of-packet markers. <HALT -1>
<L1>e.g. SET SEND START-OF-PACKET X1F - sets the start-of-packet marker for
output packets to Unit Separator. <HALT -1>
<J1651>
*1661 @ SET SEND/RECEIVE PACKET-LENGTH @
<L1>SET SEND/RECEIVE PACKET-LENGTH: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} PACKET-LENGTH number <HALT -1>
<L1>Sets the maximum length for a packet. The maximum packet-length plus the
padding (if any) must not exceed the limits of the VME terminal description
(normally 80 for output and 128 for input). The default packet-length is 80
characters. The minimum packet-length that can be set is 30 characters and the
maximum is defined by the terminal description (normally 80 for output and 94
for input). 'Number' may be expressed as a decimal value (e.g. 80) or as a
hexadecimal value (e.g. X50). <HALT -1>
<L1>e.g. SET RECEIVE PACKET-LENGTH 72 - sets the maximum packet-length of input
packets to 72 characters. <HALT -1>
<J1651>
*1662 @ SET SEND/RECEIVE TIMEOUT @
<L1>SET SEND/RECEIVE TIMEOUT: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} TIMEOUT seconds <HALT -1>
<L1>Sets the length of time to wait for a packet to arrive. The default is 0
seconds i.e. indefinite wait. The maximum timeout that can be set is 94 seconds.
'Seconds' may be expressed as a decimal value (e.g. 20) or as a hexadecimal
value (e.g. X14). <HALT -1>
<L1>e.g. SET RECEIVE TIMEOUT 20 - sets the timeout value for input packets to 20
seconds. <HALT -1>
<J1651>
*1663 @ SET SEND/RECEIVE END-OF-LINE @
<L1>SET SEND/RECEIVE END-OF-LINE: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} END-OF-LINE ctl-char <HALT -1>
<L1>Sets the ASCII control character to be used as the end of packet terminator.
The default is Carriage Return (decimal 13, hex 0D). 'Ctl-char' may be expressed
as a decimal value (e.g. 13) or as a hexadecimal value (e.g. X0D). Note a number
of control characters are not accepted by VME as valid end-of-line terminators.
<HALT -1>
<L1>e.g. SET RECEIVE END-OF-LINE X09 - sets the input packet end-of-line
terminator to Tab. <HALT -1>
<J1651>
*1664 @ SET SEND/RECEIVE PADDING @
<L1>SET SEND/RECEIVE PADDING: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} PADDING number <HALT -1>
<L1>Sets the number of padding characters to be sent before each packet. The
padding plus the maximum packet length must not exceed the limits of the VME
terminal description (normally 80 for output and 128 for input). The default
padding is 0 characters i.e. no padding. The maximum padding that can be set is
defined by the VME terminal description. <HALT -1>
<L1>e.g. SET SEND PADDING 4 - sets the padding for output packets to 4 pad
characters. <HALT -1>
<J1651>
*1665 @ SET SEND/RECEIVE PAD-CHARACTER @
<L1>SET SEND/RECEIVE PAD-CHARACTER: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} PAD-CHARACTER ctl-char <HALT -1>
<L1>Sets the ASCII control character to be used as a pad character to be sent
before each packet. The default is Null (decimal 0, hex 00). 'Ctl-char' may be
expressed as a decimal value (e.g. 0) or as a hexadecimal value (e.g X00).
Note a number of the control characters are not accepted by VME as valid pad
characters. <HALT -1>
<L1>e.g. SET SEND PAD-CHARACTER 7 - sets the output packet pad character to
Bell. <HALT -1>
<J1651>
*1666 @ SET SEND/RECEIVE QUOTE @
<L1>SET SEND/RECEIVE QUOTE: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} QUOTE char <HALT -1>
<L1>Sets the printable ASCII character to be used for control character
prefixing. It may be any printable character but it must be different from the
eighth-bit-prefix character. The default value is Hash (#) (decimal 35, hex 23).
'Char' may be expressed as an ASCII character (e.g. #), as a decimal value
(e.g. 35) or as a hexadecimal value (e.g. X23). <HALT -1>
<L1>e.g. SET SEND QUOTE ? - sets the output packet quote character to question
mark. <HALT -1>
<J1651>
*1667 @ SET SEND/RECEIVE EIGHTH-BIT-PREFIX @
<L1>SET SEND/RECEIVE EIGHTH-BIT-PREFIX: <HALT -1>
<L1><TAB 15>Syntax: SET {SEND/RECEIVE} EIGHTH-BIT-PREFIX char <HALT -1>
<L1>Sets the printable ASCII character to be used for eighth bit prefixing.
It may be any printable character in the range ASCII 32 to 62 or ASCII 96 TO 126
but it must be different from the control character prefix.
The default value is Ampersand (&) (decimal 38, hex 26).
'Char' may be expressed as an ASCII character (e.g. &), as a decimal value
(e.g. 38) or as a hexadecimal value (e.g. X26). <HALT -1>
<L1>e.g. SET SEND EIGHTH-BIT-PREFIX ! - sets the output packet eighth-bit-prefix
character to exclamation mark. <HALT -1>
<J1651>
*1750 @ SHOW command help @
<L1>SHOW command: <HALT -1>
<L1><TAB 15>Syntax: SHOW <HALT -1>
<L1>Displays the current values of SET parameters, capabilities etc. <HALT -1>
<CASE P1 <>,J60 ESAC>
*2000 @ STATISTICS command help @
<L1>STATISTICS command: <HALT -1>
<L1><TAB 15>Syntax: STATISTICS <HALT -1>
<L1>Displays statistical information about the most recent file transfer.
<HALT -1>
<CASE P1 <>,J60 ESAC>
*9000 @ START-OF-PACKET info @
<L>VME I/0 cannot handle the standard Kermit START-OF-PACKET character Hex 01
(decimal 1) so initially the VME Kermit START-OF-PACKET character is set to
Hex 1E (decimal 30). For a Kermit file transfer to work, the START-OF-PACKET
character on the micro Kermit must be set to correspond to the VME Kermit
START-OF-PACKET character. Consult the documentation for the micro Kermit to
find out how to change the START-OF-PACKET character on the micro.<HALT -1>
<L>If the VME Kermit START-OF-PACKET character isn't suitable for the micro
Kermit then the START-OF-PACKET character should be altered on BOTH Kermits.
Appendix 2 of the VME KERMIT User Guide lists the characters that VME I/O
can handle. To change the START-OF-PACKET character on VME Kermit use the
commands SET RECEIVE START-OF-PACKET and SET SEND START-OF-PACKET. HELP is
available for these commands. If you attempt to alter the START-OF-PACKET
character to an unacceptable character you will be notified.
*END
$$$$ KMT_SP_MTM
*@ VME KERMIT SUPPORT PROCEDURE MESSAGE TEXT MODULE @
*@ ************************************************ @
*CREATE(KMTSPMTM)
*PROC(KMTSPMTM)
*VERSION(101)
*PARAMS(EXP&ICL)
*LINESPLIT(SPACE)
*@ MESSAGES MESSAGE TEXTS @
*@ ********************** @
*@ GENERAL MESSAGES @
*@ **************** @
*1 @ KMT_VERSION_NUMBER @
<L><TAB 25>SWURCC VME KERMIT VERSION <P2>
*2 @ KMT_SWURCC_BANNER @
<L>South West Universities Regional Computer Centre,
<HALT -1>Claverton Down, Bath BA2 7AY, U.K.
*3 @ NON-STANDARD MARK CHARACTER @
<L>The VME Kermit START-OF-PACKET character is Hex 1E (decimal 30).
<HALT -1>Please set the START-OF-PACKET character on your micro to correspond.
<HALT -1>Type: HELP START-OF-PACKET for further details.
*@ SUPPORT PROCEDURES MESSAGES @
*@ *************************** @
*50 @ KMT_SP_TRACE_MSG @
<CASE P1
THEN <>
DEFAULT <<HEX P2>>
ESAC>
*@ ERROR HANDLER MESSAGES @
*@ ********************** @
*@ DEVICE HANDLER MESSAGES @
*@ *********************** @
*150 @ KMT_DH_DATA_IN_MSG @
<L>KMT_DH_DATA_IN :- <HALT -1, J50>
*151 @ KMT_DH_DATA_OUT_MSG @
<L>KMT_DH_DATA_OUT :- <HALT -1, J50>
*152 @ KMT_DH_EVENT_MSG @
<L>KMT_DH_EVENT :- <HALT -1, J50>
*@ FILE HANDLER MESSAGES @
*@ ********************* @
*200 @ KMT_FH_RECORD_IN_MSG @
<L>KMT_FH_RECORD_IN :- <HALT -1,J50>
*201 @ KMT_FH_RECORD_OUT_MSG @
<L>KMT_FH_RECORD_OUT :- <HALT -1,J50>
*@ PACKET PROCESSOR MESSAGES @
*@ *************************
*250 @ KMT_PP_TRACE_MESSAGE @
<HEX P2, HALT -1>
<HALT -1>MARK = X"<HEX P3>"
<HALT -1>LEN = <P4>
<HALT -1>SEQ = <P5>
<HALT -1>TYPE = <CASE P6
THEN <INVALID TYPE>,
<B (BREAK)>,
<D (DATA)>,
<E (ERROR)>,
<F (FILE_HEADER)>,
<G (GENERIC_COMMAND)>,
<I (INIT_PARAM)>,
<K (KERMIT_COMMAND)>,
<N (NAK)>,
<R (REC_INIT)>,
<S (SEND_INIT)>,
<Y (ACK)>,
<Z (EOF)>
DEFAULT <INVALID TYPE>
ESAC>
<HALT -1>DATA = X"<HEX P7>"
<HALT -1>CHECKSUM = X"<HEX P8>"
*251 @ KMT_PP_PACKET_IN_MSG @
<L>KMT_PP_PACKET_IN :- <HALT -1,J250>
*252 @ KMT_PP_PACKET_OUT_MSG @
<L>KMT_PP_PACKET_OUT :- <HALT -1,J250>
*253 @ KMT_PP_PACKET_DATA_IN_MSG @
<L>KMT_PP_PACKET_DATA_IN <CASE P2
THEN J255,
J256,
J257
DEFAULT J255
ESAC>
*254 @ KMT_PP_PACKET_DATA_OUT_MSG @
<L>KMT_PP_PACKET_DATA_OUT <CASE P2
THEN J255,
J256,
J257
DEFAULT J255
ESAC>
*255 @ EBCDIC DATA @
(EBCDIC) :-
<HALT -1><P3>
*256 @ ASCII DATA @
(ASCII) :-
<HALT -1><P3>
*257 @ BINARY DATA @
(BINARY) :-
<HALT -1>X"<HEX P3>"
*258 @ KMT_PP_PARAM_OUT_MSG @
<L>KMT_PP_PARAM_OUT :- <HALT -1,CASE P1 J260,J261 ESAC>
*259 @ KMT_PP_PARAM_IN_MSG @
<L>KMT_PP_PARAM_IN :- <HALT -1,CASE P1 J260,J261 ESAC>
*260 @ NO PARAMATERS! @
<L>NONE!
*261 @ KMT_PP_PARAMS @
<HALT -1>MAXL = <P2><CASE P1 ,,J262 ESAC>
*262
<HALT -1>TIME = <P3><CASE P1 ,,,J263 ESAC>
*263
<HALT -1>NPAD = <P4><CASE P1 ,,,,J264 ESAC>
*264
<HALT -1>PADC = X"<HEX P5>"<CASE P1 ,,,,,J265 ESAC>
*265
<HALT -1>EOL = X"<HEX P6>"<CASE P1 ,,,,,,J266 ESAC>
*266
<HALT -1>QCTL = X"<HEX P7>"<CASE P1 ,,,,,,,J267 ESAC>
*267
<HALT -1>QBIN = X"<HEX P8>"<CASE P1 ,,,,,,,,J268 ESAC>
*268
<HALT -1>CHKT = "<P9>"<CASE P1 ,,,,,,,,,J269 ESAC>
*269
<HALT -1>REPT = X"<HEX P10>"<CASE P1 ,,,,,,,,,,J270 ESAC>
*270
<HALT -1>CAPAS = X"<HEX P11>"
*@ PROTOCOL HANDLER MESSAGES @
*@ *************************
*300 @ KMT_PH_STATES_MSG @
<L>KMT_PH_STATES :- <HALT -1,J301>
*301 @ KMT_PH_TRACE_MESSAGE @
STATE = <P2> (<CASE P2
THEN <REC_SERVER_IDLE>,
<REC_INIT>,
<REC_FILE>,
<REC_DATA>,
<SEND_INIT>,
<SEND_FILE>,
<SEND_DATA>,
<SEND_EOF>,
<SEND_BREAK>
DEFAULT <UNKNOWN STATE>
ESAC>),
EVENT = <P3> (<CASE P3
THEN <ENTRY>,
<BREAK>,
<DATA>,
<ERROR>,
<FILE_HEADER>,
<GENERIC_COMMAND>,
<INIT_PARAM>,
<KERMIT_COMMAND>,
<NAK>,
<REC_INIT>,
<SEND_INIT>,
<ACK>,
<EOF>,
<CORRUPT_DATA>,
<PROTOCOL_ERROR>
DEFAULT <UNKNOWN EVENT>
ESAC>)
*@ COMMAND AND PARAMETER CHECKING @
*5000 @ check Kermit initial mode @
<CASE P1 STARTS
<SERVER> THEN HALT 0,
<RECEIVE> THEN HALT 1,
<SEND> THEN HALT 2,
<COMMAND> THEN HALT 3
DEFAULT HALT 4 @ invalid mode @
ESAC
>
*5010 @ check Kermit command @
<CASE P1 STARTS
<SERVER> THEN HALT 0,
<RECEIVE> THEN HALT 1,
<SEND> THEN HALT 2,
<HELP> THEN HALT 3,
<EXIT> THEN HALT 4,
<SET> THEN HALT 5,
<SHOW> THEN HALT 6,
<STATISTICS> THEN HALT 7
DEFAULT HALT 8 @ invalid command @
ESAC
>
*5100 @ SET command: check for SEND or RECEIVE option @
<CASE P2 STARTS
<RECEIVE> THEN HALT 0,
<SEND> THEN HALT 1
DEFAULT HALT -1 @ not present - ok though @
ESAC
>
*5110 @ check SET parameter @
<CASE P2 STARTS
<DEBUG> THEN HALT 0,
<DELAY> THEN HALT 1,
<FILE> THEN HALT 2,
<RETRY> THEN HALT 3,
<PAUSE> THEN HALT 4
DEFAULT HALT 920 @ invalid parameter @
ESAC
>
*5120 @ check parameter following SEND or RECEIVE option @
<CASE P3 STARTS
<START-OF-PACKET> THEN HALT 0,
<PACKET-LENGTH> THEN HALT 1,
<TIMEOUT> THEN HALT 2,
<END-OF-LINE> THEN HALT 3,
<PADDING> THEN HALT 4,
<PAD-CHARACTER> THEN HALT 5,
<QUOTE> THEN HALT 6,
<EIGHTH-BIT-PREFIX> THEN HALT 7
DEFAULT HALT 921 @ invalid parameter @
ESAC
>
*5130 @ check DEBUG option @
<CASE P3 STARTS
<ALL> THEN HALT 0,
<FILE> THEN HALT 1,
<PROTOCOL> THEN HALT 2,
<PACKET> THEN HALT 3,
<DEVICE> THEN HALT 4
DEFAULT HALT 921 @ invalid DEBUG parameter @
ESAC
>
*5140 @ check FILE option @
<CASE P3 STARTS
<TYPE> THEN CASE P4 STARTS
<EBCDIC> THEN HALT 0,
<ASCII> THEN HALT 1,
<BINARY> THEN HALT 2
DEFAULT HALT 931
ESAC,
<NAMING> THEN CASE P4 STARTS
<UNTRANSLATED> THEN HALT 3,
<NORMAL-FORM> THEN HALT 4
DEFAULT HALT 931
ESAC,
<OVERWRITE> THEN CASE P4 STARTS
<OFF> THEN HALT 5,
<ON> THEN HALT 6
DEFAULT HALT 931
ESAC,
<INCOMPLETE> THEN CASE P4 STARTS
<DISCARD> THEN HALT 7,
<KEEP> THEN HALT 8
DEFAULT HALT 931
ESAC
DEFAULT HALT 921 @ invalid SET FILE argument @
ESAC
>
*5150 @ check OFF/ON option @
<CASE P4 STARTS
<OFF> THEN HALT 0,
<ON> THEN HALT 1
DEFAULT HALT 931
ESAC
>
*@ RESULTCODES MESSAGE TEXTS @
*@ ************************* @
*@ GENERAL RESULTCODES @
*@ ******************* @
*@ SUPPORT PROCEDURES RESULTCODES @
*@ ****************************** @
*80050 @ KMT_SP_NOT_HEX @
NON-HEXADECIMAL CHARACTERS FOUND IN STRING
*80051 @ KMT_SP_STRING_TOO_BIG @
KMT_SP_STRING_TOO_BIG
*@ ERROR HANDLER RESULTCODES @
*@ ************************* @
*80100 @ KMT_EH_ERROR_MSG @
<P2>
*80101 @ KMT_EH_SOFTWARE_ERROR @
AN UNRECOVERABLE SOFTWARE ERROR HAS OCCURED
*80102 @ KMT_EH_ICL_RESULT @
<>**** RC = <P2> RETURNED FROM PROCEDURE <CASE P1
THEN <*UNKNOWN*>,
<<P3>>
DEFAULT <<P3, HALT -1, P4>>
ESAC>
*@ DEVICE HANDLER RESULTCODES @
*@ ************************** @
*80150 @ KMT_DH_UNEXPECTED_BREAK_IN @
<>**** UNEXPECTED BREAK_IN EVENT ****
*80151 @ KMT_DH_UNEXPECTED_EVENT @
<>**** UNEXPECTED EVENT ****
*80152 @ KMT_DH_DATA_AVAILABLE @
KMT_DH_DATA_AVAILABLE
*80153 @ KMT_DH_QUEUE_EMPTY @
KMT_DH_QUEUE_EMPTY
*@ FILE HANDLER RESULTCODES @
*@ ************************ @
*80200 @ KMT_FH_RECORD_TOO_BIG @
<>**** MAXIMUM RECORD SIZE EXCEEDED, SIZE = <P2>, MAX SIZE = <P3>
*@ PACKET PROCESSOR RESULTCODES @
*@ **************************** @
*80250 @ KMT_PP_NO_INPUT_PACKET @
KMT_PP_NO_INPUT_PACKET
*80251 @ KMT_PP_UNSUPPORTED_PACKET_TYPE @
KMT_PP_UNSUPPORTED_PACKET_TYPE
*80252 @ KMT_PP_INVALID_PACKET_TYPE @
KMT_PP_INVALID_PACKET_TYPE
*80253 @ KMT_PP_INVALID_CHACKSUM @
KMT_PP_INVALID_CHECKSUM
*80254 @ KMT_PP_INVALID_PACKET_LENGTH @
KMT_PP_INVALID_PACKET_LENGTH
*80255 @ KMT_PP_RECORD_TOO_BIG @
<>**** MAXIMUM RECORD SIZE EXCEEDED, MAX SIZE = <P2>
*80256 @ KMT_PP_STRING_TOO_BIG @
<>**** MAXIMUM MESSAGE SIZE EXCEEDED, SIZE = <P2>, MAX SIZE = <P3>
*80257 @ KMT_PP_INVALID_CONFIG_PARAM @
INVALID CONFIGURATION PARAMETER
<CASE P2 <"MARK">,<"NPAD">,<"PADC">,<"EOL">,<"QCTL">,<"QBIN">,<> ESAC>,
VALUE = X"<HEX P3>"
<CASE P1 EQUALS <3>
THEN JP4
DEFAULT <>
ESAC>
*80258 @ KMT_PP_QBIN_AND_QCTL_EQUAL @
THE CONTROL-QUOTE AND EIGHTH-BIT-PREFIX CHARACTERS ARE EQUAL <HALT -1>
QBIN = X"<HEX P2>", REMOTE QCTL = X"<HEX P3>", LOCAL QCTL = X"<HEX P4>"
*80259 @ KMT_PP_QCTL_WARNING @
<>**** WARNING THE REMOTE QCTL CHARACTER X"<HEX P2>" WILL RESULT IN THE
CORRUPTION OF ANY X"<HEX P3>" CHARACTERS TO X"<HEX P2>"
*80260 @ KMT_PP_QBIN_REJECTED @
THE EIGHTH-BIT PREFIXING HAS BEEN REJECTED BY THE REMOTE SYSTEM
*80270 @ INVALID CONFIG PARAM REASONS@
(less than minimum packet length)
*80271
(too many PAD characters requested)
*80272
(not a control character)
*80273
(not a printable character)
*80274
(character not acceptable for VME I/O)
*80275
(not a valid character)
*80276
(same as START-OF-PACKET character)
*80277
(same as END-OF-LINE character)
*@ VME COMMAND ERRORS @
*85000 @ filenames not reqd @
<L>**** File names not required with <P1> option.
*85001 @ rem_file not reqd for Receive @
<L>**** Remote filename not required with Receive option.
*85010 @ vme_file mandatory for Send @
<L>**** Filename must be specified with Send option.
*85020 @ invalid option @
<L>**** <P1> is not a valid VME Kermit option.
*85030 @ terminated with fatal error @
<L>**** VME Kermit terminated due to fatal error.<L>
*85031 @ logging out vm on exit @
<L>Logging out.....!<L>
*85032 @ terminate with a new line @
<S1>
*@ USER INTERFACE (KMT_UI) MESSAGES @
*85820
<L>TRANSFER STATISTICS <HALT -1>
<S5>Packets in <P1,TAB40>Packets out <P2,HALT -1>
<S5>Retries <P3,TAB40>Timeouts <P4,HALT -1>
<S5>Records read <P5,TAB40>Records written <P6,HALT -1>
*85821
<L>GENERAL PARAMETERS <HALT -1>
<S5>Send delay (secs) <P1,TAB40>TX pause (10th sec) <P2,HALT -1>
<S5>Maximum retries <P3,HALT -1>
*85822
RECEIVE PARAMETERS <J85824>
*85823
SEND PARAMETERS <J85824>
*85824
<HALT -1>
<S5>Packet start X<HEX P1,TAB40>End of line X<HEX P6,HALT -1>
<S5>Packet length <P2, TAB40>Timeout (secs) <P3,HALT -1>
<S5>Padding <P4, TAB40>Pad character X<HEX P5,HALT -1>
<S5>Quote character <P7, TAB40>8th bit prefix <P8,HALT -1>
*85825
FILE PARAMETERS <HALT -1>
<S5>File type <CASE P1 <EBCDIC>,<ASCII>,<BINARY>,<UNKNOWN> ESAC>
<TAB40>Overwrite option <CASE P2 EQUALS
<1> THEN <OFF>,
<2> THEN <ON>
DEFAULT <UNKNOWN>
ESAC,HALT -1>
<S5>Incomplete <CASE P3 <DISCARD>,<KEEP> ESAC>
<TAB40>Naming <CASE P4 <UNTRANSLAED>,<NORMAL-FORM> ESAC,HALT -1>
*85826
TERMINAL PARAMETERS <HALT -1>
<S5>Input length <P1,TAB40>Output length <P2,HALT -1>
*85827
DEBUGGING PARAMETERS <HALT -1>
<S5>File <CASE P1 <OFF>,<ON> ESAC>
<TAB40>Protocol <CASE P2 <OFF>,<ON> ESAC,HALT -1>
<S5>Packet <CASE P3 <OFF>,<ON> ESAC>
<TAB40>Device <CASE P4 <OFF>,<ON> ESAC,HALT -1>
*@ USER INTERFACE (KMT_UI) ERROR MESSAGES @
*85910 @ invalid command @
<L>**** <P1> is not a valid VME Kermit command.
*85920 @ invalid parameter P2 @
<L>**** <P2> is not a valid <P1> command parameter.
*85921 @ invalid parameter P3 @
<L>**** <P3> is not a valid <P1> <P2> command parameter.
*85930 @ invalid option P3 @
<L>**** <P3> is not a valid <P1> <P2> command option.
*85931 @ invalid option P4 @
<L>**** <P4> is not a valid <P1> <P2> <P3> option.
*85932 @ command parameter missing @
<L>**** Command parameter missing.
*85933 @ QUOTE and EIGHTH-BIT-PREFIX characters equal @
<L>**** QUOTE and EIGHTH-BIT-PREFIX characters equal.
*85934 @ Padding and packet length combined exceeds device length @
<L>**** Padding plus packet length exceeds the device line length.
*85935 @ START-OF-PACKET/END-OF-LINE/PADC not a control character @
<L>**** <P1> <P2> <P3> parameter must be in range 0 - 31 or 127.
*85936 @ parameter not acceptable for VME I/O @
<L>**** <P2> <P3> parameter not acceptable for VME I/O.
*85937 @ conflict with another character @
<L>**** <P2> <P3> parameter conflicts with <P2>
<CASE P5 <START-OF-PACKET>,<END-OF-LINE>,<PAD>,<> ESAC> character.
*@ PROTOCOL HANDLER MESSAGES @
*87000 @ transfer cancelled by remote Kermit @
<L>File transfer cancelled by remote Kermit.
*87001 @ filename used by remote Kermit for sent file @
<L>File <P1> sent as <P2> to remote Kermit.
*87002 @ filename used by local Kermit for receive file @
<L>File <P1> stored as <P2> on VME Kermit.
*87010 @ error packet received, log details @
<L>Remote Kermit error: <HALT -1>
<P1>
*@ PROTOCOL HANDLER ERRORS @
*89000 @ unexpected pkt_no @
Unexpected packet number.
*89001 @ unexpected pkt_type @
Unexpected packet type.
*89010 @ Generic command failed @
Generic command "<P1>" failed.
*89011 @ Generic command not implemented/recognised @
Generic command "<P1>" not implemented.
*89020 @ Kermit command failed in Server mode @
Kermit command "<P1>" failed in Server mode.
*89021 @ Kermit command not implemented in Server mode @
Kermit command "<P1>" not implemented in Server mode.
*89022 @ No command in Kermit command packet @
No command found in Kermit command packet.
*89030 @ No filename in Rec_Init pkt @
No filename in Receive Init packet.
*89031 @ No filename in File_Hdr pkt @
No filename in File Header packet.
*89040 @ Unable to open Rec file @
Unable to open Receive file.
*89041 @ Unable to open Send file @
Unable to open Send file.
*89042 @ Unable to close Rec file @
Unable to close file received.
*89043 @ Unable to close Send file @
Unable to close Send file.
*89044 @ Unable to save Rec file @
Unable to save file received.
*89046 @ error writing to file @
Unable to write data to file.
*89047 @ error reading from file @
Unable to read data from file.
*89050 @ Retry count exceeded max_try.
Maximum retries exceeded.
*89060 @ Fatal error in Get_Packet @
Fatal I/O error: unable to read packet.
*89061 @ Fatal error in Send_Packet @
Fatal I/O error: unable to send packet.
*89070 @ their parameters unacceptable @
Initial parameters unacceptable.
*END @ KMT_SP_MTUP_MODULE @