$NetBSD: patch-ab,v 1.3 2005/12/07 14:32:07 joerg Exp $

--- pftop.c.orig	2003-08-05 01:20:39.000000000 +0000
+++ pftop.c
@@ -31,6 +31,11 @@
  */
 #include "config.h"
 
+#ifdef __NetBSD__
+#include <sys/param.h>
+#include <sys/syslimits.h>
+#endif
+
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -54,7 +59,9 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <netdb.h>
+#include <poll.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -192,9 +199,6 @@ int cachestates = 0;
 
 volatile sig_atomic_t gotsig_close = 0;
 volatile sig_atomic_t gotsig_resize = 0;
-volatile sig_atomic_t gotsig_alarm = 0;
-int need_update = 0;
-int need_sort = 0;
 
 #define FLD_ALIGN_LEFT   0
 #define FLD_ALIGN_RIGHT  1
@@ -506,7 +510,6 @@ tb_end(void)
 
 int
 tbprintf(char *format, ...)
-	GCC_PRINTFLIKE(1,2)       /* defined in curses.h */
 {
 	int len;
 	va_list arg;
@@ -543,6 +546,10 @@ move_horiz(int offset)
 	}
 }
 
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
 void
 print_str(int len, const char *str)
 {
@@ -758,7 +765,6 @@ set_curr_view(field_view *v)
 	}
 
 	if ((curr_view != NULL) && (curr_view->mgr != v->mgr)) {
-		gotsig_alarm = 1;
 		if (v->mgr != NULL && v->mgr->select_fn != NULL)
 			v->mgr->select_fn();
 	}
@@ -766,7 +772,6 @@ set_curr_view(field_view *v)
 	curr_view = v;
 	curr_mgr = v->mgr;
 	field_setup();
-	need_update = 1;
 }
 
 void
@@ -849,11 +854,9 @@ update_cache()
 	if (cachestates) {
 		show_field(FLD_SI);
 		show_field(FLD_SP);
-		gotsig_alarm = 1;
 	} else {
 		hide_field(FLD_SI);
 		hide_field(FLD_SP);
-		need_update = 1;
 	}
 	field_setup();
 }
@@ -1212,7 +1215,7 @@ read_states(int dev)
 		ps.ps_buf = (char *) state_buf;
 
 		if (ioctl(dev, DIOCGETSTATES, &ps) < 0) {
-			errx(1, "DIOCGETSTATES");
+			err(1, "DIOCGETSTATES");
 		}
 		num_states = ps.ps_len / sizeof(struct pf_state);
 
@@ -1303,7 +1306,7 @@ print_header(struct pf_status *status)
 		tbprintf(" PAUSED");
 
 	if (rawmode)
-		printf("\n\n%s\n", tmp_buf);
+		printf("\n%s", tmp_buf);
 	else
 		mvprintw(0, 0, "%s", tmp_buf);
 
@@ -1319,7 +1322,10 @@ print_header(struct pf_status *status)
 		len = columns - strlen(tmp_buf);
 		if (len < 0)
 			len = 0;
-		mvprintw(0, len, "%s", tmp_buf);
+		if (rawmode)
+			printf(" %s\n", tmp_buf);
+		else
+			mvprintw(0, len, "%s", tmp_buf);
 	}
 
 	tb_end();
@@ -1645,7 +1651,7 @@ disp_update(int dev)
 		dispstart = 0;
 
 	if (ioctl(dev, DIOCGETSTATUS, &status)) {
-		warnx("DIOCGETSTATUS");
+		warn("DIOCGETSTATUS");
 		return (-1);
 	}
 
@@ -1681,7 +1687,7 @@ read_rules(int dev)
 
 	memset(&pr, 0, sizeof(pr));
 	if (ioctl(dev, DIOCGETRULES, &pr)) {
-		warnx("DIOCGETRULES");
+		warn("DIOCGETRULES");
 		return (-1);
 	}
 
@@ -1704,7 +1710,7 @@ read_rules(int dev)
 	for (nr = 0; nr < num_rules; ++nr) {
 		pr.nr = nr;
 		if (ioctl(dev, DIOCGETRULE, &pr)) {
-			warnx("DIOCGETRULE");
+			warn("DIOCGETRULE");
 			return (-1);
 		}
 		rules[nr] = pr.rule;
@@ -1802,7 +1808,11 @@ tb_print_fromto(struct pf_rule_addr *src
 			 PF_AZERO(PT_MASK(src), AF_INET6))
 			tbprintf("any ");
 		else {
+#if OS_LEVEL > 35
+			if (src->neg)
+#else		
 			if (src->not)
+#endif
 				tbprintf("! ");
 #ifdef HAVE_ADDR_WRAP
 			tb_print_addrw(&src->addr, PT_MASK(src), af);
@@ -1823,7 +1833,11 @@ tb_print_fromto(struct pf_rule_addr *src
 			 PF_AZERO(PT_MASK(dst), AF_INET6))
 			tbprintf("any ");
 		else {
+#if OS_LEVEL > 35
+			if (dst->neg)
+#else
 			if (dst->not)
+#endif
 				tbprintf("! ");
 #ifdef HAVE_ADDR_WRAP
 			tb_print_addrw(&dst->addr, PT_MASK(dst), af);
@@ -1890,8 +1904,13 @@ print_rule(struct pf_rule *pr)
 #ifdef HAVE_RULE_STATES
 	print_fld_size(FLD_STATS, pr->states);
 #endif
+#if OS_LEVEL > 37
+	print_fld_size(FLD_PKTS, pr->packets[0] + pr->packets[1]);
+	print_fld_size(FLD_BYTES, pr->bytes[0] + pr->bytes[1]);
+#else
 	print_fld_size(FLD_PKTS, pr->packets);
 	print_fld_size(FLD_BYTES, pr->bytes);
+#endif
 	print_fld_uint(FLD_RULE, pr->nr);
 	print_fld_str(FLD_DIR, pr->direction == PF_OUT ? "Out" : "In");
 	if (pr->quick)
@@ -2486,12 +2505,6 @@ sig_resize(int signal)
 }
 
 void
-sig_alarm(int signal)
-{
-	gotsig_alarm = 1;
-}
-
-void
 usage()
 {
 	extern char *__progname;
@@ -2544,7 +2557,9 @@ show_help(void)
 	line++;
 	mvprintw(line++, 6, "press any key to continue ...");
 
+	timeout(-1);
 	while (getch() == ERR);
+	timeout(0);
 }
 
 void
@@ -2577,8 +2592,9 @@ setup_term(int maxstates)
 		keypad(stdscr, TRUE);
 		intrflush(stdscr, FALSE);
 
-		halfdelay(10);
+		cbreak();
 		noecho();
+		timeout(0);
 	}
 
 	if (maxstates == 0)
@@ -2597,7 +2613,6 @@ command_set(struct command *cmd)
 		cmdbuf[0] = 0;
 	}
 	curr_cmd = cmd;
-	need_update = 1;
 	return prev;
 }
 
@@ -2618,10 +2633,8 @@ cmd_delay(void)
 {
 	int del;
 	del = atoi(cmdbuf);
-	if (del > 0) {
+	if (del > 0)
 		delay = del;
-		gotsig_alarm = 1;
-	}
 }
 
 void
@@ -2646,7 +2659,6 @@ cmd_keyboard(int ch)
 		if (cmd_len < sizeof(cmdbuf) - 1) {
 			cmdbuf[cmd_len++] = ch;
 			cmdbuf[cmd_len] = 0;
-			need_update = 1;
 		} else
 			beep();
 	}
@@ -2663,10 +2675,9 @@ cmd_keyboard(int ch)
 	case KEY_BACKSPACE:
 	case KEY_DC:
 	case CTRL_H:
-		if (cmd_len > 0) {
+		if (cmd_len > 0)
 			cmdbuf[--cmd_len] = 0;
-			need_update = 1;
-		} else
+		else
 			beep();
 		break;
 	default:
@@ -2687,9 +2698,6 @@ keyboard(void)
 	}
 
 	switch (ch) {
-	case ' ':
-		gotsig_alarm = 1;
-		break;
 	case 'c':
 		cachestates = !cachestates;
 		update_cache();
@@ -2698,25 +2706,21 @@ keyboard(void)
 		/* FALLTHROUGH */
 	case 'h':
 		show_help();
-		need_update = 1;
 		break;
 	case 'n':
 		command_set(&cm_count);
 		break;
 	case 'o':
 		next_order();
-		need_sort = 1;
 		break;
 	case 'p':
 		paused = !paused;
-		gotsig_alarm = 1;
 		break;
 	case 'q':
 		gotsig_close = 1;
 		break;
 	case 'r':
 		sortdir *= -1;
-		need_sort = 1;
 		break;
 	case 's':
 		command_set(&cm_delay);
@@ -2737,49 +2741,40 @@ keyboard(void)
 		/* FALLTHROUGH */
 	case CTRL_N:
 		dispstart++;
-		need_update = 1;
 		break;
 	case KEY_UP:
 		/* FALLTHROUGH */
 	case CTRL_P:
 		dispstart--;
-		need_update = 1;
 		break;
 	case KEY_NPAGE:
 		/* FALLTHROUGH */
 	case CTRL_V:
 		dispstart += maxprint;
-		need_update = 1;
 		break;
 	case KEY_PPAGE:
 		/* FALLTHROUGH */
 	case META_V:
 		dispstart -= maxprint;
-		need_update = 1;
 		break;
 	case KEY_HOME:
 		/* FALLTHROUGH */
 	case CTRL_A:
 		dispstart = 0;
-		need_update = 1;
 		break;
 	case KEY_END:
 		/* FALLTHROUGH */
 	case CTRL_E:
 		dispstart = num_disp;
-		need_update = 1;
 		break;
 	case CTRL_L:
 		clear();
-		need_update = 1;
 		break;
 	default:
 		break;
 	}
 
-	if (set_order_hotkey(ch))
-		need_sort = 1;
-	else
+	if (!set_order_hotkey(ch))
 		set_view_hotkey(ch);
 }
 
@@ -2790,6 +2785,7 @@ main(int argc, char *argv[])
 	extern int optind;
 
 	struct pf_status status;
+	struct pollfd set[1];
 
 	char *orderstr = NULL;
 	char *viewstr = NULL;
@@ -2872,7 +2868,6 @@ main(int argc, char *argv[])
 	signal(SIGINT, sig_close);
 	signal(SIGQUIT, sig_close);
 	signal(SIGWINCH, sig_resize);
-	signal(SIGALRM, sig_alarm);
 
 #ifdef HAVE_DEVICE_RO
 	dev = open("/dev/pf", O_RDONLY);
@@ -2884,7 +2879,7 @@ main(int argc, char *argv[])
 
 	/* preallocate existing states if possible */
 	if (ioctl(dev, DIOCGETSTATUS, &status)) {
-		warnx("DIOCGETSTATUS");
+		warn("DIOCGETSTATUS");
 		alloc_buf(0);
 	} else
 		alloc_buf(status.states);
@@ -2910,36 +2905,7 @@ main(int argc, char *argv[])
 	if (rawmode && countmax == 0)
 		countmax = 1;
 
-	gotsig_alarm = 1;
 	for (;;) {
-		if (gotsig_alarm) {
-			read_view(dev);
-			need_sort = 1;
-			gotsig_alarm = 0;
-			alarm(delay);
-		}
-
-		if (need_sort) {
-			sort_view();
-			need_sort = 0;
-			need_update = 1;
-			
-			/* XXX if sort took too long */
-			if (gotsig_alarm) {
-				gotsig_alarm = 0;
-				alarm(delay);
-			}
-		}
-
-		if (need_update) {
-			erase();
-			disp_update(dev);
-			end_page();
-			need_update = 0;
-			if (countmax && ++count >= countmax)
-				break;
-		}
-
 		if (gotsig_close)
 			break;
 		if (gotsig_resize) {
@@ -2947,12 +2913,30 @@ main(int argc, char *argv[])
 				endwin();
 			setup_term(maxstates);
 			gotsig_resize = 0;
-			need_update = 1;
 		}
 
-		if (interactive && need_update == 0)
-			keyboard();
-		else if (interactive == 0)
+		read_view(dev);
+		sort_view();
+
+		if (rawmode == 0)
+			erase();
+		disp_update(dev);
+		end_page();
+
+		if (countmax && ++count >= countmax)
+			break;
+
+		if (interactive) {
+			set[0].fd = STDIN_FILENO;
+			set[0].events = POLLIN;
+			if (poll(set, 1, delay * 1000) == -1) {
+				if (errno == EINTR)
+					continue;
+				break;
+			}
+			if ((set[0].revents & POLLIN) != 0)
+				keyboard();
+		} else
 			sleep(delay);
 	}
 
