
/*
 *  GETFILES.C
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getfiles.h"
#include "ndir.h"
#include "version.h"

IDENT(".01");

Prototype dir_list *getfiles(const char *, int, int (*)(char *), int (*)(dir_list *, dir_list *));


#define offsetof(t,l)   ((int)(long)(((char*)&(((t*)0)->l))-((char*)((t*)0))))

dir_list *
getfiles(dir, gap, sel, cmp)
const char *dir;
int gap;
int (*sel)(char *);
int (*cmp)(dir_list *, dir_list *);
{
    register DIR *dirp;
    register struct direct *dp;
    register dir_list *this;
    dir_list *first = NULL;	/*  assignment avoids warning, not reqd */

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

    this = (dir_list *)&first;
    while (dp = readdir(dirp)) {
	if (sel == NULL || (*sel)(dp->d_name)) {
	    this->next = malloc(offsetof(dir_list, name)
				+ gap
				+ strlen(dp->d_name)
				+ 1
			       );
	    if ((this = this->next) == NULL)
		break;
	    strcpy(this->name + gap, dp->d_name);
	}
    }
    this->next = NULL;
    closedir(dirp);

    if (cmp == NULL)
	return first;
    return list_sort(first, (int (*)(void *, void *))cmp);
}


#ifdef TEST

sel(a)
char *a;
{
	while (*a != '\0')
		if (*a++ == '.' && *a == 'o')
			return 1;
	return 0;
}

cmp(a, b)
dir_list *a, *b;
{
	return strcmp(a->name, b->name);
}

main()
{
	register dir_list *p, *q;

	p = getfiles("", 0, (void *)NULL, (void *)NULL);
	while (p)
		puts(p->name), q = p->next, free(p), p = q;

	p = getfiles("", sel, cmp);
	while (p)
		puts(p->name), q = p->next, free(p), p = q;
}

#endif

