diff -ru tcpspy-1.7/rule.c tcpspy-1.7c/rule.c
--- tcpspy-1.7/rule.c	Fri Jun  1 22:22:54 2001
+++ tcpspy-1.7c/rule.c	Thu Jan 10 15:57:44 2002
@@ -3,7 +3,7 @@
  *
  * This file is part of tcpspy, a TCP/IP connection monitor. 
  *
- * Copyright (c) 2000, 2001 Tim J. Robbins. 
+ * Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@
 
 #include <assert.h>
 #include <fnmatch.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -494,6 +495,20 @@
 	rule_lexer_scan_string (r);
 	if (ruleparse () != 0)
 		abort ();
+}
+
+/*
+ * rule_parse_file ()
+ *
+ * Parse and compile the specified open file.
+ */
+void rule_parse_file (FILE *fp)
+{
+	extern void rulerestart (FILE *);
+	extern int ruleparse (void);
+
+	rulerestart (fp);
+	ruleparse ();
 }
 
 /*
diff -ru tcpspy-1.7/rule.h tcpspy-1.7c/rule.h
--- tcpspy-1.7/rule.h	Fri Jun  1 22:22:51 2001
+++ tcpspy-1.7c/rule.h	Thu Jan 10 15:57:44 2002
@@ -3,7 +3,7 @@
  *
  * This file is part of tcpspy, a TCP/IP connection monitor. 
  *
- * Copyright (c) 2000, 2001 Tim J. Robbins. 
+ * Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
 
 #include <netinet/in.h>
 #include <sys/types.h>
+#include <stdio.h>
 #include <unistd.h>
 
 void rule_gen_user (uid_t uid);
@@ -50,6 +51,7 @@
 int rule_eval (uid_t muid, u_int32_t mladdr, u_int16_t mlport,
 		u_int32_t mraddr, u_int16_t mrport, const char *mexe);
 void rule_parse (const char *r);
+void rule_parse_file (FILE *fp);
 
 unsigned long st_store (const char *s);
 
diff -ru tcpspy-1.7/rule_grammar.y tcpspy-1.7c/rule_grammar.y
--- tcpspy-1.7/rule_grammar.y	Fri Jun  1 22:22:48 2001
+++ tcpspy-1.7c/rule_grammar.y	Thu Jan 10 15:57:44 2002
@@ -4,7 +4,7 @@
  *
  * This file is part of tcpspy, a TCP/IP connection monitor.
  *
- * Copyright (c) 2000, 2001 Tim J. Robbins. 
+ * Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,8 @@
 int yyerror ();
 extern int yylex ();
 
+extern int firstrule;
+
 %}
 
 %union {
@@ -76,8 +78,12 @@
 
 %%
 
-ruleset	:	/* empty */
-	|	rule ruleset
+ruleset	:	rule ruleset		{
+	if (!firstrule) rule_gen_or ();
+	firstrule = 0;
+}
+
+	|	/* empty */		{ } 
 	;
 
 rule	:	rule OR rule		{ rule_gen_or (); }
diff -ru tcpspy-1.7/rule_lexer.l tcpspy-1.7c/rule_lexer.l
--- tcpspy-1.7/rule_lexer.l	Fri Jun  1 22:22:48 2001
+++ tcpspy-1.7c/rule_lexer.l	Thu Jan 10 15:57:44 2002
@@ -4,7 +4,7 @@
  *
  * This file is part of tcpspy, a TCP/IP connection monitor. 
  *
- * Copyright (c) 2000, 2001 Tim J. Robbins. 
+ * Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -179,6 +179,8 @@
 			rulelval.exe = st_store (yytext + 1);
 			return EXE_SPEC;
 			}
+
+<*>#.*\n		{ /* eat comments */ }
 
 <*>[ \n\t]		{ /* whitespace is ignored */ }
 
diff -ru tcpspy-1.7/tcpspy.8 tcpspy-1.7c/tcpspy.8
--- tcpspy-1.7/tcpspy.8	Fri Jun  1 22:24:06 2001
+++ tcpspy-1.7c/tcpspy.8	Thu Jan 10 15:57:44 2002
@@ -1,6 +1,6 @@
 .\" This file is part of tcpspy, a TCP/IP connection monitor.
 .\"
-.\" Copyright (c) 2000, 2001 Tim J. Robbins. 
+.\" Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
 .\" All rights reserved.
 .\" 
 .\" Redistribution and use in source and binary forms, with or without
@@ -251,6 +251,11 @@
 .TP
 tcpspy -e 'exe "/usr/bin/irc"'
 Log connections made by /usr/bin/irc (probably ircII).
+
+.SH BUGS
+Empty rule files cause
+.B tcpspy
+to log no connections instead of all connections.
 
 .SH AUTHOR
 Tim J. Robbins <tim@robbins.dropbear.id.au>
diff -ru tcpspy-1.7/tcpspy.c tcpspy-1.7c/tcpspy.c
--- tcpspy-1.7/tcpspy.c	Fri Jun  1 22:22:59 2001
+++ tcpspy-1.7c/tcpspy.c	Thu Jan 10 16:01:26 2002
@@ -3,7 +3,7 @@
  *
  * This file is part of tcpspy, a TCP/IP connection monitor.
  *
- * Copyright (c) 2000, 2001 Tim J. Robbins. 
+ * Copyright (c) 2000, 2001, 2002 Tim J. Robbins. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $Id: tcpspy.c,v 1.39 2001/06/01 12:18:45 tim Stab $
+ * $Id: tcpspy.c,v 1.39.1.3 2001/07/02 11:55:36 tim Stab $
  */
 
 #include <arpa/inet.h>
@@ -59,7 +59,7 @@
 #include "rcsid.h"
 #include "rule.h"
 
-RCSID("$Id: tcpspy.c,v 1.39 2001/06/01 12:18:45 tim Stab $");
+RCSID("$Id: tcpspy.c,v 1.39.1.3 2001/07/02 11:55:36 tim Stab $");
 
 /*
  * Defaults for compile-time settings. Descriptions of these are in
@@ -229,8 +229,10 @@
 	while (fgets (buf, sizeof (buf), fp) != NULL) {
 		unsigned long st;
 
-		if (sscanf (buf, "%*d: %lx:%lx %lx:%lx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu", &c.lcl, &c.lclp, &c.rmt, &c.rmtp, &st, &c.uid, &c.ino) != 7)
-			panic ("/proc/net/tcp: bad file format");
+		if (sscanf (buf, "%*d: %lx:%lx %lx:%lx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu", &c.lcl, &c.lclp, &c.rmt, &c.rmtp, &st, &c.uid, &c.ino) != 7) {
+			logmsg ("/proc/net/tcp: warning: incomplete line");
+			continue;
+		}
 		if ((c.ino == 0) || (st != TCP_ESTABLISHED)) continue;
 		if (showprocs != 0)
 			huntinode ((ino_t) c.ino, c.exe, sizeof (c.exe));
@@ -354,7 +356,7 @@
 	char uidbuf[32];
 	char *user;
 	struct servent *se;
-	char lport[6], rport[6]; /* assume 16 bit unsigned */
+	char lport[64], rport[64];
 
 	assert (c != NULL);
 	assert (action != NULL);
@@ -458,10 +460,12 @@
 static void usage (void)
 {
 	fprintf (stderr, "usage: tcpspy [-dp] [-e rule]... [-f rulefile] [-I interval] "
-			"[-U user] [-G group]\n\t[-F facility] [-I interval]\n");
+			"[-U user]\n\t[-G group] [-F facility] [-I interval]\n");
 	exit (EXIT_FAILURE);
 }
 
+int firstrule = 1;
+
 int main (int argc, char *argv[])
 {
 	conntable_t old, new;
@@ -469,7 +473,7 @@
 	int ch;
 	uid_t dropuser = -1;
 	gid_t dropgroup = -1, defgroup = -1;
-	int debug = 0, firstrule = 1;
+	int debug = 0;
 
 	log_set_syslog ();
 
@@ -496,41 +500,21 @@
 					 */
 					rule_gen_or ();
 				firstrule = 0;
+				/* Hide rule from `ps' */
+				memset (optarg, '\0', strlen (optarg));
 				break;
 			case 'f':
 			{
 				FILE *fp;
-				char fbuf[512];
-				unsigned lineno = 0;
-				char *c;
+
+				gotrule = 1; /* XXX */
 
 				if ((fp = fopen (optarg, "r")) == NULL) {
 					fprintf (stderr, "tcpspy: %s: %s\n", optarg, strerror (errno));
 					exit (EXIT_FAILURE);
 				}
 
-				while (fgets (fbuf, sizeof fbuf, fp) != NULL) {
-					lineno++;
-					if (fbuf[strlen (fbuf) - 1] != '\n') {
-						fprintf (stderr, "tcpspy: %s:%u: line too long or missing newline\n", optarg, lineno);
-						exit (EXIT_FAILURE);
-					}
-					/*
-					 * Remove newline, remove comments.
-					 */
-					fbuf[strlen (fbuf) - 1] = '\0';
-					if ((c = strchr (fbuf, '#')) != NULL)
-						*c = '\0';
-					/*
-					 * Skip blank lines or whole line comments.
-					 */
-					if (*fbuf == '\0') continue;
-
-					rule_parse (fbuf);
-					if (firstrule == 0) rule_gen_or ();
-					gotrule = 1;
-					firstrule = 0;
-				}
+				rule_parse_file (fp);
 
 				fclose (fp);
 			}
@@ -617,18 +601,30 @@
 	}
 
 	/*
-	 * Become a daemon..
+	 * Become a daemon by double-forking and detaching completely from
+	 * the terminal.
 	 */
 
 	if (debug == 0) {
 		pid_t p;
+
+		/* 1st fork */
+		p = fork();
+		if (p < 0) {
+			fprintf (stderr, "tcpspy: fork: %s\n",
+					strerror (errno));
+			exit (EXIT_FAILURE);
+		} else if (p != 0)
+			exit (0);
+
+		/* 2nd fork */
 		p = fork();
 		if (p < 0) {
 			fprintf (stderr, "tcpspy: fork: %s\n",
 					strerror (errno));
 			exit (EXIT_FAILURE);
 		} else if (p != 0) {
-			fprintf (stderr, "tcpspy 1.7 started (pid %d)\n", 
+			fprintf (stderr, "tcpspy 1.7c started (pid %d)\n", 
 					(int) p);
 			exit (EXIT_SUCCESS);
 		}
@@ -637,8 +633,10 @@
 		close (STDIN_FILENO); 
 		close (STDOUT_FILENO); 
 		close (STDERR_FILENO);
+		setpgid (0, 0);
+		chdir ("/");
 	} else
-		fprintf (stderr, "tcpspy 1.7 started (debug)\n");
+		fprintf (stderr, "tcpspy 1.7c started (debug)\n");
 
 	signal (SIGTERM, stopsig);
 	if (debug != 0) signal (SIGINT, stopsig);
