home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / jove4.9 / part02 / scandir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-25  |  4.8 KB  |  218 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.  
  8. #include "jove.h"
  9.  
  10. #ifdef MSDOS
  11. #include <dos.h>
  12. #include <search.h>
  13. #endif
  14.  
  15. #ifdef UNIX
  16. #include <sys/stat.h>
  17. #ifdef M_XENIX
  18. #include <sys/ndir.h>
  19. #else
  20. #include <sys/dir.h>
  21. #endif /* M_XENIX */
  22. #endif
  23.  
  24. #ifdef F_COMPLETION
  25.  
  26. #ifdef UNIX
  27.  
  28. #if defined(BSD4_2) || defined(M_XENIX)
  29.  
  30. #define DIRSIZE(entry)    DIRSIZ(entry)
  31.  
  32. #else
  33.  
  34. #define DIRSIZE(entry)    (entry->d_name[DIRSIZ-1]=='\0' ? strlen(entry->d_name) : DIRSIZ)
  35.  
  36. typedef struct {
  37.     int    d_fd;        /* File descriptor for this directory */
  38. } DIR;
  39.  
  40. DIR *
  41. opendir(dir)
  42. char    *dir;
  43. {
  44.     DIR    *dp = (DIR *) malloc(sizeof *dp);
  45.     struct stat    stbuf;
  46.  
  47.     if ((dp->d_fd = open(dir, 0)) == -1)
  48.         return 0;
  49.     if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
  50.         closedir(dp);
  51.         return 0;    /* this isn't a directory! */
  52.     }
  53.     return dp;
  54. }
  55.  
  56. closedir(dp)
  57. DIR    *dp;
  58. {
  59.     (void) close(dp->d_fd);
  60.     free((char *) dp);
  61. }
  62.  
  63. struct direct *
  64. readdir(dp)
  65. DIR    *dp;
  66. {
  67.     static struct direct    dir;
  68.  
  69.     do
  70.         if (read(dp->d_fd, &dir, sizeof dir) != sizeof dir)
  71.             return 0;
  72. #if defined(elxsi) && defined(SYSV)
  73.     /*
  74.      * Elxsi has a BSD4.2 implementation which may or may not use
  75.      * `twisted inodes' ...  Anyone able to check?
  76.      */
  77.     while (*(unsigned short *)&dir.d_ino == 0);
  78. #else
  79.     while (dir.d_ino == 0);
  80. #endif
  81.  
  82.     return &dir;
  83. }
  84.  
  85. #endif /* BSD4_2 */
  86.  
  87. /* Scandir returns the number of entries or -1 if the directory cannoot
  88.    be opened or malloc fails. */
  89.  
  90. int
  91. scandir(dir, nmptr, qualify, sorter)
  92. char    *dir;
  93. char    ***nmptr;
  94. int    (*qualify)();
  95. int    (*sorter)();
  96. {
  97.     DIR    *dirp;
  98.     struct direct    *entry;
  99.     char    **ourarray;
  100.     unsigned int    nalloc = 10,
  101.             nentries = 0;
  102.  
  103.     if ((dirp = opendir(dir)) == 0)
  104.         return -1;
  105.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  106. memfail:    complain("[Malloc failed: cannot scandir]");
  107.     while ((entry = readdir(dirp)) != 0) {
  108.         if (qualify != 0 && (*qualify)(entry->d_name) == 0)
  109.             continue;
  110.         if (nentries == nalloc) {
  111.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  112.             if (ourarray == 0)
  113.                 goto memfail;
  114.         }
  115.         ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1);
  116.         null_ncpy(ourarray[nentries], entry->d_name, (int) DIRSIZE(entry));
  117.         nentries += 1;
  118.     }
  119.     closedir(dirp);
  120.     if ((nentries + 1) != nalloc)
  121.         ourarray = (char **) realloc((char *) ourarray,
  122.                     ((nentries + 1) * sizeof (char *)));
  123.     if (sorter != 0)
  124.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  125.     *nmptr = ourarray;
  126.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  127.  
  128.     return nentries;
  129. }
  130.  
  131. #endif /* UNIX */
  132.  
  133. #ifdef MSDOS
  134. #define    DIRSIZ    13
  135. #define DIRSIZE(entry)    strlen(entry.name)
  136.  
  137. /* Scandir returns the number of entries or -1 if the directory cannoot
  138.    be opened or malloc fails. */
  139.  
  140. unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
  141.  
  142. int
  143. scandir(dir, nmptr, qualify, sorter)
  144. char    *dir;
  145. char    ***nmptr;
  146. int    (*qualify)();
  147. int    (*sorter)();
  148. {
  149.     char dirname[FILESIZE];
  150.     struct find_t entry;
  151.     char *ptr;
  152.     char    **ourarray;
  153.     unsigned int    nalloc = 10,
  154.             nentries = 0;
  155.  
  156.     strcpy(dirname, dir);
  157.     ptr = &dirname[strlen(dirname)-1];
  158.     if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
  159.        strcat(dirname, "*.*");
  160.     else
  161.        strcat(dirname, "/*.*");
  162.  
  163.     if (_dos_findfirst(dirname, fmask, &entry))
  164.        return -1;
  165.     if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
  166. memfail:    complain("[Malloc failed: cannot scandir]");
  167.     do  {
  168.         if ((fmask == 0x10) && !(entry.attrib&fmask))
  169.             goto skip;
  170.         strlwr(entry.name);
  171.         if (qualify != (int (*)())0 && (*qualify)(entry.name) == 0)
  172.             goto skip;
  173.         if (nentries == nalloc) {
  174.             ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
  175.             if (ourarray == 0)
  176.                 goto memfail;
  177.         }
  178.         ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1);
  179.         null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry));
  180.         nentries++;
  181. skip:    ;
  182.     }
  183.     while (_dos_findnext(&entry) == 0);
  184.  
  185.     if ((nentries + 1) != nalloc)
  186.         ourarray = (char **) realloc((char *) ourarray,
  187.                     ((nentries + 1) * sizeof (char *)));
  188.     if (sorter != (int (*)())0)
  189.         qsort((char *) ourarray, nentries, sizeof (char **), sorter);
  190.     *nmptr = ourarray;
  191.     ourarray[nentries] = 0;        /* guaranteed 0 pointer */
  192.  
  193.     return nentries;
  194. }
  195.  
  196. #endif /* MSDOS */
  197.  
  198. void
  199. freedir(nmptr, nentries)
  200. char    ***nmptr;
  201. {
  202.     char    **ourarray = *nmptr;
  203.  
  204.     while (--nentries >= 0)
  205.         free(*ourarray++);
  206.     free((char *) *nmptr);
  207.     *nmptr = 0;
  208. }
  209.  
  210. int
  211. alphacomp(a, b)
  212. char    **a,
  213.     **b;
  214. {
  215.     return strcmp(*a, *b);
  216. }
  217. #endif
  218.