]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/rpcmisc.c
Fix rpc_init so it isn't confused by ssh
[nfs-utils.git] / support / nfs / rpcmisc.c
index 4c0906d883e35629e7f7d329bbb40a8b54d978f3..1c02364cecb153e6f33886b3b40499d97268d4ea 100644 (file)
@@ -50,16 +50,22 @@ rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport)
 
        asize = sizeof(saddr);
        sock = 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);
-               _rpcfdtype = 0;
-               if (saddr.sin_family != AF_INET)
-                       xlog(L_FATAL, "init: stdin is bound to non-inet addr");
+               int fdtype = 0;
                if (getsockopt(0, SOL_SOCKET, SO_TYPE,
-                               (char *)&_rpcfdtype, &ssize) == -1)
+                               (char *)&fdtype, &ssize) == -1)
                        xlog(L_FATAL, "getsockopt failed: %s", strerror(errno));
-               _rpcpmstart = 1;
-       } else {
+               /* inetd passes a UDP socket or a listening TCP socket.
+                * listen will fail on a connected TCP socket(passed by rsh).
+                */
+               if (!(fdtype == SOCK_STREAM && listen(0,5) == -1)) {
+                       _rpcfdtype = fdtype;
+                       _rpcpmstart = 1;
+               }
+       }
+       if (!_rpcpmstart) {
                pmap_unset(prog, vers);
                sock = RPC_ANYSOCK;
        }
@@ -67,17 +73,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)) < 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 +103,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)) < 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 +141,6 @@ int sig;
 {
        (void) signal(sig, closedown);
        if (_rpcsvcdirty == 0) {
-               extern fd_set svc_fdset;
                static int size;
                int i, openfd;