/*
 *      $Filename: ScanDir.c $
 *      $Revision: 1.1 $
 *      $Date: 1994/04/06 14:47:13 $
 *
 *      Copyright (C) 1993 by Peter Simons <simons@peti.GUN.de>
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License as
 *      published by the Free Software Foundation; either version 2 of
 *      the License, or (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *      General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *      $Id: ScanDir.c,v 1.1 1994/04/06 14:47:13 simons Exp simons $
 *
 */

/************************************* includes ***********/
#include <stdlib.h>
#include <string.h>
#include <dos/dos.h>
#include <dos/exall.h>
#include <proto/dos.h>

/************************************* defines ************/
char **ScanDir(char *, char *);

/************************************* global variables ***/
static const char __RCSId[] = "$Id: ScanDir.c,v 1.1 1994/04/06 14:47:13 simons Exp simons $";

static char **namearray;
static int namepointer;

/************************************* subroutines ********/
int InitDirScan(char *pattern)
{
        namepointer = 0;

        if (namearray = ScanDir(NULL, pattern))
                return TRUE;
        else
                return FALSE;
}

char *ScanNextFile(void)
{
        if (namearray[namepointer])
                return namearray[namepointer++];
        else
                return NULL;
}

void EndDirScan(void)
{
        int i;

        if (!namearray)
                return;

        for (i = 0; namearray[i]; i++)
                free(namearray[i]);
        free(namearray);

        namearray = NULL;
}

 /*
  * ScanDir() reads all entries in the specified directory and returns those
  * matching the provided pattern. A pattern of NULL means that all files
  * are returned. If the directory-parameter is NULL, the current directory
  * will be scanned.
  *
  * PORT NOTE: Sorry, this routine is very AmigaOS specific and will not
  *            work on other platforms. However, it should be pretty easy
  *            to re-write.
  */

char **ScanDir(char *directory, char *pattern)
{
        struct ExAllControl *eac;
        struct ExAllData *ead;
        BPTR dir_lock;
        char **filenames = NULL, *parsed_pattern = NULL, *buffer;
        int i = 0, cont;

        if (!(buffer = malloc(10 * 1024)))
                return NULL;

        if (!(filenames = malloc(sizeof(char *) * 4096))) {
                free(buffer);
                return NULL;
        }

        if (pattern)
                if (parsed_pattern = malloc(strlen(pattern) + 256)) {
                        if (ParsePatternNoCase(pattern, parsed_pattern, strlen(pattern) + 256) == -1L) {
                                free(buffer);
                                free(filenames);
                                free(parsed_pattern);
                                return NULL;
                        }
                }
                else
                        return NULL;

        if (dir_lock = Lock(directory ? directory : "", ACCESS_READ)) {
                if (eac = AllocDosObject(DOS_EXALLCONTROL, NULL)) {
                        if (parsed_pattern)
                                eac->eac_MatchString = parsed_pattern;

                        do {
                                cont = ExAll(dir_lock, (struct ExAllData *) buffer, 10 * 1024, ED_NAME, eac);
                                ead = (struct ExAllData *) buffer;
                                if (eac->eac_Entries > 0) {
                                        do {
                                                filenames[i++] = strdup(ead->ed_Name);
                                                ead = ead->ed_Next;
                                        } while (ead);
                                }
                        } while (cont);
                        filenames[i] = NULL;

                        FreeDosObject(DOS_EXALLCONTROL, eac);
                }
                UnLock(dir_lock);
        }

        if (parsed_pattern)
                free(parsed_pattern);
        free(buffer);
        if (*filenames)
                return filenames;
        else {
                free(filenames);
                return NULL;
        }
}
