int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
{
    WDIR   dir;
    word32 handle[2] = {0, 0};
    word32 sz;
    word32 idx = 0;
    int count = 0;
    int ret;
    WS_SFTPNAME* name = NULL;
    WS_SFTPNAME* list = NULL;
    word32 outSz = 0;
    DIR_HANDLE* cur = dirList;
    char* dirName = NULL;
    byte* out;

    if (ssh == NULL) {
        return WS_BAD_ARGUMENT;
    }

    WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READDIR");

    #ifdef USE_WINDOWS_API
        dir = INVALID_HANDLE_VALUE;
    #endif

    /* get directory handle */
    ato32(data + idx, &sz); idx += UINT32_SZ;
    if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
        return WS_BUFFER_E;
    }

    if (sz != (sizeof(word32) * 2)) {
        WLOG(WS_LOG_SFTP, "Unexpected handle size");
        return WS_FATAL_ERROR;
    }
    ato32(data + idx, &handle[0]);
    ato32(data + idx + UINT32_SZ, &handle[1]);

    /* find DIR given handle */
    while (cur != NULL) {
        if (cur->id[0] == handle[0] && cur->id[1] == handle[1]) {
            dir = cur->dir;
            dirName = cur->dirName;
            break;
        }
        cur = cur->next;
    }
    if (cur == NULL) {
        /* unable to find handle */
        WLOG(WS_LOG_SFTP, "Unable to find handle");
        return WS_FATAL_ERROR;
    }

    /* get directory information */
    outSz += UINT32_SZ + WOLFSSH_SFTP_HEADER; /* hold header+number of files */
    if (!cur->isEof) {
        do {
            name = wolfSSH_SFTPNAME_new(ssh->ctx->heap);
            ret = wolfSSH_SFTPNAME_readdir(ssh, &dir, name, dirName);
            if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) {
                count++;
                outSz += name->fSz + name->lSz + (UINT32_SZ * 2);
                outSz += SFTP_AtributesSz(ssh, &name->atrb);
                name->next = list;
                list = name;
            }
            else {
                wolfSSH_SFTPNAME_free(name);
            }
        } while (ret == WS_SUCCESS);
    }

    if (list == NULL || cur->isEof) {
        if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_EOF, reqId,
                "No More Files In Directory", "English", NULL, &outSz)
                != WS_SIZE_ONLY) {
            return WS_FATAL_ERROR;
        }
        out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
        if (out == NULL) {
            return WS_MEMORY_E;
        }
        if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_EOF, reqId,
                "No More Files In Directory", "English", out, &outSz)
                != WS_SUCCESS) {
            WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
            return WS_FATAL_ERROR;
        }

        /* set send out buffer, "out" is taken by ssh  */
        wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
        return WS_SUCCESS;
    }

    /* if next state would cause an error then set EOF flag for when called
     * again */
    cur->isEof = 1;
    out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
    if (out == NULL) {
        return WS_MEMORY_E;
    }

    if (wolfSSH_SFTP_SendName(ssh, list, count, out, &outSz, reqId)
            != WS_SUCCESS) {
        WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
        return WS_FATAL_ERROR;
    }
    wolfSSH_SFTPNAME_list_free(list);

    /* set send out buffer, "out" is taken by ssh  */
    wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
    return WS_SUCCESS;
}
int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
{
    WDIR   dir;
    word32 handle[2] = {0, 0};
    word32 sz;
    word32 idx = 0;
    int count = 0;
    int ret;
    WS_SFTPNAME* name = NULL;
    WS_SFTPNAME* list = NULL;
    word32 outSz = 0;
    DIR_HANDLE* cur = dirList;
    char* dirName = NULL;
    byte* out;

    if (ssh == NULL) {
        return WS_BAD_ARGUMENT;
    }

    WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READDIR");

    #ifdef USE_WINDOWS_API
        dir = INVALID_HANDLE_VALUE;
    #endif

     
    ato32(data + idx, &sz); idx += UINT32_SZ;
    if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
        return WS_BUFFER_E;
    }

    if (sz != (sizeof(word32) * 2)) {
        WLOG(WS_LOG_SFTP, "Unexpected handle size");
        return WS_FATAL_ERROR;
    }
    ato32(data + idx, &handle[0]);
    ato32(data + idx + UINT32_SZ, &handle[1]);

     
    while (cur != NULL) {
        if (cur->id[0] == handle[0] && cur->id[1] == handle[1]) {
            dir = cur->dir;
            dirName = cur->dirName;
            break;
        }
        cur = cur->next;
    }
    if (cur == NULL) {
         
        WLOG(WS_LOG_SFTP, "Unable to find handle");
        return WS_FATAL_ERROR;
    }

     
    outSz += UINT32_SZ + WOLFSSH_SFTP_HEADER;  
    if (!cur->isEof) {
        do {
            name = wolfSSH_SFTPNAME_new(ssh->ctx->heap);
            ret = wolfSSH_SFTPNAME_readdir(ssh, &dir, name, dirName);
            if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) {
                count++;
                outSz += name->fSz + name->lSz + (UINT32_SZ * 2);
                outSz += SFTP_AtributesSz(ssh, &name->atrb);
                name->next = list;
                list = name;
            }
            else {
                wolfSSH_SFTPNAME_free(name);
            }
        } while (ret == WS_SUCCESS);
    }

    if (list == NULL || cur->isEof) {
        if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_EOF, reqId,
                "No More Files In Directory", "English", NULL, &outSz)
                != WS_SIZE_ONLY) {
            return WS_FATAL_ERROR;
        }
        out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
        if (out == NULL) {
            return WS_MEMORY_E;
        }
        if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_EOF, reqId,
                "No More Files In Directory", "English", out, &outSz)
                != WS_SUCCESS) {
            WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
            return WS_FATAL_ERROR;
        }

         
        wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
        return WS_SUCCESS;
    }

     
    cur->isEof = 1;
    out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
    if (out == NULL) {
        return WS_MEMORY_E;
    }

    if (wolfSSH_SFTP_SendName(ssh, list, count, out, &outSz, reqId)
            != WS_SUCCESS) {
        WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
        return WS_FATAL_ERROR;
    }
    wolfSSH_SFTPNAME_list_free(list);

     
    wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
    return WS_SUCCESS;
}