/*
 * fake_daemon3173.c — automountd(8) stand-in for the DF-3173 harness.
 *
 * Plays automountd(8): opens /dev/autofs (single-opener), loops on the
 * AUTOFSREQUEST ioctl, and completes each request with AUTOFSDONE
 * (error=0, wildcards=0) after a fixed delay given in milliseconds.
 *
 * The delay is the harness's "boundary control": with
 * vfs.autofs.timeout=1, a delay of ~1050 ms lands the AUTOFSDONE just
 * AFTER the request's 1 s timeout callout has fired — exactly the
 * production situation of a lagging automountd catching up with the
 * 30 s timeout frontier of its request queue.
 *
 * Build: cc -O2 -o fake_daemon3173 fake_daemon3173.c
 * Run (root): ./fake_daemon3173 <delay_ms>
 */
#include <sys/ioctl.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "autofs_ioctl.h"

int
main(int argc, char **argv)
{
	struct autofs_daemon_request req;
	struct autofs_daemon_done done;
	long delay_ms;
	int fd, i;

	if (argc != 2) {
		fprintf(stderr, "usage: %s <delay_ms>\n", argv[0]);
		return (1);
	}
	delay_ms = strtol(argv[1], NULL, 10);

	if (setsid() == -1) {
		perror("setsid");
		return (1);
	}
	fd = open("/dev/autofs", O_RDWR);
	if (fd < 0) {
		perror("open /dev/autofs (kldload autofs first)");
		return (1);
	}
	fprintf(stderr, "fake_daemon3173: ready, DONE delay=%ldms "
	    "(sid=%d)\n", delay_ms, getsid(0));

	for (i = 0; ; i++) {
		memset(&req, 0, sizeof(req));
		if (ioctl(fd, AUTOFSREQUEST, &req) == -1) {
			if (errno == EINTR)
				continue;
			perror("AUTOFSREQUEST");
			return (1);
		}
		fprintf(stderr, "%ld fake_daemon3173: [%d] GOT request id=%d "
		    "path=%s key=%s -> DONE in %ldms\n",
		    (long)time(NULL), i, req.adr_id, req.adr_path,
		    req.adr_key, delay_ms);

		usleep(delay_ms * 1000);

		memset(&done, 0, sizeof(done));
		done.add_id = req.adr_id;
		done.add_wildcards = 0;
		done.add_error = 0;
		fprintf(stderr, "%ld fake_daemon3173: SEND DONE id=%d\n",
		    (long)time(NULL), req.adr_id);
		if (ioctl(fd, AUTOFSDONE, &done) == -1) {
			fprintf(stderr, "%ld fake_daemon3173: DONE id=%d: %s\n",
			    (long)time(NULL), req.adr_id, strerror(errno));
		}
	}
}
