while (cur_state < STATE_QUIT) {
for (;;) {
priv_init(int argc, char **argv){	int bpfd = -1;	int i, socks[2], cmd, nflag = 0;	struct passwd *pw;	uid_t uid;	gid_t gid;	char *cmdbuf, *infile = NULL;	char *RFileName = NULL;	char *WFileName = NULL;	closefrom(STDERR_FILENO + 1);	for (i = 1; i < _NSIG; i++)		signal(i, SIG_DFL);	/* Create sockets */	if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)		err(1, "socketpair() failed");	child_pid = fork();	if (child_pid < 0)		err(1, "fork() failed");	if (!child_pid) {		if (getuid() == 0) {			pw = getpwnam("_tcpdump");			if (pw == NULL)				errx(1, "unknown user _tcpdump");			endpwent();			/* chroot, drop privs and return */			if (chroot(pw->pw_dir) != 0)				err(1, "unable to chroot");			if (chdir("/") != 0)				err(1, "unable to chdir");			/* drop to _tcpdump */			if (setgroups(1, &pw->pw_gid) == -1)				err(1, "setgroups() failed");			if (setegid(pw->pw_gid) == -1)				err(1, "setegid() failed");			if (setgid(pw->pw_gid) == -1)				err(1, "setgid() failed");			if (seteuid(pw->pw_uid) == -1)				err(1, "seteuid() failed");			if (setuid(pw->pw_uid) == -1)				err(1, "setuid() failed");		} else {			/* Child - drop suid privileges */			gid = getgid();			uid = getuid();			if (setegid(gid) == -1)				err(1, "setegid() failed");			if (setgid(gid) == -1)				err(1, "setgid() failed");			if (seteuid(uid) == -1)				err(1, "seteuid() failed");			if (setuid(uid) == -1)				err(1, "setuid() failed");		}		close(socks[0]);		priv_fd = socks[1];		return (0);	}	/* Father - drop suid privileges */	gid = getgid();	uid = getuid();	if (setegid(gid) == -1)		err(1, "setegid() failed");	if (setgid(gid) == -1)		err(1, "setgid() failed");	if (seteuid(uid) == -1)		err(1, "seteuid() failed");	if (setuid(uid) == -1)		err(1, "setuid() failed");	/* parse the arguments for required options so that the child	 * need not send them back */	opterr = 0;	while ((i = getopt(argc, argv,	    "ac:deE:fF:i:lLnNOopqr:s:StT:vw:xXy:Y")) != -1) {		switch (i) {		case 'n':			nflag++;			break;		case 'r':			RFileName = optarg;			break;		case 'w':			WFileName = optarg;			break;		case 'F':			infile = optarg;			break;		default:			/* nothing */			break;		}	}	if (RFileName != NULL) {		if (strcmp(RFileName, "-") != 0)			allowed_ext[STATE_INIT] |= ALLOW(PRIV_OPEN_DUMP);	} else		allowed_ext[STATE_INIT] |= ALLOW(PRIV_OPEN_BPF);	if (WFileName != NULL) {		if (strcmp(WFileName, "-") != 0)			allowed_ext[STATE_FILTER] |= ALLOW(PRIV_OPEN_OUTPUT);		else			allowed_ext[STATE_FILTER] |= ALLOW(PRIV_INIT_DONE);	} else		allowed_ext[STATE_FILTER] |= ALLOW(PRIV_INIT_DONE);	if (!nflag) {		allowed_ext[STATE_RUN] |= ALLOW(PRIV_GETHOSTBYADDR);		allowed_ext[STATE_FILTER] |= ALLOW(PRIV_ETHER_NTOHOST);		allowed_ext[STATE_RUN] |= ALLOW(PRIV_ETHER_NTOHOST);		allowed_ext[STATE_RUN] |= ALLOW(PRIV_GETRPCBYNUMBER);		allowed_ext[STATE_FILTER] |= ALLOW(PRIV_GETPROTOENTRIES);	}	if (infile)		cmdbuf = read_infile(infile);	else		cmdbuf = copy_argv(&argv[optind]);	/* Pass ALRM/TERM/HUP through to child, and accept CHLD */	signal(SIGALRM, sig_pass_to_chld);	signal(SIGTERM, sig_pass_to_chld);	signal(SIGHUP,  sig_pass_to_chld);	signal(SIGCHLD, sig_got_chld);	setproctitle("[priv]");	close(socks[1]);	while (cur_state < STATE_QUIT) {		if (may_read(socks[0], &cmd, sizeof(int)))			break;		switch (cmd) {		case PRIV_OPEN_BPF:			test_state(cmd, STATE_BPF);			parent_open_bpf(socks[0], &bpfd);			break;		case PRIV_OPEN_DUMP:			test_state(cmd, STATE_BPF);			parent_open_dump(socks[0], RFileName);			break;		case PRIV_OPEN_OUTPUT:			test_state(cmd, STATE_RUN);			parent_open_output(socks[0], WFileName);			break;		case PRIV_SETFILTER:			test_state(cmd, STATE_FILTER);			parent_setfilter(socks[0], cmdbuf, &bpfd);			break;		case PRIV_INIT_DONE:			test_state(cmd, STATE_RUN);			parent_init_done(socks[0], &bpfd);			break;		case PRIV_GETHOSTBYADDR:			test_state(cmd, STATE_RUN);			parent_gethostbyaddr(socks[0]);			break;		case PRIV_ETHER_NTOHOST:			test_state(cmd, cur_state);			parent_ether_ntohost(socks[0]);			break;		case PRIV_GETRPCBYNUMBER:			test_state(cmd, STATE_RUN);			parent_getrpcbynumber(socks[0]);			break;		case PRIV_GETSERVENTRIES:			test_state(cmd, STATE_FILTER);			parent_getserventries(socks[0]);			break;		case PRIV_GETPROTOENTRIES:			test_state(cmd, STATE_FILTER);			parent_getprotoentries(socks[0]);			break;		case PRIV_LOCALTIME:			test_state(cmd, STATE_RUN);			parent_localtime(socks[0]);			break;		case PRIV_GETLINES:			test_state(cmd, STATE_RUN);			parent_getlines(socks[0]);			break;		default:			logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);			_exit(1);			/* NOTREACHED */		}	}	_exit(0);}