/*
 * File system functions are implemented here.
 *
*/

#include <windows.h>
#include <limits.h>
#include <sys\types.h>

#include <unixapi.h>

/*
 * Since there isn't an "open directory" concept in WIN32, fabricate one
 * by searching for a file name of "*" in the given directory. Then use
 * the FIND_DATA structure from then on to "read directory", "rewind" ect.
 *
 * A pointer to FIND_DATA is carried around in the "Index" field of the returned
 * DIR structure.
 *
*/

DIR *opendir (Dirname)
    char *Dirname ;
{
    DIR *DirStruc ;              /* Has a pointer to lpffd                   */
    WIN32_FIND_DATA lpffd;	/* Keeps information about the directory    */
    HANDLE  FileHandle ;
    char *SavedDirname ;
    register int i ;
    
    if ( ((DirStruc = malloc(sizeof(DIR))) == NULL) ||
                        ((SavedDirname = malloc((strlen(Dirname) + 8))) == NULL) )
    {
        DBGPRINT ("opendir: Insufficent memory\n" ) ;
        return(-1);
    }

    sprintf(SavedDirname,"%s\\*.*", Dirname) ;
    /* This is not a great idea, but is expedient */
    DirStruc->Directory =  (int) SavedDirname ;

    if ( (FileHandle = FindFirstFile(SavedDirname, &lpffd)) ==  INVALID_HANDLE_VALUE )
    {
        DBGPRINT ("opendir: Couldn't get first file name in: \n%s\n GetLastError = %x\n", SavedDirname, GetLastError() ) ;
        free(SavedDirname) ;
        free(DirStruc) ;
        return(NULL);
    }
    
    /* jac BUGBUG - the first file (.) is forgotten. Can I ignore it? */
    DirStruc->Index = (unsigned long) FileHandle ;
    return(DirStruc) ;

}

int closedir (DirStruc)
    DIR *DirStruc ;
{
     HANDLE  FileHandle ;
     char *SavedDirname ;

     FileHandle = (HANDLE) DirStruc->Index ;
    SavedDirname = (char *) DirStruc->Directory ;
    free(SavedDirname) ;
     free(DirStruc) ;

     if (FindClose(FileHandle) == FALSE)
     {
        DBGPRINT ("closedir: Couldn't close the directory. GetLastError = %x\n", GetLastError() ) ;
        return(-1);
     }
     return(0);
}

struct dirent *readdir(DirStruc)
    DIR *DirStruc ;
{
    WIN32_FIND_DATA lpffd;	/* Has information about the directory    */
    HANDLE  FileHandle ;
    struct dirent *FileName ;

    FileHandle = (HANDLE) DirStruc->Index ;
    
    if ( FindNextFile(FileHandle, &lpffd) ==  FALSE)
    {
        if (GetLastError() != ERROR_NO_MORE_FILES)
            DBGPRINT ("readdir: Couldn't get next file name. GetLastError = %x\n", GetLastError() ) ;
        return(NULL);
    }
    strcpy(DirStruc->Dirent.d_name, lpffd.cFileName) ;
    return(DirStruc->Dirent.d_name);
}

VOID rewinddir (DirStruc)
    DIR *DirStruc ;
{
     HANDLE  FileHandle ;
     WIN32_FIND_DATA lpffd;
    
     FileHandle = (HANDLE) DirStruc->Index ;

     if (FindClose(FileHandle) == FALSE)
     {
        DBGPRINT ("rewinddir: Couldn't close the directory. GetLastError = %x\n", GetLastError() ) ;
        /* to free or not to free DirStruc - that is the question */
        return(-1);
     }

    if ( (FileHandle = FindFirstFile((LPSTR)DirStruc->Directory, &lpffd)) ==  INVALID_HANDLE_VALUE )
    {
        DBGPRINT ("opendir: Couldn't get first file name. GetLastError = %x\n", GetLastError() ) ;
        return(-1);
    }
    
    /* jac BUGBUG - Again, the first file (.) is lost... Can I ignore it? */

    DirStruc->Index = (unsigned long) FileHandle ;
     return(0);
}    
