diff -urN util-linux-2.12i/mount/Makefile util-linux-2.12p/mount/Makefile --- util-linux-2.12i/mount/Makefile 2004-08-24 20:31:37.000000000 -0400 +++ util-linux-2.12p/mount/Makefile 2004-12-22 04:32:08.000000000 -0500 @@ -47,18 +47,19 @@ %.o: %.c $(COMPILE) $< -mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \ +mount: mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \ get_label_uuid.o mount_by_label.o mount_blkid.o mount_guess_fstype.o \ getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(LINK) $^ -o $@ $(BLKID_LIB) -umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \ - get_label_uuid.o mount_by_label.o mount_blkid.o version.o \ - $(LIB)/env.o $(LO_OBJS) +umount: umount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o \ + getusername.o get_label_uuid.o mount_by_label.o mount_blkid.o \ + version.o $(LIB)/env.o $(LO_OBJS) $(LINK) $^ -o $@ $(BLKID_LIB) -swapon: swapon.o version.o - $(LINK) $^ -o $@ +swapon: swapon.o version.o xmalloc.o \ + get_label_uuid.o mount_by_label.o mount_blkid.o + $(LINK) $^ -o $@ $(BLKID_LIB) main_losetup.o: lomount.c $(COMPILE) -DMAIN lomount.c -o $@ diff -urN util-linux-2.12i/mount/fstab.c util-linux-2.12p/mount/fstab.c --- util-linux-2.12i/mount/fstab.c 2004-11-04 14:25:17.000000000 -0500 +++ util-linux-2.12p/mount/fstab.c 2004-12-21 14:09:24.000000000 -0500 @@ -11,7 +11,8 @@ #include #include "mntent.h" #include "fstab.h" -#include "sundries.h" /* for xmalloc() etc */ +#include "sundries.h" +#include "xmalloc.h" #include "mount_blkid.h" #include "paths.h" #include "nls.h" @@ -105,7 +106,7 @@ discard_mntentchn(struct mntentchn *mc0) { struct mntentchn *mc, *mc1; - for (mc = mc0->nxt; mc != mc0; mc = mc1) { + for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) { mc1 = mc->nxt; my_free(mc->m.mnt_fsname); my_free(mc->m.mnt_dir); @@ -411,6 +412,15 @@ /* nothing, fcntl will fail anyway */ } +/* Remove lock file. */ +void +unlock_mtab (void) { + if (we_created_lockfile) { + unlink (MOUNTED_LOCK); + we_created_lockfile = 0; + } +} + /* Create the lock file. The lock file will be removed if we catch a signal or when we exit. */ /* The old code here used flock on a lock file /etc/mtab~ and deleted @@ -436,6 +446,8 @@ int tries = 3; char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; + at_die = unlock_mtab; + if (!signals_have_been_setup) { int sig = 0; struct sigaction sa; @@ -543,15 +555,6 @@ } } -/* Remove lock file. */ -void -unlock_mtab (void) { - if (we_created_lockfile) { - unlink (MOUNTED_LOCK); - we_created_lockfile = 0; - } -} - /* * Update the mtab. * Used by umount with null INSTEAD: remove the last DIR entry. diff -urN util-linux-2.12i/mount/get_label_uuid.c util-linux-2.12p/mount/get_label_uuid.c --- util-linux-2.12i/mount/get_label_uuid.c 2004-09-16 13:09:11.000000000 -0400 +++ util-linux-2.12p/mount/get_label_uuid.c 2004-12-21 13:55:39.000000000 -0500 @@ -1,6 +1,6 @@ #ifndef HAVE_BLKID /* - * Get label. Used by both mount and umount. + * Get label. Used by mount, umount and swapon. */ #include #include @@ -8,8 +8,10 @@ #include #include +#include "xmalloc.h" #include "linux_fs.h" #include "get_label_uuid.h" +#include "../disk-utils/swapheader.h" /* * See whether this device has (the magic of) a RAID superblock at the end. @@ -60,15 +62,48 @@ return rc; } +static void +store_uuid(char *udest, char *usrc) { + if (usrc) + memcpy(udest, usrc, 16); + else + memset(udest, 0, 16); +} + +static void +store_label(char **ldest, char *lsrc, int len) { + *ldest = xmalloc(len+1); + memset(*ldest, 0, len+1); + memcpy(*ldest, lsrc, len); +} + +static int +is_v1_swap_partition(int fd, char **label, char *uuid) { + int n = getpagesize(); + char *buf = xmalloc(n); + struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf; + + if (lseek(fd, 0, SEEK_SET) == 0 + && read(fd, buf, n) == n + && !strncmp(buf+n-10, "SWAPSPACE2", 10) + && p->version == 1) { + store_uuid(uuid, p->uuid); + store_label(label, p->volume_name, 16); + return 1; + } + return 0; +} + + /* * Get both label and uuid. - * For now, only ext2, ext3, xfs, ocfs, ocfs2, reiserfs are supported + * For now, only ext2, ext3, xfs, ocfs, ocfs2, reiserfs, swap are supported + * + * Return 0 on success. */ int get_label_uuid(const char *device, char **label, char *uuid) { int fd; - int rv = 1; - size_t namesize; struct ext2_super_block e2sb; struct xfs_super_block xfsb; struct jfs_super_block jfssb; @@ -76,47 +111,50 @@ struct ocfs_volume_label olbl; struct ocfs2_super_block osb; struct reiserfs_super_block reiserfssb; + int blksize; + int rv = 0; fd = open(device, O_RDONLY); if (fd < 0) - return rv; + return -1; /* If there is a RAID partition, or an error, ignore this partition */ if (is_raid_partition(fd)) { - close(fd); - return rv; + rv = 1; + goto done; } + if (is_v1_swap_partition(fd, label, uuid)) + goto done; + if (lseek(fd, 1024, SEEK_SET) == 1024 && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb) && (ext2magic(e2sb) == EXT2_SUPER_MAGIC)) { - memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid)); - namesize = sizeof(e2sb.s_volume_name); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, e2sb.s_volume_name, namesize); - rv = 0; + store_uuid(uuid, e2sb.s_uuid); + store_label(label, e2sb.s_volume_name, + sizeof(e2sb.s_volume_name)); + goto done; } - else if (lseek(fd, 0, SEEK_SET) == 0 + + if (lseek(fd, 0, SEEK_SET) == 0 && read(fd, (char *) &xfsb, sizeof(xfsb)) == sizeof(xfsb) && (strncmp(xfsb.s_magic, XFS_SUPER_MAGIC, 4) == 0)) { - memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid)); - namesize = sizeof(xfsb.s_fname); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, xfsb.s_fname, namesize); - rv = 0; + store_uuid(uuid, xfsb.s_uuid); + store_label(label, xfsb.s_fname, sizeof(xfsb.s_fname)); + goto done; } - else if (lseek(fd, 0, SEEK_SET) == 0 + + if (lseek(fd, 0, SEEK_SET) == 0 && read(fd, (char *) &ovh, sizeof(ovh)) == sizeof(ovh) && (strncmp(ovh.signature, OCFS_MAGIC, sizeof(OCFS_MAGIC)) == 0) && (lseek(fd, 512, SEEK_SET) == 512) && read(fd, (char *) &olbl, sizeof(olbl)) == sizeof(olbl)) { - uuid[0] = '\0'; - namesize = ocfslabellen(olbl); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, olbl.label, namesize); - rv = 0; + store_uuid(uuid, NULL); + store_label(label, olbl.label, ocfslabellen(olbl)); + goto done; } - else if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) == JFS_SUPER1_OFF + + if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) == JFS_SUPER1_OFF && read(fd, (char *) &jfssb, sizeof(jfssb)) == sizeof(jfssb) && (strncmp(jfssb.s_magic, JFS_MAGIC, 4) == 0)) { @@ -136,55 +174,47 @@ if (assemble4le(jfssb.s_version) == 1 && strncmp(jfssb.s_label, jfssb.s_fpack, 11) != 0) { - memset(uuid, 0, 16); - namesize = sizeof(jfssb.s_fpack); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, jfssb.s_fpack, namesize); + store_uuid(uuid, NULL); + store_label(label, jfssb.s_fpack, + sizeof(jfssb.s_fpack)); } else { - memcpy(uuid, jfssb.s_uuid, sizeof(jfssb.s_uuid)); - namesize = sizeof(jfssb.s_label); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, jfssb.s_label, namesize); + store_uuid(uuid, jfssb.s_uuid); + store_label(label, jfssb.s_label, + sizeof(jfssb.s_label)); } - rv = 0; + goto done; } - else if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) - == REISERFS_DISK_OFFSET_IN_BYTES + + if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) + == REISERFS_DISK_OFFSET_IN_BYTES && read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) - == sizeof(reiserfssb) - /* Only 3.6.x format supers have labels or uuids. - Label and UUID can be set by reiserfstune -l/-u. */ + == sizeof(reiserfssb) + /* Only 3.6.x format supers have labels or uuids. + Label and UUID can be set by reiserfstune -l/-u. */ && reiserfs_magic_version(reiserfssb.s_magic) > 1) { - namesize = sizeof (reiserfssb.s_label); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, reiserfssb.s_label, namesize); - memcpy(uuid, reiserfssb.s_uuid, sizeof (reiserfssb.s_uuid)); - rv = 0; - } - else { - int blksize, blkoff; - - for (blksize = OCFS2_MIN_BLOCKSIZE; - blksize <= OCFS2_MAX_BLOCKSIZE; - blksize <<= 1) { - blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO; - if (lseek(fd, blkoff, SEEK_SET) == blkoff - && read(fd, (char *) &osb, sizeof(osb)) - == sizeof(osb) - && strncmp(osb.signature, - OCFS2_SUPER_BLOCK_SIGNATURE, - sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) - == 0) { - memcpy(uuid, osb.s_uuid, sizeof(osb.s_uuid)); - namesize = sizeof(osb.s_label); - if ((*label = calloc(namesize, 1)) != NULL) - memcpy(*label, osb.s_label, namesize); - rv = 0; - break; - } + store_uuid(uuid, reiserfssb.s_uuid); + store_label(label, reiserfssb.s_label, + sizeof(reiserfssb.s_label)); + goto done; + } + + for (blksize = OCFS2_MIN_BLOCKSIZE; + blksize <= OCFS2_MAX_BLOCKSIZE; + blksize <<= 1) { + int blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO; + + if (lseek(fd, blkoff, SEEK_SET) == blkoff + && read(fd, (char *) &osb, sizeof(osb)) == sizeof(osb) + && strncmp(osb.signature, + OCFS2_SUPER_BLOCK_SIGNATURE, + sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) { + store_uuid(uuid, osb.s_uuid); + store_label(label, osb.s_label, sizeof(osb.s_label)); + goto done; } } - + rv = 1; + done: close(fd); return rv; } diff -urN util-linux-2.12i/mount/lomount.c util-linux-2.12p/mount/lomount.c --- util-linux-2.12i/mount/lomount.c 2004-09-22 14:26:02.000000000 -0400 +++ util-linux-2.12p/mount/lomount.c 2004-12-20 17:11:04.000000000 -0500 @@ -1,17 +1,4 @@ -/* Taken from Ted's losetup.c - Mitch */ -/* Added vfs mount options - aeb - 960223 */ -/* Removed lomount - aeb - 960224 */ - -/* - * 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support - * 1999-03-21 Arnaldo Carvalho de Melo - * - fixed strerr(errno) in gettext calls - * 2000-09-24 Marc Mutz - * - added -p option to pass passphrases via fd's to losetup/mount. - * Used for encryption in non-interactive environments. - * The idea behind xgetpass() is stolen from GnuPG, v.1.0.3. - */ +/* Originally from Ted's losetup.c */ #define LOOPMAJOR 7 @@ -37,6 +24,7 @@ #include "nls.h" extern int verbose; +extern char *progname; extern char *xstrdup (const char *s); /* not: #include "sundries.h" */ extern void error (const char *fmt, ...); /* idem */ @@ -160,7 +148,7 @@ So, we just try /dev/loop[0-7]. */ char dev[20]; char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" }; - int i, j, fd, somedev = 0, someloop = 0; + int i, j, fd, somedev = 0, someloop = 0, permission = 0; struct stat statbuf; struct loop_info loopinfo; @@ -178,7 +166,9 @@ return xstrdup(dev);/* probably free */ } close (fd); - } + } else if (errno == EACCES) + permission++; + continue;/* continue trying as long as devices exist */ } break; @@ -186,15 +176,17 @@ } if (!somedev) - error(_("mount: could not find any device /dev/loop#")); - else if (!someloop) { + error(_("%s: could not find any device /dev/loop#"), progname); + else if (!someloop && permission) + error(_("%s: no permission to look at /dev/loop#"), progname); + else if (!someloop) error(_( - "mount: Could not find any loop device. Maybe this kernel " + "%s: Could not find any loop device. Maybe this kernel " "does not know\n" " about the loop device? (If so, recompile or " - "`modprobe loop'.)")); - } else - error(_("mount: could not find any free loop device")); + "`modprobe loop'.)"), progname); + else + error(_("%s: could not find any free loop device"), progname); return 0; } @@ -226,15 +218,16 @@ break; } } - if (read(pfd, pass+i, 1) != 1 || pass[i] == '\n') + if (read(pfd, pass+i, 1) != 1 || + pass[i] == '\n' || pass[i] == 0) break; } + if (pass == NULL) return ""; - else { - pass[i] = 0; - return pass; - } + + pass[i] = 0; + return pass; } static int @@ -302,13 +295,11 @@ break; case LO_CRYPT_XOR: pass = getpass(_("Password: ")); - xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE); - memset(pass, 0, strlen(pass)); - loopinfo64.lo_encrypt_key_size = - strlen(loopinfo64.lo_encrypt_key); - break; + goto gotpass; default: pass = xgetpass(pfd, _("Password: ")); + gotpass: + memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE); xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE); memset(pass, 0, strlen(pass)); loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE; @@ -408,15 +399,16 @@ #include int verbose = 0; -static char *progname; +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); + %s loop_device # give info\n\ + %s -d loop_device # delete\n\ + %s -f # find unused\n\ + %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"), + progname, progname, progname, progname); exit(1); } @@ -449,8 +441,8 @@ int main(int argc, char **argv) { - char *offset, *encryption, *passfd; - int delete, c; + char *p, *offset, *encryption, *passfd, *device, *file; + int delete, find, c; int res = 0; int ro = 0; int pfd = -1; @@ -460,10 +452,15 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - delete = off = 0; + delete = find = 0; + off = 0; offset = encryption = passfd = NULL; + progname = argv[0]; - while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) { + if ((p = strrchr(progname, '/')) != NULL) + progname = p+1; + + while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) { switch (c) { case 'd': delete = 1; @@ -472,6 +469,9 @@ case 'e': encryption = optarg; break; + case 'f': + find = 1; + break; case 'o': offset = optarg; break; @@ -485,22 +485,49 @@ usage(); } } - if (argc == 1) usage(); - if ((delete && (argc != optind+1 || encryption || offset)) || - (!delete && (argc < optind+1 || argc > optind+2))) + + if (argc == 1) { usage(); - if (argc == optind+1) { - if (delete) - res = del_loop(argv[optind]); - else - res = show_loop(argv[optind]); + } else if (delete) { + if (argc != optind+1 || encryption || offset || find) + usage(); + } else if (find) { + if (argc < optind || argc > optind+1) + usage(); + } else { + if (argc < optind+1 || argc > optind+2) + usage(); + } + + if (find) { + device = find_unused_loop_device(); + if (device == NULL) + return -1; + if (verbose) + printf("Loop device is %s\n", device); + if (argc == optind) { + printf("%s\n", device); + return 0; + } + file = argv[optind]; } else { + device = argv[optind]; + if (argc == optind+1) + file = NULL; + else + file = argv[optind+1]; + } + + if (delete) + res = del_loop(device); + else if (file == NULL) + res = show_loop(device); + else { if (offset && sscanf(offset, "%llu", &off) != 1) usage(); if (passfd && sscanf(passfd, "%d", &pfd) != 1) usage(); - res = set_loop(argv[optind], argv[optind+1], off, - encryption, pfd, &ro); + res = set_loop(device, file, off, encryption, pfd, &ro); } return res; } diff -urN util-linux-2.12i/mount/losetup.8 util-linux-2.12p/mount/losetup.8 --- util-linux-2.12i/mount/losetup.8 2003-07-15 19:06:37.000000000 -0400 +++ util-linux-2.12p/mount/losetup.8 2004-12-04 20:35:54.000000000 -0500 @@ -3,24 +3,40 @@ losetup \- set up and control loop devices .SH SYNOPSIS .ad l +Get info: +.sp +.in +5 .B losetup -[ -.RB [ \-e | \-E ] -.I encryption -] [ -.B \-o -.I offset -] [ -.B \-p -.I pfd -] -.I loop_device file -.br -.B losetup -[ -.B \-d -] .I loop_device +.sp +.in -5 +Delete loop: +.sp +.in +5 +.B "losetup \-d" +.I loop_device +.sp +.in -5 +Print name of first unused loop device: +.sp +.in +5 +.B "losetup \-f" +.sp +.in -5 +Setup loop device: +.sp +.in +5 +.B losetup +.RB [{\-e | \-E} +.IR encryption ] +.RB [ \-o +.IR offset ] +.RB [ \-p +.IR pfd ] +.in +8 +.RB { \-f | \fIloop_device\fP } +.I file +.in -13 .ad b .SH DESCRIPTION .B losetup @@ -56,6 +72,10 @@ Enable data encryption with specified number. .IP "\fB\-e \fIencryption_name\fP" Enable data encryption with specified name. +.IP "\fB\-f\fP" +Find the first unused loop device. If a +.I file +argument is present, use this device. Otherwise, print its name. .IP "\fB\-o \fIoffset\fP" The data start is moved \fIoffset\fP bytes into the specified file or device. diff -urN util-linux-2.12i/mount/mount.8 util-linux-2.12p/mount/mount.8 --- util-linux-2.12i/mount/mount.8 2004-09-19 16:00:49.000000000 -0400 +++ util-linux-2.12p/mount/mount.8 2004-12-19 17:30:14.000000000 -0500 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1996 Andries Brouwer +.\" Copyright (c) 1996-2004 Andries Brouwer .\" .\" This page is somewhat derived from a page that was .\" (c) 1980, 1989, 1991 The Regents of the University of California @@ -39,7 +39,7 @@ .\" 010725, Nikita Danilov : reiserfs options .\" 011124, Karl Eichwalder : tmpfs options .\" -.TH MOUNT 8 "14 September 1997" "Linux 2.0" "Linux Programmer's Manual" +.TH MOUNT 8 "2004-12-16" "Linux 2.6" "Linux Programmer's Manual" .SH NAME mount \- mount a file system .SH SYNOPSIS @@ -119,7 +119,10 @@ .B "mount --rbind olddir newdir" .RE .\" available since Linux 2.4.11. -The mount options are not changed. + +Note that the filesystem mount options will remain the same as those +on the original mount point, and cannot be changed by passing the -o +option along with --bind/--rbind. Since Linux 2.5.1 it is possible to atomically move a mounted tree to another place. The call is @@ -180,7 +183,7 @@ .I fstab contains the .B user -option on a line, then anybody can mount the corresponding system. +option on a line, anybody can mount the corresponding system. .LP Thus, given a line .RS @@ -216,6 +219,10 @@ of the special file. This may be useful e.g. for .I /dev/fd if a login script makes the console user owner of this device. +The +.B group +option is similar, with the restriction that the user must be +member of the group of the special file. The programs .B mount @@ -310,7 +317,9 @@ One can set such a label for ext2 or ext3 using the .BR e2label (8) utility, or for XFS using -.BR xfs_admin (8). +.BR xfs_admin (8), +or for reiserfs using +.BR reiserfstune (8). .TP .B \-n Mount without writing in @@ -354,7 +363,7 @@ The argument following the .B \-t is used to indicate the file system type. The file system types which are -currently supported are: +currently supported include: .IR adfs , .IR affs , .IR autofs , @@ -551,6 +560,18 @@ .B exec Permit execution of binaries. .TP +.B group +Allow an ordinary (i.e., non-root) user to mount the file system if one +of his groups matches the group of the device. +This option implies the options +.BR nosuid " and " nodev +(unless overridden by subsequent options, as in the option line +.BR group,dev,suid ). +.TP +.B mand +Allow mandatory locks on this filesystem. See +.BR fcntl (2). +.TP .B _netdev The filesystem resides on a device that requires network access (used to prevent the system from attempting to mount these filesystems @@ -574,6 +595,9 @@ (Until recently it was possible to run binaries anyway using a command like /lib/ld*.so /mnt/binary. This trick fails since Linux 2.4.25 / 2.6.0.) .TP +.B nomand +Do not allow mandatory locks on this filesystem. +.TP .B nosuid Do not allow set-user-identifier or set-group-identifier bits to take effect. (This seems safe, but is in fact rather unsafe if you have @@ -583,6 +607,14 @@ Forbid an ordinary (i.e., non-root) user to mount the file system. This is the default. .TP +.B owner +Allow an ordinary (i.e., non-root) user to mount the file system if he +is the owner of the device. +This option implies the options +.BR nosuid " and " nodev +(unless overridden by subsequent options, as in the option line +.BR owner,dev,suid ). +.TP .B remount Attempt to remount an already-mounted file system. This is commonly used to change the mount flags for a file system, especially to make a @@ -635,6 +667,11 @@ We sort them by file system. They all follow the .B \-o flag. + +What options are supported depends a bit on the running kernel. +More info may be found in the kernel source subdirectory +.IR Documentation/filesystems . + .SH "Mount options for adfs" .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP @@ -738,6 +775,10 @@ is determined by the filesystem superblock. Set them with .BR tune2fs (8). .TP +.BR acl " / " noacl +Support POSIX Access Control Lists (or not). +.\" requires CONFIG_EXT2_FS_POSIX_ACL +.TP .BR bsddf " / " minixdf Set the behaviour for the .I statfs @@ -806,6 +847,9 @@ from the parent directory, and also gets the setgid bit set if it is a directory itself. .TP +.BR grpquota " / " noquota " / " quota " / " usrquota +These options are accepted but ignored. +.TP .BR nobh Do not attach buffer_heads to file pagecache. (Since 2.5.49.) .TP @@ -844,17 +888,10 @@ .BR user_xattr " / " nouser_xattr Support "user." extended attributes (or not). .\" requires CONFIG_EXT2_FS_XATTR -.TP -.BR acl " / " noacl -Support POSIX Access Control Lists (or not). -.\" requires CONFIG_EXT2_FS_POSIX_ACL -.TP -.BR grpquota " / " noquota " / " quota " / " usrquota -These options are accepted but ignored. .SH "Mount options for ext3" -The `ext3' file system is version of the ext2 file system which has been +The `ext3' file system is a version of the ext2 file system which has been enhanced with journalling. It supports the same options as ext2 as well as the following additions: .\" .TP @@ -876,6 +913,10 @@ .TP .BR data=journal " / " data=ordered " / " data=writeback Specifies the journalling mode for file data. Metadata is always journaled. +To use modes other than +.B ordered +on the root file system, pass the mode to the kernel as boot parameter, e.g. +.IR rootflags=data=journal . .RS .TP .B journal @@ -892,6 +933,12 @@ This is rumoured to be the highest-throughput option. It guarantees internal file system integrity, however it can allow old data to appear in files after a crash and journal recovery. +.RE +.TP +.BI commit= nrsec +Sync all data and metadata every +.I nrsec +seconds. The default value is 5 seconds. Zero means default. .SH "Mount options for fat" (Note: @@ -907,8 +954,8 @@ Set blocksize (default 512). .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP -Set the owner and group of all files. (Default: the uid and gid -of the current process.) +Set the owner and group of all files. +(Default: the uid and gid of the current process.) .TP .BI umask= value Set the umask (the bitmask of the permissions that are @@ -919,12 +966,14 @@ .BI dmask= value Set the umask applied to directories only. The default is the umask of the current process. -The value is given in octal. Present since 2.5.43. +The value is given in octal. +.\" Present since Linux 2.5.43. .TP .BI fmask= value Set the umask applied to regular files only. The default is the umask of the current process. -The value is given in octal. Present since 2.5.43. +The value is given in octal. +.\" Present since Linux 2.5.43. .TP .BI check= value Three different levels of pickyness can be chosen: @@ -1017,6 +1066,33 @@ Various misguided attempts to force Unix or DOS conventions onto a FAT file system. +.SH "Mount options for hfs" +.TP +.BI creator= cccc ", type=" cccc +Set the creator/type values as shown by the MacOS finder +used for creating new files. Default values: '????'. +.TP +.BI uid= n ", gid=" n +Set the owner and group of all files. +(Default: the uid and gid of the current process.) +.TP +.BI dir_umask= n ", file_umask=" n ", umask=" n +Set the umask used for all directories, all regular files, or all +files and directories. Defaults to the umask of the current process. +.TP +.BI session= n +Select the CDROM session to mount. +Defaults to leaving that decision to the CDROM driver. +This option will fail with anything but a CDROM as underlying device. +.TP +.BI part= n +Select partition number n from the device. +Only makes sense for CDROMS. +Defaults to not parsing the partition table at all. +.TP +.B quiet +Don't complain about invalid mount options. + .SH "Mount options for hpfs" .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP @@ -1293,7 +1369,13 @@ .BI iocharset= name Character set to use when returning file names. Unlike VFAT, NTFS suppresses names that contain -unconvertible characters. +unconvertible characters. Deprecated. +.\" since 2.5.11 +.TP +.BI nls= name +New name for the option earlier called +.IR iocharset . +.\" since 2.5.11 .TP .BR utf8 Use UTF-8 for converting file names. @@ -1348,7 +1430,7 @@ .B tea A Davis-Meyer function implemented by Jeremy Fitzhardinge. It uses hash permuting bits in the name. It gets high randomness -and, therefore, low probability of hash collisions at come CPU cost. +and, therefore, low probability of hash collisions at some CPU cost. This may be used if EHASHCOLLISION errors are experienced with the r5 hash. .TP .B r5 @@ -1435,7 +1517,7 @@ for Ki, Mi, Gi (binary kilo, mega and giga) and can be changed on remount. .TP .BI size= nbytes -Override default size of the filesystem. +Override default maximum size of the filesystem. The size is given in bytes, and rounded down to entire pages. The default is half of the memory. .TP @@ -1470,14 +1552,14 @@ .B undelete Show deleted files in lists. .TP -.B strict -Set strict conformance (unused). -.TP -.B utf8 -(unused). +.B nostrict +Unset strict conformance. +.\" .TP +.\" .B utf8 +.\" (unused). .TP .B iocharset -(unused). +Set the NLS character set. .TP .B bs= Set the block size. (May not work unless 2048.) @@ -1701,6 +1783,9 @@ .B norecovery must be mounted read-only or the mount will fail. .TP +.B nouuid +Ignore the filesystem uuid. This avoids errors for duplicate uuids. +.TP .B osyncisdsync Make writes to files opened with the O_SYNC flag set behave as if the O_DSYNC flag had been used instead. @@ -1755,10 +1840,14 @@ .IR /tmp/fdimage , and then mount this device on .IR /mnt . + This type of mount knows about three options, namely .BR loop ", " offset " and " encryption , that are really options to -.BR losetup (8). +.BR \%losetup (8). +(These options can be used in addition to those specific +to the filesystem type.) + If no explicit loop device is mentioned (but just an option `\fB\-o loop\fP' is given), then .B mount @@ -1808,17 +1897,22 @@ some mount succeeded .SH FILES +.TP 18n .I /etc/fstab file system table -.br +.TP .I /etc/mtab table of mounted file systems -.br +.TP .I /etc/mtab~ lock file -.br +.TP .I /etc/mtab.tmp temporary file +.TP +.I /etc/filesystems +a list of filesystem types to try + .SH "SEE ALSO" .BR mount (2), .BR umount (2), @@ -1857,6 +1951,11 @@ .B umask for the .IR fatfs ). +.PP +Mount by label or uuid will work only if your devices have the names listed in +.IR /proc/partitions . +In particular, it may well fail if the kernel was compiled with devfs +but devfs is not mounted. .SH HISTORY A .B mount diff -urN util-linux-2.12i/mount/mount.c util-linux-2.12p/mount/mount.c --- util-linux-2.12i/mount/mount.c 2004-10-13 16:54:39.000000000 -0400 +++ util-linux-2.12p/mount/mount.c 2004-12-21 17:00:36.000000000 -0500 @@ -24,6 +24,7 @@ #include "mount_blkid.h" #include "mount_constants.h" #include "sundries.h" +#include "xmalloc.h" #include "mntent.h" #include "fstab.h" #include "lomount.h" @@ -96,6 +97,7 @@ #define MS_USERS 0x40000000 #define MS_USER 0x20000000 #define MS_OWNER 0x10000000 +#define MS_GROUP 0x08000000 #define MS_COMMENT 0x00020000 #define MS_LOOP 0x00010000 @@ -135,6 +137,8 @@ { "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */ { "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */ { "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */ + { "group", 0, 0, MS_GROUP }, /* Let the group of the device mount */ + { "nogroup", 0, 1, MS_GROUP }, /* Device group has no special privs */ { "_netdev", 0, 0, MS_COMMENT}, /* Device requires network */ { "comment", 0, 0, MS_COMMENT}, /* fstab comment only (kudzu,_netdev)*/ @@ -251,7 +255,7 @@ * For the options uid= and gid= replace user or group name by its value. */ static inline void -parse_opt (const char *opt, int *mask, char *extra_opts) { +parse_opt(const char *opt, int *mask, char *extra_opts, int len) { const struct opt_map *om; for (om = opt_map; om->opt != NULL; om++) @@ -263,7 +267,8 @@ if ((om->mask == MS_USER || om->mask == MS_USERS) && !om->inv) *mask |= MS_SECURE; - if ((om->mask == MS_OWNER) && !om->inv) + if ((om->mask == MS_OWNER || om->mask == MS_GROUP) + && !om->inv) *mask |= MS_OWNERSECURE; #ifdef MS_SILENT if (om->mask == MS_SILENT && om->inv) { @@ -274,7 +279,9 @@ return; } - if (*extra_opts) + len -= strlen(extra_opts); + + if (*extra_opts && --len > 0) strcat(extra_opts, ","); /* convert nonnumeric ids to numeric */ @@ -284,7 +291,8 @@ if (pw) { sprintf(uidbuf, "uid=%d", pw->pw_uid); - strcat(extra_opts, uidbuf); + if ((len -= strlen(uidbuf)) > 0) + strcat(extra_opts, uidbuf); return; } } @@ -294,12 +302,14 @@ if (gr) { sprintf(gidbuf, "gid=%d", gr->gr_gid); - strcat(extra_opts, gidbuf); + if ((len -= strlen(gidbuf)) > 0) + strcat(extra_opts, gidbuf); return; } } - strcat(extra_opts, opt); + if ((len -= strlen(opt)) > 0) + strcat(extra_opts, opt); } /* Take -o options list and compute 4th and 5th args to mount(2). flags @@ -314,13 +324,14 @@ if (options != NULL) { char *opts = xstrdup(options); char *opt; + int len = strlen(opts) + 20; - *extra_opts = xmalloc (strlen (opts) + 1); + *extra_opts = xmalloc(len); **extra_opts = '\0'; - for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ",")) - if (!parse_string_opt (opt)) - parse_opt (opt, flags, *extra_opts); + for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ",")) + if (!parse_string_opt(opt)) + parse_opt(opt, flags, *extra_opts, len); free(opts); } @@ -507,20 +518,47 @@ static void suid_check(const char *spec, const 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(spec, "/dev/", 5)) { - struct stat sb; + /* + * MS_OWNER: 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. + * MS_GROUP: Allow members of device group to mount. (Martin Dickopp) + */ + if (*flags & (MS_OWNER | MS_GROUP)) { + struct stat sb; + + if (!strncmp(spec, "/dev/", 5) && stat(spec, &sb) == 0) { - if (!stat(spec, &sb)) { + if (*flags & MS_OWNER) { if (getuid() == sb.st_uid) *flags |= MS_USER; } + + if (*flags & MS_GROUP) { + if (getgid() == sb.st_gid) + *flags |= MS_USER; + else { + int n = getgroups(0, NULL); + + if (n > 0) { + gid_t *groups = xmalloc(n * sizeof(*groups)); + if (getgroups(n, groups) == n) { + int i; + for (i = 0; i < n; i++) { + if (groups[i] == sb.st_gid) { + *flags |= MS_USER; + break; + } + } + } + free(groups); + } + } + } } } + /* James Kehl came with a similar patch: allow an arbitrary user to mount when he is the owner of the mount-point and has write-access to the device. @@ -537,8 +575,7 @@ *user = getusername(); } - if (*flags & MS_OWNER) - *flags &= ~MS_OWNER; + *flags &= ~(MS_OWNER | MS_GROUP); } static int @@ -927,21 +964,23 @@ error (_("mount: %s not mounted already, or bad option"), node); } else { error (_("mount: wrong fs type, bad option, bad superblock on %s,\n" - " or too many mounted file systems"), + " missing codepage or other error"), spec); if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode) && (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) { if (ioctl(fd, BLKGETSIZE, &size) == 0) { - if (size == 0) { + if (size == 0 && !loop) { warned++; - error (" (could this be the IDE device where you in fact use\n" - " ide-scsi so that sr0 or sda or so is needed?)"); + error(_( + " (could this be the IDE device where you in fact use\n" + " ide-scsi so that sr0 or sda or so is needed?)")); } if (size && size <= 2) { warned++; - error (" (aren't you trying to mount an extended partition,\n" - " instead of some logical partition inside?)"); + error(_( + " (aren't you trying to mount an extended partition,\n" + " instead of some logical partition inside?)")); } close(fd); } @@ -956,6 +995,9 @@ } #endif } + error(_( + " In some cases useful info is found in syslog - try\n" + " dmesg | tail or so\n")); } break; } @@ -1025,7 +1067,7 @@ types = types0; } if (opts) { - char *opts2 = realloc(xstrdup(opts), strlen(opts)+4); + char *opts2 = xrealloc(xstrdup(opts), strlen(opts)+4); strcat(opts2, ",ro"); my_free(opts1); opts = opts1 = opts2; @@ -1111,61 +1153,63 @@ static int mount_one (const char *spec, const char *node, const char *types, const char *opts, char *cmdlineopts, int freq, int pass) { - int status, status2; - const char *nspec; + int status, status2; + const char *nspec; - /* Substitute values in opts, if required */ - opts = usersubst(opts); + /* Substitute values in opts, if required */ + opts = usersubst(opts); - /* Merge the fstab and command line options. */ - if (opts == NULL) - opts = cmdlineopts; - else if (cmdlineopts != NULL) - opts = xstrconcat3(opts, ",", cmdlineopts); - - /* Handle possible LABEL= and UUID= forms of spec */ - nspec = mount_get_devname_for_mounting(spec); - if (nspec) - spec = nspec; - - if (types == NULL && !mounttype && !is_existing_file(spec)) { - if (strchr (spec, ':') != NULL) { - types = "nfs"; - if (verbose) - printf(_("mount: no type was given - " - "I'll assume nfs because of the colon\n")); - } else if(!strncmp(spec, "//", 2)) { - types = "smbfs"; - if (verbose) - printf(_("mount: no type was given - " - "I'll assume smbfs because of the // prefix\n")); - } - } - - /* - * Try to mount the file system. When the exit status is EX_BG, - * we will retry in the background. Otherwise, we're done. - */ - status = try_mount_one (spec, node, types, opts, freq, pass, 0, 0); - if (status != EX_BG) - return status; + /* Merge the fstab and command line options. */ + if (opts == NULL) + opts = cmdlineopts; + else if (cmdlineopts != NULL) + opts = xstrconcat3(opts, ",", cmdlineopts); + + /* Handle possible LABEL= and UUID= forms of spec */ + nspec = mount_get_devname_for_mounting(spec); + if (nspec) + spec = nspec; + + if (types == NULL && !mounttype && !is_existing_file(spec)) { + if (strchr (spec, ':') != NULL) { + types = "nfs"; + if (verbose) + printf(_("mount: no type was given - " + "I'll assume nfs because of " + "the colon\n")); + } else if(!strncmp(spec, "//", 2)) { + types = "smbfs"; + if (verbose) + printf(_("mount: no type was given - " + "I'll assume smbfs because of " + "the // prefix\n")); + } + } - /* - * Retry in the background. - */ - printf (_("mount: backgrounding \"%s\"\n"), spec); - fflush( stdout ); /* prevent duplicate output */ - if (fork() > 0) - return 0; /* parent returns "success" */ - spec = xstrdup(spec); /* arguments will be destroyed */ - node = xstrdup(node); /* by set_proc_name() */ - types = xstrdup(types); - opts = xstrdup(opts); - set_proc_name (spec); /* make a nice "ps" listing */ - status2 = try_mount_one (spec, node, types, opts, freq, pass, 1, 0); - if (verbose && status2) - printf (_("mount: giving up \"%s\"\n"), spec); - exit (0); /* child stops here */ + /* + * Try to mount the file system. When the exit status is EX_BG, + * we will retry in the background. Otherwise, we're done. + */ + status = try_mount_one (spec, node, types, opts, freq, pass, 0, 0); + if (status != EX_BG) + return status; + + /* + * Retry in the background. + */ + printf (_("mount: backgrounding \"%s\"\n"), spec); + fflush( stdout ); /* prevent duplicate output */ + if (fork() > 0) + return 0; /* parent returns "success" */ + spec = xstrdup(spec); /* arguments will be destroyed */ + node = xstrdup(node); /* by set_proc_name() */ + types = xstrdup(types); + opts = xstrdup(opts); + set_proc_name (spec); /* make a nice "ps" listing */ + status2 = try_mount_one (spec, node, types, opts, freq, pass, 1, 0); + if (verbose && status2) + printf (_("mount: giving up \"%s\"\n"), spec); + exit (0); /* child stops here */ } /* Check if an fsname/dir pair was already in the old mtab. */ @@ -1177,6 +1221,8 @@ /* Handle possible UUID= and LABEL= in spec */ spec0 = mount_get_devname(spec0); + if (!spec0) + return ret; spec = canonicalize(spec0); node = canonicalize(node0); @@ -1189,8 +1235,8 @@ break; } - free(spec); - free(node); + my_free(spec); + my_free(node); return ret; } @@ -1407,14 +1453,17 @@ exit (n); } +char *progname; + int -main (int argc, char *argv[]) { +main(int argc, char *argv[]) { int c, result = 0, specseen; char *options = NULL, *test_opts = NULL, *node; const char *spec; char *volumelabel = NULL; char *uuid = NULL; char *types = NULL; + char *p; struct mntentchn *mc; int fd; @@ -1423,7 +1472,11 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - umask(033); + progname = argv[0]; + if ((p = strrchr(progname, '/')) != NULL) + progname = p+1; + + umask(022); /* People report that a mount called from init without console writes error messages to /etc/mtab diff -urN util-linux-2.12i/mount/mount_blkid.c util-linux-2.12p/mount/mount_blkid.c --- util-linux-2.12i/mount/mount_blkid.c 2004-04-13 16:00:13.000000000 -0400 +++ util-linux-2.12p/mount/mount_blkid.c 2004-12-22 04:54:41.000000000 -0500 @@ -57,7 +57,7 @@ const char * mount_get_volume_label_by_spec(const char *spec) { - return strdup(get_volume_label_by_spec(spec)); + return xstrdup(get_volume_label_by_spec(spec)); } const char * @@ -74,6 +74,8 @@ return get_spec_by_uuid(uuid); } +extern char *progname; + const char * mount_get_devname_by_label(const char *volumelabel) { const char *spec, *spec2; @@ -82,9 +84,8 @@ spec2 = second_occurrence_of_vol_label(volumelabel); if (spec2) die (EX_FAIL, - _("mount: the label %s occurs on " - "both %s and %s - not mounted\n"), - volumelabel, spec, spec2); + _("%s: error: the label %s occurs on both %s and %s\n"), + progname, volumelabel, spec, spec2); return spec; } diff -urN util-linux-2.12i/mount/mount_by_label.c util-linux-2.12p/mount/mount_by_label.c --- util-linux-2.12i/mount/mount_by_label.c 2004-04-13 15:41:28.000000000 -0400 +++ util-linux-2.12p/mount/mount_by_label.c 2004-12-21 18:15:33.000000000 -0500 @@ -40,6 +40,8 @@ #define EVMS_VOLUME_NAME_SIZE 127 #define PROC_EVMS_VOLUMES "/proc/evms/volumes" +extern char *progname; + static struct uuidCache_s { struct uuidCache_s *next; char uuid[16]; @@ -82,7 +84,7 @@ sprintf(buffer, "%s/%s/LVs", VG_DIR, vg_iter->d_name); lv_list = opendir(buffer); if (lv_list == NULL) { - perror("mount (init_lvm)"); + perror("uuidcache_init_lvm"); continue; } seekdir(lv_list, 2); @@ -94,7 +96,7 @@ sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR, vg_iter->d_name, lv_iter->d_name); if (!get_label_uuid(lvm_device, &label, uuid)) - uuidcache_addentry(strdup(lvm_device), + uuidcache_addentry(xstrdup(lvm_device), label, uuid); } closedir(lv_list); @@ -117,7 +119,7 @@ while (fgets(line, sizeof(line), procvol)) { if (sscanf(line, "%*d %*d %*d %*s %*s %[^\n]", volname) == 1) { if (!get_label_uuid(volname, &label, uuid)) - uuidcache_addentry(strdup(volname), label, uuid); + uuidcache_addentry(xstrdup(volname), label, uuid); } } @@ -187,9 +189,9 @@ if (!procpt) { static int warn = 0; if (!warn++) - error (_("mount: could not open %s, so UUID and LABEL " + error (_("%s: could not open %s, so UUID and LABEL " "conversion cannot be done.\n"), - PROC_PARTITIONS); + progname, PROC_PARTITIONS); return; } #if 0 @@ -211,6 +213,9 @@ fseek(procpt, 0, SEEK_SET); while (fgets(line, sizeof(line), procpt)) { + if (!index(line, '\n')) + break; + if (sscanf (line, " %d %d %d %[^\n ]", &ma, &mi, &sz, ptname) != 4) continue; @@ -229,7 +234,7 @@ /* heuristic: partition name ends in a digit */ /* devfs has .../disc and .../part1 etc. */ - for(s = ptname; *s; s++); + for (s = ptname; *s; s++); if (isdigit(s[-1]) || is_xvm(ptname)) { /* @@ -243,7 +248,7 @@ */ sprintf(device, "%s/%s", DEVLABELDIR, ptname); if (!get_label_uuid(device, &label, uuid)) - uuidcache_addentry(strdup(device), label, uuid); + uuidcache_addentry(xstrdup(device), label, uuid); } } } @@ -263,14 +268,14 @@ uuidcache_init(); uc = uuidCache; - while(uc) { + 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)) + if (uc->label && !strcmp(t, uc->label)) return xstrdup(uc->device); break; } @@ -307,7 +312,7 @@ return get_spec_by_x(UUID, uuid); bad_uuid: - die(EX_USAGE, _("mount: bad UUID")); + die(EX_USAGE, _("%s: bad UUID"), progname); return NULL; /* just for gcc */ } @@ -344,7 +349,7 @@ uuidcache_init(); for (last = uuidCache; last; last = last->next) { - if (!strcmp(last->label, label)) { + if (last->label && !strcmp(last->label, label)) { occurrences++; if (occurrences == 2) return last->device; diff -urN util-linux-2.12i/mount/mount_guess_fstype.c util-linux-2.12p/mount/mount_guess_fstype.c --- util-linux-2.12i/mount/mount_guess_fstype.c 2004-09-19 15:17:23.000000000 -0400 +++ util-linux-2.12p/mount/mount_guess_fstype.c 2004-11-08 10:21:33.000000000 -0500 @@ -559,7 +559,7 @@ while (fgets(line, sizeof(line), procfs)) { if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue; if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue; - return strdup(fsname); + return xstrdup(fsname); } return 0; } diff -urN util-linux-2.12i/mount/mount_guess_rootdev.c util-linux-2.12p/mount/mount_guess_rootdev.c --- util-linux-2.12i/mount/mount_guess_rootdev.c 2001-09-29 15:11:59.000000000 -0400 +++ util-linux-2.12p/mount/mount_guess_rootdev.c 2004-11-08 10:22:00.000000000 -0500 @@ -60,7 +60,7 @@ sprintf(devname, "/dev/%s%c", type, let); else sprintf(devname, "/dev/%s%c%d", type, let, mi); - return strdup(devname); + return xstrdup(devname); } return NULL; } diff -urN util-linux-2.12i/mount/sundries.c util-linux-2.12p/mount/sundries.c --- util-linux-2.12i/mount/sundries.c 2004-10-13 17:15:39.000000000 -0400 +++ util-linux-2.12p/mount/sundries.c 2004-12-21 14:12:31.000000000 -0500 @@ -18,35 +18,6 @@ #include "nfsmount.h" #include "nls.h" -void * -xmalloc (size_t size) { - void *t; - - if (size == 0) - return NULL; - - t = malloc (size); - if (t == NULL) - die (EX_SYSERR, _("not enough memory")); - - return t; -} - -char * -xstrdup (const char *s) { - char *t; - - if (s == NULL) - return NULL; - - t = strdup (s); - - if (t == NULL) - die (EX_SYSERR, _("not enough memory")); - - return t; -} - char * xstrndup (const char *s, int n) { char *t; @@ -136,20 +107,6 @@ free (fmt2); } -/* Fatal error. Print message and exit. */ -void -die (int err, const char *fmt, ...) { - va_list args; - - va_start (args, fmt); - vfprintf (stderr, fmt, args); - fprintf (stderr, "\n"); - va_end (args); - - unlock_mtab (); - exit (err); -} - /* True if fstypes match. Null *TYPES means match anything, except that swap types always return false. */ /* Accept nonfs,proc,devpts and nonfs,noproc,nodevpts @@ -278,11 +235,12 @@ if (path == NULL) return NULL; +#if 1 if (streq(path, "none") || streq(path, "proc") || streq(path, "devpts")) return xstrdup(path); - +#endif if (myrealpath (path, canonical, PATH_MAX+1)) return xstrdup(canonical); diff -urN util-linux-2.12i/mount/swap.configure util-linux-2.12p/mount/swap.configure --- util-linux-2.12i/mount/swap.configure 1999-07-08 22:56:39.000000000 -0400 +++ util-linux-2.12p/mount/swap.configure 2004-12-12 09:38:29.000000000 -0500 @@ -23,7 +23,7 @@ echo '#include main(){ exit(0); swapon("/dev/null", 0); }' >> conftest.c eval $compile -if test -s conftest && ./conftest 2>/dev/null; then +if test -s conftest; then echo "#define SWAPON_HAS_TWO_ARGS" > swapargs.h echo $PAGEH >> swapargs.h echo $SWAPH >> swapargs.h diff -urN util-linux-2.12i/mount/swapon.8 util-linux-2.12p/mount/swapon.8 --- util-linux-2.12i/mount/swapon.8 2002-10-31 13:00:03.000000000 -0500 +++ util-linux-2.12p/mount/swapon.8 2004-12-21 15:59:42.000000000 -0500 @@ -58,6 +58,15 @@ .SH DESCRIPTION .B Swapon is used to specify devices on which paging and swapping are to take place. + +The device or file used is given by the +.I specialfile +parameter. It may be of the form +.BI \-L " label" +or +.BI \-U " uuid" +to indicate a device by label or uuid. + Calls to .B swapon normally occur in the system multi-user initialization file @@ -67,30 +76,28 @@ Normally, the first form is used: .TP -.B \-h -Provide help -.TP -.B \-V -Display version -.TP -.B \-s -Display swap usage summary by device. Equivalent to "cat /proc/swaps". -Not available before Linux 2.1.25. -.TP .B \-a All devices marked as ``swap'' swap devices in .I /etc/fstab -are made available. Devices that are already running as swap are silently -skipped. +are made available, except for those with the ``noauto'' option. +Devices that are already running as swap are silently skipped. .TP .B \-e When .B \-a is used with swapon, -.B -\-e -makes swapon silently skip devices that -do not exist. +.B \-e +makes swapon silently skip devices that do not exist. +.TP +.B \-h +Provide help +.TP +.BI \-L " label" +Use the partition that has the specified +.IR label . +(For this, access to +.I /proc/partitions +is needed.) .TP .BI \-p " priority" Specify priority for @@ -99,7 +106,8 @@ .B swapon was compiled under and is used under a 1.3.2 or later kernel. .I priority -is a value between 0 and 32767. See +is a value between 0 and 32767. Higher numbers indicate higher +priority. See .BR swapon (2) for a full description of swap priorities. Add .BI pri= value @@ -107,6 +115,23 @@ .I /etc/fstab for use with .BR "swapon -a" . +.TP +.B \-s +Display swap usage summary by device. Equivalent to "cat /proc/swaps". +Not available before Linux 2.1.25. +.TP +.BI \-U " uuid" +Use the partition that has the specified +.IR uuid . +(For this, access to +.I /proc/partitions +is needed.) +.TP +.B \-v +Be verbose. +.TP +.B \-V +Display version .PP .B Swapoff disables swapping on the specified devices and files. diff -urN util-linux-2.12i/mount/swapon.c util-linux-2.12p/mount/swapon.c --- util-linux-2.12i/mount/swapon.c 2004-10-12 12:04:20.000000000 -0400 +++ util-linux-2.12p/mount/swapon.c 2004-12-22 04:50:19.000000000 -0500 @@ -1,16 +1,6 @@ /* * A swapon(8)/swapoff(8) for Linux 0.99. * swapon.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp - * - * 1997-02-xx - * - added '-s' (summary option) - * 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support - * 1999-03-21 Arnaldo Carvalho de Melo - * - fixed strerr(errno) in gettext calls - * 2001-03-22 Erik Troan - * - added -e option for -a - * - -a shouldn't try to add swaps that are already enabled */ #include @@ -21,9 +11,12 @@ #include #include #include +#include "xmalloc.h" #include "swap_constants.h" #include "swapargs.h" #include "nls.h" +#include "mount_blkid.h" +#include "mount_by_label.h" #define streq(s, t) (strcmp ((s), (t)) == 0) @@ -42,7 +35,7 @@ int ifexists = 0; extern char version[]; -static char *program_name; +char *progname; static struct option longswaponopts[] = { /* swapon only */ @@ -63,9 +56,9 @@ swapon_usage(FILE *fp, int n) { fprintf(fp, _("usage: %s [-hV]\n" " %s -a [-e] [-v]\n" - " %s [-v] [-p priority] special ...\n" + " %s [-v] [-p priority] special|LABEL=volume_name ...\n" " %s [-s]\n"), - program_name, program_name, program_name, program_name); + progname, progname, progname, progname); exit(n); } @@ -74,7 +67,7 @@ fprintf(fp, _("usage: %s [-hV]\n" " %s -a [-v]\n" " %s [-v] special ...\n"), - program_name, program_name, program_name); + progname, progname, progname); exit(n); } @@ -111,7 +104,7 @@ read_proc_swaps(void) { FILE *swaps; char line[1024]; - char *p; + char *p, **q; numSwaps = 0; swapFiles = NULL; @@ -131,20 +124,22 @@ for (p = line; *p && *p != ' '; p++); *p = 0; - numSwaps++; - swapFiles = realloc(swapFiles, - numSwaps * sizeof(*swapFiles)); - swapFiles[numSwaps-1] = strdup(line); + q = realloc(swapFiles, (numSwaps+1) * sizeof(*swapFiles)); + if (q == NULL) + break; + swapFiles = q; + + swapFiles[numSwaps++] = strdup(line); } fclose(swaps); } static int -is_in_proc_swaps(char *fname) { +is_in_proc_swaps(const char *fname) { int i; for (i = 0; i < numSwaps; i++) - if (!strcmp(fname, swapFiles[i])) + if (swapFiles[i] && !strcmp(fname, swapFiles[i])) return 1; return 0; } @@ -157,7 +152,7 @@ if ((swaps = fopen(PROC_SWAPS, "r")) == NULL) { int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, PROC_SWAPS, + fprintf(stderr, "%s: %s: %s\n", progname, PROC_SWAPS, strerror(errsv)); return -1 ; } @@ -170,17 +165,25 @@ } static int -do_swapon(const char *special, int prio) { +do_swapon(const char *orig_special, int prio) { int status; struct stat st; + const char *special; if (verbose) - printf(_("%s on %s\n"), program_name, special); + printf(_("%s on %s\n"), progname, orig_special); + + special = mount_get_devname(orig_special); + if (!special) { + fprintf(stderr, _("%s: cannot find the device for %s\n"), + progname, orig_special); + return -1; + } if (stat(special, &st) < 0) { int errsv = errno; - fprintf(stderr, _("swapon: cannot stat %s: %s\n"), - special, strerror(errsv)); + fprintf(stderr, _("%s: cannot stat %s: %s\n"), + progname, special, strerror(errsv)); return -1; } @@ -190,10 +193,10 @@ int permMask = (S_ISBLK(st.st_mode) ? 07007 : 07077); if ((st.st_mode & permMask) != 0) { - fprintf(stderr, _("swapon: warning: %s has " + fprintf(stderr, _("%s: warning: %s has " "insecure permissions %04o, " "%04o suggested\n"), - special, st.st_mode & 07777, + progname, special, st.st_mode & 07777, ~permMask & 0666); } } @@ -202,9 +205,9 @@ if (S_ISREG(st.st_mode)) { if (st.st_blocks * 512 < st.st_size) { fprintf(stderr, - _("swapon: Skipping file %s - it appears " + _("%s: Skipping file %s - it appears " "to have holes.\n"), - special); + progname, special); return -1; } } @@ -229,17 +232,42 @@ #endif if (status < 0) { int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, - special, strerror(errsv)); + fprintf(stderr, "%s: %s: %s\n", + progname, orig_special, strerror(errsv)); } return status; } static int -do_swapoff(const char *special, int quiet) { +cannot_find(const char *special) { + fprintf(stderr, _("%s: cannot find the device for %s\n"), + progname, special); + return -1; +} + +static int +swapon_by_label(const char *label, int prio) { + const char *special = mount_get_devname_by_label(label); + return special ? do_swapon(special, prio) : cannot_find(label); +} + +static int +swapon_by_uuid(const char *uuid, int prio) { + const char *special = mount_get_devname_by_uuid(uuid); + return special ? do_swapon(special, prio) : cannot_find(uuid); +} + +static int +do_swapoff(const char *orig_special, int quiet) { + const char *special; + if (verbose) - printf(_("%s on %s\n"), program_name, special); + printf(_("%s on %s\n"), progname, orig_special); + + special = mount_get_devname(orig_special); + if (!special) + return cannot_find(orig_special); if (swapoff(special) == 0) return 0; /* success */ @@ -250,22 +278,96 @@ } if (!quiet || errno == ENOMEM) { - int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, - special, strerror(errsv)); + fprintf(stderr, "%s: %s: %s\n", + progname, orig_special, strerror(errno)); } return -1; } static int -main_swapon(int argc, char *argv[]) { +swapoff_by_label(const char *label, int quiet) { + const char *special = mount_get_devname_by_label(label); + return special ? do_swapoff(special, quiet) : cannot_find(label); +} + +static int +swapoff_by_uuid(const char *uuid, int quiet) { + const char *special = mount_get_devname_by_uuid(uuid); + return special ? do_swapoff(special, quiet) : cannot_find(uuid); +} + +static int +swapon_all(void) { FILE *fp; struct mntent *fstab; int status = 0; - int c; - while ((c = getopt_long(argc, argv, "ahep:svV", - longswaponopts, NULL)) != -1) { + read_proc_swaps(); + + fp = setmntent(_PATH_FSTAB, "r"); + if (fp == NULL) { + int errsv = errno; + fprintf(stderr, _("%s: cannot open %s: %s\n"), + progname, _PATH_FSTAB, strerror(errsv)); + exit(2); + } + + while ((fstab = getmntent(fp)) != NULL) { + const char *orig_special = fstab->mnt_fsname; + const char *special; + int skip = 0; + int pri = priority; + + if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) + continue; + + special = mount_get_devname(orig_special); + if (!special) + continue; + + if (!is_in_proc_swaps(special) && + (!ifexists || !access(special, R_OK))) { + /* parse mount options; */ + char *opt, *opts = strdup(fstab->mnt_opts); + + for (opt = strtok(opts, ","); opt != NULL; + opt = strtok(NULL, ",")) { + if (strncmp(opt, "pri=", 4) == 0) + pri = atoi(opt+4); + if (strcmp(opt, "noauto") == 0) + skip = 1; + } + if (!skip) + status |= do_swapon(special, pri); + } + } + fclose(fp); + + return status; +} + +static const char **llist = NULL; +static int llct = 0; +static const char **ulist = NULL; +static int ulct = 0; + +static void addl(const char *label) { + llist = (const char **) xrealloc(llist, (++llct) * sizeof(char *)); + llist[llct-1] = label; +} + +static void addu(const char *uuid) { + ulist = (const char **) xrealloc(ulist, (++ulct) * sizeof(char *)); + ulist[ulct-1] = uuid; +} + +static int +main_swapon(int argc, char *argv[]) { + int status = 0; + int c, i; + + while ((c = getopt_long(argc, argv, "ahep:svVL:U:", + longswaponopts, NULL)) != -1) { switch (c) { case 'a': /* all */ ++all; @@ -276,6 +378,12 @@ case 'p': /* priority */ priority = atoi(optarg); break; + case 'L': + addl(optarg); + break; + case 'U': + addu(optarg); + break; case 'e': /* ifexists */ ifexists = 1; break; @@ -286,7 +394,7 @@ ++verbose; break; case 'V': /* version */ - printf("%s: %s\n", program_name, version); + printf("%s: %s\n", progname, version); exit(0); case 0: break; @@ -297,40 +405,20 @@ } argv += optind; - if (!all && *argv == NULL) + if (!all && !llct && !ulct && *argv == NULL) swapon_usage(stderr, 2); - if (ifexists && (!all || strcmp(program_name, "swapon"))) - swapon_usage(stderr, 1); + if (ifexists && (!all || strcmp(progname, "swapon"))) + swapon_usage(stderr, 1); - if (all) { - read_proc_swaps(); + if (all) + status |= swapon_all(); - fp = setmntent(_PATH_FSTAB, "r"); - if (fp == NULL) { - int errsv = errno; - fprintf(stderr, _("%s: cannot open %s: %s\n"), - program_name, _PATH_FSTAB, strerror(errsv)); - exit(2); - } - while ((fstab = getmntent(fp)) != NULL) { - char *special = fstab->mnt_fsname; + for (i = 0; i < llct; i++) + status |= swapon_by_label(llist[i], priority); - if (streq(fstab->mnt_type, MNTTYPE_SWAP) && - !is_in_proc_swaps(special) - && (!ifexists || !access(special, R_OK))) { - /* parse mount options; */ - char *opt, *opts = strdup(fstab->mnt_opts); - - for (opt = strtok(opts, ","); opt != NULL; - opt = strtok(NULL, ",")) - if (strncmp(opt, "pri=", 4) == 0) - priority = atoi(opt+4); - status |= do_swapon(special, priority); - } - } - fclose(fp); - } + for (i = 0; i < ulct; i++) + status |= swapon_by_uuid(ulist[i], priority); while (*argv != NULL) status |= do_swapon(*argv++, priority); @@ -345,7 +433,7 @@ int status = 0; int c, i; - while ((c = getopt_long(argc, argv, "ahvV", + while ((c = getopt_long(argc, argv, "ahvVL:U:", longswapoffopts, NULL)) != -1) { switch (c) { case 'a': /* all */ @@ -358,8 +446,14 @@ ++verbose; break; case 'V': /* version */ - printf("%s: %s\n", program_name, version); + printf("%s: %s\n", progname, version); exit(0); + case 'L': + addl(optarg); + break; + case 'U': + addu(optarg); + break; case 0: break; case '?': @@ -369,19 +463,25 @@ } argv += optind; - if (!all && *argv == NULL) + if (!all && !llct && !ulct && *argv == NULL) swapoff_usage(stderr, 2); /* * swapoff any explicitly given arguments. * Complain in case the swapoff call fails. */ + for (i = 0; i < llct; i++) + status |= swapoff_by_label(llist[i], !QUIET); + + for (i = 0; i < ulct; i++) + status |= swapoff_by_uuid(ulist[i], !QUIET); + while (*argv != NULL) status |= do_swapoff(*argv++, !QUIET); if (all) { /* - * In case /proc/swaps exists, unmount stuff listed there. + * In case /proc/swaps exists, unswap stuff listed there. * We are quiet but report errors in status. * Errors might mean that /proc/swaps * exists as ordinary file, not in procfs. @@ -392,7 +492,7 @@ status |= do_swapoff(swapFiles[i], QUIET); /* - * Unmount stuff mentioned in /etc/fstab. + * Unswap stuff mentioned in /etc/fstab. * Probably it was unmounted already, so errors are not bad. * Doing swapoff -a twice should not give error messages. */ @@ -400,7 +500,7 @@ if (fp == NULL) { int errsv = errno; fprintf(stderr, _("%s: cannot open %s: %s\n"), - program_name, _PATH_FSTAB, strerror(errsv)); + progname, _PATH_FSTAB, strerror(errsv)); exit(2); } while ((fstab = getmntent(fp)) != NULL) { @@ -422,12 +522,12 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - program_name = argv[0]; - p = strrchr(program_name, '/'); + progname = argv[0]; + p = strrchr(progname, '/'); if (p) - program_name = p+1; + progname = p+1; - if (streq(program_name, "swapon")) + if (streq(progname, "swapon")) return main_swapon(argc, argv); else return main_swapoff(argc, argv); diff -urN util-linux-2.12i/mount/umount.8 util-linux-2.12p/mount/umount.8 --- util-linux-2.12i/mount/umount.8 2002-10-31 20:00:50.000000000 -0500 +++ util-linux-2.12p/mount/umount.8 2004-11-10 14:49:37.000000000 -0500 @@ -74,6 +74,9 @@ In case the unmounted device was a loop device, also free this loop device. .TP +.B \-i +Don't call the /sbin/umount. helper even if it exists. By default /sbin/umount. helper is called if one exists. +.TP .B \-a All of the file systems described in .I /etc/mtab diff -urN util-linux-2.12i/mount/umount.c util-linux-2.12p/mount/umount.c --- util-linux-2.12i/mount/umount.c 2004-09-28 07:56:31.000000000 -0400 +++ util-linux-2.12p/mount/umount.c 2004-12-20 17:03:45.000000000 -0500 @@ -1,32 +1,5 @@ /* - * A umount(8) for Linux 0.99. - * umount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp - * - * Wed Sep 14 22:43:54 1994: Sebastian Lederer - * (lederer@next-pc.informatik.uni-bonn.de) added support for sending an - * unmount RPC call to the server when an NFS-filesystem is unmounted. - * - * Tue Sep 26 16:33:09 1995: Added patches from Greg Page (greg@caldera.com) - * so that NetWare filesystems can be unmounted. - * - * 951213: Marek Michalkiewicz : - * Ignore any RPC errors, so that you can umount an nfs mounted filesystem - * if the server is down. - * - * 960223: aeb - several minor changes - * 960324: aeb - added some changes from Rob Leslie - * 960823: aeb - also try umount(spec) when umount(node) fails - * 970307: aeb - canonicalise names from fstab - * 970726: aeb - remount read-only in cases where umount fails - * 980810: aeb - umount2 support - * 981222: aeb - If mount point or special file occurs several times - * in mtab, try them all, with last one tried first - * - Differentiate "user" and "users" key words in fstab - * 001202: aeb - remove at most one line from /etc/mtab - * 010716: Michael K. Johnson @@ -36,6 +9,7 @@ #include #include #include +#include #include #include "mount_constants.h" #include "sundries.h" @@ -91,6 +65,10 @@ #define MNT_DETACH 2 #endif + +/* True if we are allowed to call /sbin/umount.${FSTYPE} */ +int external_allowed = 1; + /* Nonzero for force umount (-f). There is kernel support since 2.1.116. */ int force = 0; @@ -112,15 +90,61 @@ /* True if ruid != euid. */ int suid = 0; -#ifdef USE_SPECIAL_UMOUNTPROG -/* unimplemented so far */ +/* + * check_special_umountprog() + * If there is a special umount program for this type, exec it. + * returns: 0: no exec was done, 1: exec was done, status has result + */ static int -check_special_umountprog() { - /* find type from command line or /etc/mtab; - stat /sbin/umount.%s - if it exists, use it */ +check_special_umountprog(const char *spec, const char *node, + const char *type, int *status) { + char umountprog[120]; + struct stat statbuf; + int res; + + if (!external_allowed) + return 0; + + if (type && strlen(type) < 100) { + sprintf(umountprog, "/sbin/umount.%s", type); + if (stat(umountprog, &statbuf) == 0) { + res = fork(); + if (res == 0) { + char *umountargs[8]; + int i = 0; + + setuid(getuid()); + setgid(getgid()); + umountargs[i++] = umountprog; + umountargs[i++] = xstrdup(node); + if (nomtab) + umountargs[i++] = "-n"; + if (lazy) + umountargs[i++] = "-l"; + if (force) + umountargs[i++] = "-f"; + if (verbose) + umountargs[i++] = "-v"; + if (remount) + umountargs[i++] = "-r"; + umountargs[i] = NULL; + execv(umountprog, umountargs); + exit(1); /* exec failed */ + } else if (res != -1) { + int st; + wait(&st); + *status = (WIFEXITED(st) ? WEXITSTATUS(st) + : EX_SYSERR); + return 1; + } else { + int errsv = errno; + error(_("umount: cannot fork: %s"), + strerror(errsv)); + } + } + } + return 0; } -#endif #ifdef HAVE_NFS static int xdr_dir(XDR *xdrsp, char *dirp) @@ -248,6 +272,7 @@ int umnt_err, umnt_err2; int isroot; int res; + int status; const char *loopdev; /* Special case for root. As of 0.99pl10 we can (almost) unmount root; @@ -260,6 +285,13 @@ || streq (node, "rootfs")); if (isroot) nomtab++; + + /* + * Call umount.TYPE for types that require a separate umount program. + * All such special things must occur isolated in the types string. + */ + if (check_special_umountprog(spec, node, type, &status)) + return status; #ifdef HAVE_NFS /* Ignore any RPC errors, so that you can umount the filesystem @@ -322,7 +354,7 @@ spec); remnt.mnt_type = remnt.mnt_fsname = NULL; remnt.mnt_dir = xstrdup(node); - remnt.mnt_opts = "ro"; + remnt.mnt_opts = xstrdup("ro"); update_mtab(node, &remnt); return 0; } else if (errno != EBUSY) { /* hmm ... */ @@ -514,7 +546,13 @@ umount_file (char *arg) { struct mntentchn *mc, *fs; const char *file, *options; - int fstab_has_user, fstab_has_users, fstab_has_owner, ok; + int fstab_has_user, fstab_has_users, fstab_has_owner, fstab_has_group; + int ok; + + if (!*arg) { /* "" would be expanded to `pwd` */ + die(2, _("Cannot umount \"\"\n")); + return 0; + } file = canonicalize(arg); /* mtab paths are canonicalized */ if (verbose > 1) @@ -533,7 +571,10 @@ die(2, _("umount: %s is not mounted (according to mtab)"), file); - if (!is_mounted_once(file)) + /* The 2.4 kernel will generally refuse to mount the same + filesystem on the same mount point, but will accept NFS. + So, unmounting must be possible. */ + if (!is_mounted_once(file) && strcmp(mc->m.mnt_type,"nfs")) die(2, _("umount: it seems %s is mounted multiple times"), file); @@ -556,16 +597,17 @@ "the fstab"), file); } - /* User mounting and unmounting is allowed only - if fstab contains one of the options `user', - `users' or `owner'. */ - /* The option `users' allows arbitrary users to mount - and unmount - this may be a security risk. */ - /* The option `user' only allows unmounting by the user - that mounted. */ - /* The option `owner' only allows (un)mounting by the owner. */ - /* A convenient side effect is that the user who mounted - is visible in mtab. */ + /* + * User mounting and unmounting is allowed only + * if fstab contains one of the options `user', + * `users' or `owner' or `group'. + * + * The option `users' allows arbitrary users to mount + * and unmount - this may be a security risk. + * + * The options `user', `owner' and `group' only allow + * unmounting by the user that mounted (visible in mtab). + */ options = fs->m.mnt_opts; if (!options) @@ -573,12 +615,14 @@ fstab_has_user = contains(options, "user"); fstab_has_users = contains(options, "users"); fstab_has_owner = contains(options, "owner"); + fstab_has_group = contains(options, "group"); ok = 0; if (fstab_has_users) ok = 1; - if (!ok && (fstab_has_user || fstab_has_owner)) { + if (!ok && (fstab_has_user || fstab_has_owner || + fstab_has_group)) { char *user = getusername(); options = mc->m.mnt_opts; @@ -601,11 +645,13 @@ return umount_one (arg, arg, arg, arg, NULL); } +char *progname; + int main (int argc, char *argv[]) { int c; int all = 0; - char *types = NULL, *test_opts = NULL; + char *types = NULL, *test_opts = NULL, *p; int result = 0; sanitize_env(); @@ -613,9 +659,13 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - umask(033); + progname = argv[0]; + if ((p = strrchr(progname, '/')) != NULL) + progname = p+1; + + umask(022); - while ((c = getopt_long (argc, argv, "adfhlnrt:O:vV", + while ((c = getopt_long (argc, argv, "adfhlnrit:O:vV", longopts, NULL)) != -1) switch (c) { case 'a': /* umount everything */ @@ -652,6 +702,9 @@ case 't': /* specify file system type */ types = optarg; break; + case 'i': + external_allowed = 0; + break; case 0: break; case '?': diff -urN util-linux-2.12i/mount/xmalloc.c util-linux-2.12p/mount/xmalloc.c --- util-linux-2.12i/mount/xmalloc.c 1969-12-31 19:00:00.000000000 -0500 +++ util-linux-2.12p/mount/xmalloc.c 2004-12-21 14:23:15.000000000 -0500 @@ -0,0 +1,66 @@ +#include +#include +#include /* strdup() */ +#include "xmalloc.h" +#include "nls.h" /* _() */ +#include "sundries.h" /* EX_SYSERR */ + +void (*at_die)(void) = NULL; + +/* Fatal error. Print message and exit. */ +void +die(int err, const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + + if (at_die) + (*at_die)(); + + exit(err); +} + +static void +die_if_null(void *t) { + if (t == NULL) + die(EX_SYSERR, _("not enough memory")); +} + +void * +xmalloc (size_t size) { + void *t; + + if (size == 0) + return NULL; + + t = malloc(size); + die_if_null(t); + + return t; +} + +void * +xrealloc (void *p, size_t size) { + void *t; + + t = realloc(p, size); + die_if_null(t); + + return t; +} + +char * +xstrdup (const char *s) { + char *t; + + if (s == NULL) + return NULL; + + t = strdup(s); + die_if_null(t); + + return t; +} diff -urN util-linux-2.12i/mount/xmalloc.h util-linux-2.12p/mount/xmalloc.h --- util-linux-2.12i/mount/xmalloc.h 1969-12-31 19:00:00.000000000 -0500 +++ util-linux-2.12p/mount/xmalloc.h 2004-12-21 16:59:30.000000000 -0500 @@ -0,0 +1,8 @@ +#include +#include + +extern void *xmalloc(size_t size); +extern void *xrealloc(void *p, size_t size); +extern char *xstrdup(const char *s); +extern void die(int err, const char *fmt, ...); +extern void (*at_die)(void);