summaryrefslogtreecommitdiffstats
path: root/mount
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:43 +0100
committerKarel Zak2006-12-07 00:25:43 +0100
commit22853e4a82c6ef7b336527529acb94b14a0b0fd8 (patch)
treeee28e4598c8c449d7e811711d8ce8eb17caecfb6 /mount
parentImported from util-linux-2.10f tarball. (diff)
downloadkernel-qcow2-util-linux-22853e4a82c6ef7b336527529acb94b14a0b0fd8.tar.gz
kernel-qcow2-util-linux-22853e4a82c6ef7b336527529acb94b14a0b0fd8.tar.xz
kernel-qcow2-util-linux-22853e4a82c6ef7b336527529acb94b14a0b0fd8.zip
Imported from util-linux-2.10m tarball.
Diffstat (limited to 'mount')
-rw-r--r--mount/Makefile56
-rw-r--r--mount/lomount.c553
-rw-r--r--mount/losetup.c237
-rw-r--r--mount/mount.830
-rw-r--r--mount/mount.c436
-rw-r--r--mount/mount_by_label.c198
-rw-r--r--mount/mount_by_label.h1
-rw-r--r--mount/mount_guess_fstype.c12
-rw-r--r--mount/nfs_mount4.h53
-rw-r--r--mount/nfs_mount4.h.sv (renamed from mount/nfs_mount3.h)22
-rw-r--r--mount/nfsmount.c204
-rw-r--r--mount/nfsmount.h325
-rw-r--r--mount/nfsmount.x78
-rw-r--r--mount/nfsmount_clnt.c281
-rw-r--r--mount/nfsmount_xdr.c334
-rw-r--r--mount/pivot_root.297
-rw-r--r--mount/pivot_root.865
-rw-r--r--mount/pivot_root.c24
-rw-r--r--mount/realpath.c21
-rw-r--r--mount/rpcsvc/nfsmount.h310
-rw-r--r--mount/rpcsvc/nfsmount.x78
-rw-r--r--mount/rpcsvc/nfsmount_clnt.c230
-rw-r--r--mount/rpcsvc/nfsmount_xdr.c467
-rw-r--r--mount/swapon.810
24 files changed, 1963 insertions, 2159 deletions
diff --git a/mount/Makefile b/mount/Makefile
index 443e8f783..6f72413db 100644
--- a/mount/Makefile
+++ b/mount/Makefile
@@ -14,14 +14,20 @@ LINK = $(CC) $(LDFLAGS)
SUID_PROGS = mount umount
NOSUID_PROGS = swapon losetup
-PROGS = $(SUID_PROGS) $(NOSUID_PROGS)
MAN5 = fstab.5 nfs.5
MAN8 = mount.8 swapoff.8 swapon.8 umount.8 losetup.8
+ifeq "$(HAVE_PIVOT_ROOT)" "yes"
+NOSUID_PROGS := $(NOSUID_PROGS) pivot_root
+MAN8 := $(MAN8) pivot_root.8
+endif
+
+PROGS = $(SUID_PROGS) $(NOSUID_PROGS)
+
# comment these out if you are not compiling in NFS support
NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
# uncomment this if you don't have libc-4.2 but do have the rpclib
-GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
+GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
# comment these out if you are not compiling in loop support
LO_OBJS=lomount.o
@@ -30,8 +36,8 @@ all: $(PROGS)
install: $(PROGS)
$(INSTALLDIR) $(BINDIR) $(SBINDIR)
- $(INSTALLSUID) -s $(SUID_PROGS) $(BINDIR)
- $(INSTALLBIN) -s $(NOSUID_PROGS) $(SBINDIR)
+ $(INSTALLSUID) $(SUID_PROGS) $(BINDIR)
+ $(INSTALLBIN) $(NOSUID_PROGS) $(SBINDIR)
(cd $(SBINDIR); ln -sf swapon swapoff)
$(INSTALLDIR) $(MAN5DIR) $(MAN8DIR)
$(INSTALLMAN) $(MAN5) $(MAN5DIR)
@@ -52,6 +58,10 @@ umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \
swapon: swapon.o version.o
$(LINK) $^ -o $@
+losetup.o: lomount.c
+ $(COMPILE) -DMAIN lomount.c
+ mv lomount.o losetup.o
+
losetup: losetup.o
$(LINK) $^ -o $@
@@ -85,28 +95,20 @@ nfsmount_clnt.o: nfsmount_clnt.c
nfsmount_xdr.o: nfsmount_xdr.c
$(COMPILE) $(RPC_CFLAGS) nfsmount_xdr.c
-# rpcgen generates files that do not compile - use the pregenerated ones
-# nfsmount.h nfsmount_xdr.c nfsmount_clnt.c: nfsmount.x
-# rm -f nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
-# $(RPCGEN) -h -o nfsmount.h nfsmount.x
-# $(RPCGEN) -c -o nfsmount_xdr.c nfsmount.x
-# $(RPCGEN) -l -o nfsmount_clnt.c nfsmount.x
-
-nfsmount.x:
- cp $(RPCSVCDIR)/nfsmount.x .
-
-nfsmount.o: nfs_mountversion.h nfs_mount3.h
-
-NFSMOUNTH=/usr/include/linux/nfs_mount.h
-
-nfs_mountversion.h:
- rm -f nfs_mountversion.h
- if [ -f $(NFSMOUNTH) ]; then \
- grep NFS_MOUNT_VERSION $(NFSMOUNTH) \
- | sed -e 's/NFS/KERNEL_NFS/'; \
- else \
- echo '#define KERNEL_NFS_MOUNT_VERSION 0'; \
- fi > nfs_mountversion.h
+ifeq "$(HAVE_GOOD_RPC)" "yes"
+nfsmount.h nfsmount_xdr.c nfsmount_clnt.c: nfsmount.x
+ rm -f nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
+ $(RPCGEN) -h -o nfsmount.h nfsmount.x
+ $(RPCGEN) -c -o nfsmount_xdr.c nfsmount.x
+ $(RPCGEN) -l -o nfsmount_clnt.c nfsmount.x
+else
+nfsmount.h nfsmount_xdr.c nfsmount_clnt.c:
+ cp $(RPCSVCDIR)/nfsmount.h .
+ cp $(RPCSVCDIR)/nfsmount_xdr.c .
+ cp $(RPCSVCDIR)/nfsmount_clnt.c .
+endif
+
+nfsmount.o: nfs_mount4.h
swapargs.h:
sh swap.configure
@@ -119,4 +121,4 @@ clean:
rm -f loop.h nfs_mountversion.h
clobber distclean realclean: clean
-# rm -f $(GEN_FILES)
+ rm -f $(GEN_FILES)
diff --git a/mount/lomount.c b/mount/lomount.c
index d99078585..52157a14a 100644
--- a/mount/lomount.c
+++ b/mount/lomount.c
@@ -23,268 +23,393 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include "loop.h"
#include "lomount.h"
#include "nls.h"
-char *xstrdup (const char *s); /* not: #include "sundries.h" */
-void error (const char *fmt, ...); /* idem */
+extern int verbose;
+extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
+extern void error (const char *fmt, ...); /* idem */
#ifdef LOOP_SET_FD
struct crypt_type_struct {
- int id;
- char *name;
+ int id;
+ char *name;
} crypt_type_tbl[] = {
- { LO_CRYPT_NONE, "no" },
- { LO_CRYPT_NONE, "none" },
- { LO_CRYPT_XOR, "xor" },
- { LO_CRYPT_DES, "DES" },
- { -1, NULL }
+ { LO_CRYPT_NONE, "no" },
+ { LO_CRYPT_NONE, "none" },
+ { LO_CRYPT_XOR, "xor" },
+ { LO_CRYPT_DES, "DES" },
+ { -1, NULL }
};
static int
-crypt_type (const char *name)
-{
- int i;
-
- if (name)
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (!strcasecmp (name, crypt_type_tbl[i].name))
- return crypt_type_tbl[i].id;
- return -1;
+crypt_type (const char *name) {
+ int i;
+
+ if (name) {
+ for (i = 0; crypt_type_tbl[i].id != -1; i++)
+ if (!strcasecmp (name, crypt_type_tbl[i].name))
+ return crypt_type_tbl[i].id;
+ }
+ return -1;
}
-#if 0
+#ifdef MAIN
static char *
-crypt_name (int id)
-{
- int i;
-
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (id == crypt_type_tbl[i].id)
- return crypt_type_tbl[i].name;
- return "undefined";
+crypt_name (int id) {
+ int i;
+
+ for (i = 0; crypt_type_tbl[i].id != -1; i++)
+ if (id == crypt_type_tbl[i].id)
+ return crypt_type_tbl[i].name;
+ return "undefined";
}
static void
-show_loop (char *device)
-{
- struct loop_info loopinfo;
- int fd;
-
- if ((fd = open (device, O_RDONLY)) < 0) {
- int errsv = errno;
- fprintf(stderr, _("loop: can't open device %s: %s\n"),
- device, strerror (errsv));
- return;
- }
- if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
- int errsv = errno;
- fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
- device, strerror (errsv));
- close (fd);
- return;
- }
- printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
- device, loopinfo.lo_device, loopinfo.lo_inode,
- loopinfo.lo_name, loopinfo.lo_offset,
- crypt_name (loopinfo.lo_encrypt_type));
- close (fd);
+show_loop (char *device) {
+ struct loop_info loopinfo;
+ int fd;
+
+ if ((fd = open (device, O_RDONLY)) < 0) {
+ int errsv = errno;
+ fprintf(stderr, _("loop: can't open device %s: %s\n"),
+ device, strerror (errsv));
+ return;
+ }
+ if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
+ int errsv = errno;
+ fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
+ device, strerror (errsv));
+ close (fd);
+ return;
+ }
+ printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
+ device, loopinfo.lo_device, loopinfo.lo_inode,
+ loopinfo.lo_name, loopinfo.lo_offset,
+ crypt_name (loopinfo.lo_encrypt_type));
+ close (fd);
}
#endif
char *
-find_unused_loop_device (void)
-{
- /* Just creating a device, say in /tmp, is probably a bad idea -
- people might have problems with backup or so.
- So, we just try /dev/loop[0-7]. */
- char dev[20];
- int i, fd, somedev = 0, someloop = 0, loop_known = 0;
- struct stat statbuf;
- struct loop_info loopinfo;
- FILE *procdev;
-
- for(i = 0; i < 256; i++) {
- sprintf(dev, "/dev/loop%d", i);
- if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
- somedev++;
- fd = open (dev, O_RDONLY);
- if (fd >= 0) {
- if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
- someloop++; /* in use */
- else if (errno == ENXIO) {
- close (fd);
- return xstrdup(dev); /* probably free */
- }
- close (fd);
- }
- continue; /* continue trying as long as devices exist */
- }
- if (i >= 7)
- break;
- }
-
- /* Nothing found. Why not? */
- if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
- char line[100];
- while (fgets (line, sizeof(line), procdev))
- if (strstr (line, " loop\n")) {
- loop_known = 1;
- break;
+find_unused_loop_device (void) {
+ /* Just creating a device, say in /tmp, is probably a bad idea -
+ people might have problems with backup or so.
+ So, we just try /dev/loop[0-7]. */
+ char dev[20];
+ int i, fd, somedev = 0, someloop = 0, loop_known = 0;
+ struct stat statbuf;
+ struct loop_info loopinfo;
+ FILE *procdev;
+
+ for(i = 0; i < 256; i++) {
+ sprintf(dev, "/dev/loop%d", i);
+ if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
+ somedev++;
+ fd = open (dev, O_RDONLY);
+ if (fd >= 0) {
+ if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
+ someloop++; /* in use */
+ else if (errno == ENXIO) {
+ close (fd);
+ return xstrdup(dev);/* probably free */
+ }
+ close (fd);
+ }
+ continue;/* continue trying as long as devices exist */
+ }
+ if (i >= 7)
+ break;
}
- fclose(procdev);
- if (!loop_known)
- loop_known = -1;
- }
-
- if (!somedev)
- error(_("mount: could not find any device /dev/loop#"));
- else if(!someloop) {
- if (loop_known == 1)
- error(_(
-"mount: Could not find any loop device.\n"
-" Maybe /dev/loop# has a wrong major number?"));
- else if (loop_known == -1)
- error(_(
-"mount: Could not find any loop device, and, according to %s,\n"
-" this kernel does not know about the loop device.\n"
-" (If so, then recompile or `insmod loop.o'.)"), PROC_DEVICES);
- else
- error(_(
-"mount: Could not find any loop device. Maybe this kernel does not know\n"
-" about the loop device (then recompile or `insmod loop.o'), or\n"
-" maybe /dev/loop# has the wrong major number?"));
- } else
- error(_("mount: could not find any free loop device"));
- return 0;
+
+ /* Nothing found. Why not? */
+ if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
+ char line[100];
+ while (fgets (line, sizeof(line), procdev))
+ if (strstr (line, " loop\n")) {
+ loop_known = 1;
+ break;
+ }
+ fclose(procdev);
+ if (!loop_known)
+ loop_known = -1;
+ }
+
+ if (!somedev)
+ error(_("mount: could not find any device /dev/loop#"));
+ else if(!someloop) {
+ if (loop_known == 1)
+ error(_(
+ "mount: Could not find any loop device.\n"
+ " Maybe /dev/loop# has a wrong major number?"));
+ else if (loop_known == -1)
+ error(_(
+ "mount: Could not find any loop device, and, according to %s,\n"
+ " this kernel does not know about the loop device.\n"
+ " (If so, then recompile or `insmod loop.o'.)"),
+ PROC_DEVICES);
+ else
+ error(_(
+ "mount: Could not find any loop device. Maybe this kernel does not know\n"
+ " about the loop device (then recompile or `insmod loop.o'), or\n"
+ " maybe /dev/loop# has the wrong major number?"));
+ } else
+ error(_("mount: could not find any free loop device"));
+ return 0;
}
int
set_loop (const char *device, const char *file, int offset,
- const char *encryption, int *loopro)
-{
- struct loop_info loopinfo;
- int fd, ffd, mode, i;
- char *pass;
-
- mode = (*loopro ? O_RDONLY : O_RDWR);
- if ((ffd = open (file, mode)) < 0) {
- if (!*loopro && errno == EROFS)
- ffd = open (file, mode = O_RDONLY);
- if (ffd < 0) {
- perror (file);
- return 1;
- }
- }
- if ((fd = open (device, mode)) < 0) {
- perror (device);
- return 1;
- }
- *loopro = (mode == O_RDONLY);
- memset (&loopinfo, 0, sizeof (loopinfo));
- strncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
- loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
- if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
- < 0) {
- fprintf (stderr, _("Unsupported encryption type %s\n"), encryption);
- return 1;
- }
- loopinfo.lo_offset = offset;
- switch (loopinfo.lo_encrypt_type) {
- case LO_CRYPT_NONE:
- loopinfo.lo_encrypt_key_size = 0;
- break;
- case LO_CRYPT_XOR:
- pass = getpass (_("Password: "));
- strncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
- loopinfo.lo_encrypt_key[LO_KEY_SIZE - 1] = 0;
- loopinfo.lo_encrypt_key_size = strlen (loopinfo.lo_encrypt_key);
- break;
- case LO_CRYPT_DES:
- pass = getpass (_("Password: "));
- strncpy (loopinfo.lo_encrypt_key, pass, 8);
- loopinfo.lo_encrypt_key[8] = 0;
- loopinfo.lo_encrypt_key_size = 8;
- pass = getpass (_("Init (up to 16 hex digits): "));
- for (i = 0; i < 16 && pass[i]; i++)
- if (isxdigit (pass[i]))
- loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
- (islower (pass[i]) ? toupper (pass[i]) :
- pass[i]) - 'A' + 10 : pass[i] - '0') << (i & 7) * 4;
- else {
- fprintf (stderr, _("Non-hex digit '%c'.\n"), pass[i]);
- return 1;
- }
- break;
- default:
- fprintf (stderr,
- _("Don't know how to get key for encryption system %d\n"),
- loopinfo.lo_encrypt_type);
- return 1;
- }
- if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
- perror ("ioctl: LOOP_SET_FD");
- return 1;
- }
- if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
- (void) ioctl (fd, LOOP_CLR_FD, 0);
- perror ("ioctl: LOOP_SET_STATUS");
- return 1;
- }
- close (fd);
- close (ffd);
- if (verbose > 1)
- printf(_("set_loop(%s,%s,%d): success\n"), device, file, offset);
- return 0;
+ const char *encryption, int *loopro) {
+ struct loop_info loopinfo;
+ int fd, ffd, mode, i;
+ char *pass;
+
+ mode = (*loopro ? O_RDONLY : O_RDWR);
+ if ((ffd = open (file, mode)) < 0) {
+ if (!*loopro && errno == EROFS)
+ ffd = open (file, mode = O_RDONLY);
+ if (ffd < 0) {
+ perror (file);
+ return 1;
+ }
+ }
+ if ((fd = open (device, mode)) < 0) {
+ perror (device);
+ return 1;
+ }
+ *loopro = (mode == O_RDONLY);
+
+ memset (&loopinfo, 0, sizeof (loopinfo));
+ strncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
+ loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
+ if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
+ < 0) {
+ fprintf (stderr, _("Unsupported encryption type %s\n"),
+ encryption);
+ return 1;
+ }
+ loopinfo.lo_offset = offset;
+
+#ifdef MCL_FUTURE
+ /*
+ * Oh-oh, sensitive data coming up. Better lock into memory to prevent
+ * passwd etc being swapped out and left somewhere on disk.
+ */
+
+ if(mlockall(MCL_CURRENT|MCL_FUTURE)) {
+ perror("memlock");
+ fprintf(stderr, _("Couldn't lock into memory, exiting.\n"));
+ exit(1);
+ }
+#endif
+
+ switch (loopinfo.lo_encrypt_type) {
+ case LO_CRYPT_NONE:
+ loopinfo.lo_encrypt_key_size = 0;
+ break;
+ case LO_CRYPT_XOR:
+ pass = getpass (_("Password: "));
+ strncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
+ loopinfo.lo_encrypt_key[LO_KEY_SIZE - 1] = 0;
+ loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
+ break;
+ case LO_CRYPT_DES:
+ pass = getpass (_("Password: "));
+ strncpy (loopinfo.lo_encrypt_key, pass, 8);
+ loopinfo.lo_encrypt_key[8] = 0;
+ loopinfo.lo_encrypt_key_size = 8;
+ pass = getpass (_("Init (up to 16 hex digits): "));
+ for (i = 0; i < 16 && pass[i]; i++)
+ if (isxdigit (pass[i])) {
+ loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
+ (islower (pass[i]) ? toupper (pass[i]) :
+ pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
+ } else {
+ fprintf (stderr, _("Non-hex digit '%c'.\n"),
+ pass[i]);
+ return 1;
+ }
+ break;
+ default:
+ fprintf (stderr,
+ _("Don't know how to get key for encryption system %d\n"),
+ loopinfo.lo_encrypt_type);
+ return 1;
+ }
+ if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
+ perror ("ioctl: LOOP_SET_FD");
+ return 1;
+ }
+ if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
+ (void) ioctl (fd, LOOP_CLR_FD, 0);
+ perror ("ioctl: LOOP_SET_STATUS");
+ return 1;
+ }
+ close (fd);
+ close (ffd);
+ if (verbose > 1)
+ printf(_("set_loop(%s,%s,%d): success\n"),
+ device, file, offset);
+ return 0;
}
int
-del_loop (const char *device)
-{
- int fd;
-
- if ((fd = open (device, O_RDONLY)) < 0) {
- int errsv = errno;
- fprintf(stderr, _("loop: can't delete device %s: %s\n"),
- device, strerror (errsv));
- return 1;
- }
- if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
- perror ("ioctl: LOOP_CLR_FD");
- return 1;
- }
- close (fd);
- if (verbose > 1)
- printf(_("del_loop(%s): success\n"), device);
- return 0;
+del_loop (const char *device) {
+ int fd;
+
+ if ((fd = open (device, O_RDONLY)) < 0) {
+ int errsv = errno;
+ fprintf(stderr, _("loop: can't delete device %s: %s\n"),
+ device, strerror (errsv));
+ return 1;
+ }
+ if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
+ perror ("ioctl: LOOP_CLR_FD");
+ return 1;
+ }
+ close (fd);
+ if (verbose > 1)
+ printf(_("del_loop(%s): success\n"), device);
+ return 0;
}
#else /* no LOOP_SET_FD defined */
static void
mutter(void) {
- fprintf(stderr,
- _("This mount was compiled without loop support. Please recompile.\n"));
+ fprintf(stderr,
+ _("This mount was compiled without loop support. "
+ "Please recompile.\n"));
}
int
set_loop (const char *device, const char *file, int offset,
const char *encryption, int *loopro) {
- mutter();
- return 1;
+ mutter();
+ return 1;
}
int
del_loop (const char *device) {
- mutter();
- return 1;
+ mutter();
+ return 1;
}
char *
find_unused_loop_device (void) {
- mutter();
- return 0;
+ mutter();
+ return 0;
}
#endif
+
+#ifdef MAIN
+
+#ifdef LOOP_SET_FD
+
+#include <getopt.h>
+#include <stdarg.h>
+
+int verbose = 0;
+static char *progname;
+
+static void
+usage(void) {
+ fprintf(stderr, _("usage:\n\
+ %s loop_device # give info\n\
+ %s -d loop_device # delete\n\
+ %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
+ progname, progname, progname);
+ exit(1);
+}
+
+char *
+xstrdup (const char *s) {
+ char *t;
+
+ if (s == NULL)
+ return NULL;
+
+ t = strdup (s);
+
+ if (t == NULL) {
+ fprintf(stderr, _("not enough memory"));
+ exit(1);
+ }
+
+ return t;
+}
+
+void
+error (const char *fmt, ...) {
+ va_list args;
+
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ fprintf (stderr, "\n");
+}
+
+int
+main(int argc, char **argv) {
+ char *offset, *encryption;
+ int delete,off,c;
+ int res = 0;
+ int ro = 0;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ delete = off = 0;
+ offset = encryption = NULL;
+ progname = argv[0];
+ while ((c = getopt(argc,argv,"de:o:v")) != EOF) {
+ switch (c) {
+ case 'd':
+ delete = 1;
+ break;
+ case 'e':
+ encryption = optarg;
+ break;
+ case 'o':
+ offset = optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+ if (argc == 1) usage();
+ if ((delete && (argc != optind+1 || encryption || offset)) ||
+ (!delete && (argc < optind+1 || argc > optind+2)))
+ usage();
+ if (argc == optind+1) {
+ if (delete)
+ res = del_loop(argv[optind]);
+ else
+ show_loop(argv[optind]);
+ } else {
+ if (offset && sscanf(offset,"%d",&off) != 1)
+ usage();
+ res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
+ }
+ return res;
+}
+
+#else /* LOOP_SET_FD not defined */
+
+int
+main(int argc, char **argv) {
+ fprintf(stderr,
+ _("No loop support was available at compile time. "
+ "Please recompile.\n"));
+ return -1;
+}
+#endif
+#endif
diff --git a/mount/losetup.c b/mount/losetup.c
deleted file mode 100644
index 9f20ee8b6..000000000
--- a/mount/losetup.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * losetup.c - setup and control loop devices
- */
-
-/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
- * - added Native Language Support
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#include "loop.h"
-#include "lomount.h"
-#include "nls.h"
-
-#ifdef LOOP_SET_FD
-
-static char *progname;
-
-struct crypt_type_struct {
- int id;
- char *name;
-} crypt_type_tbl[] = {
- { LO_CRYPT_NONE,"no" },
- { LO_CRYPT_NONE,"none" },
- { LO_CRYPT_XOR, "xor" },
- { LO_CRYPT_DES, "DES" },
- { -1, NULL }
-};
-
-
-static char *crypt_name(int id)
-{
- int i;
-
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (id == crypt_type_tbl[i].id)
- return crypt_type_tbl[i].name;
- return "undefined";
-}
-
-
-static int crypt_type(const char *name)
-{
- int i;
-
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (!strcasecmp(name, crypt_type_tbl[i].name))
- return crypt_type_tbl[i].id;
- return -1;
-}
-
-
-static void show_loop(const char *device)
-{
- struct loop_info loopinfo;
- int fd;
-
- if ((fd = open(device, O_RDWR)) < 0) {
- perror(device);
- return;
- }
- if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) < 0) {
- perror(_("Cannot get loop info"));
- close(fd);
- return;
- }
- printf(_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
- device, loopinfo.lo_device, loopinfo.lo_inode,
- loopinfo.lo_name, loopinfo.lo_offset,
- crypt_name(loopinfo.lo_encrypt_type));
- close(fd);
-}
-
-
-int set_loop(const char *device, const char *file, int offset,
- const char *encryption, int *loopro)
-{
- struct loop_info loopinfo;
- int fd, ffd, mode, i;
- char *pass;
-
- mode = *loopro ? O_RDONLY : O_RDWR;
- if ((ffd = open (file, mode)) < 0 && !*loopro
- && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) {
- perror (file);
- return 1;
- }
- if ((fd = open (device, mode)) < 0) {
- perror (device);
- return 1;
- }
- *loopro = (mode == O_RDONLY);
-
- memset(&loopinfo, 0, sizeof(loopinfo));
- strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
- loopinfo.lo_name[LO_NAME_SIZE-1] = 0;
- if (encryption && (loopinfo.lo_encrypt_type = crypt_type(encryption))
- < 0) {
- fprintf(stderr,_("Unsupported encryption type %s\n"),
- encryption);
- exit(1);
- }
- loopinfo.lo_offset = offset;
- switch (loopinfo.lo_encrypt_type) {
- case LO_CRYPT_NONE:
- loopinfo.lo_encrypt_key_size = 0;
- break;
- case LO_CRYPT_XOR:
- pass = getpass(_("Password: "));
- strncpy(loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
- loopinfo.lo_encrypt_key[LO_KEY_SIZE-1] = 0;
- loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
- break;
- case LO_CRYPT_DES:
- pass = getpass(_("Password: "));
- strncpy(loopinfo.lo_encrypt_key, pass, 8);
- loopinfo.lo_encrypt_key[8] = 0;
- loopinfo.lo_encrypt_key_size = 8;
- pass = getpass(_("Init (up to 16 hex digits): "));
- for (i = 0; i < 16 && pass[i]; i++)
- if (isxdigit(pass[i]))
- loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
- (islower(pass[i]) ? toupper(pass[i]) :
- pass[i])-'A'+10 : pass[i]-'0') << (i & 7)*4;
- else {
- fprintf(stderr,_("Non-hex digit '%c'.\n"),
- pass[i]);
- exit(1);
- }
- break;
- default:
- fprintf(stderr,
- _("Don't know how to get key for encryption system %d\n"),
- loopinfo.lo_encrypt_type);
- exit(1);
- }
- if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
- perror("ioctl: LOOP_SET_FD");
- exit(1);
- }
- if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
- (void) ioctl(fd, LOOP_CLR_FD, 0);
- perror("ioctl: LOOP_SET_STATUS");
- exit(1);
- }
- close(fd);
- close(ffd);
- return 0;
-}
-
-int del_loop(const char *device)
-{
- int fd;
-
- if ((fd = open(device, O_RDONLY)) < 0) {
- perror(device);
- exit(1);
- }
- if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
- perror("ioctl: LOOP_CLR_FD");
- exit(1);
- }
- return(0);
-}
-
-
-static int usage(void)
-{
- fprintf(stderr, _("usage:\n\
- %s loop_device # give info\n\
- %s -d loop_device # delete\n\
- %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
- progname, progname, progname);
- exit(1);
-}
-
-int main(int argc, char **argv)
-{
- char *offset,*encryption;
- int delete,off,c;
- int res = 0;
- int ro = 0;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- delete = off = 0;
- offset = encryption = NULL;
- progname = argv[0];
- while ((c = getopt(argc,argv,"de:o:")) != EOF) {
- switch (c) {
- case 'd':
- delete = 1;
- break;
- case 'e':
- encryption = optarg;
- break;
- case 'o':
- offset = optarg;
- break;
- default:
- usage();
- }
- }
- if (argc == 1) usage();
- if ((delete && (argc != optind+1 || encryption || offset)) ||
- (!delete && (argc < optind+1 || argc > optind+2)))
- usage();
- if (argc == optind+1) {
- if (delete)
- del_loop(argv[optind]);
- else
- show_loop(argv[optind]);
- } else {
- if (offset && sscanf(offset,"%d",&off) != 1)
- usage();
- res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
- }
- return res;
-}
-
-#else /* LOOP_SET_FD not defined */
-
-int main(int argc, char **argv) {
- fprintf(stderr,
- _("No loop support was available at compile time. Please recompile.\n"));
- return -1;
-}
-#endif
diff --git a/mount/mount.8 b/mount/mount.8
index 4aba358c2..7016ee535 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -40,7 +40,7 @@
.SH NAME
mount \- mount a file system
.SH SYNOPSIS
-.BI "mount [\-hV]"
+.BI "mount [\-lhV]"
.LP
.BI "mount \-a [\-fFnrsvw] [\-t " vfstype ]
.br
@@ -91,11 +91,12 @@ prints a help message;
.RE
prints a version string; and just
.RS
-.BI "mount [-t" " type" ]
+.BI "mount [-l] [-t" " type" ]
.RE
lists all mounted file systems (of type
-.IR type )
-- see below.
+.IR type ).
+The option \-l adds the (ext2) labels in this listing.
+See below.
The
.I proc
@@ -270,6 +271,14 @@ flag to determine what the
command is trying to do. It can also be used to add entries for devices
that were mounted earlier with the -n option.
.TP
+.B \-l
+Add the ext2 labels in the mount output. Mount must have permission to
+read the disk device (e.g. be suid root) for this to work.
+One can set such a label
+using the
+.BR e2label (8)
+utility.
+.TP
.B \-n
Mount without writing in
.IR /etc/mtab .
@@ -624,12 +633,15 @@ to the options given in
Set checking level. When at least one of these options is set (and
.B check=normal
is set by default) the inodes and blocks bitmaps are checked upon mount
-(which can take half a minute or so on a big disk).
+(which can take half a minute or so on a big disk, and is rather useless).
With strict checking, block deallocation checks that the block to free
is in the data zone.
.TP
.BR check=none " / " nocheck
-No checking is done.
+No checking is done. This is fast. Recent kernels do not have a
+check option anymore - checking with
+.BR e2fsck (8)
+is more meaningful.
.TP
.B debug
Print debugging info upon each (re)mount.
@@ -985,7 +997,10 @@ Especially useful options include
.TP
.B rsize=8192,wsize=8192
This will make your nfs connection much faster than with the default
-buffer size of 1024.
+buffer size of 1024. (NFSv2 does not work with larger values of
+.B rsize
+and
+.BR wsize .)
.TP
.B hard
The program accessing a file on a NFS mounted file system will hang
@@ -1251,6 +1266,7 @@ temporary file
.BR umount (8),
.BR swapon (8),
.BR nfs (5),
+.BR e2label (8),
.BR mountd (8),
.BR nfsd (8),
.BR mke2fs (8),
diff --git a/mount/mount.c b/mount/mount.c
index 6c1f40a29..b8ee2ebec 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -34,6 +34,8 @@
* - fixed use of nouser option
* 1999-09-09 Michael K. Johnson <johnsonm@redhat.com>
* - added `owner' mount option
+ * 2000-05-11 Mark A. Peloquin <peloquin@us.ibm.com>
+ * - check_special_mountprog now returns correct status
*/
#include <unistd.h>
@@ -68,13 +70,13 @@
#endif
/* True for fake mount (-f). */
-int fake = 0;
+static int fake = 0;
/* Don't write a entry in /etc/mtab (-n). */
-int nomtab = 0;
+static int nomtab = 0;
/* True for explicit readonly (-r). */
-int readonly = 0;
+static int readonly = 0;
/* Nonzero for chatty (-v). */
int verbose = 0;
@@ -83,20 +85,22 @@ int verbose = 0;
int sloppy = 0;
/* True for explicit read/write (-w). */
-int readwrite = 0;
+static int readwrite = 0;
/* True for all mount (-a). */
int all = 0;
/* True for fork() during all mount (-F). */
-int optfork = 0;
+static int optfork = 0;
+
+/* Add volumelabel in a listing of mounted devices (-l). */
+static int list_with_volumelabel = 0;
/* True if ruid != euid. */
-int suid = 0;
+static int suid = 0;
/* Map from -o and fstab option strings to the flag argument to mount(2). */
-struct opt_map
-{
+struct opt_map {
const char *opt; /* option name */
int skip; /* skip in mtab option string */
int inv; /* true if flag value should be inverted */
@@ -124,7 +128,7 @@ struct opt_map
/* Options that we make owner-mounted devices have by default */
#define MS_OWNERSECURE (MS_NOSUID|MS_NODEV)
-const struct opt_map opt_map[] = {
+static const struct opt_map opt_map[] = {
{ "defaults", 0, 0, 0 }, /* default options */
{ "ro", 1, 0, MS_RDONLY }, /* read-only */
{ "rw", 1, 1, MS_RDONLY }, /* read-write */
@@ -170,9 +174,10 @@ const struct opt_map opt_map[] = {
{ NULL, 0, 0, 0 }
};
-static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption;
+static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
+ *opt_speed;
-struct string_opt_map {
+static struct string_opt_map {
char *tag;
int skip;
char **valptr;
@@ -181,6 +186,7 @@ struct string_opt_map {
{ "vfs=", 1, &opt_vfstype },
{ "offset=", 0, &opt_offset },
{ "encryption=", 0, &opt_encryption },
+ { "speed=", 0, &opt_speed },
{ NULL, 0, NULL }
};
@@ -219,13 +225,18 @@ print_one (const struct mntentchn *mc) {
printf (" type %s", mc->mnt_type);
if (mc->mnt_opts != NULL)
printf (" (%s)", mc->mnt_opts);
+ if (list_with_volumelabel) {
+ const char *label;
+ label = get_volume_label_by_spec(mc->mnt_fsname);
+ if (label)
+ printf (" [%s]", label);
+ }
printf ("\n");
}
/* Report on everything in mtab (of the specified types if any). */
static int
-print_all (string_list types)
-{
+print_all (string_list types) {
struct mntentchn *mc;
for (mc = mtab_head()->nxt; mc; mc = mc->nxt) {
@@ -239,8 +250,7 @@ print_all (string_list types)
/* Look for OPT in opt_map table and return mask value. If OPT isn't found,
tack it onto extra_opts (which is non-NULL). */
static inline void
-parse_opt (const char *opt, int *mask, char *extra_opts)
-{
+parse_opt (const char *opt, int *mask, char *extra_opts) {
const struct opt_map *om;
for (om = opt_map; om->opt != NULL; om++)
@@ -270,8 +280,7 @@ parse_opt (const char *opt, int *mask, char *extra_opts)
/* Take -o options list and compute 4th and 5th args to mount(2). flags
gets the standard options and extra_opts anything we don't recognize. */
static void
-parse_opts (char *opts, int *flags, char **extra_opts)
-{
+parse_opts (char *opts, int *flags, char **extra_opts) {
char *opt;
*flags = 0;
@@ -387,9 +396,13 @@ create_mtab (void) {
/* count successful mount system calls */
static int mountcount = 0;
-/* returns 0: OK, -1: error */
+/*
+ * do_mount_syscall()
+ * Mount a single file system. Keep track of successes.
+ * returns: 0: OK, -1: error in errno
+ */
static int
-mount5 (struct mountargs *args) {
+do_mount_syscall (struct mountargs *args) {
int ret = mount (args->spec, args->node, args->type,
MS_MGC_VAL | (args->flags), args->data);
if (ret == 0)
@@ -397,11 +410,15 @@ mount5 (struct mountargs *args) {
return ret;
}
-/* Mount a single file system.
- Return status: 0: OK, -1: error in errno, 1: other error
- don't exit on non-fatal errors. */
+/*
+ * guess_fstype_and_mount()
+ * Mount a single file system. Guess the type when unknown.
+ * returns: 0: OK, -1: error in errno, 1: other error
+ * don't exit on non-fatal errors.
+ */
static int
-try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
+guess_fstype_and_mount (char *spec, char *node, char **type,
+ int flags, char *mount_opts) {
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
if (*type && strcasecmp (*type, "auto") == 0)
@@ -418,55 +435,30 @@ try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
if (*type || (flags & MS_REMOUNT)) {
args.type = *type;
- return mount5 (&args);
+ return do_mount_syscall (&args);
}
- return procfsloop(mount5, &args, type);
+ return procfsloop(do_mount_syscall, &args, type);
}
/*
- * try_mount_one()
- * Try to mount one file system. When "bg" is 1, this is a retry
- * in the background. One additional exit code EX_BG is used here.
- * It is used to instruct the caller to retry the mount in the
- * background.
+ * suid_check()
+ * Die if the user is not allowed to do this.
*/
-static int
-try_mount_one (const char *spec0, const char *node0, char *type0,
- const char *opts0, int freq, int pass, int bg, int ro) {
- struct mntentchn mcn;
- struct mntent mnt;
- int mnt5_res = 0; /* only for gcc */
- int mnt_err;
- int flags;
- char *extra_opts; /* written in mtab */
- char *mount_opts; /* actually used on system call */
- int loop, looptype, offset;
- const char *opts;
- char *spec, *node, *type, *loopdev, *loopfile;
- char *user = 0;
- struct stat statbuf;
-
- spec = xstrdup(spec0);
- node = xstrdup(node0);
- type = xstrdup(type0);
- opts = xstrdup(opts0);
-
- parse_opts (xstrdup (opts), &flags, &extra_opts);
-
- /* root may allow certain types of mounts by ordinary users */
+static void
+suid_check(char *spec, char *node, int *flags, char **user) {
if (suid) {
/* RedHat patch: allow owners to mount when fstab contains
the owner option. Note that this should never be used
in a high security environment, but may be useful to give
people at the console the possibility of mounting a floppy. */
- if (flags & MS_OWNER) {
- if (!strncmp(spec0, "/dev/", 5)) {
+ if (*flags & MS_OWNER) {
+ if (!strncmp(spec, "/dev/", 5)) {
struct stat sb;
- if (!stat(spec0, &sb)) {
+ if (!stat(spec, &sb)) {
if (getuid() == sb.st_uid)
- flags |= MS_USER;
+ *flags |= MS_USER;
}
}
}
@@ -476,24 +468,24 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
This is even less secure. Let me skip it for the time being;
there should be an explicit fstab line allowing such things. */
- if (!(flags & (MS_USER | MS_USERS))) {
+ if (!(*flags & (MS_USER | MS_USERS))) {
if (already (spec, node))
die (EX_USAGE, _("mount failed"));
else
die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
}
- if (flags & MS_USER)
- user = getusername();
+ if (*flags & MS_USER)
+ *user = getusername();
}
- if (flags & MS_OWNER)
- flags &= ~MS_OWNER;
-
- /* quietly succeed for fstab entries that don't get mounted automatically */
- if (all && (flags & MS_NOAUTO))
- return 0;
+ if (*flags & MS_OWNER)
+ *flags &= ~MS_OWNER;
+}
- mount_opts = extra_opts;
+static int
+loop_check(char **spec, char **type, int *flags,
+ int *loop, char **loopdev, char **loopfile) {
+ int looptype, offset;
/*
* In the case of a loop mount, either type is of the form lo@/dev/loop5
@@ -503,84 +495,142 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
* immediately: maybe later other types of mountable objects will occur.
*/
- loopdev = opt_loopdev;
+ *loopdev = opt_loopdev;
- looptype = (type && strncmp("lo@", type, 3) == 0);
+ looptype = (*type && strncmp("lo@", *type, 3) == 0);
if (looptype) {
- if (loopdev)
+ if (*loopdev)
error(_("mount: loop device specified twice"));
- loopdev = type+3;
- type = opt_vfstype;
- }
- else if (opt_vfstype) {
- if (type)
+ *loopdev = *type + 3;
+ *type = opt_vfstype;
+ } else if (opt_vfstype) {
+ if (*type)
error(_("mount: type specified twice"));
else
- type = opt_vfstype;
+ *type = opt_vfstype;
}
- loop = ((flags & MS_LOOP) || loopdev || opt_offset || opt_encryption);
- loopfile = spec;
+ *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption);
+ *loopfile = *spec;
- if (loop) {
- flags |= MS_LOOP;
+ if (*loop) {
+ *flags |= MS_LOOP;
if (fake) {
if (verbose)
printf(_("mount: skipping the setup of a loop device\n"));
} else {
- int loopro = (flags & MS_RDONLY);
+ int loopro = (*flags & MS_RDONLY);
- if (!loopdev || !*loopdev)
- loopdev = find_unused_loop_device();
- if (!loopdev)
+ if (!*loopdev || !**loopdev)
+ *loopdev = find_unused_loop_device();
+ if (!*loopdev)
return EX_SYSERR; /* no more loop devices */
if (verbose)
- printf(_("mount: going to use the loop device %s\n"), loopdev);
+ printf(_("mount: going to use the loop device %s\n"), *loopdev);
offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
- if (set_loop (loopdev, loopfile, offset, opt_encryption, &loopro)) {
+ if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
if (verbose)
printf(_("mount: failed setting up loop device\n"));
return EX_FAIL;
}
if (verbose > 1)
printf(_("mount: setup loop device successfully\n"));
- spec = loopdev;
+ *spec = *loopdev;
if (loopro)
- flags |= MS_RDONLY;
+ *flags |= MS_RDONLY;
}
}
- if (!fake && type && streq (type, "nfs")) {
-#ifdef HAVE_NFS
- mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts, bg);
- if (mnt_err)
- return mnt_err;
-#else
- die (EX_SOFTWARE, _("mount: this version was compiled "
- "without support for the type `nfs'"));
-#endif
- }
+ return 0;
+}
- /*
- * Call mount.TYPE for types that require a separate
- * mount program. For the moment these types are ncp and smb.
- */
- if (type)
+static void
+update_mtab_entry(char *spec, char *node, char *type, char *opts,
+ int flags, int freq, int pass) {
+ struct mntentchn mcn;
+ struct mntent mnt;
+
+ mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (spec);
+ mcn.mnt_dir = mnt.mnt_dir = canonicalize (node);
+ mcn.mnt_type = mnt.mnt_type = type;
+ mcn.mnt_opts = mnt.mnt_opts = opts;
+ mcn.nxt = 0;
+ mnt.mnt_freq = freq;
+ mnt.mnt_passno = pass;
+
+ /* We get chatty now rather than after the update to mtab since the
+ mount succeeded, even if the write to /etc/mtab should fail. */
+ if (verbose)
+ print_one (&mcn);
+
+ if (!nomtab && mtab_is_writable()) {
+ if (flags & MS_REMOUNT)
+ update_mtab (mnt.mnt_dir, &mnt);
+ else {
+ mntFILE *mfp;
+
+ lock_mtab();
+ mfp = my_setmntent(MOUNTED, "a+");
+ if (mfp == NULL || mfp->mntent_fp == NULL) {
+ int errsv = errno;
+ error(_("mount: can't open %s: %s"), MOUNTED,
+ strerror (errsv));
+ } else {
+ if ((my_addmntent (mfp, &mnt)) == 1) {
+ int errsv = errno;
+ error(_("mount: error writing %s: %s"), MOUNTED,
+ strerror (errsv));
+ }
+ my_endmntent(mfp);
+ }
+ unlock_mtab();
+ }
+ }
+}
+
+static void
+cdrom_setspeed(char *spec) {
+#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
+ if (opt_speed) {
+ int cdrom;
+ int speed = atoi(opt_speed);
+
+ if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
+ die(EX_FAIL, _("mount: cannot not open %s for setting speed"),
+ spec);
+ if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
+ die(EX_FAIL, _("mount: cannot set speed: %s"),
+ strerror(errno));
+ close(cdrom);
+ }
+}
+
+/*
+ * check_special_mountprog()
+ * If there is a special mount program for this type, exec it.
+ * returns: 0: no exec was done, 1: exec was done, status has result
+ */
+static int
+check_special_mountprog(char *spec, char *node, char *type, int flags,
+ char *extra_opts, int *status) {
+ char mountprog[120];
+ struct stat statbuf;
+ int res;
+
+ if (type &&
#ifndef ALWAYS_STAT
- if (streq (type, "smb") || streq (type, "ncp")
+ (streq (type, "smb") || streq (type, "ncp")
/* these are incorrect but perhaps used by smbmount or so */
|| streq (type, "smbfs") || streq (type, "ncpfs")
)
#else
- if (strlen (type) < 100)
+ (strlen (type) < 100)
#endif
- {
- char mountprog[120];
-
+ ) {
sprintf(mountprog, "/sbin/mount.%s", type);
if (stat(mountprog, &statbuf) == 0) {
- int res;
- if ((res = fork()) == 0) {
+ res = fork();
+ if (res == 0) {
char *oo, *mountargs[10];
int i = 0;
@@ -602,63 +652,103 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
execv(mountprog, mountargs);
exit(1); /* exec failed */
} else if (res != -1) {
- int status;
- wait(&status);
- return status;
+ int st;
+ wait(&st);
+ *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR);
+ return 1;
} else {
int errsv = errno;
error(_("mount: cannot fork: %s"), strerror(errsv));
}
}
}
+ return 0;
+}
+
+/*
+ * try_mount_one()
+ * Try to mount one file system. When "bg" is 1, this is a retry
+ * in the background. One additional exit code EX_BG is used here.
+ * It is used to instruct the caller to retry the mount in the
+ * background.
+ * returns: 0: OK, EX_SYSERR, EX_FAIL, return code from nfsmount,
+ * return status from wait
+ */
+static int
+try_mount_one (const char *spec0, const char *node0, char *type0,
+ const char *opts0, int freq, int pass, int bg, int ro) {
+ int res, status;
+ int mnt5_res = 0; /* only for gcc */
+ int mnt_err;
+ int flags;
+ char *extra_opts; /* written in mtab */
+ char *mount_opts; /* actually used on system call */
+ const char *opts;
+ char *spec, *node, *type;
+ char *user = 0;
+ int loop = 0;
+ char *loopdev = 0, *loopfile = 0;
+ struct stat statbuf;
+
+ spec = xstrdup(spec0);
+ node = xstrdup(node0);
+ type = xstrdup(type0);
+ opts = xstrdup(opts0);
+
+ parse_opts (xstrdup (opts), &flags, &extra_opts);
+
+ suid_check (spec, node, &flags, &user);
+
+ /* quietly succeed for fstab entries that don't get mounted automatically */
+ if (all && (flags & MS_NOAUTO))
+ return 0;
+
+ mount_opts = extra_opts;
+
+ if (opt_speed)
+ cdrom_setspeed(spec);
+
+ res = loop_check (&spec, &type, &flags, &loop, &loopdev, &loopfile);
+ if (res)
+ return res;
+
+ /*
+ * Call mount.TYPE for types that require a separate mount program.
+ * For the moment these types are ncp and smb.
+ */
+ if (check_special_mountprog (spec, node, type, flags, extra_opts, &status))
+ return status;
+
+ if (!fake && type && streq (type, "nfs")) {
+#ifdef HAVE_NFS
+retry_nfs:
+ mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts, bg);
+ if (mnt_err)
+ return mnt_err;
+#else
+ die (EX_SOFTWARE, _("mount: this version was compiled "
+ "without support for the type `nfs'"));
+#endif
+ }
block_signals (SIG_BLOCK);
if (!fake)
- mnt5_res = try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts);
+ mnt5_res = guess_fstype_and_mount (spec, node, &type, flags & ~MS_NOSYS,
+ mount_opts);
if (fake || mnt5_res == 0) {
- /* Mount succeeded, report this (if verbose) and write mtab entry. */
+ /* Mount succeeded, report this (if verbose) and write mtab entry. */
if (loop)
opt_loopdev = loopdev;
- mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (loop ? loopfile : spec);
- mcn.mnt_dir = mnt.mnt_dir = canonicalize (node);
- mcn.mnt_type = mnt.mnt_type = type ? type : "unknown";
- mcn.mnt_opts = mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB,
- extra_opts, user);
- mcn.nxt = 0;
- mnt.mnt_freq = freq;
- mnt.mnt_passno = pass;
-
- /* We get chatty now rather than after the update to mtab since the
- mount succeeded, even if the write to /etc/mtab should fail. */
- if (verbose)
- print_one (&mcn);
-
- if (!nomtab && mtab_is_writable()) {
- if (flags & MS_REMOUNT)
- update_mtab (mnt.mnt_dir, &mnt);
- else {
- mntFILE *mfp;
-
- lock_mtab();
- mfp = my_setmntent(MOUNTED, "a+");
- if (mfp == NULL || mfp->mntent_fp == NULL) {
- int errsv = errno;
- error(_("mount: can't open %s: %s"), MOUNTED,
- strerror (errsv));
- } else {
- if ((my_addmntent (mfp, &mnt)) == 1) {
- int errsv = errno;
- error(_("mount: error writing %s: %s"), MOUNTED,
- strerror (errsv));
- }
- my_endmntent(mfp);
- }
- unlock_mtab();
- }
- }
+ update_mtab_entry(loop ? loopfile : spec,
+ node,
+ type ? type : "unknown",
+ fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user),
+ flags,
+ freq,
+ pass);
block_signals (SIG_UNBLOCK);
return 0;
@@ -671,6 +761,18 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
block_signals (SIG_UNBLOCK);
+#ifdef HAVE_NFS
+ if (mnt_err && type && streq (type, "nfs")) {
+ extern int nfs_mount_version;
+ if (nfs_mount_version == 4) {
+ if (verbose)
+ printf(_("mount: failed with nfs mount version 4, trying 3..\n"));
+ nfs_mount_version = 3;
+ goto retry_nfs;
+ }
+ }
+#endif
+
/* Mount failed, complain, but don't die. */
if (type == 0) {
@@ -799,10 +901,15 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
error (_("mount: %s is not a valid block device"), spec); break;
case EACCES: /* pre-linux 1.1.38, 1.1.41 and later */
case EROFS: /* linux 1.1.38 and later */
+ { char *bd = (loop ? "" : _("block device "));
if (ro) {
- error (_("mount: block device %s is not permitted on its filesystem"),
- spec);
+ error (_("mount: %s%s is not permitted on its filesystem"),
+ bd, spec);
break;
+ } else if (readwrite) {
+ error (_("mount: %s%s is write-protected but explicit `-w' flag given"),
+ bd, spec);
+ break;
} else {
if (loop) {
opts = opts0;
@@ -817,10 +924,11 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
if (type && !strcmp(type, "guess"))
type = 0;
error (_("mount: %s%s is write-protected, mounting read-only"),
- loop ? "" : _("block device "), spec0);
+ bd, spec0);
return try_mount_one (spec0, node0, type, opts, freq, pass, bg, 1);
}
break;
+ }
default:
error ("mount: %s", strerror (mnt_err)); break;
}
@@ -950,6 +1058,15 @@ mount_one (const char *spec, const char *node, char *type, const char *opts,
static int
mounted (char *spec, char *node) {
struct mntentchn *mc;
+ char *nspec = NULL;
+
+ if (!strncmp(spec, "UUID=", 5))
+ nspec = get_spec_by_uuid(spec+5);
+ else if (!strncmp(spec, "LABEL=", 6))
+ nspec = get_spec_by_volume_label(spec+6);
+
+ if (nspec)
+ spec = nspec;
spec = canonicalize (spec);
node = canonicalize (node);
@@ -1102,7 +1219,7 @@ static struct option longopts[] =
static void
usage (FILE *fp, int n)
{
- fprintf (fp, _("Usage: mount [-hV]\n"
+ fprintf (fp, _("Usage: mount [-lhV]\n"
" mount -a [-nfFrsvw] [-t vfstypes]\n"
" mount [-nfrsvw] [-o options] special | node\n"
" mount [-nfrsvw] [-t vfstype] [-o options] special node\n"
@@ -1136,7 +1253,7 @@ main (int argc, char *argv[]) {
initproctitle(argc, argv);
#endif
- while ((c = getopt_long (argc, argv, "afFhL:no:rsU:vVwt:", longopts, NULL))
+ while ((c = getopt_long (argc, argv, "afFhlL:no:rsU:vVwt:", longopts, NULL))
!= EOF)
switch (c) {
case 'a': /* mount everything in fstab */
@@ -1151,6 +1268,9 @@ main (int argc, char *argv[]) {
case 'h': /* help */
usage (stdout, 0);
break;
+ case 'l':
+ list_with_volumelabel = 1;
+ break;
case 'L':
volumelabel = optarg;
break;
diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c
index be37496f8..1567bfb18 100644
--- a/mount/mount_by_label.c
+++ b/mount/mount_by_label.c
@@ -1,5 +1,12 @@
-/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+/*
+ * mount_by_label.c - aeb
+ *
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
* - added Native Language Support
+ * 2000-01-20 James Antill <james@and.org>
+ * - Added error message if /proc/partitions cannot be opened
+ * 2000-05-09 Erik Troan <ewt@redhat.com>
+ * - Added cache for UUID and disk labels
*/
#include <stdio.h>
@@ -15,98 +22,143 @@
#define PROC_PARTITIONS "/proc/partitions"
#define DEVLABELDIR "/dev"
-static FILE *procpt;
-
-static void
-procptclose(void) {
- if (procpt)
- fclose (procpt);
- procpt = 0;
-}
-
-static int
-procptopen(void) {
- return ((procpt = fopen(PROC_PARTITIONS, "r")) != NULL);
-}
-
-static char *
-procptnext(void) {
- char line[100];
- char *s;
- int ma, mi, sz;
- static char ptname[100];
-
- while (fgets(line, sizeof(line), procpt)) {
- if (sscanf (line, " %d %d %d %[^\n]\n", &ma, &mi, &sz, ptname) != 4)
- continue;
-
- /* skip extended partitions (heuristic: size 1) */
- if (sz == 1)
- continue;
-
- /* skip entire disk (minor 0, 64, ... on ide; 0, 16, ... on sd) */
- /* heuristic: partition name ends in a digit */
- for(s = ptname; *s; s++);
- if (isdigit(s[-1]))
- return ptname;
- }
- return 0;
-}
-
-#define UUID 1
-#define VOL 2
+static struct uuidCache_s {
+ struct uuidCache_s *next;
+ char uuid[16];
+ char *label;
+ char *device;
+} *uuidCache = NULL;
/* for now, only ext2 is supported */
static int
-has_right_label(const char *device, int n, const char *label) {
+get_label_uuid(const char *device, char **label, char *uuid) {
/* start with a test for ext2, taken from mount_guess_fstype */
/* should merge these later */
int fd;
- char *s;
struct ext2_super_block e2sb;
fd = open(device, O_RDONLY);
if (fd < 0)
- return 0;
+ return 1;
if (lseek(fd, 1024, SEEK_SET) != 1024
|| read(fd, (char *) &e2sb, sizeof(e2sb)) != sizeof(e2sb)
|| (ext2magic(e2sb) != EXT2_SUPER_MAGIC)) {
close(fd);
- return 0;
+ return 1;
}
close(fd);
/* superblock is ext2 - now what is its label? */
- s = ((n == UUID) ? e2sb.s_uuid : e2sb.s_volume_name);
- return (strncmp(s, label, 16) == 0);
+ memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
+ *label = strdup(e2sb.s_volume_name);
+
+ return 0;
}
-static char *
-get_spec_by_x(int n, const char *t) {
- char *pt;
+static void
+uuidcache_addentry(char *device, char *label, char *uuid) {
+ struct uuidCache_s *last;
+
+ if (!uuidCache) {
+ last = uuidCache = malloc(sizeof(*uuidCache));
+ } else {
+ for (last = uuidCache; last->next; last = last->next) ;
+ last->next = malloc(sizeof(*uuidCache));
+ last = last->next;
+ }
+ last->next = NULL;
+ last->device = device;
+ last->label = label;
+ memcpy(last->uuid, uuid, sizeof(last->uuid));
+}
+
+static void
+uuidcache_init(void) {
+ char line[100];
+ char *s;
+ int ma, mi, sz;
+ static char ptname[100];
+ FILE *procpt;
+ char uuid[16], *label;
char device[110];
+ int firstPass;
+ int handleOnFirst;
+
+ if (uuidCache)
+ return;
+
+ procpt = fopen(PROC_PARTITIONS, "r");
+ if (!procpt)
+ return;
+
+ for (firstPass = 1; firstPass >= 0; firstPass--) {
+ fseek(procpt, 0, SEEK_SET);
+
+ while (fgets(line, sizeof(line), procpt)) {
+ if (sscanf (line, " %d %d %d %[^\n ]",
+ &ma, &mi, &sz, ptname) != 4)
+ continue;
+
+ /* skip extended partitions (heuristic: size 1) */
+ if (sz == 1)
+ continue;
+
+ /* look only at md devices on first pass */
+ handleOnFirst = !strncmp(ptname, "md", 2);
+ if (firstPass != handleOnFirst)
+ continue;
+
+ /* skip entire disk (minor 0, 64, ... on ide;
+ 0, 16, ... on sd) */
+ /* heuristic: partition name ends in a digit */
+
+ for(s = ptname; *s; s++);
+ if (isdigit(s[-1])) {
+ /*
+ * Note: this is a heuristic only - there is no reason
+ * why these devices should live in /dev.
+ * Perhaps this directory should be specifiable by option.
+ * One might for example have /devlabel with links to /dev
+ * for the devices that may be accessed in this way.
+ * (This is useful, if the cdrom on /dev/hdc must not
+ * be accessed.)
+ */
+ sprintf(device, "%s/%s", DEVLABELDIR, ptname);
+ if (!get_label_uuid(device, &label, uuid))
+ uuidcache_addentry(strdup(device), label, uuid);
+ }
+ }
+ }
+
+ fclose(procpt);
+}
- if(!procptopen())
- return NULL;
- while((pt = procptnext()) != NULL) {
- /* Note: this is a heuristic only - there is no reason
- why these devices should live in /dev.
- Perhaps this directory should be specifiable by option.
- One might for example have /devlabel with links to /dev
- for the devices that may be accessed in this way.
- (This is useful, if the cdrom on /dev/hdc must not
- be accessed.)
- */
- sprintf(device, "%s/%s", DEVLABELDIR, pt);
- if (has_right_label(device, n, t)) {
- procptclose();
- return xstrdup(device);
+#define UUID 1
+#define VOL 2
+
+static char *
+get_spec_by_x(int n, const char *t) {
+ struct uuidCache_s *uc;
+
+ uuidcache_init();
+ uc = uuidCache;
+
+ while(uc) {
+ switch (n) {
+ case UUID:
+ if (!memcmp(t, uc->uuid, sizeof(uc->uuid)))
+ return xstrdup(uc->device);
+ break;
+ case VOL:
+ if (!strcmp(t, uc->label))
+ return xstrdup(uc->device);
+ break;
}
+ uc = uc->next;
}
- procptclose();
return NULL;
}
@@ -147,3 +199,17 @@ get_spec_by_volume_label(const char *s) {
return get_spec_by_x(VOL, s);
}
+const char *
+get_volume_label_by_spec(const char *spec) {
+ struct uuidCache_s *uc;
+
+ uuidcache_init();
+ uc = uuidCache;
+
+ while(uc) {
+ if (!strcmp(spec, uc->device))
+ return uc->label;
+ uc = uc->next;
+ }
+ return NULL;
+}
diff --git a/mount/mount_by_label.h b/mount/mount_by_label.h
index 21c2d844b..64bbbfa7d 100644
--- a/mount/mount_by_label.h
+++ b/mount/mount_by_label.h
@@ -1,2 +1,3 @@
char *get_spec_by_uuid(const char *uuid);
char *get_spec_by_volume_label(const char *volumelabel);
+const char *get_volume_label_by_spec(const char *spec);
diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c
index 9e3a54a48..ec39c531a 100644
--- a/mount/mount_guess_fstype.c
+++ b/mount/mount_guess_fstype.c
@@ -72,13 +72,14 @@ swapped(unsigned short a) {
Added a very weak heuristic for vfat - aeb
Added qnx4 - aeb
Added swap - aeb
+ Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>
Currently supports: minix, ext, ext2, xiafs, iso9660, romfs,
- ufs, ntfs, vfat, qnx4, bfs
+ ufs, ntfs, vfat, qnx4, bfs, xfs
*/
static char
*magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660", "romfs",
- "ufs", "ntfs", "qnx4", "bfs", "udf",
+ "ufs", "ntfs", "qnx4", "bfs", "udf", "xfs",
"swap" /* last - just to warn the user */
};
@@ -130,6 +131,7 @@ fstype(const char *device) {
union {
struct xiafs_super_block xiasb;
char romfs_magic[8];
+ char xfs_magic[4];
char qnx4fs_magic[10]; /* ignore first 4 bytes */
long bfs_magic;
struct ntfs_super_block ntfssb;
@@ -177,6 +179,9 @@ fstype(const char *device) {
type = "xiafs";
else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))
type = "romfs";
+ else if(!strncmp(xsb.xfs_magic, "XFSB", 4) ||
+ !strncmp(xsb.xfs_magic, "BSFX", 4))
+ type = "xfs";
else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
type = "qnx4fs";
else if(xsb.bfs_magic == 0x1badface)
@@ -187,7 +192,8 @@ fstype(const char *device) {
else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||
!strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||
!strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||
- !strncmp(xsb.fatsb.s_os, "mkdosfs", 7))
+ !strncmp(xsb.fatsb.s_os, "mkdosfs", 7) ||
+ !strncmp(xsb.fatsb.s_os, "kmkdosfs", 8))
&& (!strncmp(xsb.fatsb.s_fs, "FAT12 ", 8) ||
!strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) ||
!strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8)))
diff --git a/mount/nfs_mount4.h b/mount/nfs_mount4.h
new file mode 100644
index 000000000..0e3b052bd
--- /dev/null
+++ b/mount/nfs_mount4.h
@@ -0,0 +1,53 @@
+/*
+ * We want to be able to compile mount on old kernels in such a way
+ * that the binary will work well on more recent kernels.
+ * Thus, if necessary we teach nfsmount.c the structure of new fields
+ * that will come later.
+ *
+ * Moreover, the new kernel includes conflict with glibc includes
+ * so it is easiest to ignore the kernel altogether (at compile time).
+ */
+
+#define NFS_MOUNT_VERSION 4
+
+struct nfs2_fh {
+ char data[32];
+};
+struct nfs3_fh {
+ unsigned short size;
+ unsigned char data[64];
+};
+
+struct nfs_mount_data {
+ int version; /* 1 */
+ int fd; /* 1 */
+ struct nfs2_fh old_root; /* 1 */
+ int flags; /* 1 */
+ int rsize; /* 1 */
+ int wsize; /* 1 */
+ int timeo; /* 1 */
+ int retrans; /* 1 */
+ int acregmin; /* 1 */
+ int acregmax; /* 1 */
+ int acdirmin; /* 1 */
+ int acdirmax; /* 1 */
+ struct sockaddr_in addr; /* 1 */
+ char hostname[256]; /* 1 */
+ int namlen; /* 2 */
+ unsigned int bsize; /* 3 */
+ struct nfs3_fh root; /* 4 */
+};
+
+/* bits in the flags field */
+
+#define NFS_MOUNT_SOFT 0x0001 /* 1 */
+#define NFS_MOUNT_INTR 0x0002 /* 1 */
+#define NFS_MOUNT_SECURE 0x0004 /* 1 */
+#define NFS_MOUNT_POSIX 0x0008 /* 1 */
+#define NFS_MOUNT_NOCTO 0x0010 /* 1 */
+#define NFS_MOUNT_NOAC 0x0020 /* 1 */
+#define NFS_MOUNT_TCP 0x0040 /* 2 */
+#define NFS_MOUNT_VER3 0x0080 /* 3 */
+#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
+#define NFS_MOUNT_NONLM 0x0200 /* 3 */
+
diff --git a/mount/nfs_mount3.h b/mount/nfs_mount4.h.sv
index e5c2b2fe4..f3111d784 100644
--- a/mount/nfs_mount3.h
+++ b/mount/nfs_mount4.h.sv
@@ -6,7 +6,7 @@
*/
#include "nfs_mountversion.h"
-#if KERNEL_NFS_MOUNT_VERSION >= 3
+#if KERNEL_NFS_MOUNT_VERSION >= 4
/*
* The kernel includes are at least as good as this file.
@@ -14,18 +14,31 @@
*/
#include <linux/nfs_mount.h>
-#else /* KERNEL_NFS_MOUNT_VERSION < 3 */
+#define NFS_FHSIZE 32
+#define NFS_PORT 2049
+#define NFS_VERSION 2
+
+
+#else /* KERNEL_NFS_MOUNT_VERSION < 4 */
/*
* We know more than the kernel. Override the kernel defines.
* Check at runtime whether the running kernel can handle the new stuff.
*/
-#define NFS_MOUNT_VERSION 3
+#define NFS_MOUNT_VERSION 4
+
+struct nfs2_fh {
+ char data[32];
+};
+struct nfs3_fh {
+ unsigned short size;
+ unsigned char data[64];
+};
struct nfs_mount_data {
int version; /* 1 */
int fd; /* 1 */
- struct nfs_fh root; /* 1 */
+ struct nfs2_fh old_root; /* 1 */
int flags; /* 1 */
int rsize; /* 1 */
int wsize; /* 1 */
@@ -39,6 +52,7 @@ struct nfs_mount_data {
char hostname[256]; /* 1 */
int namlen; /* 2 */
unsigned int bsize; /* 3 */
+ struct nfs3_fh root; /* 4 */
};
/* bits in the flags field */
diff --git a/mount/nfsmount.c b/mount/nfsmount.c
index 9500ec292..bf4be6369 100644
--- a/mount/nfsmount.c
+++ b/mount/nfsmount.c
@@ -24,6 +24,8 @@
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
* - added Native Language Support
*
+ * Modified by Olaf Kirch and Trond Myklebust for new NFS code,
+ * plus NFSv3 stuff.
*/
/*
@@ -50,7 +52,8 @@
#include <linux/nfs.h>
#include "mount_constants.h"
-#include "nfs_mount3.h"
+#include "nfs_mount4.h"
+
#include "nls.h"
#include "../defines.h" /* for HAVE_inet_aton */
@@ -59,6 +62,8 @@ 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)
+
static int
linux_version_code(void) {
struct utsname my_utsname;
@@ -74,9 +79,9 @@ linux_version_code(void) {
}
/*
- * nfs_mount_version according to the kernel sources seen at compile time.
+ * nfs_mount_version according to the sources seen at compile time.
*/
-static int nfs_mount_version = KERNEL_NFS_MOUNT_VERSION;
+int nfs_mount_version = NFS_MOUNT_VERSION;
/*
* Unfortunately, the kernel prints annoying console messages
@@ -91,18 +96,73 @@ static int nfs_mount_version = KERNEL_NFS_MOUNT_VERSION;
*/
static void
find_kernel_nfs_mount_version(void) {
- int kernel_version = linux_version_code();
+ static int kernel_version = 0;
+
+ if (kernel_version)
+ return;
+
+ kernel_version = linux_version_code();
if (kernel_version) {
if (kernel_version < MAKE_VERSION(2,1,32))
nfs_mount_version = 1;
- else
+ else if (kernel_version < MAKE_VERSION(2,3,99))
nfs_mount_version = 3;
+ else
+ nfs_mount_version = 4; /* since 2.3.99pre4 */
}
if (nfs_mount_version > NFS_MOUNT_VERSION)
nfs_mount_version = NFS_MOUNT_VERSION;
}
+static struct pmap *
+get_mountport(struct sockaddr_in *server_addr,
+ long unsigned prog,
+ long unsigned version,
+ long unsigned proto,
+ long unsigned port)
+{
+struct pmaplist *pmap;
+static struct pmap p = {0, 0, 0, 0};
+
+server_addr->sin_port = PMAPPORT;
+pmap = pmap_getmaps(server_addr);
+
+if (version > MAX_NFSPROT)
+ version = MAX_NFSPROT;
+if (!prog)
+ prog = MOUNTPROG;
+p.pm_prog = prog;
+p.pm_vers = version;
+p.pm_prot = proto;
+p.pm_port = port;
+
+while (pmap) {
+ if (pmap->pml_map.pm_prog != prog)
+ goto next;
+ if (!version && p.pm_vers > pmap->pml_map.pm_vers)
+ goto next;
+ if (version > 2 && pmap->pml_map.pm_vers != version)
+ goto next;
+ if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
+ goto next;
+ if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
+ (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
+ (port && pmap->pml_map.pm_port != port))
+ goto next;
+ memcpy(&p, &pmap->pml_map, sizeof(p));
+next:
+ pmap = pmap->pml_next;
+}
+if (!p.pm_vers)
+ p.pm_vers = MOUNTVERS;
+if (!p.pm_port)
+ p.pm_port = MOUNTPORT;
+if (!p.pm_prot)
+ p.pm_prot = IPPROTO_TCP;
+return &p;
+}
+
int nfsmount(const char *spec, const char *node, int *flags,
char **extra_opts, char **mount_opts, int running_bg)
{
@@ -114,7 +174,6 @@ int nfsmount(const char *spec, const char *node, int *flags,
char *old_opts;
char *mounthost=NULL;
char new_opts[1024];
- fhandle root_fhandle;
struct timeval total_timeout;
enum clnt_stat clnt_stat;
static struct nfs_mount_data data;
@@ -123,13 +182,18 @@ int nfsmount(const char *spec, const char *node, int *flags,
struct hostent *hp;
struct sockaddr_in server_addr;
struct sockaddr_in mount_server_addr;
+ struct pmap* pm_mnt;
int msock, fsock;
struct timeval retry_timeout;
- struct fhstatus status;
+ union {
+ struct fhstatus nfsv2;
+ struct mountres3 nfsv3;
+ } status;
struct stat statbuf;
char *s;
int port;
int mountport;
+ int proto;
int bg;
int soft;
int intr;
@@ -238,11 +302,11 @@ int nfsmount(const char *spec, const char *node, int *flags,
tcp = 0;
mountprog = MOUNTPROG;
- mountvers = MOUNTVERS;
+ mountvers = 0;
port = 0;
mountport = 0;
nfsprog = NFS_PROGRAM;
- nfsvers = NFS_VERSION;
+ nfsvers = 0;
/* parse options */
@@ -352,6 +416,8 @@ int nfsmount(const char *spec, const char *node, int *flags,
}
}
}
+ proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
+
data.flags = (soft ? NFS_MOUNT_SOFT : 0)
| (intr ? NFS_MOUNT_INTR : 0)
| (posix ? NFS_MOUNT_POSIX : 0)
@@ -365,6 +431,19 @@ int nfsmount(const char *spec, const char *node, int *flags,
if (nfs_mount_version >= 3)
data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
#endif
+ if (nfsvers > MAX_NFSPROT) {
+ fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
+ return 0;
+ }
+ if (mountvers > MAX_NFSPROT) {
+ fprintf(stderr, "NFSv%d not supported!\n", nfsvers);
+ return 0;
+ }
+ if (nfsvers && !mountvers)
+ mountvers = (nfsvers < 3) ? 1 : nfsvers;
+ if (nfsvers && nfsvers < mountvers) {
+ mountvers = nfsvers;
+ }
/* Adjust options if none specified */
if (!data.timeo)
@@ -470,28 +549,60 @@ int nfsmount(const char *spec, const char *node, int *flags,
if (t - prevt < 30)
sleep(30);
+ pm_mnt = get_mountport(&mount_server_addr,
+ mountprog,
+ mountvers,
+ proto,
+ mountport);
+
/* contact the mount daemon via TCP */
- mount_server_addr.sin_port = htons(mountport);
+ mount_server_addr.sin_port = htons(pm_mnt->pm_port);
msock = RPC_ANYSOCK;
- mclient = clnttcp_create(&mount_server_addr,
- mountprog, mountvers,
- &msock, 0, 0);
- /* if this fails, contact the mount daemon via UDP */
- if (!mclient) {
- mount_server_addr.sin_port = htons(mountport);
- msock = RPC_ANYSOCK;
+ switch (pm_mnt->pm_prot) {
+ case IPPROTO_UDP:
mclient = clntudp_create(&mount_server_addr,
- mountprog, mountvers,
- retry_timeout, &msock);
+ pm_mnt->pm_prog,
+ pm_mnt->pm_vers,
+ retry_timeout,
+ &msock);
+ if (mclient)
+ break;
+ mount_server_addr.sin_port = htons(pm_mnt->pm_port);
+ msock = RPC_ANYSOCK;
+ case IPPROTO_TCP:
+ mclient = clnttcp_create(&mount_server_addr,
+ pm_mnt->pm_prog,
+ pm_mnt->pm_vers,
+ &msock, 0, 0);
+ break;
+ default:
+ mclient = 0;
}
if (mclient) {
/* try to mount hostname:dirname */
mclient->cl_auth = authunix_create_default();
- clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
- (xdrproc_t) xdr_dirpath, (caddr_t) &dirname,
- (xdrproc_t) xdr_fhstatus, (caddr_t) &status,
+
+ /* make pointers in xdr_mountres3 NULL so
+ * that xdr_array allocates memory for us
+ */
+ memset(&status, 0, sizeof(status));
+
+ if (pm_mnt->pm_vers == 3)
+ clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
+ (xdrproc_t) xdr_dirpath,
+ (caddr_t) &dirname,
+ (xdrproc_t) xdr_mountres3,
+ (caddr_t) &status,
total_timeout);
+ else
+ clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
+ (xdrproc_t) xdr_dirpath,
+ (caddr_t) &dirname,
+ (xdrproc_t) xdr_fhstatus,
+ (caddr_t) &status,
+ total_timeout);
+
if (clnt_stat == RPC_SUCCESS)
break; /* we're done */
if (errno != ECONNREFUSED) {
@@ -522,15 +633,46 @@ int nfsmount(const char *spec, const char *node, int *flags,
if (t >= timeout)
goto fail;
}
-
- if (status.fhs_status != 0) {
- fprintf(stderr,
- _("mount: %s:%s failed, reason given by server: %s\n"),
- hostname, dirname, nfs_strerror(status.fhs_status));
- goto fail;
+ nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
+
+ if (nfsvers == 2) {
+ if (status.nfsv2.fhs_status != 0) {
+ fprintf(stderr,
+ "mount: %s:%s failed, reason given by server: %s\n",
+ hostname, dirname,
+ nfs_strerror(status.nfsv2.fhs_status));
+ goto fail;
+ }
+ memcpy(data.root.data,
+ (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
+ NFS_FHSIZE);
+#if NFS_MOUNT_VERSION >= 4
+ data.root.size = NFS_FHSIZE;
+ memcpy(data.old_root.data,
+ (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
+ NFS_FHSIZE);
+#endif
+ } else {
+#if NFS_MOUNT_VERSION >= 4
+ fhandle3 *fhandle;
+ if (status.nfsv3.fhs_status != 0) {
+ fprintf(stderr,
+ "mount: %s:%s failed, reason given by server: %s\n",
+ hostname, dirname,
+ nfs_strerror(status.nfsv3.fhs_status));
+ goto fail;
+ }
+ fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
+ memset(data.old_root.data, 0, NFS_FHSIZE);
+ memset(&data.root, 0, sizeof(data.root));
+ data.root.size = fhandle->fhandle3_len;
+ memcpy(data.root.data,
+ (char *) fhandle->fhandle3_val,
+ fhandle->fhandle3_len);
+
+ data.flags |= NFS_MOUNT_VER3;
+#endif
}
- memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
- sizeof (root_fhandle));
/* create nfs socket for kernel */
@@ -580,8 +722,6 @@ int nfsmount(const char *spec, const char *node, int *flags,
/* prepare data structure for kernel */
data.fd = fsock;
- memcpy((char *) &data.root, (char *) &root_fhandle,
- sizeof (root_fhandle));
memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
strncpy(data.hostname, hostname, sizeof(data.hostname));
diff --git a/mount/nfsmount.h b/mount/nfsmount.h
deleted file mode 100644
index 73c71fc68..000000000
--- a/mount/nfsmount.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#ifndef _NFSMOUNT_H_RPCGEN
-#define _NFSMOUNT_H_RPCGEN
-
-#include <rpc/rpc.h>
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-#ifndef _rpcsvc_mount_h
-#define _rpcsvc_mount_h
-#define MNTPATHLEN 1024
-#define MNTNAMLEN 255
-#define FHSIZE 32
-
-typedef char fhandle[FHSIZE];
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhandle(XDR *, fhandle);
-#elif __STDC__
-extern bool_t xdr_fhandle(XDR *, fhandle);
-#else /* Old Style C */
-bool_t xdr_fhandle();
-#endif /* Old Style C */
-
-
-struct fhstatus {
- u_int fhs_status;
- union {
- fhandle fhs_fhandle;
- } fhstatus_u;
-};
-typedef struct fhstatus fhstatus;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
-#elif __STDC__
-extern bool_t xdr_fhstatus(XDR *, fhstatus*);
-#else /* Old Style C */
-bool_t xdr_fhstatus();
-#endif /* Old Style C */
-
-
-typedef char *dirpath;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
-#elif __STDC__
-extern bool_t xdr_dirpath(XDR *, dirpath*);
-#else /* Old Style C */
-bool_t xdr_dirpath();
-#endif /* Old Style C */
-
-
-typedef char *name;
-#ifdef __cplusplus
-extern "C" bool_t xdr_name(XDR *, name*);
-#elif __STDC__
-extern bool_t xdr_name(XDR *, name*);
-#else /* Old Style C */
-bool_t xdr_name();
-#endif /* Old Style C */
-
-
-typedef struct mountbody *mountlist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
-#elif __STDC__
-extern bool_t xdr_mountlist(XDR *, mountlist*);
-#else /* Old Style C */
-bool_t xdr_mountlist();
-#endif /* Old Style C */
-
-
-struct mountbody {
- name ml_hostname;
- dirpath ml_directory;
- mountlist ml_next;
-};
-typedef struct mountbody mountbody;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
-#elif __STDC__
-extern bool_t xdr_mountbody(XDR *, mountbody*);
-#else /* Old Style C */
-bool_t xdr_mountbody();
-#endif /* Old Style C */
-
-
-typedef struct groupnode *groups;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groups(XDR *, groups*);
-#elif __STDC__
-extern bool_t xdr_groups(XDR *, groups*);
-#else /* Old Style C */
-bool_t xdr_groups();
-#endif /* Old Style C */
-
-
-struct groupnode {
- name gr_name;
- groups gr_next;
-};
-typedef struct groupnode groupnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
-#elif __STDC__
-extern bool_t xdr_groupnode(XDR *, groupnode*);
-#else /* Old Style C */
-bool_t xdr_groupnode();
-#endif /* Old Style C */
-
-
-typedef struct exportnode *exports;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exports(XDR *, exports*);
-#elif __STDC__
-extern bool_t xdr_exports(XDR *, exports*);
-#else /* Old Style C */
-bool_t xdr_exports();
-#endif /* Old Style C */
-
-
-struct exportnode {
- dirpath ex_dir;
- groups ex_groups;
- exports ex_next;
-};
-typedef struct exportnode exportnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
-#elif __STDC__
-extern bool_t xdr_exportnode(XDR *, exportnode*);
-#else /* Old Style C */
-bool_t xdr_exportnode();
-#endif /* Old Style C */
-
-
-struct ppathcnf {
- int pc_link_max;
- short pc_max_canon;
- short pc_max_input;
- short pc_name_max;
- short pc_path_max;
- short pc_pipe_buf;
- u_char pc_vdisable;
- char pc_xxx;
- short pc_mask[2];
-};
-typedef struct ppathcnf ppathcnf;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#elif __STDC__
-extern bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#else /* Old Style C */
-bool_t xdr_ppathcnf();
-#endif /* Old Style C */
-
-#endif /*!_rpcsvc_mount_h*/
-
-#define MOUNTPROG ((u_long)100005)
-#define MOUNTVERS ((u_long)1)
-
-#ifdef __cplusplus
-#define MOUNTPROC_NULL ((u_long)0)
-extern "C" void * mountproc_null_1(void *, CLIENT *);
-extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern "C" void * mountproc_umntall_1(void *, CLIENT *);
-extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern "C" exports * mountproc_export_1(void *, CLIENT *);
-extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#elif __STDC__
-#define MOUNTPROC_NULL ((u_long)0)
-extern void * mountproc_null_1(void *, CLIENT *);
-extern void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern mountlist * mountproc_dump_1(void *, CLIENT *);
-extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern void * mountproc_umntall_1(void *, CLIENT *);
-extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern exports * mountproc_export_1(void *, CLIENT *);
-extern exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern exports * mountproc_exportall_1(void *, CLIENT *);
-extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#else /* Old Style C */
-#define MOUNTPROC_NULL ((u_long)0)
-extern void * mountproc_null_1();
-extern void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT ((u_long)1)
-extern fhstatus * mountproc_mnt_1();
-extern fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP ((u_long)2)
-extern mountlist * mountproc_dump_1();
-extern mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT ((u_long)3)
-extern void * mountproc_umnt_1();
-extern void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern void * mountproc_umntall_1();
-extern void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern exports * mountproc_export_1();
-extern exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern exports * mountproc_exportall_1();
-extern exports * mountproc_exportall_1_svc();
-#endif /* Old Style C */
-#define MOUNTVERS_POSIX ((u_long)2)
-
-#ifdef __cplusplus
-extern "C" void * mountproc_null_2(void *, CLIENT *);
-extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
-extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern "C" void * mountproc_umntall_2(void *, CLIENT *);
-extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_export_2(void *, CLIENT *);
-extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#elif __STDC__
-extern void * mountproc_null_2(void *, CLIENT *);
-extern void * mountproc_null_2_svc(void *, struct svc_req *);
-extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern mountlist * mountproc_dump_2(void *, CLIENT *);
-extern mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern void * mountproc_umntall_2(void *, CLIENT *);
-extern void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern exports * mountproc_export_2(void *, CLIENT *);
-extern exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern exports * mountproc_exportall_2(void *, CLIENT *);
-extern exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#else /* Old Style C */
-extern void * mountproc_null_2();
-extern void * mountproc_null_2_svc();
-extern fhstatus * mountproc_mnt_2();
-extern fhstatus * mountproc_mnt_2_svc();
-extern mountlist * mountproc_dump_2();
-extern mountlist * mountproc_dump_2_svc();
-extern void * mountproc_umnt_2();
-extern void * mountproc_umnt_2_svc();
-extern void * mountproc_umntall_2();
-extern void * mountproc_umntall_2_svc();
-extern exports * mountproc_export_2();
-extern exports * mountproc_export_2_svc();
-extern exports * mountproc_exportall_2();
-extern exports * mountproc_exportall_2_svc();
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern ppathcnf * mountproc_pathconf_2();
-extern ppathcnf * mountproc_pathconf_2_svc();
-#endif /* Old Style C */
-
-#endif /* !_NFSMOUNT_H_RPCGEN */
diff --git a/mount/nfsmount.x b/mount/nfsmount.x
index 90590eb2c..c27e74b7c 100644
--- a/mount/nfsmount.x
+++ b/mount/nfsmount.x
@@ -46,10 +46,13 @@
#ifdef RPC_CLNT
%#include <string.h> /* for memset() */
#endif
+%#include <asm/types.h>
+const MOUNTPORT = 635;
const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
const MNTNAMLEN = 255; /* maximum bytes in a name argument */
const FHSIZE = 32; /* size in bytes of a file handle */
+const FHSIZE3 = 64; /* size in bytes of a file handle */
/*
* The fhandle is the file handle that the server passes to the client.
@@ -58,6 +61,20 @@ const FHSIZE = 32; /* size in bytes of a file handle */
* server needs to distinguish an individual file.
*/
typedef opaque fhandle[FHSIZE];
+typedef opaque fhandle3<FHSIZE3>;
+
+enum mountstat3 {
+ MNT_OK = 0, /* no error */
+ MNT3ERR_PERM = 1, /* not owner */
+ MNT3ERR_NOENT = 2, /* No such file or directory */
+ MNT3ERR_IO = 5, /* I/O error */
+ MNT3ERR_ACCES = 13, /* Permission denied */
+ MNT3ERR_NOTDIR = 20, /* Not a directory */
+ MNT3ERR_INVAL = 22, /* Invalid argument */
+ MNT3ERR_NAMETOOLONG = 63, /* File name too long */
+ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
+ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
+};
/*
* If a status of zero is returned, the call completed successfully, and
@@ -71,6 +88,18 @@ default:
void;
};
+struct mountres3_ok {
+ fhandle3 fhandle;
+ int auth_flavours<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case MNT_OK:
+ mountres3_ok mountinfo;
+default:
+ void;
+};
+
/*
* The type dirpath is the pathname of a directory
*/
@@ -252,6 +281,55 @@ program MOUNTPROG {
ppathcnf
MOUNTPROC_PATHCONF(dirpath) = 7;
} = 2;
+ version MOUNT_V3 {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC3_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ mountres3
+ MOUNTPROC3_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC3_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC3_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC3_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC3_EXPORT(void) = 5;
+
+ } = 3;
} = 100005;
#ifdef RPC_HDR
diff --git a/mount/nfsmount_clnt.c b/mount/nfsmount_clnt.c
deleted file mode 100644
index ef5752583..000000000
--- a/mount/nfsmount_clnt.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include "nfsmount.h"
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-#include <string.h> /* for memset() */
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 25, 0 };
-
-void *
-mountproc_null_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-fhstatus *
-mountproc_mnt_1(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
-{
- static fhstatus clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
- (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-mountlist *
-mountproc_dump_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static mountlist clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void,
- (caddr_t) argp, (xdrproc_t) xdr_mountlist,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-void *
-mountproc_umnt_1(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
- (caddr_t) argp, (xdrproc_t) xdr_void,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-void *
-mountproc_umntall_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
- (caddr_t) argp, (xdrproc_t) xdr_void,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-exports *
-mountproc_export_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static exports clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
- (caddr_t) argp, (xdrproc_t) xdr_exports,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-exports *
-mountproc_exportall_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static exports clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void,
- (caddr_t) argp, (xdrproc_t) xdr_exports,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-void *
-mountproc_null_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-fhstatus *
-mountproc_mnt_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
-{
- static fhstatus clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath,
- (caddr_t) argp, (xdrproc_t) xdr_fhstatus,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-mountlist *
-mountproc_dump_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static mountlist clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp,
- (xdrproc_t) xdr_mountlist, (caddr_t) &clnt_res,
- TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-void *
-mountproc_umnt_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath,
- (caddr_t) argp, (xdrproc_t) xdr_void,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-void *
-mountproc_umntall_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static char clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void,
- (caddr_t) argp, (xdrproc_t) xdr_void,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return ((void *)&clnt_res);
-}
-
-exports *
-mountproc_export_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static exports clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void,
- argp, (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
- TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-exports *
-mountproc_exportall_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
-{
- static exports clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp,
- (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
- TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
-
-ppathcnf *
-mountproc_pathconf_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
-{
- static ppathcnf clnt_res;
-
- memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath,
- (caddr_t) argp, (xdrproc_t) xdr_ppathcnf,
- (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) {
- return (NULL);
- }
- return (&clnt_res);
-}
diff --git a/mount/nfsmount_xdr.c b/mount/nfsmount_xdr.c
deleted file mode 100644
index 91fbeec6a..000000000
--- a/mount/nfsmount_xdr.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-
-#include "nfsmount.h"
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-bool_t
-xdr_fhandle(XDR *xdrs, fhandle objp)
-{
-
- register long *buf;
-
- if (!xdr_opaque(xdrs, objp, FHSIZE)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_fhstatus(XDR *xdrs, fhstatus *objp)
-{
-
- register long *buf;
-
- if (!xdr_u_int(xdrs, &objp->fhs_status)) {
- return (FALSE);
- }
- switch (objp->fhs_status) {
- case 0:
- if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_dirpath(XDR *xdrs, dirpath *objp)
-{
-
- register long *buf;
-
- if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_name(XDR *xdrs, name *objp)
-{
-
- register long *buf;
-
- if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_mountlist(XDR *xdrs, mountlist *objp)
-{
-
- register long *buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), (xdrproc_t)xdr_mountbody)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_mountbody(XDR *xdrs, mountbody *objp)
-{
-
- register long *buf;
-
- if (!xdr_name(xdrs, &objp->ml_hostname)) {
- return (FALSE);
- }
- if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
- return (FALSE);
- }
- if (!xdr_mountlist(xdrs, &objp->ml_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_groups(XDR *xdrs, groups *objp)
-{
-
- register long *buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), (xdrproc_t)xdr_groupnode)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_groupnode(XDR *xdrs, groupnode *objp)
-{
-
- register long *buf;
-
- if (!xdr_name(xdrs, &objp->gr_name)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->gr_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_exports(XDR *xdrs, exports *objp)
-{
-
- register long *buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), (xdrproc_t)xdr_exportnode)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_exportnode(XDR *xdrs, exportnode *objp)
-{
-
- register long *buf;
-
- if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->ex_groups)) {
- return (FALSE);
- }
- if (!xdr_exports(xdrs, &objp->ex_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_ppathcnf(XDR *xdrs, ppathcnf *objp)
-{
-
- register long *buf;
-
- int i;
-
- if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_LONG(buf,objp->pc_link_max);
- IXDR_PUT_SHORT(buf,objp->pc_max_canon);
- IXDR_PUT_SHORT(buf,objp->pc_max_input);
- IXDR_PUT_SHORT(buf,objp->pc_name_max);
- IXDR_PUT_SHORT(buf,objp->pc_path_max);
- IXDR_PUT_SHORT(buf,objp->pc_pipe_buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- IXDR_PUT_SHORT(buf,*genp++);
- }
- };
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- objp->pc_link_max = IXDR_GET_LONG(buf);
- objp->pc_max_canon = IXDR_GET_SHORT(buf);
- objp->pc_max_input = IXDR_GET_SHORT(buf);
- objp->pc_name_max = IXDR_GET_SHORT(buf);
- objp->pc_path_max = IXDR_GET_SHORT(buf);
- objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- *genp++ = IXDR_GET_SHORT(buf);
- }
- };
- }
- return(TRUE);
- }
-
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
- return (TRUE);
-}
diff --git a/mount/pivot_root.2 b/mount/pivot_root.2
new file mode 100644
index 000000000..1c8f168a7
--- /dev/null
+++ b/mount/pivot_root.2
@@ -0,0 +1,97 @@
+.TH PIVOT_ROOT 2 "Feb 23, 2000" "Linux" "System Calls"
+.SH NAME
+pivot_root \- change the root file system
+.SH SYNOPSIS
+.B #include <linux/unistd.h>
+.sp
+.B _syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
+.sp
+.BI "int pivot_root(const char *" new_root ", const char *" put_old );
+.SH DESCRIPTION
+\fBpivot_root\fP moves the root file system of the current process to the
+directory \fIput_old\fP and makes \fInew_root\fP the new root file system
+of the current process.
+
+The typical use of \fBpivot_root\fP is during system startup, when the
+system mounts a temporary root file system (e.g. an \fBinitrd\fP), then
+mounts the real root file system, and eventually turns the latter into
+the current root of all relevant processes or threads.
+
+\fBpivot_root\fP may or may not change the current root and the current
+working directory (cwd) of any processes or threads which use the old
+root directory. The caller of \fBpivot_root\fP
+must ensure that processes with root or cwd at the old root operate
+correctly in either case. An easy way to ensure this is to change their
+root and cwd to \fInew_root\fP before invoking \fBpivot_root\fP.
+
+The paragraph above is intentionally vague because the implementation
+of \fBpivot_root\fP may change in the future. At the time of writing,
+\fBpivot_root\fP changes root and cwd of each process or
+thread to \fInew_root\fP if they point to the old root directory. This
+is necessary in order to prevent kernel threads from keeping the old
+root directory busy with their root and cwd, even if they never access
+the file system in any way. In the future, there may be a mechanism for
+kernel threads to explicitly relinquish any access to the file system,
+such that this fairly intrusive mechanism can be removed from
+\fBpivot_root\fP.
+
+Note that this also applies to the current process: \fBpivot_root\fP may
+or may not affect its cwd. It is therefore recommended to call
+\fBchdir("/")\fP immediately after \fBpivot_root\fP.
+
+The following restrictions apply to \fInew_root\fP and \fIput_old\fP:
+.IP \- 3
+They must be directories.
+.IP \- 3
+\fInew_root\fP and \fIput_old\fP must not be on the same file system as
+the current root.
+.IP \- 3
+\fIput_old\fP must be underneath \fInew_root\fP, i.e. adding a non-zero
+number of \fB/..\fP to the string pointed to by \fIput_old\fP must yield
+the same directory as \fInew_root\fP.
+.IP \- 3
+No other file system may be mounted on \fIput_old\fP.
+.PP
+See also \fBpivot_root(8)\fP for additional usage examples.
+
+If the current root is not a mount point (e.g. after \fBchroot(2)\fP or
+\fBpivot_root\fP, see also below), not the old root directory, but the
+mount point of that file system is mounted on \fIput_old\fP.
+.SH NOTES
+\fInew_root\fP does not have to be a mount point. In this case,
+\fB/proc/mounts\fP will show the mount point of the file system containing
+\fInew_root\fP as root (\fB/\fP).
+.SH "RETURN VALUE"
+On success, zero is returned. On error, \-1 is returned, and
+\fIerrno\fP is set appropriately.
+.SH ERRORS
+\fBpivot_root\fP may return (in \fIerrno\fP) any of the errors returned by
+\fBstat(2)\fP. Additionally, it may return:
+
+.TP
+.B EBUSY
+\fInew_root\fP or \fIput_old\fP are on the current root file system,
+or a file system is already mounted on \fIput_old\fP.
+.TP
+.B EINVAL
+\fIput_old\fP is not underneath \fInew_root\fP.
+.TP
+.B ENOTDIR
+\fInew_root\fP or \fIput_old\fP is not a directory.
+.TP
+.B EPERM
+The current process does not have the administrator capability.
+.SH BUGS
+\fBpivot_root\fP should not have to change root and cwd of all other
+processes in the system.
+
+Some of the more obscure uses of \fBpivot_root\fP may quickly lead to
+insanity.
+.SH HISTORY
+\fBpivot_root\fP was introduced in Linux 2.3.41.
+.SH "SEE ALSO"
+.BR chdir(2),
+.BR chroot(2),
+.BR initrd(4),
+.BR pivot_root(8),
+.BR stat(2)
diff --git a/mount/pivot_root.8 b/mount/pivot_root.8
new file mode 100644
index 000000000..83d1daa22
--- /dev/null
+++ b/mount/pivot_root.8
@@ -0,0 +1,65 @@
+.TH PIVOT_ROOT 8 "Feb 23, 2000" "Linux" "Maintenance Commands"
+.SH NAME
+pivot_root \- change the root file system
+.SH SYNOPSIS
+.B pivot_root
+.RB \fInew_root\fP
+.RB \fIput_old\fP
+.SH DESCRIPTION
+\fBpivot_root\fP moves the root file system of the current process to the
+directory \fIput_old\fP and makes \fInew_root\fP the new root file system.
+Since \fBpivot_root(8)\fP simply calls \fBpivot_root(2)\fP, we refer to
+the man page of the latter for further details.
+
+Note that, depending on the implementation of \fBpivot_root\fP, root and
+cwd of the caller may or may not change. The following is a sequence for
+invoking \fBpivot_root\fP that works in either case, assuming that
+\fBpivot_root\fP and \fBchroot\fP are in the current \fBPATH\fP:
+.sp
+cd \fInew_root\fP
+.br
+pivot_root . \fIput_old\fP
+.br
+exec chroot . \fIcommand\fP
+.sp
+Note that \fBchroot\fP must be available under the old root and under the new
+root, because \fBpivot_root\fP may or may not have implicitly changed the
+root directory of the shell.
+
+Note that \fBexec chroot\fP changes the running executable, which is
+necessary if the old root directory should be unmounted afterwards.
+Also note that standard input, output, and error may still point to a
+device on the old root file system, keeping it busy. They can easily be
+changed when invoking \fBchroot\fP (see below; note the absence of
+leading slashes to make it work whether \fBpivot_root\fP has changed the
+shell's root or not).
+.SH EXAMPLES
+Change the root file system to /dev/hda1 from an interactive shell:
+.sp
+.nf
+mount /dev/hda1 /new-root
+cd /new-root
+pivot_root . old-root
+exec chroot . sh <dev/console >dev/console 2>&1
+umount /old-root
+.fi
+.sp
+Mount the new root file system over NFS from 10.0.0.1:/my_root and run
+\fBinit\fP:
+.sp
+.nf
+ifconfig lo 127.0.0.1 up # for portmap
+# configure Ethernet or such
+portmap # for lockd (implicitly started by mount)
+mount -o ro 10.0.0.1:/my_root /mnt
+killall portmap # portmap keeps old root busy
+cd /mnt
+pivot_root . old_root
+exec chroot . sh -c 'umount /old_root; exec /sbin/init' \\
+ <dev/console >dev/console 2>&1
+.fi
+.SH "SEE ALSO"
+.BR chroot(1),
+.BR mount(8),
+.BR pivot_root(2),
+.BR umount(8)
diff --git a/mount/pivot_root.c b/mount/pivot_root.c
new file mode 100644
index 000000000..4ab8be853
--- /dev/null
+++ b/mount/pivot_root.c
@@ -0,0 +1,24 @@
+/* pivot_root.c - Change the root file system */
+
+/* Written 2000 by Werner Almesberger */
+
+
+#include <stdio.h>
+#include <linux/unistd.h>
+
+
+_syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
+
+
+int main(int argc,const char **argv)
+{
+ if (argc != 3) {
+ fprintf(stderr,"usage: %s new_root put_old\n",argv[0]);
+ return 1;
+ }
+ if (pivot_root(argv[1],argv[2]) < 0) {
+ perror("pivot_root");
+ return 1;
+ }
+ return 0;
+}
diff --git a/mount/realpath.c b/mount/realpath.c
index f0d7c76c0..374f8a3a2 100644
--- a/mount/realpath.c
+++ b/mount/realpath.c
@@ -27,18 +27,20 @@
#define MAX_READLINKS 32
+/* this leaks some memory - unimportant for mount */
char *
myrealpath(const char *path, char *resolved_path, int maxreslth) {
- char *npath;
+ char *npath, *buf;
char link_path[PATH_MAX+1];
int readlinks = 0;
- int n;
+ int m, n;
npath = resolved_path;
/* If it's a relative pathname use getcwd for starters. */
if (*path != '/') {
- getcwd(npath, maxreslth-2);
+ if (!getcwd(npath, maxreslth-2))
+ return NULL;
npath += strlen(npath);
if (npath[-1] != '/')
*npath++ = '/';
@@ -100,14 +102,13 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
/* Otherwise back up over this component. */
while (*(--npath) != '/')
;
- /* Safe sex check. */
- if (strlen(path) + n >= sizeof(link_path)) {
- errno = ENAMETOOLONG;
- return NULL;
- }
+
/* Insert symlink contents into path. */
- strcat(link_path, path);
- path = xstrdup(link_path);
+ m = strlen(path);
+ buf = xmalloc(m + n + 1);
+ memcpy(buf, link_path, n);
+ memcpy(buf + n, path, m + 1);
+ path = buf;
}
*npath++ = '/';
diff --git a/mount/rpcsvc/nfsmount.h b/mount/rpcsvc/nfsmount.h
index 73c71fc68..55b5d8e7e 100644
--- a/mount/rpcsvc/nfsmount.h
+++ b/mount/rpcsvc/nfsmount.h
@@ -8,6 +8,11 @@
#include <rpc/rpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@@ -44,19 +49,33 @@
/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
#ifndef _rpcsvc_mount_h
#define _rpcsvc_mount_h
+#include <asm/types.h>
+#define MOUNTPORT 635
#define MNTPATHLEN 1024
#define MNTNAMLEN 255
#define FHSIZE 32
+#define FHSIZE3 64
typedef char fhandle[FHSIZE];
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhandle(XDR *, fhandle);
-#elif __STDC__
-extern bool_t xdr_fhandle(XDR *, fhandle);
-#else /* Old Style C */
-bool_t xdr_fhandle();
-#endif /* Old Style C */
+typedef struct {
+ u_int fhandle3_len;
+ char *fhandle3_val;
+} fhandle3;
+
+enum mountstat3 {
+ MNT_OK = 0,
+ MNT3ERR_PERM = 1,
+ MNT3ERR_NOENT = 2,
+ MNT3ERR_IO = 5,
+ MNT3ERR_ACCES = 13,
+ MNT3ERR_NOTDIR = 20,
+ MNT3ERR_INVAL = 22,
+ MNT3ERR_NAMETOOLONG = 63,
+ MNT3ERR_NOTSUPP = 10004,
+ MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
struct fhstatus {
u_int fhs_status;
@@ -65,44 +84,29 @@ struct fhstatus {
} fhstatus_u;
};
typedef struct fhstatus fhstatus;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
-#elif __STDC__
-extern bool_t xdr_fhstatus(XDR *, fhstatus*);
-#else /* Old Style C */
-bool_t xdr_fhstatus();
-#endif /* Old Style C */
+struct mountres3_ok {
+ fhandle3 fhandle;
+ struct {
+ u_int auth_flavours_len;
+ int *auth_flavours_val;
+ } auth_flavours;
+};
+typedef struct mountres3_ok mountres3_ok;
-typedef char *dirpath;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
-#elif __STDC__
-extern bool_t xdr_dirpath(XDR *, dirpath*);
-#else /* Old Style C */
-bool_t xdr_dirpath();
-#endif /* Old Style C */
+struct mountres3 {
+ mountstat3 fhs_status;
+ union {
+ mountres3_ok mountinfo;
+ } mountres3_u;
+};
+typedef struct mountres3 mountres3;
+typedef char *dirpath;
typedef char *name;
-#ifdef __cplusplus
-extern "C" bool_t xdr_name(XDR *, name*);
-#elif __STDC__
-extern bool_t xdr_name(XDR *, name*);
-#else /* Old Style C */
-bool_t xdr_name();
-#endif /* Old Style C */
-
typedef struct mountbody *mountlist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
-#elif __STDC__
-extern bool_t xdr_mountlist(XDR *, mountlist*);
-#else /* Old Style C */
-bool_t xdr_mountlist();
-#endif /* Old Style C */
-
struct mountbody {
name ml_hostname;
@@ -110,48 +114,16 @@ struct mountbody {
mountlist ml_next;
};
typedef struct mountbody mountbody;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
-#elif __STDC__
-extern bool_t xdr_mountbody(XDR *, mountbody*);
-#else /* Old Style C */
-bool_t xdr_mountbody();
-#endif /* Old Style C */
-
typedef struct groupnode *groups;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groups(XDR *, groups*);
-#elif __STDC__
-extern bool_t xdr_groups(XDR *, groups*);
-#else /* Old Style C */
-bool_t xdr_groups();
-#endif /* Old Style C */
-
struct groupnode {
name gr_name;
groups gr_next;
};
typedef struct groupnode groupnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
-#elif __STDC__
-extern bool_t xdr_groupnode(XDR *, groupnode*);
-#else /* Old Style C */
-bool_t xdr_groupnode();
-#endif /* Old Style C */
-
typedef struct exportnode *exports;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exports(XDR *, exports*);
-#elif __STDC__
-extern bool_t xdr_exports(XDR *, exports*);
-#else /* Old Style C */
-bool_t xdr_exports();
-#endif /* Old Style C */
-
struct exportnode {
dirpath ex_dir;
@@ -159,14 +131,6 @@ struct exportnode {
exports ex_next;
};
typedef struct exportnode exportnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
-#elif __STDC__
-extern bool_t xdr_exportnode(XDR *, exportnode*);
-#else /* Old Style C */
-bool_t xdr_exportnode();
-#endif /* Old Style C */
-
struct ppathcnf {
int pc_link_max;
@@ -180,110 +144,62 @@ struct ppathcnf {
short pc_mask[2];
};
typedef struct ppathcnf ppathcnf;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#elif __STDC__
-extern bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#else /* Old Style C */
-bool_t xdr_ppathcnf();
-#endif /* Old Style C */
-
#endif /*!_rpcsvc_mount_h*/
-#define MOUNTPROG ((u_long)100005)
-#define MOUNTVERS ((u_long)1)
+#define MOUNTPROG 100005
+#define MOUNTVERS 1
-#ifdef __cplusplus
-#define MOUNTPROC_NULL ((u_long)0)
-extern "C" void * mountproc_null_1(void *, CLIENT *);
-extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern "C" void * mountproc_umntall_1(void *, CLIENT *);
-extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern "C" exports * mountproc_export_1(void *, CLIENT *);
-extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#elif __STDC__
-#define MOUNTPROC_NULL ((u_long)0)
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC_NULL 0
extern void * mountproc_null_1(void *, CLIENT *);
extern void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
extern mountlist * mountproc_dump_1(void *, CLIENT *);
extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
extern void * mountproc_umnt_1(dirpath *, CLIENT *);
extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
extern void * mountproc_umntall_1(void *, CLIENT *);
extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
extern exports * mountproc_export_1(void *, CLIENT *);
extern exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
extern exports * mountproc_exportall_1(void *, CLIENT *);
extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
-#else /* Old Style C */
-#define MOUNTPROC_NULL ((u_long)0)
+#else /* K&R C */
+#define MOUNTPROC_NULL 0
extern void * mountproc_null_1();
extern void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT ((u_long)1)
+#define MOUNTPROC_MNT 1
extern fhstatus * mountproc_mnt_1();
extern fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP ((u_long)2)
+#define MOUNTPROC_DUMP 2
extern mountlist * mountproc_dump_1();
extern mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT ((u_long)3)
+#define MOUNTPROC_UMNT 3
extern void * mountproc_umnt_1();
extern void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL ((u_long)4)
+#define MOUNTPROC_UMNTALL 4
extern void * mountproc_umntall_1();
extern void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT ((u_long)5)
+#define MOUNTPROC_EXPORT 5
extern exports * mountproc_export_1();
extern exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL ((u_long)6)
+#define MOUNTPROC_EXPORTALL 6
extern exports * mountproc_exportall_1();
extern exports * mountproc_exportall_1_svc();
-#endif /* Old Style C */
-#define MOUNTVERS_POSIX ((u_long)2)
+extern int mountprog_1_freeresult ();
+#endif /* K&R C */
+#define MOUNTVERS_POSIX 2
-#ifdef __cplusplus
-extern "C" void * mountproc_null_2(void *, CLIENT *);
-extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
-extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern "C" void * mountproc_umntall_2(void *, CLIENT *);
-extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_export_2(void *, CLIENT *);
-extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#elif __STDC__
+#if defined(__STDC__) || defined(__cplusplus)
extern void * mountproc_null_2(void *, CLIENT *);
extern void * mountproc_null_2_svc(void *, struct svc_req *);
extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
@@ -298,11 +214,12 @@ extern exports * mountproc_export_2(void *, CLIENT *);
extern exports * mountproc_export_2_svc(void *, struct svc_req *);
extern exports * mountproc_exportall_2(void *, CLIENT *);
extern exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+extern int mountprog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
-#else /* Old Style C */
+#else /* K&R C */
extern void * mountproc_null_2();
extern void * mountproc_null_2_svc();
extern fhstatus * mountproc_mnt_2();
@@ -317,9 +234,96 @@ extern exports * mountproc_export_2();
extern exports * mountproc_export_2_svc();
extern exports * mountproc_exportall_2();
extern exports * mountproc_exportall_2_svc();
-#define MOUNTPROC_PATHCONF ((u_long)7)
+#define MOUNTPROC_PATHCONF 7
extern ppathcnf * mountproc_pathconf_2();
extern ppathcnf * mountproc_pathconf_2_svc();
-#endif /* Old Style C */
+extern int mountprog_2_freeresult ();
+#endif /* K&R C */
+#define MOUNT_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC3_NULL 0
+extern void * mountproc3_null_3(void *, CLIENT *);
+extern void * mountproc3_null_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_MNT 1
+extern mountres3 * mountproc3_mnt_3(dirpath *, CLIENT *);
+extern mountres3 * mountproc3_mnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_DUMP 2
+extern mountlist * mountproc3_dump_3(void *, CLIENT *);
+extern mountlist * mountproc3_dump_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_UMNT 3
+extern void * mountproc3_umnt_3(dirpath *, CLIENT *);
+extern void * mountproc3_umnt_3_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC3_UMNTALL 4
+extern void * mountproc3_umntall_3(void *, CLIENT *);
+extern void * mountproc3_umntall_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_EXPORT 5
+extern exports * mountproc3_export_3(void *, CLIENT *);
+extern exports * mountproc3_export_3_svc(void *, struct svc_req *);
+extern int mountprog_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC3_NULL 0
+extern void * mountproc3_null_3();
+extern void * mountproc3_null_3_svc();
+#define MOUNTPROC3_MNT 1
+extern mountres3 * mountproc3_mnt_3();
+extern mountres3 * mountproc3_mnt_3_svc();
+#define MOUNTPROC3_DUMP 2
+extern mountlist * mountproc3_dump_3();
+extern mountlist * mountproc3_dump_3_svc();
+#define MOUNTPROC3_UMNT 3
+extern void * mountproc3_umnt_3();
+extern void * mountproc3_umnt_3_svc();
+#define MOUNTPROC3_UMNTALL 4
+extern void * mountproc3_umntall_3();
+extern void * mountproc3_umntall_3_svc();
+#define MOUNTPROC3_EXPORT 5
+extern exports * mountproc3_export_3();
+extern exports * mountproc3_export_3_svc();
+extern int mountprog_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_fhandle (XDR *, fhandle);
+extern bool_t xdr_fhandle3 (XDR *, fhandle3*);
+extern bool_t xdr_mountstat3 (XDR *, mountstat3*);
+extern bool_t xdr_fhstatus (XDR *, fhstatus*);
+extern bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern bool_t xdr_mountres3 (XDR *, mountres3*);
+extern bool_t xdr_dirpath (XDR *, dirpath*);
+extern bool_t xdr_name (XDR *, name*);
+extern bool_t xdr_mountlist (XDR *, mountlist*);
+extern bool_t xdr_mountbody (XDR *, mountbody*);
+extern bool_t xdr_groups (XDR *, groups*);
+extern bool_t xdr_groupnode (XDR *, groupnode*);
+extern bool_t xdr_exports (XDR *, exports*);
+extern bool_t xdr_exportnode (XDR *, exportnode*);
+extern bool_t xdr_ppathcnf (XDR *, ppathcnf*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle ();
+extern bool_t xdr_fhandle3 ();
+extern bool_t xdr_mountstat3 ();
+extern bool_t xdr_fhstatus ();
+extern bool_t xdr_mountres3_ok ();
+extern bool_t xdr_mountres3 ();
+extern bool_t xdr_dirpath ();
+extern bool_t xdr_name ();
+extern bool_t xdr_mountlist ();
+extern bool_t xdr_mountbody ();
+extern bool_t xdr_groups ();
+extern bool_t xdr_groupnode ();
+extern bool_t xdr_exports ();
+extern bool_t xdr_exportnode ();
+extern bool_t xdr_ppathcnf ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
#endif /* !_NFSMOUNT_H_RPCGEN */
diff --git a/mount/rpcsvc/nfsmount.x b/mount/rpcsvc/nfsmount.x
index 90590eb2c..c27e74b7c 100644
--- a/mount/rpcsvc/nfsmount.x
+++ b/mount/rpcsvc/nfsmount.x
@@ -46,10 +46,13 @@
#ifdef RPC_CLNT
%#include <string.h> /* for memset() */
#endif
+%#include <asm/types.h>
+const MOUNTPORT = 635;
const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
const MNTNAMLEN = 255; /* maximum bytes in a name argument */
const FHSIZE = 32; /* size in bytes of a file handle */
+const FHSIZE3 = 64; /* size in bytes of a file handle */
/*
* The fhandle is the file handle that the server passes to the client.
@@ -58,6 +61,20 @@ const FHSIZE = 32; /* size in bytes of a file handle */
* server needs to distinguish an individual file.
*/
typedef opaque fhandle[FHSIZE];
+typedef opaque fhandle3<FHSIZE3>;
+
+enum mountstat3 {
+ MNT_OK = 0, /* no error */
+ MNT3ERR_PERM = 1, /* not owner */
+ MNT3ERR_NOENT = 2, /* No such file or directory */
+ MNT3ERR_IO = 5, /* I/O error */
+ MNT3ERR_ACCES = 13, /* Permission denied */
+ MNT3ERR_NOTDIR = 20, /* Not a directory */
+ MNT3ERR_INVAL = 22, /* Invalid argument */
+ MNT3ERR_NAMETOOLONG = 63, /* File name too long */
+ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
+ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
+};
/*
* If a status of zero is returned, the call completed successfully, and
@@ -71,6 +88,18 @@ default:
void;
};
+struct mountres3_ok {
+ fhandle3 fhandle;
+ int auth_flavours<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case MNT_OK:
+ mountres3_ok mountinfo;
+default:
+ void;
+};
+
/*
* The type dirpath is the pathname of a directory
*/
@@ -252,6 +281,55 @@ program MOUNTPROG {
ppathcnf
MOUNTPROC_PATHCONF(dirpath) = 7;
} = 2;
+ version MOUNT_V3 {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC3_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ mountres3
+ MOUNTPROC3_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC3_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC3_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC3_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC3_EXPORT(void) = 5;
+
+ } = 3;
} = 100005;
#ifdef RPC_HDR
diff --git a/mount/rpcsvc/nfsmount_clnt.c b/mount/rpcsvc/nfsmount_clnt.c
index a77f4c5eb..053d357af 100644
--- a/mount/rpcsvc/nfsmount_clnt.c
+++ b/mount/rpcsvc/nfsmount_clnt.c
@@ -3,6 +3,7 @@
* It was generated using rpcgen.
*/
+#include <memory.h> /* for memset */
#include "nfsmount.h"
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -38,217 +39,322 @@
*/
/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-#include <string.h> /* for memset() */
+#include <string.h> /* for memset() */
+#include <asm/types.h>
/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
void *
-mountproc_null_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_null_1(void *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_NULL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
fhstatus *
-mountproc_mnt_1(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
+mountproc_mnt_1(dirpath *argp, CLIENT *clnt)
{
static fhstatus clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath, argp, (xdrproc_t) xdr_fhstatus, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_MNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_fhstatus, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
mountlist *
-mountproc_dump_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_dump_1(void *argp, CLIENT *clnt)
{
static mountlist clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_mountlist, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_DUMP,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_mountlist, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
void *
-mountproc_umnt_1(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
+mountproc_umnt_1(dirpath *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_UMNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
void *
-mountproc_umntall_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_umntall_1(void *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_UMNTALL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
exports *
-mountproc_export_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_export_1(void *argp, CLIENT *clnt)
{
static exports clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_exports, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_EXPORT,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
exports *
-mountproc_exportall_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_exportall_1(void *argp, CLIENT *clnt)
{
static exports clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_exports, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_EXPORTALL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
void *
-mountproc_null_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_null_2(void *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_NULL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_NULL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
fhstatus *
-mountproc_mnt_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
+mountproc_mnt_2(dirpath *argp, CLIENT *clnt)
{
static fhstatus clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_MNT, (xdrproc_t) xdr_dirpath, argp, (xdrproc_t) xdr_fhstatus, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_MNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_fhstatus, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
mountlist *
-mountproc_dump_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_dump_2(void *argp, CLIENT *clnt)
{
static mountlist clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_DUMP, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_mountlist, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_DUMP,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_mountlist, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
void *
-mountproc_umnt_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
+mountproc_umnt_2(dirpath *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNT, (xdrproc_t) xdr_dirpath, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_UMNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
void *
-mountproc_umntall_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_umntall_2(void *argp, CLIENT *clnt)
{
static char clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_UMNTALL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_UMNTALL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *)&clnt_res);
}
exports *
-mountproc_export_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_export_2(void *argp, CLIENT *clnt)
{
static exports clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_exports, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_EXPORT,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
exports *
-mountproc_exportall_2(argp, clnt)
- void *argp;
- CLIENT *clnt;
+mountproc_exportall_2(void *argp, CLIENT *clnt)
{
static exports clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_EXPORTALL, (xdrproc_t) xdr_void, argp, (xdrproc_t) xdr_exports, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_EXPORTALL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
ppathcnf *
-mountproc_pathconf_2(argp, clnt)
- dirpath *argp;
- CLIENT *clnt;
+mountproc_pathconf_2(dirpath *argp, CLIENT *clnt)
{
static ppathcnf clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
- if (clnt_call(clnt, MOUNTPROC_PATHCONF, (xdrproc_t) xdr_dirpath, argp, (xdrproc_t) xdr_ppathcnf, &clnt_res, TIMEOUT) != RPC_SUCCESS) {
+ if (clnt_call (clnt, MOUNTPROC_PATHCONF,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_ppathcnf, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&clnt_res);
+}
+
+void *
+mountproc3_null_3(void *argp, CLIENT *clnt)
+{
+ static char clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_NULL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return ((void *)&clnt_res);
+}
+
+mountres3 *
+mountproc3_mnt_3(dirpath *argp, CLIENT *clnt)
+{
+ static mountres3 clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_MNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_mountres3, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&clnt_res);
+}
+
+mountlist *
+mountproc3_dump_3(void *argp, CLIENT *clnt)
+{
+ static mountlist clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_DUMP,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_mountlist, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&clnt_res);
+}
+
+void *
+mountproc3_umnt_3(dirpath *argp, CLIENT *clnt)
+{
+ static char clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_UMNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return ((void *)&clnt_res);
+}
+
+void *
+mountproc3_umntall_3(void *argp, CLIENT *clnt)
+{
+ static char clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_UMNTALL,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return ((void *)&clnt_res);
+}
+
+exports *
+mountproc3_export_3(void *argp, CLIENT *clnt)
+{
+ static exports clnt_res;
+
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call (clnt, MOUNTPROC3_EXPORT,
+ (xdrproc_t) xdr_void, (caddr_t) argp,
+ (xdrproc_t) xdr_exports, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
diff --git a/mount/rpcsvc/nfsmount_xdr.c b/mount/rpcsvc/nfsmount_xdr.c
index 6f539c24f..c22492de3 100644
--- a/mount/rpcsvc/nfsmount_xdr.c
+++ b/mount/rpcsvc/nfsmount_xdr.c
@@ -38,314 +38,293 @@
*/
/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
+#include <asm/types.h>
bool_t
-xdr_fhandle(xdrs, objp)
- XDR *xdrs;
- fhandle objp;
+xdr_fhandle (XDR *xdrs, fhandle objp)
{
+ register int32_t *buf;
- register long *buf;
+ if (!xdr_opaque (xdrs, objp, FHSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
+{
+ register int32_t *buf;
- if (!xdr_opaque(xdrs, objp, FHSIZE)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_fhstatus(xdrs, objp)
- XDR *xdrs;
- fhstatus *objp;
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
{
+ register int32_t *buf;
- register long *buf;
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fhstatus (XDR *xdrs, fhstatus *objp)
+{
+ register int32_t *buf;
- if (!xdr_u_int(xdrs, &objp->fhs_status)) {
- return (FALSE);
- }
+ if (!xdr_u_int (xdrs, &objp->fhs_status))
+ return FALSE;
switch (objp->fhs_status) {
case 0:
- if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
- return (FALSE);
- }
+ if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
+ return FALSE;
+ break;
+ default:
break;
}
- return (TRUE);
+ return TRUE;
}
bool_t
-xdr_dirpath(xdrs, objp)
- XDR *xdrs;
- dirpath *objp;
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
{
+ register int32_t *buf;
+
+ if (!xdr_fhandle3 (xdrs, &objp->fhandle))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
+ sizeof (int), (xdrproc_t) xdr_int))
+ return FALSE;
+ return TRUE;
+}
- register long *buf;
+bool_t
+xdr_mountres3 (XDR *xdrs, mountres3 *objp)
+{
+ register int32_t *buf;
- if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
+ return FALSE;
+ switch (objp->fhs_status) {
+ case MNT_OK:
+ if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
}
bool_t
-xdr_name(xdrs, objp)
- XDR *xdrs;
- name *objp;
+xdr_dirpath (XDR *xdrs, dirpath *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_string (xdrs, objp, MNTPATHLEN))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_mountlist(xdrs, objp)
- XDR *xdrs;
- mountlist *objp;
+xdr_name (XDR *xdrs, name *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), (xdrproc_t)xdr_mountbody)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_string (xdrs, objp, MNTNAMLEN))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_mountbody(xdrs, objp)
- XDR *xdrs;
- mountbody *objp;
+xdr_mountlist (XDR *xdrs, mountlist *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- if (!xdr_name(xdrs, &objp->ml_hostname)) {
- return (FALSE);
- }
- if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
- return (FALSE);
- }
- if (!xdr_mountlist(xdrs, &objp->ml_next)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_groups(xdrs, objp)
- XDR *xdrs;
- groups *objp;
+xdr_mountbody (XDR *xdrs, mountbody *objp)
{
+ register int32_t *buf;
+
+ if (!xdr_name (xdrs, &objp->ml_hostname))
+ return FALSE;
+ if (!xdr_dirpath (xdrs, &objp->ml_directory))
+ return FALSE;
+ if (!xdr_mountlist (xdrs, &objp->ml_next))
+ return FALSE;
+ return TRUE;
+}
- register long *buf;
+bool_t
+xdr_groups (XDR *xdrs, groups *objp)
+{
+ register int32_t *buf;
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), (xdrproc_t)xdr_groupnode)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_groupnode(xdrs, objp)
- XDR *xdrs;
- groupnode *objp;
+xdr_groupnode (XDR *xdrs, groupnode *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- if (!xdr_name(xdrs, &objp->gr_name)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->gr_next)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_name (xdrs, &objp->gr_name))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->gr_next))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_exports(xdrs, objp)
- XDR *xdrs;
- exports *objp;
+xdr_exports (XDR *xdrs, exports *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), (xdrproc_t)xdr_exportnode)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_exportnode(xdrs, objp)
- XDR *xdrs;
- exportnode *objp;
+xdr_exportnode (XDR *xdrs, exportnode *objp)
{
-
- register long *buf;
-
- if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->ex_groups)) {
- return (FALSE);
- }
- if (!xdr_exports(xdrs, &objp->ex_next)) {
- return (FALSE);
- }
- return (TRUE);
+ register int32_t *buf;
+
+ if (!xdr_dirpath (xdrs, &objp->ex_dir))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->ex_groups))
+ return FALSE;
+ if (!xdr_exports (xdrs, &objp->ex_next))
+ return FALSE;
+ return TRUE;
}
bool_t
-xdr_ppathcnf(xdrs, objp)
- XDR *xdrs;
- ppathcnf *objp;
+xdr_ppathcnf (XDR *xdrs, ppathcnf *objp)
{
+ register int32_t *buf;
- register long *buf;
-
- int i;
-
- if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_LONG(buf,objp->pc_link_max);
- IXDR_PUT_SHORT(buf,objp->pc_max_canon);
- IXDR_PUT_SHORT(buf,objp->pc_max_input);
- IXDR_PUT_SHORT(buf,objp->pc_name_max);
- IXDR_PUT_SHORT(buf,objp->pc_path_max);
- IXDR_PUT_SHORT(buf,objp->pc_pipe_buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+ int i;
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ /* On many machines XDR_INLINE returns a (long *) */
+ buf = (int32_t *) XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->pc_link_max);
+ IXDR_PUT_SHORT(buf, objp->pc_max_canon);
+ IXDR_PUT_SHORT(buf, objp->pc_max_input);
+ IXDR_PUT_SHORT(buf, objp->pc_name_max);
+ IXDR_PUT_SHORT(buf, objp->pc_path_max);
+ IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
+ }
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ buf = (int32_t *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- IXDR_PUT_SHORT(buf,*genp++);
- }
- };
- }
-
- return (TRUE);
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ } else {
+ {
+ register short *genp;
+
+ for (i = 0, genp = objp->pc_mask;
+ i < 2; ++i) {
+ IXDR_PUT_SHORT(buf, *genp++);
+ }
+ }
+ }
+ return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- objp->pc_link_max = IXDR_GET_LONG(buf);
- objp->pc_max_canon = IXDR_GET_SHORT(buf);
- objp->pc_max_input = IXDR_GET_SHORT(buf);
- objp->pc_name_max = IXDR_GET_SHORT(buf);
- objp->pc_path_max = IXDR_GET_SHORT(buf);
- objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+ buf = (int32_t *) XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+
+ } else {
+ objp->pc_link_max = IXDR_GET_LONG(buf);
+ objp->pc_max_canon = IXDR_GET_SHORT(buf);
+ objp->pc_max_input = IXDR_GET_SHORT(buf);
+ objp->pc_name_max = IXDR_GET_SHORT(buf);
+ objp->pc_path_max = IXDR_GET_SHORT(buf);
+ objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
+ }
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ buf = (int32_t *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- *genp++ = IXDR_GET_SHORT(buf);
- }
- };
- }
- return(TRUE);
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ } else {
+ {
+ register short *genp;
+
+ for (i = 0, genp = objp->pc_mask;
+ i < 2; ++i) {
+ *genp++ = IXDR_GET_SHORT(buf);
+ }
+ }
+ }
+ return TRUE;
}
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
- return (TRUE);
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ return TRUE;
}
diff --git a/mount/swapon.8 b/mount/swapon.8
index 74f61eea4..61cd3b375 100644
--- a/mount/swapon.8
+++ b/mount/swapon.8
@@ -111,9 +111,15 @@ flag is given.
You should not use
.B swapon
on a file with holes.
+Swap over NFS may not work.
.SH SEE ALSO
-.BR swapon "(2), " swapoff "(2), " fstab "(5), " init "(8), " mkswap (8),
-.BR rc "(8), " mount (8)
+.BR swapon (2),
+.BR swapoff (2),
+.BR fstab (5),
+.BR init (8),
+.BR mkswap (8),
+.BR rc (8),
+.BR mount (8)
.SH FILES
.I /dev/hd??
standard paging devices