All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2 / 2] Move NFS mount code from util-linux to nfs-utils
@ 2006-06-08 19:11 Amit Gud
  2006-06-09  6:21 ` Neil Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Amit Gud @ 2006-06-08 19:11 UTC (permalink / raw)
  To: Neil Brown; +Cc: nfs, Steve Dickson

[-- Attachment #1: Type: text/plain, Size: 66 bytes --]



AG
-- 
May the source be with you.
http://www.cis.ksu.edu/~gud


[-- Attachment #2: nfsmount-migration-to-nfsutils-support-v2.patch --]
[-- Type: text/plain, Size: 39760 bytes --]

Adds the support functions needed for mount and umount. This functionality will someday be available in the form of shared mount library.


Signed-off-by: Amit Gud <agud@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>

---
diff -uprN nfs-utils-1.0.8/support/include/conn.h nfs-utils-1.0.8-ag/support/include/conn.h
--- nfs-utils-1.0.8/support/include/conn.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/conn.h	2006-06-08 11:22:25.876915000 -0400
@@ -0,0 +1,41 @@
+/* 
+ * conn.h -- Connection routines for NFS mount / umount code.
+ *
+ * 2006-06-06 Amit Gud <agud@redhat.com>
+ * - Moved code snippets here from util-linux/mount
+ */
+
+#ifndef _CONN_H
+#define _CONN_H
+
+#ifdef HAVE_RPCSVC_NFS_PROT_H
+#include <rpcsvc/nfs_prot.h>
+#else
+#include <linux/nfs.h>
+#define nfsstat nfs_stat
+#endif
+
+#include <rpc/pmap_prot.h>
+
+#define MNT_SENDBUFSIZE ((u_int)2048)
+#define MNT_RECVBUFSIZE ((u_int)1024)
+
+typedef struct {
+	char **hostname;
+	struct sockaddr_in saddr;
+	struct pmap pmap;
+} clnt_addr_t;
+
+/* RPC call timeout values */
+static const struct timeval TIMEOUT = { 20, 0 };
+static const struct timeval RETRY_TIMEOUT = { 3, 0 };
+
+int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int);
+u_long nfsvers_to_mnt(const u_long);
+u_long mntvers_to_nfs(const u_long);
+int get_socket(struct sockaddr_in *, u_int, int);
+CLIENT * mnt_openclnt(clnt_addr_t *, int *);
+void mnt_closeclnt(CLIENT *, int);
+
+#endif /* _CONN_H */
+
diff -uprN nfs-utils-1.0.8/support/include/fstab.h nfs-utils-1.0.8-ag/support/include/fstab.h
--- nfs-utils-1.0.8/support/include/fstab.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/fstab.h	2006-06-08 11:22:25.881916000 -0400
@@ -0,0 +1,24 @@
+#ifndef _NFS_FSTAB_H
+#define _NFS_FSTAB_H
+
+#include "nfs_mntent.h"
+
+int mtab_is_writable(void);
+int mtab_does_not_exist(void);
+
+struct mntentchn {
+	struct mntentchn *nxt, *prev;
+	nfs_mntent_t m;
+};
+
+struct mntentchn *mtab_head (void);
+struct mntentchn *getmntoptfile (const char *file);
+struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
+struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
+
+void lock_mtab (void);
+void unlock_mtab (void);
+void update_mtab (const char *special, nfs_mntent_t *with);
+
+#endif /* _NFS_FSTAB_H */
+
diff -uprN nfs-utils-1.0.8/support/include/Makefile.am nfs-utils-1.0.8-ag/support/include/Makefile.am
--- nfs-utils-1.0.8/support/include/Makefile.am	2005-12-19 23:12:43.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/Makefile.am	2006-06-08 11:22:25.885917000 -0400
@@ -3,9 +3,13 @@
 SUBDIRS = nfs rpcsvc sys
 
 noinst_HEADERS = \
+	conn.h \
 	exportfs.h \
+	fstab.h \
 	ha-callout.h \
 	misc.h \
+	nfs_mntent.h \
+	nfs_paths.h \
 	nfslib.h \
 	rpcdispatch.h \
 	rpcmisc.h \
@@ -15,6 +19,7 @@ noinst_HEADERS = \
 	xio.h \
 	xlog.h \
 	xmalloc.h \
+	xcommon.h \
 	ypupdate.h
 
 MAINTAINERCLEANFILES = Makefile.in
diff -uprN nfs-utils-1.0.8/support/include/nfs_mntent.h nfs-utils-1.0.8-ag/support/include/nfs_mntent.h
--- nfs-utils-1.0.8/support/include/nfs_mntent.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/nfs_mntent.h	2006-06-08 11:22:25.891916000 -0400
@@ -0,0 +1,34 @@
+/*
+ * 2006-06-08 Amit Gud <agud@redhat.com>
+ * - Moved code snippets here from util-linux/mount/my_mntent.h
+ */
+
+#ifndef _NFS_MNTENT_H
+#define _NFS_MNTENT_H
+
+typedef struct nfs_mntent_s {
+	const char *mnt_fsname;
+	const char *mnt_dir;
+	const char *mnt_type;
+	const char *mnt_opts;
+	int mnt_freq;
+	int mnt_passno;
+} nfs_mntent_t;
+
+#define ERR_MAX 5
+
+typedef struct mntFILEstruct {
+	FILE *mntent_fp;
+	char *mntent_file;
+	int mntent_lineno;
+	int mntent_errs;
+	int mntent_softerrs;
+} mntFILE;
+
+mntFILE *nfs_setmntent (const char *file, char *mode);
+void nfs_endmntent (mntFILE *mfp);
+int nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt);
+struct nfs_mntent *my_getmntent (mntFILE *mfp);
+nfs_mntent_t *nfs_getmntent (mntFILE *mfp);
+
+#endif /* _NFS_MNTENT_H */
diff -uprN nfs-utils-1.0.8/support/include/nfs_paths.h nfs-utils-1.0.8-ag/support/include/nfs_paths.h
--- nfs-utils-1.0.8/support/include/nfs_paths.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/nfs_paths.h	2006-06-08 11:22:25.896916000 -0400
@@ -0,0 +1,16 @@
+#ifndef _NFS_PATHS_H
+#define _NFS_PATHS_H
+
+#include <paths.h>
+#define _PATH_FSTAB	"/etc/fstab"
+#ifdef _PATH_MOUNTED
+#define MOUNTED_LOCK	_PATH_MOUNTED "~"
+#define MOUNTED_TEMP	_PATH_MOUNTED ".tmp"
+#else
+#define MOUNTED_LOCK	"/etc/mtab~"
+#define MOUNTED_TEMP	"/etc/mtab.tmp"
+#endif
+#define LOCK_TIMEOUT	10
+
+#endif /* _NFS_PATHS_H */
+
diff -uprN nfs-utils-1.0.8/support/include/nls.h nfs-utils-1.0.8-ag/support/include/nls.h
--- nfs-utils-1.0.8/support/include/nls.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/nls.h	2006-06-08 11:22:25.902916000 -0400
@@ -0,0 +1,27 @@
+/* 
+ * 2006-06-08 Amit Gud <agud@redhat.com>
+ * - Copied to nfs-utils/support/include from util-linux/mount
+ */
+
+#ifndef LOCALEDIR
+#define LOCALEDIR "/usr/share/locale"
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+# ifdef gettext_noop
+#  define N_(String) gettext_noop (String)
+# else
+#  define N_(String) (String)
+# endif
+#else
+# undef bindtextdomain
+# define bindtextdomain(Domain, Directory) /* empty */
+# undef textdomain
+# define textdomain(Domain) /* empty */
+# define _(Text) (Text)
+# define N_(Text) (Text)
+#endif
+
+
diff -uprN nfs-utils-1.0.8/support/include/xcommon.h nfs-utils-1.0.8-ag/support/include/xcommon.h
--- nfs-utils-1.0.8/support/include/xcommon.h	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/include/xcommon.h	2006-06-08 11:22:25.907915000 -0400
@@ -0,0 +1,48 @@
+/*
+ * xcommon.h -- Support function prototypes. Functions are in xcommon.c.
+ *
+ * 2006-06-06 Amit Gud <agud@redhat.com>
+ * - Moved code snippets  from mount/sundries.h of util-linux
+ *   and merged code from support/nfs/xmalloc.c by Olaf Kirch <okir@monad.swb.de> here.
+ */
+
+#ifndef _XMALLOC_H
+#define _MALLOC_H
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define streq(s, t)	(strcmp ((s), (t)) == 0)
+
+/* Functions in sundries.c that are used in mount.c and umount.c  */ 
+char *canonicalize (const char *path);
+void nfs_error (const char *fmt, ...);
+void *xmalloc (size_t size);
+void *xrealloc(void *p, size_t size);
+void xfree(void *);
+char *xstrdup (const char *s);
+char *xstrndup (const char *s, int n);
+char *xstrconcat2 (const char *, const char *);
+char *xstrconcat3 (const char *, const char *, const char *);
+char *xstrconcat4 (const char *, const char *, const char *, const char *);
+void die (int errcode, const char *fmt, ...);
+
+extern void die(int err, const char *fmt, ...);
+extern void (*at_die)(void);
+
+/* exit status - bits below are ORed */
+#define EX_USAGE	1	/* incorrect invocation or permission */
+#define EX_SYSERR	2	/* out of memory, cannot fork, ... */
+#define EX_SOFTWARE	4	/* internal mount bug or wrong version */
+#define EX_USER		8	/* user interrupt */
+#define EX_FILEIO      16	/* problems writing, locking, ... mtab/fstab */
+#define EX_FAIL	       32	/* mount failure */
+#define EX_SOMEOK      64	/* some mount succeeded */
+#define EX_BG         256       /* retry in background (internal only) */
+
+#endif /* XMALLOC_H */
diff -uprN nfs-utils-1.0.8/support/include/xmalloc.h nfs-utils-1.0.8-ag/support/include/xmalloc.h
--- nfs-utils-1.0.8/support/include/xmalloc.h	1999-10-18 19:21:12.000000000 -0400
+++ nfs-utils-1.0.8-ag/support/include/xmalloc.h	2006-06-08 11:22:25.911916000 -0400
@@ -1,16 +1 @@
-/*
- * xmalloc	Module for memory allocation. Drop in your
- *		debugging malloc module if you feel like it.
- *
- * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
- */
-
-#ifndef XMALLOC_H
-#define XMALLOC_H
-
-void	*xmalloc(size_t size);
-void	*xrealloc(void *ptr, size_t size);
-char	*xstrdup(const char *s);
-void	xfree(void *ptr);
-
-#endif /* XMALLOC_H */
+#include "xcommon.h"
diff -uprN nfs-utils-1.0.8/support/nfs/conn.c nfs-utils-1.0.8-ag/support/nfs/conn.c
--- nfs-utils-1.0.8/support/nfs/conn.c	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/conn.c	2006-06-08 11:22:25.917915000 -0400
@@ -0,0 +1,212 @@
+/*
+ * conn.c -- NFS client mount / umount connection code support functions
+ *
+ * 2006-06-06 Amit Gud <agud@redhat.com>
+ * - Moved code snippets to nfs-utils/support/nfs from util-linux/mount/nfsmount.c
+ *
+ */
+
+#include <errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+//#include <sys/mount.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "conn.h"
+
+extern int verbose;
+
+/* Map an NFS version into the corresponding Mountd version */
+u_long nfsvers_to_mnt(const u_long vers)
+{
+	static const u_long nfs_to_mnt[] = { 0, 0, 1, 3 };
+	if (vers <= 3)
+		return nfs_to_mnt[vers];
+	return 0;
+}
+
+/* Map a Mountd version into the corresponding NFS version */
+u_long mntvers_to_nfs(const u_long vers)
+{
+	static const u_long mnt_to_nfs[] = { 0, 2, 2, 3 };
+	if (vers <= 3)
+		return mnt_to_nfs[vers];
+	return 0;
+}
+
+/*
+ * Create a socket that is locally bound to a 
+ * reserve or non-reserve port. For any failures,
+ * RPC_ANYSOCK is returned which will cause 
+ * the RPC code to create the socket instead. 
+ */
+int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
+{
+	int so, cc, type;
+	struct sockaddr_in laddr;
+	socklen_t namelen = sizeof(laddr);
+
+	type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
+	if ((so = socket (AF_INET, type, p_prot)) < 0) {
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
+		if (verbose) {
+			fprintf(stderr, 
+				"mount: Unable to create %s socket: errno %d (%s)\n",
+				p_prot == IPPROTO_UDP ? "UDP" : "TCP", 
+				errno, strerror(errno));
+		}
+		return RPC_ANYSOCK;
+	}
+	laddr.sin_family = AF_INET;
+	laddr.sin_port = 0;
+	laddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	if (resvp) {
+		if (bindresvport(so, &laddr) < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
+			if (verbose) {
+				fprintf(stderr, 
+					"mount: Unable to bindresvport %s socket: errno %d (%s)\n",
+					p_prot == IPPROTO_UDP ? "UDP" : "TCP", 
+					errno, strerror(errno));
+			}
+			close(so);
+			return RPC_ANYSOCK;
+		}
+	} else {
+		cc = bind(so, (struct sockaddr *)&laddr, namelen);
+		if (cc < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
+			if (verbose) {
+				fprintf(stderr, 
+					"mount: Unable to bind to %s socket: errno %d (%s)\n",
+					p_prot == IPPROTO_UDP ? "UDP" : "TCP", 
+					errno, strerror(errno));
+			}
+			close(so);
+			return RPC_ANYSOCK;
+		}
+	}
+	if (type == SOCK_STREAM) {
+		cc = connect(so, (struct sockaddr *)saddr, namelen);
+		if (cc < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
+			if (verbose) {
+				fprintf(stderr, 
+					"mount: Unable to connect to %s:%d, errno %d (%s)\n",
+					inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port),
+					errno, strerror(errno));
+			}
+			close(so);
+			return RPC_ANYSOCK;
+		}
+	}
+	return so;
+}
+
+/*
+ * Sigh... getport() doesn't actually check the version number.
+ * In order to make sure that the server actually supports the service
+ * we're requesting, we open and RPC client, and fire off a NULL
+ * RPC call.
+ */
+int
+clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
+	  const u_int prot)
+{
+	CLIENT *clnt=NULL;
+	int sock, stat;
+	static char clnt_res;
+
+	rpc_createerr.cf_stat = stat = errno = 0;
+	sock = get_socket(saddr, prot, FALSE);
+	if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
+		/*
+		 * TCP timeout. Bubble up the error to see 
+		 * how it should be handled.
+		 */
+		rpc_createerr.cf_stat = RPC_TIMEDOUT;
+		goto out_bad;
+	}
+
+	switch(prot) {
+	case IPPROTO_UDP:
+		clnt = clntudp_bufcreate(saddr, prog, vers,
+					 RETRY_TIMEOUT, &sock,
+					 RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+		break;
+	case IPPROTO_TCP:
+		clnt = clnttcp_create(saddr, prog, vers, &sock,
+				      RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+		break;
+	default:
+		goto out_bad;
+	}
+	if (!clnt)
+		goto out_bad;
+	memset(&clnt_res, 0, sizeof(clnt_res));
+	stat = clnt_call(clnt, NULLPROC,
+			 (xdrproc_t)xdr_void, (caddr_t)NULL,
+			 (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
+			 TIMEOUT);
+	if (stat) {
+		clnt_geterr(clnt, &rpc_createerr.cf_error);
+		rpc_createerr.cf_stat = stat;
+	}
+	clnt_destroy(clnt);
+	if (sock != -1)
+		close(sock);
+
+	if (stat == RPC_SUCCESS)
+		return 1;
+
+ out_bad:
+	return 0;
+}
+
+CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
+{
+	struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
+	struct pmap *mnt_pmap = &mnt_server->pmap;
+	CLIENT *clnt = NULL;
+
+	/* contact the mount daemon via TCP */
+	mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
+	*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE);
+
+	switch (mnt_pmap->pm_prot) {
+	case IPPROTO_UDP:
+		clnt = clntudp_bufcreate(mnt_saddr,
+					 mnt_pmap->pm_prog, mnt_pmap->pm_vers,
+					 RETRY_TIMEOUT, msock,
+					 MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
+		break;
+	case IPPROTO_TCP:
+		clnt = clnttcp_create(mnt_saddr,
+				      mnt_pmap->pm_prog, mnt_pmap->pm_vers,
+				      msock,
+				      MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
+		break;
+	}
+	if (clnt) {
+		/* try to mount hostname:dirname */
+		clnt->cl_auth = authunix_create_default();
+		return clnt;
+	}
+	return NULL;
+}
+
+void mnt_closeclnt(CLIENT *clnt, int msock)
+{
+	auth_destroy(clnt->cl_auth);
+	clnt_destroy(clnt);
+	close(msock);
+}
+
diff -uprN nfs-utils-1.0.8/support/nfs/fstab.c nfs-utils-1.0.8-ag/support/nfs/fstab.c
--- nfs-utils-1.0.8/support/nfs/fstab.c	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/fstab.c	2006-06-08 11:26:14.690640000 -0400
@@ -0,0 +1,486 @@
+/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+ * - added Native Language Support
+ * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - fixed strerr(errno) in gettext calls
+ *
+ * 2006-06-08 Amit Gud <agud@redhat.com>
+ * - Moved code to nfs-utils/support/nfs from util-linux/mount.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <mntent.h>
+
+#include "fstab.h"
+#include "xcommon.h"
+#include "nfs_mntent.h"
+#include "nfs_paths.h"
+#include "nls.h"
+
+#define streq(s, t)	(strcmp ((s), (t)) == 0)
+#define PROC_MOUNTS		"/proc/mounts"
+
+extern int verbose;
+
+/* Information about mtab. ------------------------------------*/
+static int have_mtab_info = 0;
+static int var_mtab_does_not_exist = 0;
+static int var_mtab_is_a_symlink = 0;
+
+static void
+get_mtab_info(void) {
+	struct stat mtab_stat;
+
+	if (!have_mtab_info) {
+		if (lstat(MOUNTED, &mtab_stat))
+			var_mtab_does_not_exist = 1;
+		else if (S_ISLNK(mtab_stat.st_mode))
+			var_mtab_is_a_symlink = 1;
+		have_mtab_info = 1;
+	}
+}
+
+int
+mtab_does_not_exist(void) {
+	get_mtab_info();
+	return var_mtab_does_not_exist;
+}
+
+static int
+mtab_is_a_symlink(void) {
+        get_mtab_info();
+        return var_mtab_is_a_symlink;
+}
+
+int
+mtab_is_writable() {
+	int fd;
+
+	/* Should we write to /etc/mtab upon an update?
+	   Probably not if it is a symlink to /proc/mounts, since that
+	   would create a file /proc/mounts in case the proc filesystem
+	   is not mounted. */
+	if (mtab_is_a_symlink())
+		return 0;
+
+	fd = open(MOUNTED, O_RDWR | O_CREAT, 0644);
+	if (fd >= 0) {
+		close(fd);
+		return 1;
+	} else
+		return 0;
+}
+
+/* Contents of mtab and fstab ---------------------------------*/
+
+struct mntentchn mounttable;
+static int got_mtab = 0;
+
+static void read_mounttable(void);
+
+struct mntentchn *
+mtab_head() {
+	if (!got_mtab)
+		read_mounttable();
+	return &mounttable;
+}
+
+static void
+my_free(const void *s) {
+	if (s)
+		free((void *) s);
+}
+
+static void
+discard_mntentchn(struct mntentchn *mc0) {
+	struct mntentchn *mc, *mc1;
+
+	for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
+		mc1 = mc->nxt;
+		my_free(mc->m.mnt_fsname);
+		my_free(mc->m.mnt_dir);
+		my_free(mc->m.mnt_type);
+		my_free(mc->m.mnt_opts);
+		free(mc);
+	}
+}
+
+static void
+read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
+	struct mntentchn *mc = mc0;
+	nfs_mntent_t *mnt;
+
+	while ((mnt = nfs_getmntent(mfp)) != NULL) {
+		if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
+			mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
+			mc->nxt->prev = mc;
+			mc = mc->nxt;
+			mc->m = *mnt;
+			mc->nxt = mc0;
+		}
+	}
+	mc0->prev = mc;
+	if (ferror(mfp->mntent_fp)) {
+		int errsv = errno;
+		nfs_error(_("warning: error reading %s: %s"),
+		      fnam, strerror (errsv));
+		mc0->nxt = mc0->prev = NULL;
+	}
+	nfs_endmntent(mfp);
+}
+
+/*
+ * Read /etc/mtab.  If that fails, try /proc/mounts.
+ * This produces a linked list. The list head mounttable is a dummy.
+ * Return 0 on success.
+ */
+static void
+read_mounttable() {
+        mntFILE *mfp;
+        const char *fnam;
+        struct mntentchn *mc = &mounttable;
+
+        got_mtab = 1;
+        mc->nxt = mc->prev = NULL;
+
+        fnam = MOUNTED;
+        mfp = nfs_setmntent (fnam, "r");
+        if (mfp == NULL || mfp->mntent_fp == NULL) {
+                int errsv = errno;
+                fnam = PROC_MOUNTS;
+                mfp = nfs_setmntent (fnam, "r");
+                if (mfp == NULL || mfp->mntent_fp == NULL) {
+                        nfs_error(_("warning: can't open %s: %s"),
+                              MOUNTED, strerror (errsv));
+                        return;
+                }
+                if (verbose)
+                        printf (_("mount: could not open %s - "
+                                  "using %s instead\n"),
+                                MOUNTED, PROC_MOUNTS);
+        }
+        read_mntentchn(mfp, fnam, mc);
+}
+
+/*
+ * Given the directory name NAME, and the place MCPREV we found it last time,
+ * try to find more occurrences.
+ */ 
+struct mntentchn *
+getmntdirbackward (const char *name, struct mntentchn *mcprev) {
+	struct mntentchn *mc, *mc0;
+
+	mc0 = mtab_head();
+	if (!mcprev)
+		mcprev = mc0;
+	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
+		if (streq(mc->m.mnt_dir, name))
+			return mc;
+	return NULL;
+}
+
+/*
+ * Given the device name NAME, and the place MCPREV we found it last time,
+ * try to find more occurrences.
+ */ 
+struct mntentchn *
+getmntdevbackward (const char *name, struct mntentchn *mcprev) {
+	struct mntentchn *mc, *mc0;
+
+	mc0 = mtab_head();
+	if (!mcprev)
+		mcprev = mc0;
+	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
+		if (streq(mc->m.mnt_fsname, name))
+			return mc;
+	return NULL;
+}
+
+/* Updating mtab ----------------------------------------------*/
+
+/* Flag for already existing lock file. */
+static int we_created_lockfile = 0;
+static int lockfile_fd = -1;
+
+/* Flag to indicate that signals have been set up. */
+static int signals_have_been_setup = 0;
+
+/* Ensure that the lock is released if we are interrupted.  */
+extern char *strsignal(int sig);	/* not always in <string.h> */
+
+static void
+handler (int sig) {
+     die(EX_USER, "%s", strsignal(sig));
+}
+
+static void
+setlkw_timeout (int sig) {
+     /* nothing, fcntl will fail anyway */
+}
+
+/* Remove lock file.  */
+void
+unlock_mtab (void) {
+	if (we_created_lockfile) {
+		close(lockfile_fd);
+		lockfile_fd = -1;
+		unlink (MOUNTED_LOCK);
+		we_created_lockfile = 0;
+	}
+}
+
+/* Create the lock file.
+   The lock file will be removed if we catch a signal or when we exit. */
+/* The old code here used flock on a lock file /etc/mtab~ and deleted
+   this lock file afterwards. However, as rgooch remarks, that has a
+   race: a second mount may be waiting on the lock and proceed as
+   soon as the lock file is deleted by the first mount, and immediately
+   afterwards a third mount comes, creates a new /etc/mtab~, applies
+   flock to that, and also proceeds, so that the second and third mount
+   now both are scribbling in /etc/mtab.
+   The new code uses a link() instead of a creat(), where we proceed
+   only if it was us that created the lock, and hence we always have
+   to delete the lock afterwards. Now the use of flock() is in principle
+   superfluous, but avoids an arbitrary sleep(). */
+
+/* Where does the link point to? Obvious choices are mtab and mtab~~.
+   HJLu points out that the latter leads to races. Right now we use
+   mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */
+#define MOUNTLOCK_LINKTARGET		MOUNTED_LOCK "%d"
+#define MOUNTLOCK_LINKTARGET_LTH	(sizeof(MOUNTED_LOCK)+20)
+
+void
+lock_mtab (void) {
+	int tries = 100000, i;
+	char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
+
+	at_die = unlock_mtab;
+
+	if (!signals_have_been_setup) {
+		int sig = 0;
+		struct sigaction sa;
+
+		sa.sa_handler = handler;
+		sa.sa_flags = 0;
+		sigfillset (&sa.sa_mask);
+  
+		while (sigismember (&sa.sa_mask, ++sig) != -1
+		       && sig != SIGCHLD) {
+			if (sig == SIGALRM)
+				sa.sa_handler = setlkw_timeout;
+			else
+				sa.sa_handler = handler;
+			sigaction (sig, &sa, (struct sigaction *) 0);
+		}
+		signals_have_been_setup = 1;
+	}
+
+	sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
+
+	i = open (linktargetfile, O_WRONLY|O_CREAT, 0);
+	if (i < 0) {
+		int errsv = errno;
+		/* linktargetfile does not exist (as a file)
+		   and we cannot create it. Read-only filesystem?
+		   Too many files open in the system?
+		   Filesystem full? */
+		die (EX_FILEIO, _("can't create lock file %s: %s "
+						  "(use -n flag to override)"),
+			 linktargetfile, strerror (errsv));
+	}
+	close(i);
+	
+	/* Repeat until it was us who made the link */
+	while (!we_created_lockfile) {
+		struct flock flock;
+		int errsv, j;
+
+		j = link(linktargetfile, MOUNTED_LOCK);
+		errsv = errno;
+
+		if (j == 0)
+			we_created_lockfile = 1;
+
+		if (j < 0 && errsv != EEXIST) {
+			(void) unlink(linktargetfile);
+			die (EX_FILEIO, _("can't link lock file %s: %s "
+			     "(use -n flag to override)"),
+			     MOUNTED_LOCK, strerror (errsv));
+		}
+
+		lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
+
+		if (lockfile_fd < 0) {
+			int errsv = errno;
+			/* Strange... Maybe the file was just deleted? */
+			if (errno == ENOENT && tries-- > 0) {
+				if (tries % 200 == 0)
+					usleep(30);
+				continue;
+			}
+			(void) unlink(linktargetfile);
+			die (EX_FILEIO, _("can't open lock file %s: %s "
+			     "(use -n flag to override)"),
+			     MOUNTED_LOCK, strerror (errsv));
+		}
+
+		flock.l_type = F_WRLCK;
+		flock.l_whence = SEEK_SET;
+		flock.l_start = 0;
+		flock.l_len = 0;
+
+		if (j == 0) {
+			/* We made the link. Now claim the lock. */
+			if (fcntl (lockfile_fd, F_SETLK, &flock) == -1) {
+				if (verbose) {
+				    int errsv = errno;
+				    printf(_("Can't lock lock file %s: %s\n"),
+					   MOUNTED_LOCK, strerror (errsv));
+				}
+				/* proceed anyway */
+			}
+			(void) unlink(linktargetfile);
+		} else {
+			static int tries = 0;
+
+			/* Someone else made the link. Wait. */
+			alarm(LOCK_TIMEOUT);
+			if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
+				int errsv = errno;
+				(void) unlink(linktargetfile);
+				die (EX_FILEIO, _("can't lock lock file %s: %s"),
+				     MOUNTED_LOCK, (errno == EINTR) ?
+				     _("timed out") : strerror (errsv));
+			}
+			alarm(0);
+			/* Limit the number of iterations - maybe there
+			   still is some old /etc/mtab~ */
+			++tries;
+			if (tries % 200 == 0)
+			   usleep(30);
+			if (tries > 100000) {
+				(void) unlink(linktargetfile);
+				close(lockfile_fd);
+				die (EX_FILEIO, _("Cannot create link %s\n"
+						  "Perhaps there is a stale lock file?\n"),
+					 MOUNTED_LOCK);
+ 			}
+			close(lockfile_fd);
+		}
+	}
+}
+
+/*
+ * Update the mtab.
+ *  Used by umount with null INSTEAD: remove the last DIR entry.
+ *  Used by mount upon a remount: update option part,
+ *   and complain if a wrong device or type was given.
+ *   [Note that often a remount will be a rw remount of /
+ *    where there was no entry before, and we'll have to believe
+ *    the values given in INSTEAD.]
+ */
+
+void
+update_mtab (const char *dir, nfs_mntent_t *instead) {
+	mntFILE *mfp, *mftmp;
+	const char *fnam = MOUNTED;
+	struct mntentchn mtabhead;	/* dummy */
+	struct mntentchn *mc, *mc0, *absent = NULL;
+
+	if (mtab_does_not_exist() || !mtab_is_writable())
+		return;
+
+	lock_mtab();
+
+	/* having locked mtab, read it again */
+	mc0 = mc = &mtabhead;
+	mc->nxt = mc->prev = NULL;
+
+	mfp = nfs_setmntent(fnam, "r");
+	if (mfp == NULL || mfp->mntent_fp == NULL) {
+		int errsv = errno;
+		nfs_error (_("cannot open %s (%s) - mtab not updated"),
+		       fnam, strerror (errsv));
+		goto leave;
+	}
+
+	read_mntentchn(mfp, fnam, mc);
+
+	/* find last occurrence of dir */
+	for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
+		if (streq(mc->m.mnt_dir, dir))
+			break;
+	if (mc && mc != mc0) {
+		if (instead == NULL) {
+			/* An umount - remove entry */
+			if (mc && mc != mc0) {
+				mc->prev->nxt = mc->nxt;
+				mc->nxt->prev = mc->prev;
+				free(mc);
+			}
+		} else {
+			/* A remount */
+			mc->m.mnt_opts = instead->mnt_opts;
+		}
+	} else if (instead) {
+		/* not found, add a new entry */
+		absent = xmalloc(sizeof(*absent));
+		absent->m = *instead;
+		absent->nxt = mc0;
+		absent->prev = mc0->prev;
+		mc0->prev = absent;
+		if (mc0->nxt == NULL)
+			mc0->nxt = absent;
+	}
+
+	/* write chain to mtemp */
+	mftmp = nfs_setmntent (MOUNTED_TEMP, "w");
+	if (mftmp == NULL || mftmp->mntent_fp == NULL) {
+		int errsv = errno;
+		nfs_error (_("cannot open %s (%s) - mtab not updated"),
+		       MOUNTED_TEMP, strerror (errsv));
+		goto leave;
+	}
+
+	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
+		if (nfs_addmntent(mftmp, &(mc->m)) == 1) {
+			int errsv = errno;
+			die (EX_FILEIO, _("error writing %s: %s"),
+			     MOUNTED_TEMP, strerror (errsv));
+		}
+	}
+
+	discard_mntentchn(mc0);
+
+	if (fchmod (fileno (mftmp->mntent_fp),
+		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
+		int errsv = errno;
+		fprintf(stderr, _("error changing mode of %s: %s\n"),
+			MOUNTED_TEMP, strerror (errsv));
+	}
+	nfs_endmntent (mftmp);
+
+	{ /*
+	   * If mount is setuid and some non-root user mounts sth,
+	   * then mtab.tmp might get the group of this user. Copy uid/gid
+	   * from the present mtab before renaming.
+	   */
+	    struct stat sbuf;
+	    if (stat (MOUNTED, &sbuf) == 0)
+		chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid);
+	}
+
+	/* rename mtemp to mtab */
+	if (rename (MOUNTED_TEMP, MOUNTED) < 0) {
+		int errsv = errno;
+		fprintf(stderr, _("can't rename %s to %s: %s\n"),
+			MOUNTED_TEMP, MOUNTED, strerror(errsv));
+	}
+
+ leave:
+	unlock_mtab();
+}
diff -uprN nfs-utils-1.0.8/support/nfs/Makefile.am nfs-utils-1.0.8-ag/support/nfs/Makefile.am
--- nfs-utils-1.0.8/support/nfs/Makefile.am	2005-12-19 23:12:44.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/Makefile.am	2006-06-08 11:22:25.928915000 -0400
@@ -2,9 +2,9 @@
 
 noinst_LIBRARIES = libnfs.a
 libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
-		   xlog.c xmalloc.c wildmat.c nfssvc.c nfsclient.c \
+		   xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \
 		   nfsexport.c getfh.c nfsctl.c lockdsvc.c \
-		   svc_socket.c cacheio.c closeall.c
+		   svc_socket.c cacheio.c closeall.c conn.c fstab.c nfs_mntent.c
 
 MAINTAINERCLEANFILES = Makefile.in
 
diff -uprN nfs-utils-1.0.8/support/nfs/nfs_mntent.c nfs-utils-1.0.8-ag/support/nfs/nfs_mntent.c
--- nfs-utils-1.0.8/support/nfs/nfs_mntent.c	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/nfs_mntent.c	2006-06-08 11:22:25.934916000 -0400
@@ -0,0 +1,226 @@
+/* Private version of the libc *mntent() routines. */
+/* Note slightly different prototypes. */
+
+/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+ * - added Native Language Support
+ *
+ * 2006-06-08 Amit Gud <agud@redhat.com>
+ * - Moved to nfs-utils/support/nfs from util-linux/mount
+ */
+
+#include <stdio.h>
+#include <string.h>		/* for index */
+#include <ctype.h>		/* for isdigit */
+#include <sys/stat.h>		/* for umask */
+
+#include "nfs_mntent.h"
+#include "nls.h"
+#include "xcommon.h"
+
+/* Unfortunately the classical Unix /etc/mtab and /etc/fstab
+   do not handle directory names containing spaces.
+   Here we mangle them, replacing a space by \040.
+   What do other Unices do? */
+
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static char *
+mangle(const unsigned char *s) {
+	char *ss, *sp;
+	int n;
+
+	n = strlen(s);
+	ss = sp = xmalloc(4*n+1);
+	while(1) {
+		for (n = 0; n < sizeof(need_escaping); n++) {
+			if (*s == need_escaping[n]) {
+				*sp++ = '\\';
+				*sp++ = '0' + ((*s & 0300) >> 6);
+				*sp++ = '0' + ((*s & 070) >> 3);
+				*sp++ = '0' + (*s & 07);
+				goto next;
+			}
+		}
+		*sp++ = *s;
+		if (*s == 0)
+			break;
+	next:
+		s++;
+	}
+	return ss;
+}
+
+static int
+is_space_or_tab (char c) {
+	return (c == ' ' || c == '\t');
+}
+
+static char *
+skip_spaces(char *s) {
+	while (is_space_or_tab(*s))
+		s++;
+	return s;
+}
+
+static char *
+skip_nonspaces(char *s) {
+	while (*s && !is_space_or_tab(*s))
+		s++;
+	return s;
+}
+
+#define isoctal(a) (((a) & ~7) == '0')
+
+/* returns malloced pointer - no more strdup required */
+static char *
+unmangle(char *s) {
+	char *ret, *ss, *sp;
+
+	ss = skip_nonspaces(s);
+	ret = sp = xmalloc(ss-s+1);
+	while(s != ss) {
+		if (*s == '\\' && isoctal(s[1]) && isoctal(s[2]) && isoctal(s[3])) {
+			*sp++ = 64*(s[1] & 7) + 8*(s[2] & 7) + (s[3] & 7);
+			s += 4;
+		} else
+			*sp++ = *s++;
+	}
+	*sp = 0;
+	return ret;
+}
+
+/*
+ * fstat'ing the file and allocating a buffer holding all of it
+ * may be a bad idea: if the file is /proc/mounts, the stat
+ * returns 0.
+ * (On the other hand, mangling and unmangling is meaningless
+ *  for /proc/mounts.)
+ */
+
+mntFILE *
+nfs_setmntent (const char *file, char *mode) {
+	mntFILE *mfp = xmalloc(sizeof(*mfp));
+	mode_t old_umask = umask(077);
+
+	mfp->mntent_fp = fopen(file, mode);
+	umask(old_umask);
+	mfp->mntent_file = xstrdup(file);
+	mfp->mntent_errs = (mfp->mntent_fp == NULL);
+	mfp->mntent_softerrs = 0;
+	mfp->mntent_lineno = 0;
+	return mfp;
+}
+
+void
+nfs_endmntent (mntFILE *mfp) {
+	if (mfp) {
+		if (mfp->mntent_fp)
+			fclose(mfp->mntent_fp);
+		if (mfp->mntent_file)
+			free(mfp->mntent_file);
+		free(mfp);
+	}
+}
+
+int
+nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt) {
+	char *m1, *m2, *m3, *m4;
+	int res;
+
+	if (fseek (mfp->mntent_fp, 0, SEEK_END))
+		return 1;			/* failure */
+
+	m1 = mangle(mnt->mnt_fsname);
+	m2 = mangle(mnt->mnt_dir);
+	m3 = mangle(mnt->mnt_type);
+	m4 = mangle(mnt->mnt_opts);
+
+	res = fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
+		       m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno);
+
+	free(m1);
+	free(m2);
+	free(m3);
+	free(m4);
+	return (res < 0) ? 1 : 0;
+}
+
+/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
+nfs_mntent_t *
+nfs_getmntent (mntFILE *mfp) {
+	static char buf[4096];
+	static nfs_mntent_t me;
+	char *s;
+
+ again:
+	if (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX)
+		return NULL;
+
+	/* read the next non-blank non-comment line */
+	do {
+		if (fgets (buf, sizeof(buf), mfp->mntent_fp) == NULL)
+			return NULL;
+
+		mfp->mntent_lineno++;
+		s = index (buf, '\n');
+		if (s == NULL) {
+			/* Missing final newline?  Otherwise extremely */
+			/* long line - assume file was corrupted */
+			if (feof(mfp->mntent_fp)) {
+				fprintf(stderr, _("[mntent]: warning: no final "
+					"newline at the end of %s\n"),
+					mfp->mntent_file);
+				s = index (buf, 0);
+			} else {
+				mfp->mntent_errs = 1;
+				goto err;
+			}
+		}
+		*s = 0;
+		if (--s >= buf && *s == '\r')
+			*s = 0;
+		s = skip_spaces(buf);
+	} while (*s == '\0' || *s == '#');
+
+	me.mnt_fsname = unmangle(s);
+	s = skip_nonspaces(s);
+	s = skip_spaces(s);
+	me.mnt_dir = unmangle(s);
+	s = skip_nonspaces(s);
+	s = skip_spaces(s);
+	me.mnt_type = unmangle(s);
+	s = skip_nonspaces(s);
+	s = skip_spaces(s);
+	me.mnt_opts = unmangle(s);
+	s = skip_nonspaces(s);
+	s = skip_spaces(s);
+
+	if (isdigit(*s)) {
+		me.mnt_freq = atoi(s);
+		while(isdigit(*s)) s++;
+	} else
+		me.mnt_freq = 0;
+	if(*s && !is_space_or_tab(*s))
+		goto err;
+
+	s = skip_spaces(s);
+	if(isdigit(*s)) {
+		me.mnt_passno = atoi(s);
+		while(isdigit(*s)) s++;
+	} else
+		me.mnt_passno = 0;
+	if(*s && !is_space_or_tab(*s))
+		goto err;
+
+	/* allow more stuff, e.g. comments, on this line */
+
+	return &me;
+
+ err:
+	mfp->mntent_softerrs++;
+	fprintf(stderr, _("[mntent]: line %d in %s is bad%s\n"),
+		mfp->mntent_lineno, mfp->mntent_file,
+		(mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) ?
+		_("; rest of file ignored") : "");
+	goto again;
+}
diff -uprN nfs-utils-1.0.8/support/nfs/xcommon.c nfs-utils-1.0.8-ag/support/nfs/xcommon.c
--- nfs-utils-1.0.8/support/nfs/xcommon.c	1969-12-31 19:00:00.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/xcommon.c	2006-06-08 11:22:25.940915000 -0400
@@ -0,0 +1,185 @@
+/*
+ * xcommon.c - various functions put together to avoid basic error checking.
+ *
+ * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927
+ *
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+ * - added Native Language Support
+ *
+ * 2006-06-06 Amit Gud <agud@redhat.com>
+ * - Moved code snippets here from mount/sundries.c of util-linux
+ *   and merged code from support/nfs/xmalloc.c by Olaf Kirch <okir@monad.swb.de> here.
+ */
+
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "xcommon.h"
+#include "nls.h"	/* _() */
+
+void (*at_die)(void ) = NULL;
+
+char *
+xstrndup (const char *s, int n) {
+     char *t;
+
+     if (s == NULL)
+	  die (EX_SOFTWARE, _("bug in xstrndup call"));
+
+     t = xmalloc(n+1);
+     strncpy(t,s,n);
+     t[n] = 0;
+
+     return t;
+}
+
+char *
+xstrconcat2 (const char *s, const char *t) {
+     char *res;
+
+     if (!s) s = "";
+     if (!t) t = "";
+     res = xmalloc(strlen(s) + strlen(t) + 1);
+     strcpy(res, s);
+     strcat(res, t);
+     return res;
+}
+
+/* frees its first arg - typical use: s = xstrconcat3(s,t,u); */
+char *
+xstrconcat3 (const char *s, const char *t, const char *u) {
+     char *res;
+
+     if (!s) s = "";
+     if (!t) t = "";
+     if (!u) u = "";
+     res = xmalloc(strlen(s) + strlen(t) + strlen(u) + 1);
+     strcpy(res, s);
+     strcat(res, t);
+     strcat(res, u);
+     free((void *) s);
+     return res;
+}
+
+/* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */
+char *
+xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
+     char *res;
+
+     if (!s) s = "";
+     if (!t) t = "";
+     if (!u) u = "";
+     if (!v) v = "";
+     res = xmalloc(strlen(s) + strlen(t) + strlen(u) + strlen(v) + 1);
+     strcpy(res, s);
+     strcat(res, t);
+     strcat(res, u);
+     strcat(res, v);
+     free((void *) s);
+     return res;
+}
+
+/* Non-fatal error.  Print message and return.  */
+/* (print the message in a single printf, in an attempt
+    to avoid mixing output of several threads) */
+void
+nfs_error (const char *fmt, ...) {
+     va_list args;
+     char *fmt2;
+
+     fmt2 = xstrconcat2 (fmt, "\n");
+     va_start (args, fmt);
+     vfprintf (stderr, fmt2, args);
+     va_end (args);
+     free (fmt2);
+}
+
+/* Make a canonical pathname from PATH.  Returns a freshly malloced string.
+   It is up the *caller* to ensure that the PATH is sensible.  i.e.
+   canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
+   is not a legal pathname for ``/dev/fd0''.  Anything we cannot parse
+   we return unmodified.   */
+char *canonicalize (const char *path) {
+	char canonical[PATH_MAX+2];
+
+	if (path == NULL)
+		return NULL;
+
+#if 1
+	if (streq(path, "none") ||
+	    streq(path, "proc") ||
+	    streq(path, "devpts"))
+		return xstrdup(path);
+#endif
+	if (realpath (path, canonical))
+		return xstrdup(canonical);
+
+	return xstrdup(path);
+}
+
+/* Fatal error.  Print message and exit.  */
+void
+die(int err, const char *fmt, ...) {
+	va_list args;
+
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	fprintf(stderr, "\n");
+	va_end(args);
+
+	if (at_die)
+		(*at_die)();
+
+	exit(err);
+}
+
+static void
+die_if_null(void *t) {
+	if (t == NULL)
+		die(EX_SYSERR, _("not enough memory"));
+}
+
+void *
+xmalloc (size_t size) {
+	void *t;
+
+	if (size == 0)
+		return NULL;
+
+	t = malloc(size);
+	die_if_null(t);
+
+	return t;
+}
+
+void *
+xrealloc (void *p, size_t size) {
+	void *t;
+
+	t = realloc(p, size);
+	die_if_null(t);
+
+	return t;
+}
+
+void
+xfree(void *ptr)
+{
+	free(ptr);
+}
+
+char *
+xstrdup (const char *s) {
+	char *t;
+
+	if (s == NULL)
+		return NULL;
+
+	t = strdup(s);
+	die_if_null(t);
+
+	return t;
+}
diff -uprN nfs-utils-1.0.8/support/nfs/xmalloc.c nfs-utils-1.0.8-ag/support/nfs/xmalloc.c
--- nfs-utils-1.0.8/support/nfs/xmalloc.c	2005-12-19 23:12:44.000000000 -0500
+++ nfs-utils-1.0.8-ag/support/nfs/xmalloc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- * support/nfs/xmalloc.c
- *
- * malloc with NULL checking.
- *
- * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include "xmalloc.h"
-#include "xlog.h"
-
-void *
-xmalloc(size_t size)
-{
-	void	*ptr;
-
-	if (!(ptr = malloc(size)))
-		xlog(L_FATAL, "malloc: out of memory");
-	return ptr;
-}
-
-void *
-xrealloc(void *ptr, size_t size)
-{
-	if (!(ptr = realloc(ptr, size)))
-		xlog(L_FATAL, "realloc: out of memory");
-	return ptr;
-}
-
-void
-xfree(void *ptr)
-{
-	free(ptr);
-}
-
-char *
-xstrdup(const char *str)
-{
-	char	*ret;
-
-	if (!(ret = strdup(str)))
-		xlog(L_FATAL, "strdup: out of memory");
-	return ret;
-}

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



[-- Attachment #4: Type: text/plain, Size: 140 bytes --]

_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 2 / 2] Move NFS mount code from util-linux to nfs-utils
  2006-06-08 19:11 [PATCH 2 / 2] Move NFS mount code from util-linux to nfs-utils Amit Gud
@ 2006-06-09  6:21 ` Neil Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Neil Brown @ 2006-06-09  6:21 UTC (permalink / raw)
  To: Amit Gud; +Cc: nfs, Steve Dickson

On Thursday June 8, agud@redhat.com wrote:
> 
> 
> AG
> -- 
> May the source be with you.
> http://www.cis.ksu.edu/~gud
> 
> Adds the support functions needed for mount and umount. This
> functionality will someday be available in the form of shared mount
> library. 

Is it really big enough to deserve a shared library? I suspect not.

> diff -uprN nfs-utils-1.0.8/support/include/nfs_paths.h nfs-utils-1.0.8-ag/support/include/nfs_paths.h
> --- nfs-utils-1.0.8/support/include/nfs_paths.h	1969-12-31 19:00:00.000000000 -0500
> +++ nfs-utils-1.0.8-ag/support/include/nfs_paths.h	2006-06-08 11:22:25.896916000 -0400
> @@ -0,0 +1,16 @@
> +#ifndef _NFS_PATHS_H
> +#define _NFS_PATHS_H
> +
> +#include <paths.h>
> +#define _PATH_FSTAB	"/etc/fstab"
> +#ifdef _PATH_MOUNTED
> +#define MOUNTED_LOCK	_PATH_MOUNTED "~"
> +#define MOUNTED_TEMP	_PATH_MOUNTED ".tmp"
> +#else
> +#define MOUNTED_LOCK	"/etc/mtab~"
> +#define MOUNTED_TEMP	"/etc/mtab.tmp"
> +#endif

How about:

 #ifndef _PATH_MOUNTED
 #define _PATH_MOUNTED "/etc/fstab"
 #endif
 #define MOUNTED_LOCK	_PATH_MOUNTED "~"
 #define MOUNTED_TEMP	_PATH_MOUNTED ".tmp"

Looks cleaner to me.


Thanks.
I'll look forward to the next version.

NeilBrown


_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-06-09  6:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-08 19:11 [PATCH 2 / 2] Move NFS mount code from util-linux to nfs-utils Amit Gud
2006-06-09  6:21 ` Neil Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.