home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / iclvme2900 / kmt_main_module < prev    next >
Text File  |  2020-01-01  |  21KB  |  517 lines

  1. MODULE KMT_MAIN_MODULE;                                         @ Version 1.01 @
  2.  
  3. @------------------------------------------------------------------------------@
  4. @                                                                              @
  5. @                                                                              @
  6. @               -----  S W U R C C   V M E   K E R M I T  -----                @
  7. @                                                                              @
  8. @                                                                              @
  9. @       ----------------------------------------------------------------       @
  10. @                                                                              @
  11. @                                                                              @
  12. @       Version 1.00   (February 1986)                                         @
  13. @                                                                              @
  14. @         Written by : Richard Andrews and David Lord,                         @
  15. @                      South West Universities Regional Computer Centre,       @
  16. @                      Claverton Down, Bath BA2 7AY, U.K.                      @
  17. @                                                                              @
  18. @                                                                              @
  19. @       ----------------------------------------------------------------       @
  20. @                                                                              @
  21. @                                                                              @
  22. @       Version 1.01   (October 1986)                                          @
  23. @                                                                              @
  24. @           Fixes by : Dave Allum and David Lord, SWURCC.                      @
  25. @                                                                              @
  26. @           1. The BOOL variable ASG_ROUTE is set by reading the BOOL ASG      @
  27. @              set in the interface procedure KERMIT. (If the BOOL ASG is      @
  28. @              not found ASG_ROUTE is set FALSE). ASG_ROUTE is used when       @
  29. @              checking valid characters for START-OF-PACKET etc. VME I/O      @
  30. @              cannot handle all control characters, the ASG can handle        @
  31. @              more than other communications controllers (eg NIC and CSC).    @
  32. @                                                                              @
  33. @           2. A warning message informs the user that VME KERMIT doesn't      @
  34. @              use the standard Kermit START-OF-PACKET character.              @
  35. @                                                                              @
  36. @           3. Attempts to set START-OF-PACKET, END-OF-LINE or PAD-CHARACTER   @
  37. @              to a character that cannot be handled by VME I/O are trapped.   @
  38. @                                                                              @
  39. @           4. VME KERMIT now does 8th bit prefixing correctly.                @
  40. @                                                                              @
  41. @           5. The EOF packet sent by VME KERMIT no longer contains the        @
  42. @              data field from the last Data packet sent.                      @
  43. @                                                                              @
  44. @           6. The DELAY timer now works properly. Previously if the micro     @
  45. @              Kermit sent a Nak before the DELAY timer had expired a VME      @
  46. @              break-in occurred.                                              @
  47. @                                                                              @
  48. @           7. VME KERMIT in SERVER mode no longer sends the name of the       @
  49. @              first file sent in the File_Hdr packet for second (and          @
  50. @              subsequent) files requested via GET command on the remote       @
  51. @              Kermit.                                                         @
  52. @                                                                              @
  53. @           8. VME KERMIT can now receive a batch of files sent by a micro     @
  54. @              Kermit using a wildcard send. Previously VME Kermit output      @
  55. @              several generations of the same filename.                       @
  56. @                                                                              @
  57. @           9. The way VME KERMIT standardises filenames has been improved.    @
  58. @              (VME filenames don't conform to the form 'name.type' as         @
  59. @              in the Kermit protocol: see KMT_SP_STANDARDISE_FILENAME)        @
  60. @                                                                              @
  61. @          10. Resources are released after each transfer so that a file       @
  62. @              that has just been sent to VME can be accessed by other users.  @
  63. @                                                                              @
  64. @          11. The DEBUG information at PACKET level is now in a more          @
  65. @              readable form.                                                  @
  66. @                                                                              @
  67. @------------------------------------------------------------------------------@
  68.  
  69.  
  70. @ Mode declarations: @
  71.  
  72. MODE KMT_BUFFER IS (96)BYTE;
  73. MODE KMT_STRING IS REF()BYTE;
  74. MODE KMT_WORD IS REF()BYTE;
  75.  
  76. MODE KMT_MTM_VALUES IS ANY
  77.   (LONG WORD      LW_VALUE,
  78.    LONG INT       LI_VALUE,
  79.    REF WORD       RW_VALUE,
  80.    REF INT        RI_VALUE,
  81.    REF LONG WORD  RLW_VALUE,
  82.    REF LONG INT   RLI_VALUE,
  83.    REF()BYTE      RVB_VALUE,
  84.    REF()REF()BYTE RVRVB_VALUE);
  85.  
  86. MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
  87.    (INT INPUT_TOTAL,
  88.         OUTPUT_TOTAL);
  89.  
  90.  
  91.  
  92. @ External procedures @
  93.  
  94. EXT PROC (RESPONSE)                              KMT_UI;
  95.  
  96. EXT PROC (REF INT,INT,RESPONSE)                  KMT_PH;
  97.  
  98. EXT PROC (REF INT,REF INT,RESPONSE)              KMT_PP_GET_PACKET,
  99.     PROC (INT,INT,BOOL,RESPONSE)                 KMT_PP_SEND_PACKET,
  100.     PROC (REF()BYTE,RESPONSE)            KMT_PP_BUILD_STRING_PACKET_DATA;
  101.  
  102. EXT PROC (RESPONSE)                              KMT_DH_OPEN_FILE,
  103.     PROC (RESPONSE)                              KMT_DH_CLOSE_FILE;
  104.  
  105. EXT PROC (RESPONSE)                      KMT_EH_INFORM_PE_CONTINGENCY;
  106.  
  107. EXT PROC (RESPONSE)                              KMT_FH_CLOSE_FILE,
  108.     PROC (RESPONSE)                              KMT_FH_SAVE_FILE;
  109.  
  110. EXT PROC (INT,REF()KMT_MTM_VALUES) INT            KMT_SP_MTM;
  111.  
  112. EXT PROC (REF KMT_STRING) KMT_WORD                KMT_SP_GET_WORD;
  113.  
  114. EXT PROC ()                                       KMT_SP_SET_DEFAULTS;
  115.  
  116. EXT PROC (INT,REF()KMT_MTM_VALUES)                KMT_SP_LOG_TRACE_MESSAGE;
  117.  
  118. EXT (<PREFIX "ICLCTM">)
  119.     PROC ()                                       ENDJOB;
  120. EXT (<PREFIX "ICLCTM">)
  121.     PROC (WORD,WORD,REF()BYTE,RESPONSE)           CTM_LOG;
  122. EXT (<PREFIX "ICLCTM">)
  123.     PROC (RESPONSE)                               CTM_JS_BEGIN;
  124. EXT (<PREFIX "ICLCTM">)
  125.     PROC (RESPONSE)                               CTM_JS_END;
  126. EXT (<PREFIX "ICLCTM">)
  127.     PROC (REF () BYTE,LONG WORD,REF () WORD,REF LONG LONG WORD,RESPONSE)
  128.                                                   CTM_JS_CALL;
  129. EXT (<PREFIX "ICLCTM">)
  130.     PROC (REF () BYTE,REF LONG INT,REF () BYTE,REF BOOL,RESPONSE)
  131.                                                   CTM_JS_READ;
  132.  
  133. @ External constants: @
  134.  
  135. EXT INT UNSET,EXIT,LOGOUT,FATAL_ERROR;  @ Miscellaneous constants @
  136.  
  137. EXT INT SERVER_MODE,COMMAND_MODE;
  138.  
  139. EXT INT REC_SERVER_IDLE,REC_INIT,SEND_INIT,ENTRY,ABORT,COMPLETE;
  140.  
  141. EXT INT ERROR_PKT;
  142.  
  143.  
  144. @ External variables @
  145.  
  146. EXT REF () BYTE KMT_VERSION;
  147.  
  148. EXT REF BOOL ASG_ROUTE;
  149.  
  150. EXT REF()KMT_MTM_VALUES KMT_MTM_AREA;
  151. EXT REF()BYTE MTM_TEXT;
  152. EXT REF INT MTM_TEXT_LEN;
  153. EXT REF ()REF ()BYTE MTM_RECALL_DATA;
  154.  
  155. EXT REF INT RC_IGNORED;
  156.  
  157. EXT REF INT PKT_SEQ,PKT_NO,PKT_TYPE;
  158.  
  159. EXT REF BOOL SAVE_INCOMPLETE_FILE;
  160.  
  161. EXT REF INT RETRY_COUNT,TIMEOUT_TOTAL;
  162.  
  163. EXT REF INT EXIT_STATE,KMT_CURRENT_MODE,KMT_PH_STATE;
  164.  
  165. EXT REF KMT_BUFFER KMT_VME_FILE_BUF,KMT_REM_FILE_BUF;
  166.  
  167. EXT REF KMT_WORD KMT_VME_FILE,KMT_REM_FILE;
  168.  
  169.  
  170.  
  171. GLOBAL STATIC PROC KMT_MESSAGE IS (INT MSG_NO,RESPONSE RESULT):
  172.  
  173.    @ outputs messages to terminal and journal file                             @
  174.    @ if error returned from protocol handler, an error packet is sent          @
  175.  
  176.    BEGIN
  177.       INT REPLY := UNSET,
  178.           M := IF MSG_NO > 0
  179.                THEN MSG_NO
  180.                ELSE -MSG_NO               @ warning message codes are negative @
  181.                FI;
  182.       RESULT := 0;
  183.  
  184.       WHILE REPLY = UNSET
  185.       DO                                                      @ expand message @
  186.          REPLY := KMT_SP_MTM(M,KMT_MTM_AREA);
  187.          IF REPLY = -1 OR REPLY = 0
  188.          THEN
  189.             CTM_LOG(3,6,MTM_TEXT(SIZE MTM_TEXT_LEN),RC_IGNORED);
  190.  
  191.             IF M = MSG_NO                 @ 1st message text from error number @
  192.             THEN       @ protocol handler error, send 1st message in error pkt @
  193.                KMT_PP_BUILD_STRING_PACKET_DATA(MTM_TEXT(SIZE MTM_TEXT_LEN),
  194.                                                             RC_IGNORED);
  195.                KMT_PP_SEND_PACKET(ERROR_PKT,PKT_SEQ,FALSE,RC_IGNORED);
  196.                IF RC_IGNORED > 0
  197.                THEN         @ fatal error sending packet! - continue expansion @
  198.                              @ of current message, but ensure abort afterwards @
  199.                   KMT_PH_STATE := ABORT;                     @ set abort state @
  200.                   EXIT_STATE := FATAL_ERROR;
  201.                   RESULT := -89061
  202.                FI
  203.             FI;
  204.  
  205.             IF REPLY = 0 AND RESULT NE 0
  206.             THEN                        @ error sending packet, record message @
  207.                M := -RESULT; RESULT := 0         @ zero result always returned @
  208.             ELSE
  209.                M := REPLY                    @ continue message text expansion @
  210.             FI
  211.          FI
  212.       REPEAT
  213.  
  214.    END
  215.  
  216.    ; @ KMT_MESSAGE @
  217.  
  218.  
  219.  
  220. STATIC PROC KERMIT_SUPPORT IS (REF () BYTE OPTION,REF () BYTE VME_FILE,
  221.                                REF () BYTE REM_FILE,RESPONSE RESULT):
  222.  
  223.    BEGIN
  224.  
  225.       INT KMT_OPTION;                       @ mode supplied on entry to Kermit @
  226.  
  227.  
  228.       PROC VALIDATE_ARGS IS (RESPONSE RESULT):
  229.  
  230.          @ checks Kermit option and verifies that file arguments are           @
  231.          @ present for Receive or Send options                                 @
  232.          @ sets initial protocal handler state (where appropriate)             @
  233.  
  234.          BEGIN             @ remove leading and trailing spaces from filenames @
  235.             ()BYTE VME_BUF := VME_FILE;
  236.             KMT_WORD VME_PTR := VME_BUF;
  237.             ()BYTE REM_BUF := REM_FILE;
  238.             KMT_WORD REM_PTR := REM_BUF;
  239.             KMT_VME_FILE := KMT_SP_GET_WORD(VME_PTR);
  240.             KMT_REM_FILE := KMT_SP_GET_WORD(REM_PTR);
  241.  
  242.             KMT_MTM_AREA(3) := OPTION AS KMT_MTM_VALUES.RVB_VALUE;
  243.  
  244.             KMT_OPTION := KMT_CURRENT_MODE :=
  245.                KMT_SP_MTM(5000,KMT_MTM_AREA(SIZE 4));        @ validate option @
  246.  
  247.             RESULT := 0;
  248.  
  249.             CASE KMT_OPTION
  250.             THEN                     @ Server - no file args should be present @
  251.                KMT_PH_STATE := REC_SERVER_IDLE;
  252.                UNLESS KMT_VME_FILE REF NIL AND KMT_REM_FILE REF NIL
  253.                DO
  254.                   KMT_VME_FILE := NIL;
  255.                   KMT_REM_FILE := NIL;
  256.                   RESULT := -85000                                   @ warning @
  257.                FI
  258.             ELSE          @ Receive - VME_FILE may be present but not REM_FILE @
  259.                KMT_PH_STATE := REC_INIT;
  260.                UNLESS KMT_VME_FILE REF NIL
  261.                DO
  262.                   KMT_VME_FILE :=
  263.                      KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
  264.                         KMT_VME_FILE
  265.                FI;
  266.                UNLESS KMT_REM_FILE REF NIL
  267.                DO
  268.                   KMT_REM_FILE := NIL;
  269.                   RESULT := -85001                                   @ warning @
  270.                FI
  271.             ELSE       @ Send - VME_FILE must be present, REM_FILE is optional @
  272.                KMT_PH_STATE := SEND_INIT;
  273.                IF KMT_VME_FILE REF NIL
  274.                THEN
  275.                   EXIT_STATE := FATAL_ERROR;
  276.                   RESULT := -85010                                     @ error @
  277.                ELSE
  278.                   KMT_VME_FILE :=
  279.                      KMT_VME_FILE_BUF(SIZE LENGTH VME_FILE):=
  280.                         KMT_VME_FILE;
  281.                   UNLESS KMT_REM_FILE REF NIL
  282.                   DO
  283.                      KMT_REM_FILE :=
  284.                         KMT_REM_FILE_BUF(SIZE LENGTH KMT_REM_FILE) :=
  285.                            KMT_REM_FILE
  286.                   FI
  287.                FI
  288.             ELSE               @ Command - no file arguments should be present @
  289.                KMT_PH_STATE := UNSET;
  290.                UNLESS KMT_VME_FILE REF NIL AND KMT_REM_FILE REF NIL
  291.                DO
  292.                   KMT_VME_FILE := NIL;
  293.                   KMT_REM_FILE := NIL;
  294.                   RESULT := -85000                                   @ warning @
  295.                FI
  296.             DEFAULT                                       @ invalid entry mode @
  297.                EXIT_STATE := FATAL_ERROR;
  298.                RESULT := -85020
  299.             ESAC
  300.          END
  301.  
  302.          ; @ VALIDATE_ARGS @
  303.  
  304.  
  305.       PROC CLOSE_FILES IS (RESPONSE RESULT):
  306.  
  307.          @ close Kermit Send/Receive files when aborting                       @
  308.  
  309.          BEGIN
  310.             INT RC;
  311.             KMT_FH_CLOSE_FILE(RC);
  312.             RESULT := IF RC <= 0
  313.                       THEN 0                             @ ignore -ve warnings @
  314.                       ELSE 89042                          @ error closing file @
  315.                       FI;
  316.             IF SAVE_INCOMPLETE_FILE
  317.             THEN
  318.                KMT_FH_SAVE_FILE(RC);
  319.                IF RC > 0
  320.                THEN RESULT := 89044                        @ error saving file @
  321.                FI
  322.             FI;
  323.             KMT_VME_FILE := NIL;
  324.             KMT_REM_FILE := NIL
  325.          END
  326.  
  327.          ; @ CLOSE_FILES @
  328.  
  329.  
  330.       @ main Kermit segment @
  331.  
  332.       EXIT_STATE := UNSET;
  333.  
  334.       KMT_SP_SET_DEFAULTS();
  335.  
  336.       @ initialise message text area @
  337.       KMT_MTM_AREA(SIZE 3) :=
  338.          (MTM_TEXT AS KMT_MTM_VALUES.RVB_VALUE,
  339.           MTM_TEXT_LEN AS KMT_MTM_VALUES.RI_VALUE,
  340.           MTM_RECALL_DATA AS KMT_MTM_VALUES.RVRVB_VALUE);
  341.  
  342.       KMT_MTM_AREA(3 SIZE 2) := (1           AS KMT_MTM_VALUES.LI_VALUE,
  343.                                  KMT_VERSION AS KMT_MTM_VALUES.RVB_VALUE);
  344.  
  345.       KMT_MESSAGE(-1,RC_IGNORED);                             @ output banners @
  346.       KMT_SP_LOG_TRACE_MESSAGE(2,NIL);
  347.  
  348.       VALIDATE_ARGS(RESULT);
  349.       IF RESULT NE 0
  350.       THEN    @ output message & continue (n.b. exit state may be fatal_error) @
  351.          KMT_MESSAGE(RESULT,RESULT)
  352.       FI;
  353.       KMT_DH_OPEN_FILE(RESULT);
  354.       IF RESULT NE 0
  355.       THEN
  356.          KMT_MESSAGE(RESULT,RESULT);
  357.          EXIT_STATE := FATAL_ERROR
  358.       FI;
  359.  
  360.       IF CTM_JS_BEGIN(RESULT);                           @ start new SCL block @
  361.          RESULT > 0
  362.       THEN
  363.          EXIT_STATE := FATAL_ERROR
  364.       FI;
  365.  
  366.       IF EXIT_STATE = UNSET
  367.       THEN                       @ notify user of non-standard START-OF-PACKET @
  368.          KMT_MESSAGE(-3,RC_IGNORED)
  369.       FI;
  370.  
  371.       WHILE EXIT_STATE = UNSET
  372.       DO
  373.          RESULT := 0;                            @ everything ok at this point @
  374.          IF KMT_CURRENT_MODE = COMMAND_MODE
  375.          THEN   @ get command from user, if command is SERVER, SEND or RECEIVE @
  376.                 @ then KMT_CURRENT_MODE and KMT_PH_STATE will be reset         @
  377.             KMT_UI(RESULT);
  378.             IF RESULT NE 0
  379.             THEN
  380.                KMT_MESSAGE(RESULT,RESULT)
  381.             FI
  382.          ELSE    @ sending or receiving, carry out action on entry to protocol @
  383.                  @ handler state, wait for a packet, then carry out action in  @
  384.                  @ response to type of packet received                         @
  385.             KMT_PH(KMT_PH_STATE,ENTRY,RESULT);
  386.             IF RESULT = 0
  387.             THEN
  388.                KMT_PP_GET_PACKET(PKT_TYPE,PKT_NO,RESULT);
  389.                IF RESULT = 39854                                     @ timeout @
  390.                THEN
  391.                   TIMEOUT_TOTAL := TIMEOUT_TOTAL + 1;
  392.                   RESULT := 0
  393.                FI;
  394.                IF RESULT <= 0
  395.                THEN                  @ warning message already ouput, continue @
  396.                   RESULT := 0;
  397.                   KMT_PH(KMT_PH_STATE,PKT_TYPE,RESULT)
  398.                FI
  399.             FI;
  400.             IF RESULT NE 0
  401.             THEN
  402.                KMT_MESSAGE(RESULT,RESULT)
  403.             FI;
  404.  
  405.             IF KMT_PH_STATE = ABORT
  406.             THEN
  407.                CLOSE_FILES(RESULT);
  408.                IF RESULT NE 0
  409.                THEN
  410.                   KMT_MESSAGE(RESULT,RESULT)
  411.                FI;
  412.                KMT_PH_STATE := COMPLETE
  413.             FI;
  414.  
  415.             IF KMT_PH_STATE = COMPLETE
  416.             THEN
  417.                IF CTM_JS_END(RESULT);                @ close current SCL block @
  418.                   RESULT > 0
  419.                THEN
  420.                   EXIT_STATE := FATAL_ERROR
  421.                ELSF CTM_JS_BEGIN(RESULT);                 @ open new SCL block @
  422.                   RESULT > 0
  423.                THEN
  424.                   EXIT_STATE := FATAL_ERROR
  425.                ELSE
  426.                   PKT_SEQ := 0;                         @ zero packet sequence @
  427.                   IF KMT_CURRENT_MODE = SERVER_MODE
  428.                   THEN         @ remain in Server mode until EXIT_STATE is set @
  429.                        @ (may already have been set by Server Generic command) @
  430.                      KMT_PH_STATE := REC_SERVER_IDLE;
  431.                      RETRY_COUNT := 0
  432.                   ELSF KMT_OPTION = COMMAND_MODE
  433.                   THEN     @ resume Command mode on completion of Send/Receive @
  434.                      KMT_CURRENT_MODE := COMMAND_MODE
  435.                   ELSE     @ Send or Receive specified in VME command, exit on @
  436.                      EXIT_STATE := EXIT                           @ completion @
  437.                   FI
  438.                FI
  439.             FI
  440.          FI
  441.       REPEAT;
  442.  
  443.       CTM_JS_END(RC_IGNORED);                        @ close current SCL block @
  444.  
  445.       KMT_DH_CLOSE_FILE(RC_IGNORED);                     @ close logging files @
  446.  
  447.       IF EXIT_STATE = FATAL_ERROR
  448.       THEN
  449.          KMT_MESSAGE(-85030,RC_IGNORED)                            @ tell user @
  450.       ELSF EXIT_STATE = LOGOUT
  451.       THEN             @ log out Kermit after receiving Generic Logout command @
  452.          KMT_MESSAGE(-85031,RC_IGNORED);
  453.          ENDJOB()
  454.       ELSE
  455.          KMT_MESSAGE(-85032,RC_IGNORED)                       @ output newline @
  456.       FI
  457.  
  458.    END
  459.  
  460.    ; @ KERMIT_SUPPORT @
  461.  
  462.  
  463. GLOBAL STATIC (<STATUS 5;PSPACE 10001; TEMPLATE>) PROC KERMIT_THE_FROG IS
  464.       ((<LIT "COMMAND">)             REF()BYTE OPTION,
  465.        (<LIT ""       >)             REF()BYTE VME_FILE,
  466.        (<LIT ""       >)             REF()BYTE REM_FILE,
  467.        (<KEY RESPONSE;DEF N'RESULT>) RESPONSE RESULT):
  468.  
  469.    BEGIN
  470.  
  471.       ()BYTE JSV_NAME := "ASG";              @ obtain value for ASG_ROUTE bool @
  472.       CTM_JS_READ(JSV_NAME,NIL,NIL,ASG_ROUTE,RC_IGNORED);
  473.       IF RC_IGNORED NE 0 THEN ASG_ROUTE := FALSE FI;
  474.  
  475.       @ verify parameter references (parameter values validated later):        @
  476.       @    OPTION   must be of mode REF () BYTE, may not be ZLR or NIL         @
  477.       @    VME_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL   @
  478.       @    REM_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL   @
  479.  
  480.       UNLESS (VERIFY OPTION AND VALIDR OPTION)
  481.       AND    (VERIFY VME_FILE AND (VALIDR VME_FILE OR NOT(VME_FILE IS NIL)))
  482.       AND    (VERIFY REM_FILE AND (VALIDR REM_FILE OR NOT(REM_FILE IS NIL)))
  483.       THEN                                       @ invalid parameter reference @
  484.          RESULT := 10002 @ ARCH_INACCESSIBLE_PARAMETER @
  485.  
  486.       ELSF                                             @ create resource block @
  487.          CTM_JS_BEGIN(RESULT);
  488.          RESULT <= 0
  489.       THEN                                            @ resource block created @
  490.          LONG LONG WORD KERMIT_RESULT;
  491.          ANY((3)LONG WORD AS_LW,(6) WORD AS_W) PARAMS;
  492.          PARAMS.AS_LW := (BDESC OPTION,BDESC VME_FILE,BDESC REM_FILE);
  493.  
  494.                                                 @ set up program error handler @
  495.          IF  KMT_EH_INFORM_PE_CONTINGENCY(RESULT);
  496.               RESULT > 0
  497.          THEN                                    @ failed to set error handler @
  498.             SKIP
  499.          ELSF CTM_JS_CALL(NIL,PDESC KERMIT_SUPPORT,PARAMS.AS_W,KERMIT_RESULT,
  500.                           RESULT);                           @ create firewall @
  501.               RESULT <= 0
  502.          THEN                         @ either exited normally or via CTM_STOP @
  503.             RESULT := IF (S'S'KERMIT_RESULT) <= 0
  504.                       THEN 0                                 @ ignore warnings @
  505.                       ELSE 52000              @ error return common resultcode @
  506.                       FI
  507.          FI;
  508.  
  509.          CTM_JS_END(RC_IGNORED)                           @ end resource block @
  510.       FI
  511.  
  512.    END
  513.  
  514.    ; @ KERMIT_THE_FROG @
  515.  
  516. ENDMODULE @ KMT_MAIN_MODULE @
  517.