]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/rpcmisc.c
Define and use get_reliable_hostbyname
[nfs-utils.git] / support / nfs / rpcmisc.c
index 457d642558c2c705ac0ea97a9d0a594ed5b536d1..ca63c8142975940557ba6ed9470e594d720f284a 100644 (file)
 #include <memory.h>
 #include <errno.h>
 #include <unistd.h>
+#include <time.h>
 #include "nfslib.h"
 
 static void    closedown(int sig);
-static int     makesock(int port, int proto, int socksz);
+int    makesock(int port, int proto);
 
 #define _RPCSVC_CLOSEDOWN      120
 int    _rpcpmstart = 0;
@@ -40,8 +41,7 @@ int   _rpcfdtype = 0;
 int    _rpcsvcdirty = 0;
 
 void
-rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport,
-                                                       int bufsiz)
+rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport)
 {
        struct sockaddr_in saddr;
        SVCXPRT *transp;
@@ -50,11 +50,10 @@ rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport,
 
        asize = sizeof(saddr);
        sock = 0;
-       _rpcfdtype = 0;
-       if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0) {
+       if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0
+           && saddr.sin_family == AF_INET) {
                int ssize = sizeof (int);
-               if (saddr.sin_family != AF_INET)
-                       xlog(L_FATAL, "init: stdin is bound to non-inet addr");
+               _rpcfdtype = 0;
                if (getsockopt(0, SOL_SOCKET, SO_TYPE,
                                (char *)&_rpcfdtype, &ssize) == -1)
                        xlog(L_FATAL, "getsockopt failed: %s", strerror(errno));
@@ -67,17 +66,21 @@ rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport,
        if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
                static SVCXPRT *last_transp = NULL;
  
-               if (_rpcfdtype == 0) {
+               if (_rpcpmstart == 0) {
                        if (last_transp
                            && (!defport || defport == last_transp->xp_port)) {
                                transp = last_transp;
                                goto udp_transport;
                        }
-                       if ((sock = makesock(defport, IPPROTO_UDP, bufsiz)) < 0) {
+                       if (defport == 0)
+                               sock = RPC_ANYSOCK;
+                       else if ((sock = makesock(defport, IPPROTO_UDP)) < 0) {
                                xlog(L_FATAL, "%s: cannot make a UDP socket\n",
                                                name);
                        }
                }
+               if (sock == RPC_ANYSOCK)
+                       sock = svcudp_socket (prog, 1);
                transp = svcudp_create(sock);
                if (transp == NULL) {
                        xlog(L_FATAL, "cannot create udp service.");
@@ -93,17 +96,21 @@ rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport,
        if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
                static SVCXPRT *last_transp = NULL;
 
-               if (_rpcfdtype == 0) {
+               if (_rpcpmstart == 0) {
                        if (last_transp
                            && (!defport || defport == last_transp->xp_port)) {
                                transp = last_transp;
                                goto tcp_transport;
                        }
-                       if ((sock = makesock(defport, IPPROTO_TCP, bufsiz)) < 0) {
+                       if (defport == 0)
+                               sock = RPC_ANYSOCK;
+                       else if ((sock = makesock(defport, IPPROTO_TCP)) < 0) {
                                xlog(L_FATAL, "%s: cannot make a TCP socket\n",
                                                name);
                        }
                }
+               if (sock == RPC_ANYSOCK)
+                       sock = svctcp_socket (prog, 1);
                transp = svctcp_create(sock, 0, 0);
                if (transp == NULL) {
                        xlog(L_FATAL, "cannot create tcp service.");
@@ -127,7 +134,6 @@ int sig;
 {
        (void) signal(sig, closedown);
        if (_rpcsvcdirty == 0) {
-               extern fd_set svc_fdset;
                static int size;
                int i, openfd;
 
@@ -145,10 +151,7 @@ int sig;
        (void) alarm(_RPCSVC_CLOSEDOWN);
 }
 
-static int makesock(port, proto, socksz)
-int port;
-int proto;
-int socksz;
+int makesock(int port, int proto)
 {
        struct sockaddr_in sin;
        int     s;
@@ -171,6 +174,9 @@ int socksz;
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
                xlog(L_ERROR, "setsockopt failed: %s\n", strerror(errno));
 
+#if 0
+       /* I was told it didn't work with gigabit ethernet.
+          Don't bothet with it.  H.J. */
 #ifdef SO_SNDBUF
        {
                int sblen, rblen;
@@ -182,6 +188,7 @@ int socksz;
                        xlog(L_ERROR, "setsockopt failed: %s\n", strerror(errno));
        }
 #endif                         /* SO_SNDBUF */
+#endif
 
        if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
                xlog(L_FATAL, "Could not bind name to socket: %s\n",