/* * Convert the passed-in sockaddr-style address to presentation * format, then append an option of the form "keyword=address". * * Returns 1 if the option was appended successfully; otherwise zero. */ static int nfs_append_generic_address_option(const struct sockaddr *sap, const socklen_t salen, const char *keyword, struct mount_options *options) { char address[NI_MAXHOST]; char new_option[512]; int len; if (!nfs_present_sockaddr(sap, salen, address, sizeof(address))) goto out_err; len = snprintf(new_option, sizeof(new_option), "%s=%s", keyword, address); if (len < 0 || (size_t)len >= sizeof(new_option)) goto out_err; if (po_append(options, new_option) != PO_SUCCEEDED) goto out_err; return 1; out_err: nfs_error(_("%s: failed to construct %s option"), progname, keyword); return 0; }
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_append_sloppy_option(struct mount_options *options) { if (!sloppy || linux_version_code() < MAKE_VERSION(2, 6, 27)) return 1; if (po_append(options, "sloppy") == PO_FAILED) return 0; return 1; }
static int nfs_construct_new_options(struct mount_options *options, struct sockaddr *nfs_saddr, struct pmap *nfs_pmap, struct sockaddr *mnt_saddr, struct pmap *mnt_pmap) { char new_option[64]; char *netid; po_remove_all(options, "nfsprog"); po_remove_all(options, "mountprog"); po_remove_all(options, "v2"); po_remove_all(options, "v3"); po_remove_all(options, "vers"); po_remove_all(options, "nfsvers"); snprintf(new_option, sizeof(new_option) - 1, "vers=%lu", nfs_pmap->pm_vers); if (po_append(options, new_option) == PO_FAILED) return 0; po_remove_all(options, "proto"); po_remove_all(options, "udp"); po_remove_all(options, "tcp"); netid = nfs_get_netid(nfs_saddr->sa_family, nfs_pmap->pm_prot); if (netid == NULL) return 0; snprintf(new_option, sizeof(new_option) - 1, "proto=%s", netid); free(netid); if (po_append(options, new_option) == PO_FAILED) return 0; if(po_remove_all(options, "port") == PO_FOUND || nfs_pmap->pm_port != NFS_PORT) { snprintf(new_option, sizeof(new_option) - 1, "port=%lu", nfs_pmap->pm_port); if (po_append(options, new_option) == PO_FAILED) return 0; } po_remove_all(options, "mountvers"); snprintf(new_option, sizeof(new_option) - 1, "mountvers=%lu", mnt_pmap->pm_vers); if (po_append(options, new_option) == PO_FAILED) return 0; po_remove_all(options, "mountproto"); netid = nfs_get_netid(mnt_saddr->sa_family, mnt_pmap->pm_prot); if (netid == NULL) return 0; snprintf(new_option, sizeof(new_option) - 1, "mountproto=%s", netid); free(netid); if (po_append(options, new_option) == PO_FAILED) return 0; po_remove_all(options, "mountport"); snprintf(new_option, sizeof(new_option) - 1, "mountport=%lu", mnt_pmap->pm_port); if (po_append(options, new_option) == PO_FAILED) return 0; return 1; }