]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/nfsmount.c
mount.nfs: Move network functions into a common source module
[nfs-utils.git] / utils / mount / nfsmount.c
index 4b862f05a3f7f8aee7dfa2b4f5534450b874260d..9c08ff5837b22d4b18115e25a3e948ccade47edb 100644 (file)
@@ -64,6 +64,7 @@
 #include "mount_constants.h"
 #include "nls.h"
 #include "error.h"
+#include "network.h"
 
 #ifndef NFS_PORT
 #define NFS_PORT 2049
@@ -93,269 +94,6 @@ extern int sloppy;
 
 extern int linux_version_code();
 
-static const unsigned int probe_udp_only[] = {
-       IPPROTO_UDP,
-       0,
-};
-
-static const unsigned int probe_udp_first[] = {
-       IPPROTO_UDP,
-       IPPROTO_TCP,
-       0,
-};
-
-static const unsigned int probe_tcp_first[] = {
-       IPPROTO_TCP,
-       IPPROTO_UDP,
-       0,
-};
-
-static const unsigned long probe_nfs2_only[] = {
-       2,
-       0,
-};
-
-static const unsigned long probe_nfs3_first[] = {
-       3,
-       2,
-       0,
-};
-
-static const unsigned long probe_mnt1_first[] = {
-       1,
-       2,
-       0,
-};
-
-static const unsigned long probe_mnt3_first[] = {
-       3,
-       1,
-       2,
-       0,
-};
-
-int nfs_gethostbyname(const char *, struct sockaddr_in *);
-int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
-{
-       struct hostent *hp;
-
-       saddr->sin_family = AF_INET;
-       if (!inet_aton(hostname, &saddr->sin_addr)) {
-               if ((hp = gethostbyname(hostname)) == NULL) {
-                       fprintf(stderr, _("mount: can't get address for %s\n"),
-                               hostname);
-                       return 0;
-               } else {
-                       if (hp->h_length > sizeof(*saddr)) {
-                               fprintf(stderr,
-                                       _("mount: got bad hp->h_length\n"));
-                               hp->h_length = sizeof(*saddr);
-                       }
-                       memcpy(&saddr->sin_addr, hp->h_addr, hp->h_length);
-               }
-       }
-       return 1;
-}
-
-/*
- * getport() is very similar to pmap_getport() with
- * the exception this version uses a non-reserve ports 
- * instead of reserve ports since reserve ports
- * are not needed for pmap requests.
- */
-u_short
-getport(
-       struct sockaddr_in *saddr, 
-       u_long prog, 
-       u_long vers, 
-       u_int prot)
-{
-       u_short port = 0;
-       int    socket;
-       CLIENT *clnt = NULL;
-       struct pmap parms;
-       enum clnt_stat stat;
-
-       saddr->sin_port = htons (PMAPPORT);
-       socket = get_socket(saddr, prot, FALSE, FALSE);
-
-       switch (prot) {
-       case IPPROTO_UDP:
-               clnt = clntudp_bufcreate(saddr,
-                                        PMAPPROG, PMAPVERS, TIMEOUT, &socket,
-                                        UDPMSGSIZE, UDPMSGSIZE);
-               break;
-       case IPPROTO_TCP:
-               clnt = clnttcp_create(saddr,
-                       PMAPPROG, PMAPVERS, &socket, 50, 500);
-               break;
-       }
-       if (clnt != NULL) {
-               parms.pm_prog = prog;
-               parms.pm_vers = vers;
-               parms.pm_prot = prot;
-               parms.pm_port = 0;    /* not needed or used */
-
-               stat = clnt_call(clnt, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap,
-                       (caddr_t)&parms, (xdrproc_t)xdr_u_short, (caddr_t)&port, TIMEOUT);
-               if (stat) {
-                       clnt_geterr(clnt, &rpc_createerr.cf_error);
-                       rpc_createerr.cf_stat = stat;
-               }
-               clnt_destroy(clnt);
-               if (stat != RPC_SUCCESS)
-                       port = 0;
-               else if (port == 0)
-                       rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
-       }
-       if (socket != 1)
-               close(socket);
-
-       return port;
-}
-
-/*
- * Use the portmapper to discover whether or not the service we want is
- * available. The lists 'versions' and 'protos' define ordered sequences
- * of service versions and udp/tcp protocols to probe for.
- */
-static int
-probe_port(clnt_addr_t *server, 
-          const u_long *versions,
-          const u_int *protos)
-{
-       struct sockaddr_in *saddr = &server->saddr;
-       struct pmap *pmap = &server->pmap;
-       const u_long prog = pmap->pm_prog, *p_vers;
-       const u_int prot = (u_int)pmap->pm_prot,
-               *p_prot;
-       const u_short port = (u_short) pmap->pm_port;
-       u_long vers = pmap->pm_vers;
-       u_short p_port;
-       p_prot = prot ? &prot : protos;
-       p_vers = vers ? &vers : versions;
-       rpc_createerr.cf_stat = 0;
-       for (;;) {
-               saddr->sin_port = htons(PMAPPORT);
-               p_port = getport(saddr, prog, *p_vers, *p_prot);
-               if (p_port) {
-                       if (!port || port == p_port) {
-                               saddr->sin_port = htons(p_port);
-                               if (verbose) {
-                                       fprintf(stderr, 
-                                               "mount: trying %s prog %ld vers %ld prot %s port %d\n", 
-                                               inet_ntoa(saddr->sin_addr), prog, *p_vers,
-                                               *p_prot == IPPROTO_UDP ? "udp" : "tcp", p_port);
-                               }
-                               if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
-                                       goto out_ok;
-                               if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
-                                       goto out_bad;
-                       }
-               }
-               if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED) 
-                       goto out_bad;
-
-               if (!prot) {
-                       if (*++p_prot)
-                               continue;
-                       p_prot = protos;
-               }
-               if (vers == pmap->pm_vers) {
-                       p_vers = versions;
-                       vers = 0;
-               }
-               if (vers || !*++p_vers)
-                       break;
-       }
-out_bad:
-       return 0;
-
- out_ok:
-       if (!vers)
-               pmap->pm_vers = *p_vers;
-       if (!prot)
-               pmap->pm_prot = *p_prot;
-       if (!port)
-               pmap->pm_port = p_port;
-       rpc_createerr.cf_stat = 0;
-       return 1;
-}
-
-static int probe_nfsport(clnt_addr_t *nfs_server)
-{
-       struct pmap *pmap = &nfs_server->pmap;
-
-       if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
-               return 1;
-
-       if (nfs_mount_data_version >= 4)
-               return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first);
-       else
-               return probe_port(nfs_server, probe_nfs2_only, probe_udp_only);
-}
-
-int probe_mntport(clnt_addr_t *mnt_server)
-{
-       struct pmap *pmap = &mnt_server->pmap;
-
-       if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
-               return 1;
-
-       if (nfs_mount_data_version >= 4)
-               return probe_port(mnt_server, probe_mnt3_first, probe_udp_first);
-       else
-               return probe_port(mnt_server, probe_mnt1_first, probe_udp_only);
-}
-
-static int
-probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
-{
-       struct pmap *nfs_pmap = &nfs_server->pmap;
-       struct pmap *mnt_pmap = &mnt_server->pmap;
-       struct pmap save_nfs, save_mnt;
-       int res;
-       const unsigned long *probe_vers;
-
-       if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
-               nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
-       else if (nfs_pmap->pm_vers && !mnt_pmap->pm_vers)
-               mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
-       if (nfs_pmap->pm_vers)
-               goto version_fixed;
-
-       memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
-       memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
-       probe_vers = (nfs_mount_data_version >= 4) ?
-                       probe_mnt3_first : probe_mnt1_first;
-
-       for (; *probe_vers; probe_vers++) {
-               nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
-               if ((res = probe_nfsport(nfs_server) != 0)) {
-                       mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
-                       if ((res = probe_mntport(mnt_server)) != 0)
-                               return 1;
-                       memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
-               }
-               switch (rpc_createerr.cf_stat) {
-               case RPC_PROGVERSMISMATCH:
-               case RPC_PROGNOTREGISTERED:
-                       break;
-               default:
-                       goto out_bad;
-               }
-               memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
-       }
-
-out_bad:
-       return 0;
-
-version_fixed:
-       if (!probe_nfsport(nfs_server))
-               goto out_bad;
-       return probe_mntport(mnt_server);
-}
-
 static inline enum clnt_stat
 nfs3_mount(CLIENT *clnt, mnt3arg_t *mnt3arg, mnt3res_t *mnt3res)
 {