- writemtab:
- if (!nomtab &&
- (umnt_err == 0 || umnt_err == EINVAL || umnt_err == ENOENT)) {
- update_mtab (node, NULL);
- }
-
- if (res >= 0)
- return 0;
-
- if (umnt_err2)
- complain(umnt_err2, spec);
- if (umnt_err && umnt_err != umnt_err2)
- complain(umnt_err, node);
- return 1;
+ nfs_options2pmap(options, &nfs_pmap, &mnt_pmap);
+
+ *hostname = nfs_umount_hostname(options, *hostname);
+ if (!*hostname) {
+ nfs_error(_("%s: out of memory"), progname);
+ return EX_FAIL;
+ }
+
+ if (nfs_name_to_address(*hostname, AF_UNSPEC, sap, &salen)) {
+ if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) != 0)
+ return EX_SUCCESS;
+ else
+ nfs_error(_("%s: Server failed to unmount '%s:%s'"),
+ progname, *hostname, *dirname);
+ }
+ return EX_FAIL;
+}
+
+/*
+ * Pick up certain mount options used during the original mount
+ * from /etc/mtab. The basics include the server's IP address and
+ * the server pathname of the share to unregister.
+ *
+ * These options might also describe the mount port, mount protocol
+ * version, and transport protocol used to punch through a firewall.
+ * We will need this information to get through the firewall again
+ * to do the umount.
+ *
+ * Note that option parsing failures won't necessarily cause the
+ * umount request to fail. Those values will be left zero in the
+ * pmap tuple. If the GETPORT call later fails to disambiguate them,
+ * then we fail.
+ */
+static int nfs_umount23(const char *devname, char *string)
+{
+ char *hostname, *dirname;
+ struct mount_options *options;
+ int result = EX_FAIL;
+
+ if (!nfs_parse_devname(devname, &hostname, &dirname))
+ return EX_USAGE;
+
+ options = po_split(string);
+ if (options) {
+ result = nfs_umount_do_umnt(options, &hostname, &dirname);
+ po_destroy(options);
+ } else
+ nfs_error(_("%s: option parsing error"), progname);
+
+ free(hostname);
+ free(dirname);
+ return result;