CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      SUBROUTINE FIND_QAC(QAC_OFFSET, PACKET_LENGTH, HDR_LEN, FILENAME) 
C+
C
C FUNCTIONAL DESCRIPTION:
C
C     This routine opens an input file a second time, skips the header, then
C     reads through it until it reaches the Quality and Accounting information.
C
C FORMAL ARGUMENTS:
C
C     QAC_OFFSET:
C	INT	  I	The byte offset into the file specified in FILENAME
C			of the Quality Accounting Capsule area.
C
C     PACKET_LENGTH:
C	INT	  I	The length of packets in the specified file.  This
C			argument is longer used.
C
C     HDR_LEN:
C	INT	  I	The length of the specified file's header.
C
C     FILENAME:
C	CHAR(*)	  I	The name of the filename to be opened and read.
C
C INTERFACE:
C
!	INTERFACE
!	  SUBROUTINE FIND_QAC(QAC_OFFSET, PACKET_LENGTH, HDR_LEN, FILENAME) 
!	    INTEGER, INTENT(IN) :: QAC_OFFSET, PACKET_LENGTH, HDR_LEN
!	    CHARACTER(LEN=*), INTENT(IN) :: FILENAME
!	  END SUBROUTINE FIND_QAC
!	END INTERFACE
C
C IMPLICIT INPUTS:
C
C     None
C
C IMPLICIT OUTPUTS:
C
C     Variable LEN_QAC (INTEGER*4) in common block HEADER_INFO will contain,
C     upon return, the number of entries in the QAC list.
C
C SIDE EFFECTS:
C
C     Data stream 2 will be closed, then reopened to FILENAME and positioned
C     before the first byte of the first QAC entry.
C
C     If there is a read error while skipping data packets the file will be
C     closed and LEN_QAC will contain a zero.
C
C     If there is a read error while fetching the QAC list length a STOP 30
C     will be executed.
C
C COMMON BLOCKS:
C
C     HEADER_INFO	contains the variable LEN_QAC
C
C INCLUDE FILES:
C
C     None
C
C DESIGN:
C
C     Make use of POSITION_STREAM to avoid having to read entire file to get
C     to QAC list.
C
C     close stream 2 in case it was left hanging open (never closed by caller)
C     open data file to stream 2
C     if there is no QAC (QAC_OFFSET is zero) set LEN_QAC to zero and return
C      immediately 
C     position file just before QAC list (offset QAC_OFFSET + HDR_LEN)
C     read 4 bytes from input file
C     assemble bytes into proper order to get # bytes in QAC list
C     divide by 14 (length of a QAC) to get QAC list length, save in LEN_QAC
C
C CREATED:
C
C     20-FEB-1996    John Paquette
C
C This version:   2.0   17-MAR-2000
C
C DEVELOPMENT HISTORY:
C 
C  Author       Date		Description of Change 
C  --------	-----------	--------------------- 
C  J. PAQUETTE  20-FEB-1996     Created
C  J. PAQUETTE  22-FEB-1996     Read Header; get length in # of items, not bytes
C  J. PAQUETTE   5-MAR-1996     If QAC_OFFSET is 0, set LEN_QAC to 0 and RETURN
C  J. PAQUETTE  16-APR-1996     Handle case when file has not been completely
C				transmitted
C  L. Bleau	19-APR-1999	added IMPLICIT NONE, comments
C  L. Bleau	 1-JUL-1999	if we can't read to start of qac list, close
C				channel; to bulletproof even further, do a
C				preemptive close on 2 as we enter, since this
C				routine is to be called only once per file
C  L. Bleau	 3-NOV-1999	added comments
C  L. Bleau	17-MAR-2000	recode to use POSITION_STREAM instead of reads;
C				change messages; change TYPE to PRINT; remove
C				STOP 30 if error reading QAC list length and
C				treat as though list zero length
C-
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CDEC$ IDENT '2.0'
      IMPLICIT NONE
      INTEGER, INTENT(IN) :: QAC_OFFSET, PACKET_LENGTH, HDR_LEN
      CHARACTER(LEN=*), INTENT(IN) :: FILENAME
C
      INTEGER*4 NBYTES, STATUS
      BYTE BUFFER(4)
      INTEGER*4 LEN_QAC
      COMMON /HEADER_INFO/ LEN_QAC
C
C Open the file again, for QAC access
C Close it first, though, in case some other routine left it hanging open
C
      CALL CLOSE_STREAM(2)
      CALL OPEN_STREAM_IN(2, FILENAME, STATUS)
      IF (STATUS .NE. 1) PRINT *,' FIND_QAC: Error in OPEN_STREAM_IN, file=',FILENAME
C
C If QAC_OFFSET is 0, then there is no QAC for this file, so set LEN_QAC to 0
C and RETURN 
C
      IF(QAC_OFFSET .EQ. 0)THEN
        LEN_QAC = 0
        RETURN
      ENDIF
C
      CALL POSITION_STREAM( 2, QAC_OFFSET + HDR_LEN, STATUS )
      IF (STATUS .NE. 1) THEN
        PRINT 150
150     FORMAT(' Unable to position at QAC list, file is probably truncated',/,
	1      ' Treating as invalid file; closing')
        LEN_QAC = 0
	CALL CLOSE_STREAM(2)
        RETURN
      ENDIF
C
C Now find the length of the QAC list
C
      CALL READ_STREAM( 2, BUFFER, 4, NBYTES )
C
C Error trapping
C
      IF (NBYTES .NE. 4) THEN 
        PRINT 250
250     FORMAT(' Unable to read QAC Length field, file is probably truncated',/,
	1      ' Treating as invalid file; closing')
        LEN_QAC = 0
	CALL CLOSE_STREAM(2)
        RETURN
      ENDIF
C
C Find length in bytes
C
      LEN_QAC = ISHFT(ZEXT(BUFFER(1)), 24) + ISHFT(ZEXT(BUFFER(2)), 16) + 
     &		ISHFT(ZEXT(BUFFER(3)), 8) + ZEXT(BUFFER(4))
C
C Divide by 14 bytes/QAC list item to get # of items
C
      LEN_QAC = LEN_QAC/14
C
C Return.
C
      RETURN
      END
