Break up the portmap spoofer into a bind function and a listen
function, so we can call the bind function before forking.  Also,
waitpid() at the end so we don't make zombies.

diff --git a/nfsmount/dummypmap.c b/nfsmount/dummypmap.c
index adf64c9..0a900ca 100644
--- a/nfsmount/dummypmap.c
+++ b/nfsmount/dummypmap.c
@@ -34,18 +34,10 @@
         __u32 port;
 };
 
-FILE *portmap_file = 0;
-
-int dummy_portmap(void)
+int bind_portmap(void)
 {
 	int sock = socket(PF_INET, SOCK_DGRAM, 0);
 	struct sockaddr_in sin;
-	int pktlen, addrlen;
-	union {
-		struct portmap_call c;
-		unsigned char b[65536];	/* Max UDP packet size */
-	} pkt;
-	struct portmap_reply rply;
 	
 	if ( sock < 0 )
 		return -1;
@@ -61,6 +53,19 @@
 		return -1;
 	}
 	
+	return sock;
+}
+
+int dummy_portmap(int sock, FILE *portmap_file)
+{
+	struct sockaddr_in sin;
+	int pktlen, addrlen;
+	union {
+		struct portmap_call c;
+		unsigned char b[65536];	/* Max UDP packet size */
+	} pkt;
+	struct portmap_reply rply;
+	
 	for(;;) {
 		addrlen = sizeof sin;
 		pktlen = recvfrom(sock, &pkt.c.rpc.hdr.udp, sizeof pkt, 0,
diff --git a/nfsmount/dummypmap.h b/nfsmount/dummypmap.h
index 2625133..b67ed19 100644
--- a/nfsmount/dummypmap.h
+++ b/nfsmount/dummypmap.h
@@ -6,6 +6,6 @@
 
 #include <stdio.h>
 
-extern FILE *portmap_file;
-int dummy_portmap(void);
+int bind_portmap(void);
+int dummy_portmap(int sock, FILE *portmap_file);
 
diff --git a/nfsmount/main.c b/nfsmount/main.c
index c5eae47..a50d13c 100644
--- a/nfsmount/main.c
+++ b/nfsmount/main.c
@@ -164,6 +164,7 @@
 	char *path;
 	int c;
 	int spoof_portmap = 0;
+	FILE *portmap_file = NULL;
 
 	progname = argv[0];
 
@@ -221,14 +222,30 @@
 	check_path(path);
 
 	if ( spoof_portmap ) {
-		spoof_portmap = fork();
-		if ( spoof_portmap == -1 ) {
-			fprintf(stderr, "%s: cannot fork\n", progname);
-			exit(1);
-		} else if ( spoof_portmap == 0 ) {
-			/* Child process */
-			dummy_portmap();
-			_exit(255); /* Error */
+		int sock = bind_portmap();
+
+		if ( sock == -1 ) {
+			if ( errno == EINVAL || errno == EADDRINUSE )
+				spoof_portmap = 0; /* Assume not needed */
+			else {
+				fprintf(stderr,
+					"%s: portmap spoofing failed\n",
+					progname);
+				exit(1);
+			}
+		} else {
+			spoof_portmap = fork();
+			if ( spoof_portmap == -1 ) {
+				fprintf(stderr, "%s: cannot fork\n", progname);
+				exit(1);
+			} else if ( spoof_portmap == 0 ) {
+				/* Child process */
+				dummy_portmap(sock, portmap_file);
+				_exit(255); /* Error */
+			} else {
+				/* Parent process */
+				close(sock);
+			}
 		}
 	}
 
@@ -237,8 +254,11 @@
 		return 1;
 
 	/* If we set up the spoofer, tear it down now */
-	if ( spoof_portmap )
+	if ( spoof_portmap ) {
 		kill(SIGTERM, spoof_portmap);
+		while ( waitpid(spoof_portmap, NULL, 0) == -1 &&
+			errno == EINTR );
+	}
 
 	free(rem_name);