#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <sys/time.h>
-#include <sys/utsname.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "conn.h"
#include "xcommon.h"
-#include "nfsmount.h"
+#include "mount.h"
#include "nfsumount.h"
#include "nfs_mount.h"
#include "mount_constants.h"
#include "nls.h"
-
-#ifdef HAVE_RPCSVC_NFS_PROT_H
-#include <rpcsvc/nfs_prot.h>
-#else
-#include <linux/nfs.h>
-#define nfsstat nfs_stat
-#endif
+#include "error.h"
#ifndef NFS_PORT
#define NFS_PORT 2049
#define NFS_FHSIZE 32
#endif
-static char *nfs_strerror(int stat);
-
-#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
-#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define MAX_MNTPROT ((nfs_mount_version >= 4) ? 3 : 2)
-#define HAVE_RELIABLE_TCP (nfs_mount_version >= 4)
-
#ifndef HAVE_INET_ATON
#define inet_aton(a,b) (0)
#endif
mnt3res_t nfsv3;
} mntres_t;
-static char errbuf[BUFSIZ];
-static char *erreob = &errbuf[BUFSIZ];
+extern int nfs_mount_data_version;
extern int verbose;
+extern int sloppy;
-/* Convert RPC errors into strings */
-int rpc_strerror(int);
-int rpc_strerror(int spos)
-{
- int cf_stat = rpc_createerr.cf_stat;
- int pos=0, cf_errno = rpc_createerr.cf_error.re_errno;
- char *ptr, *estr = clnt_sperrno(cf_stat);
- char *tmp;
-
- if (estr) {
- if ((ptr = index(estr, ':')))
- estr = ++ptr;
-
- tmp = &errbuf[spos];
- if (cf_stat == RPC_SYSTEMERROR)
- pos = snprintf(tmp, (erreob - tmp),
- "System Error: %s", strerror(cf_errno));
- else
- pos = snprintf(tmp, (erreob - tmp), "RPC Error:%s", estr);
- }
- return (pos);
-}
-void mount_errors(char *, int, int);
-void mount_errors(char *server, int will_retry, int bg)
-{
- int pos = 0;
- char *tmp;
- static int onlyonce = 0;
-
- tmp = &errbuf[pos];
- if (bg)
- pos = snprintf(tmp, (erreob - tmp),
- "mount to NFS server '%s' failed: ", server);
- else
- pos = snprintf(tmp, (erreob - tmp),
- "mount: mount to NFS server '%s' failed: ", server);
+extern int linux_version_code();
- tmp = &errbuf[pos];
- if (rpc_createerr.cf_stat == RPC_TIMEDOUT) {
- pos = snprintf(tmp, (erreob - tmp), "timed out %s",
- will_retry ? "(retrying)" : "(giving up)");
- } else {
- pos += rpc_strerror(pos);
- tmp = &errbuf[pos];
- if (bg) {
- pos = snprintf(tmp, (erreob - tmp), " %s",
- will_retry ? "(retrying)" : "(giving up)");
- }
- }
- if (bg) {
- if (onlyonce++ < 1)
- openlog("mount", LOG_CONS|LOG_PID, LOG_AUTH);
- syslog(LOG_ERR, "%s.", errbuf);
- } else
- fprintf(stderr, "%s.\n", errbuf);
-}
+static const unsigned int probe_udp_only[] = {
+ IPPROTO_UDP,
+ 0,
+};
-/* Define the order in which to probe for UDP/TCP services */
-enum plist {
- use_tcp = 0,
- udp_tcp,
- udp_only,
+static const unsigned int probe_udp_first[] = {
+ IPPROTO_UDP,
+ IPPROTO_TCP,
+ 0,
};
-static const u_int *
-proto_probelist(enum plist list)
-{
- static const u_int probe_udp_tcp[] = { IPPROTO_UDP, IPPROTO_TCP, 0 };
- static const u_int probe_both[] = { IPPROTO_TCP, IPPROTO_UDP, 0 };
- static const u_int probe_udponly[] = { IPPROTO_UDP, 0 };
-
- if (list == use_tcp)
- return probe_both;
- if (list == udp_tcp)
- return probe_udp_tcp;
- return probe_udponly;
-}
-/* Define the order in which NFS versions are probed on portmapper */
-static const u_long *
-nfs_probelist(const int vers)
-{
- static const u_long nfs2_probe[] = { 2, 0};
- static const u_long nfs3_probe[] = { 3, 2, 0};
- switch (vers) {
- case 3:
- return nfs3_probe;
- default:
- return nfs2_probe;
- }
-}
+static const unsigned int probe_tcp_first[] = {
+ IPPROTO_TCP,
+ IPPROTO_UDP,
+ 0,
+};
-/* Define the order in which Mountd versions are probed on portmapper */
-static const u_long *
-mnt_probelist(const int vers)
-{
- static const u_long mnt1_probe[] = { 1, 2, 0 };
- static const u_long mnt3_probe[] = { 3, 1, 2, 0 };
- switch (vers) {
- case 3:
- return mnt3_probe;
- default:
- return mnt1_probe;
- }
-}
+static const unsigned long probe_nfs2_only[] = {
+ 2,
+ 0,
+};
-static int
-linux_version_code(void) {
- struct utsname my_utsname;
- int p, q, r;
-
- if (uname(&my_utsname) == 0) {
- p = atoi(strtok(my_utsname.release, "."));
- q = atoi(strtok(NULL, "."));
- r = atoi(strtok(NULL, "."));
- return MAKE_VERSION(p,q,r);
- }
- return 0;
-}
+static const unsigned long probe_nfs3_first[] = {
+ 3,
+ 2,
+ 0,
+};
-/*
- * Unfortunately, the kernel prints annoying console messages
- * in case of an unexpected nfs mount version (instead of
- * just returning some error). Therefore we'll have to try
- * and figure out what version the kernel expects.
- *
- * Variables:
- * NFS_MOUNT_VERSION: these nfsmount sources at compile time
- * nfs_mount_version: version this source and running kernel can handle
- */
-int nfs_mount_version = NFS_MOUNT_VERSION;
+static const unsigned long probe_mnt1_first[] = {
+ 1,
+ 2,
+ 0,
+};
-int
-find_kernel_nfs_mount_version(void) {
- static int kernel_version = -1;
- int mnt_version = NFS_MOUNT_VERSION;
-
- if (kernel_version == -1)
- kernel_version = linux_version_code();
-
- if (kernel_version) {
- if (kernel_version < MAKE_VERSION(2,1,32))
- mnt_version = 1;
- else if (kernel_version < MAKE_VERSION(2,2,18))
- mnt_version = 3;
- else if (kernel_version < MAKE_VERSION(2,3,0))
- mnt_version = 4; /* since 2.2.18pre9 */
- else if (kernel_version < MAKE_VERSION(2,3,99))
- mnt_version = 3;
- else if (kernel_version < MAKE_VERSION(2,6,3))
- mnt_version = 4;
- else
- mnt_version = 6;
- }
- if (mnt_version > NFS_MOUNT_VERSION)
- mnt_version = NFS_MOUNT_VERSION;
- return mnt_version;
-}
+static const unsigned long probe_mnt3_first[] = {
+ 3,
+ 1,
+ 2,
+ 0,
+};
int nfs_gethostbyname(const char *, struct sockaddr_in *);
int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
* instead of reserve ports since reserve ports
* are not needed for pmap requests.
*/
-static u_short
+u_short
getport(
struct sockaddr_in *saddr,
u_long prog,
u_long vers,
u_int prot)
{
- u_short port;
+ u_short port = 0;
int socket;
CLIENT *clnt = NULL;
struct pmap parms;
enum clnt_stat stat;
saddr->sin_port = htons (PMAPPORT);
- socket = get_socket(saddr, prot, FALSE);
+ socket = get_socket(saddr, prot, FALSE, FALSE);
switch (prot) {
case IPPROTO_UDP:
inet_ntoa(saddr->sin_addr), prog, *p_vers,
*p_prot == IPPROTO_UDP ? "udp" : "tcp", p_port);
}
- if (clnt_ping(saddr, prog, *p_vers, *p_prot))
+ if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
goto out_ok;
if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
goto out_bad;
return 1;
}
-static int
-probe_nfsport(clnt_addr_t *nfs_server)
+static int probe_nfsport(clnt_addr_t *nfs_server)
{
- const struct pmap *pmap = &nfs_server->pmap;
- const u_long *probe_vers;
- const u_int *probe_prot;
+ struct pmap *pmap = &nfs_server->pmap;
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
- probe_vers = nfs_probelist(MAX_NFSPROT);
- probe_prot = proto_probelist(HAVE_RELIABLE_TCP ? use_tcp : udp_only);
- return probe_port(nfs_server, probe_vers, probe_prot);
+
+ if (nfs_mount_data_version >= 4)
+ return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first);
+ else
+ return probe_port(nfs_server, probe_nfs2_only, probe_udp_only);
}
int probe_mntport(clnt_addr_t *mnt_server)
{
- const struct pmap *pmap = &mnt_server->pmap;
- const u_long *probe_vers;
- const u_int *probe_prot;
+ struct pmap *pmap = &mnt_server->pmap;
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
- probe_vers = mnt_probelist(MAX_MNTPROT);
- probe_prot = proto_probelist(HAVE_RELIABLE_TCP ? udp_tcp : udp_only);
- return probe_port(mnt_server, probe_vers, probe_prot);
+
+ if (nfs_mount_data_version >= 4)
+ return probe_port(mnt_server, probe_mnt3_first, probe_udp_first);
+ else
+ return probe_port(mnt_server, probe_mnt1_first, probe_udp_only);
}
static int
struct pmap *mnt_pmap = &mnt_server->pmap;
struct pmap save_nfs, save_mnt;
int res;
- const u_long *probe_vers;
+ const unsigned long *probe_vers;
if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
if (nfs_pmap->pm_vers)
goto version_fixed;
+
memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
- for (probe_vers = mnt_probelist(MAX_MNTPROT); *probe_vers; probe_vers++) {
+ probe_vers = (nfs_mount_data_version >= 4) ?
+ probe_mnt3_first : probe_mnt1_first;
+
+ for (; *probe_vers; probe_vers++) {
nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
if ((res = probe_nfsport(nfs_server) != 0)) {
mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
}
memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
}
- out_bad:
+
+out_bad:
return 0;
- version_fixed:
+
+version_fixed:
if (!probe_nfsport(nfs_server))
goto out_bad;
return probe_mntport(mnt_server);
struct pmap *mnt_pmap = &mnt_server->pmap;
struct pmap *nfs_pmap = &nfs_server->pmap;
int len;
- char *opt, *opteq;
+ char *opt, *opteq, *p, *opt_b;
char *mounthost = NULL;
char cbuf[128];
+ int open_quote = 0;
data->flags = 0;
*bg = 0;
len = strlen(new_opts);
- for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
+ for (p=old_opts, opt_b=NULL; p && *p; p++) {
+ if (!opt_b)
+ opt_b = p; /* begin of the option item */
+ if (*p == '"')
+ open_quote ^= 1; /* reverse the status */
+ if (open_quote)
+ continue; /* still in a quoted block */
+ if (*p == ',')
+ *p = '\0'; /* terminate the option item */
+ if (*p == '\0' || *(p+1) == '\0') {
+ opt = opt_b; /* opt is useful now */
+ opt_b = NULL;
+ }
+ else
+ continue; /* still somewhere in the option item */
+
if (strlen(opt) >= sizeof(cbuf))
goto bad_parameter;
if ((opteq = strchr(opt, '=')) && isdigit(opteq[1])) {
opt = "nfsvers";
#if NFS_MOUNT_VERSION >= 2
} else if (!strcmp(opt, "namlen")) {
- if (nfs_mount_version >= 2)
+ if (nfs_mount_data_version >= 2)
data->namlen = val;
+ else if (sloppy)
+ continue;
else
goto bad_parameter;
#endif
} else if (!strcmp(opt, "addr")) {
/* ignore */;
continue;
- } else
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
sprintf(cbuf, "%s=%s,", opt, opteq+1);
} else if (opteq) {
#if NFS_MOUNT_VERSION >= 2
data->flags &= ~NFS_MOUNT_TCP;
} else if (!strcmp(opteq+1, "tcp") &&
- nfs_mount_version > 2) {
+ nfs_mount_data_version > 2) {
nfs_pmap->pm_prot = IPPROTO_TCP;
mnt_pmap->pm_prot = IPPROTO_TCP;
data->flags |= NFS_MOUNT_TCP;
#endif
- } else
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
#if NFS_MOUNT_VERSION >= 5
} else if (!strcmp(opt, "sec")) {
char *secflavor = opteq+1;
/* see RFC 2623 */
- if (nfs_mount_version < 5) {
+ if (nfs_mount_data_version < 5) {
printf(_("Warning: ignoring sec=%s option\n"), secflavor);
continue;
- } else if (!strcmp(secflavor, "sys"))
+ } else if (!strcmp(secflavor, "none"))
+ data->pseudoflavor = AUTH_NONE;
+ else if (!strcmp(secflavor, "sys"))
data->pseudoflavor = AUTH_SYS;
else if (!strcmp(secflavor, "krb5"))
data->pseudoflavor = AUTH_GSS_KRB5;
data->pseudoflavor = AUTH_GSS_SPKMI;
else if (!strcmp(secflavor, "spkm3p"))
data->pseudoflavor = AUTH_GSS_SPKMP;
+ else if (sloppy)
+ continue;
else {
printf(_("Warning: Unrecognized security flavor %s.\n"),
secflavor);
mounthost=xstrndup(opteq+1,
strcspn(opteq+1," \t\n\r,"));
else if (!strcmp(opt, "context")) {
- char *context = opteq + 1;
-
- if (strlen(context) > NFS_MAX_CONTEXT_LEN) {
- printf(_("context parameter exceeds limit of %d\n"),
- NFS_MAX_CONTEXT_LEN);
+ char *context = opteq + 1;
+ int ctxlen = strlen(context);
+
+ if (ctxlen > NFS_MAX_CONTEXT_LEN) {
+ printf(_("context parameter exceeds limit of %d\n"),
+ NFS_MAX_CONTEXT_LEN);
goto bad_parameter;
- }
- strncpy(data->context, context, NFS_MAX_CONTEXT_LEN);
- } else
+ }
+ /* The context string is in the format of
+ * "system_u:object_r:...". We only want
+ * the context str between the quotes.
+ */
+ if (*context == '"')
+ strncpy(data->context, context+1,
+ ctxlen-2);
+ else
+ strncpy(data->context, context,
+ NFS_MAX_CONTEXT_LEN);
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
sprintf(cbuf, "%s=%s,", opt, opteq+1);
} else {
} else if (!strcmp(opt, "tcp")) {
data->flags &= ~NFS_MOUNT_TCP;
if (val) {
- if (nfs_mount_version < 2)
+ if (nfs_mount_data_version < 2)
goto bad_option;
nfs_pmap->pm_prot = IPPROTO_TCP;
mnt_pmap->pm_prot = IPPROTO_TCP;
} else if (!strcmp(opt, "udp")) {
data->flags &= ~NFS_MOUNT_TCP;
if (!val) {
- if (nfs_mount_version < 2)
+ if (nfs_mount_data_version < 2)
goto bad_option;
nfs_pmap->pm_prot = IPPROTO_TCP;
mnt_pmap->pm_prot = IPPROTO_TCP;
} else if (!strcmp(opt, "lock")) {
data->flags &= ~NFS_MOUNT_NONLM;
if (!val) {
- if (nfs_mount_version < 3)
+ if (nfs_mount_data_version < 3)
goto bad_option;
data->flags |= NFS_MOUNT_NONLM;
}
} else if (!strcmp(opt, "broken_suid")) {
data->flags &= ~NFS_MOUNT_BROKEN_SUID;
if (val) {
- if (nfs_mount_version < 4)
+ if (nfs_mount_data_version < 4)
goto bad_option;
data->flags |= NFS_MOUNT_BROKEN_SUID;
}
data->flags &= ~NFS_MOUNT_NOACL;
if (!val)
data->flags |= NFS_MOUNT_NOACL;
+ } else if (!strcmp(opt, "rdirplus")) {
+ data->flags &= ~NFS_MOUNT_NORDIRPLUS;
+ if (!val)
+ data->flags |= NFS_MOUNT_NORDIRPLUS;
+ } else if (!strcmp(opt, "sharecache")) {
+ data->flags &= ~NFS_MOUNT_UNSHARED;
+ if (!val)
+ data->flags |= NFS_MOUNT_UNSHARED;
#endif
} else {
bad_option:
+ if (sloppy)
+ continue;
printf(_("Unsupported nfs mount option: "
"%s%s\n"), val ? "" : "no", opt);
goto out_bad;
return 0;
}
-static inline int
-nfsmnt_check_compat(const struct pmap *nfs_pmap, const struct pmap *mnt_pmap)
+static int nfsmnt_check_compat(const struct pmap *nfs_pmap,
+ const struct pmap *mnt_pmap)
{
- if (nfs_pmap->pm_vers &&
- (nfs_pmap->pm_vers > MAX_NFSPROT || nfs_pmap->pm_vers < 2)) {
- if (nfs_pmap->pm_vers == 4)
- fprintf(stderr, _("'vers=4' is not supported. "
- "Use '-t nfs4' instead.\n"));
- else
- fprintf(stderr, _("NFS version %ld is not supported.\n"),
- nfs_pmap->pm_vers);
+ unsigned int max_nfs_vers = (nfs_mount_data_version >= 4) ? 3 : 2;
+ unsigned int max_mnt_vers = (nfs_mount_data_version >= 4) ? 3 : 2;
+
+ if (nfs_pmap->pm_vers == 4) {
+ fprintf(stderr, _("Please use '-t nfs4' "
+ "instead of '-o vers=4'.\n"));
goto out_bad;
}
- if (mnt_pmap->pm_vers > MAX_MNTPROT) {
+
+ if (nfs_pmap->pm_vers) {
+ if (nfs_pmap->pm_vers > max_nfs_vers || nfs_pmap->pm_vers < 2) {
+ fprintf(stderr, _("NFS version %ld is not supported.\n"),
+ nfs_pmap->pm_vers);
+ goto out_bad;
+ }
+ }
+
+ if (mnt_pmap->pm_vers > max_mnt_vers) {
fprintf(stderr, _("NFS mount version %ld s not supported.\n"),
mnt_pmap->pm_vers);
goto out_bad;
}
+
return 1;
- out_bad:
+
+out_bad:
return 0;
}
int
nfsmount(const char *spec, const char *node, int *flags,
- char **extra_opts, char **mount_opts, int *nfs_mount_vers,
- int running_bg)
+ char **extra_opts, char **mount_opts,
+ int running_bg, int *need_statd)
{
static char *prev_bg_host;
char hostdir[1024];
*nfs_pmap = &nfs_server.pmap;
struct pmap save_mnt, save_nfs;
- int fsock;
+ int fsock = -1;
mntres_t mntres;
struct stat statbuf;
char *s;
int bg, retry;
- int retval;
+ int retval = EX_FAIL;
time_t t;
time_t prevt;
time_t timeout;
- /* The version to try is either specified or 0
- In case it is 0 we tell the caller what we tried */
- if (!*nfs_mount_vers)
- *nfs_mount_vers = find_kernel_nfs_mount_version();
- nfs_mount_version = *nfs_mount_vers;
-
- retval = EX_FAIL;
- fsock = -1;
if (strlen(spec) >= sizeof(hostdir)) {
fprintf(stderr, _("mount: "
"excessively long host:dir argument\n"));
#if NFS_MOUNT_VERSION >= 2
data.namlen = NAME_MAX;
#endif
- data.pseudoflavor = AUTH_SYS;
bg = 0;
retry = 10000; /* 10000 minutes ~ 1 week */
#endif
#if NFS_MOUNT_VERSION >= 5
printf("sec = %u ", data.pseudoflavor);
+ printf("readdirplus = %d ", (data.flags & NFS_MOUNT_NORDIRPLUS) != 0);
#endif
printf("\n");
#endif
- data.version = nfs_mount_version;
+ data.version = nfs_mount_data_version;
*mount_opts = (char *) &data;
if (*flags & MS_REMOUNT)
}
#if NFS_MOUNT_VERSION >= 5
mountres = &mntres.nfsv3.mountres3_u.mountinfo;
- i = mountres->auth_flavours.auth_flavours_len;
+ i = mountres->auth_flavors.auth_flavors_len;
if (i <= 0)
- goto noauth_flavours;
+ goto noauth_flavors;
- flavor = mountres->auth_flavours.auth_flavours_val;
+ flavor = mountres->auth_flavors.auth_flavors_val;
while (--i >= 0) {
+ /* If no flavour requested, use first simple
+ * flavour that is offered.
+ */
+ if (! (data.flags & NFS_MOUNT_SECFLAVOUR) &&
+ (flavor[i] == AUTH_SYS ||
+ flavor[i] == AUTH_NONE)) {
+ data.pseudoflavor = flavor[i];
+ data.flags |= NFS_MOUNT_SECFLAVOUR;
+ }
if (flavor[i] == data.pseudoflavor)
yum = 1;
#ifdef NFS_MOUNT_DEBUG
"mount: %s:%s failed, "
"security flavor not supported\n",
hostname, dirname);
- /* server has registered us in mtab, send umount */
+ /* server has registered us in rmtab, send umount */
nfs_call_umount(&mnt_server, &dirname);
goto fail;
}
-noauth_flavours:
+noauth_flavors:
#endif
fhandle = &mntres.nfsv3.mountres3_u.mountinfo.fhandle;
memset(data.old_root.data, 0, NFS_FHSIZE);
#endif
}
- /* create nfs socket for kernel */
-
- if (nfs_pmap->pm_prot == IPPROTO_TCP)
- fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- else
- fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (fsock < 0) {
- perror(_("nfs socket"));
- goto fail;
- }
- if (bindresvport(fsock, 0) < 0) {
- perror(_("nfs bindresvport"));
- goto fail;
+ if (nfs_mount_data_version == 1) {
+ /* create nfs socket for kernel */
+ if (nfs_pmap->pm_prot == IPPROTO_TCP)
+ fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ else
+ fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fsock < 0) {
+ perror(_("nfs socket"));
+ goto fail;
+ }
+ if (bindresvport(fsock, 0) < 0) {
+ perror(_("nfs bindresvport"));
+ goto fail;
+ }
}
+
#ifdef NFS_MOUNT_DEBUG
printf(_("using port %d for nfs deamon\n"), nfs_pmap->pm_port);
#endif
* to avoid problems with multihomed hosts.
* --Swen
*/
- if (linux_version_code() <= 66314
+ if (linux_version_code() <= 0x01030a && fsock != -1
&& connect(fsock, (struct sockaddr *) nfs_saddr,
sizeof (*nfs_saddr)) < 0) {
perror(_("nfs connect"));
strcat(new_opts, cbuf);
*extra_opts = xstrdup(new_opts);
+ *need_statd = ! (data.flags & NFS_MOUNT_NONLM);
return 0;
/* abort */
close(fsock);
return retval;
}
-
-/*
- * We need to translate between nfs status return values and
- * the local errno values which may not be the same.
- *
- * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
- * "after #include <errno.h> the symbol errno is reserved for any use,
- * it cannot even be used as a struct tag or field name".
- */
-
-#ifndef EDQUOT
-#define EDQUOT ENOSPC
-#endif
-
-static struct {
- enum nfsstat stat;
- int errnum;
-} nfs_errtbl[] = {
- { NFS_OK, 0 },
- { NFSERR_PERM, EPERM },
- { NFSERR_NOENT, ENOENT },
- { NFSERR_IO, EIO },
- { NFSERR_NXIO, ENXIO },
- { NFSERR_ACCES, EACCES },
- { NFSERR_EXIST, EEXIST },
- { NFSERR_NODEV, ENODEV },
- { NFSERR_NOTDIR, ENOTDIR },
- { NFSERR_ISDIR, EISDIR },
-#ifdef NFSERR_INVAL
- { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
-#endif
- { NFSERR_FBIG, EFBIG },
- { NFSERR_NOSPC, ENOSPC },
- { NFSERR_ROFS, EROFS },
- { NFSERR_NAMETOOLONG, ENAMETOOLONG },
- { NFSERR_NOTEMPTY, ENOTEMPTY },
- { NFSERR_DQUOT, EDQUOT },
- { NFSERR_STALE, ESTALE },
-#ifdef EWFLUSH
- { NFSERR_WFLUSH, EWFLUSH },
-#endif
- /* Throw in some NFSv3 values for even more fun (HP returns these) */
- { 71, EREMOTE },
-
- { -1, EIO }
-};
-
-static char *nfs_strerror(int stat)
-{
- int i;
- static char buf[256];
-
- for (i = 0; nfs_errtbl[i].stat != -1; i++) {
- if (nfs_errtbl[i].stat == stat)
- return strerror(nfs_errtbl[i].errnum);
- }
- sprintf(buf, _("unknown nfs status return value: %d"), stat);
- return buf;
-}