#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>

main(argc, argv)
int argc;
char **argv;
{
	char *dir;
	int i, j, fd;
	struct stat sbuf;
	struct direct dbuf[1024];

	/*
	 * We declare comp() as extern, so
	 * that we may use its name as a
	 * pointer in qsort.
	 */
	extern comp();

	/*
	 * If no directory is given, then
	 * look at current directory.
	 */
	if (argc < 2) 
		dir = ".";
	else
		dir = argv[1];

	if (stat(dir, &sbuf) < 0) {
		printf("%s does not exist\en", dir);
		exit(1);
	}

	/*
	 * See if it's a directory
	 */
	if ((sbuf.st\(ulmode & S\(ulIFMT) != S\(ulIFDIR) {
		printf("%s not a directory.\en", dir);
		exit(1);
	}

	if ((fd = open(dir, 0)) < 0) {
		printf("Cannot open %s\en", dir);
		exit(1);
	}

	/*
	 * Read in the directory, and then compute
	 * number of structures read in.
	 */
	j = read(fd, dbuf, 1024 * sizeof(struct direct));
	j /= sizeof(struct direct);
	close(fd);

	/*
	 * Sort the entries.
	 */
	qsort(dbuf, j, sizeof(struct direct), comp);

	printf("The entries in %s are:\en", dir);

	for (i=0; i < j; i++) {
		/*
		 * Skip non-existent files
		 */
		if (dbuf[i].d\(ulino == 0)
			continue;

		/*
		 * Find out about the file.
		 */
		if (stat(dbuf[i].d\(ulname, &sbuf) < 0) 
			continue;

		printf("\et%14.14s ", dbuf[i].d\(ulname);

		if ((sbuf.st\(ulmode & S\(ulIFMT) == S\(ulIFDIR)
			printf("directory ");
		else
			printf("file ");
		
		printf("size: %d bytes\en", sbuf.st\(ulsize);
	}
}
/*
 * comp \- simple routine for qsort().
 */
int comp(d1, d2)
struct direct *d1, *d2;
{
	/*
	 * We check inodes to see if one or both filenames
	 * should be considered null.  This is because the
	 * d\(ulname is not always cleared when a file is 
	 * removed.
	 */
	if (d1\->d\(ulino == 0) {
		if (d2\->d\(ulino == 0)
			return(0);
		return(1);
	}

	if (d2\->d\(ulino == 0)
		return(\-1);

	return(strncmp(d1\->d\(ulname, d2\->d\(ulname, 14));
}
