home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / scandir.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  7KB  |  288 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 by Jonathan Payne.  JOVE is  *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. /*
  9.  * This file is used as a compiled module by Jove and also included as
  10.  * source in recover.c
  11.  */
  12. #ifndef TUNED
  13. # include "jove.h"
  14. #endif
  15. #include "scandir.h"
  16.  
  17. #ifdef F_COMPLETION    /* the body is the rest of this file */
  18.  
  19. #ifdef UNIX
  20.  
  21. # include <sys/stat.h>
  22.  
  23. # if defined(M_XENIX) && !defined(M_UNIX)
  24.    /* XENIX, but not SCO UNIX, which pretends to be XENIX! */
  25. #  include <sys/ndir.h>
  26. #  ifndef dirent
  27. #   define dirent direct
  28. #  endif
  29. # endif
  30.  
  31. # ifdef BSD_DIR
  32. #  include <sys/dir.h>
  33. #  ifndef dirent
  34. #   define dirent direct
  35. #  endif
  36. # endif
  37.  
  38. /* default to dirent.h */
  39. # if !defined(dirent) && !defined(DIRENT_EMULATE)
  40. #  include <dirent.h>
  41. # endif
  42.  
  43. # ifdef DIRENT_EMULATE
  44.  
  45. typedef struct {
  46.     int    d_fd;        /* File descriptor for this directory */
  47. } DIR;
  48.  
  49. private int
  50. closedir(dp)
  51. DIR    *dp;
  52. {
  53.     (void) close(dp->d_fd);
  54.     free((UnivPtr) dp);
  55.     return 0;    /* don't know how to fail */
  56. }
  57.  
  58. private DIR *
  59. opendir(dir)
  60. char    *dir;
  61. {
  62.     int    fd;
  63.  
  64.     if ((fd = open(dir, 0)) != -1) {
  65.         struct stat    stbuf;
  66.  
  67.         if ((fstat(fd, &stbuf) != -1)
  68.         && (stbuf.st_mode & S_IFMT) == S_IFDIR)
  69.         {
  70.             /* Success! */
  71.             DIR    *dp = (DIR *) emalloc(sizeof *dp);
  72.  
  73.             dp->d_fd = fd;
  74.             return dp;
  75.         }
  76.         /* this isn't a directory! */
  77.         (void) close(fd);
  78.     }
  79.     return NULL;
  80. }
  81.  
  82. private dirent *
  83. readdir(dp)
  84. DIR    *dp;
  85. {
  86.     static dirent    dir;
  87.  
  88.     do {
  89.         if (read(dp->d_fd, (UnivPtr) &dir, sizeof dir) != sizeof dir)
  90.             return NULL;
  91.     } while (dir.d_ino == 0);
  92.  
  93.     return &dir;
  94. }
  95.  
  96. #endif /* DIRENT_EMULATE */
  97.  
  98. /* jscandir returns the number of entries or -1 if the directory cannot
  99.    be opened or malloc fails. */
  100.  
  101. int
  102. jscandir(dir, nmptr, qualify, sorter)
  103. char    *dir;
  104. char    ***nmptr;
  105. bool    (*qualify) ptrproto((char *));
  106. int    (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
  107. {
  108.     DIR    *dirp;
  109.     struct  dirent    *entry;
  110.     char    **ourarray;
  111.     unsigned int    nalloc = 10,
  112.             nentries = 0;
  113.  
  114.     if ((dirp = opendir(dir)) == NULL)
  115.         return -1;
  116.     ourarray = (char **) emalloc(nalloc * sizeof (char *));
  117.     while ((entry = readdir(dirp)) != NULL) {
  118.         if (qualify != NULL && !(*qualify)(entry->d_name))
  119.             continue;
  120.         /* note: test ensures one space left in ourarray for NULL */
  121.         if (nentries+1 == nalloc)
  122.             ourarray = (char **) erealloc((UnivPtr) ourarray, (nalloc += 10) * sizeof (char *));
  123. # ifdef DIRECTORY_ADD_SLASH
  124.         /* ??? what the heck is this?  dirent doesn't have this info. */
  125.         if ((entry.attrib&_A_SUBDIR) != 0)
  126.             strcat(entry->d_name, "/");
  127. # endif
  128.         ourarray[nentries++] = copystr(entry->d_name);
  129.     }
  130.     closedir(dirp);
  131.     ourarray[nentries] = NULL;
  132.  
  133.     if (sorter != NULL)
  134.         qsort((UnivPtr) ourarray, nentries, sizeof (char **), sorter);
  135.     *nmptr = ourarray;
  136.  
  137.     return nentries;
  138. }
  139.  
  140. #endif /* UNIX */
  141.  
  142. #ifdef MSFILESYSTEM
  143. bool    MatchDir = NO;
  144. #endif
  145.  
  146. #ifdef MSDOS
  147. # include <dos.h>
  148.  
  149. # ifndef ZTCDOS
  150. #  include <search.h>
  151. # endif
  152.  
  153. /* Scandir returns the number of entries or -1 if the directory cannot
  154.    be opened or malloc fails. */
  155.  
  156. int
  157. jscandir(dir, nmptr, qualify, sorter)
  158. char    *dir;
  159. char    ***nmptr;
  160. bool    (*qualify) ptrproto((char *));
  161. int    (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
  162. {
  163.     struct find_t entry;
  164.     char    **ourarray;
  165.     unsigned int    nalloc = 10,
  166.             nentries = 0;
  167.  
  168.     {
  169.         char dirname[FILESIZE];
  170.         char *ptr;
  171.  
  172.         strcpy(dirname, dir);
  173.         ptr = &dirname[strlen(dirname)-1];
  174.         if (!((dirname[1] == ':' && dirname[2] == '\0') || *ptr == '/' || *ptr == '\\'))
  175.             *++ptr = '/';
  176.         strcpy(ptr+1, "*.*");
  177.  
  178.         if (_dos_findfirst(dirname, MatchDir? _A_SUBDIR : _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR, &entry))
  179.            return -1;
  180.     }
  181.     ourarray = (char **) emalloc(nalloc * sizeof (char *));
  182.     do  {
  183.         char filename[FILESIZE];
  184.  
  185.         if (MatchDir && (entry.attrib&_A_SUBDIR) == 0)
  186.             continue;
  187.         strlwr(entry.name);
  188.         if (qualify != NULL && !(*qualify)(entry.name))
  189.             continue;
  190.         /* note: test ensures one space left in ourarray for NULL */
  191.         if (nentries+1 == nalloc)
  192.             ourarray = (char **) erealloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  193.         strcpy(filename, entry.name);
  194. #ifdef DIRECTORY_ADD_SLASH
  195.         if ((entry.attrib&_A_SUBDIR) != 0)
  196.             strcat(filename, "/");
  197. #endif
  198.         ourarray[nentries++] = copystr(filename);
  199.     } while (_dos_findnext(&entry) == 0);
  200.     ourarray[nentries] = NULL;
  201.  
  202.     if (sorter != (int (*) ptrproto((UnivConstPtr, UnivConstPtr)))NULL)
  203.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  204.     *nmptr = ourarray;
  205.  
  206.     return nentries;
  207. }
  208.  
  209. #endif /* MSDOS */
  210.  
  211. #ifdef WIN32
  212.  
  213. # include <windows.h>
  214.  
  215. /* Scandir returns the number of entries or -1 if the directory cannot
  216.    be opened or malloc fails. */
  217.  
  218. int
  219. jscandir(dir, nmptr, qualify, sorter)
  220. char    *dir;
  221. char    ***nmptr;
  222. bool    (*qualify) ptrproto((char *));
  223. int    (*sorter) ptrproto((UnivConstPtr, UnivConstPtr));
  224. {
  225.     WIN32_FIND_DATA entry;
  226.     HANDLE findHand;
  227.     char    **ourarray;
  228.     unsigned int    nalloc = 10,
  229.             nentries = 0;
  230.  
  231.     {
  232.         char dirname[_MAX_PATH];
  233.         char *ptr;
  234.  
  235.         strcpy(dirname, dir);
  236.         ptr = &dirname[strlen(dirname)-1];
  237.         if (!((dirname[1] == ':' && dirname[2] == '\0') || *ptr == '/' || *ptr == '\\'))
  238.             *++ptr = '/';
  239.         strcpy(ptr+1, "*.*");
  240.  
  241.         if ((findHand = FindFirstFile(dirname, &entry)) == INVALID_HANDLE_VALUE)
  242.             return -1;
  243.     }
  244.     ourarray = (char **) emalloc(nalloc * sizeof (char *));
  245.     do  {
  246.         char filename[_MAX_PATH];
  247.  
  248.         if (MatchDir && (entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == 0)
  249.             continue;
  250.         strcpy(filename, entry.cFileName);
  251.         strlwr(entry.cFileName);
  252.         if (qualify != NULL && !(*qualify)(entry.cFileName))
  253.             continue;
  254.         /* note: test ensures one space left in ourarray for NULL */
  255.         if (nentries+1 == nalloc)
  256.             ourarray = (char **) erealloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  257. #ifdef DIRECTORY_ADD_SLASH
  258.         if ((entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0)
  259.             strcat(filename, "/");
  260. #endif
  261.         ourarray[nentries++] = copystr(filename);
  262.     } while (FindNextFile(findHand, &entry));
  263.     FindClose(findHand);
  264.     ourarray[nentries] = NULL;
  265.  
  266.     if (sorter != (int (*)ptrproto((UnivConstPtr, UnivConstPtr)))NULL)
  267.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  268.     *nmptr = ourarray;
  269.  
  270.     return nentries;
  271. }
  272.  
  273. #endif /* WIN32 */
  274.  
  275. void
  276. freedir(nmptr, nentries)
  277. char    ***nmptr;
  278. int    nentries;
  279. {
  280.     char    **ourarray = *nmptr;
  281.  
  282.     while (--nentries >= 0)
  283.         free((UnivPtr) *ourarray++);
  284.     free((UnivPtr) *nmptr);
  285.     *nmptr = NULL;
  286. }
  287. #endif /* F_COMPLETION */
  288.