X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=57d8dad0d66d32b09490063510bfe111fceb8978;hp=cc13325750aa1eb22e542c6c7911a8333e770838;hb=b4c9ca0c8b132f36743e324766b8532eb623e98e;hpb=60fd6cd0ada4f501d6d6bcbc3e14950d453c428d diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index cc13325..57d8dad 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -52,6 +52,14 @@ #define NFS_PORT 2049 #endif +#ifndef NFS_MAXHOSTNAME +#define NFS_MAXHOSTNAME (255) +#endif + +#ifndef NFS_MAXPATHNAME +#define NFS_MAXPATHNAME (1024) +#endif + extern int nfs_mount_data_version; extern char *progname; extern int verbose; @@ -61,26 +69,55 @@ static int bg_opt = 0; static int addr_opt = 0; static int ca_opt = 0; -static int parse_devname(char *hostdir, char **hostname, char **dirname) +static int parse_devname(const char *spec, char **hostname) { - char *s; + int ret = 0; + char *dev, *pathname, *s; - if (!(s = strchr(hostdir, ':'))) { - nfs_error(_("%s: directory to mount not in host:dir format"), + dev = xstrdup(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); - return -1; + goto out; } - *hostname = hostdir; - *dirname = s + 1; - *s = '\0'; - /* Ignore all but first hostname in replicated mounts - until they can be fully supported. (mack@sgi.com) */ - if ((s = strchr(hostdir, ','))) { + + /* + * 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); } - return 0; + *hostname = xstrdup(dev); + if (strlen(*hostname) > NFS_MAXHOSTNAME) { + nfs_error(_("%s: server hostname is too long"), + progname); + free(*hostname); + goto out; + } + + ret = 1; + +out: + free(dev); + return ret; } static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr) @@ -161,39 +198,23 @@ static void extract_interesting_options(char *opts) } /* - * Append the 'addr=' option to the options string. + * Append the 'addr=' option to the options string. The server + * address is added to /etc/mtab for use when unmounting. * * Returns 1 if 'addr=' option created successfully; * otherwise zero. */ -static int append_addr_opt(const char *spec, char **extra_opts) +static int append_addr_opt(struct sockaddr_in *saddr, char **extra_opts) { - static char hostdir[1024], new_opts[1024]; - char *hostname, *dirname, *s, *old_opts; - struct sockaddr_in addr; + static char new_opts[1024]; + char *s, *old_opts; - if (strlen(spec) >= sizeof(hostdir)) { - nfs_error(_("%s: excessively long host:dir argument\n"), - progname); - return 0; - } - strcpy(hostdir, spec); - if (parse_devname(hostdir, &hostname, &dirname)) { - nfs_error(_("%s: parsing host:dir argument failed\n"), - progname); - return 0; - } - - if (!fill_ipv4_sockaddr(hostname, &addr)) - return 0; - - /* add IP address to mtab options for use when unmounting */ - s = inet_ntoa(addr.sin_addr); + s = inet_ntoa(saddr->sin_addr); old_opts = *extra_opts; if (!old_opts) old_opts = ""; if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) { - nfs_error(_("%s: excessively long option argument\n"), + nfs_error(_("%s: too many mount options\n"), progname); return 0; } @@ -252,17 +273,26 @@ static int append_clientaddr_opt(const char *spec, char **extra_opts) int nfsmount_s(const char *spec, const char *node, int flags, char **extra_opts, int fake, int bg) { - int retval = EX_FAIL; + struct sockaddr_in saddr; + char *hostname; + int err; + + if (!parse_devname(spec, &hostname)) + return EX_FAIL; + err = fill_ipv4_sockaddr(hostname, &saddr); + free(hostname); + if (!err) + return EX_FAIL; extract_interesting_options(*extra_opts); if (!bg && addr_opt) { nfs_error(_("%s: Illegal option: 'addr='"), progname); - goto fail; + return EX_FAIL; } - if (!append_addr_opt(spec, extra_opts)) - goto fail; + if (!append_addr_opt(&saddr, extra_opts)) + return EX_FAIL; if (verbose) printf(_("%s: text-based options: '%s'\n"), @@ -272,14 +302,11 @@ int nfsmount_s(const char *spec, const char *node, int flags, if (mount(spec, node, "nfs", flags & ~(MS_USER|MS_USERS), *extra_opts)) { mount_error(spec, node, errno); - goto fail; + return EX_FAIL; } } return 0; - -fail: - return retval; } /* @@ -299,25 +326,34 @@ fail: int nfs4mount_s(const char *spec, const char *node, int flags, char **extra_opts, int fake, int child) { - int retval = EX_FAIL; + struct sockaddr_in saddr; + char *hostname; + int err; + + if (!parse_devname(spec, &hostname)) + return EX_FAIL; + err = fill_ipv4_sockaddr(hostname, &saddr); + free(hostname); + if (!err) + return EX_FAIL; extract_interesting_options(*extra_opts); if (addr_opt) { nfs_error(_("%s: Illegal option: 'addr='"), progname); - goto fail; + return EX_FAIL; } if (ca_opt) { nfs_error(_("%s: Illegal option: 'clientaddr='"), progname); - goto fail; + return EX_FAIL; } - if (!append_addr_opt(spec, extra_opts)) - goto fail; + if (!append_addr_opt(&saddr, extra_opts)) + return EX_FAIL; if (!append_clientaddr_opt(spec, extra_opts)) - goto fail; + return EX_FAIL; if (verbose) printf(_("%s: text-based options: '%s'\n"), @@ -327,12 +363,9 @@ int nfs4mount_s(const char *spec, const char *node, int flags, if (mount(spec, node, "nfs4", flags & ~(MS_USER|MS_USERS), *extra_opts)) { mount_error(spec, node, errno); - goto fail; + return EX_FAIL; } } return 0; - -fail: - return retval; }