]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/rpcmisc.c
Detect if glibc provides socklen_t and use that instead
[nfs-utils.git] / support / nfs / rpcmisc.c
index 4c0906d883e35629e7f7d329bbb40a8b54d978f3..5b0a88ff76745ea86c019718272bd3c10c66fa77 100644 (file)
@@ -12,7 +12,9 @@
  * as is, with no warranty expressed or implied.
  */
 
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <time.h>
 #include "nfslib.h"
 
+#if SIZEOF_SOCKLEN_T - 0 == 0
+#define socklen_t int
+#endif
+
 static void    closedown(int sig);
 int    makesock(int port, int proto);
 
@@ -46,20 +52,26 @@ rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport)
        struct sockaddr_in saddr;
        SVCXPRT *transp;
        int     sock;
-       int     asize;
+       socklen_t asize;
 
        asize = sizeof(saddr);
        sock = 0;
-       if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0) {
-               int ssize = sizeof (int);
-               _rpcfdtype = 0;
-               if (saddr.sin_family != AF_INET)
-                       xlog(L_FATAL, "init: stdin is bound to non-inet addr");
+       if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0
+           && saddr.sin_family == AF_INET) {
+               socklen_t ssize = sizeof (int);
+               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 +79,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 +109,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 +147,6 @@ int sig;
 {
        (void) signal(sig, closedown);
        if (_rpcsvcdirty == 0) {
-               extern fd_set svc_fdset;
                static int size;
                int i, openfd;
 
@@ -213,10 +232,12 @@ rpc_logcall(struct svc_req *rqstp, char *xname, char *arg)
                break;
        case AUTH_UNIX: {
                struct authunix_parms *unix_cred;
+               time_t time;
                struct tm *tm;
 
                unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
-               tm = localtime(&unix_cred->aup_time);
+               time = unix_cred->aup_time;
+               tm = localtime(&time);
                snprintf(sp, buflen, "UNIX %d/%d/%d %02d:%02d:%02d %s %d.%d",
                        tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
                        tm->tm_hour, tm->tm_min, tm->tm_sec,