X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=c4f2326ce9162ef63d08c649be0f7091532ca37e;hp=f856998f569b9201d11f0f0398d3592b7ad95fd4;hb=1d61a1116198714f50b081daecc663625124403d;hpb=1adb0e018f57079c6e95a9bdbf904361354b0527 diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index f856998..c4f2326 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -49,6 +49,7 @@ #include "network.h" #include "parse_opt.h" #include "version.h" +#include "parse_dev.h" #ifdef HAVE_RPCSVC_NFS_PROT_H #include @@ -94,59 +95,9 @@ struct nfsmount_info { int flags, /* MS_ flags */ fake, /* actually do the mount? */ child; /* forked bg child? */ -}; - -static int nfs_parse_devname(struct nfsmount_info *mi) -{ - int ret = 0; - char *dev, *pathname, *s; - - dev = xstrdup(mi->spec); - - if (!(pathname = strchr(dev, ':'))) { - nfs_error(_("%s: remote share not in 'host:dir' format"), - progname); - goto out; - } - *pathname = '\0'; - pathname++; - - /* - * We don't need a copy of the pathname, but let's - * sanity check it anyway. - */ - if (strlen(pathname) > NFS_MAXPATHNAME) { - nfs_error(_("%s: export pathname is too long"), - progname); - goto out; - } - - /* - * Ignore all but first hostname in replicated mounts - * until they can be fully supported. (mack@sgi.com) - */ - if ((s = strchr(dev, ','))) { - *s = '\0'; - nfs_error(_("%s: warning: multiple hostnames not supported"), - progname); - nfs_error(_("%s: ignoring hostnames that follow the first one"), - progname); - } - mi->hostname = xstrdup(dev); - if (strlen(mi->hostname) > NFS_MAXHOSTNAME) { - nfs_error(_("%s: server hostname is too long"), - progname); - free(mi->hostname); - mi->hostname = NULL; - goto out; - } - - ret = 1; -out: - free(dev); - return ret; -} + sa_family_t family; /* supported address family */ +}; static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr) { @@ -252,48 +203,47 @@ static int nfs_append_addr_option(const struct sockaddr *sap, * Returns 1 if 'clientaddr=' option created successfully or if * 'clientaddr=' option is already present; otherwise zero. */ -static int append_clientaddr_option(struct sockaddr_in *saddr, - struct mount_options *options) +static int nfs_append_clientaddr_option(const struct sockaddr *sap, + socklen_t salen, + struct mount_options *options) { - struct sockaddr_in my_addr; - char new_option[32]; + struct sockaddr_storage dummy; + struct sockaddr *my_addr = (struct sockaddr *)&dummy; + socklen_t my_len = sizeof(dummy); - if (po_contains(options, "clientaddr") == PO_SUCCEEDED) + if (po_contains(options, "clientaddr") == PO_FOUND) return 1; - if (!get_client_address(saddr, &my_addr)) - return 0; - - snprintf(new_option, sizeof(new_option) - 1, - "clientaddr=%s", inet_ntoa(my_addr.sin_addr)); + nfs_callback_address(sap, salen, my_addr, &my_len); - if (po_append(options, new_option) == PO_SUCCEEDED) - return 1; - return 0; + return nfs_append_generic_address_option(my_addr, my_len, + "clientaddr", options); } /* * Resolve the 'mounthost=' hostname and append a new option using - * the resulting IPv4 address. + * the resulting address. */ -static int fix_mounthost_option(struct mount_options *options) +static int nfs_fix_mounthost_option(const sa_family_t family, + struct mount_options *options) { - struct sockaddr_in maddr; - char *mounthost, new_option[32]; + struct sockaddr_storage dummy; + struct sockaddr *sap = (struct sockaddr *)&dummy; + socklen_t salen = sizeof(dummy); + char *mounthost; mounthost = po_get(options, "mounthost"); if (!mounthost) return 1; - if (!fill_ipv4_sockaddr(mounthost, &maddr)) + if (!nfs_name_to_address(mounthost, family, sap, &salen)) { + nfs_error(_("%s: unable to determine mount server's address"), + progname); return 0; + } - snprintf(new_option, sizeof(new_option) - 1, - "mountaddr=%s", inet_ntoa(maddr.sin_addr)); - - if (po_append(options, new_option) == PO_SUCCEEDED) - return 1; - return 0; + return nfs_append_generic_address_option(sap, salen, + "mountaddr", options); } /* @@ -333,16 +283,21 @@ static int nfs_append_sloppy_option(struct mount_options *options) */ static int nfs_validate_options(struct nfsmount_info *mi) { - struct sockaddr_in saddr; + struct sockaddr_storage dummy; + struct sockaddr *sap = (struct sockaddr *)&dummy; + socklen_t salen = sizeof(dummy); - if (!fill_ipv4_sockaddr(mi->hostname, &saddr)) + if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL)) + return 0; + + if (!nfs_name_to_address(mi->hostname, mi->family, sap, &salen)) return 0; if (strncmp(mi->type, "nfs4", 4) == 0) { - if (!append_clientaddr_option(&saddr, mi->options)) + if (!nfs_append_clientaddr_option(sap, salen, mi->options)) return 0; } else { - if (!fix_mounthost_option(mi->options)) + if (!nfs_fix_mounthost_option(mi->family, mi->options)) return 0; if (!mi->fake && !verify_lock_option(mi->options)) return 0; @@ -351,8 +306,7 @@ static int nfs_validate_options(struct nfsmount_info *mi) if (!nfs_append_sloppy_option(mi->options)) return 0; - return nfs_append_addr_option((struct sockaddr *)&saddr, - sizeof(saddr), mi->options); + return nfs_append_addr_option(sap, salen, mi->options); } /* @@ -802,12 +756,14 @@ int nfsmount_string(const char *spec, const char *node, const char *type, .flags = flags, .fake = fake, .child = child, +#ifdef IPV6_SUPPORTED + .family = AF_UNSPEC, /* either IPv4 or v6 */ +#else + .family = AF_INET, /* only IPv4 */ +#endif }; int retval = EX_FAIL; - if (!nfs_parse_devname(&mi)) - return retval; - mi.options = po_split(*extra_opts); if (mi.options) { retval = nfsmount_start(&mi);