X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=74224ffdad2a0e477b65b05748384c2d3d51f279;hp=008fdbc7c9846f41100b3921ea657cad53adb3a0;hb=df6c9d1821585c773297fbfffa1dd315b9c84359;hpb=bac279da80ae860267e8485d7fe2109096a326e9 diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index 008fdbc..74224ff 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -35,6 +35,7 @@ #include #include +#include "sockaddr.h" #include "xcommon.h" #include "mount.h" #include "nls.h" @@ -82,7 +83,7 @@ struct nfsmount_info { *node, /* mounted-on dir */ *type; /* "nfs" or "nfs4" */ char *hostname; /* server's hostname */ - struct sockaddr_storage address; /* server's address */ + union nfs_sockaddr address; socklen_t salen; /* size of server's address */ struct mount_options *options; /* parsed mount options */ @@ -205,9 +206,9 @@ static int nfs_append_clientaddr_option(const struct sockaddr *sap, socklen_t salen, struct mount_options *options) { - struct sockaddr_storage dummy; - struct sockaddr *my_addr = (struct sockaddr *)&dummy; - socklen_t my_len = sizeof(dummy); + union nfs_sockaddr address; + struct sockaddr *my_addr = &address.sa; + socklen_t my_len = sizeof(address); if (po_contains(options, "clientaddr") == PO_FOUND) return 1; @@ -219,21 +220,33 @@ static int nfs_append_clientaddr_option(const struct sockaddr *sap, } /* - * Resolve the 'mounthost=' hostname and append a new option using - * the resulting address. + * Determine whether to append a 'mountaddr=' option. The option is needed if: + * + * 1. "mounthost=" was specified, or + * 2. The address families for proto= and mountproto= are different. */ -static int nfs_fix_mounthost_option(struct mount_options *options) +static int nfs_fix_mounthost_option(struct mount_options *options, + const char *nfs_hostname) { - struct sockaddr_storage dummy; - struct sockaddr *sap = (struct sockaddr *)&dummy; - socklen_t salen = sizeof(dummy); + union nfs_sockaddr address; + struct sockaddr *sap = &address.sa; + socklen_t salen = sizeof(address); + sa_family_t nfs_family, mnt_family; char *mounthost; + if (!nfs_nfs_proto_family(options, &nfs_family)) + return 0; + if (!nfs_mount_proto_family(options, &mnt_family)) + return 0; + mounthost = po_get(options, "mounthost"); - if (!mounthost) - return 1; + if (mounthost == NULL) { + if (nfs_family == mnt_family) + return 1; + mounthost = (char *)nfs_hostname; + } - if (!nfs_name_to_address(mounthost, sap, &salen)) { + if (!nfs_lookup(mounthost, mnt_family, sap, &salen)) { nfs_error(_("%s: unable to determine mount server's address"), progname); return 0; @@ -320,13 +333,16 @@ static int nfs_set_version(struct nfsmount_info *mi) */ static int nfs_validate_options(struct nfsmount_info *mi) { - struct sockaddr *sap = (struct sockaddr *)&mi->address; + struct sockaddr *sap = &mi->address.sa; + sa_family_t family; if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL)) return 0; + if (!nfs_nfs_proto_family(mi->options, &family)) + return 0; mi->salen = sizeof(mi->address); - if (!nfs_name_to_address(mi->hostname, sap, &mi->salen)) + if (!nfs_lookup(mi->hostname, family, sap, &mi->salen)) return 0; if (!nfs_set_version(mi)) @@ -453,12 +469,12 @@ static int nfs_construct_new_options(struct mount_options *options, static int nfs_rewrite_pmap_mount_options(struct mount_options *options) { - struct sockaddr_storage nfs_address; - struct sockaddr *nfs_saddr = (struct sockaddr *)&nfs_address; + union nfs_sockaddr nfs_address; + struct sockaddr *nfs_saddr = &nfs_address.sa; socklen_t nfs_salen = sizeof(nfs_address); struct pmap nfs_pmap; - struct sockaddr_storage mnt_address; - struct sockaddr *mnt_saddr = (struct sockaddr *)&mnt_address; + union nfs_sockaddr mnt_address; + struct sockaddr *mnt_saddr = &mnt_address.sa; socklen_t mnt_salen = sizeof(mnt_address); struct pmap mnt_pmap; char *option; @@ -499,6 +515,10 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options) if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap, nfs_saddr, nfs_salen, &nfs_pmap)) { errno = ESPIPE; + if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED) + errno = EOPNOTSUPP; + else if (rpc_createerr.cf_error.re_errno != 0) + errno = rpc_createerr.cf_error.re_errno; return 0; } @@ -559,7 +579,7 @@ static int nfs_try_mount_v3v2(struct nfsmount_info *mi) return result; } - if (!nfs_fix_mounthost_option(options)) { + if (!nfs_fix_mounthost_option(options, mi->hostname)) { errno = EINVAL; goto out_fail; } @@ -594,7 +614,7 @@ out_fail: */ static int nfs_try_mount_v4(struct nfsmount_info *mi) { - struct sockaddr *sap = (struct sockaddr *)&mi->address; + struct sockaddr *sap = &mi->address.sa; struct mount_options *options = po_dup(mi->options); int result = 0;