X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fnetwork.c;h=4be48cd6a5f0941d3cb1be2b0d40ce9d7ece6d31;hp=52a538940ad2f33d1115bec1f6c34a021ee50fe8;hb=HEAD;hpb=b57cd77c13831051ad974ae027d96cd88a8d0c59 diff --git a/utils/mount/network.c b/utils/mount/network.c index 52a5389..4be48cd 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -16,8 +16,8 @@ * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 0211-1301 USA * */ @@ -155,9 +155,8 @@ static const unsigned long probe_nfs2_only[] = { 0, }; -static const unsigned long probe_nfs3_first[] = { +static const unsigned long probe_nfs3_only[] = { 3, - 2, 0, }; @@ -167,10 +166,8 @@ static const unsigned long probe_mnt1_first[] = { 0, }; -static const unsigned long probe_mnt3_first[] = { +static const unsigned long probe_mnt3_only[] = { 3, - 1, - 2, 0, }; @@ -626,7 +623,7 @@ static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen, probe_proto = nfs_default_proto(); return nfs_probe_port(sap, salen, pmap, - probe_nfs3_first, probe_proto); + probe_nfs3_only, probe_proto); } else return nfs_probe_port(sap, salen, pmap, probe_nfs2_only, probe_udp_only); @@ -653,7 +650,7 @@ static int nfs_probe_mntport(const struct sockaddr *sap, const socklen_t salen, if (nfs_mount_data_version >= 4) return nfs_probe_port(sap, salen, pmap, - probe_mnt3_first, probe_udp_first); + probe_mnt3_only, probe_udp_first); else return nfs_probe_port(sap, salen, pmap, probe_mnt1_first, probe_udp_only); @@ -717,7 +714,7 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr, 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; + probe_mnt3_only : probe_mnt1_first; for (; *probe_vers; probe_vers++) { nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers); @@ -1624,3 +1621,71 @@ int nfs_options2pmap(struct mount_options *options, return 1; } + +/* + * Discover mount server's hostname/address by examining mount options + * + * Returns a pointer to a string that the caller must free, on + * success; otherwise NULL is returned. + */ +static char *nfs_umount_hostname(struct mount_options *options, + char *hostname) +{ + char *option; + + option = po_get(options, "mountaddr"); + if (option) + goto out; + option = po_get(options, "mounthost"); + if (option) + goto out; + option = po_get(options, "addr"); + if (option) + goto out; + + return hostname; + +out: + free(hostname); + return strdup(option); +} + + +/* + * Returns EX_SUCCESS if mount options and device name have been + * parsed successfully; otherwise EX_FAIL. + */ +int nfs_umount_do_umnt(struct mount_options *options, + char **hostname, char **dirname) +{ + union nfs_sockaddr address; + struct sockaddr *sap = &address.sa; + socklen_t salen = sizeof(address); + struct pmap nfs_pmap, mnt_pmap; + sa_family_t family; + + if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap)) + return EX_FAIL; + + /* Skip UMNT call for vers=4 mounts */ + if (nfs_pmap.pm_vers == 4) + return EX_SUCCESS; + + *hostname = nfs_umount_hostname(options, *hostname); + if (!*hostname) { + nfs_error(_("%s: out of memory"), progname); + return EX_FAIL; + } + + if (!nfs_mount_proto_family(options, &family)) + return 0; + if (!nfs_lookup(*hostname, family, sap, &salen)) + /* nfs_lookup reports any errors */ + return EX_FAIL; + + if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0) + /* nfs_advise_umount reports any errors */ + return EX_FAIL; + + return EX_SUCCESS; +}