diff options
author | H. Peter Anvin <hpa@zytor.com> | 2004-06-17 07:40:58 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2004-06-17 07:40:58 +0000 |
commit | b9a218665802eeedb779c2a6adc5d51221577846 (patch) | |
tree | 5e81ddf480d46fdc96155acc5c0c159a290fbe23 | |
parent | 1b28a5ad13f2b8b212f771d77c47c6f49cac4bed (diff) | |
download | klibc-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.c | 23 | ||||
-rw-r--r-- | nfsmount/dummypmap.h | 4 | ||||
-rw-r--r-- | nfsmount/main.c | 38 |
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); |