diff options
author | Karel Zak | 2006-12-07 00:25:43 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:43 +0100 |
commit | 22853e4a82c6ef7b336527529acb94b14a0b0fd8 (patch) | |
tree | ee28e4598c8c449d7e811711d8ce8eb17caecfb6 /mount | |
parent | Imported from util-linux-2.10f tarball. (diff) | |
download | kernel-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/Makefile | 56 | ||||
-rw-r--r-- | mount/lomount.c | 553 | ||||
-rw-r--r-- | mount/losetup.c | 237 | ||||
-rw-r--r-- | mount/mount.8 | 30 | ||||
-rw-r--r-- | mount/mount.c | 436 | ||||
-rw-r--r-- | mount/mount_by_label.c | 198 | ||||
-rw-r--r-- | mount/mount_by_label.h | 1 | ||||
-rw-r--r-- | mount/mount_guess_fstype.c | 12 | ||||
-rw-r--r-- | mount/nfs_mount4.h | 53 | ||||
-rw-r--r-- | mount/nfs_mount4.h.sv (renamed from mount/nfs_mount3.h) | 22 | ||||
-rw-r--r-- | mount/nfsmount.c | 204 | ||||
-rw-r--r-- | mount/nfsmount.h | 325 | ||||
-rw-r--r-- | mount/nfsmount.x | 78 | ||||
-rw-r--r-- | mount/nfsmount_clnt.c | 281 | ||||
-rw-r--r-- | mount/nfsmount_xdr.c | 334 | ||||
-rw-r--r-- | mount/pivot_root.2 | 97 | ||||
-rw-r--r-- | mount/pivot_root.8 | 65 | ||||
-rw-r--r-- | mount/pivot_root.c | 24 | ||||
-rw-r--r-- | mount/realpath.c | 21 | ||||
-rw-r--r-- | mount/rpcsvc/nfsmount.h | 310 | ||||
-rw-r--r-- | mount/rpcsvc/nfsmount.x | 78 | ||||
-rw-r--r-- | mount/rpcsvc/nfsmount_clnt.c | 230 | ||||
-rw-r--r-- | mount/rpcsvc/nfsmount_xdr.c | 467 | ||||
-rw-r--r-- | mount/swapon.8 | 10 |
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 |