/* zglob.c zilla sep26 - filename match
 * adapted in part from code in Oliver Laumann's Elk (unix.c),
 * also calls Wildmat by Rich Salz (rsalz@bbn.com)
 */

#include <theusual.h>
#include <sys/types.h>
/*#include <sys/stat.h>*/
/*#include <errno.h>*/

#if Eansiincludes
#  include <dirent.h>
#else
#  include <sys/dir.h>
#endif

/* define this if you do not want . and .. included in the matches */
#define EXCLUDEDOTS

#define DOT '.'

int Zreaddir(spec,buffer,maxitems) 
  char *spec,**buffer;
  int maxitems;
{
    register DIR *d;
#if Eansiincludes
    register struct dirent *dp;
#else
    register struct direct *dp;
#endif
    register char *dir;
    int n;

    dir = Zpathgetpath(spec);
    if (str_len(dir)==0) dir = ".";

    if ((d = opendir (dir)) == NULL)
      Zfail("cannot open directory %s", spec);

    n = 0;
    while ((dp = readdir (d)) != NULL) {
      register int len = str_len(dp->d_name);

#ifdef EXCLUDEDOTS
      if ((dp->d_name[0] == DOT) &&
          ((len == 1)
           || ((len == 2) && (dp->d_name[1] == DOT))))
        continue;
#endif
      buffer[n] = malloc(len+1);
      Zbcopy(dp->d_name,buffer[n],len);
      (buffer[n])[len] = (char)0;
      n++;
      if (n == maxitems) {
        Zwarning("Zglob: name buffer full\n");
        break;
      }
    }

    closedir (d);
    return n;
} /*zreaddir*/



int Zglob(spec,buffer,maxitems) 
  char *spec,**buffer;
  int maxitems;
{
    register DIR *d;
#if Eansiincludes
    register struct dirent *dp;
#else
    register struct direct *dp;
#endif
    register char *dir;
    int n;

    dir = Zpathgetpath(spec);
    if (str_len(dir)==0) dir = ".";

    if ((d = opendir (dir)) == NULL)
      Zfail("cannot open directory %s", spec);

    n = 0;
    while ((dp = readdir (d)) != NULL) {
      register int len = str_len(dp->d_name);

#ifdef EXCLUDEDOTS
      if ((dp->d_name[0] == DOT) &&
          ((len == 1)
           || ((len == 2) && (dp->d_name[1] == DOT))))
        continue;
#endif

      if (wildmat(dp->d_name,spec)) {
        buffer[n] = malloc(len+1);
        Zbcopy(dp->d_name,buffer[n],len);
        (buffer[n])[len] = (char)0;
        n++;
        if (n == maxitems) {
          Zwarning("Zglob: name buffer full\n");
          break;
        }
      }/*wildmat match*/

    }/*readdir loop*/

    closedir (d);
    return n;
} /*zglob*/


#ifdef TESTIT /*%%%%%%%%%%%%%%%%*/
/*% cc -DTESTIT % wildmat.c -lZ -o zglobTST %*/
main(ac,av) 
int ac; char *av[];
{
# define Nmatches 1000
  char *matches[Nmatches];
  int i,n;

  if (ac != 2) Zquit(1,"zglobTST <path>\n");
  n = Zglob(av[1],matches,Nmatches);
  printf("found %d files\n",n);
  for( i=0; i < n; i++ )
    printf("%d: %s\n",i,matches[i]);
}

#endif /*TESTIT%%%%%%%%%%%%%%%%*/
