*DECK SFILI 
USETEXT COMCBEG 
USETEXT COMCAPR 
USETEXT COMCCAE 
USETEXT COMQDEF 
USETEXT COMQFIL 
USETEXT COMQKDS 
USETEXT COMQNET 
USETEXT COMQPID 
USETEXT COMQSCH 
USETEXT COMQSEL 
    PROC SFILI; 
      BEGIN    # SFILI #
# 
**    SFILI      UPDATE AND ADVANCE INITIATOR FILE TABLE ENTRY STATUS.
* 
*     SFILI IS CALLED PERIODICALLY FOR EACH FILE TABLE ENTRY TO 
*     DETERMINE THE CURRENT STATE OF THE FILE AND CONNECTION
*     AND TO INITIATE APPROPRIATE ACTION BASED THEREON. 
* 
*     PROC SFILI
* 
*     ENTRY      ACN = FILE TABLE ENTRY INDEX 
*                FILEFTS = CURRENT FILE TRANSFER STATE. 
* 
*     EXIT       FILEFTS = UPDATED IF POSSIBLE
*                APPROPRIATE PROCESSORS CALLED. 
* 
*     PROCESS    CASE FILEFTS OF: 
*                  VACANT:  
*                    RETURN.
*                  INITIAL: 
*                    INCREMENT ACNS-IN-USE
*                    FILEFTS = UNCONNECTED, NO FILE ASSIGNED. 
*                  WAITING FOR NETWORK MESSAGE: 
*                    IF TIMEOUT EXPIRED:  
*                      CALL CONERR ("CONNECTION TIMEOUT."). 
*                    UPDATE NEXT TIMEOUT TIMER. 
*                  ASSIGNED AND NOT CONNECTED:  
*                    IF NO CONNECT DELAY: 
*                      CALL NETPUT TO ISSUE CON ACRQ
*                      INCREMENT ACTIVE CONNECTION COUNT
*                      FILEFTS = WAITING FOR NETWORK MESSAGE. 
*                  FILE ASSIGNED AND CONNECTED: 
*                    CALL BCM00 TO SEND RFT.
*                    FILEFTS = WAITING FOR NETWORK MESSAGE. 
*                  NETXFR REQUIRED: 
*                    CALL QTFXFR TO INITIATE FILE TRANSFER. 
*                  NETXFR IN PROGRESS:  
*                    IF NETXFR COMPLETE:  
*                      CALL XFRERR TO PROCESS NETXFR COMPLETION STATUS
*                      IF CONNECTION NOT BROKEN:  
*                        FILEFTS = STOP REQUIRED. 
*                  STOP REQUIRED: 
*                    CALL CMDPUT TO ISSUE STOP COMMAND
*                    FILEFTS = WAITING FOR NETWORK MESSAGE. 
*                  ETP REQUIRED:  
*                    CALL CMDPUT TO ISSUE ETP COMMAND 
*                    FILEFTS = WAITING FOR NETWORK MESSAGE. 
*                  TRANSFER COMPLETE AND SUCCESSFUL:  
*                    CALL DSPQFIL TO EVICT FILE 
*                    IF CONNECTION NOT BROKEN:  
*                      FILEFTS = NO FILE ASSIGNED 
*                    ELSE:  
*                      FILEFTS = TERMINATED.
*                  TRANSFER COMPLETE, CONNECTION ENDED: 
*                    IF USER ERROR: 
*                      CALL SENDCLF TO SEND MESSAGE TO USER 
*                      FILEFTS = NOT CONNECTED, NO FILE ASSIGNED. 
*                    ELSE:  
*                      IF CONNECTION ERROR
*                        AND FILE STILL ASSIGNED
*                        AND RETRY COUNT NOT EXHAUSTED: 
*                          DECREMENT RETRY COUNT
*                          FILEFTS = ASSIGNED AND NOT CONNECTED.
*                        ELSE:  
*                          IF CONNECTION ERROR: 
*                            RETURN FILE TO QUEUE 
*                            DISABLE PID
*                            SET PID RETRY TIMER
*                          IF FILE STILL ASSIGNED:  
*                            CALL DSPQFIL TO EVICT OR REQUEUE FILE
*                          CLEAR PID.SELECTION-CLASS.IN-USE 
*                          DECREMENT SELECTION-CLASS.IN-USE 
*                          DECREMENT ACNS-IN-USE
*                          IF ALL AFTS WERE IN USE: 
*                            RESCHEDULE FILE SELECTION
*                          CALL RELAFT TO RELEASE AFT 
*                          FILEFTS = VACANT.
*                  CONNECTED, NO FILE ASSIGNED: 
*                    IF PID ENABLED AND IDLEDOWN NOT IN PROGRESS: 
*                      GET NEXT SELECTION CLASS FOR FILE
*                      IF NONE AVAILABLE: 
*                        FILEFTS = ETP REQUIRED.
*                      ELSE:  
*                        FILEFTS = CONNECTED, WAIT ACQUIRE
*                        CALL QACCALL(RECALL) 
*                        CALL QACRESP 
*                    ELSE:  
*                      FILEFTS = ETP REQUIRED.
*                  NOT CONNECTED, NO FILE ASSIGNED: 
*                    IF PID ENABLED AND IDLEDOWN NOT IN PROGRESS: 
*                      IF NO QAC CALL OUTSTANDING:  
*                        FILEFTS = NOT CONNECTED, WAIT ACQUIRE
*                        CALL QACCALL(RECALL) 
*                        CALL QACRESP 
*                    ELSE:  
*                      FILEFTS = TRANSFER COMPLETE, CONNECTION ENDED. 
*                  NOT CONNECTED, WAIT ACQUIRE RESPONSE:  
*                    CASE FILEQAR OF: 
*                      NOT COMPLETE:  
*                        RETURN.
*                      FILE AVAILABLE:  
*                        FILEFTS = ASSIGNED AND NOT CONNECTED.
*                      NO FILE FOUND: 
*                        FILEFTS = COMPLETE, CONNECTION ENDED.
*                      INVALID FILE:  
*                        FILEFTS = COMPLETE, CONNECTION ENDED.
*                  CONNECTED, WAIT ACQUIRE RESPONSE:  
*                    CASE FILEQAR OF: 
*                      NOT COMPLETE:  
*                        RETURN.
*                      FILE AVAILABLE:  
*                        FILEFTS = ASSIGNED AND CONNECTED.
*                      NO FILE FOUND: 
*                        FILEFTS = CONNECTED, NO FILE ASSIGNED. 
*                      INVALID FILE:  
*                        FILEFTS = CONNECTED, NO FILE ASSIGNED. 
# 
  
# 
****  XREF
# 
      XREF
        BEGIN 
        PROC ACSTORE;              # STORE LEVEL 7 COMMAND #
        PROC APSTOR;               # STORE LEVEL 7 PARAMETER #
        PROC BCM00;                # BUILD RFT #
        FUNC CLOCK      C(10);     # RETURN SYSTEM CLOCK #
        PROC CMDPUT;               # SEND LEVEL 7 COMMAND # 
        PROC CONERR;               # PROCESS CONNECTION ERROR # 
        PROC CONLOG;               # LOG CONNECTION MESSAGE # 
        PROC DSPQFIL;              # EVICT OR REQUEUE QUEUE FILE #
        PROC DUMXFR;               # INTERFACE TO QTFXFR #
        PROC FREENTA;              # SET NETWORK BUFFER ADDRESS # 
        PROC FTUPUT;               # SEND NETWORK MESSAGE # 
        PROC GETSELC;              # GET NEXT SELECTION CLASS # 
        PROC MSGLOG;               # ISSUE MESSAGE #
        PROC NAME;                 # DEBUG CODE # 
        PROC NSTORE;               # BUILD NETWORK MESSAGE #
        PROC QACCALL;              # CALL QAC/QAF TO ACQUIRE FILE # 
        PROC QACRESP;              # PROCESS QAC/QAF RESPONSE # 
        PROC RELAFT;               # RELEASE AFT ENTRY #
        PROC SENDCLF;              # SEND LOG FILE TO USER #
        PROC SETPLTA;              # SET PLT ENTRY POINTER #
        FUNC TIMADT     U;         # ADJUST TIMER # 
        PROC XFRERR;               # PROCESS NETXFR STATUS #
        FUNC XCDD       C(10);     # CONVERT TO DECIMAL DISPLAY CODE #
        END 
  
# 
****  XREF END
# 
  
  
      ITEM NOSELAVAIL B;           # NO SELECTION CLASS AVAILABLE # 
      ITEM PREVSTATE  I;           # PREVIOUS TRANSFER STATE #
      ITEM SELCLASS   U;           # SELECTION CLASS #
      ITEM TIMELEFT   I;           # SECONDS LEFT UNTIL TIMEOUT # 
      ITEM TMPCLK     U;           # STORAGE FOR CLOCK #
      ITEM TMPLID     U;           # STORAGE FOR LID #
  
      DEF LEMSG7     #21#;
      ITEM EMSG7      C(LEMSG7) = "CONNECTION TIMED OUT.";
  
      DEF LEMSGACN   #56#;
      ITEM EMSGACN C(LEMSGACN) =
         " QTF, COUNT OF ACTIVE CONNECTIONS DECREMENTED BELOW ZERO."; 
  
      DEF LSMSGCONR  #18#;
      ARRAY SMSGCONR   S(2);
        BEGIN 
        ITEM $DCONRA    C(00,00,14) = ["CONNECTING TO "]; 
        ITEM DCONPID    C(01,24,03);
        ITEM $DCONRB    C(01,42,01) = ["."];
        END 
  
*CALL COMQSWI 
      ARRAY [0:QAR$MAX];
        BEGIN 
        ITEM UQR$NXTST  U(00,00,06) = 
          [FTS$UNCWQR,             # INCOMPLETE # 
           FTS$ASGUNC,             # FILE AVAILABLE # 
           FTS$CMPCNT,             # NO FILE FOUND #
           FTS$CMPCNT];            # INVALID FILE # 
        ITEM CQR$NXTST  U(00,06,06) = 
          [FTS$CONWQR,             # INCOMPLETE # 
           FTS$ASGCON,             # FILE AVAILABLE # 
           FTS$CONNFA,             # NO FILE FOUND, TRY NEXT SEL CLASS #
           FTS$CONNFA];            # INVALID FILE, TRY AGAIN #
        END 
  
        $BEGIN
        NAME("SFILI");
        $END
  
      IF AFT[ACN] EQ 0
      THEN
        BEGIN 
        RETURN; 
        END 
  
      P<FILETAB> = AFT[ACN];
      PREVSTATE = -1; 
      ASLONGAS PREVSTATE NE FILEFTS 
      DO
        BEGIN 
        PREVSTATE = FILEFTS;
        GOTO FTSIS[FILEFTS];       # SIMULATED CASE STATEMENT # 
  
SWI$VACANT: 
  
# 
*     UNUSED ENTRY. 
# 
  
          GOTO SWIEND;             # DO NOTHING # 
  
SWI$INIT: 
  
# 
*     INITIAL STATE.
# 
  
          ACNNO = ACNNO + 1;
          MSGWFAACN1 = " "; 
          MSGWFAACN2 = ACNNO + O"33"; 
          FILEFTS = FTS$UNCNFA; 
          GOTO SWIEND;
  
SWI$WNMSG:  
  
# 
*     WAITING FOR NETWORK MESSAGE.
# 
  
          IF (FILETIM NE 0) 
          THEN
            BEGIN 
            TIMELEFT = TIMADT(FILETOU, FILETIM);
            IF (TIMELEFT EQ 0)
            THEN
              BEGIN 
              CONERR(LOC(EMSG7),LEMSG7); # PROCESS TIMEOUT ERROR #
              END 
  
            ELSE
              BEGIN 
              IF (TIMELEFT LT TIMNXTEVNT) 
              THEN
                BEGIN 
                TIMNXTEVNT = TIMELEFT;
                END 
  
              END 
  
            END 
  
          GOTO SWIEND;
  
SWI$ASGUNC: 
  
# 
*     FILE ASSIGNED AND NOT CONNECTED.
# 
  
          FILESTR = CLOCK(TMPCLK);
          NHA = SUPHDR + 1; 
          FILERCN = ACN;           # SAVE REQUESTED CONN NUMBER # 
          NSTORE(NHA,$ABHABN,ACN);
          NTAWD[1] = FILELID;      # SET LID #
          CONPID[1] = FILECPD;     # SET PID #
          NSTORE(NTA,$PFCSFC,CONACRQ);
          NSTORE(NTA,$CONANM,QTFSNAM);
          FTUPUT(NHA,NTA);         # PUT CONNECTION REQUEST # 
          DCONPID = FILECPDC; 
          CONLOG(LOC(SMSGCONR),LSMSGCONR); # CONNECTING TO PID. # 
          FILETIM = 0;             # SUBSYSTEM WILL TIME-OUT REQUEST #
          FILEFTS = FTS$WNMSG;
          GOTO SWIEND;
  
SWI$ASGCON: 
  
# 
*     FILE ASSIGNED AND CONNECTED.
# 
  
          FILESTR = CLOCK(TMPCLK);
          BCM00;                   # SEND RFT # 
          GOTO SWIEND;
  
SWI$XFRREQ: 
  
# 
*     NETXFR REQUIRED.
# 
  
          XFRACN = ACN; 
          DUMXFR;                  # CALL QTFXFR #
          XFRACN = 0; 
          GOTO SWIEND;
  
SWI$XFRIPG: 
  
# 
*     NETXFR IN PROGRESS. 
# 
  
          IF FILESTS GT 0          # IF NETXFR COMPLETE # 
          THEN
            BEGIN 
            XFRERR;                # PROCESS NETXFR STATUS #
            IF NOT FILECE          # IF CONNECTION STILL VIABLE # 
            THEN
              BEGIN 
              FILEFTS = FTS$STPREQ;# STOP REQUIRED #
              END 
  
            END 
  
          GOTO SWIEND;
  
SWI$STPREQ: 
  
# 
*     STOP REQUIRED.
# 
  
          FREENTA;                 # SET NETWORK BUFFER ADDRESS # 
          ACSTORE (NTA$B, CM$STOP, NTLMAX); 
          IF FILECER               # IF ERROR BUT NORMAL STX #
            AND (FILESTX EQ STO$NORMAL) 
          THEN
            BEGIN 
            FILESTX = STO$ABORT;   # SEND ABORTED STX # 
            END 
  
          APSTOR(NTA$B,AT$ST,ATQ$S,AT$STL,STO$STX[FILESTX]);
          FILES4 = TRUE;           # STOP SENT #
          FILEBNO = CM$STOP;       # STOP IN PROGRESS # 
          CMDPUT;                  # SEND COMMAND # 
          GOTO SWIEND;
  
SWI$ETPREQ: 
  
# 
*     ETP COMMAND REQUIRED. 
# 
  
          FREENTA;                 # SET NETWORK BUFFER ADDRESS # 
          ACSTORE (NTA$B, CM$ETP, NTLMAX); # STORE ETP COMMAND #
          FILES60 = TRUE;          # ETP SENT # 
          FILEBNO = CM$ETP;        # ETP IN PROGRESS #
          CMDPUT;                  # SEND ETP COMMAND # 
          GOTO SWIEND;
  
SWI$CMPOK:  
  
# 
*     TRANSFER SUCCESSFUL.
# 
  
          SETPLTA(FILECPD); 
          IF FILELBK               # IF LOOPBACK TRANSFER # 
          THEN
            BEGIN 
            TMPLID = FILESLD;      # QACRESP SWAPPED THEM # 
            END 
  
          ELSE
            BEGIN 
            TMPLID = FILELID;      # SAVE DESTINATION LID # 
            END 
  
          FILEANW = TRUE;          # EVICT FILE # 
          DSPQFIL;
          NOLFN = NOLFN + 1;
          KL$TINF = XCDD(NOLFN);
          IF FILEINU               # IF IN-USE COUNTS INCREMENTED # 
          THEN
            BEGIN 
            FILEINU = FALSE;
            PLTSCINUSE = PLTSCINUSE LAN (LNO (2**FILESEL) );
            SEL$INUCNT[FILESEL] = SEL$INUCNT[FILESEL] - 1;
            KS$UPDATE[KDIS"PID"] = TRUE;
            KS$UPDATE[KDIS"SC"] = TRUE; 
            END 
  
          FILESEL = 0;
          IF NOT FILECE            # IF CONNECTION NOT ENDED #
          THEN
            BEGIN 
            FILELID = TMPLID;      # GET FILES FOR THIS LID ONLY #
            FILEFTS = FTS$CONNFA;  # CONNECTED, NONE ASSIGNED # 
            END 
  
          ELSE
            BEGIN 
            FILEFTS = FTS$CMPCNT; 
            END 
  
          GOTO SWIEND;
  
SWI$CMPCNT: 
  
# 
*     TRANSFER COMPLETE, CONNECTION TERMINATED. 
# 
  
          SETPLTA(FILECPD);        # SET PLT ENTRY ADDRESS #
          IF FILECER               # IF RETRY COUNT NOT EXCEEDED #
            AND (NOT FILEUER) 
            AND (FILERTY NE 0)
            AND (FILELFN NE 0)
          THEN
            BEGIN 
            FILERTY = FILERTY - 1;
            FILEWD3 = 0;           # CLEAR CONNECTION FLAGS # 
            FILEFTS = FTS$ASGUNC;  # RETRY CONNECTION # 
            END 
  
          ELSE
            BEGIN 
            IF FILEUER             # IF USER ERROR #
            THEN
              BEGIN 
              SENDCLF;
              FILEUER = FALSE;
              FILECER = FALSE;
              END 
  
            IF FILECER             # IF ERROR OCCURRED #
            THEN
              BEGIN 
              FILEANW = FALSE;     # REQUEUE FILE # 
              PLTDISERR = TRUE; 
              PLTDISTIME = 0;      # TIMER NEEDS TO BE SET #
              TIMPLRSTRT = 0;      # REEXAMINE DISABLED TIMERS #
              KS$UPDATE[KDIS"PID"] = TRUE;
              END 
  
            IF FILELFN NE 0        # IF FILE STILL EXISTS # 
            THEN
              BEGIN 
              DSPQFIL;             # REQUEUE OR EVICT FILE #
              END 
  
            IF FILEINU             # IF INUSE COUNTS UPDATED #
            THEN
              BEGIN 
              FILEINU = FALSE;
              PLTSCINUSE = PLTSCINUSE LAN (LNO (2**FILESEL) );
              SEL$INUCNT[FILESEL] = SEL$INUCNT[FILESEL] - 1;
              KS$UPDATE[KDIS"PID"] = TRUE;
              KS$UPDATE[KDIS"SC"] = TRUE; 
              END 
  
            IF ACNNO EQ SCHMAXCONS
            THEN
              BEGIN 
              TIMSELSECS = 0;      # RESCHEDULE FILE SELECTION #
              END 
  
            ACNNO = ACNNO - 1;
            IF ACNNO LS 0 
            THEN
              BEGIN 
              ACNNO=0;
              MSGLOG(LOC(EMSGACN),LEMSGACN);
              END 
  
            MSGWFAACN2 = ACNNO + O"33"; 
            RELAFT;                # RELEASE AFT ENTRY #
            SHUTDOWN = SHUTDOWN OR (IDLE AND (ACNNO EQ 0) );
            END 
  
          GOTO SWIEND;
  
SWI$UNCNFA: 
  
# 
*     NOT CONNECTED, NO FILE ASSIGNED.
# 
  
          SETPLTA(FILECPD);        # SET PLT ENTRY ADDRESS #
          IF NOT (IDLE OR PLTIGNORE OR SEL$IGNORE[FILESEL]) 
          THEN
            BEGIN 
            QACCALL(TRUE);
            QACRESP;
            FILEFTS = FTS$UNCWQR; 
            END 
  
          ELSE
            BEGIN 
            FILEFTS = FTS$CMPCNT;  # CLEAN UP AFT # 
            END 
  
          GOTO SWIEND;
  
SWI$CONNFA: 
  
# 
*     CONNECTED, NO FILE ASSIGNED.
# 
  
          SETPLTA(FILECPD);        # SET PLT ENTRY ADDRESS #
          IF (IDLE OR PLTDISLDT OR PLTDISOPR) 
          THEN
            BEGIN 
            FILEFTS = FTS$ETPREQ; 
            END 
  
          ELSE
            BEGIN 
            SELCLASS = FILESEL; 
            GETSELC( ( (PLTSCCOVER LOR PLTSCINUSE LOR PLTSCDISAB) 
                      LXR ( (2**MXSEL) - 1) ), (SCHMAXCONS-ACNNO+1),
                     SELCLASS, SELCLASS, NOSELAVAIL); 
            IF NOSELAVAIL 
            THEN
              BEGIN 
              FILEFTS = FTS$ETPREQ; 
              END 
  
            ELSE
              BEGIN 
              FILESEL = SELCLASS; 
              QACCALL(TRUE);
              QACRESP;
              FILEFTS = FTS$CONWQR; 
              END 
  
            END 
  
          GOTO SWIEND;
  
SWI$UNCWQR: 
  
# 
*     NOT CONNECTED, WAIT ACQUIRE COMPLETE. 
# 
  
          FILEFTS = UQR$NXTST[FILEQAR]; 
          GOTO SWIEND;
  
SWI$CONWQR: 
  
# 
*     CONNECTED, WAIT ACQUIRE COMPLETE. 
# 
  
          FILEFTS = CQR$NXTST[FILEQAR]; 
          GOTO SWIEND;
  
SWIEND: 
  
# 
*     END OF SIMULATED CASE STATEMENT.
# 
  
        END                        # ASLONG # 
  
      IF FILEPTS NE FILEFTS        # IF FILE STATE CHANGED #
      THEN
        BEGIN 
        FILEPTS = FILEFTS;         # UPDATE DISPLAY # 
        KS$UPDATE[KDIS"TRANSFE"] = TRUE;
        END 
  
      END  # SFILI #
    TERM
