Signed-off-by: Kay Sievers <[EMAIL PROTECTED]>
Signed-off-by: Karel Zak <[EMAIL PROTECTED]>
---
mount/Makefile.am | 15 +--
mount/fsprobe.c | 164 ++++++++++++++++++++++++++++++++
mount/fsprobe.h | 17 ++++
mount/fsprobe_blkid.c | 11 ++
mount/mount.c | 43 +++++++--
mount/mount_guess_fstype.c | 225 --------------------------------------------
mount/mount_guess_fstype.h | 16 ---
mount/mount_paths.h | 3 +
8 files changed, 232 insertions(+), 262 deletions(-)
diff --git a/mount/Makefile.am b/mount/Makefile.am
index 6f63dcf..b5b21b5 100644
--- a/mount/Makefile.am
+++ b/mount/Makefile.am
@@ -7,24 +7,17 @@ sbin_PROGRAMS = losetup swapon
man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
MNTHDRS = fstab.h linux_fs.h mount_mntent.h mount_constants.h my_dev_t.h \
- mount_paths.h lomount.h fsprobe.h \
- mount_guess_fstype.h realpath.h xmalloc.h \
- getusername.h loop.h mount_guess_rootdev.h \
- sundries.h
+ mount_paths.h lomount.h fsprobe.h realpath.h xmalloc.h \
+ getusername.h loop.h mount_guess_rootdev.h sundries.h
mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c
\
- mount_guess_fstype.c \
- getusername.c \
- lomount.c \
- $(MNTHDRS)
+ fsprobe.c getusername.c lomount.c $(MNTHDRS)
mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a
mount_CFLAGS = $(SUID_CFLAGS)
umount_SOURCES = umount.c fstab.c sundries.c xmalloc.c realpath.c
mount_mntent.c \
- getusername.c \
- lomount.c \
- $(MNTHDRS)
+ getusername.c fsprobe.c lomount.c $(MNTHDRS)
umount_LDADD = $(top_srcdir)/lib/libenv.a
umount_CFLAGS = $(SUID_CFLAGS)
diff --git a/mount/fsprobe.c b/mount/fsprobe.c
new file mode 100644
index 0000000..4b57802
--- /dev/null
+++ b/mount/fsprobe.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "mount_paths.h"
+#include "linux_fs.h"
+#include "fsprobe.h"
+#include "sundries.h" /* for xstrdup */
+#include "nls.h"
+
+/* list of already tested filesystems by fsprobe_procfsloop_mount() */
+static struct tried {
+ struct tried *next;
+ char *type;
+} *tried = NULL;
+
+static int
+was_tested(const char *fstype) {
+ struct tried *t;
+
+ if (fsprobe_known_fstype(fstype))
+ return 1;
+ for (t = tried; t; t = t->next) {
+ if (!strcmp(t->type, fstype))
+ return 1;
+ }
+ return 0;
+}
+
+static void
+set_tested(const char *fstype) {
+ struct tried *t = xmalloc(sizeof(struct tried));
+
+ t->next = tried;
+ t->type = xstrdup(fstype);
+ tried = t;
+}
+
+static void
+free_tested(void) {
+ struct tried *t, *tt;
+
+ t = tried;
+ while(t) {
+ free(t->type);
+ tt = t->next;
+ free(t);
+ t = tt;
+ }
+ tried = NULL;
+}
+
+static char *
+procfsnext(FILE *procfs) {
+ char line[100];
+ char fsname[100];
+
+ while (fgets(line, sizeof(line), procfs)) {
+ if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
+ if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
+ return xstrdup(fsname);
+ }
+ return 0;
+}
+
+/* Only use /proc/filesystems here, this is meant to test what
+ the kernel knows about, so /etc/filesystems is irrelevant.
+ Return: 1: yes, 0: no, -1: cannot open procfs */
+int
+fsprobe_known_fstype_in_procfs(const char *type)
+{
+ FILE *procfs;
+ char *fsname;
+ int ret = -1;
+
+ procfs = fopen(PROC_FILESYSTEMS, "r");
+ if (procfs) {
+ ret = 0;
+ while ((fsname = procfsnext(procfs)) != NULL)
+ if (!strcmp(fsname, type)) {
+ ret = 1;
+ break;
+ }
+ fclose(procfs);
+ procfs = NULL;
+ }
+ return ret;
+}
+
+/* Try all types in FILESYSTEMS, except those in *types,
+ in case *types starts with "no" */
+/* return: 0: OK, -1: error in errno, 1: type not found */
+/* when 0 or -1 is returned, *types contains the type used */
+/* when 1 is returned, *types is NULL */
+int
+fsprobe_procfsloop_mount( int (*mount_fn)(struct mountargs *),
+ struct mountargs *args,
+ const char **types)
+{
+ char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
+ FILE *procfs;
+ char *fsname;
+ const char *notypes = NULL;
+ int no = 0;
+ int ret = 1;
+ int errsv = 0;
+ int i;
+
+ if (*types && !strncmp(*types, "no", 2)) {
+ no = 1;
+ notypes = (*types) + 2;
+ }
+ *types = NULL;
+
+ /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist.
+ In some cases trying a filesystem that the kernel knows about
+ on the wrong data will crash the kernel; in such cases
+ ETC_FILESYSTEMS can be used to list the filesystems that we
+ are allowed to try, and in the order they should be tried.
+ End ETC_FILESYSTEMS with a line containing a single '*' only,
+ if PROC_FILESYSTEMS should be tried afterwards. */
+
+ for (i=0; i<2; i++) {
+ procfs = fopen(files[i], "r");
+ if (!procfs)
+ continue;
+ while ((fsname = procfsnext(procfs)) != NULL) {
+ if (!strcmp(fsname, "*")) {
+ fclose(procfs);
+ goto nexti;
+ }
+ if (was_tested (fsname))
+ continue;
+ if (no && matching_type(fsname, notypes))
+ continue;
+ set_tested (fsname);
+ args->type = fsname;
+ if (verbose) {
+ printf(_("Trying %s\n"), fsname);
+ fflush(stdout);
+ }
+ if ((*mount_fn) (args) == 0) {
+ *types = fsname;
+ ret = 0;
+ break;
+ } else if (errno != EINVAL &&
+ fsprobe_known_fstype_in_procfs(fsname) == 1)
{
+ *types = "guess";
+ ret = -1;
+ errsv = errno;
+ break;
+ }
+ }
+ free_tested();
+ fclose(procfs);
+ errno = errsv;
+ return ret;
+ nexti:;
+ }
+ return 1;
+}
diff --git a/mount/fsprobe.h b/mount/fsprobe.h
index c96ff8c..cc429e1 100644
--- a/mount/fsprobe.h
+++ b/mount/fsprobe.h
@@ -10,3 +10,20 @@ extern const char *mount_get_devname_by_label(const char
*label);
extern const char *mount_get_volume_label_by_spec(const char *spec);
extern const char *mount_get_devname(const char *spec);
extern const char *mount_get_devname_for_mounting(const char *spec);
+extern int fsprobe_known_fstype(const char *fstype);
+extern const char *fsprobe_get_fstype_by_devname(const char *devname);
+
+struct mountargs {
+ const char *spec;
+ const char *node;
+ const char *type;
+ int flags;
+ void *data;
+};
+
+extern int fsprobe_known_fstype_in_procfs(const char *type);
+
+extern int fsprobe_procfsloop_mount(int (*mount_fn)(struct mountargs *),
+ struct mountargs *args,
+ const char **types);
+
diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c
index 9ff4e31..7f8c362 100644
--- a/mount/fsprobe_blkid.c
+++ b/mount/fsprobe_blkid.c
@@ -41,4 +41,15 @@ mount_get_devname_for_mounting(const char *spec) {
return blkid_get_devname(blkid, spec, 0);
}
+int
+fsprobe_known_fstype(const char *fstype)
+{
+ return blkid_known_fstype(fstype);
+}
+
+const char *
+fsprobe_get_fstype_by_devname(const char *devname) {
+ return blkid_get_tag_value(blkid, "TYPE", devname);
+}
+
#endif
diff --git a/mount/mount.c b/mount/mount.c
index 309e41e..be9e409 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -39,7 +39,6 @@
#include "loop.h"
#include "linux_fs.h" /* for BLKGETSIZE */
#include "mount_guess_rootdev.h"
-#include "mount_guess_fstype.h"
#include "getusername.h"
#include "mount_paths.h"
#include "env.h"
@@ -656,6 +655,26 @@ check_special_mountprog(const char *spec, const char
*node, const char *type, in
return 0;
}
+
+static const char *
+guess_fstype_by_devname(const char *devname)
+{
+ const char *type = fsprobe_get_fstype_by_devname(devname);
+
+ if (verbose) {
+ printf (_("mount: you didn't specify a filesystem type for %s\n"),
devname);
+
+ 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;
+}
+
/*
* guess_fstype_and_mount()
* Mount a single file system. Guess the type when unknown.
@@ -675,7 +694,7 @@ guess_fstype_and_mount(const char *spec, const char *node,
const char **types,
*types = "none"; /* random, but not "bind" */
if (!*types && !(flags & MS_REMOUNT)) {
- *types = guess_fstype(spec);
+ *types = guess_fstype_by_devname(spec);
if (*types) {
if (!strcmp(*types, "swap")) {
error(_("%s looks like swapspace - not mounted"), spec);
@@ -711,7 +730,7 @@ guess_fstype_and_mount(const char *spec, const char *node,
const char **types,
return do_mount_syscall (&args);
}
- return procfsloop(do_mount_syscall, &args, types);
+ return fsprobe_procfsloop_mount(do_mount_syscall, &args, types);
}
/*
@@ -1147,8 +1166,10 @@ try_mount_one (const char *spec0, const char *node0,
const char *types0,
case EIO:
error (_("mount: %s: can't read superblock"), spec); break;
case ENODEV:
- { int pfs;
- if ((pfs = is_in_procfs(types)) == 1 || !strcmp(types, "guess"))
+ {
+ int pfs = fsprobe_known_fstype_in_procfs(types);
+
+ if (pfs == 1 || !strcmp(types, "guess"))
error(_("mount: %s: unknown device"), spec);
else if (pfs == 0) {
char *lowtype, *p;
@@ -1165,11 +1186,13 @@ try_mount_one (const char *spec0, const char *node0,
const char *types0,
u++;
}
}
- if (u && is_in_procfs(lowtype) == 1)
+ if (u && fsprobe_known_fstype_in_procfs(lowtype) == 1)
error (_("mount: probably you meant %s"), lowtype);
- else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1)
+ else if (!strncmp(lowtype, "iso", 3) &&
+ fsprobe_known_fstype_in_procfs("iso9660") == 1)
error (_("mount: maybe you meant 'iso9660'?"));
- else if (!strncmp(lowtype, "fat", 3) && is_in_procfs("vfat") == 1)
+ else if (!strncmp(lowtype, "fat", 3) &&
+ fsprobe_known_fstype_in_procfs("vfat") == 1)
error (_("mount: maybe you meant 'vfat'?"));
free(lowtype);
} else
@@ -1741,8 +1764,8 @@ main(int argc, char *argv[]) {
use only for testing purposes -
the guessing is not reliable at all */
{
- char *fstype;
- fstype = do_guess_fstype(optarg);
+ const char *fstype;
+ fstype = fsprobe_get_fstype_by_devname(optarg);
printf("%s\n", fstype ? fstype : "unknown");
exit(fstype ? 0 : EX_FAIL);
}
diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c
deleted file mode 100644
index 01c3fc7..0000000
--- a/mount/mount_guess_fstype.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Thu Jul 14 07:32:40 1994: [EMAIL PROTECTED] added changes from Adam
- * J. Richter ([EMAIL PROTECTED]) so that /proc/filesystems is used
- * if no -t option is given. I modified his patches so that, if
- * /proc/filesystems is not available, the behavior of mount is the same as
- * it was previously.
- *
- * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <[EMAIL PROTECTED]> added
- * a probe of the superblock for the type before /proc/filesystems is
- * checked.
- *
- * Fri Apr 5 01:13:33 1996: [EMAIL PROTECTED], fixed up iso9660 autodetect
- *
- * Wed Nov 11 11:33:55 1998: [EMAIL PROTECTED], 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 <[EMAIL PROTECTED]>
- * added Native Language Support
- *
- * 2000-12-01 Sepp Wijnands <[EMAIL PROTECTED]>
- * added probes for cramfs, hfs, hpfs and adfs.
- *
- * 2001-10-26 Tim Launchbury
- * added sysv magic.
- *
- * aeb - many changes.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include "linux_fs.h"
-#include "fsprobe.h"
-#include "mount_guess_fstype.h"
-#include "sundries.h" /* for xstrdup */
-#include "nls.h"
-
-#define ETC_FILESYSTEMS "/etc/filesystems"
-#define PROC_FILESYSTEMS "/proc/filesystems"
-
-char *
-do_guess_fstype(const char *device)
-{
- return blkid_get_tag_value(blkid, "TYPE", device);
-}
-
-static int
-known_fstype(const char *fstype)
-{
- return blkid_known_fstype(fstype);
-}
-
-
-static struct tried {
- struct tried *next;
- char *type;
-} *tried = NULL;
-
-static int
-was_tested(const char *fstype) {
- struct tried *t;
-
- if (known_fstype(fstype))
- return 1;
- for (t = tried; t; t = t->next) {
- if (!strcmp(t->type, fstype))
- return 1;
- }
- return 0;
-}
-
-static void
-set_tested(const char *fstype) {
- struct tried *t = xmalloc(sizeof(struct tried));
-
- t->next = tried;
- t->type = xstrdup(fstype);
- tried = t;
-}
-
-static void
-free_tested(void) {
- struct tried *t, *tt;
-
- t = tried;
- while(t) {
- free(t->type);
- tt = t->next;
- free(t);
- t = tt;
- }
- tried = NULL;
-}
-
-char *
-guess_fstype(const char *spec) {
- char *type = do_guess_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 char *
-procfsnext(FILE *procfs) {
- char line[100];
- char fsname[100];
-
- while (fgets(line, sizeof(line), procfs)) {
- if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
- if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
- return xstrdup(fsname);
- }
- return 0;
-}
-
-/* Only use /proc/filesystems here, this is meant to test what
- the kernel knows about, so /etc/filesystems is irrelevant.
- Return: 1: yes, 0: no, -1: cannot open procfs */
-int
-is_in_procfs(const char *type) {
- FILE *procfs;
- char *fsname;
- int ret = -1;
-
- procfs = fopen(PROC_FILESYSTEMS, "r");
- if (procfs) {
- ret = 0;
- while ((fsname = procfsnext(procfs)) != NULL)
- if (!strcmp(fsname, type)) {
- ret = 1;
- break;
- }
- fclose(procfs);
- procfs = NULL;
- }
- return ret;
-}
-
-/* Try all types in FILESYSTEMS, except those in *types,
- in case *types starts with "no" */
-/* return: 0: OK, -1: error in errno, 1: type not found */
-/* when 0 or -1 is returned, *types contains the type used */
-/* when 1 is returned, *types is NULL */
-int
-procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
- const char **types) {
- char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
- FILE *procfs;
- char *fsname;
- const char *notypes = NULL;
- int no = 0;
- int ret = 1;
- int errsv = 0;
- int i;
-
- if (*types && !strncmp(*types, "no", 2)) {
- no = 1;
- notypes = (*types) + 2;
- }
- *types = NULL;
-
- /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist.
- In some cases trying a filesystem that the kernel knows about
- on the wrong data will crash the kernel; in such cases
- ETC_FILESYSTEMS can be used to list the filesystems that we
- are allowed to try, and in the order they should be tried.
- End ETC_FILESYSTEMS with a line containing a single '*' only,
- if PROC_FILESYSTEMS should be tried afterwards. */
-
- for (i=0; i<2; i++) {
- procfs = fopen(files[i], "r");
- if (!procfs)
- continue;
- while ((fsname = procfsnext(procfs)) != NULL) {
- if (!strcmp(fsname, "*")) {
- fclose(procfs);
- goto nexti;
- }
- if (was_tested (fsname))
- continue;
- if (no && matching_type(fsname, notypes))
- continue;
- set_tested (fsname);
- args->type = fsname;
- if (verbose) {
- printf(_("Trying %s\n"), fsname);
- fflush(stdout);
- }
- if ((*mount_fn) (args) == 0) {
- *types = fsname;
- ret = 0;
- break;
- } else if (errno != EINVAL &&
- is_in_procfs(fsname) == 1) {
- *types = "guess";
- ret = -1;
- errsv = errno;
- break;
- }
- }
- free_tested();
- fclose(procfs);
- errno = errsv;
- return ret;
- nexti:;
- }
- return 1;
-}
diff --git a/mount/mount_guess_fstype.h b/mount/mount_guess_fstype.h
deleted file mode 100644
index 63cb678..0000000
--- a/mount/mount_guess_fstype.h
+++ /dev/null
@@ -1,16 +0,0 @@
-struct mountargs {
- const char *spec;
- const char *node;
- const char *type;
- int flags;
- void *data;
-};
-
-extern int verbose;
-
-char *guess_fstype(const char *device);
-char *do_guess_fstype(const char *device);
-int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
- const char **type);
-int is_in_procfs(const char *fstype);
-
diff --git a/mount/mount_paths.h b/mount/mount_paths.h
index fe84e1d..9093b10 100644
--- a/mount/mount_paths.h
+++ b/mount/mount_paths.h
@@ -12,4 +12,7 @@
#endif
#define LOCK_TIMEOUT 10
+#define ETC_FILESYSTEMS "/etc/filesystems"
+#define PROC_FILESYSTEMS "/proc/filesystems"
+
#endif /* MOUNT_PATHS_H */
--
1.5.0.6
-
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html