static int nfs_do_mount_v4(struct nfsmount_info *mi, struct sockaddr *sap, socklen_t salen) { struct mount_options *options = po_dup(mi->options); int result = 0; if (!options) { errno = ENOMEM; return result; } if (mi->version == 0) { if (po_contains(options, "mounthost") || po_contains(options, "mountaddr") || po_contains(options, "mountvers") || po_contains(options, "mountproto")) { /* * Since these mountd options are set assume version 3 * is wanted so error out with EPROTONOSUPPORT so the * protocol negation starts with v3. */ errno = EPROTONOSUPPORT; goto out_fail; } if (po_append(options, "vers=4") == PO_FAILED) { errno = EINVAL; goto out_fail; } } if (!nfs_append_addr_option(sap, salen, options)) { errno = EINVAL; goto out_fail; } if (!nfs_append_clientaddr_option(sap, salen, options)) { errno = EINVAL; goto out_fail; } /* * Update option string to be recorded in /etc/mtab. */ if (po_join(options, mi->extra_opts) == PO_FAILED) { errno = ENOMEM; goto out_fail; } if (verbose) printf(_("%s: trying text-based options '%s'\n"), progname, *mi->extra_opts); result = nfs_sys_mount(mi, options); out_fail: po_destroy(options); return result; }
static int nfs_do_mount_v3v2(struct nfsmount_info *mi, struct sockaddr *sap, socklen_t salen, int checkv4) { struct mount_options *options = po_dup(mi->options); int result = 0; if (!options) { errno = ENOMEM; return result; } errno = 0; if (!nfs_append_addr_option(sap, salen, options)) { if (errno == 0) errno = EINVAL; goto out_fail; } if (!nfs_fix_mounthost_option(options, mi->hostname)) { if (errno == 0) errno = EINVAL; goto out_fail; } if (!mi->fake && !nfs_verify_lock_option(options)) { if (errno == 0) errno = EINVAL; goto out_fail; } /* * Options we negotiate below may be stale by the time this * file system is unmounted. In order to force umount.nfs * to renegotiate with the server, only write the user- * specified options, and not negotiated options, to /etc/mtab. */ if (po_join(options, mi->extra_opts) == PO_FAILED) { errno = ENOMEM; goto out_fail; } if (verbose) printf(_("%s: trying text-based options '%s'\n"), progname, *mi->extra_opts); if (!nfs_rewrite_pmap_mount_options(options, checkv4, mi->local_ip)) goto out_fail; result = nfs_sys_mount(mi, options); out_fail: po_destroy(options); return result; }
/* * Set up mandatory non-version specific NFS mount options. * * Returns 1 if successful; otherwise zero. */ static int nfs_validate_options(struct nfsmount_info *mi) { struct addrinfo hint = { .ai_protocol = (int)IPPROTO_UDP, }; sa_family_t family; int error; char *option; if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL)) return 0; if (!nfs_nfs_proto_family(mi->options, &family)) return 0; hint.ai_family = (int)family; error = getaddrinfo(mi->hostname, NULL, &hint, &mi->address); if (error != 0) { nfs_error(_("%s: Failed to resolve server %s: %s"), progname, mi->hostname, gai_strerror(error)); mi->address = NULL; return 0; } if (!nfs_set_version(mi)) return 0; if (!nfs_append_sloppy_option(mi->options)) return 0; if (!nfs_append_addr_option(mi->address->ai_addr, mi->address->ai_addrlen, mi->options)) return 0; option = po_get(mi->options, "srcaddr"); if (option) { struct local_bind_info *local_ip; local_ip = malloc(sizeof(*local_ip)); memset(local_ip, 0, sizeof(*local_ip)); if (nfs_parse_local_bind(local_ip, option, mi->address->ai_addr->sa_family) >= 0) { mi->local_ip = local_ip; } else { free(local_ip); return 0; } } return 1; } /* * Get NFS/mnt server addresses from mount options * * Returns 1 and fills in @nfs_saddr, @nfs_salen, @mnt_saddr, and @mnt_salen * if all goes well; otherwise zero. */ static int nfs_extract_server_addresses(struct mount_options *options, struct sockaddr *nfs_saddr, socklen_t *nfs_salen, struct sockaddr *mnt_saddr, socklen_t *mnt_salen) { char *option; option = po_get(options, "addr"); if (option == NULL) return 0; if (!nfs_string_to_sockaddr(option, nfs_saddr, nfs_salen)) return 0; option = po_get(options, "mountaddr"); if (option == NULL) { memcpy(mnt_saddr, nfs_saddr, *nfs_salen); *mnt_salen = *nfs_salen; } else if (!nfs_string_to_sockaddr(option, mnt_saddr, mnt_salen)) return 0; return 1; }