aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2004-06-17 07:40:58 +0000
committerH. Peter Anvin <hpa@zytor.com>2004-06-17 07:40:58 +0000
commitb9a218665802eeedb779c2a6adc5d51221577846 (patch)
tree5e81ddf480d46fdc96155acc5c0c159a290fbe23
parent1b28a5ad13f2b8b212f771d77c47c6f49cac4bed (diff)
downloadklibc-b9a218665802eeedb779c2a6adc5d51221577846.tar.gz
Break up the portmap spoofer into a bind function and a listenklibc-0.145
function, so we can call the bind function before forking. Also, waitpid() at the end so we don't make zombies.
-rw-r--r--nfsmount/dummypmap.c23
-rw-r--r--nfsmount/dummypmap.h4
-rw-r--r--nfsmount/main.c38
3 files changed, 45 insertions, 20 deletions
diff --git a/nfsmount/dummypmap.c b/nfsmount/dummypmap.c
index adf64c9e6fe89..0a900ca501a5f 100644
--- a/nfsmount/dummypmap.c
+++ b/nfsmount/dummypmap.c
@@ -34,18 +34,10 @@ struct portmap_reply
__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 @@ int dummy_portmap(void)
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 2625133d9114f..b67ed1941b198 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 c5eae47a4e886..a50d13cc0df0e 100644
--- a/nfsmount/main.c
+++ b/nfsmount/main.c
@@ -164,6 +164,7 @@ int nfsmount_main(int argc, char *argv[])
char *path;
int c;
int spoof_portmap = 0;
+ FILE *portmap_file = NULL;
progname = argv[0];
@@ -221,14 +222,30 @@ int nfsmount_main(int argc, char *argv[])
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 @@ int nfsmount_main(int argc, char *argv[])
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);