/*
 * DF-2687 forensics: dump struct tty blobs from kern.ttys and report
 * t_session / t_pgrp / t_state / t_dev for each, flagging orphaned
 * (TS_ZOMBIE, master-closed) ptys whose t_session is non-NULL.
 */
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/tty.h>
#define	_KERNEL_STRUCTURES
#include <sys/tty.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

int
main(void)
{
	static char buf[65536];
	size_t len = sizeof(buf);
	size_t off;
	int i;

	if (sysctlbyname("kern.ttys", buf, &len, NULL, 0) < 0) {
		perror("sysctl kern.ttys");
		return 1;
	}
	printf("kern.ttys: %zu bytes, sizeof(struct tty)=%zu, count=%zu\n",
	       len, sizeof(struct tty), len / sizeof(struct tty));

	for (off = 0, i = 0; off + sizeof(struct tty) <= len;
	     off += sizeof(struct tty), i++) {
		struct tty *t = (struct tty *)(buf + off);
		printf("[%02d] state=%08x line=%d dev=%p pgrp=%p session=%p "
		       "refs=%d%s\n",
		       i, t->t_state, t->t_line, (void *)(uintptr_t)t->t_dev,
		       t->t_pgrp, t->t_session, t->t_refs,
		       (t->t_session && (t->t_state & 0x100000 /*TS_ZOMBIE*/))
			   ? "  <== ORPHANED TTY WITH LIVE t_session POINTER"
			   : "");
	}
	return 0;
}
