summaryrefslogtreecommitdiff
path: root/mount/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'mount/mount.c')
-rw-r--r--mount/mount.c471
1 files changed, 245 insertions, 226 deletions
diff --git a/mount/mount.c b/mount/mount.c
index 083e747a..a9ee637d 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -2,43 +2,7 @@
* A mount(8) for Linux 0.99.
* mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
*
- * Wed Sep 14 22:43:00 1994: Mitchum DSouza
- * (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for mounting
- * the "loop" device.
- *
- * Wed Sep 14 22:55:10 1994: Sander van Malssen (svm@kozmix.hacktic.nl)
- * added support for remounting readonly file systems readonly.
- *
- * Wed Feb 8 12:27:00 1995: Andries.Brouwer@cwi.nl fixed up error messages.
- * Sat Jun 3 20:44:38 1995: Patches from Andries.Brouwer@cwi.nl applied.
- * Tue Sep 26 22:38:20 1995: aeb@cwi.nl, many changes
- * Fri Feb 23 13:47:00 1996: aeb@cwi.nl, loop device related changes
- *
- * Since then, many changes - aeb.
- *
- * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
- * Implemented the "bg", "fg" and "retry" mount options for NFS.
- *
- * Tue Aug 4 15:54:31 1998: aeb@cwi.nl:
- * Open fd 0,1,2 so that printf's do not clobber /etc/mtab or so.
- * Mangle filenames with embedded spaces. Add ufsmagic. Add locking.
- * Avoid unnecessary error messages about /proc.
- * Improve support for noncanonical names in /etc/fstab.
- * Add support for volume labels and UUIDs.
- *
- * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - 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
- * 2000-05-11 Mark A. Peloquin <peloquin@us.ibm.com>
- * - check_special_mountprog now returns correct status
- * 2000-11-08 aeb: accept nonnumeric uid=, gid= options
- * 2001-07-13 Michael K. Johnson <johnsonm@redhat.com>
- * - implemented -a -O
+ * Modifications by many people. Distributed under GPL.
*/
#include <unistd.h>
@@ -69,6 +33,7 @@
#include "mount_guess_fstype.h"
#include "mount_by_label.h"
#include "getusername.h"
+#include "paths.h"
#include "env.h"
#include "nls.h"
@@ -131,11 +96,11 @@ struct opt_map {
#define MS_USERS 0x40000000
#define MS_USER 0x20000000
#define MS_OWNER 0x10000000
-#define MS_NETDEV 0x00020000
+#define MS_COMMENT 0x00020000
#define MS_LOOP 0x00010000
/* Options that we keep the mount system call from seeing. */
-#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_NETDEV|MS_LOOP)
+#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_COMMENT|MS_LOOP)
/* Options that we keep from appearing in the options field in the mtab. */
#define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
@@ -170,7 +135,9 @@ static const struct opt_map opt_map[] = {
{ "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 */
- { "_netdev", 0, 0, MS_NETDEV }, /* Device accessible only via network */
+ { "_netdev", 0, 0, MS_COMMENT}, /* Device requires network */
+ { "comment", 0, 0, MS_COMMENT}, /* fstab comment only (kudzu,_netdev)*/
+
/* add new options here */
#ifdef MS_NOSUB
{ "sub", 0, 1, MS_NOSUB }, /* allow submounts */
@@ -196,19 +163,20 @@ static const struct opt_map opt_map[] = {
{ NULL, 0, 0, 0 }
};
-static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
- *opt_speed;
+static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
+ *opt_speed, *opt_comment;
static struct string_opt_map {
char *tag;
int skip;
- char **valptr;
+ const char **valptr;
} string_opt_map[] = {
{ "loop=", 0, &opt_loopdev },
{ "vfs=", 1, &opt_vfstype },
{ "offset=", 0, &opt_offset },
{ "encryption=", 0, &opt_encryption },
{ "speed=", 0, &opt_speed },
+ { "comment=", 1, &opt_comment },
{ NULL, 0, NULL }
};
@@ -239,23 +207,23 @@ int mount_quiet=0;
/* Report on a single mount. */
static void
-print_one (const struct mntent *me) {
- if (mount_quiet)
- return;
- printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
- if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
- printf (" type %s", me->mnt_type);
- if (me->mnt_opts != NULL)
- printf (" (%s)", me->mnt_opts);
- if (list_with_volumelabel) {
- const char *label;
- label = mount_get_volume_label_by_spec(me->mnt_fsname);
- if (label) {
- printf (" [%s]", label);
- /* free(label); */
- }
- }
- printf ("\n");
+print_one (const struct my_mntent *me) {
+ if (mount_quiet)
+ return;
+ printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
+ if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
+ printf (" type %s", me->mnt_type);
+ if (me->mnt_opts != NULL)
+ printf (" (%s)", me->mnt_opts);
+ if (list_with_volumelabel) {
+ const char *label;
+ label = mount_get_volume_label_by_spec(me->mnt_fsname);
+ if (label) {
+ printf (" [%s]", label);
+ /* free(label); */
+ }
+ }
+ printf ("\n");
}
/* Report on everything in mtab (of the specified types if any). */
@@ -271,6 +239,11 @@ print_all (char *types) {
exit (0);
}
+static void
+my_free(const void *s) {
+ if (s)
+ free((void *) s);
+}
/*
* Look for OPT in opt_map table and return mask value.
@@ -332,21 +305,24 @@ parse_opt (const char *opt, int *mask, char *extra_opts) {
/* Take -o options list and compute 4th and 5th args to mount(2). flags
gets the standard options (indicated by bits) and extra_opts all the rest */
static void
-parse_opts (char *opts, int *flags, char **extra_opts) {
- char *opt;
-
+parse_opts (const char *options, int *flags, char **extra_opts) {
*flags = 0;
*extra_opts = NULL;
clear_string_opts();
- if (opts != NULL) {
+ if (options != NULL) {
+ char *opts = xstrdup(options);
+ char *opt;
+
*extra_opts = xmalloc (strlen (opts) + 1);
**extra_opts = '\0';
for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ","))
if (!parse_string_opt (opt))
parse_opt (opt, flags, *extra_opts);
+
+ free(opts);
}
if (readonly)
@@ -363,7 +339,7 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) {
const struct string_opt_map *m;
char *new_opts;
- new_opts = (flags & MS_RDONLY) ? "ro" : "rw";
+ new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
for (om = opt_map; om->opt != NULL; om++) {
if (om->skip)
continue;
@@ -388,63 +364,66 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) {
static int
already (const char *spec, const char *node) {
- struct mntentchn *mc;
- int ret = 1;
-
- if ((mc = getmntfile(node)) != NULL)
- error (_("mount: according to mtab, %s is already mounted on %s"),
- mc->m.mnt_fsname, node);
- else if (spec && strcmp (spec, "none") &&
- (mc = getmntfile(spec)) != NULL)
- error (_("mount: according to mtab, %s is mounted on %s"),
- spec, mc->m.mnt_dir);
- else
- ret = 0;
- return ret;
+ struct mntentchn *mc;
+ int ret = 1;
+
+ if ((mc = getmntfile(node)) != NULL)
+ error (_("mount: according to mtab, "
+ "%s is already mounted on %s"),
+ mc->m.mnt_fsname, node);
+ else if (spec && strcmp (spec, "none") &&
+ (mc = getmntfile(spec)) != NULL)
+ error (_("mount: according to mtab, %s is mounted on %s"),
+ spec, mc->m.mnt_dir);
+ else
+ ret = 0;
+ return ret;
}
/* Create mtab with a root entry. */
static void
create_mtab (void) {
- struct mntentchn *fstab;
- struct mntent mnt;
- int flags;
- char *extra_opts;
- mntFILE *mfp;
-
- lock_mtab();
-
- mfp = my_setmntent (MOUNTED, "a+");
- if (mfp == NULL || mfp->mntent_fp == NULL) {
- int errsv = errno;
- die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
- MOUNTED, strerror (errsv));
- }
+ struct mntentchn *fstab;
+ struct my_mntent mnt;
+ int flags;
+ mntFILE *mfp;
+
+ lock_mtab();
+
+ mfp = my_setmntent (MOUNTED, "a+");
+ if (mfp == NULL || mfp->mntent_fp == NULL) {
+ int errsv = errno;
+ die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
+ MOUNTED, strerror (errsv));
+ }
- /* Find the root entry by looking it up in fstab */
- if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
- parse_opts (xstrdup (fstab->m.mnt_opts), &flags, &extra_opts);
- mnt.mnt_dir = "/";
- mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
- mnt.mnt_type = fstab->m.mnt_type;
- mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
- mnt.mnt_freq = mnt.mnt_passno = 0;
-
- if (my_addmntent (mfp, &mnt) == 1) {
- int errsv = errno;
- die (EX_FILEIO, _("mount: error writing %s: %s"),
- MOUNTED, strerror (errsv));
- }
- }
- if (fchmod (fileno (mfp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
- if (errno != EROFS) {
- int errsv = errno;
- die (EX_FILEIO, _("mount: error changing mode of %s: %s"),
- MOUNTED, strerror (errsv));
- }
- my_endmntent (mfp);
+ /* Find the root entry by looking it up in fstab */
+ if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
+ char *extra_opts;
+ parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
+ mnt.mnt_dir = "/";
+ mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
+ mnt.mnt_type = fstab->m.mnt_type;
+ mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
+ mnt.mnt_freq = mnt.mnt_passno = 0;
+ my_free(extra_opts);
+
+ if (my_addmntent (mfp, &mnt) == 1) {
+ int errsv = errno;
+ die (EX_FILEIO, _("mount: error writing %s: %s"),
+ MOUNTED, strerror (errsv));
+ }
+ }
+ if (fchmod (fileno (mfp->mntent_fp), 0644) < 0)
+ if (errno != EROFS) {
+ int errsv = errno;
+ die (EX_FILEIO,
+ _("mount: error changing mode of %s: %s"),
+ MOUNTED, strerror (errsv));
+ }
+ my_endmntent (mfp);
- unlock_mtab();
+ unlock_mtab();
}
/* count successful mount system calls */
@@ -477,8 +456,8 @@ do_mount_syscall (struct mountargs *args) {
* on return types is filled with the type used.
*/
static int
-guess_fstype_and_mount (char *spec, char *node, char **types,
- int flags, char *mount_opts) {
+guess_fstype_and_mount(const char *spec, const char *node, const char **types,
+ int flags, char *mount_opts) {
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
if (*types && strcasecmp (*types, "auto") == 0)
@@ -526,12 +505,12 @@ guess_fstype_and_mount (char *spec, char *node, char **types,
* Die if the user is not allowed to do this.
*/
static void
-suid_check(char *spec, char *node, int *flags, char **user) {
+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. */
+ 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;
@@ -545,14 +524,14 @@ suid_check(char *spec, char *node, int *flags, char **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. */
+ 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))
+ if (already (spec, node))
die (EX_USAGE, _("mount failed"));
else
- die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
+ die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
}
if (*flags & MS_USER)
*user = getusername();
@@ -563,8 +542,8 @@ suid_check(char *spec, char *node, int *flags, char **user) {
}
static int
-loop_check(char **spec, char **type, int *flags,
- int *loop, char **loopdev, char **loopfile) {
+loop_check(const char **spec, const char **type, int *flags,
+ int *loop, const char **loopdev, const char **loopfile) {
int looptype;
unsigned long long offset;
@@ -627,45 +606,47 @@ loop_check(char **spec, char **type, int *flags,
}
static void
-update_mtab_entry(char *spec, char *node, char *type, char *opts,
- int flags, int freq, int pass) {
- struct mntent mnt;
-
- mnt.mnt_fsname = canonicalize (spec);
- mnt.mnt_dir = canonicalize (node);
- mnt.mnt_type = type;
- mnt.mnt_opts = opts;
- mnt.mnt_freq = freq;
- mnt.mnt_passno = pass;
+update_mtab_entry(const char *spec, const char *node, const char *type,
+ const char *opts, int flags, int freq, int pass) {
+ struct my_mntent mnt;
+
+ mnt.mnt_fsname = canonicalize (spec);
+ mnt.mnt_dir = canonicalize (node);
+ mnt.mnt_type = type;
+ mnt.mnt_opts = opts;
+ mnt.mnt_freq = freq;
+ mnt.mnt_passno = pass;
- /* We get chatty now rather than after the update to mtab since the
- mount succeeded, even if the write to /etc/mtab should fail. */
- if (verbose)
- print_one (&mnt);
-
- if (!nomtab && mtab_is_writable()) {
- if (flags & MS_REMOUNT)
- update_mtab (mnt.mnt_dir, &mnt);
- else {
- mntFILE *mfp;
-
- lock_mtab();
- mfp = my_setmntent(MOUNTED, "a+");
- if (mfp == NULL || mfp->mntent_fp == NULL) {
- int errsv = errno;
- error(_("mount: can't open %s: %s"), MOUNTED,
- strerror (errsv));
- } else {
- if ((my_addmntent (mfp, &mnt)) == 1) {
- int errsv = errno;
- error(_("mount: error writing %s: %s"), MOUNTED,
- strerror (errsv));
+ /* We get chatty now rather than after the update to mtab since the
+ mount succeeded, even if the write to /etc/mtab should fail. */
+ if (verbose)
+ print_one (&mnt);
+
+ if (!nomtab && mtab_is_writable()) {
+ if (flags & MS_REMOUNT)
+ update_mtab (mnt.mnt_dir, &mnt);
+ else {
+ mntFILE *mfp;
+
+ lock_mtab();
+ mfp = my_setmntent(MOUNTED, "a+");
+ if (mfp == NULL || mfp->mntent_fp == NULL) {
+ int errsv = errno;
+ error(_("mount: can't open %s: %s"), MOUNTED,
+ strerror (errsv));
+ } else {
+ if ((my_addmntent (mfp, &mnt)) == 1) {
+ int errsv = errno;
+ error(_("mount: error writing %s: %s"),
+ MOUNTED, strerror (errsv));
+ }
+ }
+ my_endmntent(mfp);
+ unlock_mtab();
}
- my_endmntent(mfp);
- }
- unlock_mtab();
}
- }
+ my_free(mnt.mnt_fsname);
+ my_free(mnt.mnt_dir);
}
static void
@@ -677,20 +658,21 @@ set_pfd(char *s) {
}
static void
-cdrom_setspeed(char *spec) {
+cdrom_setspeed(const char *spec) {
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
- if (opt_speed) {
- int cdrom;
- int speed = atoi(opt_speed);
-
- if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
- die(EX_FAIL, _("mount: cannot open %s for setting speed"),
- spec);
- if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
- die(EX_FAIL, _("mount: cannot set speed: %s"),
- strerror(errno));
- close(cdrom);
- }
+ if (opt_speed) {
+ int cdrom;
+ int speed = atoi(opt_speed);
+
+ if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
+ die(EX_FAIL,
+ _("mount: cannot open %s for setting speed"),
+ spec);
+ if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
+ die(EX_FAIL, _("mount: cannot set speed: %s"),
+ strerror(errno));
+ close(cdrom);
+ }
}
/*
@@ -700,8 +682,8 @@ cdrom_setspeed(char *spec) {
*/
static int
-check_special_mountprog(char *spec, char *node, char *type, int flags,
- char *extra_opts, int *status) {
+check_special_mountprog(const char *spec, const char *node, const char *type,
+ int flags, char *extra_opts, int *status) {
char mountprog[120];
struct stat statbuf;
int res;
@@ -714,7 +696,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
if (stat(mountprog, &statbuf) == 0) {
res = fork();
if (res == 0) {
- char *oo, *mountargs[10];
+ const char *oo, *mountargs[10];
int i = 0;
setuid(getuid());
@@ -732,7 +714,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
mountargs[i++] = oo;
}
mountargs[i] = NULL;
- execv(mountprog, mountargs);
+ execv(mountprog, (char **) mountargs);
exit(1); /* exec failed */
} else if (res != -1) {
int st;
@@ -758,32 +740,35 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
* return status from wait
*/
static int
-try_mount_one (const char *spec0, const char *node0, char *types0,
+try_mount_one (const char *spec0, const char *node0, const char *types0,
const char *opts0, int freq, int pass, int bg, int ro) {
- int res, status;
+ int res = 0, status;
int mnt5_res = 0; /* only for gcc */
int mnt_err;
int flags;
char *extra_opts; /* written in mtab */
char *mount_opts; /* actually used on system call */
- const char *opts;
- char *spec, *node, *types;
+ const char *opts, *spec, *node, *types;
char *user = 0;
int loop = 0;
- char *loopdev = 0, *loopfile = 0;
+ const char *loopdev = 0, *loopfile = 0;
struct stat statbuf;
int nfs_mount_version = 0; /* any version */
- spec = xstrdup(spec0);
- node = xstrdup(node0);
- types = xstrdup(types0);
- opts = xstrdup(opts0);
+ /* copies for freeing on exit */
+ const char *opts1, *spec1, *node1, *types1, *extra_opts1;
- parse_opts (xstrdup (opts), &flags, &extra_opts);
+ spec = spec1 = xstrdup(spec0);
+ node = node1 = xstrdup(node0);
+ types = types1 = xstrdup(types0);
+ opts = opts1 = xstrdup(opts0);
+
+ parse_opts (opts, &flags, &extra_opts);
+ extra_opts1 = extra_opts;
/* quietly succeed for fstab entries that don't get mounted automatically */
if (mount_all && (flags & MS_NOAUTO))
- return 0;
+ goto out;
suid_check(spec, node, &flags, &user);
@@ -800,7 +785,7 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
*/
res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
if (res)
- return res;
+ goto out;
}
/*
@@ -808,8 +793,10 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
* For the moment these types are ncpfs and smbfs. Maybe also vxfs.
* All such special things must occur isolated in the types string.
*/
- if (check_special_mountprog (spec, node, types, flags, extra_opts, &status))
- return status;
+ if (check_special_mountprog(spec, node, types, flags, extra_opts, &status)) {
+ res = status;
+ goto out;
+ }
/*
* Also nfs requires a separate program, but it is built in.
@@ -819,11 +806,13 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
retry_nfs:
mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
&nfs_mount_version, bg);
- if (mnt_err)
- return mnt_err;
+ if (mnt_err) {
+ res = mnt_err;
+ goto out;
+ }
#else
die (EX_SOFTWARE, _("mount: this version was compiled "
- "without support for the type `nfs'"));
+ "without support for the type `nfs'"));
#endif
}
@@ -847,7 +836,8 @@ retry_nfs:
pass);
block_signals (SIG_UNBLOCK);
- return 0;
+ res = 0;
+ goto out;
}
mnt_err = errno;
@@ -913,13 +903,13 @@ retry_nfs:
else if (stat (spec, &statbuf))
error (_("mount: special device %s does not exist"), spec);
else {
- errno = mnt_err;
- perror("mount");
+ errno = mnt_err;
+ perror("mount");
}
break;
case ENOTDIR:
if (stat (node, &statbuf) || ! S_ISDIR(statbuf.st_mode))
- error (_("mount: mount point %s is not a directory"), node);
+ error (_("mount: mount point %s is not a directory"), node);
else if (stat (spec, &statbuf) && errno == ENOTDIR)
error (_("mount: special device %s does not exist\n"
" (a path prefix is not a directory)\n"), spec);
@@ -981,7 +971,7 @@ retry_nfs:
char *lowtype, *p;
int u;
- error (_("mount: fs type %s not supported by kernel"), types);
+ error (_("mount: unknown filesystem type '%s'"), types);
/* maybe this loser asked for FAT or ISO9660 or isofs */
lowtype = xstrdup(types);
@@ -995,7 +985,9 @@ retry_nfs:
if (u && is_in_procfs(lowtype) == 1)
error (_("mount: probably you meant %s"), lowtype);
else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1)
- error (_("mount: maybe you meant iso9660 ?"));
+ error (_("mount: maybe you meant 'iso9660'?"));
+ else if (!strncmp(lowtype, "fat", 3) && is_in_procfs("vfat") == 1)
+ error (_("mount: maybe you meant 'vfat'?"));
free(lowtype);
} else
error (_("mount: %s has wrong device number or fs type %s not supported"),
@@ -1033,16 +1025,18 @@ retry_nfs:
types = types0;
}
if (opts) {
- char *opts1 = realloc(xstrdup(opts), strlen(opts)+4);
- strcat(opts1, ",ro");
- opts = opts1;
+ char *opts2 = realloc(xstrdup(opts), strlen(opts)+4);
+ strcat(opts2, ",ro");
+ my_free(opts1);
+ opts = opts1 = opts2;
} else
opts = "ro";
if (types && !strcmp(types, "guess"))
types = 0;
error (_("mount: %s%s is write-protected, mounting read-only"),
bd, spec0);
- return try_mount_one (spec0, node0, types, opts, freq, pass, bg, 1);
+ res = try_mount_one (spec0, node0, types, opts, freq, pass, bg, 1);
+ goto out;
}
break;
}
@@ -1050,7 +1044,16 @@ retry_nfs:
error ("mount: %s", strerror (mnt_err)); break;
}
}
- return EX_FAIL;
+ res = EX_FAIL;
+
+ out:
+ my_free(extra_opts1);
+ my_free(spec1);
+ my_free(node1);
+ my_free(opts1);
+ my_free(types1);
+
+ return res;
}
/*
@@ -1094,14 +1097,20 @@ usersubst(const char *opts) {
}
return opts;
}
-
+
+static int
+is_existing_file (const char *s) {
+ struct stat statbuf;
+
+ return (stat(s, &statbuf) == 0);
+}
/*
* Return 0 for success (either mounted sth or -a and NOAUTO was given)
*/
static int
-mount_one (const char *spec, const char *node, char *types, const char *opts,
- char *cmdlineopts, int freq, int pass) {
+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;
@@ -1119,7 +1128,7 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
if (nspec)
spec = nspec;
- if (types == NULL && !mounttype) {
+ if (types == NULL && !mounttype && !is_existing_file(spec)) {
if (strchr (spec, ':') != NULL) {
types = "nfs";
if (verbose)
@@ -1161,25 +1170,34 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
/* Check if an fsname/dir pair was already in the old mtab. */
static int
-mounted (const char *spec, char *node) {
- struct mntentchn *mc, *mc0;
-
- /* Handle possible UUID= and LABEL= in spec */
- spec = mount_get_devname(spec);
+mounted (const char *spec0, const char *node0) {
+ struct mntentchn *mc, *mc0;
+ char *spec, *node;
+ int ret = 0;
+
+ /* Handle possible UUID= and LABEL= in spec */
+ spec0 = mount_get_devname(spec0);
+
+ spec = canonicalize(spec0);
+ node = canonicalize(node0);
+
+ mc0 = mtab_head();
+ for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
+ if (streq (spec, mc->m.mnt_fsname) &&
+ streq (node, mc->m.mnt_dir)) {
+ ret = 1;
+ break;
+ }
- spec = canonicalize(spec);
- node = canonicalize(node);
+ free(spec);
+ free(node);
- mc0 = mtab_head();
- for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if (streq (spec, mc->m.mnt_fsname) && streq (node, mc->m.mnt_dir))
- return 1;
- return 0;
+ return ret;
}
/* avoid using stat() on things we are not going to mount anyway.. */
static int
-has_noauto (char *opts) {
+has_noauto (const char *opts) {
char *s;
if (!opts)
@@ -1586,8 +1604,7 @@ main (int argc, char *argv[]) {
die (EX_USAGE,
_("mount: cannot find %s in %s"),
spec, _PATH_FSTAB);
- /* struct mntent does not have const qualifiers */
- mc->m.mnt_fsname = (char *) spec;
+ mc->m.mnt_fsname = spec;
} else {
/* Try to find the other pathname in fstab. */
spec = canonicalize (*argv);
@@ -1605,6 +1622,8 @@ main (int argc, char *argv[]) {
/* Earlier mtab was tried first, but this would
sometimes try the wrong mount in case mtab had
the root device entry wrong. */
+
+ my_free(spec);
}
result = mount_one (xstrdup (mc->m.mnt_fsname),