/* scandir.c
 * Given the name of a directory, return a NULL-terminated array of the names
 * of the files in that directory.
 *
 * Peter Webb, Summer 1990.
 */

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

#include "reformat.h"
#include "extern.h"
#include "types.h"
#include "error.h"

ErrorCode ScanDir(dir, array, gethidden)
  char *dir;
  char ***array;
  int gethidden;
{
  DIR *dp;
  struct dirent *entry;
  StrListPtr list = NULL, cur;
  int i, len = 0;
  ErrorCode error;

/* Check parameters */

  if (dir == NULL || array == NULL) return(err_msg(ScanDirectory, NullPtr));

/* If dir begins with a '/', assume that it is a full pathname.  Otherwise
 * assume that it is relative to the current directory.
 */

  dp = opendir(dir);
  if (dp == NULL) return(err_msg(ScanDirectory, CannotOpenFile));

/* Read each of the entries in the directory file.  If a filename begins
 * with a '.', it is included or skipped depending on the value of the
 * gethidden variable.  Always include the '..' directory.  Add to the 
 * tail of the list, so that the '.' files appear first.
 */

  while ((entry = readdir(dp)) != NULL)
    {
      if (*(entry->d_name) == '.' && ( (gethidden == FALSE &&
					strcmp(entry->d_name, "..") != 0)
				      || strlen(entry->d_name) == 1))
	continue;
      if ((error = AppendType(entry->d_name, ScratchBuf)) != AllOk)
      return(error);
      if (list == NULL)
	list = cur = NewStrListElt(ScratchBuf);
      else
	{
	  NEXT_STR(cur) = NewStrListElt(ScratchBuf);
	  cur = NEXT_STR(cur);
	}
      len++;
    }

/* Now, a list of the strings in the file has been constructed.  Copy it
 * into an array.
 */

  *array = (char **)malloc(sizeof(char *) * (len+1));
  cur = list;
  for (i=0; i<len; i++)
    {
      *((*array)+i) = strsave(LIST_STR(cur));
      cur = NEXT_STR(cur);
    }
  *((*array)+i) = NULL;

/* Free the list */

  FreeStrList(list);

  return(AllOk);
}
