home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / jove414s.zip / scandir.c < prev    next >
C/C++ Source or Header  |  1991-07-06  |  6KB  |  243 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is 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. #ifdef OS2
  8. # define INCL_BASE
  9. # include <os2.h>
  10. # define R_ONLY 0x0001
  11. # define HIDDEN 0x0002
  12. # define SYSTEM 0x0004
  13. # define SUBDIR 0x0010
  14. #endif
  15.  
  16. #include "jove.h"
  17. #include "scandir.h"
  18.  
  19. #ifdef F_COMPLETION
  20.  
  21. #ifdef MSDOS
  22. # include <dos.h>
  23. # include <search.h>
  24. #endif
  25.  
  26. #ifdef UNIX
  27. # include <sys/stat.h>
  28. # ifdef M_XENIX
  29. #  include <sys/ndir.h>
  30. # else
  31. #  include <sys/dir.h>
  32. # endif /* M_XENIX */
  33. #endif
  34.  
  35. #ifdef UNIX
  36.  
  37. #ifdef mips
  38. # undef scandir
  39. #endif
  40.  
  41. #ifdef BSD_DIR
  42. # define DIRSIZE(entry)    DIRSIZ((entry))
  43. #else
  44. # define DIRSIZE(entry)    ((entry)->d_name[DIRSIZ-1]=='\0' ? strlen((entry)->d_name) : DIRSIZ)
  45.  
  46. typedef struct {
  47.     int    d_fd;        /* File descriptor for this directory */
  48. } DIR;
  49.  
  50. DIR *
  51. opendir(dir)
  52. char    *dir;
  53. {
  54.     DIR    *dp = (DIR *) malloc(sizeof *dp);
  55.     struct stat    stbuf;
  56.  
  57.     if ((dp->d_fd = open(dir, 0)) == -1)
  58.         return 0;
  59.     if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
  60.         closedir(dp);
  61.         return 0;    /* this isn't a directory! */
  62.     }
  63.     return dp;
  64. }
  65.  
  66. closedir(dp)
  67. DIR    *dp;
  68. {
  69.     (void) close(dp->d_fd);
  70.     free((char *) dp);
  71. }
  72.  
  73. struct direct *
  74. readdir(dp)
  75. DIR    *dp;
  76. {
  77.     static struct direct    dir;
  78.  
  79.     do
  80.         if (read(dp->d_fd, &dir, sizeof dir) != sizeof dir)
  81.             return 0;
  82. #if defined(elxsi) && defined(SYSV)
  83.     /*
  84.      * Elxsi has a BSD4.2 implementation which may or may not use
  85.      * `twisted inodes' ...  Anyone able to check?
  86.      */
  87.     while (*(unsigned short *)&dir.d_ino == 0);
  88. #else
  89.     while (dir.d_ino == 0);
  90. #endif
  91.  
  92.     return &dir;
  93. }
  94.  
  95. #endif /* BSD_DIR */
  96.  
  97. /* Scandir returns the number of entries or -1 if the directory cannoot
  98.    be opened or malloc fails. */
  99.  
  100. int
  101. scandir(dir, nmptr, qualify, sorter)
  102. char    *dir;
  103. char    ***nmptr;
  104. int    (*qualify) proto((char *));
  105. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  106. {
  107.     DIR    *dirp;
  108.     struct direct    *entry;
  109.     char    **ourarray;
  110.     unsigned int    nalloc = 10,
  111.             nentries = 0;
  112.  
  113.     if ((dirp = opendir(dir)) == 0)
  114.         return -1;
  115.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  116. memfail:    complain("[Malloc failed: cannot scandir]");
  117.     while ((entry = readdir(dirp)) != 0) {
  118.         if (qualify != 0 && (*qualify)(entry->d_name) == 0)
  119.             continue;
  120.         if (nentries == nalloc) {
  121.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  122.             if (ourarray == 0)
  123.                 goto memfail;
  124.         }
  125.         ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1);
  126.         null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry));
  127.         nentries += 1;
  128.     }
  129.     closedir(dirp);
  130.     if ((nentries + 1) != nalloc)
  131.         ourarray = (char **) realloc((char *) ourarray,
  132.                     ((nentries + 1) * sizeof (char *)));
  133.     if (sorter != 0)
  134.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  135.     *nmptr = ourarray;
  136.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  137.  
  138.     return nentries;
  139. }
  140.  
  141. #endif /* UNIX */
  142.  
  143. #ifdef MSDOS
  144. # define DIRSIZ 64
  145. # define DIRSIZE(entry)    strlen((FileInfo).achName)
  146.  
  147. /* Scandir returns the number of entries or -1 if the directory cannot
  148.    be opened or malloc fails. */
  149.  
  150. //unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
  151. unsigned int fmask = R_ONLY | SYSTEM | HIDDEN | SUBDIR;
  152. int
  153. scandir(dir, nmptr, qualify, sorter)
  154. char    *dir;
  155. char    ***nmptr;
  156. int    (*qualify) proto((char *));
  157. int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
  158. {
  159.     char dirname[FILESIZE];
  160.     struct find_t entry;
  161.     char *ptr;
  162.     char    **ourarray;
  163.     unsigned int    nalloc = 10,
  164.             nentries = 0;
  165. #ifdef OS2
  166.     FILEFINDBUF  FileInfo;
  167.     HDIR         DirHandle = 0xffff;
  168.     const USHORT attr = R_ONLY | SYSTEM | HIDDEN | SUBDIR;
  169.     USHORT         searchcount = 1;
  170. #endif
  171.  
  172.     strcpy(dirname, dir);
  173.     ptr = &dirname[strlen(dirname)-1];
  174.     if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
  175.        strcat(dirname, "*.*");
  176.     else
  177.        strcat(dirname, "/*.*");
  178. #ifndef OS2
  179.     if (_dos_findfirst(dirname, fmask, &entry))
  180. #  else
  181.     if (DosFindFirst (dirname, &DirHandle, attr, &FileInfo,
  182.                sizeof (FILEFINDBUF), &searchcount, 0L))
  183. #endif
  184.        return (-1);
  185.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  186. memfail:    complain("[Malloc failed: cannot scandir]");
  187.     do  {
  188.         if ((fmask == 0x10) && !(FileInfo.attrFile&fmask))
  189.             goto skip;
  190.         strlwr(FileInfo.achName);
  191.         if (qualify != (int (*)())0 && (*qualify)(FileInfo.achName) == 0)
  192.             goto skip;
  193.         if (nentries == nalloc) {
  194.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  195.             if (ourarray == 0)
  196.                 goto memfail;
  197.         }
  198.         ourarray[nentries] = (char *) malloc(DIRSIZE(FileInfo) + 1);
  199.         null_ncpy(ourarray[nentries], FileInfo.achName, (int) DIRSIZE(FileInfo));
  200.         nentries++;
  201. skip:    ;
  202.     }
  203. #ifndef OS2
  204.     while (_dos_findnext(&entry) == 0);
  205. #else
  206.     while (DosFindNext (DirHandle, &FileInfo, sizeof (FILEFINDBUF),
  207.            &searchcount) == 0) ;
  208. #endif
  209.     if ((nentries + 1) != nalloc)
  210.         ourarray = (char **) realloc((char *) ourarray,
  211.                     ((nentries + 1) * sizeof (char *)));
  212.     if (sorter != (int (*)())0)
  213.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  214.     *nmptr = ourarray;
  215.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  216.  
  217.     return nentries;
  218. }
  219.  
  220. #endif /* MSDOS */
  221.  
  222. void
  223. freedir(nmptr, nentries)
  224. char    ***nmptr;
  225. int    nentries;
  226. {
  227.     char    **ourarray = *nmptr;
  228.  
  229.     while (--nentries >= 0)
  230.         free(*ourarray++);
  231.     free((char *) *nmptr);
  232.     *nmptr = 0;
  233. }
  234.  
  235. int
  236. alphacomp(a, b)
  237. UnivConstPtr    a,
  238.     b;
  239. {
  240.     return strcmp(*(const char **)a, *(const char **)b);
  241. }
  242. #endif
  243.