diff options
author | Karel Zak | 2006-12-07 00:25:41 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:41 +0100 |
commit | eb63b9b8f4cecb34c2478282567862bc48ef256d (patch) | |
tree | 99243f8eecb44c2bb6a559982b99c680fcb649e7 /mount | |
parent | Imported from util-linux-2.9v tarball. (diff) | |
download | kernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.tar.gz kernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.tar.xz kernel-qcow2-util-linux-eb63b9b8f4cecb34c2478282567862bc48ef256d.zip |
Imported from util-linux-2.10f tarball.
Diffstat (limited to 'mount')
-rw-r--r-- | mount/Makefile | 16 | ||||
-rw-r--r-- | mount/fstab.5 | 6 | ||||
-rw-r--r-- | mount/fstab.c | 29 | ||||
-rw-r--r-- | mount/fstab.h | 1 | ||||
-rw-r--r-- | mount/linux_fs.h | 1 | ||||
-rw-r--r-- | mount/losetup.c | 11 | ||||
-rw-r--r-- | mount/mk_loop_h | 2 | ||||
-rw-r--r-- | mount/mntent.c | 4 | ||||
-rw-r--r-- | mount/mount.8 | 264 | ||||
-rw-r--r-- | mount/mount.c | 82 | ||||
-rw-r--r-- | mount/mount_guess_fstype.c | 109 | ||||
-rw-r--r-- | mount/realpath.c | 153 | ||||
-rw-r--r-- | mount/realpath.h | 1 | ||||
-rw-r--r-- | mount/sundries.c | 5 | ||||
-rw-r--r-- | mount/umount.c | 38 | ||||
-rw-r--r-- | mount/version.c | 2 |
16 files changed, 518 insertions, 206 deletions
diff --git a/mount/Makefile b/mount/Makefile index 0d370ff8c..443e8f783 100644 --- a/mount/Makefile +++ b/mount/Makefile @@ -1,7 +1,6 @@ include ../make_include include ../MCONFIG -CC = gcc CFLAGS = -I$(LIB) $(OPT) WARNFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes DEFINES = -DHAVE_NFS @@ -9,17 +8,6 @@ DEFINES = -DHAVE_NFS RPCSVCDIR = rpcsvc RPC_CFLAGS = -Wno-unused RPCGEN = rpcgen -#INSTALL = install -#INSTALLSUID = $(INSTALL) -m 4755 -o root -#INSTALLPROG = $(INSTALL) -m 755 -#INSTALLDATA = $(INSTALL) -m 644 - -## for suid progs (mount, umount) -#BINDIR = /bin -## for nosuid progs (swapon) -#SBINDIR = /sbin - -# End of configuration section. COMPILE = $(CC) -c $(WARNFLAGS) $(CFLAGS) $(DEFINES) LINK = $(CC) $(LDFLAGS) @@ -67,7 +55,7 @@ swapon: swapon.o version.o losetup: losetup.o $(LINK) $^ -o $@ -mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h +mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h mount.o umount.o fstab.o sundries.o: fstab.h @@ -89,6 +77,8 @@ umount.o: mount_constants.h mount.o mount_by_label.o mount_guess_fstype.o: linux_fs.h +sundries.o realpath.o: realpath.h + nfsmount_clnt.o: nfsmount_clnt.c $(COMPILE) $(RPC_CFLAGS) nfsmount_clnt.c diff --git a/mount/fstab.5 b/mount/fstab.5 index 5b85fb996..6d7638e4a 100644 --- a/mount/fstab.5 +++ b/mount/fstab.5 @@ -189,7 +189,11 @@ The documentation in .BR mount (8) is often more up-to-date. .SH "SEE ALSO" -.BR getmntent "(3), " mount "(8), " swapon "(8), " nfs (5) +.BR getmntent (3), +.BR mount (8), +.BR swapon (8), +.BR fs (5) +.BR nfs (5) .SH HISTORY The .B fstab diff --git a/mount/fstab.c b/mount/fstab.c index 793caddde..aef26d90c 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -224,6 +224,23 @@ getmntoptfile (const char *file) return NULL; } +/* Find the entry (SPEC,FILE) in fstab */ +struct mntentchn * +getfsspecfile (const char *spec, const char *file) { + struct mntentchn *mc; + + for (mc = fstab_head()->nxt; mc; mc = mc->nxt) + if (streq (mc->mnt_dir, file) && streq (mc->mnt_fsname, spec)) + return mc; + for (mc = fstab_head()->nxt; mc; mc = mc->nxt) + if ((streq (mc->mnt_dir, file) || + streq (canonicalize(mc->mnt_dir), file)) + && (streq (mc->mnt_fsname, spec) || + streq (canonicalize(mc->mnt_fsname), spec))) + break; + return mc; +} + /* Find the dir FILE in fstab. */ struct mntentchn * getfsfile (const char *file) { @@ -401,6 +418,8 @@ lock_mtab (void) { } we_created_lockfile = 1; } else { + static int tries = 0; + /* Someone else made the link. Wait. */ alarm(LOCK_TIMEOUT); if (fcntl (fd, F_SETLKW, &flock) == -1) { @@ -410,7 +429,15 @@ lock_mtab (void) { _("timed out") : strerror (errsv)); } alarm(0); - /* Maybe limit the number of iterations? */ + /* Limit the number of iterations - maybe there + still is some old /etc/mtab~ */ + if (tries++ > 3) { + if (tries > 5) + die (EX_FILEIO, _("Cannot create link %s\n" + "Perhaps there is a stale lock file?\n"), + MOUNTED_LOCK); + sleep(1); + } } close(fd); diff --git a/mount/fstab.h b/mount/fstab.h index acd8f6271..65bf5dba6 100644 --- a/mount/fstab.h +++ b/mount/fstab.h @@ -28,6 +28,7 @@ struct mntentchn *getmntfilesbackward (const char *file, struct mntentchn *mc); struct mntentchn *fstab_head (void); struct mntentchn *getfsfile (const char *file); struct mntentchn *getfsspec (const char *spec); +struct mntentchn *getfsspecfile (const char *spec, const char *file); struct mntentchn *getfsuuidspec (const char *uuid); struct mntentchn *getfsvolspec (const char *label); diff --git a/mount/linux_fs.h b/mount/linux_fs.h index bd9243b55..635389a01 100644 --- a/mount/linux_fs.h +++ b/mount/linux_fs.h @@ -91,6 +91,7 @@ struct ntfs_super_block { struct fat_super_block { u_char s_dummy[3]; u_char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */ + /* mtools-3.9.4 writes "MTOOL394" */ u_char s_dummy2[32]; u_char s_label[11]; /* for DOS? */ u_char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */ diff --git a/mount/losetup.c b/mount/losetup.c index 911d73060..9f20ee8b6 100644 --- a/mount/losetup.c +++ b/mount/losetup.c @@ -103,7 +103,8 @@ int set_loop(const char *device, const char *file, int offset, 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); + fprintf(stderr,_("Unsupported encryption type %s\n"), + encryption); exit(1); } loopinfo.lo_offset = offset; @@ -129,7 +130,8 @@ int set_loop(const char *device, const char *file, int offset, (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]); + fprintf(stderr,_("Non-hex digit '%c'.\n"), + pass[i]); exit(1); } break; @@ -183,6 +185,7 @@ int main(int argc, char **argv) { char *offset,*encryption; int delete,off,c; + int res = 0; int ro = 0; setlocale(LC_ALL, ""); @@ -219,9 +222,9 @@ int main(int argc, char **argv) } else { if (offset && sscanf(offset,"%d",&off) != 1) usage(); - set_loop(argv[optind],argv[optind+1],off,encryption,&ro); + res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro); } - return 0; + return res; } #else /* LOOP_SET_FD not defined */ diff --git a/mount/mk_loop_h b/mount/mk_loop_h index dfeff296e..86e76f35e 100644 --- a/mount/mk_loop_h +++ b/mount/mk_loop_h @@ -14,8 +14,10 @@ rm -f loop.h if [ -f /usr/include/linux/posix_types.h ]; then echo '#include <linux/posix_types.h>' >> loop.h + echo '#undef dev_t' >> loop.h echo '#define dev_t __kernel_dev_t' >> loop.h else + echo '#undef dev_t' >> loop.h echo '#define dev_t unsigned short' >> loop.h fi diff --git a/mount/mntent.c b/mount/mntent.c index ac9cce823..d28171b98 100644 --- a/mount/mntent.c +++ b/mount/mntent.c @@ -86,10 +86,10 @@ unmangle(char *s) { /* * fstat'ing the file and allocating a buffer holding all of it - * may be a bad idea: if the file is /proc/mounttab, the stat + * may be a bad idea: if the file is /proc/mounts, the stat * returns 0. * (On the other hand, mangling and unmangling is meaningless - * for /proc/mounttab.) + * for /proc/mounts.) */ mntFILE * diff --git a/mount/mount.8 b/mount/mount.8 index f42375fdc..4aba358c2 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -33,6 +33,8 @@ .\" 970914, reg: -s option .\" 981111, K.Garloff: /etc/filesystems .\" 990111, aeb: documented /sbin/mount.smbfs +.\" 990730, Yann Droneaud <lch@multimania.com>: updated page +.\" 991214, Elrond <Elrond@Wunder-Nett.org>: added some docs on devpts .\" .TH MOUNT 8 "14 September 1997" "Linux 2.0" "Linux Programmer's Manual" .SH NAME @@ -175,6 +177,14 @@ instead of in the .I fstab line. +The +.B owner +option is similar to the +.B user +option, with the restriction that the user must be the owner +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 programs .B mount @@ -202,7 +212,11 @@ option below). It is possible to replace by a symbolic link to .IR /proc/mounts , but some information is lost that way, and in particular -working with the loop device will be less convenient. +working with the loop device will be less convenient. Also, +pathnames containing spaces are handled correctly by +.I /etc/mtab +but not (yet) by +.IR /proc/mounts . .SH OPTIONS The full set of options used by an invocation of @@ -294,31 +308,35 @@ The argument following the is used to indicate the file system type. The file system types which are currently supported are listed in .IR linux/fs/filesystems.c : -.IR minix , -.IR xiafs , -.IR ext , -.IR ext2 , -.IR msdos , -.IR umsdos , -.IR vfat , -.IR proc , -.IR autofs , -.IR devpts , -.IR nfs , -.IR iso9660 , -.IR smbfs , -.IR ncpfs , .IR adfs , .IR affs , +.IR autofs , .IR coda , +.IR coherent , +.IR devpts , +.IR efs , +.IR ext , +.IR ext2 , .IR hfs , .IR hpfs , +.IR iso9660 , +.IR minix , +.IR msdos , +.IR ncpfs , +.IR nfs , .IR ntfs , +.IR proc , .IR qnx4 , .IR romfs , +.IR smbfs , +.IR sysv , +.IR udf , .IR ufs , -.IR sysv ", " xenix ", " coherent . -Note that the last three are equivalent and that +.IR umsdos , +.IR vfat , +.IR xenix , +.IR xiafs . +Note that coherent, sysv and xenix are equivalent and that .I xenix and .I coherent @@ -355,6 +373,7 @@ option is given, or if the .B auto type is specified, the superblock is probed for the filesystem type .RI ( minix ", " ext ", " ext2 ", " xiafs ", " iso9660 ", " romfs +.RI , ufs ", " ntfs ", " qnx4 ", " bfs are supported). If this probe fails, mount will try to read the file .IR /etc/filesystems , @@ -362,6 +381,7 @@ or, if that does not exist, .IR /proc/filesystems . All of the filesystem types listed there will be tried, except for those that are labeled "nodev" (e.g., +.IR devpts , .I proc and .IR nfs ). @@ -537,6 +557,32 @@ These options are accepted but ignored. .SH "Mount options for coherent" None. +.SH "Mount options for devpts" +The devpts file system is a pseudo file system, traditionally mounted on +.IR /dev/pts . +In order to acquire a pseudo terminal, a process opens +.IR /dev/ptmx ; +the number of the pseudo terminal is then made available to the process +and the pseudo terminal slave can be accessed as +.IR /dev/pts/ <number>. +.TP +\fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP +This sets the owner or the group of newly created PTYs to +the specified values. When nothing is specified, they will +be set to the UID and GID of the creating process. +For example, if there is a tty group with GID 5, then +.B gid=5 +will cause newly created PTYs to belong to the tty group. +.TP +.BI mode= value +Set the mode of newly created PTYs to the specified value. +The default is 0600. +A value of +.B mode=620 +and +.B gid=5 +makes "mesg y" the default on newly created PTYs. + .SH "Mount options for ext" None. Note that the `ext' file system is obsolete. Don't use it. @@ -619,11 +665,15 @@ These options determine who can use the reserved blocks. Instead of block 1, use block .I n as superblock. This could be useful when the filesystem has been damaged. -Usually, copies of the superblock are found every 8192 blocks: in -block 1, 8193, 16385, ... -(Thus, one gets hundreds or even thousands of copies of the superblock -on a big filesystem. I do not know of options to mke2fs that would -cause fewer copies to be written.) +(Earlier, copies of the superblock would be made every 8192 blocks: in +block 1, 8193, 16385, ... (and one got hundreds or even thousands +of copies on a big filesystem). Since version 1.08, +.B mke2fs +has a \-s (sparse superblock) option to reduce the number of backup +superblocks, and since version 1.15 this is the default. Note +that this may mean that ext2 filesystems created by a recent +.B mke2fs +cannot be mounted r/w under Linux 2.0.*.) .TP .BR grpquota " / " noquota " / " quota " / " usrquota These options are accepted but ignored. @@ -638,7 +688,7 @@ and .I vfat filesystems.) .TP -.BR blocksize=512 " / " blocksize=1024 +.BR blocksize=512 " / " blocksize=1024 " / " blocksize=2048 Set blocksize (default 512). .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP @@ -673,6 +723,10 @@ that are sometimes used on Linux, but are not accepted by MS-DOS are rejected. (+, =, spaces, etc.) .RE .TP +.BI codepage= value +Sets the codepage for converting to shortname characters on FAT +and VFAT filesystems. By default, codepage 437 is used. +.TP .BR conv=b[inary] " / " conv=t[ext] " / " conv=a[uto] The .I fat @@ -703,6 +757,15 @@ For file systems mounted in binary mode, a conversion tool (fromdos/todos) is available. .RE .TP +.BI cvf_format= module +Forces the driver to use the CVF (Compressed Volume File) module +.RI cvf_ module +instead of auto-detection. If the kernel supports kmod, the +cvf_format=xxx option also controls on-demand CVF module loading. +.TP +.BI cvf_option= option +Option passed to the CVF module. +.TP .B debug Turn on the .I debug @@ -710,10 +773,15 @@ flag. A version string and a list of file system parameters will be printed (these data are also printed if the parameters appear to be inconsistent). .TP -.BR fat=12 " / " fat=16 -Specify either a 12 bit fat or a 16 bit fat. This overrides +.BR fat=12 " / " fat=16 " / " fat=32 +Specify a 12, 16 or 32 bit fat. This overrides the automatic FAT type detection routine. Use with caution! .TP +.BI iocharset= value +Character set to use for converting between 8 bit characters +and 16 bit Unicode characters. The default is iso8859-1. +Long filenames are stored on disk in Unicode format. +.TP .B quiet Turn on the .I quiet @@ -774,6 +842,9 @@ that it is read-only, of course). .B norock Disable the use of Rock Ridge extensions, even if available. Cf.\& .BR map . +.B nojoliet +Disable the use of Microsoft Joliet extensions, even if available. Cf.\& +.BR map . .TP .BR check=r[elaxed] " / " check=s[trict] With @@ -792,7 +863,7 @@ possibly overriding the information found in the Rock Ridge extensions. (Default: .BR uid=0,gid=0 .) .TP -.BR map=n[ormal] " / " map=o[ff] +.BR map=n[ormal] " / " map=o[ff] " / " map=a[corn] For non-Rock Ridge volumes, normal name translation maps upper to lower case ASCII, drops a trailing `;1', and converts `;' to `.'. With @@ -801,6 +872,10 @@ no name translation is done. See .BR norock . (Default: .BR map=normal .) +.B map=acorn +is like +.BR map=normal +but also apply Acorn extensions if present. .TP .BI mode= value For non-Rock Ridge volumes, give all files the indicated mode. @@ -821,7 +896,7 @@ Set the block size to the indicated value. .BR conv=binary .) Since Linux 1.3.54 this option has no effect anymore. (And non-binary settings used to be very dangerous, -often leading to silent data corruption.) +possibly leading to silent data corruption.) .TP .B cruft If the high byte of the file length contains other garbage, @@ -830,6 +905,12 @@ This implies that a file cannot be larger than 16MB. The `cruft' option is set automatically if the entire CDROM has a weird size (negative, or more than 800MB). It is also set when volume sequence numbers other than 0 or 1 are seen. +.TP +.B session=x +Select number of session on multisession CD. (Since 2.3.4.) +.TP +.B sbsector=xxx +Session begins from sector xxx. (Since 2.3.4.) .SH "Mount options for minix" None. @@ -926,6 +1007,30 @@ Usually it just causes lots of trouble. .B nolock Do not use locking. Do not start lockd. +.SH "Mount options for ntfs" +.TP +.BI iocharset= name +Character set to use when returning file names. +Unlike VFAT, NTFS suppresses names that contain +unconvertible characters. +.TP +.BR utf8 +Use UTF-8 for converting file names. +.TP +.B uni_xlate=[0|1|2] +For 0 (or `no' or `false') or 1 (or `yes' or `true'): +use the VFAT-style encoding for file names outside the current +character set. A value of 2 will disable the encoding with ":". +.TP +.B posix=[0|1] +If enabled (posix=1), the file system distinguishes between +upper and lower case. The 8.3 alias names are presented as +hard links instead of being suppressed. +.TP +\fBuid=\fP\fIvalue\fP, \fBgid=\fP\fIvalue\fP and \fBumask=\fP\fIvalue\fP +Set the file permission on the filesystem. +By default, the files are owned by root and not readable by somebody else. + .SH "Mount options for proc" .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP @@ -943,13 +1048,109 @@ to the mount system call. This argument is constructed by .BR smbmount (8) and the current version of .B mount -(2.6c) does not know anything about smb. +(2.9w) does not know anything about smb. .SH "Mount options for sysv" None. +.SH "Mount options for udf" +.TP +.B gid= +Set the default group. +.TP +.B umask= +Set the default umask. +.TP +.B uid= +Set the default user. +.TP +.B unhide +Show otherwise hidden files. +.TP +.B undelete +Show deleted files in lists. +.TP +.B strict +Set strict conformance (unused). +.TP +.B utf8 +(unused). +.TP +.B iocharset +(unused). +.TP +.B bs= +Set the block size. (May not work unless 2048.) +.TP +.B novrs +Skip volume sequence recognition. +.TP +.B session= +Set the CDROM session counting from 0. Default: last session. +.TP +.B anchor= +Override standard anchor location. Default: 256. +.TP +.B volume= +Override the VolumeDesc location. (unused) +.TP +.B partition= +Override the PartitionDesc location. (unused) +.TP +.B lastblock= +Set the last block of the filesystem. +.TP +.B fileset= +Override the fileset block location. (unused) +.TP +.B rootdir= +Override the root directory location. (unused) + .SH "Mount options for ufs" -None. +.TP +.BI ufstype= value +UFS is a file system widely used in different operating systems. +The problem are differences among implementations. Features of some +implementations are undocumented, so its hard to recognize the +type of ufs automatically. +That's why user must specify the type of ufs by mount option. +Possible values are: +.RS +.TP +.B old +Old format of ufs, this is the default, read only. +.TP +.B 44bsd +For filesystems created by a BSD-like system (NetBSD,FreeBSD,OpenBSD). +.TP +.B sun +For filesystems created by SunOS or Solaris on Sparc. +.TP +.B sunx86 +For filesystems created by Solaris on x86. +.TP +.B nextstep +For filesystems created by NeXTStep (on NeXT station) (currently read only). +.TP +.B nextstep-cd +For NextStep CDROMs (block_size == 2048), read-only. +.TP +.B openstep +For filesystems created by OpenStep (currently read only). +.RE + +.TP +.BI onerror= value +Set behaviour on error: +.RS +.TP +.B panic +If an error is encountered, cause a kernel panic. +.TP +.B [lock|umount|repair] +These mount options don't do anything at present; +when an error is encountered only a console message is printed. +.RE .SH "Mount options for umsdos" See mount options for msdos. @@ -984,6 +1185,11 @@ Allow two files with names that only differ in case. First try to make a short name without sequence number, before trying .IR name~num.ext . +.TP +.B utf8 +UTF8 is the filesystem safe 8-bit encoding of Unicode that is used +by the console. It can be be enabled for the filesystem with this option. +If `uni_xlate' gets set, UTF8 gets disabled. .SH "Mount options for xenix" None. diff --git a/mount/mount.c b/mount/mount.c index 9f51db310..6c1f40a29 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -32,6 +32,8 @@ * - fixed strerr(errno) in gettext calls * 1999-07-05 Hirokazu Takahashi <h-takaha@sss.abk.nec.co.jp> * - fixed use of nouser option + * 1999-09-09 Michael K. Johnson <johnsonm@redhat.com> + * - added `owner' mount option */ #include <unistd.h> @@ -107,6 +109,7 @@ struct opt_map #define MS_NOAUTO 0x80000000 #define MS_USERS 0x40000000 #define MS_USER 0x20000000 +#define MS_OWNER 0x10000000 #define MS_LOOP 0x00010000 /* Options that we keep the mount system call from seeing. */ @@ -115,9 +118,12 @@ struct opt_map /* Options that we keep from appearing in the options field in the mtab. */ #define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER) -/* OPTIONS that we make ordinary users have by default. */ +/* Options that we make ordinary users have by default. */ #define MS_SECURE (MS_NOEXEC|MS_NOSUID|MS_NODEV) +/* Options that we make owner-mounted devices have by default */ +#define MS_OWNERSECURE (MS_NOSUID|MS_NODEV) + const struct opt_map opt_map[] = { { "defaults", 0, 0, 0 }, /* default options */ { "ro", 1, 0, MS_RDONLY }, /* read-only */ @@ -137,6 +143,8 @@ const struct opt_map opt_map[] = { { "nousers", 0, 1, MS_USERS }, /* Forbid ordinary user to mount */ { "user", 0, 0, MS_USER }, /* Allow ordinary user to mount */ { "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 */ /* add new options here */ #ifdef MS_NOSUB { "sub", 0, 1, MS_NOSUB }, /* allow submounts */ @@ -244,6 +252,8 @@ parse_opt (const char *opt, int *mask, char *extra_opts) if ((om->mask == MS_USER || om->mask == MS_USERS) && !om->inv) *mask |= MS_SECURE; + if ((om->mask == MS_OWNER) && !om->inv) + *mask |= MS_OWNERSECURE; #ifdef MS_SILENT if (om->mask == MS_SILENT && om->inv) { mount_quiet = 1; @@ -377,6 +387,7 @@ create_mtab (void) { /* count successful mount system calls */ static int mountcount = 0; +/* returns 0: OK, -1: error */ static int mount5 (struct mountargs *args) { int ret = mount (args->spec, args->node, args->type, @@ -386,9 +397,9 @@ mount5 (struct mountargs *args) { return ret; } -/* Mount a single file system. Return status, - so don't exit on non-fatal errors. */ - +/* Mount a single file system. + Return status: 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) { struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts }; @@ -396,8 +407,14 @@ try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) { if (*type && strcasecmp (*type, "auto") == 0) *type = NULL; - if (!*type && !(flags & MS_REMOUNT)) + if (!*type && !(flags & MS_REMOUNT)) { *type = guess_fstype_from_superblock(spec); + if (*type && !strcmp(*type, "swap")) { + error(_("%s looks like swapspace - not mounted"), spec); + *type = NULL; + return 1; + } + } if (*type || (flags & MS_REMOUNT)) { args.type = *type; @@ -419,6 +436,7 @@ 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 */ @@ -438,6 +456,26 @@ try_mount_one (const char *spec0, const char *node0, char *type0, /* root may allow certain types of mounts by ordinary users */ 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)) { + struct stat sb; + + if (!stat(spec0, &sb)) { + if (getuid() == sb.st_uid) + flags |= MS_USER; + } + } + } + /* James Kehl <mkehl@gil.com.au> 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. + 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 (already (spec, node)) die (EX_USAGE, _("mount failed")); @@ -448,6 +486,9 @@ try_mount_one (const char *spec0, const char *node0, char *type0, 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; @@ -538,7 +579,8 @@ try_mount_one (const char *spec0, const char *node0, char *type0, sprintf(mountprog, "/sbin/mount.%s", type); if (stat(mountprog, &statbuf) == 0) { - if (fork() == 0) { + int res; + if ((res = fork()) == 0) { char *oo, *mountargs[10]; int i = 0; @@ -559,7 +601,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0, mountargs[i] = NULL; execv(mountprog, mountargs); exit(1); /* exec failed */ - } else if (fork() != -1) { + } else if (res != -1) { int status; wait(&status); return status; @@ -572,10 +614,11 @@ try_mount_one (const char *spec0, const char *node0, char *type0, block_signals (SIG_BLOCK); - if (fake - || (try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts)) == 0) + if (!fake) + mnt5_res = try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts); + + if (fake || mnt5_res == 0) { /* Mount succeeded, report this (if verbose) and write mtab entry. */ - { if (loop) opt_loopdev = loopdev; @@ -619,7 +662,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0, block_signals (SIG_UNBLOCK); return 0; - } + } mnt_err = errno; @@ -630,11 +673,17 @@ try_mount_one (const char *spec0, const char *node0, char *type0, /* Mount failed, complain, but don't die. */ - if (type == 0) - error (_("mount: you must specify the filesystem type")); - else - switch (mnt_err) - { + if (type == 0) { + if (suid) + error (_("mount: I could not determine the filesystem type, " + "and none was specified")); + else + error (_("mount: you must specify the filesystem type")); + } else if (mnt5_res != -1) { + /* should not happen */ + error (_("mount: mount failed")); + } else { + switch (mnt_err) { case EPERM: if (geteuid() == 0) { if (stat (node, &statbuf) || !S_ISDIR(statbuf.st_mode)) @@ -775,6 +824,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0, default: error ("mount: %s", strerror (mnt_err)); break; } + } return EX_FAIL; } diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c index 8e8207223..9e3a54a48 100644 --- a/mount/mount_guess_fstype.c +++ b/mount/mount_guess_fstype.c @@ -13,6 +13,9 @@ * * Wed Nov 11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before * /proc/filesystems + * [This was mainly in order to specify vfat before fat; these days we often + * detect *fat and then assume vfat, so perhaps /etc/filesystems isnt + * so useful anymore.] * * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org> * - added Native Language Support @@ -67,12 +70,17 @@ swapped(unsigned short a) { Added ufs from a patch by jj. But maybe there are several types of ufs? Added ntfs from a patch by Richard Russon. Added a very weak heuristic for vfat - aeb + Added qnx4 - aeb + Added swap - aeb - Currently supports: minix, ext, ext2, xiafs, iso9660, romfs, ufs, ntfs, vfat + Currently supports: minix, ext, ext2, xiafs, iso9660, romfs, + ufs, ntfs, vfat, qnx4, bfs */ static char *magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660", "romfs", - "ufs", "ntfs" }; + "ufs", "ntfs", "qnx4", "bfs", "udf", + "swap" /* last - just to warn the user */ +}; static int tested(const char *device) { @@ -84,6 +92,32 @@ tested(const char *device) { return 0; } +/* udf magic - I find that trying to mount garbage as an udf fs + causes a very large kernel delay, almost killing the machine. + So, we do not try udf unless there is positive evidence that it + might work. Try iso9660 first, it is much more likely. + + Strings below taken from ECMA 167. */ +static char +*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02", + "NSR03", "TEA01" }; + +static int +may_be_udf(const char *id) { + char **m; + + for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++) + if (!strncmp(*m, id, 5)) + return 1; + return 0; +} + +static int +may_be_swap(const char *s) { + return (strncmp(s-10, "SWAP-SPACE", 10) == 0 || + strncmp(s-10, "SWAPSPACE2", 10) == 0); +} + static char * fstype(const char *device) { int fd; @@ -96,6 +130,8 @@ fstype(const char *device) { union { struct xiafs_super_block xiasb; char romfs_magic[8]; + char qnx4fs_magic[10]; /* ignore first 4 bytes */ + long bfs_magic; struct ntfs_super_block ntfssb; struct fat_super_block fatsb; } xsb; @@ -141,11 +177,17 @@ fstype(const char *device) { type = "xiafs"; else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8)) type = "romfs"; + else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6)) + type = "qnx4fs"; + else if(xsb.bfs_magic == 0x1badface) + type = "bfs"; else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC, sizeof(xsb.ntfssb.s_magic))) type = "ntfs"; else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) || - !strncmp(xsb.fatsb.s_os, "MSWIN", 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_fs, "FAT12 ", 8) || !strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) || !strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8))) @@ -169,6 +211,28 @@ fstype(const char *device) { if(strncmp(isosb.iso.id, ISO_STANDARD_ID, sizeof(isosb.iso.id)) == 0 || strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) type = "iso9660"; + else if (may_be_udf(isosb.iso.id)) + type = "udf"; + } + + if (!type) { + /* perhaps the user tries to mount the swap space + on a new disk; warn her before she does mke2fs on it */ + int pagesize = getpagesize(); + int rd; + char buf[32768]; + + rd = pagesize; + if (rd < 8192) + rd = 8192; + if (rd > sizeof(buf)) + rd = sizeof(buf); + if (lseek(fd, 0, SEEK_SET) != 0 + || read(fd, buf, rd) != rd) + goto io_error; + if (may_be_swap(buf+pagesize) || + may_be_swap(buf+4096) || may_be_swap(buf+8192)) + type = "swap"; } close (fd); @@ -182,17 +246,19 @@ io_error: char * guess_fstype_from_superblock(const char *spec) { - char *type = fstype(spec); - if (verbose) { - printf (_("mount: you didn't specify a filesystem type for %s\n"), - spec); - if (type) - printf (_(" I will try type %s\n"), type); - else - printf (_(" I will try all types mentioned in %s or %s\n"), - ETC_FILESYSTEMS, PROC_FILESYSTEMS); - } - return type; + char *type = fstype(spec); + if (verbose) { + printf (_("mount: you didn't specify a filesystem type for %s\n"), + spec); + if (!type) + printf (_(" I will try all types mentioned in %s or %s\n"), + ETC_FILESYSTEMS, PROC_FILESYSTEMS); + else if (!strcmp(type, "swap")) + printf (_(" and it looks like this is swapspace\n")); + else + printf (_(" I will try type %s\n"), type); + } + return type; } static FILE *procfs; @@ -237,17 +303,24 @@ is_in_procfs(const char *type) { return 0; } +/* return: 0: OK, -1: error in errno, 1: type not found */ +/* when 1 is returned, *type is NULL */ int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args, char **type) { char *fsname; + *type = NULL; if (!procfsopen()) - return -1; + return 1; while ((fsname = procfsnext()) != NULL) { if (tested (fsname)) continue; args->type = fsname; + if (verbose) { + printf(_("Trying %s\n"), fsname); + fflush(stdout); + } if ((*mount_fn) (args) == 0) { *type = xstrdup(fsname); procfsclose(); @@ -255,13 +328,11 @@ procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args, } else if (errno != EINVAL) { *type = "guess"; procfsclose(); - return 1; + return -1; } } procfsclose(); - *type = NULL; - - return -1; + return 1; } int diff --git a/mount/realpath.c b/mount/realpath.c index 0eebba3ac..f0d7c76c0 100644 --- a/mount/realpath.c +++ b/mount/realpath.c @@ -13,170 +13,109 @@ * GNU Library Public License for more details. */ -#define HAVE_GETCWD - /* * This routine is part of libc. We include it nevertheless, * since the libc version has some security flaws. */ -#ifdef __linux__ -extern char *realpath(const char *path, char *resolved_path); -#define HAVE_UNISTD_H -#define HAVE_STRING_H -#endif - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#if defined(HAVE_UNISTD_H) || defined(STDC_HEADERS) +#include <limits.h> /* for PATH_MAX */ #include <unistd.h> -#endif -#include <stdio.h> -#ifdef HAVE_STRING_H #include <string.h> -#else -#include <strings.h> -#endif -#ifdef _POSIX_VERSION -#include <limits.h> /* for PATH_MAX */ -#else -#include <sys/param.h> /* for MAXPATHLEN */ -#endif #include <errno.h> - -#include <sys/stat.h> /* for S_IFLNK */ - -#ifndef PATH_MAX -#ifdef _POSIX_VERSION -#define PATH_MAX _POSIX_PATH_MAX -#else -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif +#include "realpath.h" +#include "sundries.h" /* for xstrdup */ #define MAX_READLINKS 32 -#ifdef __STDC__ -char *realpath(const char *path, char *resolved_path) -#else -char *realpath(path, resolved_path) -const char *path; -char *resolved_path; -#endif -{ - char copy_path[PATH_MAX]; - char link_path[PATH_MAX]; - char *new_path = resolved_path; - char *max_path; +char * +myrealpath(const char *path, char *resolved_path, int maxreslth) { + char *npath; + char link_path[PATH_MAX+1]; int readlinks = 0; int n; - /* Make a copy of the source path since we may need to modify it. */ - if (strlen(path) >= PATH_MAX) { - errno = ENAMETOOLONG; - return NULL; - } - strcpy(copy_path, path); - path = copy_path; - max_path = copy_path + PATH_MAX - 2; + npath = resolved_path; - /* If it's a relative pathname use getwd for starters. */ + /* If it's a relative pathname use getcwd for starters. */ if (*path != '/') { -#ifdef HAVE_GETCWD - getcwd(new_path, PATH_MAX - 1); -#else - getwd(new_path); -#endif - new_path += strlen(new_path); - if (new_path[-1] != '/') - *new_path++ = '/'; - } - else { - *new_path++ = '/'; + getcwd(npath, maxreslth-2); + npath += strlen(npath); + if (npath[-1] != '/') + *npath++ = '/'; + } else { + *npath++ = '/'; path++; } + /* Expand each slash-separated pathname component. */ while (*path != '\0') { - /* Ignore stray "/". */ + /* Ignore stray "/" */ if (*path == '/') { path++; continue; } - if (*path == '.') { - /* Ignore ".". */ - if (path[1] == '\0' || path[1] == '/') { - path++; - continue; - } - if (path[1] == '.') { - if (path[2] == '\0' || path[2] == '/') { - path += 2; - /* Ignore ".." at root. */ - if (new_path == resolved_path + 1) - continue; - /* Handle ".." by backing up. */ - while ((--new_path)[-1] != '/') - ; - continue; - } - } + if (*path == '.' && (path[1] == '\0' || path[1] == '/')) { + /* Ignore "." */ + path++; + continue; + } + if (*path == '.' && path[1] == '.' && + (path[2] == '\0' || path[2] == '/')) { + /* Backup for ".." */ + path += 2; + while (npath > resolved_path+1 && + (--npath)[-1] != '/') + ; + continue; } /* Safely copy the next pathname component. */ while (*path != '\0' && *path != '/') { - if (path > max_path) { + if (npath-resolved_path > maxreslth-2) { errno = ENAMETOOLONG; return NULL; } - *new_path++ = *path++; + *npath++ = *path++; } -#ifdef S_IFLNK + /* Protect against infinite loops. */ if (readlinks++ > MAX_READLINKS) { errno = ELOOP; return NULL; } + /* See if latest pathname component is a symlink. */ - *new_path = '\0'; - n = readlink(resolved_path, link_path, PATH_MAX - 1); + *npath = '\0'; + n = readlink(resolved_path, link_path, PATH_MAX); if (n < 0) { /* EINVAL means the file exists but isn't a symlink. */ if (errno != EINVAL) return NULL; - } - else { + } else { /* Note: readlink doesn't add the null byte. */ link_path[n] = '\0'; if (*link_path == '/') /* Start over for an absolute symlink. */ - new_path = resolved_path; + npath = resolved_path; else /* Otherwise back up over this component. */ - while (*(--new_path) != '/') + while (*(--npath) != '/') ; /* Safe sex check. */ - if (strlen(path) + n >= PATH_MAX) { + if (strlen(path) + n >= sizeof(link_path)) { errno = ENAMETOOLONG; return NULL; } /* Insert symlink contents into path. */ strcat(link_path, path); - strcpy(copy_path, link_path); - path = copy_path; + path = xstrdup(link_path); } -#endif /* S_IFLNK */ - *new_path++ = '/'; + + *npath++ = '/'; } /* Delete trailing slash but don't whomp a lone slash. */ - if (new_path != resolved_path + 1 && new_path[-1] == '/') - new_path--; + if (npath != resolved_path+1 && npath[-1] == '/') + npath--; /* Make sure it's null terminated. */ - *new_path = '\0'; + *npath = '\0'; return resolved_path; } diff --git a/mount/realpath.h b/mount/realpath.h new file mode 100644 index 000000000..206e53c10 --- /dev/null +++ b/mount/realpath.h @@ -0,0 +1 @@ +extern char *myrealpath(const char *path, char *resolved_path, int m); diff --git a/mount/sundries.c b/mount/sundries.c index a844724e9..de17b256d 100644 --- a/mount/sundries.c +++ b/mount/sundries.c @@ -14,6 +14,7 @@ #include <mntent.h> /* for MNTTYPE_SWAP */ #include "fstab.h" #include "sundries.h" +#include "realpath.h" #include "nfsmount.h" #include "nls.h" @@ -224,9 +225,9 @@ canonicalize (const char *path) { if (streq(path, "none") || streq(path, "proc") || streq(path, "devpts")) return xstrdup(path); - canonical = xmalloc (PATH_MAX + 1); + canonical = xmalloc (PATH_MAX+2); - if (realpath (path, canonical)) + if (myrealpath (path, canonical, PATH_MAX+1)) return canonical; free(canonical); diff --git a/mount/umount.c b/mount/umount.c index 36f9407f2..98a1d330a 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -49,17 +49,21 @@ #include <arpa/inet.h> #endif -#ifdef MNT_FORCE +#if defined(MNT_FORCE) && !defined(__sparc__) && !defined(__arm__) /* Interesting ... it seems libc knows about MNT_FORCE and presumably about umount2 as well -- need not do anything */ #else /* MNT_FORCE */ -static int umount2(const char *path, int flags); /* Does the present kernel source know about umount2? */ #include <linux/unistd.h> #ifdef __NR_umount2 + +static int umount2(const char *path, int flags); + _syscall2(int, umount2, const char *, path, int, flags); + #else /* __NR_umount2 */ + static int umount2(const char *path, int flags) { fprintf(stderr, _("umount: compiled without support for -f\n")); @@ -68,8 +72,10 @@ umount2(const char *path, int flags) { } #endif /* __NR_umount2 */ +#if !defined(MNT_FORCE) /* dare not try to include <linux/mount.h> -- lots of errors */ #define MNT_FORCE 1 +#endif #endif /* MNT_FORCE */ @@ -476,14 +482,21 @@ main (int argc, char *argv[]) die (2, _("umount: %s is not mounted (according to mtab)"), file); if (getmntfilesbackward (file, mc)) die (2, _("umount: it seems %s is mounted multiple times"), file); - if (!(fs = getfsspec (file)) && !(fs = getfsfile (file))) - die (2, _("umount: %s is not in the fstab (and you are not root)"), + + /* If fstab contains the two lines + /dev/sda1 /mnt/zip auto user,noauto 0 0 + /dev/sda4 /mnt/zip auto user,noauto 0 0 + then "mount /dev/sda4" followed by "umount /mnt/zip" + used to fail. So, we must not look for file, but for + the pair (spec,file) in fstab. */ + fs = getfsspecfile(mc->mnt_fsname, mc->mnt_dir); + if (!fs) { + if (!getfsspec (file) && !getfsfile (file)) + die (2, + _("umount: %s is not in the fstab (and you are not root)"), file); - if ((!streq (mc->mnt_fsname, fs->mnt_fsname) && - !streq (mc->mnt_fsname, canonicalize (fs->mnt_fsname))) - || (!streq (mc->mnt_dir, fs->mnt_dir) && - !streq (mc->mnt_dir, canonicalize (fs->mnt_dir)))) { - die (2, _("umount: %s mount disagrees with the fstab"), file); + else + die (2, _("umount: %s mount disagrees with the fstab"), file); } /* User mounting and unmounting is allowed only @@ -492,19 +505,22 @@ main (int argc, char *argv[]) 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. */ options = parse_list (fs->mnt_opts); while (options) { if (streq (car (options), "user") || - streq (car (options), "users")) + streq (car (options), "users") || + streq (car (options), "owner")) break; options = cdr (options); } if (!options) die (2, _("umount: only root can unmount %s from %s"), fs->mnt_fsname, fs->mnt_dir); - if (streq (car (options), "user")) { + if (streq (car (options), "user") || + streq (car (options), "owner")) { char *user = getusername(); options = parse_list (mc->mnt_opts); diff --git a/mount/version.c b/mount/version.c index 790c447bf..a98d11874 100644 --- a/mount/version.c +++ b/mount/version.c @@ -1,2 +1,2 @@ -#include "../version.h" +#include "../defines.h" char version[] = "mount-" UTIL_LINUX_VERSION; |