Logo Search packages:      
Sourcecode: jove version File versions

scandir.c

/**************************************************************************
 * This program is Copyright (C) 1986-2002 by Jonathan Payne.  JOVE is    *
 * provided by Jonathan and Jovehacks without charge and without          *
 * warranty.  You may copy, modify, and/or distribute JOVE, provided that *
 * this notice is included in all the source files and documentation.     *
 **************************************************************************/

/*
 * This file is used as a compiled module by Jove and also included as
 * source in recover.c
 */
#ifndef TUNED
# include "jove.h"
#endif
#include "scandir.h"

#ifdef F_COMPLETION     /* the body is the rest of this file */

#ifdef UNIX

# include <sys/stat.h>

# if defined(M_XENIX) && !defined(M_UNIX)
   /* XENIX, but not SCO UNIX, which pretends to be XENIX! */
#  include <sys/ndir.h>
#  ifndef dirent
#   define dirent direct
#  endif
# endif

# ifdef BSD_DIR
#  include <sys/dir.h>
#  ifndef dirent
#   define dirent direct
#  endif
# endif

/* default to dirent.h */
# if !defined(dirent) && !defined(DIRENT_EMULATE)
#  include <dirent.h>
# endif

# ifdef DIRENT_EMULATE

typedef struct {
      int   d_fd;       /* File descriptor for this directory */
} DIR;

private int
closedir(dp)
DIR   *dp;
{
      (void) close(dp->d_fd);
      free((UnivPtr) dp);
      return 0;   /* don't know how to fail */
}

private DIR *
opendir(dir)
const char  *dir;
{
      int   fd;

      if ((fd = open(dir, O_RDONLY | O_BINARY)) != -1) {
            struct stat stbuf;

            if ((fstat(fd, &stbuf) != -1)
            && (stbuf.st_mode & S_IFMT) == S_IFDIR)
            {
                  /* Success! */
                  DIR   *dp = (DIR *) emalloc(sizeof *dp);

                  dp->d_fd = fd;
                  return dp;
            }
            /* this isn't a directory! */
            (void) close(fd);
      }
      return NULL;
}

private dirent *
readdir(dp)
DIR   *dp;
{
      static dirent     dir;

      do {
            if (read(dp->d_fd, (UnivPtr) &dir, sizeof dir) != sizeof dir)
                  return NULL;
      } while (dir.d_ino == 0);

      return &dir;
}

#endif /* DIRENT_EMULATE */

/* jscandir returns the number of entries or -1 if the directory cannot
 * be opened or malloc fails.
 */
int
jscandir(dir, nmptr, qualify, sorter)
const char  *dir;
char  ***nmptr;
bool  (*qualify) ptrproto((char *));
int   (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
{
      DIR   *dirp;
      struct  dirent    *entry;
      char  **ourarray;
      unsigned int      nalloc = 10,
                  nentries = 0;

      if ((dirp = opendir(dir)) == NULL)
            return -1;

      ourarray = (char **) emalloc(nalloc * sizeof (char *));
      while ((entry = readdir(dirp)) != NULL) {
            if (qualify != NULL && !(*qualify)(entry->d_name))
                  continue;

            /* note: test ensures one space left in ourarray for NULL */
            if (nentries+1 == nalloc)
                  ourarray = (char **) erealloc((UnivPtr) ourarray, (nalloc += 10) * sizeof (char *));
            ourarray[nentries++] = copystr(entry->d_name);
      }
      closedir(dirp);
      ourarray[nentries] = NULL;

      if (sorter != NULL)
            qsort((UnivPtr) ourarray, nentries, sizeof (char **), sorter);
      *nmptr = ourarray;

      return nentries;
}

#endif /* UNIX */

#ifdef MSFILESYSTEM
/* NOTE: MatchDir affects any call to jscandir!
 * Currently, the only calls to jscandir are from:
 * - the recover program (which never touches MatchDir)
 * - descendants of ask_file or ask_dir (which always set it)
 */
bool  MatchDir = NO;
#endif

#ifdef MSDOS
# include <dos.h>

# ifndef ZTCDOS
#  include <search.h>
# endif

/* Scandir returns the number of entries or -1 if the directory cannot
 * be opened or malloc fails.
 */
int
jscandir(dir, nmptr, qualify, sorter)
const char  *dir;
char  ***nmptr;
bool  (*qualify) ptrproto((char *));
int   (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
{
      struct find_t entry;
      char  **ourarray;
      unsigned int      nalloc = 10,
                  nentries = 0;

      {
            char dirname[FILESIZE];
            char *ptr;

            strcpy(dirname, dir);
            ptr = &dirname[strlen(dirname)-1];
            if (!((dirname[1] == ':' && dirname[2] == '\0') || *ptr == '/' || *ptr == '\\'))
                  *++ptr = '/';
            strcpy(ptr+1, "*.*");

            if (_dos_findfirst(dirname, _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR, &entry))
                  return -1;
      }
      ourarray = (char **) emalloc(nalloc * sizeof (char *));
      do  {
            char filename[FILESIZE];

            if (MatchDir && (entry.attrib&_A_SUBDIR) == 0)
                  continue;

            strlwr(entry.name);
            if (qualify != NULL && !(*qualify)(entry.name))
                  continue;

            /* note: test ensures one space left in ourarray for NULL */
            if (nentries+1 == nalloc)
                  ourarray = (char **) erealloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
            strcpy(filename, entry.name);
#ifdef DIRECTORY_ADD_SLASH
            if ((entry.attrib&_A_SUBDIR) != 0)
                  strcat(filename, "/");
#endif
            ourarray[nentries++] = copystr(filename);
      } while (_dos_findnext(&entry) == 0);
      ourarray[nentries] = NULL;

      if (sorter != (int (*) ptrproto((UnivConstPtr, UnivConstPtr)))NULL)
            qsort((char *) ourarray, nentries, sizeof (char **), sorter);
      *nmptr = ourarray;

      return nentries;
}

#endif /* MSDOS */

#ifdef WIN32

# include <windows.h>

/* Scandir returns the number of entries or -1 if the directory cannot
 * be opened or malloc fails.
 */
int
jscandir(dir, nmptr, qualify, sorter)
char  *dir;
char  ***nmptr;
bool  (*qualify) ptrproto((char *));
int   (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
{
      WIN32_FIND_DATA entry;
      HANDLE findHand;
      char  **ourarray;
      unsigned int      nalloc = 10,
                  nentries = 0;

      {
            char dirname[_MAX_PATH];
            char *ptr;

            strcpy(dirname, dir);
            ptr = &dirname[strlen(dirname)-1];
            if (!((dirname[1] == ':' && dirname[2] == '\0') || *ptr == '/' || *ptr == '\\'))
                  *++ptr = '/';
            strcpy(ptr+1, "*.*");

            if ((findHand = FindFirstFile(dirname, &entry)) == INVALID_HANDLE_VALUE)
                  return -1;
      }
      ourarray = (char **) emalloc(nalloc * sizeof (char *));
      do  {
            char filename[_MAX_PATH];

            if (MatchDir && (entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == 0)
                  continue;

            strcpy(filename, entry.cFileName);
            strlwr(entry.cFileName);
            if (qualify != NULL && !(*qualify)(entry.cFileName))
                  continue;

            /* note: test ensures one space left in ourarray for NULL */
            if (nentries+1 == nalloc)
                  ourarray = (char **) erealloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
#ifdef DIRECTORY_ADD_SLASH
            if ((entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0)
                  strcat(filename, "/");
#endif
            ourarray[nentries++] = copystr(filename);
      } while (FindNextFile(findHand, &entry));
      FindClose(findHand);
      ourarray[nentries] = NULL;

      if (sorter != (int (*)ptrproto((UnivConstPtr, UnivConstPtr)))NULL)
            qsort((char *) ourarray, nentries, sizeof (char **), sorter);
      *nmptr = ourarray;

      return nentries;
}

#endif /* WIN32 */

void
freedir(nmptr, nentries)
char  ***nmptr;
int   nentries;
{
      char  **ourarray = *nmptr;

      while (--nentries >= 0)
            free((UnivPtr) *ourarray++);
      free((UnivPtr) *nmptr);
      *nmptr = NULL;
}
#endif /* F_COMPLETION */

Generated by  Doxygen 1.6.0   Back to index