$NetBSD: patch-ab,v 1.4 2006/03/06 23:02:08 peter Exp $

--- pftop.c.orig	2003-08-05 03:20:39.000000000 +0200
+++ pftop.c	2006-03-06 23:52:20.000000000 +0100
@@ -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>
@@ -39,7 +44,11 @@
 #include <netinet/in.h>
 #define TCPSTATES
 #include <netinet/tcp_fsm.h>
+#ifdef __DragonFly__
+#include <net/pf/pfvar.h>
+#else
 #include <net/pfvar.h>
+#endif
 #include <arpa/inet.h>
 
 #ifdef HAVE_ALTQ
@@ -54,7 +63,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 +203,6 @@
 
 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 +514,6 @@
 
 int
 tbprintf(char *format, ...)
-	GCC_PRINTFLIKE(1,2)       /* defined in curses.h */
 {
 	int len;
 	va_list arg;
@@ -543,6 +550,10 @@
 	}
 }
 
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
 void
 print_str(int len, const char *str)
 {
@@ -758,7 +769,6 @@
 	}
 
 	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 +776,6 @@
 	curr_view = v;
 	curr_mgr = v->mgr;
 	field_setup();
-	need_update = 1;
 }
 
 void
@@ -849,11 +858,9 @@
 	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 +1219,7 @@
 		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 +1310,7 @@
 		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 +1326,10 @@
 		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 +1655,7 @@
 		dispstart = 0;
 
 	if (ioctl(dev, DIOCGETSTATUS, &status)) {
-		warnx("DIOCGETSTATUS");
+		warn("DIOCGETSTATUS");
 		return (-1);
 	}
 
@@ -1681,7 +1691,7 @@
 
 	memset(&pr, 0, sizeof(pr));
 	if (ioctl(dev, DIOCGETRULES, &pr)) {
-		warnx("DIOCGETRULES");
+		warn("DIOCGETRULES");
 		return (-1);
 	}
 
@@ -1704,7 +1714,7 @@
 	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 +1812,11 @@
 			 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 +1837,11 @@
 			 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 +1908,13 @@
 #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 +2509,6 @@
 }
 
 void
-sig_alarm(int signal)
-{
-	gotsig_alarm = 1;
-}
-
-void
 usage()
 {
 	extern char *__progname;
@@ -2544,7 +2561,9 @@
 	line++;
 	mvprintw(line++, 6, "press any key to continue ...");
 
+	timeout(-1);
 	while (getch() == ERR);
+	timeout(0);
 }
 
 void
@@ -2577,8 +2596,9 @@
 		keypad(stdscr, TRUE);
 		intrflush(stdscr, FALSE);
 
-		halfdelay(10);
+		cbreak();
 		noecho();
+		timeout(0);
 	}
 
 	if (maxstates == 0)
@@ -2597,7 +2617,6 @@
 		cmdbuf[0] = 0;
 	}
 	curr_cmd = cmd;
-	need_update = 1;
 	return prev;
 }
 
@@ -2618,10 +2637,8 @@
 {
 	int del;
 	del = atoi(cmdbuf);
-	if (del > 0) {
+	if (del > 0)
 		delay = del;
-		gotsig_alarm = 1;
-	}
 }
 
 void
@@ -2646,7 +2663,6 @@
 		if (cmd_len < sizeof(cmdbuf) - 1) {
 			cmdbuf[cmd_len++] = ch;
 			cmdbuf[cmd_len] = 0;
-			need_update = 1;
 		} else
 			beep();
 	}
@@ -2663,10 +2679,9 @@
 	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 +2702,6 @@
 	}
 
 	switch (ch) {
-	case ' ':
-		gotsig_alarm = 1;
-		break;
 	case 'c':
 		cachestates = !cachestates;
 		update_cache();
@@ -2698,25 +2710,21 @@
 		/* 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 +2745,40 @@
 		/* 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 +2789,7 @@
 	extern int optind;
 
 	struct pf_status status;
+	struct pollfd set[1];
 
 	char *orderstr = NULL;
 	char *viewstr = NULL;
@@ -2872,7 +2872,6 @@
 	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 +2883,7 @@
 
 	/* preallocate existing states if possible */
 	if (ioctl(dev, DIOCGETSTATUS, &status)) {
-		warnx("DIOCGETSTATUS");
+		warn("DIOCGETSTATUS");
 		alloc_buf(0);
 	} else
 		alloc_buf(status.states);
@@ -2910,36 +2909,7 @@
 	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 +2917,30 @@
 				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);
 	}
 
