libfsid - A new library to determine filesystems.
authorÁkos Kovács <akoskovacs@gmx.com>
Wed, 8 Dec 2010 19:35:28 +0000 (20:35 +0100)
committerAlex Hornung <ahornung@gmail.com>
Mon, 13 Dec 2010 18:20:20 +0000 (18:20 +0000)
* The idea is extracted from the sbin/fsid tool. The library provides an
  interface to probe a given device for a file system and get its volume
  label.

* fsid was changed to use libfsid functionality.

Sponsored-by: Google Code-In
12 files changed:
lib/libfsid/Makefile [new file with mode: 0644]
lib/libfsid/cd9660.c [copied from sbin/fsid/fsid.h with 67% similarity]
lib/libfsid/ext2.c [copied from sbin/fsid/fsid.h with 67% similarity]
lib/libfsid/hammer.c [moved from sbin/fsid/hammer.c with 80% similarity]
lib/libfsid/libfsid.3 [new file with mode: 0644]
lib/libfsid/libfsid.c [copied from sbin/fsid/ufs.c with 52% similarity]
lib/libfsid/libfsid.h [copied from sbin/fsid/fsid.h with 74% similarity]
lib/libfsid/msdosfs.c [copied from sbin/fsid/ufs.c with 53% similarity]
lib/libfsid/ufs.c [moved from sbin/fsid/ufs.c with 82% similarity]
sbin/fsid/Makefile
sbin/fsid/fsid.c
sbin/fsid/fsid.h

diff --git a/lib/libfsid/Makefile b/lib/libfsid/Makefile
new file mode 100644 (file)
index 0000000..1e15baf
--- /dev/null
@@ -0,0 +1,14 @@
+LIB=   fsid
+SRCS=  libfsid.c ufs.c hammer.c cd9660.c msdosfs.c ext2.c 
+INCS=  libfsid.h
+WARNS?=        6
+CFLAGS+=       -D_FSID_INTERNAL
+MAN=    libfsid.3
+MLINKS+=       libfsid.3 fsid_probe.3
+MLINKS+=       libfsid.3 fsid_probe_all.3
+MLINKS+=       libfsid.3 fsid_volname.3
+MLINKS+=       libfsid.3 fsid_volname_all.3
+MLINKS+=       libfsid.3 fsid_fsname.3
+MLINKS+=       libfsid.3 fsid_fs_count.3
+
+.include <bsd.lib.mk>
similarity index 67%
copy from sbin/fsid/fsid.h
copy to lib/libfsid/cd9660.c
index 8022abc..9f6acaf 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
- * by Alex Hornung <ahornung@gmail.com>
+ * by Ákos Kovács <akoskovacs@gmx.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/uio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <err.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
+#include "libfsid.h"
+#include <vfs/isofs/cd9660/iso.h>
 
-typedef int (probe_func_t)(const char *);
-typedef char *(volname_func_t)(const char *);
+static char buffer[ISO_DEFAULT_BLOCK_SIZE];
 
-struct fs_type {
-       const char *fs_name;
-       probe_func_t    *fs_probe;
-       volname_func_t  *fs_volname;
-};
+int
+cd9660_probe(const char *dev)
+{
+       struct iso_primary_descriptor *pdsc;
 
-struct fsid_entry {
-       char    *dev_path;
-       char    *link_path;
+       if (fsid_dev_read(dev, 32768L, sizeof(buffer), buffer) != 0)
+               return 0;
 
-       TAILQ_ENTRY(fsid_entry)         link;
-};
+       pdsc = (struct iso_primary_descriptor *)&buffer;
 
-TAILQ_HEAD(fsid_head, fsid_entry);
+       if ((strncmp(pdsc->id, ISO_STANDARD_ID, 4)) == 0)
+               return 1;
 
-probe_func_t hammer_probe;
-probe_func_t ufs_probe;
-volname_func_t hammer_volname;
-volname_func_t ufs_volname;
+       return 0;
+}
 
+char *
+cd9660_volname(const char *dev)
+{
+       static struct iso_primary_descriptor *pdsc;
+
+       if (fsid_dev_read(dev, 32768L, sizeof(buffer), buffer) != 0)
+               return NULL;
+
+       pdsc = (struct iso_primary_descriptor *)&buffer;
+
+       if ((strncmp(pdsc->id, ISO_STANDARD_ID, 4)) != 0)
+               return NULL;
+
+       if (pdsc->volume_id[0] == '\0')
+               return NULL;
+
+       pdsc->volume_id[30] = '\0';
+       return pdsc->volume_id;
+}
similarity index 67%
copy from sbin/fsid/fsid.h
copy to lib/libfsid/ext2.c
index 8022abc..6d485b5 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
- * by Alex Hornung <ahornung@gmail.com>
+ * by Ákos Kovács <akoskovacs@gmx.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/uio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <err.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
+#include "libfsid.h"
+#include <vfs/gnu/ext2fs/ext2_fs.h>
+#include <vfs/gnu/ext2fs/fs.h>
 
-typedef int (probe_func_t)(const char *);
-typedef char *(volname_func_t)(const char *);
+static char buffer[sizeof(struct ext2_super_block)*2];
 
-struct fs_type {
-       const char *fs_name;
-       probe_func_t    *fs_probe;
-       volname_func_t  *fs_volname;
-};
+int
+ext2_probe(const char *dev)
+{
+       static struct ext2_super_block *fs;
 
-struct fsid_entry {
-       char    *dev_path;
-       char    *link_path;
+       if (fsid_dev_read(dev, SBOFF, sizeof(buffer), buffer) != 0)
+               return 0;
 
-       TAILQ_ENTRY(fsid_entry)         link;
-};
+       fs = (struct ext2_super_block *)&buffer;
 
-TAILQ_HEAD(fsid_head, fsid_entry);
+       if (fs->s_magic == EXT2_SUPER_MAGIC)
+               return 1;
 
-probe_func_t hammer_probe;
-probe_func_t ufs_probe;
-volname_func_t hammer_volname;
-volname_func_t ufs_volname;
+       return 0;
+}
 
+char *
+ext2_volname(const char *dev)
+{
+       static struct ext2_super_block *fs;
+
+       if (fsid_dev_read(dev, SBOFF, sizeof(buffer), buffer) != 0)
+               return NULL;
+
+       fs = (struct ext2_super_block *)&buffer;
+
+       if (fs->s_magic != EXT2_SUPER_MAGIC)
+               return NULL;
+
+       if (fs->s_volume_name[0] == '\0')
+               return NULL;
+
+       fs->s_volume_name[15] = '\0';
+               return fs->s_volume_name;
+}
similarity index 80%
rename from sbin/fsid/hammer.c
rename to lib/libfsid/hammer.c
index cb0edea..e35e3a8 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "fsid.h"
+#include "libfsid.h"
 #include <vfs/hammer/hammer_disk.h>
 
 static char buffer[16384];
@@ -40,23 +40,10 @@ int
 hammer_probe(const char *dev)
 {
        static struct hammer_volume_ondisk *fs;
-       int ret, fd;
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
-               perror("open in hammer_probe failed");
+       if (fsid_dev_read(dev, 0L, sizeof(buffer), buffer) != 0)
                return 0;
-       }
-
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, sizeof(buffer));
-       if (ret < 0) {
-               close(fd);
-               perror("read in hammer_probe failed");
-               return 0;
-       }
 
-       close(fd);
        fs = (struct hammer_volume_ondisk *)&buffer;
 
        if (fs->vol_signature != HAMMER_FSBUF_VOLUME) {
@@ -70,23 +57,10 @@ char *
 hammer_volname(const char *dev)
 {
        static struct hammer_volume_ondisk *fs;
-       int ret, fd;
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
-               perror("open in hammer_volname failed");
+       if (fsid_dev_read(dev, 0L, sizeof(buffer), buffer) != 0)
                return NULL;
-       }
-
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, sizeof(buffer));
-       if (ret < 0) {
-               close(fd);
-               perror("read in hammer_volname failed");
-               return NULL;
-       }
 
-       close(fd);
        fs = (struct hammer_volume_ondisk *)&buffer;
 
        if (fs->vol_signature != HAMMER_FSBUF_VOLUME) {
diff --git a/lib/libfsid/libfsid.3 b/lib/libfsid/libfsid.3
new file mode 100644 (file)
index 0000000..0afe95f
--- /dev/null
@@ -0,0 +1,128 @@
+.\" Copyright (c) 2010 The DragonFly Project.  All rights reserved.
+.\" 
+.\" This code is derived from software contributed to The DragonFly Project
+.\" by Ákos Kovács <akoskovacs@gmx.com>
+.\" 
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in
+.\"    the documentation and/or other materials provided with the
+.\"    distribution.
+.\" 3. Neither the name of The DragonFly Project nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific, prior written permission.
+.\" 
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd December 12, 2010
+.Dt LIBFSID 3
+.Os
+.Sh NAME
+.Nm fsid_probe ,
+.Nm fsid_probe_all ,
+.Nm fsid_volname ,
+.Nm fsid_volname_all ,
+.Nm fsid_fsname
+.Nm fsid_fs_count
+.Nd general libfsid functions
+.Sh LIBRARY
+A simple interface for filesystem recognising.
+Programs should be linked with
+.Fl lfsid .
+.Sh SYNOPSIS
+.In libfsid.h
+.Ft int
+.Fn fsid_probe "const char *dev" "const char *fs_type"
+.Ft int
+.Fn fsid_probe_all "const char *dev"
+.Ft char *
+.Fn fsid_volname "const char *dev" "const char *fs_type"
+.Ft char *
+.Fn fsid_volname_all "const char *dev"
+.Ft char *
+.Fn fsid_fsname "int id"
+.Ft int
+.Fn fsid_fs_count "void"
+.Sh DESCRIPTION
+.Pp
+.\" General description
+The 
+.Lb libfsid
+provides an interface to determine several filesystems
+and to get their volume labels.
+.Pp
+Big part of the functions use the first parameter
+.Fa dev
+as the full path of the device, some of them has additionally an
+.Fa fs_type
+parameter wich is the name of the choosen filesystem. It can be:
+.Pp
+.Bd -literal -offset indent -compact
+HAMMER         HAMMER
+UFS            UFS
+CD9660         ISO 9660
+EXT2           Extended 2
+MSDOSFS                FAT32, FAT16
+.Ed
+.Pp
+.Pp
+.\" fsid_probe function
+The
+.Fn fsid_probe
+returns 1 if the device has the filesystem type as expected by the
+.Fa fs_type
+parameter, otherwise 0.
+.Pp
+.\" fsid_probe_all function
+.Fn fsid_probe_all
+function try to identify the filesystem type, it returns 0 if the filesystem unknown, or the check fails. Otherwise the returned value is one of this macros:
+.Pp
+.Bd -literal -offset indent -compact
+FSID_HAMMER    HAMMER
+FSID_UFS       UFS
+FSID_CD9660    ISO 9660
+FSID_EXT2      Extended 2
+FSID_MSDOSFS   FAT32, FAT16
+.Ed
+.Pp
+The name of the filesystem can easily queried with the
+.Fn fsid_fsname .
+.Pp
+.Fn fsid_volname
+function returns with the volume label, if the filesystem is the same as the
+.Fa fs_type ,
+if not just returns with 
+.Dv NULL .
+.Pp
+.Fn fsid_volname_all
+give back the volume label, if the filesystem known otherwise returns with
+.Dv NULL .
+.Pp
+.Fn fsid_fsname
+give back the name of the filesystem as a pointer to string. The
+.Fa id
+is mostly the return value of the
+.Fn fsid_probe_all .
+.Pp
+.Fn fsid_fs_count
+return with a number of supported filesystems.
+.Sh AUTHOR
+The library and the manual page wrote by Ákos Kovács <akoskovacs@gmx.com>.
+.Sh SEE ALSO
+.Xr devattr 3 
similarity index 52%
copy from sbin/fsid/ufs.c
copy to lib/libfsid/libfsid.c
index a3b43f0..868246a 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
- * by Alex Hornung <ahornung@gmail.com>
+ * by Ákos Kovács <akoskovacs@gmx.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "fsid.h"
-#include <vfs/ufs/ufs_types.h>
-#include <vfs/ufs/fs.h>
+#include "libfsid.h"
+#include <sys/stat.h>
+#include <errno.h>
+
+struct fs_type fs_types[] = {
+    { "HAMMER", hammer_probe,  hammer_volname  },
+    { "UFS",   ufs_probe,      ufs_volname     },
+    { "CD9660",        cd9660_probe,   cd9660_volname  },
+    { "EXT2",  ext2_probe,     ext2_volname    },
+    { "MSDOSFS",msdosfs_probe, msdosfs_volname },
+    { NULL,    NULL,           NULL            }
+};
+
+const char *
+fsid_fsname(int id)
+{
+       if (id < 1)
+               return 0;
 
-static char buffer[MAXBSIZE];
+       return fs_types[id-1].fs_name;
+}
 
 int
-ufs_probe(const char *dev)
+fsid_fs_count(void)
 {
-       static struct fs *fs;
-       int ret, fd;
+       int count;
+       for (count = 0; fs_types[count].fs_name != NULL; count++)
+               ;
+
+       return count;
+}
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+int
+fsid_probe(const char *dev, const char *fs_type)
+{
+       int i;
+       if (dev == NULL || fs_type == NULL)
                return 0;
+
+       for (i = 0; fs_types[i].fs_name != NULL; i++)  {
+               if ((strcmp(fs_type, fs_types[i].fs_name)) == 0)
+                       return fs_types[i].fs_probe(dev);
        }
+       return 0;
+}
 
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
+int
+fsid_probe_all(const char *dev)
+{
+       int i;
+       if (dev == NULL)
                return 0;
 
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
-               close(fd);
-               return 0;
+       for (i = 0; fs_types[i].fs_name != NULL; i++) {
+               if ((fs_types[i].fs_probe(dev)) == 1)
+                       return i + 1;
        }
+       return 0;
+}
 
-       close(fd);
-       fs = (struct fs *)&buffer;
+char *
+fsid_volname(const char *dev, const char *fs_type)
+{
+       int i;
+       if (dev == NULL || fs_type == NULL)
+               return NULL;
 
-       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
-               (unsigned)fs->fs_bsize < sizeof(struct fs)) {
-               return 0;
+       for (i = 0; fs_types[i].fs_name != NULL; i++) {
+               if ((strcmp(fs_type, fs_types[i].fs_name)) == 0) {
+                       return fs_types[i].fs_volname(dev);
+               }
        }
-
-       return 1;
+       return NULL;
 }
 
 char *
-ufs_volname(const char *dev)
+fsid_volname_all(const char *dev)
 {
-       static struct fs *fs;
-       int ret, fd;
-
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+       int fs_id;
+       if (dev == NULL)
                return NULL;
-       }
 
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
+       if ((fs_id = fsid_probe_all(dev)) != 0)
+               return fs_types[fs_id - 1].fs_volname(dev);
+       else
                return NULL;
+}
+
+int
+fsid_dev_read(const char *dev, off_t off, size_t len, char *buf)
+{
+       int fd;
+
+       if ((fd = open(dev, O_RDONLY)) < 0)
+               return -1;
 
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
+       if ((lseek(fd, off, SEEK_SET)) < 0) {
                close(fd);
-               return NULL;
+               return -1;
        }
 
-       close(fd);
-       fs = (struct fs *)&buffer;
-
-       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
-               (unsigned)fs->fs_bsize < sizeof(struct fs)) {
-               return NULL;
+       bzero(buf, len);
+       if ((read(fd, buf, len)) < 0) {
+               close(fd);
+               return -1;
        }
 
-       if (fs->fs_volname[0] == '\0')
-               return NULL;
+       close(fd);
 
-       fs->fs_volname[MAXVOLLEN - 1] = '\0';
-       return fs->fs_volname;
+       return 0;
 }
-
similarity index 74%
copy from sbin/fsid/fsid.h
copy to lib/libfsid/libfsid.h
index 8022abc..14b8ec0 100644 (file)
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#ifndef LIBFSID_H
+#define LIBFSID_H
+
 #include <sys/types.h>
-#include <sys/queue.h>
 #include <sys/uio.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 
+#define FSID_HAMMER     0x01
+#define FSID_UFS        0x02
+#define FSID_CD9660     0x03
+#define FSID_EXT2       0x04
+#define FSID_MSDOSFS    0x05
+
 typedef int (probe_func_t)(const char *);
 typedef char *(volname_func_t)(const char *);
 
@@ -50,17 +58,30 @@ struct fs_type {
        volname_func_t  *fs_volname;
 };
 
-struct fsid_entry {
-       char    *dev_path;
-       char    *link_path;
-
-       TAILQ_ENTRY(fsid_entry)         link;
-};
-
-TAILQ_HEAD(fsid_head, fsid_entry);
-
 probe_func_t hammer_probe;
 probe_func_t ufs_probe;
+probe_func_t cd9660_probe;
+probe_func_t ext2_probe;
+probe_func_t msdosfs_probe;
+
 volname_func_t hammer_volname;
 volname_func_t ufs_volname;
+volname_func_t cd9660_volname;
+volname_func_t ext2_volname;
+volname_func_t msdosfs_volname;
+
+int fsid_probe(const char *dev, const char *fs_type);
+int fsid_probe_all(const char *dev);
+
+char *fsid_volname(const char *dev, const char *fs_type);
+char *fsid_volname_all(const char *dev);
+
+/* Extra functions */
+const char *fsid_fsname(int);
+int fsid_fs_count(void);
+
 
+#ifdef _FSID_INTERNAL
+int fsid_dev_read(const char *dev, off_t off, size_t len, char *buf);
+#endif
+#endif /* LIBFSID_H */
similarity index 53%
copy from sbin/fsid/ufs.c
copy to lib/libfsid/msdosfs.c
index a3b43f0..fbcd89d 100644 (file)
@@ -2,7 +2,8 @@
  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
- * by Alex Hornung <ahornung@gmail.com>
+ * by Alex Hornung <ahornung@gmail.com
+ * and Ákos Kovács <akoskovacs@gmx.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "fsid.h"
-#include <vfs/ufs/ufs_types.h>
-#include <vfs/ufs/fs.h>
+#include "libfsid.h"
+#include <vfs/msdosfs/bootsect.h>
 
-static char buffer[MAXBSIZE];
+#define MSDOS_BOOT_BLOCK_SIZE 512
+
+static char buffer[MSDOS_BOOT_BLOCK_SIZE * 4];
+static char *get_volname(char *buf);
 
 int
-ufs_probe(const char *dev)
+msdosfs_probe(const char *dev)
 {
-       static struct fs *fs;
-       int ret, fd;
-
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+       if (fsid_dev_read(dev, 0L, sizeof(buffer), buffer) != 0)
                return 0;
-       }
 
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
+       if (get_volname(buffer) != NULL)
+               return 1;
+       else
                return 0;
-
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
-               close(fd);
-               return 0;
-       }
-
-       close(fd);
-       fs = (struct fs *)&buffer;
-
-       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
-               (unsigned)fs->fs_bsize < sizeof(struct fs)) {
-               return 0;
-       }
-
-       return 1;
 }
-
 char *
-ufs_volname(const char *dev)
+msdosfs_volname(const char *dev)
 {
-       static struct fs *fs;
-       int ret, fd;
+       char *volname;
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+       if (fsid_dev_read(dev, 0L, sizeof(buffer), buffer) != 0)
                return NULL;
-       }
 
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
+       volname = get_volname(buffer);
+       if (volname == NULL)
                return NULL;
 
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
-               close(fd);
+       if (volname[0] == '\0')
                return NULL;
-       }
 
-       close(fd);
-       fs = (struct fs *)&buffer;
-
-       if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
-               (unsigned)fs->fs_bsize < sizeof(struct fs)) {
-               return NULL;
-       }
-
-       if (fs->fs_volname[0] == '\0')
-               return NULL;
-
-       fs->fs_volname[MAXVOLLEN - 1] = '\0';
-       return fs->fs_volname;
+       volname[10] = '\0';
+       return volname;
 }
 
+/*
+ * This function used to get the offset address of
+ * the volume name, of the FAT partition.
+ * It also checks, that is a real FAT partition.
+*/
+static char *
+get_volname(char *buff)
+{
+       struct bootsector710 *bpb7;
+       struct bootsector50 *bpb4;
+       struct extboot *extb;
+
+       bpb7 = (struct bootsector710 *)buff;
+       bpb4 = (struct bootsector50 *)buff;
+
+       /*
+        * First, assume BPB v7
+        */
+       extb = (struct extboot *)bpb7->bsExt;
+       if ((extb->exBootSignature == 0x28 || extb->exBootSignature == 0x29) &&
+           strncmp(extb->exFileSysType, "FAT", 3) == 0)
+               return extb->exVolumeLabel;
+
+       /*
+        * If this is not a BPB v7, try it as a bpb v4.
+        */
+       extb = (struct extboot *)bpb4->bsExt;
+       if ((extb->exBootSignature == 0x28 || extb->exBootSignature == 0x29) &&
+           strncmp(extb->exFileSysType, "FAT", 3) == 0)
+               return extb->exVolumeLabel;
+
+       /*
+        * If previous checks failed, it may not a FAT filesystem, or
+        * it may an older one without a volume name.
+        */
+       return NULL;
+}
similarity index 82%
rename from sbin/fsid/ufs.c
rename to lib/libfsid/ufs.c
index a3b43f0..e052775 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "fsid.h"
+#include "libfsid.h"
 #include <vfs/ufs/ufs_types.h>
 #include <vfs/ufs/fs.h>
 
@@ -41,25 +41,10 @@ int
 ufs_probe(const char *dev)
 {
        static struct fs *fs;
-       int ret, fd;
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+       if(fsid_dev_read(dev, SBOFF, sizeof(buffer), buffer) != 0)
                return 0;
-       }
-
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
-               return 0;
-
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
-               close(fd);
-               return 0;
-       }
 
-       close(fd);
        fs = (struct fs *)&buffer;
 
        if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
@@ -74,25 +59,10 @@ char *
 ufs_volname(const char *dev)
 {
        static struct fs *fs;
-       int ret, fd;
 
-       fd = open(dev, O_RDONLY);
-       if (fd < 0) {
+       if(fsid_dev_read(dev, SBOFF, sizeof(buffer), buffer) != 0)
                return NULL;
-       }
-
-       ret = lseek(fd, SBOFF, SEEK_SET);
-       if (ret < 0)
-               return NULL;
-
-       bzero(buffer, sizeof(buffer));
-       ret = read(fd, &buffer, SBSIZE);
-       if (ret < 0) {
-               close(fd);
-               return NULL;
-       }
 
-       close(fd);
        fs = (struct fs *)&buffer;
 
        if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
index e46291c..3e5a283 100644 (file)
@@ -1,6 +1,6 @@
 PROG=  fsid
-SRCS=  fsid.c ufs.c hammer.c
-LDADD= -ldevattr -lprop
+SRCS=  fsid.c
+LDADD= -ldevattr -lprop -lfsid
 NOMAN=
 
 .include <bsd.prog.mk>
index 3ee49a8..cce409e 100644 (file)
 #include <sys/stat.h>
 #include <devattr.h>
 #include <errno.h>
+#include <libfsid.h>
 #include "fsid.h"
 
-static struct fs_type fs_types[] = {
-       { "HAMMER",     hammer_probe,   hammer_volname  },
-       { "UFS",        ufs_probe,      ufs_volname     },
-       { NULL,         NULL,           NULL            }
-};
-
-
 static struct fsid_head fsid_list =
                TAILQ_HEAD_INITIALIZER(fsid_list);
 
@@ -72,38 +66,34 @@ fsid_check_create_alias(const char *dev)
        char full_path[MAXPATHLEN];
        char link_path[MAXPATHLEN];
        char *volname;
-       int i;
 
        if (fsid_alias_exists(dev))
                return EEXIST;
 
        sprintf(full_path, "/dev/%s", dev);
-       for (i = 0; fs_types[i].fs_name != NULL; i++) {
-               volname = fs_types[i].fs_volname(full_path);
-               if (volname == NULL)
-                       continue;
+       volname = fsid_volname_all(full_path);
+       if (volname == NULL)
+               return 0;
 
-               printf("Volume name for %s is %s\n", dev, volname);
-               fsid = malloc(sizeof(struct fsid_entry));
-               if (fsid == NULL)
-                       return ENOMEM;
+       printf("Volume name for %s is %s\n", dev, volname);
+       fsid = malloc(sizeof(struct fsid_entry));
+       if (fsid == NULL)
+               return ENOMEM;
 #if 1
-               sprintf(link_path, "/dev/vol-by-name/%s", volname);
+       sprintf(link_path, "/dev/vol-by-name/%s", volname);
 
-               fsid->dev_path = strdup(dev);
-               fsid->link_path = strdup(link_path);
-               if ((fsid->dev_path == NULL) || (fsid->link_path == NULL)) {
-                       free(fsid);
-                       return ENOMEM;
-               }
+       fsid->dev_path = strdup(dev);
+       fsid->link_path = strdup(link_path);
+       if ((fsid->dev_path == NULL) || (fsid->link_path == NULL)) {
+               free(fsid);
+               return ENOMEM;
+       }
 
-               mkdir("/dev/vol-by-name", 0755);
-               symlink(full_path, link_path);
+       mkdir("/dev/vol-by-name", 0755);
+       symlink(full_path, link_path);
 
-               TAILQ_INSERT_TAIL(&fsid_list, fsid, link);
+       TAILQ_INSERT_TAIL(&fsid_list, fsid, link);
 #endif
-               break;
-       }
 
        return 0;
 }
index 8022abc..4e7cc81 100644 (file)
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
-
-typedef int (probe_func_t)(const char *);
-typedef char *(volname_func_t)(const char *);
-
-struct fs_type {
-       const char *fs_name;
-       probe_func_t    *fs_probe;
-       volname_func_t  *fs_volname;
-};
+#include <libfsid.h>
 
 struct fsid_entry {
        char    *dev_path;
@@ -58,9 +50,3 @@ struct fsid_entry {
 };
 
 TAILQ_HEAD(fsid_head, fsid_entry);
-
-probe_func_t hammer_probe;
-probe_func_t ufs_probe;
-volname_func_t hammer_volname;
-volname_func_t ufs_volname;
-