[PATCH] blkid: add support for adfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for adfs to blkid.

ADFS discs do not have a magic number, so I verify the checksum of the 512-byte boot block, and do a sanity check on the sector size and disc size.

If a disc name is present in the disc record, it is used as the label.

Signed-off-by: Richard Fearn<richardfearn@xxxxxxxxx>

diff --git a/shlibs/blkid/src/superblocks/Makefile.am b/shlibs/blkid/src/superblocks/Makefile.am
index a7c4a23..89354f7 100644
--- a/shlibs/blkid/src/superblocks/Makefile.am
+++ b/shlibs/blkid/src/superblocks/Makefile.am
@@ -43,4 +43,5 @@ libblkid_superblocks_la_SOURCES = \
             lvm.c \
             zfs.c \
             ubifs.c \
-            bfs.c
+            bfs.c \
+            adfs.c
diff --git a/shlibs/blkid/src/superblocks/adfs.c b/shlibs/blkid/src/superblocks/adfs.c
new file mode 100644
index 0000000..54e6402
--- /dev/null
+++ b/shlibs/blkid/src/superblocks/adfs.c
@@ -0,0 +1,69 @@
+/*
+ * util-linux-ng/shlibs/blkid/src/superblocks/adfs.c
+ *
+ * Copyright (C) 2009 Richard Fearn <richardfearn@xxxxxxxxx>
+ *
+ * Sanity checks based on ADFS code from the Linux kernel, written
+ * by Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <string.h>
+#include "superblocks.h"
+#include "adfs.h"
+
+#define IS_ADFS   0
+#define NOT_ADFS -1
+
+#define BOOT_BLOCK_OFFSET 0xC00
+#define BOOT_BLOCK_SIZE   512
+
+#define DISC_RECORD_OFFSET 0x1C0
+
+static int probe_adfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+        unsigned char *as;
+        uint8_t *dr;
+        long int disc_size;
+        unsigned char disc_name[11];
+
+        /* read superblock */
+ as = blkid_probe_get_buffer(pr, BOOT_BLOCK_OFFSET, BOOT_BLOCK_SIZE);
+        if (!as)
+                return NOT_ADFS;
+
+        /* verify boot block checksum */
+        if (adfs_checkbblk(as))
+                return NOT_ADFS;
+
+        dr = as + DISC_RECORD_OFFSET;
+
+        /* check log2secsize */
+        if (dr[0] != 8 && dr[0] != 9 && dr[0] != 10)
+                return NOT_ADFS;
+
+        /* check disc size is non-zero */
+ disc_size = dr[16] + (dr[17] << 8) + (dr[18] << 16) + (dr[19] << 24);
+        if (disc_size == 0)
+                return NOT_ADFS;
+
+        /* set label, if disc has a name */
+        if (dr[22]) {
+                disc_name[10] = '\0';
+                strncpy(disc_name, dr + 22, 10);
+                *strchrnul(disc_name, '\r') = '\0';
+                blkid_probe_set_label(pr, disc_name, strlen(disc_name));
+        }
+
+        return IS_ADFS;
+}
+
+const struct blkid_idinfo adfs_idinfo = {
+        .name = "adfs",
+        .usage = BLKID_USAGE_FILESYSTEM,
+        .probefunc = probe_adfs,
+        .flags = BLKID_IDINFO_TOLERANT
+};
diff --git a/shlibs/blkid/src/superblocks/adfs.h b/shlibs/blkid/src/superblocks/adfs.h
new file mode 100644
index 0000000..c910aba
--- /dev/null
+++ b/shlibs/blkid/src/superblocks/adfs.h
@@ -0,0 +1,29 @@
+/*
+ * util-linux-ng/shlibs/blkid/src/superblocks/adfs.h
+ *
+ * The adfs_checkbblk function is from include/linux/adfs_fs.h in the Linux
+ * kernel.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Calculate the boot block checksum on an ADFS drive.  Note that this will
+ * appear to be correct if the sector contains all zeros, so also check that
+ * the disk size is non-zero!!!
+ */
+static inline int adfs_checkbblk(unsigned char *ptr)
+{
+    unsigned int result = 0;
+    unsigned char *p = ptr + 511;
+
+    do {
+            result = (result & 0xff) + (result >> 8);
+            result = result + *--p;
+    } while (p != ptr);
+
+    return (result & 0xff) != ptr[511];
+}
+
diff --git a/shlibs/blkid/src/superblocks/superblocks.c b/shlibs/blkid/src/superblocks/superblocks.c
index d2c7825..8cb8a58 100644
--- a/shlibs/blkid/src/superblocks/superblocks.c
+++ b/shlibs/blkid/src/superblocks/superblocks.c
@@ -132,7 +132,8 @@ static const struct blkid_idinfo *idinfos[] =
&netware_idinfo,
&btrfs_idinfo,
&ubifs_idinfo,
- &bfs_idinfo
+ &bfs_idinfo,
+ &adfs_idinfo
 };

 /*
diff --git a/shlibs/blkid/src/superblocks/superblocks.h b/shlibs/blkid/src/superblocks/superblocks.h
index 641397a..537d88f 100644
--- a/shlibs/blkid/src/superblocks/superblocks.h
+++ b/shlibs/blkid/src/superblocks/superblocks.h
@@ -61,6 +61,7 @@ extern const struct blkid_idinfo btrfs_idinfo;
 extern const struct blkid_idinfo ubifs_idinfo;
 extern const struct blkid_idinfo zfs_idinfo;
 extern const struct blkid_idinfo bfs_idinfo;
+extern const struct blkid_idinfo adfs_idinfo;

 /*
  * superblock functions

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux