/*static char *SCCSID = "@(#)readea.c   6.2 92/01/31";*/
#define BSWAP0 BSWAP0

#define INCL_ERRORS
#include <os2.h>
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "ea.h"
#include "fnode.h"
#include "volume.h"
#include "tables.h"
#include "pbmacros.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "log.h"                                                 // @76193

#include "pr_debug.h"
#include "pr_ea.h"
#include "pr_cache.h"
#include "pr_misc.h"
#include "pr_read.h"


/*
 ***    ReadEA - Read Next EA
 *
 *      ReadEA reads the next extended attribute from the file.
 *      If the EA would be greater than the maximum then it's not
 *      read, and the seek pointer into the source is left
 *      indeterminate.
 *
 *      Note that the AUXHAND structure may point to a held buffer.
 *      This buffer may be left held if there is no error.  If the
 *      AUXHAND's pbuf is non-null, then it's a buffer header and
 *      it is held--the caller is responsible for cleaning this
 *      up.  (If an error is encountered, the buffer will be
 *      unheld and cleared.)
 *
 *      ENTRY   pah (esi) = AUXHAND address
 *              pbTarget (edi) = memory address
 *              *pusEASize (ecx) = maximum EA size - offset to FEA.szName field
 *
 *      EXIT    Returns READEA_ERROR if not enough room or hard
 *                                              error encountered.
 *                      READEA_NO_MORE if no more
 *                      READEA_NO_ERROR if got one
 *
 *              *pusEASize (ecx) = length in memory
 *
 *      USES    All but ESI, EDI, EBP
 *
 *      HISTORY
 *  @76193  23-Nov-1993 by D.Azzarito - Change holds for LOG support
 *          19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *              - Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

USHORT
ReadEA (pah, pb, pusEASize, pfrm)
PAUXHAND pah;
PBYTE pb;
PUSHORT pusEASize;      /* max ea size - offset of FEA_szName */
PFRAME  pfrm;
{
        PBYTE pbSrc;
        PBYTE pbDest;
        USHORT us;
        USHORT erc;

        pbSrc = pah -> pbDataBuf;
        pbDest = pb;

        /* read the first part of the next one */
        us = FEA_NAME_OFFSET;
        CHECKSWAP(&swapBSWAP0);
        erc = RdAH(pah, &us, &pbSrc, &pbDest, pfrm);

        if (erc != NO_ERROR) {

            /*  error encountered in auxillary read.  */
#ifdef DEBUG
            dprintf ("ReadEA: RdAH returned an error (%d)\n", erc);
#endif
            if (pah->pbuf != NULL){
                DecrHoldsBUF(pah->pbuf);  // @76193
                pah->pbuf = NULL;
            }
            return(READEA_ERROR);
        }

        if (us < FEA_NAME_OFFSET) {

#ifdef DEBUG
                if( us != 0 ) {
                    /*
                     * Flag the garbage at the end of the file!
                     *  We must have gotten out of sync with the
                     *  EA list in the file and read EA data as an EA Header!
                     */
                    dprintf( __FILE__": Garbage detected at end of EA file\n" );
                    Int3();
                    /* KLUDGE!!!
                     * Ignore garbage if tester decides to continue
                     */
                    pah->cbFile = 0;
                }
#endif


                /* no more EAs to read. */
                return (READEA_NO_MORE);
        }
        *pusEASize -= us;

        /*
         * We got a header.  Read the variable length fields.
         *
         * pbSrc now points to the FEA.szName field.
         *
         */
        if ((us = (((PFEA) pb)->cbName + 1 + ((PFEA) pb)->cbValue)) >
                                        *pusEASize) {
/* rea99: */
                /* return not enough room */

                if (pah->pbuf != NULL){
                    DecrHoldsBUF(pah->pbuf);  // @76193
                    pah->pbuf = NULL;
                }
                return (READEA_ERROR);
        }

        CHECKSWAP(&swapBSWAP0);
        if (RdAH(pah, &us, &pbSrc, &pbDest, pfrm) != NO_ERROR) {

            /*  error encountered in auxillary read.  */

#ifdef DEBUG
            dprintf ("ReadEA: RdAH returned an error (%d)\n", erc);
#endif
            if (pah->pbuf != NULL){
                DecrHoldsBUF(pah->pbuf);  // @76193
                pah->pbuf = NULL;
            }
            return(READEA_ERROR);
        }

#ifdef DEBUG
        /*
         * Check to make sure we could get all of the EA we just read
         */
        if( us != ( ((PFEA)pb)->cbName + 1 + ((PFEA)pb)->cbValue ) ) {
            dprintf( __FILE__": Could not read all of Last EA\n" );
            Int3();
        }
#endif

/* rea5: */
        pah -> pbDataBuf = pbSrc;

        /* return got one */
        *pusEASize = pbDest - pb;
        return (READEA_NO_ERROR);
}
