int ff_findnext()

in ff_stdio.c [1341:1511]


int ff_findnext( FF_FindData_t * pxFindData )
{
    FF_Error_t xError;

    #if ( ffconfigTIME_SUPPORT != 0 )
        BaseType_t xSetTime = 0;
    #endif /* ffconfigTIME_SUPPORT */

    if( pxFindData->xDirectoryHandler.u.bits.bIsValid == pdFALSE )
    {
        xError = ( FF_Error_t ) ( FF_ERR_DIR_INVALID_PARAMETER | FF_FINDNEXT );
        FF_PRINTF( "ff_findnext: xDirectoryHandler not valid\n" );
    }
    else
    {
        xError = ( FF_Error_t ) ( FF_ERR_DIR_END_OF_DIR | FF_FINDNEXT );

        if( pxFindData->xDirectoryHandler.pxManager != NULL )
        {
            if( pxFindData->xDirectoryHandler.u.bits.bFirstCalled == pdFALSE )
            {
                pxFindData->xDirectoryHandler.u.bits.bFirstCalled = pdTRUE;
                xError = FF_FindFirst( pxFindData->xDirectoryHandler.pxManager, &( pxFindData->xDirectoryEntry ),
                                       pxFindData->xDirectoryHandler.pcPath );
            }
            else if( pxFindData->xDirectoryHandler.u.bits.bEndOfDir == pdFALSE )
            {
                xError = FF_FindNext( pxFindData->xDirectoryHandler.pxManager, &( pxFindData->xDirectoryEntry ) );
            }

            if( FF_GETERROR( xError ) == FF_ERR_DIR_END_OF_DIR )
            {
                /* Stop further calls to FF_FindNext(). */
                pxFindData->xDirectoryHandler.u.bits.bEndOfDir = pdTRUE;
            }

            #if ( ffconfigDEV_SUPPORT != 0 )
                {
                    if( pxFindData->bIsDeviceDir != pdFALSE )
                    {
                        FF_Device_GetDirEnt( pxFindData->xDirectoryHandler.pcPath, &( pxFindData->xDirectoryEntry ) );
                    }
                }
            #endif
        }

        if( FF_isERR( xError ) == pdFALSE )
        {
            /* If an entry is found, see if it is a dot-entry.  Dot-entries
             * ("." and "..") need a time-stamp. */
            if( pxFindData->xDirectoryEntry.pcFileName[ 0 ] == '.' )
            {
                if( ( pxFindData->xDirectoryEntry.pcFileName[ 1 ] == '.' ) &&
                    ( pxFindData->xDirectoryEntry.pcFileName[ 2 ] == '\0' ) )
                {
                    /* This is a directory "..". Clear the flag for DOT_2. */
                    pxFindData->xDirectoryHandler.u.bits.bAddDotEntries &= stdioDIR_ENTRY_DOT_1;
                    #if ( ffconfigTIME_SUPPORT != 0 )
                        {
                            /* The dot-entries do not have a proper time stamp, add
                             * it here. */
                            xSetTime = pdTRUE;
                        }
                    #endif /* ffconfigTIME_SUPPORT */
                }
                else if( pxFindData->xDirectoryEntry.pcFileName[ 1 ] == '\0' )
                {
                    /* This is a directory ".". Clear the flag for DOT_1. */
                    pxFindData->xDirectoryHandler.u.bits.bAddDotEntries &= stdioDIR_ENTRY_DOT_2;
                    #if ( ffconfigTIME_SUPPORT != 0 )
                        {
                            xSetTime = pdTRUE;
                        }
                    #endif /* ffconfigTIME_SUPPORT */
                }
            }
        }

        if( FF_GETERROR( xError ) == FF_ERR_DIR_END_OF_DIR )
        {
            /* No more physical entries were found.  Now see if there are FS
             * entries or dot-entries to be added: */
            while( ( pxFindData->xDirectoryHandler.xFSIndex > 0 ) ||
                   ( pxFindData->xDirectoryHandler.u.bits.bAddDotEntries != 0 ) )
            {
                if( pxFindData->xDirectoryHandler.xFSIndex > 0 )
                {
                    FF_SubSystem_t xSubSystem;
                    int found;

                    pxFindData->xDirectoryHandler.xFSIndex--;
                    found = FF_FS_Get( pxFindData->xDirectoryHandler.xFSIndex, &xSubSystem );

                    if( ( found == pdFALSE ) || ( xSubSystem.pcPath[ 1 ] == '\0' ) )
                    {
                        continue;
                    }

                    snprintf( pxFindData->xDirectoryEntry.pcFileName, sizeof( pxFindData->xDirectoryEntry.pcFileName ), "%s", xSubSystem.pcPath + 1 );

                    if( xSubSystem.pxManager != NULL )
                    {
                        pxFindData->xDirectoryEntry.ulObjectCluster = xSubSystem.pxManager->xPartition.ulRootDirCluster;
                    }
                    else
                    {
                        pxFindData->xDirectoryEntry.ulObjectCluster = 0;
                    }
                }
                else if( ( pxFindData->xDirectoryHandler.u.bits.bAddDotEntries & stdioDIR_ENTRY_DOT_2 ) != 0 )
                {
                    strcpy( pxFindData->xDirectoryEntry.pcFileName, ".." );

                    /* Clear DOT_2 (keep DOT_1). */
                    pxFindData->xDirectoryHandler.u.bits.bAddDotEntries &= stdioDIR_ENTRY_DOT_1;
                }
                else
                {
                    strcpy( pxFindData->xDirectoryEntry.pcFileName, "." );
                    pxFindData->xDirectoryHandler.u.bits.bAddDotEntries = 0;
                }

                pxFindData->xDirectoryEntry.ucAttrib = FF_FAT_ATTR_READONLY | FF_FAT_ATTR_DIR;
                pxFindData->xDirectoryEntry.ulFileSize = stdioDOT_ENTRY_FILE_SIZE;
                #if ( ffconfigTIME_SUPPORT != 0 )
                    {
                        xSetTime = pdTRUE;
                    }
                #endif /* ffconfigTIME_SUPPORT */

                xError = FF_ERR_NONE;
                break;
            }
        }

        #if ( ffconfigTIME_SUPPORT != 0 )
            {
                if( xSetTime != pdFALSE )
                {
                    FF_TimeStruct_t xTimeStruct;
                    time_t xSeconds;

                    xSeconds = FreeRTOS_time( NULL );
                    FreeRTOS_gmtime_r( &xSeconds, &xTimeStruct );

                    pxFindData->xDirectoryEntry.xCreateTime.Year = ( uint16_t ) ( xTimeStruct.tm_year + 1900 ); /* Year (e.g. 2009). */
                    pxFindData->xDirectoryEntry.xCreateTime.Month = ( uint16_t ) ( xTimeStruct.tm_mon + 1 );    /* Month (e.g. 1 = Jan, 12 = Dec). */
                    pxFindData->xDirectoryEntry.xCreateTime.Day = ( uint16_t ) xTimeStruct.tm_mday;             /* Day (1 - 31). */
                    pxFindData->xDirectoryEntry.xCreateTime.Hour = ( uint16_t ) xTimeStruct.tm_hour;            /* Hour (0 - 23). */
                    pxFindData->xDirectoryEntry.xCreateTime.Minute = ( uint16_t ) xTimeStruct.tm_min;           /* Min (0 - 59). */
                    pxFindData->xDirectoryEntry.xCreateTime.Second = ( uint16_t ) xTimeStruct.tm_sec;           /* Second (0 - 59). */
                    pxFindData->xDirectoryEntry.xModifiedTime = pxFindData->xDirectoryEntry.xCreateTime;        /* Date and Time Modified. */
                    pxFindData->xDirectoryEntry.xAccessedTime = pxFindData->xDirectoryEntry.xCreateTime;        /* Date of Last Access. */
                }
            }
        #endif /* ffconfigTIME_SUPPORT */

        if( FF_GETERROR( xError ) == FF_ERR_DIR_END_OF_DIR )
        {
            /* FF_ERR_DIR_END_OF_DIR will be returned. */
            pxFindData->xDirectoryHandler.u.bits.bIsValid = 0;
        }

        pxFindData->ucAttributes = pxFindData->xDirectoryEntry.ucAttrib;
        pxFindData->ulFileSize = pxFindData->xDirectoryEntry.ulFileSize;
    }

    stdioSET_ERRNO( prvFFErrorToErrno( xError ) );

    return xError;
}