*DECK,CMD 
USETEXT MISC$ 
USETEXT TCH$COM 
USETEXT TSB$COM 
USETEXT ABH$COM 
USETEXT CMD$COM 
USETEXT SMDEF 
USETEXT GLOBALI 
USETEXT SM$COM
USETEXT TCB$COM 
      PROC CMD; 
        BEGIN                # CALLS CRACKER TO PARSE CONSOLE COMMANDS #
  
*IF,DEF,IMS 
 #
*1DC  CMD 
* 
*     1. PROC NAME           AUTHOR              DATE 
*        CMD                 PRATT/WEST          6/15/78
*                            SEYUNG OH           NOV 21,1979
* 
*     2. FUNCTIONAL DESCRIPTION 
*        "CMD" IS RESPONSIBLE FOR THE EXECUTION OF COMMANDS SENT UPLINE 
*        BY AN RBF CONSOLE
* 
*     3. METHOD USED
*        CMD CONCATENATES 0 OR MORE "BLK" BLOCKS FOLLOWED BY ONE "MSG"
*        BLOCK.  THE RESULT CONSTITUTES ONE COMPLETE RBF COMMAND WHICH
*        IS SUBSEQUENTLY PASSED TO "CRACKER" FOR PARSING. CRACKER 
*        BUILDS AN ENCODED FORM OF THE COMMAND IN CIT$TABLE.  CODE
*        WHICH EXECUTES THE CONSOLE COMMANDS USES THE ENCODED FORM
*        PROVIDED BY CRACKER. 
* 
*        "RESUME" COMMANDS AND ERRORS ARE EXECUTED IN "CMD" ITSELF. 
*        ALL OTHER COMMANDS ARE ACTUALLY EXECUTED IN OTHER OVERLAYS:  
*        IN "DIS" OR "EXTCMD".
* 
*     4. ENTRY PARAMETERS 
*        TCB$INPUT - CONTAINS TSB ORDINAL OF CHAIN OF BLOCKS WHICH
*        CONSTITUTE ONE RBF COMMAND 
* 
*     5. EXIT PARAMETERS
*        CIT$TABLE (FOR COMMANDS TO BE PROCESSED BY EXTCMD) 
*        TCB - FOR "DIS" COMMANDS 
* 
*     6. COMDECKS CALLED
*        RBF$COM
*        ABH$COM
*        TCB$COM
*        TSBMDEFS 
*        TSBMBASE 
*        CMD$COM
* 
*     7. ROUTINES CALLED
*        CONSOLE
*        CRACKER
*        RETTSB 
*        LINK 
*        GETBUF 
*        WAIT 
*        RDYMSG 
*        FREEBUFFER 
* 
*     8. DAYFILE MESSAGES.
*        NONE 
* 
*     9. CMD LINKS TO IDLE, DIS, OR EXTCMD
 #
*ENDIF
#     EXTERNAL REFERENCES                                              #
  
      XREF PROC CONSOLE;     # CHAINS MESSAGES ON THE CONSOLE"S TCB    #
      XREF PROC CRACKER;     # CRACKER - CRACKS COMMAND LINE           #
      XREF PROC EVENT;                           # LINK TO EVENT       #
      XREF PROC RETTSB;      # RETURNS ALLOCATED BUFFERS               #
      XREF PROC LINK;        # LINK - LINK PROCESSOR                   #
      XREF FUNC GETBUF U;    # GETBUF - OBTAINS BUFFER SPACE           #
      XREF PROC SETUPACN;    # SET UP CONTROL BLOCKS                # 
      XREF PROC RDYMSG;      # SEND READY MESSAGE TO THE CONSOLE       #
      XREF FUNC INPTYPE U;                       # SEARCH FOR INPUT    #
      XREF PROC SENDMSG;                         # SEND CONSOLE OUTPUT #
      XREF PROC FREEBUFFER;                      # FREE I/O BUFFER     #
      XREF LABEL CALLRTN; 
  
      ITEM END$OF$MSG B;
      ITEM LINE$ERROR B;
      ITEM I I; 
      ITEM CITORD I;
      ITEM TEXTORD I; 
      ITEM CMDTOOLONG C(22) = " COMMAND LINE TOO LONG" ;
      CONTROL EJECT;
# 
      CMD - BEGIN EXECUTABLE CODE 
                                                                       #
#       RETURN IF NO DATA TO PROCESS                                   #
  
  
CMDPROCESS: 
#                                               # 
#                                                                      #
#     SET UP CIT$TABLE                                                 #
#                                                                      #
      CITORD = GETBUF(CIT$SIZE,MOVEABLE);  # GET CIT$TABLE SPACE       #
  
      IF CITORD EQ 0
      THEN
        BEGIN                                    # WAIT FOR STORAGE    #
                EVENT (CHAINS"BACKGROUND"); 
        GOTO CMDPROCESS;
        END                  # WAIT FOR STORAGE                        #
  
      TCB$CITBUF = CITORD;
      P<CIT$TABLE> = ADDRESS[CITORD]; 
        CIT$CMDTYPE = S"NOCOMMAND"; 
        END$OF$MSG = FALSE; 
        LINE$ERROR = FALSE; 
  
        FOR I = I WHILE NOT END$OF$MSG DO 
          BEGIN              # ACCUMULATE MESSAGE, BLOCK BY BLOCK      #
          P<ABH> = ADDRESS[TCB$INPUT];
  
          IF CIT$NOCHARS + ABH$TLC LQ 255 
          THEN
            BEGIN            # MOVE DATA TO CIT$MESSAGE                #
            C<CIT$NOCHARS,ABH$TLC>CIT$MESSAGE = C<0,ABH$TLC>ABH$TEXTC;
            CIT$NOCHARS = CIT$NOCHARS + ABH$TLC;
            END              # MOVE DATA ...                           #
  
          ELSE
  
            LINE$ERROR = TRUE;     # MESSAGE TOO LONG                  #
  
  
          IF ABH$ABT EQ S"MSG" OR ABH$NEXT EQ 0 
          THEN
            BEGIN # BUFFER EMPTY #
            END$OF$MSG = TRUE;
            END # BUFFER EMPTY #
          TEXTORD = TCB$INPUT;
          TCB$INPUT = ABH$NEXT; 
          IF TEXTORD EQ TCB$ILAST 
          THEN
            BEGIN                                # CLEAR LAST INPUT    #
            TCB$ILAST = ZERO;                    # BUFFER POINTER      #
            END 
          RETTSB(TEXTORD);
          SETUPACN (ACN); 
          END                # ACCUMULATE MESSAGE ...                  #
  
  
        IF NOT LINE$ERROR 
        THEN
          CRACKER;           # CALL CRACKER TO PARSE COMMAND           #
        ELSE
          BEGIN              # MESSAGE TOO LONG                        #
          CIT$CMDTYPE = S"NOCOMMAND"; 
          CIT$MESSAGE = CMDTOOLONG; 
          END                # MESSAGE TOO LONG                        #
  
  
# SWITCH TO MODULE WHICH IS TO PROCESS COMMAND                         #
  
  
  
  
      IF CIT$CMDTYPE EQ S"DISPLAY"
      THEN
        BEGIN                # DISPLAY COMMAND                         #
        TCB$DIS = CIT$DIS;         # SET-UP TCB FOR "DIS" CALL         #
        TCB$REFRESH = CIT$RFRFLAG;
      TCB$JSN = CIT$JSN ; 
      TCB$ZERO = 0 ;
        TCB$REF = CLOCK;
        LINK (CHAINS"DIS$",NOEVENT);
        GOTO ENDCMD;
        END                  # DISPLAY COMMAND                         #
  
  
      IF CIT$CMDTYPE EQ S"NOCOMMAND"
      THEN
        GOTO CMD$ERR; 
  
  
      CITORD = 0;            # ENSURE CIT$TABLE NOT RELEASED           #
      GOTO ENDOFCMDPROC;
# 
      PROCESS ERROR IN COMMAND
# 
CMD$ERR:  
  
      CONSOLE (CIT$ERRMSG,NON$CRITICAL,40); 
  
# 
      ISSUE READY MESSAGE 
# 
CMD$READY:  
           RDYMSG(FALSE); 
# 
      EXIT COMMAND PROCESSING 
# 
ENDOFCMDPROC: 
      LINK (CHAINS"EXT$CMD",NOEVENT); 
ENDCMD: 
      IF CITORD NQ 0
      THEN
        BEGIN                # RELEASE CIT$TABLE BUFFER                #
        TCB$CITBUF = 0; 
        RETTSB(CITORD); 
        SETUPACN (ACN); 
        END                  # RELEASE CIT$TABLE BUFFER                #
  
      GOTO CALLRTN;                              # RETURN TO PROCESS   #
      END                    # CMD                                     #
TERM; 
