diff options
Diffstat (limited to 'sys-boot/grub/files/grub-0.97-uuid.patch')
-rw-r--r-- | sys-boot/grub/files/grub-0.97-uuid.patch | 5406 |
1 files changed, 0 insertions, 5406 deletions
diff --git a/sys-boot/grub/files/grub-0.97-uuid.patch b/sys-boot/grub/files/grub-0.97-uuid.patch deleted file mode 100644 index f99670a8..00000000 --- a/sys-boot/grub/files/grub-0.97-uuid.patch +++ /dev/null @@ -1,5406 +0,0 @@ -=== modified file 'Makefile.am' ---- grub-0.97.orig/Makefile.am 2004-04-23 13:39:01 +0000 -+++ grub-0.97/Makefile.am 2008-07-09 17:23:44 +0000 -@@ -1,4 +1,9 @@ - # Do not change this order if you don't know what you are doing. - AUTOMAKE_OPTIONS = 1.7 gnu --SUBDIRS = netboot stage2 stage1 lib grub util docs -+if UUID_SUPPORT -+SUBDIRS = libvolume_id netboot stage2 stage1 lib grub util docs -+else -+SUBDIRS = netboot stage2 stage1 lib grub util docs -+endif -+ - EXTRA_DIST = BUGS MAINTENANCE - -=== modified file 'configure.ac' ---- grub-0.97.orig/configure.ac 2008-01-28 18:41:45 +0000 -+++ grub-0.97/configure.ac 2008-07-09 17:23:44 +0000 -@@ -605,6 +606,11 @@ - [ --disable-serial disable serial terminal support]) - AM_CONDITIONAL(SERIAL_SUPPORT, test "x$enable_serial" != xno) - -+dnl UUID scanning -+AC_ARG_ENABLE(uuid, -+ [ --disable-uuid disable uuid scanning support]) -+AM_CONDITIONAL(UUID_SUPPORT, test "x$enable_uuid" != xno) -+ - dnl Simulation of the slowness of a serial device. - AC_ARG_ENABLE(serial-speed-simulation, - [ --enable-serial-speed-simulation -@@ -666,5 +672,6 @@ - docs/Makefile lib/Makefile util/Makefile \ - grub/Makefile netboot/Makefile util/grub-image \ - util/grub-install util/grub-md5-crypt \ -- util/grub-terminfo util/grub-set-default]) -+ util/grub-terminfo util/grub-set-default \ -+ libvolume_id/Makefile]) - AC_OUTPUT - -=== modified file 'grub/Makefile.am' ---- grub-0.97.orig/grub/Makefile.am 2005-02-02 20:40:05 +0000 -+++ grub-0.97/grub/Makefile.am 2008-07-09 17:23:44 +0000 -@@ -16,4 +16,9 @@ - AM_CFLAGS = $(GRUB_CFLAGS) - - grub_SOURCES = main.c asmstub.c --grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS) -+ -+if UUID_SUPPORT -+grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a ../libvolume_id/libvolume_id.a $(GRUB_LIBS) -+else -+grub_LDADD = ../stage2/libgrub.a ../lib/libcommon.a $(GRUB_LIBS) -+endif - -=== added directory 'libvolume_id' -=== added file 'libvolume_id/Makefile.am' ---- grub-0.97.orig/libvolume_id/Makefile.am 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/Makefile.am 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,27 @@ -+noinst_LIBRARIES = libvolume_id.a -+ -+AM_CFLAGS = $(STAGE2_CFLAGS) -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1 -+ -+LIBVOLUME_ID_FS_SUPPORTED = ext.c fat.c hfs.c jfs.c \ -+ luks.c ntfs.c ocfs.c reiserfs.c \ -+ xfs.c -+ -+LIBVOLUME_ID_FS_UNSUPPORTED = cramfs.c gfs.c hpfs.c iso9660.c \ -+ lvm.c minix.c romfs.c squashfs.c \ -+ sysv.c udf.c ufs.c vxfs.c -+ -+LIBVOLUME_ID_RAID_SUPPORTED = ddf_raid.c -+ -+LIBVOLUME_ID_RAID_UNSUPPORTED = adaptec_raid.c highpoint.c isw_raid.c \ -+ jmicron_raid.c linux_raid.c lsi_raid.c \ -+ nvidia_raid.c promise_raid.c silicon_raid.c \ -+ via_raid.c -+ -+LIBVOLUME_ID_MISC_UNSUPPORTED = linux_swap.c netware.c -+ -+libvolume_id_a_SOURCES = $(LIBVOLUME_ID_FS_SUPPORTED) \ -+ $(LIBVOLUME_ID_RAID_SUPPORTED) \ -+ $(LIBVOLUME_ID_FS_UNSUPPORTED) \ -+ $(LIBVOLUME_ID_RAID_UNSUPPORTED) \ -+ volume_id.h volume_id.c util.c util.h misc.c -+ - -=== added file 'libvolume_id/adaptec_raid.c' ---- grub-0.97.orig/libvolume_id/adaptec_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/adaptec_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,107 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct adaptec_meta { -+ uint32_t b0idcode; -+ uint8_t lunsave[8]; -+ uint16_t sdtype; -+ uint16_t ssavecyl; -+ uint8_t ssavehed; -+ uint8_t ssavesec; -+ uint8_t sb0flags; -+ uint8_t jbodEnable; -+ uint8_t lundsave; -+ uint8_t svpdirty; -+ uint16_t biosInfo; -+ uint16_t svwbskip; -+ uint16_t svwbcln; -+ uint16_t svwbmax; -+ uint16_t res3; -+ uint16_t svwbmin; -+ uint16_t res4; -+ uint16_t svrcacth; -+ uint16_t svwcacth; -+ uint16_t svwbdly; -+ uint8_t svsdtime; -+ uint8_t res5; -+ uint16_t firmval; -+ uint16_t firmbln; -+ uint32_t firmblk; -+ uint32_t fstrsvrb; -+ uint16_t svBlockStorageTid; -+ uint16_t svtid; -+ uint8_t svseccfl; -+ uint8_t res6; -+ uint8_t svhbanum; -+ uint8_t resver; -+ uint32_t drivemagic; -+ uint8_t reserved[20]; -+ uint8_t testnum; -+ uint8_t testflags; -+ uint16_t maxErrorCount; -+ uint32_t count; -+ uint32_t startTime; -+ uint32_t interval; -+ uint8_t tstxt0; -+ uint8_t tstxt1; -+ uint8_t serNum[32]; -+ uint8_t res8[102]; -+ uint32_t fwTestMagic; -+ uint32_t fwTestSeqNum; -+ uint8_t fwTestRes[8]; -+ uint8_t smagic[4]; -+ uint32_t raidtbl; -+ uint16_t raidline; -+ uint8_t res9[0xF6]; -+} PACKED; -+ -+int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct adaptec_meta *ad; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-1) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ ad = (struct adaptec_meta *) buf; -+ if (memcmp((char*)ad->smagic, "DPTM", 4) != 0) -+ return -1; -+ -+ if (ad->b0idcode != be32_to_cpu(0x37FC4D1E)) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ sprintf(id->type_version, "%u", ad->resver); -+ id->type = "adaptec_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/cramfs.c' ---- grub-0.97.orig/libvolume_id/cramfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/cramfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,60 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct cramfs_super { -+ uint8_t magic[4]; -+ uint32_t size; -+ uint32_t flags; -+ uint32_t future; -+ uint8_t signature[16]; -+ struct cramfs_info { -+ uint32_t crc; -+ uint32_t edition; -+ uint32_t blocks; -+ uint32_t files; -+ } PACKED info; -+ uint8_t name[16]; -+} PACKED; -+ -+int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct cramfs_super *cs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ cs = (struct cramfs_super *) volume_id_get_buffer(id, off, 0x200); -+ if (cs == NULL) -+ return -1; -+ -+ if (memcmp((char*)cs->magic, "\x45\x3d\xcd\x28", 4) == 0 || memcmp((char*)cs->magic, "\x28\xcd\x3d\x45", 4) == 0) { -+ volume_id_set_label_raw(id, cs->name, 16); -+ volume_id_set_label_string(id, cs->name, 16); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "cramfs"; -+ return 0; -+ } -+ -+ return -1; -+} - -=== added file 'libvolume_id/ddf_raid.c' ---- grub-0.97.orig/libvolume_id/ddf_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/ddf_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,60 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+/* http://www.snia.org/standards/home */ -+ -+#define DDF_HEADER 0xDE11DE11 -+#define DDF_GUID_LENGTH 24 -+#define DDF_REV_LENGTH 8 -+ -+static struct ddf_header { -+ uint32_t signature; -+ uint32_t crc; -+ uint8_t guid[DDF_GUID_LENGTH]; -+ uint8_t ddf_rev[DDF_REV_LENGTH]; -+} PACKED *ddf; -+ -+int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint64_t ddf_off = ((size / 0x200)-1) * 0x200; -+ const uint8_t *buf; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ if (size < 0x10000) -+ return -1; -+ -+ buf = volume_id_get_buffer(id, off + ddf_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ ddf = (struct ddf_header *) buf; -+ -+ if (ddf->signature != cpu_to_be32(DDF_HEADER)) -+ return -1; -+ -+ volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING); -+ strcpy(id->type_version, (char*) ddf->ddf_rev); -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "ddf_raid_member"; -+ return 0; -+} - -=== added file 'libvolume_id/ext.c' ---- grub-0.97.orig/libvolume_id/ext.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/ext.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,129 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct ext2_super_block { -+ uint32_t s_inodes_count; -+ uint32_t s_blocks_count; -+ uint32_t s_r_blocks_count; -+ uint32_t s_free_blocks_count; -+ uint32_t s_free_inodes_count; -+ uint32_t s_first_data_block; -+ uint32_t s_log_block_size; -+ uint32_t s_log_frag_size; -+ uint32_t s_blocks_per_group; -+ uint32_t s_frags_per_group; -+ uint32_t s_inodes_per_group; -+ uint32_t s_mtime; -+ uint32_t s_wtime; -+ uint16_t s_mnt_count; -+ uint16_t s_max_mnt_count; -+ uint16_t s_magic; -+ uint16_t s_state; -+ uint16_t s_errors; -+ uint16_t s_minor_rev_level; -+ uint32_t s_lastcheck; -+ uint32_t s_checkinterval; -+ uint32_t s_creator_os; -+ uint32_t s_rev_level; -+ uint16_t s_def_resuid; -+ uint16_t s_def_resgid; -+ uint32_t s_first_ino; -+ uint16_t s_inode_size; -+ uint16_t s_block_group_nr; -+ uint32_t s_feature_compat; -+ uint32_t s_feature_incompat; -+ uint32_t s_feature_ro_compat; -+ uint8_t s_uuid[16]; -+ uint8_t s_volume_name[16]; -+} PACKED; -+ -+#define EXT_SUPER_MAGIC 0xEF53 -+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -+#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 -+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -+ -+#define EXT_SUPERBLOCK_OFFSET 0x400 -+ -+#define EXT3_MIN_BLOCK_SIZE 0x400 -+#define EXT3_MAX_BLOCK_SIZE 0x1000 -+ -+int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct ext2_super_block *es; -+ size_t bsize; -+ uint32_t feature_compat; -+ uint32_t feature_incompat; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); -+ if (es == NULL) -+ return -1; -+ -+ if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC)) -+ return -1; -+ -+ bsize = 0x400 << le32_to_cpu(es->s_log_block_size); -+ dbg("ext blocksize 0x%zx", bsize); -+ if (bsize < EXT3_MIN_BLOCK_SIZE || bsize > EXT3_MAX_BLOCK_SIZE) { -+ dbg("invalid ext blocksize"); -+ return -1; -+ } -+ -+ volume_id_set_label_raw(id, es->s_volume_name, 16); -+ volume_id_set_label_string(id, es->s_volume_name, 16); -+ volume_id_set_uuid(id, es->s_uuid, 0, UUID_DCE); -+ sprintf(id->type_version, "%u.%u", -+ le32_to_cpu(es->s_rev_level), le16_to_cpu(es->s_minor_rev_level)); -+ -+ feature_compat = le32_to_cpu(es->s_feature_compat); -+ feature_incompat = le32_to_cpu(es->s_feature_incompat); -+ -+ /* check for external journal device */ -+ if ((feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { -+ volume_id_set_usage(id, VOLUME_ID_OTHER); -+ id->type = "jbd"; -+ goto out; -+ } -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ -+ if ((feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) != 0 || -+ (feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0 || -+ (feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) != 0) { -+ id->type = "ext4"; -+ goto out; -+ } -+ -+ if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { -+ id->type = "ext3"; -+ goto out; -+ } -+ -+ id->type = "ext2"; -+ -+out: -+ return 0; -+} - -=== added file 'libvolume_id/fat.c' ---- grub-0.97.orig/libvolume_id/fat.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/fat.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,482 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004-2007 Kay Sievers <kay.sievers@vrfy.org> -+ * Copyright (C) 2007 Ryan Lortie <desrt@desrt.ca> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define FAT12_MAX 0xff5 -+#define FAT16_MAX 0xfff5 -+#define FAT_ATTR_VOLUME_ID 0x08 -+#define FAT_ATTR_DIR 0x10 -+#define FAT_ATTR_LONG_NAME 0x0f -+#define FAT_ATTR_MASK 0x3f -+#define FAT_ENTRY_FREE 0xe5 -+ -+#define VFAT_LFN_SEQ_MASK 0x3f -+#define VFAT_LFN_SEQ_LAST 0x40 -+#define VFAT_LFN_SEQ_MAX 20 -+#define VFAT_LFN_CHARS_PER_ENTRY (5 + 6 + 2) -+#define VFAT_LOWERCASE_NAME 0x10 -+#define VFAT_LOWERCASE_EXT 0x08 -+ -+struct vfat_super_block { -+ uint8_t boot_jump[3]; -+ uint8_t sysid[8]; -+ uint16_t sector_size; -+ uint8_t sectors_per_cluster; -+ uint16_t reserved; -+ uint8_t fats; -+ uint16_t dir_entries; -+ uint16_t sectors; -+ uint8_t media; -+ uint16_t fat_length; -+ uint16_t secs_track; -+ uint16_t heads; -+ uint32_t hidden; -+ uint32_t total_sect; -+ union { -+ struct fat_super_block { -+ uint8_t unknown[3]; -+ uint8_t serno[4]; -+ uint8_t label[11]; -+ uint8_t magic[8]; -+ uint8_t dummy2[192]; -+ uint8_t pmagic[2]; -+ } PACKED fat; -+ struct fat32_super_block { -+ uint32_t fat32_length; -+ uint16_t flags; -+ uint8_t version[2]; -+ uint32_t root_cluster; -+ uint16_t fsinfo_sector; -+ uint16_t backup_boot; -+ uint16_t reserved2[6]; -+ uint8_t unknown[3]; -+ uint8_t serno[4]; -+ uint8_t label[11]; -+ uint8_t magic[8]; -+ uint8_t dummy2[164]; -+ uint8_t pmagic[2]; -+ } PACKED fat32; -+ } PACKED type; -+} PACKED; -+ -+struct fat32_fsinfo { -+ uint8_t signature1[4]; -+ uint32_t reserved1[120]; -+ uint8_t signature2[4]; -+ uint32_t free_clusters; -+ uint32_t next_cluster; -+ uint32_t reserved2[4]; -+} PACKED; -+ -+struct vfat_dir_entry { -+ uint8_t name[11]; -+ uint8_t attr; -+ uint8_t lowercase; -+ uint8_t fine_time_creat; -+ uint16_t time_creat; -+ uint16_t date_creat; -+ uint16_t date_acc; -+ uint16_t cluster_high; -+ uint16_t time_write; -+ uint16_t date_write; -+ uint16_t cluster_low; -+ uint32_t size; -+} PACKED; -+ -+ -+struct vfat_lfn_entry { -+ uint8_t seq; -+ uint16_t name0[5]; -+ uint8_t attr; -+ uint8_t reserved; -+ uint8_t cksum; -+ uint16_t name1[6]; -+ uint16_t cluster; -+ uint16_t name2[2]; -+} PACKED; -+ -+static uint8_t fat_lfn_checksum(const uint8_t name[11]) -+{ -+ uint8_t cksum = 0; -+ int i; -+ -+ /* http://en.wikipedia.org/wiki/File_Allocation_Table */ -+ for (i = 0; i < 11; i++) -+ cksum = ((cksum & 1) ? 0x80 : 0) + (cksum >> 1) + name[i]; -+ -+ return cksum; -+} -+ -+static size_t fat_read_lfn(uint8_t *filename, size_t fnsize, -+ struct vfat_dir_entry *direntry, -+ struct vfat_dir_entry *entry) -+{ -+ uint8_t buffer[VFAT_LFN_SEQ_MAX * VFAT_LFN_CHARS_PER_ENTRY * 2]; -+ uint8_t expected_seq = 1; -+ uint8_t cksum; -+ size_t len = 0; -+ size_t fnlen = 0; -+ -+ cksum = fat_lfn_checksum(entry->name); -+ -+ while (--entry >= direntry) { -+ struct vfat_lfn_entry *lfn = (struct vfat_lfn_entry *) entry; -+ -+ if (expected_seq > VFAT_LFN_SEQ_MAX) -+ break; -+ -+ if ((lfn->attr & FAT_ATTR_MASK) != FAT_ATTR_LONG_NAME) -+ break; -+ -+ if (lfn->cksum != cksum) -+ break; -+ -+ if ((lfn->seq & VFAT_LFN_SEQ_MASK) != expected_seq++) -+ break; -+ -+ if (lfn->cluster != 0) -+ break; -+ -+ /* extra paranoia -- should never happen */ -+ if (len + sizeof(lfn->name0) + sizeof(lfn->name1) + -+ sizeof(lfn->name2) > sizeof(buffer)) -+ break; -+ -+ memcpy (&buffer[len], lfn->name0, sizeof(lfn->name0)); -+ len += sizeof(lfn->name0); -+ memcpy (&buffer[len], lfn->name1, sizeof(lfn->name1)); -+ len += sizeof(lfn->name1); -+ memcpy (&buffer[len], lfn->name2, sizeof(lfn->name2)); -+ len += sizeof(lfn->name2); -+ -+ if (lfn->seq & VFAT_LFN_SEQ_LAST) { -+ fnlen = volume_id_set_unicode16(filename, fnsize, buffer, LE, len); -+ break; -+ } -+ } -+ -+ return fnlen; -+} -+ -+static size_t fat_read_filename(uint8_t *filename, size_t fnsize, -+ struct vfat_dir_entry *direntry, struct vfat_dir_entry *entry) -+{ -+ size_t len; -+ int i; -+ -+ /* check if maybe we have LFN entries */ -+ len = fat_read_lfn(filename, fnsize, direntry, entry); -+ if (len > 0) -+ goto out; -+ -+ /* else, read the normal 8.3 name */ -+ for (i = 0; i < 11; i++) { -+ if (entry->lowercase & ((i < 8) ? VFAT_LOWERCASE_NAME : VFAT_LOWERCASE_EXT)) -+ filename[i] = tolower(entry->name[i]); -+ else -+ filename[i] = entry->name[i]; -+ } -+ len = 11; -+ -+out: -+ filename[len] = '\0'; -+ return len; -+} -+ -+/* fills filename, returns string length */ -+static size_t get_fat_attr_volume_id(uint8_t *filename, size_t fnsize, -+ struct vfat_dir_entry *direntry, unsigned int count) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < count; i++) { -+ /* end marker */ -+ if (direntry[i].name[0] == 0x00) { -+ dbg("end of dir"); -+ break; -+ } -+ -+ /* empty entry */ -+ if (direntry[i].name[0] == FAT_ENTRY_FREE) -+ continue; -+ -+ /* long name */ -+ if ((direntry[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME) -+ continue; -+ -+ if ((direntry[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { -+ /* labels do not have file data */ -+ if (direntry[i].cluster_high != 0 || direntry[i].cluster_low != 0) -+ continue; -+ -+ dbg("found ATTR_VOLUME_ID id in root dir"); -+ return fat_read_filename(filename, fnsize, direntry, &direntry[i]); -+ } -+ -+ dbg("skip dir entry"); -+ } -+ -+ return 0; -+} -+ -+int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint8_t filename[255 * 3]; -+ struct vfat_super_block *vs; -+ struct vfat_dir_entry *direntry; -+ struct fat32_fsinfo *fsinfo; -+ uint16_t sector_size; -+ uint16_t dir_entries; -+ uint32_t sect_count; -+ uint16_t reserved; -+ uint32_t fat_size; -+ uint32_t root_cluster; -+ uint32_t dir_size; -+ uint32_t cluster_count; -+ uint16_t fat_length; -+ uint32_t fat32_length; -+ uint64_t root_start; -+ uint32_t start_data_sect; -+ uint16_t root_dir_entries; -+ uint16_t fsinfo_sect; -+ uint8_t *buf; -+ uint32_t buf_size; -+ uint32_t next; -+ int maxloop; -+ size_t fnlen; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off, 0x400); -+ if (buf == NULL) -+ return -1; -+ -+ /* check signature */ -+ if (buf[510] != 0x55 || buf[511] != 0xaa) -+ return -1; -+ -+ vs = (struct vfat_super_block *) buf; -+ if (memcmp((char*)vs->sysid, "NTFS", 4) == 0) -+ return -1; -+ -+ /* believe only that's fat, don't trust the version */ -+ if (memcmp((char*)vs->type.fat32.magic, "MSWIN", 5) == 0) -+ goto magic; -+ -+ if (memcmp((char*)vs->type.fat32.magic, "FAT32 ", 8) == 0) -+ goto magic; -+ -+ if (memcmp((char*)vs->type.fat.magic, "FAT16 ", 8) == 0) -+ goto magic; -+ -+ if (memcmp((char*)vs->type.fat.magic, "MSDOS", 5) == 0) -+ goto magic; -+ -+ if (memcmp((char*)vs->type.fat.magic, "FAT12 ", 8) == 0) -+ goto magic; -+ -+ /* some old floppies don't have a magic, expect the boot jump address to match */ -+ if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && -+ vs->boot_jump[0] != 0xe9) -+ return -1; -+ -+magic: -+ /* reserverd sector count */ -+ if (!vs->reserved) -+ return -1; -+ -+ /* fat count */ -+ if (!vs->fats) -+ return -1; -+ -+ /* media check */ -+ if (vs->media < 0xf8 && vs->media != 0xf0) -+ return -1; -+ -+ /* cluster size check */ -+ if (vs->sectors_per_cluster == 0 || -+ (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) -+ return -1; -+ -+ /* sector size check */ -+ sector_size = le16_to_cpu(vs->sector_size); -+ if (sector_size == 0 || ((sector_size & (sector_size-1)) != 0)) -+ return -1; -+ -+ dbg("sector_size 0x%x", sector_size); -+ dbg("sectors_per_cluster 0x%x", vs->sectors_per_cluster); -+ -+ dir_entries = le16_to_cpu(vs->dir_entries); -+ reserved = le16_to_cpu(vs->reserved); -+ dbg("reserved 0x%x", reserved); -+ -+ sect_count = le16_to_cpu(vs->sectors); -+ if (sect_count == 0) -+ sect_count = le32_to_cpu(vs->total_sect); -+ dbg("sect_count 0x%x", sect_count); -+ -+ fat_length = le16_to_cpu(vs->fat_length); -+ dbg("fat_length 0x%x", fat_length); -+ fat32_length = le32_to_cpu(vs->type.fat32.fat32_length); -+ dbg("fat32_length 0x%x", fat32_length); -+ -+ if (fat_length) -+ fat_size = fat_length * vs->fats; -+ else if (fat32_length) -+ fat_size = fat32_length * vs->fats; -+ else -+ return -1; -+ dbg("fat_size 0x%x", fat_size); -+ -+ dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + -+ (sector_size-1)) / sector_size; -+ dbg("dir_size 0x%x", dir_size); -+ -+ cluster_count = sect_count - (reserved + fat_size + dir_size); -+ cluster_count /= vs->sectors_per_cluster; -+ dbg("cluster_count 0x%x", cluster_count); -+ -+ /* must be FAT32 */ -+ if (!fat_length && fat32_length) -+ goto fat32; -+ -+ /* cluster_count tells us the format */ -+ if (cluster_count < FAT12_MAX) -+ strcpy(id->type_version, "FAT12"); -+ else if (cluster_count < FAT16_MAX) -+ strcpy(id->type_version, "FAT16"); -+ else -+ goto fat32; -+ -+ /* the label may be an attribute in the root directory */ -+ root_start = (reserved + fat_size) * sector_size; -+ dbg("root dir start 0x%llx", (unsigned long long) root_start); -+ root_dir_entries = le16_to_cpu(vs->dir_entries); -+ dbg("expected entries 0x%x", root_dir_entries); -+ -+ buf_size = root_dir_entries * sizeof(struct vfat_dir_entry); -+ buf = volume_id_get_buffer(id, off + root_start, buf_size); -+ if (buf == NULL) -+ goto found; -+ -+ direntry = (struct vfat_dir_entry*) buf; -+ -+ fnlen = get_fat_attr_volume_id(filename, sizeof(filename), direntry, root_dir_entries); -+ -+ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); -+ if (vs == NULL) -+ return -1; -+ -+ if (fnlen > 0 && memcmp((char*)filename, "NO NAME ", 11) != 0) { -+ volume_id_set_label_raw(id, filename, fnlen); -+ volume_id_set_label_string(id, filename, fnlen); -+ } else if (memcmp((char*)vs->type.fat.label, "NO NAME ", 11) != 0) { -+ volume_id_set_label_raw(id, vs->type.fat.label, 11); -+ volume_id_set_label_string(id, vs->type.fat.label, 11); -+ } -+ volume_id_set_uuid(id, vs->type.fat.serno, 0, UUID_DOS); -+ goto found; -+ -+fat32: -+ /* FAT32 should have a valid signature in the fsinfo block */ -+ fsinfo_sect = le16_to_cpu(vs->type.fat32.fsinfo_sector); -+ buf = volume_id_get_buffer(id, off + (fsinfo_sect * sector_size), 0x200); -+ if (buf == NULL) -+ return -1; -+ fsinfo = (struct fat32_fsinfo *) buf; -+ if (memcmp((char*)fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0) -+ return -1; -+ if (memcmp((char*)fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0) -+ return -1 ; -+ -+ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); -+ if (vs == NULL) -+ return -1; -+ -+ strcpy(id->type_version, "FAT32"); -+ -+ /* FAT32 root dir is a cluster chain like any other directory */ -+ buf_size = vs->sectors_per_cluster * sector_size; -+ root_cluster = le32_to_cpu(vs->type.fat32.root_cluster); -+ dbg("root dir cluster %u", root_cluster); -+ start_data_sect = reserved + fat_size; -+ -+ next = root_cluster; -+ maxloop = 100; -+ while (--maxloop) { -+ uint32_t next_sect_off; -+ uint64_t next_off; -+ uint64_t fat_entry_off; -+ int count; -+ -+ dbg("next cluster %u", next); -+ next_sect_off = (next - 2) * vs->sectors_per_cluster; -+ next_off = (start_data_sect + next_sect_off) * sector_size; -+ dbg("cluster offset 0x%llx", (unsigned long long) next_off); -+ -+ /* get cluster */ -+ buf = volume_id_get_buffer(id, off + next_off, buf_size); -+ if (buf == NULL) -+ goto found; -+ -+ direntry = (struct vfat_dir_entry*) buf; -+ count = buf_size / sizeof(struct vfat_dir_entry); -+ dbg("expected entries 0x%x", count); -+ -+ fnlen = get_fat_attr_volume_id(filename, sizeof(filename), direntry, count); -+ if (fnlen > 0) -+ break; -+ -+ /* get FAT entry */ -+ fat_entry_off = (reserved * sector_size) + (next * sizeof(uint32_t)); -+ buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size); -+ if (buf == NULL) -+ goto found; -+ -+ /* set next cluster */ -+ next = le32_to_cpu(*((uint32_t *) buf)) & 0x0fffffff; -+ if (next < 2 || next >= 0x0ffffff0) -+ break; -+ } -+ if (maxloop == 0) -+ dbg("reached maximum follow count of root cluster chain, give up"); -+ -+ vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); -+ if (vs == NULL) -+ return -1; -+ -+ if (fnlen > 0 && memcmp((char*)filename, "NO NAME ", 11) != 0) { -+ volume_id_set_label_raw(id, filename, fnlen); -+ volume_id_set_label_string(id, filename, fnlen); -+ } else if (memcmp((char*)vs->type.fat32.label, "NO NAME ", 11) != 0) { -+ volume_id_set_label_raw(id, vs->type.fat32.label, 11); -+ volume_id_set_label_string(id, vs->type.fat32.label, 11); -+ } -+ volume_id_set_uuid(id, vs->type.fat32.serno, 0, UUID_DOS); -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "vfat"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/gfs.c' ---- grub-0.97.orig/libvolume_id/gfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/gfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,115 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2006 Red Hat, Inc. <redhat.com> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+/* Common gfs/gfs2 constants: */ -+#define GFS_MAGIC 0x01161970 -+#define GFS_DEFAULT_BSIZE 4096 -+#define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE) -+#define GFS_METATYPE_SB 1 -+#define GFS_FORMAT_SB 100 -+#define GFS_LOCKNAME_LEN 64 -+ -+/* gfs1 constants: */ -+#define GFS_FORMAT_FS 1309 -+#define GFS_FORMAT_MULTI 1401 -+/* gfs2 constants: */ -+#define GFS2_FORMAT_FS 1801 -+#define GFS2_FORMAT_MULTI 1900 -+ -+struct gfs2_meta_header { -+ uint32_t mh_magic; -+ uint32_t mh_type; -+ uint64_t __pad0; /* Was generation number in gfs1 */ -+ uint32_t mh_format; -+ uint32_t __pad1; /* Was incarnation number in gfs1 */ -+}; -+ -+struct gfs2_inum { -+ uint64_t no_formal_ino; -+ uint64_t no_addr; -+}; -+ -+struct gfs2_sb { -+ struct gfs2_meta_header sb_header; -+ -+ uint32_t sb_fs_format; -+ uint32_t sb_multihost_format; -+ uint32_t __pad0; /* Was superblock flags in gfs1 */ -+ -+ uint32_t sb_bsize; -+ uint32_t sb_bsize_shift; -+ uint32_t __pad1; /* Was journal segment size in gfs1 */ -+ -+ struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */ -+ struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */ -+ struct gfs2_inum sb_root_dir; -+ -+ char sb_lockproto[GFS_LOCKNAME_LEN]; -+ char sb_locktable[GFS_LOCKNAME_LEN]; -+ /* In gfs1, quota and license dinodes followed */ -+} PACKED; -+ -+static int volume_id_probe_gfs_generic(struct volume_id *id, uint64_t off, int vers) -+{ -+ struct gfs2_sb *sbd; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ sbd = (struct gfs2_sb *) -+ volume_id_get_buffer(id, off + GFS_SUPERBLOCK_OFFSET, sizeof(struct gfs2_sb)); -+ if (sbd == NULL) -+ return -1; -+ -+ if (be32_to_cpu(sbd->sb_header.mh_magic) == GFS_MAGIC && -+ be32_to_cpu(sbd->sb_header.mh_type) == GFS_METATYPE_SB && -+ be32_to_cpu(sbd->sb_header.mh_format) == GFS_FORMAT_SB) { -+ if (vers == 1) { -+ if (be32_to_cpu(sbd->sb_fs_format) != GFS_FORMAT_FS || -+ be32_to_cpu(sbd->sb_multihost_format) != GFS_FORMAT_MULTI) -+ return -1; /* not gfs1 */ -+ id->type = "gfs"; -+ } -+ else if (vers == 2) { -+ if (be32_to_cpu(sbd->sb_fs_format) != GFS2_FORMAT_FS || -+ be32_to_cpu(sbd->sb_multihost_format) != GFS2_FORMAT_MULTI) -+ return -1; /* not gfs2 */ -+ id->type = "gfs2"; -+ } -+ else -+ return -1; -+ strcpy(id->type_version, "1"); -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ return 0; -+ } -+ return -1; -+} -+ -+int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ return volume_id_probe_gfs_generic(id, off, 1); -+} -+ -+int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ return volume_id_probe_gfs_generic(id, off, 2); -+} - -=== added file 'libvolume_id/hfs.c' ---- grub-0.97.orig/libvolume_id/hfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/hfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,318 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct hfs_finder_info{ -+ uint32_t boot_folder; -+ uint32_t start_app; -+ uint32_t open_folder; -+ uint32_t os9_folder; -+ uint32_t reserved; -+ uint32_t osx_folder; -+ uint8_t id[8]; -+} PACKED; -+ -+static struct hfs_mdb { -+ uint8_t signature[2]; -+ uint32_t cr_date; -+ uint32_t ls_Mod; -+ uint16_t atrb; -+ uint16_t nm_fls; -+ uint16_t vbm_st; -+ uint16_t alloc_ptr; -+ uint16_t nm_al_blks; -+ uint32_t al_blk_size; -+ uint32_t clp_size; -+ uint16_t al_bl_st; -+ uint32_t nxt_cnid; -+ uint16_t free_bks; -+ uint8_t label_len; -+ uint8_t label[27]; -+ uint32_t vol_bkup; -+ uint16_t vol_seq_num; -+ uint32_t wr_cnt; -+ uint32_t xt_clump_size; -+ uint32_t ct_clump_size; -+ uint16_t num_root_dirs; -+ uint32_t file_count; -+ uint32_t dir_count; -+ struct hfs_finder_info finder_info; -+ uint8_t embed_sig[2]; -+ uint16_t embed_startblock; -+ uint16_t embed_blockcount; -+} PACKED *hfs; -+ -+struct hfsplus_bnode_descriptor { -+ uint32_t next; -+ uint32_t prev; -+ uint8_t type; -+ uint8_t height; -+ uint16_t num_recs; -+ uint16_t reserved; -+} PACKED; -+ -+struct hfsplus_bheader_record { -+ uint16_t depth; -+ uint32_t root; -+ uint32_t leaf_count; -+ uint32_t leaf_head; -+ uint32_t leaf_tail; -+ uint16_t node_size; -+} PACKED; -+ -+struct hfsplus_catalog_key { -+ uint16_t key_len; -+ uint32_t parent_id; -+ uint16_t unicode_len; -+ uint8_t unicode[255 * 2]; -+} PACKED; -+ -+struct hfsplus_extent { -+ uint32_t start_block; -+ uint32_t block_count; -+} PACKED; -+ -+#define HFSPLUS_EXTENT_COUNT 8 -+struct hfsplus_fork { -+ uint64_t total_size; -+ uint32_t clump_size; -+ uint32_t total_blocks; -+ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; -+} PACKED; -+ -+static struct hfsplus_vol_header { -+ uint8_t signature[2]; -+ uint16_t version; -+ uint32_t attributes; -+ uint32_t last_mount_vers; -+ uint32_t reserved; -+ uint32_t create_date; -+ uint32_t modify_date; -+ uint32_t backup_date; -+ uint32_t checked_date; -+ uint32_t file_count; -+ uint32_t folder_count; -+ uint32_t blocksize; -+ uint32_t total_blocks; -+ uint32_t free_blocks; -+ uint32_t next_alloc; -+ uint32_t rsrc_clump_sz; -+ uint32_t data_clump_sz; -+ uint32_t next_cnid; -+ uint32_t write_count; -+ uint64_t encodings_bmp; -+ struct hfs_finder_info finder_info; -+ struct hfsplus_fork alloc_file; -+ struct hfsplus_fork ext_file; -+ struct hfsplus_fork cat_file; -+ struct hfsplus_fork attr_file; -+ struct hfsplus_fork start_file; -+} PACKED *hfsplus; -+ -+#define HFS_SUPERBLOCK_OFFSET 0x400 -+#define HFS_NODE_LEAF 0xff -+#define HFSPLUS_POR_CNID 1 -+ -+static void hfsid_set_uuid(struct volume_id *id, const uint8_t *hfs_id) -+{ -+#if 0 -+ MD5_CTX md5c; -+ static const uint8_t hash_init[16] = { -+ 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6, -+ 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac -+ }; -+ uint8_t uuid[16]; -+ -+ if (*((uint64_t *)hfs_id) == 0) -+ return; -+ -+ MD5_Init(&md5c); -+ MD5_Update(&md5c, &hash_init, 16); -+ MD5_Update(&md5c, hfs_id, 8); -+ MD5_Final(uuid, &md5c); -+ -+ uuid[6] = 0x30 | (uuid[6] & 0x0f); -+ uuid[8] = 0x80 | (uuid[8] & 0x3f); -+ volume_id_set_uuid(id, uuid, UUID_DCE); -+#endif -+ -+ volume_id_set_uuid(id, hfs_id, 0, UUID_64BIT_BE); -+} -+ -+int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ unsigned int blocksize; -+ unsigned int cat_block; -+ unsigned int ext_block_start; -+ unsigned int ext_block_count; -+ int ext; -+ unsigned int leaf_node_head; -+ unsigned int leaf_node_count; -+ unsigned int leaf_node_size; -+ unsigned int leaf_block; -+ uint64_t leaf_off; -+ unsigned int alloc_block_size; -+ unsigned int alloc_first_block; -+ unsigned int embed_first_block; -+ unsigned int record_count; -+ struct hfsplus_bnode_descriptor *descr; -+ struct hfsplus_bheader_record *bnode; -+ struct hfsplus_catalog_key *key; -+ unsigned int label_len; -+ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; -+ const uint8_t *buf; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ hfs = (struct hfs_mdb *) buf; -+ if (memcmp((char *)hfs->signature, "BD", 2) != 0) -+ goto checkplus; -+ -+ /* it may be just a hfs wrapper for hfs+ */ -+ if (memcmp((char *)hfs->embed_sig, "H+", 2) == 0) { -+ alloc_block_size = be32_to_cpu(hfs->al_blk_size); -+ dbg("alloc_block_size 0x%x", alloc_block_size); -+ -+ alloc_first_block = be16_to_cpu(hfs->al_bl_st); -+ dbg("alloc_first_block 0x%x", alloc_first_block); -+ -+ embed_first_block = be16_to_cpu(hfs->embed_startblock); -+ dbg("embed_first_block 0x%x", embed_first_block); -+ -+ off += (alloc_first_block * 512) + -+ (embed_first_block * alloc_block_size); -+ dbg("hfs wrapped hfs+ found at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ goto checkplus; -+ } -+ -+ if (hfs->label_len > 0 && hfs->label_len < 28) { -+ volume_id_set_label_raw(id, hfs->label, hfs->label_len); -+ volume_id_set_label_string(id, hfs->label, hfs->label_len) ; -+ } -+ -+ hfsid_set_uuid(id, hfs->finder_info.id); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "hfs"; -+ -+ return 0; -+ -+checkplus: -+ hfsplus = (struct hfsplus_vol_header *) buf; -+ if (memcmp((char *)hfsplus->signature, "H+", 2) == 0) -+ goto hfsplus; -+ if (memcmp((char *)hfsplus->signature, "HX", 2) == 0) -+ goto hfsplus; -+ return -1; -+ -+hfsplus: -+ hfsid_set_uuid(id, hfsplus->finder_info.id); -+ -+ blocksize = be32_to_cpu(hfsplus->blocksize); -+ dbg("blocksize %u", blocksize); -+ -+ memcpy(extents, hfsplus->cat_file.extents, sizeof(extents)); -+ cat_block = be32_to_cpu(extents[0].start_block); -+ dbg("catalog start block 0x%x", cat_block); -+ -+ buf = volume_id_get_buffer(id, off + (cat_block * blocksize), 0x2000); -+ if (buf == NULL) -+ goto found; -+ -+ bnode = (struct hfsplus_bheader_record *) -+ &buf[sizeof(struct hfsplus_bnode_descriptor)]; -+ -+ leaf_node_head = be32_to_cpu(bnode->leaf_head); -+ dbg("catalog leaf node 0x%x", leaf_node_head); -+ -+ leaf_node_size = be16_to_cpu(bnode->node_size); -+ dbg("leaf node size 0x%x", leaf_node_size); -+ -+ leaf_node_count = be32_to_cpu(bnode->leaf_count); -+ dbg("leaf node count 0x%x", leaf_node_count); -+ if (leaf_node_count == 0) -+ goto found; -+ -+ leaf_block = (leaf_node_head * leaf_node_size) / blocksize; -+ -+ /* get physical location */ -+ for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) { -+ ext_block_start = be32_to_cpu(extents[ext].start_block); -+ ext_block_count = be32_to_cpu(extents[ext].block_count); -+ dbg("extent start block 0x%x, count 0x%x", ext_block_start, ext_block_count); -+ -+ if (ext_block_count == 0) -+ goto found; -+ -+ /* this is our extent */ -+ if (leaf_block < ext_block_count) -+ break; -+ -+ leaf_block -= ext_block_count; -+ } -+ if (ext == HFSPLUS_EXTENT_COUNT) -+ goto found; -+ dbg("found block in extent %i", ext); -+ -+ leaf_off = (ext_block_start + leaf_block) * blocksize; -+ -+ buf = volume_id_get_buffer(id, off + leaf_off, leaf_node_size); -+ if (buf == NULL) -+ goto found; -+ -+ descr = (struct hfsplus_bnode_descriptor *) buf; -+ dbg("descriptor type 0x%x", descr->type); -+ -+ record_count = be16_to_cpu(descr->num_recs); -+ dbg("number of records %u", record_count); -+ if (record_count == 0) -+ goto found; -+ -+ if (descr->type != HFS_NODE_LEAF) -+ goto found; -+ -+ key = (struct hfsplus_catalog_key *) -+ &buf[sizeof(struct hfsplus_bnode_descriptor)]; -+ -+ dbg("parent id 0x%x", be32_to_cpu(key->parent_id)); -+ if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID) -+ goto found; -+ -+ label_len = be16_to_cpu(key->unicode_len) * 2; -+ dbg("label unicode16 len %i", label_len); -+ volume_id_set_label_raw(id, key->unicode, label_len); -+ volume_id_set_label_unicode16(id, key->unicode, BE, label_len); -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "hfsplus"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/highpoint.c' ---- grub-0.97.orig/libvolume_id/highpoint.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/highpoint.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,91 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct hpt37x_meta { -+ uint8_t filler1[32]; -+ uint32_t magic; -+} PACKED; -+ -+struct hpt45x_meta { -+ uint32_t magic; -+} PACKED; -+ -+#define HPT37X_CONFIG_OFF 0x1200 -+#define HPT37X_MAGIC_OK 0x5a7816f0 -+#define HPT37X_MAGIC_BAD 0x5a7816fd -+ -+#define HPT45X_MAGIC_OK 0x5a7816f3 -+#define HPT45X_MAGIC_BAD 0x5a7816fd -+ -+ -+int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct hpt37x_meta *hpt; -+ uint32_t magic; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ hpt = (struct hpt37x_meta *) buf; -+ magic = le32_to_cpu(hpt->magic); -+ if (magic != HPT37X_MAGIC_OK && magic != HPT37X_MAGIC_BAD) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "highpoint_raid_member"; -+ -+ return 0; -+} -+ -+int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct hpt45x_meta *hpt; -+ uint64_t meta_off; -+ uint32_t magic; -+ -+ dbg("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-11) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ hpt = (struct hpt45x_meta *) buf; -+ magic = le32_to_cpu(hpt->magic); -+ if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "highpoint_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/hpfs.c' ---- grub-0.97.orig/libvolume_id/hpfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/hpfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,51 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct hpfs_super -+{ -+ uint8_t magic[4]; -+ uint8_t version; -+} PACKED; -+ -+#define HPFS_SUPERBLOCK_OFFSET 0x2000 -+ -+int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct hpfs_super *hs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ hs = (struct hpfs_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_OFFSET, 0x200); -+ if (hs == NULL) -+ return -1; -+ -+ if (memcmp((char *)hs->magic, "\x49\xe8\x95\xf9", 4) == 0) { -+ sprintf(id->type_version, "%u", hs->version); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "hpfs"; -+ return 0; -+ } -+ -+ return -1; -+} - -=== added file 'libvolume_id/iso9660.c' ---- grub-0.97.orig/libvolume_id/iso9660.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/iso9660.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,119 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define ISO_SUPERBLOCK_OFFSET 0x8000 -+#define ISO_SECTOR_SIZE 0x800 -+#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE) -+#define ISO_VD_PRIMARY 0x1 -+#define ISO_VD_SUPPLEMENTARY 0x2 -+#define ISO_VD_END 0xff -+#define ISO_VD_MAX 16 -+ -+struct iso_volume_descriptor { -+ uint8_t type; -+ uint8_t id[5]; -+ uint8_t version; -+ uint8_t flags; -+ uint8_t system_id[32]; -+ uint8_t volume_id[32]; -+ uint8_t unused[8]; -+ uint8_t space_size[8]; -+ uint8_t escape_sequences[8]; -+} PACKED; -+ -+struct high_sierra_volume_descriptor { -+ uint8_t foo[8]; -+ uint8_t type; -+ uint8_t id[5]; -+ uint8_t version; -+} PACKED; -+ -+int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint8_t *buf; -+ struct iso_volume_descriptor *is; -+ struct high_sierra_volume_descriptor *hs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ is = (struct iso_volume_descriptor *) buf; -+ -+ if (memcmp((char*)is->id, "CD001", 5) == 0) { -+ int vd_offset; -+ int i; -+ -+ dbg("read label from PVD"); -+ volume_id_set_label_raw(id, is->volume_id, 32); -+ volume_id_set_label_string(id, is->volume_id, 32); -+ -+ dbg("looking for SVDs"); -+ vd_offset = ISO_VD_OFFSET; -+ for (i = 0; i < ISO_VD_MAX; i++) { -+ uint8_t svd_label[64]; -+ -+ is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200); -+ if (is == NULL || is->type == ISO_VD_END) -+ break; -+ if (is->type != ISO_VD_SUPPLEMENTARY) -+ continue; -+ -+ dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset)); -+ if (memcmp((char *)is->escape_sequences, "%/@", 3) == 0|| -+ memcmp((char *)is->escape_sequences, "%/C", 3) == 0|| -+ memcmp((char *)is->escape_sequences, "%/E", 3) == 0) { -+ dbg("Joliet extension found"); -+ volume_id_set_unicode16(svd_label, sizeof(svd_label), is->volume_id, BE, 32); -+ if (memcmp((char *)id->label, (char *)svd_label, 16) == 0) { -+ dbg("SVD label is identical, use the possibly longer PVD one"); -+ break; -+ } -+ -+ volume_id_set_label_raw(id, is->volume_id, 32); -+ volume_id_set_label_string(id, svd_label, 32); -+ strcpy(id->type_version, "Joliet Extension"); -+ goto found; -+ } -+ vd_offset += ISO_SECTOR_SIZE; -+ } -+ goto found; -+ } -+ -+ hs = (struct high_sierra_volume_descriptor *) buf; -+ -+ if (memcmp((char *)hs->id, "CDROM", 5) == 0) { -+ strcpy(id->type_version, "High Sierra"); -+ goto found; -+ } -+ -+ return -1; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "iso9660"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/isw_raid.c' ---- grub-0.97.orig/libvolume_id/isw_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/isw_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,61 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct isw_meta { -+ uint8_t sig[32]; -+ uint32_t check_sum; -+ uint32_t mpb_size; -+ uint32_t family_num; -+ uint32_t generation_num; -+} PACKED; -+ -+#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " -+ -+ -+int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct isw_meta *isw; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-2) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ isw = (struct isw_meta *) buf; -+ if (memcmp((char *)isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ memcpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); -+ id->type = "isw_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/jfs.c' ---- grub-0.97.orig/libvolume_id/jfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/jfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,60 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct jfs_super_block { -+ uint8_t magic[4]; -+ uint32_t version; -+ uint64_t size; -+ uint32_t bsize; -+ uint32_t dummy1; -+ uint32_t pbsize; -+ uint32_t dummy2[27]; -+ uint8_t uuid[16]; -+ uint8_t label[16]; -+ uint8_t loguuid[16]; -+} PACKED; -+ -+#define JFS_SUPERBLOCK_OFFSET 0x8000 -+ -+int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct jfs_super_block *js; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); -+ if (js == NULL) -+ return -1; -+ -+ if (memcmp((char *)js->magic, "JFS1", 4) != 0) -+ return -1; -+ -+ volume_id_set_label_raw(id, js->label, 16); -+ volume_id_set_label_string(id, js->label, 16); -+ volume_id_set_uuid(id, js->uuid, 0, UUID_DCE); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "jfs"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/jmicron_raid.c' ---- grub-0.97.orig/libvolume_id/jmicron_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/jmicron_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,57 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct jmicron_meta { -+ int8_t signature[2]; -+ uint8_t minor_version; -+ uint8_t major_version; -+ uint16_t checksum; -+} PACKED; -+ -+int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct jmicron_meta *jm; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-1) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ jm = (struct jmicron_meta *) buf; -+ if (memcmp((char *)jm->signature, "JM", 2) != 0) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ sprintf(id->type_version, "%u.%u", jm->major_version, jm->minor_version); -+ id->type = "jmicron_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/linux_raid.c' ---- grub-0.97.orig/libvolume_id/linux_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/linux_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,160 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+static struct mdp0_super_block { -+ uint32_t md_magic; -+ uint32_t major_version; -+ uint32_t minor_version; -+ uint32_t patch_version; -+ uint32_t gvalid_words; -+ uint32_t set_uuid0; -+ uint32_t ctime; -+ uint32_t level; -+ uint32_t size; -+ uint32_t nr_disks; -+ uint32_t raid_disks; -+ uint32_t md_minor; -+ uint32_t not_persistent; -+ uint32_t set_uuid1; -+ uint32_t set_uuid2; -+ uint32_t set_uuid3; -+} PACKED *mdp0; -+ -+struct mdp1_super_block { -+ uint32_t magic; -+ uint32_t major_version; -+ uint32_t feature_map; -+ uint32_t pad0; -+ uint8_t set_uuid[16]; -+ uint8_t set_name[32]; -+} PACKED *mdp1; -+ -+#define MD_RESERVED_BYTES 0x10000 -+#define MD_SB_MAGIC 0xa92b4efc -+ -+static int volume_id_probe_linux_raid0(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ union { -+ uint32_t ints[4]; -+ uint8_t bytes[16]; -+ } uuid; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ if (size < 0x10000) -+ return -1; -+ -+ buf = volume_id_get_buffer(id, off, 0x800); -+ if (buf == NULL) -+ return -1; -+ mdp0 = (struct mdp0_super_block *) buf; -+ -+ if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { -+ uuid.ints[0] = bswap_32(mdp0->set_uuid0); -+ if (le32_to_cpu(mdp0->minor_version >= 90)) { -+ uuid.ints[1] = bswap_32(mdp0->set_uuid1); -+ uuid.ints[2] = bswap_32(mdp0->set_uuid2); -+ uuid.ints[3] = bswap_32(mdp0->set_uuid3); -+ } else { -+ uuid.ints[1] = 0; -+ uuid.ints[2] = 0; -+ uuid.ints[3] = 0; -+ } -+ volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); -+ sprintf(id->type_version, "%u.%u.%u", -+ le32_to_cpu(mdp0->major_version), -+ le32_to_cpu(mdp0->minor_version), -+ le32_to_cpu(mdp0->patch_version)); -+ } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) { -+ uuid.ints[0] = mdp0->set_uuid0; -+ if (be32_to_cpu(mdp0->minor_version >= 90)) { -+ uuid.ints[1] = mdp0->set_uuid1; -+ uuid.ints[2] = mdp0->set_uuid2; -+ uuid.ints[3] = mdp0->set_uuid3; -+ } else { -+ uuid.ints[1] = 0; -+ uuid.ints[2] = 0; -+ uuid.ints[3] = 0; -+ } -+ volume_id_set_uuid(id, uuid.bytes, 0, UUID_FOURINT); -+ sprintf(id->type_version, "%u.%u.%u", -+ be32_to_cpu(mdp0->major_version), -+ be32_to_cpu(mdp0->minor_version), -+ be32_to_cpu(mdp0->patch_version)); -+ } else -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "linux_raid_member"; -+ return 0; -+} -+ -+static int volume_id_probe_linux_raid1(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ buf = volume_id_get_buffer(id, off, 0x800); -+ if (buf == NULL) -+ return -1; -+ mdp1 = (struct mdp1_super_block *) buf; -+ -+ if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC) -+ return -1; -+ -+ volume_id_set_uuid(id, mdp1->set_uuid, 0, UUID_FOURINT); -+ volume_id_set_label_raw(id, mdp1->set_name, 32); -+ volume_id_set_label_string(id, mdp1->set_name, 32); -+ sprintf(id->type_version, "%u", le32_to_cpu(mdp1->major_version)); -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "linux_raid_member"; -+ return 0; -+} -+ -+int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint64_t sboff; -+ -+ /* version 0 at the end of the device */ -+ sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; -+ if (volume_id_probe_linux_raid0(id, off + sboff, size) == 0) -+ return 0; -+ -+ /* version 1.0 at the end of the device */ -+ sboff = (size & ~(0x1000 - 1)) - 0x2000; -+ if (volume_id_probe_linux_raid1(id, off + sboff, size) == 0) -+ return 0; -+ -+ /* version 1.1 at the start of the device */ -+ if (volume_id_probe_linux_raid1(id, off, size) == 0) -+ return 0; -+ -+ /* version 1.2 at 4k offset from the start */ -+ if (volume_id_probe_linux_raid1(id, off + 0x1000, size) == 0) -+ return 0; -+ -+ return -1; -+} - -=== added file 'libvolume_id/linux_swap.c' ---- grub-0.97.orig/libvolume_id/linux_swap.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/linux_swap.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,85 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct swap_header_v1_2 { -+ uint8_t bootbits[1024]; -+ uint32_t version; -+ uint32_t last_page; -+ uint32_t nr_badpages; -+ uint8_t uuid[16]; -+ uint8_t volume_name[16]; -+} PACKED; -+ -+#define LARGEST_PAGESIZE 0x4000 -+ -+int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ unsigned int page; -+ struct swap_header_v1_2 *sw; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ /* eek, the swap signature is at the end of the PAGE_SIZE */ -+ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { -+ buf = volume_id_get_buffer(id, off + page-10, 10); -+ if (buf == NULL) -+ return -1; -+ -+ if (memcmp((char *)buf, "SWAP-SPACE", 10) == 0) { -+ strcpy(id->type_version, "1"); -+ goto found; -+ } -+ -+ if (memcmp((char *)buf, "SWAPSPACE2", 10) == 0) { -+ id->type = "swap"; -+ strcpy(id->type_version, "2"); -+ goto found_label; -+ } -+ -+ if (memcmp((char *)buf, "S1SUSPEND", 9) == 0) { -+ id->type = "suspend"; -+ strcpy(id->type_version, "s1suspend"); -+ goto found_label; -+ } -+ -+ if (memcmp((char *)buf, "ULSUSPEND", 9) == 0) { -+ id->type = "suspend"; -+ strcpy(id->type_version, "ulsuspend"); -+ goto found_label; -+ } -+ } -+ return -1; -+ -+found_label: -+ sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); -+ if (sw != NULL) { -+ volume_id_set_label_raw(id, sw->volume_name, 16); -+ volume_id_set_label_string(id, sw->volume_name, 16); -+ volume_id_set_uuid(id, sw->uuid, 0, UUID_DCE); -+ } -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_OTHER); -+ return 0; -+} - -=== added file 'libvolume_id/lsi_raid.c' ---- grub-0.97.orig/libvolume_id/lsi_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/lsi_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,55 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct lsi_meta { -+ uint8_t sig[6]; -+} PACKED; -+ -+#define LSI_SIGNATURE "$XIDE$" -+ -+int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct lsi_meta *lsi; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-1) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ lsi = (struct lsi_meta *) buf; -+ if (memcmp((char *)lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "lsi_mega_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/luks.c' ---- grub-0.97.orig/libvolume_id/luks.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/luks.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,76 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 W. Michael Petullo <mike@flyn.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define LUKS_SECTOR_SHIFT 9 -+#define LUKS_SECTOR_SIZE (1 << LUKS_SECTOR_SHIFT) -+ -+#define LUKS_CIPHERNAME_L 32 -+#define LUKS_CIPHERMODE_L 32 -+#define LUKS_HASHSPEC_L 32 -+#define LUKS_DIGESTSIZE 20 -+#define LUKS_SALTSIZE 32 -+#define LUKS_NUMKEYS 8 -+ -+#define LUKS_MAGIC_L 6 -+#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/LUKS_SECTOR_SIZE+1) -+#define UUID_STRING_L 40 -+static const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; -+ -+struct luks_phdr { -+ uint8_t magic[LUKS_MAGIC_L]; -+ uint16_t version; -+ uint8_t cipherName[LUKS_CIPHERNAME_L]; -+ uint8_t cipherMode[LUKS_CIPHERMODE_L]; -+ uint8_t hashSpec[LUKS_HASHSPEC_L]; -+ uint32_t payloadOffset; -+ uint32_t keyBytes; -+ uint8_t mkDigest[LUKS_DIGESTSIZE]; -+ uint8_t mkDigestSalt[LUKS_SALTSIZE]; -+ uint32_t mkDigestIterations; -+ uint8_t uuid[UUID_STRING_L]; -+ struct { -+ uint32_t active; -+ uint32_t passwordIterations; -+ uint8_t passwordSalt[LUKS_SALTSIZE]; -+ uint32_t keyMaterialOffset; -+ uint32_t stripes; -+ } keyblock[LUKS_NUMKEYS]; -+}; -+ -+int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct luks_phdr *header; -+ -+ header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); -+ if (header == NULL) -+ return -1; -+ -+ if (memcmp((char *)header->magic, (char *)LUKS_MAGIC, LUKS_MAGIC_L)) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_CRYPTO); -+ volume_id_set_uuid(id, header->uuid, 36, UUID_HEX_STRING); -+ sprintf(id->type_version, "%u", le16_to_cpu(header->version)); -+ id->type = "crypto_LUKS"; -+ return 0; -+} - -=== added file 'libvolume_id/lvm.c' ---- grub-0.97.orig/libvolume_id/lvm.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/lvm.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,92 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct lvm1_super_block { -+ uint8_t id[2]; -+} PACKED; -+ -+struct lvm2_super_block { -+ uint8_t id[8]; -+ uint64_t sector_xl; -+ uint32_t crc_xl; -+ uint32_t offset_xl; -+ uint8_t type[8]; -+} PACKED; -+ -+#define LVM1_SB_OFF 0x400 -+#define LVM1_MAGIC "HM" -+ -+int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct lvm1_super_block *lvm; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); -+ if (buf == NULL) -+ return -1; -+ -+ lvm = (struct lvm1_super_block *) buf; -+ -+ if (memcmp((char *)lvm->id, LVM1_MAGIC, 2) != 0) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "LVM1_member"; -+ -+ return 0; -+} -+ -+#define LVM2_LABEL_ID "LABELONE" -+#define LVM2LABEL_SCAN_SECTORS 4 -+ -+int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ unsigned int soff; -+ struct lvm2_super_block *lvm; -+ -+ dbg("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ -+ for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { -+ lvm = (struct lvm2_super_block *) &buf[soff]; -+ -+ if (memcmp((char *)lvm->id, LVM2_LABEL_ID, 8) == 0) -+ goto found; -+ } -+ -+ return -1; -+ -+found: -+ memcpy(id->type_version, lvm->type, 8); -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "LVM2_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/minix.c' ---- grub-0.97.orig/libvolume_id/minix.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/minix.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,112 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define MINIX_SUPERBLOCK_OFFSET 0x400 -+ -+#define MINIX_SUPER_MAGIC 0x137F -+#define MINIX_SUPER_MAGIC2 0x138F -+#define MINIX2_SUPER_MAGIC 0x2468 -+#define MINIX2_SUPER_MAGIC2 0x2478 -+#define MINIX3_SUPER_MAGIC 0x4d5a -+ -+struct minix_super_block -+{ -+ uint16_t s_ninodes; -+ uint16_t s_nzones; -+ uint16_t s_imap_blocks; -+ uint16_t s_zmap_blocks; -+ uint16_t s_firstdatazone; -+ uint16_t s_log_zone_size; -+ uint32_t s_max_size; -+ uint16_t s_magic; -+ uint16_t s_state; -+ uint32_t s_zones; -+} PACKED; -+ -+struct minix3_super_block { -+ uint32_t s_ninodes; -+ uint16_t s_pad0; -+ uint16_t s_imap_blocks; -+ uint16_t s_zmap_blocks; -+ uint16_t s_firstdatazone; -+ uint16_t s_log_zone_size; -+ uint16_t s_pad1; -+ uint32_t s_max_size; -+ uint32_t s_zones; -+ uint16_t s_magic; -+ uint16_t s_pad2; -+ uint16_t s_blocksize; -+ uint8_t s_disk_version; -+} PACKED; -+ -+int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint8_t *buf; -+ struct minix_super_block *ms; -+ struct minix3_super_block *m3s; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ ms = (struct minix_super_block *) buf; -+ -+ if (ms->s_magic == MINIX_SUPER_MAGIC || -+ ms->s_magic == bswap_16(MINIX_SUPER_MAGIC)) { -+ strcpy(id->type_version, "1"); -+ goto found; -+ } -+ if (ms->s_magic == MINIX_SUPER_MAGIC2 || -+ ms->s_magic == bswap_16(MINIX_SUPER_MAGIC2)) { -+ strcpy(id->type_version, "1"); -+ goto found; -+ } -+ if (ms->s_magic == MINIX2_SUPER_MAGIC || -+ ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC)) { -+ strcpy(id->type_version, "2"); -+ goto found; -+ } -+ if (ms->s_magic == MINIX2_SUPER_MAGIC2 || -+ ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC2)) { -+ strcpy(id->type_version, "2"); -+ goto found; -+ } -+ -+ m3s = (struct minix3_super_block *) buf; -+ if (m3s->s_magic == MINIX3_SUPER_MAGIC || -+ m3s->s_magic == bswap_16(MINIX3_SUPER_MAGIC)) { -+ strcpy(id->type_version, "3"); -+ goto found; -+ } -+ goto exit; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "minix"; -+ return 0; -+ -+exit: -+ return -1; -+} - -=== added file 'libvolume_id/misc.c' ---- grub-0.97.orig/libvolume_id/misc.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/misc.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,34 @@ -+/* -+ * volume_id/misc.c -+ * -+ * Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+#define _GNU_SOURCE -+#include <string.h> -+ -+/* -+ * Misc auxiliary functions required for volume_id inside grub -+ */ -+size_t strnlen(const char *s, size_t limit) -+{ -+ size_t length = 0; -+ while ( (length < limit) && (*s++) ) -+ length++; -+ -+ return length; -+} -+ -+char *strchr (const char *s, int c) -+{ -+ do { -+ if ( *s == c ) { -+ return (char*)s; -+ } -+ } while ( *s++ ); -+ -+ return 0; -+} - -=== added file 'libvolume_id/netware.c' ---- grub-0.97.orig/libvolume_id/netware.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/netware.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,98 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define NW_SUPERBLOCK_OFFSET 0x1000 -+ -+struct netware_super_block { -+ uint8_t SBH_Signature[4]; -+ uint16_t SBH_VersionMajor; -+ uint16_t SBH_VersionMinor; -+ uint16_t SBH_VersionMediaMajor; -+ uint16_t SBH_VersionMediaMinor; -+ uint32_t SBH_ItemsMoved; -+ uint8_t SBH_InternalID[16]; -+ uint32_t SBH_PackedSize; -+ uint32_t SBH_Checksum; -+ uint32_t supersyncid; -+ int64_t superlocation[4]; -+ uint32_t physSizeUsed; -+ uint32_t sizeUsed; -+ uint32_t superTimeStamp; -+ uint32_t reserved0[1]; -+ int64_t SBH_LoggedPoolDataBlk; -+ int64_t SBH_PoolDataBlk; -+ uint8_t SBH_OldInternalID[16]; -+ uint32_t SBH_PoolToLVStartUTC; -+ uint32_t SBH_PoolToLVEndUTC; -+ uint16_t SBH_VersionMediaMajorCreate; -+ uint16_t SBH_VersionMediaMinorCreate; -+ uint32_t SBH_BlocksMoved; -+ uint32_t SBH_TempBTSpBlk; -+ uint32_t SBH_TempFTSpBlk; -+ uint32_t SBH_TempFTSpBlk1; -+ uint32_t SBH_TempFTSpBlk2; -+ uint32_t nssMagicNumber; -+ uint32_t poolClassID; -+ uint32_t poolID; -+ uint32_t createTime; -+ int64_t SBH_LoggedVolumeDataBlk; -+ int64_t SBH_VolumeDataBlk; -+ int64_t SBH_SystemBeastBlkNum; -+ uint64_t totalblocks; -+ uint16_t SBH_Name[64]; -+ uint8_t SBH_VolumeID[16]; -+ uint8_t SBH_PoolID[16]; -+ uint8_t SBH_PoolInternalID[16]; -+ uint64_t SBH_Lsn; -+ uint32_t SBH_SS_Enabled; -+ uint32_t SBH_SS_CreateTime; -+ uint8_t SBH_SS_OriginalPoolID[16]; -+ uint8_t SBH_SS_OriginalVolumeID[16]; -+ uint8_t SBH_SS_Guid[16]; -+ uint16_t SBH_SS_OriginalName[64]; -+ uint32_t reserved2[64-(2+46)]; -+} PACKED; -+ -+int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct netware_super_block *nw; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ nw = (struct netware_super_block *) volume_id_get_buffer(id, off + NW_SUPERBLOCK_OFFSET, 0x200); -+ if (nw == NULL) -+ return -1; -+ -+ if (memcmp((char *)nw->SBH_Signature, "SPB5", 4) != 0) -+ return -1; -+ -+ volume_id_set_uuid(id, nw->SBH_PoolID, 0, UUID_DCE); -+ -+ sprintf(id->type_version, "%u.%02u", -+ le16_to_cpu(nw->SBH_VersionMediaMajor), le16_to_cpu(nw->SBH_VersionMediaMinor)); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "nss"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/ntfs.c' ---- grub-0.97.orig/libvolume_id/ntfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/ntfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,192 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+static struct ntfs_super_block { -+ uint8_t jump[3]; -+ uint8_t oem_id[8]; -+ uint16_t bytes_per_sector; -+ uint8_t sectors_per_cluster; -+ uint16_t reserved_sectors; -+ uint8_t fats; -+ uint16_t root_entries; -+ uint16_t sectors; -+ uint8_t media_type; -+ uint16_t sectors_per_fat; -+ uint16_t sectors_per_track; -+ uint16_t heads; -+ uint32_t hidden_sectors; -+ uint32_t large_sectors; -+ uint16_t unused[2]; -+ uint64_t number_of_sectors; -+ uint64_t mft_cluster_location; -+ uint64_t mft_mirror_cluster_location; -+ int8_t cluster_per_mft_record; -+ uint8_t reserved1[3]; -+ int8_t cluster_per_index_record; -+ uint8_t reserved2[3]; -+ uint8_t volume_serial[8]; -+ uint16_t checksum; -+} PACKED *ns; -+ -+static struct master_file_table_record { -+ uint8_t magic[4]; -+ uint16_t usa_ofs; -+ uint16_t usa_count; -+ uint64_t lsn; -+ uint16_t sequence_number; -+ uint16_t link_count; -+ uint16_t attrs_offset; -+ uint16_t flags; -+ uint32_t bytes_in_use; -+ uint32_t bytes_allocated; -+} PACKED *mftr; -+ -+static struct file_attribute { -+ uint32_t type; -+ uint32_t len; -+ uint8_t non_resident; -+ uint8_t name_len; -+ uint16_t name_offset; -+ uint16_t flags; -+ uint16_t instance; -+ uint32_t value_len; -+ uint16_t value_offset; -+} PACKED *attr; -+ -+static struct volume_info { -+ uint64_t reserved; -+ uint8_t major_ver; -+ uint8_t minor_ver; -+} PACKED *info; -+ -+#define MFT_RECORD_VOLUME 3 -+#define MFT_RECORD_ATTR_VOLUME_NAME 0x60 -+#define MFT_RECORD_ATTR_VOLUME_INFO 0x70 -+#define MFT_RECORD_ATTR_OBJECT_ID 0x40 -+#define MFT_RECORD_ATTR_END 0xffffffffu -+ -+#undef debug -+#define debug grub_printf -+ -+int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ unsigned int sector_size; -+ unsigned int cluster_size; -+ uint64_t mft_cluster; -+ uint64_t mft_off; -+ unsigned int mft_record_size; -+ unsigned int attr_type; -+ unsigned int attr_off; -+ unsigned int attr_len; -+ unsigned int val_off; -+ unsigned int val_len; -+ const uint8_t *buf; -+ const uint8_t *val; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); -+ if (ns == NULL) -+ return -1; -+ -+ if (memcmp((char *)ns->oem_id, "NTFS", 4) != 0) -+ return -1; -+ -+ volume_id_set_uuid(id, ns->volume_serial, 0, UUID_64BIT_LE); -+ -+ sector_size = le16_to_cpu(ns->bytes_per_sector); -+ if (sector_size < 0x200) -+ return -1; -+ -+ cluster_size = ns->sectors_per_cluster * sector_size; -+ mft_cluster = le64_to_cpu(ns->mft_cluster_location); -+ mft_off = mft_cluster * cluster_size; -+ -+ if (ns->cluster_per_mft_record < 0) -+ /* size = -log2(mft_record_size); normally 1024 Bytes */ -+ mft_record_size = 1 << -ns->cluster_per_mft_record; -+ else -+ mft_record_size = ns->cluster_per_mft_record * cluster_size; -+ -+ dbg("sectorsize 0x%x", sector_size); -+ dbg("clustersize 0x%x", cluster_size); -+ dbg("mftcluster %llu", (unsigned long long) mft_cluster); -+ dbg("mftoffset 0x%llx", (unsigned long long) mft_off); -+ dbg("cluster per mft_record %i", ns->cluster_per_mft_record); -+ dbg("mft record size %i", mft_record_size); -+ -+ buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size), -+ mft_record_size); -+ if (buf == NULL) -+ return -1; -+ -+ mftr = (struct master_file_table_record*) buf; -+ dbg("mftr->magic '%c%c%c%c'", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]); -+ if (memcmp((char *)mftr->magic, "FILE", 4) != 0) -+ return -1; -+ -+ attr_off = le16_to_cpu(mftr->attrs_offset); -+ dbg("file $Volume's attributes are at offset %i", attr_off); -+ -+ while (1) { -+ attr = (struct file_attribute*) &buf[attr_off]; -+ attr_type = le32_to_cpu(attr->type); -+ attr_len = le16_to_cpu(attr->len); -+ val_off = le16_to_cpu(attr->value_offset); -+ val_len = le32_to_cpu(attr->value_len); -+ attr_off += attr_len; -+ -+ if (attr_len == 0) -+ break; -+ -+ if (attr_off >= mft_record_size) -+ break; -+ -+ if (attr_type == MFT_RECORD_ATTR_END) -+ break; -+ -+ dbg("found attribute type 0x%x, len %i, at offset %i", -+ attr_type, attr_len, attr_off); -+ -+ if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { -+ dbg("found info, len %i", val_len); -+ info = (struct volume_info*) (((uint8_t *) attr) + val_off); -+ sprintf(id->type_version, "%u.%u", info->major_ver, info->minor_ver); -+ } -+ -+ if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { -+ dbg("found label, len %i", val_len); -+ if (val_len > VOLUME_ID_LABEL_SIZE) -+ val_len = VOLUME_ID_LABEL_SIZE; -+ -+ val = ((uint8_t *) attr) + val_off; -+ volume_id_set_label_raw(id, val, val_len); -+ volume_id_set_label_unicode16(id, val, LE, val_len); -+ } -+ } -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "ntfs"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/nvidia_raid.c' ---- grub-0.97.orig/libvolume_id/nvidia_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/nvidia_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,59 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct nvidia_meta { -+ uint8_t vendor[8]; -+ uint32_t size; -+ uint32_t chksum; -+ uint16_t version; -+} PACKED; -+ -+#define NVIDIA_SIGNATURE "NVIDIA" -+ -+int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct nvidia_meta *nv; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-2) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ nv = (struct nvidia_meta *) buf; -+ if (memcmp((char *)nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ sprintf(id->type_version, "%u", le16_to_cpu(nv->version)); -+ id->type = "nvidia_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/ocfs.c' ---- grub-0.97.orig/libvolume_id/ocfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/ocfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,186 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Andre Masella <andre@masella.no-ip.org> -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct ocfs1_super_block_header { -+ uint32_t minor_version; -+ uint32_t major_version; -+ uint8_t signature[128]; -+ uint8_t mount_point[128]; -+ uint64_t serial_num; -+ uint64_t device_size; -+ uint64_t start_off; -+ uint64_t bitmap_off; -+ uint64_t publ_off; -+ uint64_t vote_off; -+ uint64_t root_bitmap_off; -+ uint64_t data_start_off; -+ uint64_t root_bitmap_size; -+ uint64_t root_off; -+ uint64_t root_size; -+ uint64_t cluster_size; -+ uint64_t num_nodes; -+ uint64_t num_clusters; -+ uint64_t dir_node_size; -+ uint64_t file_node_size; -+ uint64_t internal_off; -+ uint64_t node_cfg_off; -+ uint64_t node_cfg_size; -+ uint64_t new_cfg_off; -+ uint32_t prot_bits; -+ int32_t excl_mount; -+} PACKED; -+ -+struct ocfs1_super_block_label { -+ struct ocfs1_disk_lock { -+ uint32_t curr_master; -+ uint8_t file_lock; -+ uint8_t compat_pad[3]; -+ uint64_t last_write_time; -+ uint64_t last_read_time; -+ uint32_t writer_node_num; -+ uint32_t reader_node_num; -+ uint64_t oin_node_map; -+ uint64_t dlock_seq_num; -+ } PACKED disk_lock; -+ uint8_t label[64]; -+ uint16_t label_len; -+ uint8_t vol_id[16]; -+ uint16_t vol_id_len; -+ uint8_t cluster_name[64]; -+ uint16_t cluster_name_len; -+} PACKED; -+ -+struct ocfs2_super_block { -+ uint8_t i_signature[8]; -+ uint32_t i_generation; -+ int16_t i_suballoc_slot; -+ uint16_t i_suballoc_bit; -+ uint32_t i_reserved0; -+ uint32_t i_clusters; -+ uint32_t i_uid; -+ uint32_t i_gid; -+ uint64_t i_size; -+ uint16_t i_mode; -+ uint16_t i_links_count; -+ uint32_t i_flags; -+ uint64_t i_atime; -+ uint64_t i_ctime; -+ uint64_t i_mtime; -+ uint64_t i_dtime; -+ uint64_t i_blkno; -+ uint64_t i_last_eb_blk; -+ uint32_t i_fs_generation; -+ uint32_t i_atime_nsec; -+ uint32_t i_ctime_nsec; -+ uint32_t i_mtime_nsec; -+ uint64_t i_reserved1[9]; -+ uint64_t i_pad1; -+ uint16_t s_major_rev_level; -+ uint16_t s_minor_rev_level; -+ uint16_t s_mnt_count; -+ int16_t s_max_mnt_count; -+ uint16_t s_state; -+ uint16_t s_errors; -+ uint32_t s_checkinterval; -+ uint64_t s_lastcheck; -+ uint32_t s_creator_os; -+ uint32_t s_feature_compat; -+ uint32_t s_feature_incompat; -+ uint32_t s_feature_ro_compat; -+ uint64_t s_root_blkno; -+ uint64_t s_system_dir_blkno; -+ uint32_t s_blocksize_bits; -+ uint32_t s_clustersize_bits; -+ uint16_t s_max_slots; -+ uint16_t s_reserved1; -+ uint32_t s_reserved2; -+ uint64_t s_first_cluster_group; -+ uint8_t s_label[64]; -+ uint8_t s_uuid[16]; -+} PACKED; -+ -+int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct ocfs1_super_block_header *osh; -+ struct ocfs1_super_block_label *osl; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ osh = (struct ocfs1_super_block_header *) buf; -+ if (memcmp((char *)osh->signature, "OracleCFS", 9) != 0) -+ return -1; -+ sprintf(id->type_version, "%u.%u", osh->major_version, osh->minor_version); -+ -+ dbg("found OracleCFS signature, now reading label"); -+ buf = volume_id_get_buffer(id, off + 0x200, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ osl = (struct ocfs1_super_block_label *) buf; -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ if (osl->label_len <= 64) { -+ volume_id_set_label_raw(id, osl->label, 64); -+ volume_id_set_label_string(id, osl->label, 64); -+ } -+ if (osl->vol_id_len == 16) -+ volume_id_set_uuid(id, osl->vol_id, 0, UUID_DCE); -+ id->type = "ocfs"; -+ return 0; -+} -+ -+#define OCFS2_MAX_BLOCKSIZE 0x1000 -+#define OCFS2_SUPER_BLOCK_BLKNO 2 -+ -+int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct ocfs2_super_block *os; -+ size_t blksize; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ for (blksize = 0x200; blksize <= OCFS2_MAX_BLOCKSIZE; blksize <<= 1) { -+ buf = volume_id_get_buffer(id, off + OCFS2_SUPER_BLOCK_BLKNO * blksize, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ os = (struct ocfs2_super_block *) buf; -+ if (memcmp((char *)os->i_signature, "OCFSV2", 6) != 0) -+ continue; -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ volume_id_set_label_raw(id, os->s_label, 64); -+ volume_id_set_label_string(id, os->s_label, 64); -+ volume_id_set_uuid(id, os->s_uuid, 0, UUID_DCE); -+ sprintf(id->type_version, "%u.%u", os->s_major_rev_level, os->s_minor_rev_level); -+ id->type = "ocfs2"; -+ return 0; -+ } -+ return -1; -+} - -=== added file 'libvolume_id/promise_raid.c' ---- grub-0.97.orig/libvolume_id/promise_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/promise_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,65 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct promise_meta { -+ uint8_t sig[24]; -+} PACKED; -+ -+#define PDC_CONFIG_OFF 0x1200 -+#define PDC_SIGNATURE "Promise Technology, Inc." -+ -+int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ struct promise_meta *pdc; -+ unsigned int i; -+ static unsigned int sectors[] = { -+ 63, 255, 256, 16, 399, 0 -+ }; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x40000) -+ return -1; -+ -+ for (i = 0; sectors[i] != 0; i++) { -+ uint64_t meta_off; -+ -+ meta_off = ((size / 0x200) - sectors[i]) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ pdc = (struct promise_meta *) buf; -+ if (memcmp((char *)pdc->sig, PDC_SIGNATURE, sizeof(PDC_SIGNATURE)-1) == 0) -+ goto found; -+ } -+ return -1; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ id->type = "promise_fasttrack_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/reiserfs.c' ---- grub-0.97.orig/libvolume_id/reiserfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/reiserfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,113 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Copyright (C) 2005 Tobias Klauser <tklauser@access.unizh.ch> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct reiserfs_super_block { -+ uint32_t blocks_count; -+ uint32_t free_blocks; -+ uint32_t root_block; -+ uint32_t journal_block; -+ uint32_t journal_dev; -+ uint32_t orig_journal_size; -+ uint32_t dummy2[5]; -+ uint16_t blocksize; -+ uint16_t dummy3[3]; -+ uint8_t magic[12]; -+ uint32_t dummy4[5]; -+ uint8_t uuid[16]; -+ uint8_t label[16]; -+} PACKED; -+ -+struct reiser4_super_block { -+ uint8_t magic[16]; -+ uint16_t dummy[2]; -+ uint8_t uuid[16]; -+ uint8_t label[16]; -+ uint64_t dummy2; -+} PACKED; -+ -+#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 -+#define REISERFS_SUPERBLOCK_OFFSET 0x10000 -+ -+int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct reiserfs_super_block *rs; -+ struct reiser4_super_block *rs4; -+ uint8_t *buf; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ buf = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ rs = (struct reiserfs_super_block *) buf; -+ if (memcmp((char *)rs->magic, "ReIsErFs", 8) == 0) { -+ strcpy(id->type_version, "3.5"); -+ id->type = "reiserfs"; -+ goto found; -+ } -+ if (memcmp((char *)rs->magic, "ReIsEr2Fs", 9) == 0) { -+ strcpy(id->type_version, "3.6"); -+ id->type = "reiserfs"; -+ goto found_label; -+ } -+ if (memcmp((char *)rs->magic, "ReIsEr3Fs", 9) == 0) { -+ strcpy(id->type_version, "JR"); -+ id->type = "reiserfs"; -+ goto found_label; -+ } -+ -+ rs4 = (struct reiser4_super_block *) buf; -+ if (memcmp((char *)rs4->magic, "ReIsEr4", 7) == 0) { -+ strcpy(id->type_version, "4"); -+ volume_id_set_label_raw(id, rs4->label, 16); -+ volume_id_set_label_string(id, rs4->label, 16); -+ volume_id_set_uuid(id, rs4->uuid, 0, UUID_DCE); -+ id->type = "reiser4"; -+ goto found; -+ } -+ -+ buf = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ rs = (struct reiserfs_super_block *) buf; -+ if (memcmp((char *)rs->magic, "ReIsErFs", 8) == 0) { -+ strcpy(id->type_version, "3.5"); -+ id->type = "reiserfs"; -+ goto found; -+ } -+ -+ return -1; -+ -+found_label: -+ volume_id_set_label_raw(id, rs->label, 16); -+ volume_id_set_label_string(id, rs->label, 16); -+ volume_id_set_uuid(id, rs->uuid, 0, UUID_DCE); -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ -+ return 0; -+} - -=== added file 'libvolume_id/romfs.c' ---- grub-0.97.orig/libvolume_id/romfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/romfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,55 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct romfs_super { -+ uint8_t magic[8]; -+ uint32_t size; -+ uint32_t checksum; -+ uint8_t name[0]; -+} PACKED; -+ -+int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct romfs_super *rfs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ rfs = (struct romfs_super *) volume_id_get_buffer(id, off, 0x200); -+ if (rfs == NULL) -+ return -1; -+ -+ if (memcmp((char *)rfs->magic, "-rom1fs-", 4) == 0) { -+ size_t len = strlen((char *)rfs->name); -+ -+ if (len) { -+ volume_id_set_label_raw(id, rfs->name, len); -+ volume_id_set_label_string(id, rfs->name, len); -+ } -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "romfs"; -+ return 0; -+ } -+ -+ return -1; -+} - -=== added file 'libvolume_id/silicon_raid.c' ---- grub-0.97.orig/libvolume_id/silicon_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/silicon_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,71 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct silicon_meta { -+ uint8_t unknown0[0x2E]; -+ uint8_t ascii_version[0x36 - 0x2E]; -+ uint8_t diskname[0x56 - 0x36]; -+ uint8_t unknown1[0x60 - 0x56]; -+ uint32_t magic; -+ uint32_t unknown1a[0x6C - 0x64]; -+ uint32_t array_sectors_low; -+ uint32_t array_sectors_high; -+ uint8_t unknown2[0x78 - 0x74]; -+ uint32_t thisdisk_sectors; -+ uint8_t unknown3[0x100 - 0x7C]; -+ uint8_t unknown4[0x104 - 0x100]; -+ uint16_t product_id; -+ uint16_t vendor_id; -+ uint16_t minor_ver; -+ uint16_t major_ver; -+} PACKED; -+ -+#define SILICON_MAGIC 0x2F000000 -+ -+int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct silicon_meta *sil; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-1) * 0x200; -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ sil = (struct silicon_meta *) buf; -+ if (le32_to_cpu(sil->magic) != SILICON_MAGIC) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ sprintf(id->type_version, "%u.%u", le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); -+ id->type = "silicon_medley_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/squashfs.c' ---- grub-0.97.orig/libvolume_id/squashfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/squashfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,63 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define SQUASHFS_MAGIC 0x73717368 -+ -+struct squashfs_super { -+ uint32_t s_magic; -+ uint32_t inodes; -+ uint32_t bytes_used_2; -+ uint32_t uid_start_2; -+ uint32_t guid_start_2; -+ uint32_t inode_table_start_2; -+ uint32_t directory_table_start_2; -+ uint16_t s_major; -+ uint16_t s_minor; -+} PACKED; -+ -+int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct squashfs_super *sqs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ sqs = (struct squashfs_super *) volume_id_get_buffer(id, off, 0x200); -+ if (sqs == NULL) -+ return -1; -+ -+ if (sqs->s_magic == SQUASHFS_MAGIC) { -+ sprintf(id->type_version, "%u.%u", sqs->s_major, sqs->s_minor); -+ goto found; -+ } -+ if (sqs->s_magic == bswap_32(SQUASHFS_MAGIC)) { -+ sprintf(id->type_version, "%u.%u", bswap_16(sqs->s_major), bswap_16(sqs->s_minor)); -+ goto found; -+ } -+ -+ return -1; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "squashfs"; -+ return 0; -+} - -=== added file 'libvolume_id/strfuncs.h' ---- grub-0.97.orig/libvolume_id/strfuncs.h 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/strfuncs.h 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,5 @@ -+ -+#include <stdlib.h> -+ -+size_t strnlen(const char *s, size_t limit); -+char *strchr (const char *s, int c); - -=== added file 'libvolume_id/sysv.c' ---- grub-0.97.orig/libvolume_id/sysv.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/sysv.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,128 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define SYSV_NICINOD 100 -+#define SYSV_NICFREE 50 -+ -+struct sysv_super -+{ -+ uint16_t s_isize; -+ uint16_t s_pad0; -+ uint32_t s_fsize; -+ uint16_t s_nfree; -+ uint16_t s_pad1; -+ uint32_t s_free[SYSV_NICFREE]; -+ uint16_t s_ninode; -+ uint16_t s_pad2; -+ uint16_t s_inode[SYSV_NICINOD]; -+ uint8_t s_flock; -+ uint8_t s_ilock; -+ uint8_t s_fmod; -+ uint8_t s_ronly; -+ uint32_t s_time; -+ uint16_t s_dinfo[4]; -+ uint32_t s_tfree; -+ uint16_t s_tinode; -+ uint16_t s_pad3; -+ uint8_t s_fname[6]; -+ uint8_t s_fpack[6]; -+ uint32_t s_fill[12]; -+ uint32_t s_state; -+ uint32_t s_magic; -+ uint32_t s_type; -+} PACKED; -+ -+#define XENIX_NICINOD 100 -+#define XENIX_NICFREE 100 -+ -+struct xenix_super { -+ uint16_t s_isize; -+ uint32_t s_fsize; -+ uint16_t s_nfree; -+ uint32_t s_free[XENIX_NICFREE]; -+ uint16_t s_ninode; -+ uint16_t s_inode[XENIX_NICINOD]; -+ uint8_t s_flock; -+ uint8_t s_ilock; -+ uint8_t s_fmod; -+ uint8_t s_ronly; -+ uint32_t s_time; -+ uint32_t s_tfree; -+ uint16_t s_tinode; -+ uint16_t s_dinfo[4]; -+ uint8_t s_fname[6]; -+ uint8_t s_fpack[6]; -+ uint8_t s_clean; -+ uint8_t s_fill[371]; -+ uint32_t s_magic; -+ uint32_t s_type; -+} PACKED; -+ -+#define SYSV_SUPERBLOCK_BLOCK 0x01 -+#define SYSV_MAGIC 0xfd187e20 -+#define XENIX_SUPERBLOCK_BLOCK 0x18 -+#define XENIX_MAGIC 0x2b5544 -+#define SYSV_MAX_BLOCKSIZE 0x800 -+ -+int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct sysv_super *vs; -+ struct xenix_super *xs; -+ unsigned int boff; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { -+ vs = (struct sysv_super *) -+ volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200); -+ if (vs == NULL) -+ return -1; -+ -+ if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) { -+ volume_id_set_label_raw(id, vs->s_fname, 6); -+ volume_id_set_label_string(id, vs->s_fname, 6); -+ id->type = "sysv"; -+ goto found; -+ } -+ } -+ -+ for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { -+ xs = (struct xenix_super *) -+ volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200); -+ if (xs == NULL) -+ return -1; -+ -+ if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) { -+ volume_id_set_label_raw(id, xs->s_fname, 6); -+ volume_id_set_label_string(id, xs->s_fname, 6); -+ id->type = "xenix"; -+ goto found; -+ } -+ } -+ -+ return -1; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ return 0; -+} - -=== added file 'libvolume_id/udf.c' ---- grub-0.97.orig/libvolume_id/udf.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/udf.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,173 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct volume_descriptor { -+ struct descriptor_tag { -+ uint16_t id; -+ uint16_t version; -+ uint8_t checksum; -+ uint8_t reserved; -+ uint16_t serial; -+ uint16_t crc; -+ uint16_t crc_len; -+ uint32_t location; -+ } PACKED tag; -+ union { -+ struct anchor_descriptor { -+ uint32_t length; -+ uint32_t location; -+ } PACKED anchor; -+ struct primary_descriptor { -+ uint32_t seq_num; -+ uint32_t desc_num; -+ struct dstring { -+ uint8_t clen; -+ uint8_t c[31]; -+ } PACKED ident; -+ } PACKED primary; -+ } PACKED type; -+} PACKED; -+ -+struct volume_structure_descriptor { -+ uint8_t type; -+ uint8_t id[5]; -+ uint8_t version; -+} PACKED; -+ -+#define UDF_VSD_OFFSET 0x8000 -+ -+int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct volume_descriptor *vd; -+ struct volume_structure_descriptor *vsd; -+ unsigned int bs; -+ unsigned int b; -+ unsigned int type; -+ unsigned int count; -+ unsigned int loc; -+ unsigned int clen; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200); -+ if (vsd == NULL) -+ return -1; -+ -+ if (memcmp((char *)vsd->id, "NSR02", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "NSR03", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "BEA01", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "BOOT2", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "CD001", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "CDW02", 5) == 0) -+ goto blocksize; -+ if (memcmp((char *)vsd->id, "TEA03", 5) == 0) -+ goto blocksize; -+ return -1; -+ -+blocksize: -+ /* search the next VSD to get the logical block size of the volume */ -+ for (bs = 0x800; bs < 0x8000; bs += 0x800) { -+ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800); -+ if (vsd == NULL) -+ return -1; -+ dbg("test for blocksize: 0x%x", bs); -+ if (vsd->id[0] != '\0') -+ goto nsr; -+ } -+ return -1; -+ -+nsr: -+ /* search the list of VSDs for a NSR descriptor */ -+ for (b = 0; b < 64; b++) { -+ vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800); -+ if (vsd == NULL) -+ return -1; -+ -+ dbg("vsd: %c%c%c%c%c", -+ vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); -+ -+ if (vsd->id[0] == '\0') -+ return -1; -+ if (memcmp((char *)vsd->id, "NSR02", 5) == 0) -+ goto anchor; -+ if (memcmp((char *)vsd->id, "NSR03", 5) == 0) -+ goto anchor; -+ } -+ return -1; -+ -+anchor: -+ /* read anchor volume descriptor */ -+ vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + (256 * bs), 0x200); -+ if (vd == NULL) -+ return -1; -+ -+ type = le16_to_cpu(vd->tag.id); -+ if (type != 2) /* TAG_ID_AVDP */ -+ goto found; -+ -+ /* get desriptor list address and block count */ -+ count = le32_to_cpu(vd->type.anchor.length) / bs; -+ loc = le32_to_cpu(vd->type.anchor.location); -+ dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); -+ -+ /* pick the primary descriptor from the list */ -+ for (b = 0; b < count; b++) { -+ vd = (struct volume_descriptor *) volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200); -+ if (vd == NULL) -+ return -1; -+ -+ type = le16_to_cpu(vd->tag.id); -+ dbg("descriptor type %i", type); -+ -+ /* check validity */ -+ if (type == 0) -+ goto found; -+ if (le32_to_cpu(vd->tag.location) != loc + b) -+ goto found; -+ -+ if (type == 1) /* TAG_ID_PVD */ -+ goto pvd; -+ } -+ goto found; -+ -+pvd: -+ volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32); -+ -+ clen = vd->type.primary.ident.clen; -+ dbg("label string charsize=%i bit", clen); -+ if (clen == 8) -+ volume_id_set_label_string(id, vd->type.primary.ident.c, 31); -+ else if (clen == 16) -+ volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE,31); -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "udf"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/ufs.c' ---- grub-0.97.orig/libvolume_id/ufs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/ufs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,217 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct ufs_super_block { -+ uint32_t fs_link; -+ uint32_t fs_rlink; -+ uint32_t fs_sblkno; -+ uint32_t fs_cblkno; -+ uint32_t fs_iblkno; -+ uint32_t fs_dblkno; -+ uint32_t fs_cgoffset; -+ uint32_t fs_cgmask; -+ uint32_t fs_time; -+ uint32_t fs_size; -+ uint32_t fs_dsize; -+ uint32_t fs_ncg; -+ uint32_t fs_bsize; -+ uint32_t fs_fsize; -+ uint32_t fs_frag; -+ uint32_t fs_minfree; -+ uint32_t fs_rotdelay; -+ uint32_t fs_rps; -+ uint32_t fs_bmask; -+ uint32_t fs_fmask; -+ uint32_t fs_bshift; -+ uint32_t fs_fshift; -+ uint32_t fs_maxcontig; -+ uint32_t fs_maxbpg; -+ uint32_t fs_fragshift; -+ uint32_t fs_fsbtodb; -+ uint32_t fs_sbsize; -+ uint32_t fs_csmask; -+ uint32_t fs_csshift; -+ uint32_t fs_nindir; -+ uint32_t fs_inopb; -+ uint32_t fs_nspf; -+ uint32_t fs_optim; -+ uint32_t fs_npsect_state; -+ uint32_t fs_interleave; -+ uint32_t fs_trackskew; -+ uint32_t fs_id[2]; -+ uint32_t fs_csaddr; -+ uint32_t fs_cssize; -+ uint32_t fs_cgsize; -+ uint32_t fs_ntrak; -+ uint32_t fs_nsect; -+ uint32_t fs_spc; -+ uint32_t fs_ncyl; -+ uint32_t fs_cpg; -+ uint32_t fs_ipg; -+ uint32_t fs_fpg; -+ struct ufs_csum { -+ uint32_t cs_ndir; -+ uint32_t cs_nbfree; -+ uint32_t cs_nifree; -+ uint32_t cs_nffree; -+ } PACKED fs_cstotal; -+ int8_t fs_fmod; -+ int8_t fs_clean; -+ int8_t fs_ronly; -+ int8_t fs_flags; -+ union { -+ struct { -+ int8_t fs_fsmnt[512]; -+ uint32_t fs_cgrotor; -+ uint32_t fs_csp[31]; -+ uint32_t fs_maxcluster; -+ uint32_t fs_cpc; -+ uint16_t fs_opostbl[16][8]; -+ } PACKED fs_u1; -+ struct { -+ int8_t fs_fsmnt[468]; -+ uint8_t fs_volname[32]; -+ uint64_t fs_swuid; -+ int32_t fs_pad; -+ uint32_t fs_cgrotor; -+ uint32_t fs_ocsp[28]; -+ uint32_t fs_contigdirs; -+ uint32_t fs_csp; -+ uint32_t fs_maxcluster; -+ uint32_t fs_active; -+ int32_t fs_old_cpc; -+ int32_t fs_maxbsize; -+ int64_t fs_sparecon64[17]; -+ int64_t fs_sblockloc; -+ struct ufs2_csum_total { -+ uint64_t cs_ndir; -+ uint64_t cs_nbfree; -+ uint64_t cs_nifree; -+ uint64_t cs_nffree; -+ uint64_t cs_numclusters; -+ uint64_t cs_spare[3]; -+ } PACKED fs_cstotal; -+ struct ufs_timeval { -+ int32_t tv_sec; -+ int32_t tv_usec; -+ } PACKED fs_time; -+ int64_t fs_size; -+ int64_t fs_dsize; -+ uint64_t fs_csaddr; -+ int64_t fs_pendingblocks; -+ int32_t fs_pendinginodes; -+ } PACKED fs_u2; -+ } fs_u11; -+ union { -+ struct { -+ int32_t fs_sparecon[53]; -+ int32_t fs_reclaim; -+ int32_t fs_sparecon2[1]; -+ int32_t fs_state; -+ uint32_t fs_qbmask[2]; -+ uint32_t fs_qfmask[2]; -+ } PACKED fs_sun; -+ struct { -+ int32_t fs_sparecon[53]; -+ int32_t fs_reclaim; -+ int32_t fs_sparecon2[1]; -+ uint32_t fs_npsect; -+ uint32_t fs_qbmask[2]; -+ uint32_t fs_qfmask[2]; -+ } PACKED fs_sunx86; -+ struct { -+ int32_t fs_sparecon[50]; -+ int32_t fs_contigsumsize; -+ int32_t fs_maxsymlinklen; -+ int32_t fs_inodefmt; -+ uint32_t fs_maxfilesize[2]; -+ uint32_t fs_qbmask[2]; -+ uint32_t fs_qfmask[2]; -+ int32_t fs_state; -+ } PACKED fs_44; -+ } fs_u2; -+ int32_t fs_postblformat; -+ int32_t fs_nrpos; -+ int32_t fs_postbloff; -+ int32_t fs_rotbloff; -+ uint32_t fs_magic; -+ uint8_t fs_space[1]; -+} PACKED; -+ -+#define UFS_MAGIC 0x00011954 -+#define UFS2_MAGIC 0x19540119 -+#define UFS_MAGIC_FEA 0x00195612 -+#define UFS_MAGIC_LFN 0x00095014 -+ -+int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ uint32_t magic; -+ int i; -+ struct ufs_super_block *ufs; -+ int offsets[] = {0, 8, 64, 256, -1}; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ for (i = 0; offsets[i] >= 0; i++) { -+ ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800); -+ if (ufs == NULL) -+ return -1; -+ -+ dbg("offset 0x%x", offsets[i] * 0x400); -+ magic = be32_to_cpu(ufs->fs_magic); -+ if ((magic == UFS_MAGIC) || -+ (magic == UFS2_MAGIC) || -+ (magic == UFS_MAGIC_FEA) || -+ (magic == UFS_MAGIC_LFN)) { -+ dbg("magic 0x%08x(be)", magic); -+ goto found; -+ } -+ magic = le32_to_cpu(ufs->fs_magic); -+ if ((magic == UFS_MAGIC) || -+ (magic == UFS2_MAGIC) || -+ (magic == UFS_MAGIC_FEA) || -+ (magic == UFS_MAGIC_LFN)) { -+ dbg("magic 0x%08x(le)", magic); -+ goto found; -+ } -+ } -+ return -1; -+ -+found: -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "ufs"; -+ switch (magic) { -+ case UFS_MAGIC: -+ strcpy(id->type_version, "1"); -+ break; -+ case UFS2_MAGIC: -+ strcpy(id->type_version, "2"); -+ volume_id_set_label_raw(id, ufs->fs_u11.fs_u2.fs_volname, 32); -+ volume_id_set_label_string(id, ufs->fs_u11.fs_u2.fs_volname, 32); -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} - -=== added file 'libvolume_id/util.c' ---- grub-0.97.orig/libvolume_id/util.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/util.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,472 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include <stdlib.h> -+ -+#include "strfuncs.h" -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+static char hex[] = "0123456789abcdef"; -+ -+#define hexhi(val) hex[val >> 4] -+#define hexlo(val) hex[val & 0xf] -+ -+/* count of characters used to encode one unicode char */ -+static int utf8_encoded_expected_len(const char *str) -+{ -+ unsigned char c = (unsigned char)str[0]; -+ -+ if (c < 0x80) -+ return 1; -+ if ((c & 0xe0) == 0xc0) -+ return 2; -+ if ((c & 0xf0) == 0xe0) -+ return 3; -+ if ((c & 0xf8) == 0xf0) -+ return 4; -+ if ((c & 0xfc) == 0xf8) -+ return 5; -+ if ((c & 0xfe) == 0xfc) -+ return 6; -+ return 0; -+} -+ -+/* decode one unicode char */ -+static int utf8_encoded_to_unichar(const char *str) -+{ -+ int unichar; -+ int len; -+ int i; -+ -+ len = utf8_encoded_expected_len(str); -+ switch (len) { -+ case 1: -+ return (int)str[0]; -+ case 2: -+ unichar = str[0] & 0x1f; -+ break; -+ case 3: -+ unichar = (int)str[0] & 0x0f; -+ break; -+ case 4: -+ unichar = (int)str[0] & 0x07; -+ break; -+ case 5: -+ unichar = (int)str[0] & 0x03; -+ break; -+ case 6: -+ unichar = (int)str[0] & 0x01; -+ break; -+ default: -+ return -1; -+ } -+ -+ for (i = 1; i < len; i++) { -+ if (((int)str[i] & 0xc0) != 0x80) -+ return -1; -+ unichar <<= 6; -+ unichar |= (int)str[i] & 0x3f; -+ } -+ -+ return unichar; -+} -+ -+/* expected size used to encode one unicode char */ -+static int utf8_unichar_to_encoded_len(int unichar) -+{ -+ if (unichar < 0x80) -+ return 1; -+ if (unichar < 0x800) -+ return 2; -+ if (unichar < 0x10000) -+ return 3; -+ if (unichar < 0x200000) -+ return 4; -+ if (unichar < 0x4000000) -+ return 5; -+ return 6; -+} -+ -+/* check if unicode char has a valid numeric range */ -+static int utf8_unichar_valid_range(int unichar) -+{ -+ if (unichar > 0x10ffff) -+ return 0; -+ if ((unichar & 0xfffff800) == 0xd800) -+ return 0; -+ if ((unichar > 0xfdcf) && (unichar < 0xfdf0)) -+ return 0; -+ if ((unichar & 0xffff) == 0xffff) -+ return 0; -+ return 1; -+} -+ -+/* validate one encoded unicode char and return its length */ -+int volume_id_utf8_encoded_valid_unichar(const char *str) -+{ -+ int len; -+ int unichar; -+ int i; -+ -+ len = utf8_encoded_expected_len(str); -+ if (len == 0) -+ return -1; -+ -+ /* ascii is valid */ -+ if (len == 1) -+ return 1; -+ -+ /* check if expected encoded chars are available */ -+ for (i = 0; i < len; i++) -+ if ((str[i] & 0x80) != 0x80) -+ return -1; -+ -+ unichar = utf8_encoded_to_unichar(str); -+ -+ /* check if encoded length matches encoded value */ -+ if (utf8_unichar_to_encoded_len(unichar) != len) -+ return -1; -+ -+ /* check if value has valid range */ -+ if (!utf8_unichar_valid_range(unichar)) -+ return -1; -+ -+ return len; -+} -+ -+size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) -+{ -+ size_t i, j; -+ uint16_t c; -+ -+ j = 0; -+ for (i = 0; i + 2 <= count; i += 2) { -+ if (endianess == LE) -+ c = (buf[i+1] << 8) | buf[i]; -+ else -+ c = (buf[i] << 8) | buf[i+1]; -+ if (c == 0) { -+ str[j] = '\0'; -+ break; -+ } else if (c < 0x80) { -+ if (j+1 >= len) -+ break; -+ str[j++] = (uint8_t) c; -+ } else if (c < 0x800) { -+ if (j+2 >= len) -+ break; -+ str[j++] = (uint8_t) (0xc0 | (c >> 6)); -+ str[j++] = (uint8_t) (0x80 | (c & 0x3f)); -+ } else { -+ if (j+3 >= len) -+ break; -+ str[j++] = (uint8_t) (0xe0 | (c >> 12)); -+ str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); -+ str[j++] = (uint8_t) (0x80 | (c & 0x3f)); -+ } -+ } -+ str[j] = '\0'; -+ return j; -+} -+ -+static char *usage_to_string(enum volume_id_usage usage_id) -+{ -+ switch (usage_id) { -+ case VOLUME_ID_FILESYSTEM: -+ return "filesystem"; -+ case VOLUME_ID_OTHER: -+ return "other"; -+ case VOLUME_ID_RAID: -+ return "raid"; -+ case VOLUME_ID_DISKLABEL: -+ return "disklabel"; -+ case VOLUME_ID_CRYPTO: -+ return "crypto"; -+ case VOLUME_ID_UNPROBED: -+ return "unprobed"; -+ case VOLUME_ID_UNUSED: -+ return "unused"; -+ } -+ return NULL; -+} -+ -+void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id) -+{ -+ id->usage_id = usage_id; -+ id->usage = usage_to_string(usage_id); -+} -+ -+void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count) -+{ -+ if (count > sizeof(id->label)) -+ count = sizeof(id->label); -+ -+ memcpy(id->label_raw, buf, count); -+ id->label_raw_len = count; -+} -+ -+void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count) -+{ -+ size_t i; -+ -+ if (count >= sizeof(id->label)) -+ count = sizeof(id->label)-1; -+ -+ memcpy(id->label, buf, count); -+ id->label[count] = '\0'; -+ -+ /* remove trailing whitespace */ -+ i = strnlen(id->label, count); -+ while (i--) { -+ if (!isspace(id->label[i])) -+ break; -+ } -+ id->label[i+1] = '\0'; -+} -+ -+void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) -+{ -+ if (count >= sizeof(id->label)) -+ count = sizeof(id->label)-1; -+ -+ volume_id_set_unicode16((uint8_t *)id->label, sizeof(id->label), buf, endianess, count); -+} -+ -+void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format) -+{ -+ unsigned int i; -+ unsigned int count = 0; -+ char *uuid; -+ -+ if (len > sizeof(id->uuid_raw)) -+ len = sizeof(id->uuid_raw); -+ -+ switch(format) { -+ case UUID_STRING: -+ count = len; -+ break; -+ case UUID_HEX_STRING: -+ count = len; -+ break; -+ case UUID_DOS: -+ count = 4; -+ break; -+ case UUID_64BIT_LE: -+ case UUID_64BIT_BE: -+ count = 8; -+ break; -+ case UUID_DCE: -+ count = 16; -+ break; -+ case UUID_FOURINT: -+ count = 35; -+ break; -+ } -+ memcpy(id->uuid_raw, buf, count); -+ id->uuid_raw_len = count; -+ -+ /* if set, create string in the same format, the native platform uses */ -+ for (i = 0; i < count; i++) -+ if (buf[i] != 0) -+ goto set; -+ return; -+ -+set: -+ uuid = id->uuid; -+ switch(format) { -+ case UUID_DOS: -+ *uuid++ = hexhi(buf[3]); -+ *uuid++ = hexlo(buf[3]); -+ *uuid++ = hexhi(buf[2]); -+ *uuid++ = hexlo(buf[2]); -+ *uuid++ = '-'; -+ *uuid++ = hexhi(buf[1]); -+ *uuid++ = hexlo(buf[1]); -+ *uuid++ = hexhi(buf[0]); -+ *uuid++ = hexlo(buf[0]); -+ *uuid = '\0'; -+ break; -+ case UUID_64BIT_LE: -+ *uuid++ = hexhi(buf[7]); -+ *uuid++ = hexlo(buf[7]); -+ *uuid++ = hexhi(buf[6]); -+ *uuid++ = hexlo(buf[6]); -+ *uuid++ = hexhi(buf[5]); -+ *uuid++ = hexlo(buf[5]); -+ *uuid++ = hexhi(buf[4]); -+ *uuid++ = hexlo(buf[4]); -+ *uuid++ = hexhi(buf[3]); -+ *uuid++ = hexlo(buf[3]); -+ *uuid++ = hexhi(buf[2]); -+ *uuid++ = hexlo(buf[2]); -+ *uuid++ = hexhi(buf[1]); -+ *uuid++ = hexlo(buf[1]); -+ *uuid++ = hexhi(buf[0]); -+ *uuid++ = hexlo(buf[0]); -+ *uuid = '\0'; -+ break; -+ case UUID_64BIT_BE: -+ *uuid++ = hexhi(buf[0]); -+ *uuid++ = hexlo(buf[0]); -+ *uuid++ = hexhi(buf[1]); -+ *uuid++ = hexlo(buf[1]); -+ *uuid++ = hexhi(buf[2]); -+ *uuid++ = hexlo(buf[2]); -+ *uuid++ = hexhi(buf[3]); -+ *uuid++ = hexlo(buf[3]); -+ *uuid++ = hexhi(buf[4]); -+ *uuid++ = hexlo(buf[4]); -+ *uuid++ = hexhi(buf[5]); -+ *uuid++ = hexlo(buf[5]); -+ *uuid++ = hexhi(buf[6]); -+ *uuid++ = hexlo(buf[6]); -+ *uuid++ = hexhi(buf[7]); -+ *uuid++ = hexlo(buf[7]); -+ *uuid = '\0'; -+ break; -+ case UUID_DCE: -+ *uuid++ = hexhi(buf[0]); -+ *uuid++ = hexlo(buf[0]); -+ *uuid++ = hexhi(buf[1]); -+ *uuid++ = hexlo(buf[1]); -+ *uuid++ = hexhi(buf[2]); -+ *uuid++ = hexlo(buf[2]); -+ *uuid++ = hexhi(buf[3]); -+ *uuid++ = hexlo(buf[3]); -+ *uuid++ = '-'; -+ *uuid++ = hexhi(buf[4]); -+ *uuid++ = hexlo(buf[4]); -+ *uuid++ = hexhi(buf[5]); -+ *uuid++ = hexlo(buf[5]); -+ *uuid++ = '-'; -+ *uuid++ = hexhi(buf[6]); -+ *uuid++ = hexlo(buf[6]); -+ *uuid++ = hexhi(buf[7]); -+ *uuid++ = hexlo(buf[7]); -+ *uuid++ = '-'; -+ *uuid++ = hexhi(buf[8]); -+ *uuid++ = hexlo(buf[8]); -+ *uuid++ = hexhi(buf[9]); -+ *uuid++ = hexlo(buf[9]); -+ *uuid++ = '-'; -+ *uuid++ = hexhi(buf[10]); -+ *uuid++ = hexlo(buf[10]); -+ *uuid++ = hexhi(buf[11]); -+ *uuid++ = hexlo(buf[11]); -+ *uuid++ = hexhi(buf[12]); -+ *uuid++ = hexlo(buf[12]); -+ *uuid++ = hexhi(buf[13]); -+ *uuid++ = hexlo(buf[13]); -+ *uuid++ = hexhi(buf[14]); -+ *uuid++ = hexlo(buf[14]); -+ *uuid++ = hexhi(buf[15]); -+ *uuid++ = hexlo(buf[15]); -+ *uuid = '\0'; -+ break; -+ case UUID_HEX_STRING: -+ /* translate A..F to a..f */ -+ memcpy(id->uuid, buf, count); -+ for (i = 0; i < count; i++) -+ if (id->uuid[i] >= 'A' && id->uuid[i] <= 'F') -+ id->uuid[i] = (id->uuid[i] - 'A') + 'a'; -+ id->uuid[count] = '\0'; -+ break; -+ case UUID_STRING: -+ memcpy(id->uuid, buf, count); -+ id->uuid[count] = '\0'; -+ break; -+ case UUID_FOURINT: -+ *uuid++ = hexhi(buf[0]); -+ *uuid++ = hexlo(buf[0]); -+ *uuid++ = hexhi(buf[1]); -+ *uuid++ = hexlo(buf[1]); -+ *uuid++ = hexhi(buf[2]); -+ *uuid++ = hexlo(buf[2]); -+ *uuid++ = hexhi(buf[3]); -+ *uuid++ = hexlo(buf[3]); -+ *uuid++ = ':'; -+ *uuid++ = hexhi(buf[4]); -+ *uuid++ = hexlo(buf[4]); -+ *uuid++ = hexhi(buf[5]); -+ *uuid++ = hexlo(buf[5]); -+ *uuid++ = hexhi(buf[6]); -+ *uuid++ = hexlo(buf[6]); -+ *uuid++ = hexhi(buf[7]); -+ *uuid++ = hexlo(buf[7]); -+ *uuid++ = ':'; -+ *uuid++ = hexhi(buf[8]); -+ *uuid++ = hexlo(buf[8]); -+ *uuid++ = hexhi(buf[9]); -+ *uuid++ = hexlo(buf[9]); -+ *uuid++ = hexhi(buf[10]); -+ *uuid++ = hexlo(buf[10]); -+ *uuid++ = hexhi(buf[11]); -+ *uuid++ = hexlo(buf[11]); -+ *uuid++ = ':'; -+ *uuid++ = hexhi(buf[12]); -+ *uuid++ = hexlo(buf[12]); -+ *uuid++ = hexhi(buf[13]); -+ *uuid++ = hexlo(buf[13]); -+ *uuid++ = hexhi(buf[14]); -+ *uuid++ = hexlo(buf[14]); -+ *uuid++ = hexhi(buf[15]); -+ *uuid++ = hexlo(buf[15]); -+ *uuid = '\0'; -+ break; -+ default: -+ *uuid = '\0'; -+ break; -+ } -+} -+ -+uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) -+{ -+ info("get buffer off 0x%llx(%llu), len 0x%zx", (unsigned long long) off, (unsigned long long) off, len); -+ /* check if requested area fits in superblock buffer */ -+ if (off + len <= SB_BUFFER_SIZE) { -+ /* check if we need to read */ -+ if ((off + len) > id->sbbuf_len) { -+ if (devread (0, 0, off + len, (char*)id->sbbuf) == 0) -+ { -+ return NULL; -+ } -+ id->sbbuf_len = off + len; -+ } -+ return &(id->sbbuf[off]); -+ } else { -+ if (len > SEEK_BUFFER_SIZE) { -+ dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); -+ return NULL; -+ } -+ -+ /* check if we need to read */ -+ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { -+ info("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); -+ if (devread(off >> 9, off & 0x1ff, len, (char*)id->seekbuf) == 0) -+ { -+ return NULL; -+ } -+ id->seekbuf_off = off; -+ id->seekbuf_len = len; -+ } -+ return &(id->seekbuf[off - id->seekbuf_off]); -+ } -+} - -=== added file 'libvolume_id/util.h' ---- grub-0.97.orig/libvolume_id/util.h 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/util.h 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,98 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005-2006 Kay Sievers <kay.sievers@vrfy.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _VOLUME_ID_UTIL_ -+#define _VOLUME_ID_UTIL_ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include <endian.h> -+#include <byteswap.h> -+#include <syslog.h> -+ -+#define ALLOWED_CHARS "#+-.:=@_" -+ -+#ifndef PACKED -+#define PACKED __attribute__((packed)) -+#endif -+ -+#define err(format, arg...) volume_id_log_fn(LOG_ERR, __FILE__, __LINE__, format, ##arg) -+#ifdef INFO -+#define info(format, arg...) volume_id_log_fn(LOG_INFO, __FILE__, __LINE__, format, ##arg) -+#else -+#define info(format, arg...) do { } while (0) -+#endif -+ -+#ifdef DEBUG -+#define dbg(format, arg...) volume_id_log_fn(LOG_DEBUG, __FILE__, __LINE__, format, ##arg) -+#else -+#define dbg(format, arg...) do { } while (0) -+#endif -+ -+/* size of superblock buffer, reiserfs block is at 64k */ -+#define SB_BUFFER_SIZE 0x11000 -+/* size of seek buffer, FAT cluster is 32k max */ -+#define SEEK_BUFFER_SIZE 0x10000 -+ -+#ifdef __BYTE_ORDER -+#if (__BYTE_ORDER == __LITTLE_ENDIAN) -+#define le16_to_cpu(x) (x) -+#define le32_to_cpu(x) (x) -+#define le64_to_cpu(x) (x) -+#define be16_to_cpu(x) bswap_16(x) -+#define be32_to_cpu(x) bswap_32(x) -+#define cpu_to_le16(x) (x) -+#define cpu_to_le32(x) (x) -+#define cpu_to_be32(x) bswap_32(x) -+#elif (__BYTE_ORDER == __BIG_ENDIAN) -+#define le16_to_cpu(x) bswap_16(x) -+#define le32_to_cpu(x) bswap_32(x) -+#define le64_to_cpu(x) bswap_64(x) -+#define be16_to_cpu(x) (x) -+#define be32_to_cpu(x) (x) -+#define cpu_to_le16(x) bswap_16(x) -+#define cpu_to_le32(x) bswap_32(x) -+#define cpu_to_be32(x) (x) -+#endif -+#endif /* __BYTE_ORDER */ -+ -+enum uuid_format { -+ UUID_STRING, -+ UUID_HEX_STRING, -+ UUID_DCE, -+ UUID_DOS, -+ UUID_64BIT_LE, -+ UUID_64BIT_BE, -+ UUID_FOURINT, -+}; -+ -+enum endian { -+ LE = 0, -+ BE = 1 -+}; -+ -+extern int volume_id_utf8_encoded_valid_unichar(const char *str); -+extern size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count); -+extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id); -+extern void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count); -+extern void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count); -+extern void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count); -+extern void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format); -+extern uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len); -+extern void volume_id_free_buffer(struct volume_id *id); -+ -+#endif /* _VOLUME_ID_UTIL_ */ -+ - -=== added file 'libvolume_id/via_raid.c' ---- grub-0.97.orig/libvolume_id/via_raid.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/via_raid.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,88 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * Based on information taken from dmraid: -+ * Copyright (C) 2004-2006 Heinz Mauelshagen, Red Hat GmbH -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct via_meta { -+ uint16_t signature; -+ uint8_t version_number; -+ struct via_array { -+ uint16_t disk_bit_mask; -+ uint8_t disk_array_ex; -+ uint32_t capacity_low; -+ uint32_t capacity_high; -+ uint32_t serial_checksum; -+ } PACKED array; -+ uint32_t serial_checksum[8]; -+ uint8_t checksum; -+} PACKED; -+ -+#define VIA_SIGNATURE 0xAA55 -+ -+/* 8 bit checksum on first 50 bytes of metadata. */ -+static uint8_t meta_checksum(struct via_meta *via) -+{ -+ uint8_t i = 50, sum = 0; -+ -+ while (i--) -+ sum += ((uint8_t*) via)[i]; -+ -+ return sum == via->checksum; -+} -+ -+ -+int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ const uint8_t *buf; -+ uint64_t meta_off; -+ struct via_meta *via; -+ -+ dbg("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ if (size < 0x10000) -+ return -1; -+ -+ meta_off = ((size / 0x200)-1) * 0x200; -+ -+ buf = volume_id_get_buffer(id, off + meta_off, 0x200); -+ if (buf == NULL) -+ return -1; -+ -+ via = (struct via_meta *) buf; -+ if (le16_to_cpu(via->signature) != VIA_SIGNATURE) -+ return -1; -+ -+ if (via->version_number > 1) -+ return -1; -+ -+ if (!meta_checksum(via)) -+ return -1; -+ -+ volume_id_set_usage(id, VOLUME_ID_RAID); -+ sprintf(id->type_version, "%u", via->version_number); -+ id->type = "via_raid_member"; -+ -+ return 0; -+} - -=== added file 'libvolume_id/volume_id.c' ---- grub-0.97.orig/libvolume_id/volume_id.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/volume_id.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,222 @@ -+/* -+ * volume_id - reads volume label and uuid -+ * -+ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> -+ * Grub Port, Copyright (C) 2008 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include <fcntl.h> -+#include <sys/stat.h> -+ -+#include "volume_id.h" -+#include "util.h" -+#include "strfuncs.h" -+#include "shared.h" -+ -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -+ -+struct prober { -+ volume_id_probe_fn_t prober; -+ const char *name[4]; -+}; -+ -+#define NOT_SUPPORTED(x) -+#define SUPPORTED(x) x -+ -+static const struct prober prober_raid[] = { -+ { volume_id_probe_ddf_raid, { "ddf_raid", } }, -+ -+ /* { volume_id_probe_linux_raid, { "linux_raid", } }, */ -+ /* { volume_id_probe_intel_software_raid, { "isw_raid", } }, */ -+ /* { volume_id_probe_lsi_mega_raid, { "lsi_mega_raid", } }, */ -+ /* { volume_id_probe_via_raid, { "via_raid", } }, */ -+ /* { volume_id_probe_silicon_medley_raid, { "silicon_medley_raid", } }, */ -+ /* { volume_id_probe_nvidia_raid, { "nvidia_raid", } }, */ -+ /* { volume_id_probe_promise_fasttrack_raid, { "promise_fasttrack_raid", } }, */ -+ /* { volume_id_probe_highpoint_45x_raid, { "highpoint_raid", } }, */ -+ /* { volume_id_probe_adaptec_raid, { "adaptec_raid", } }, */ -+ /* { volume_id_probe_jmicron_raid, { "jmicron_raid", } }, */ -+ /* { volume_id_probe_lvm1, { "lvm1", } }, */ -+ /* { volume_id_probe_lvm2, { "lvm2", } }, */ -+ /* { volume_id_probe_highpoint_37x_raid, { "highpoint_raid", } }, */ -+}; -+ -+static const struct prober prober_filesystem[] = { -+ { volume_id_probe_vfat, { "vfat", } }, -+ { volume_id_probe_luks, { "luks", } }, -+ { volume_id_probe_xfs, { "xfs", } }, -+ { volume_id_probe_ext, { "ext2", "ext3", "jbd", } }, -+ { volume_id_probe_reiserfs, { "reiserfs", "reiser4", } }, -+ { volume_id_probe_jfs, { "jfs", } }, -+ { volume_id_probe_hfs_hfsplus, { "hfs", "hfsplus", } }, -+ { volume_id_probe_ntfs, { "ntfs", } }, -+ { volume_id_probe_ocfs1, { "ocfs1", } }, -+ { volume_id_probe_ocfs2, { "ocfs2", } }, -+ -+ /* { volume_id_probe_linux_swap, { "swap", } }, */ -+ /* { volume_id_probe_udf, { "udf", } }, */ -+ /* { volume_id_probe_iso9660, { "iso9660", } }, */ -+ /* { volume_id_probe_ufs, { "ufs", } }, */ -+ /* { volume_id_probe_cramfs, { "cramfs", } }, */ -+ /* { volume_id_probe_romfs, { "romfs", } }, */ -+ /* { volume_id_probe_hpfs, { "hpfs", } }, */ -+ /* { volume_id_probe_sysv, { "sysv", "xenix", } }, */ -+ /* { volume_id_probe_minix, { "minix", } }, */ -+ /* { volume_id_probe_vxfs, { "vxfs", } }, */ -+ /* { volume_id_probe_squashfs, { "squashfs", } }, */ -+ /* { volume_id_probe_netware, { "netware", } }, */ -+}; -+ -+/* the user can overwrite this log function */ -+static void default_log(int priority, const char *file, int line, const char *format, ...) -+{ -+ return; -+} -+ -+volume_id_log_fn_t volume_id_log_fn = default_log; -+ -+/** -+ * volume_id_get_type: -+ * @id: Probing context -+ * @type: Type string. Must not be freed by the caller. -+ * -+ * Get the type string after a successful probe. -+ * -+ * Returns: 1 if the value was set, 0 otherwise. -+ **/ -+int volume_id_get_type(struct volume_id *id, const char **type) -+{ -+ if (id == NULL) -+ return 0; -+ if (type == NULL) -+ return 0; -+ if (id->usage_id == VOLUME_ID_UNUSED) -+ return 0; -+ -+ *type = id->type; -+ return 1; -+} -+ -+ -+/** -+ * volume_id_get_uuid: -+ * @id: Probing context. -+ * @uuid: UUID string. Must not be freed by the caller. -+ * -+ * Get the raw UUID string after a successful probe. -+ * -+ * Returns: 1 if the value was set, 0 otherwise. -+ **/ -+int volume_id_get_uuid(struct volume_id *id, const char **uuid) -+{ -+ if (id == NULL) -+ return 0; -+ if (uuid == NULL) -+ return 0; -+ if (id->usage_id == VOLUME_ID_UNUSED) -+ return 0; -+ -+ *uuid = id->uuid; -+ return 1; -+} -+ -+/** -+ * volume_id_probe_raid: -+ * @id: Probing context. -+ * @off: Probing offset relative to the start of the device. -+ * @size: Total size of the device. -+ * -+ * Probe device for all known raid signatures. -+ * -+ * Returns: 0 on successful probe, otherwise negative value. -+ **/ -+int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ unsigned int i; -+ -+ if (id == NULL) -+ return -1; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ for (i = 0; i < ARRAY_SIZE(prober_raid); i++) -+ if (prober_raid[i].prober(id, off, size) == 0) -+ goto found; -+ return -1; -+ -+found: -+ return 0; -+} -+ -+/** -+ * volume_id_probe_filesystem: -+ * @id: Probing context. -+ * @off: Probing offset relative to the start of the device. -+ * @size: Total size of the device. -+ * -+ * Probe device for all known filesystem signatures. -+ * -+ * Returns: 0 on successful probe, otherwise negative value. -+ **/ -+int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ unsigned int i; -+ -+ if (id == NULL) -+ return -1; -+ -+ info("probing at offset 0x%llx, size 0x%llx", -+ (unsigned long long) off, (unsigned long long) size); -+ -+ for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) -+ if (prober_filesystem[i].prober(id, off, size) == 0) -+ goto found; -+ return -1; -+ -+found: -+ return 0; -+} -+ -+/** -+ * volume_id_probe_raid: -+ * @all_probers_fn: prober function to called for all known probing routines. -+ * @id: Context passed to prober function. -+ * @off: Offset value passed to prober function. -+ * @size: Size value passed to prober function. -+ * @data: Arbitrary data passed to the prober function. -+ * -+ * Run a custom function for all known probing routines. -+ **/ -+void volume_id_all_probers(all_probers_fn_t all_probers_fn, -+ struct volume_id *id, uint64_t off, uint64_t size, -+ void *data) -+{ -+ unsigned int i; -+ -+ if (all_probers_fn == NULL) -+ return; -+ -+ for (i = 0; i < ARRAY_SIZE(prober_raid); i++) { -+ if (all_probers_fn(prober_raid[i].prober, id, off, size, data) != 0) -+ goto out; -+ } -+ for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) { -+ if (all_probers_fn(prober_filesystem[i].prober, id, off, size, data) != 0) -+ goto out; -+ } -+out: -+ return; -+} - -=== added file 'libvolume_id/volume_id.h' ---- grub-0.97.orig/libvolume_id/volume_id.h 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/volume_id.h 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,137 @@ -+/* -+ * volume_id - reads volume label and uuid -+ * -+ * Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _LIBVOLUME_ID_H_ -+#define _LIBVOLUME_ID_H_ -+ -+#include <stdint.h> -+#include <stddef.h> -+ -+typedef void (*volume_id_log_fn_t)(int priority, const char *file, int line, const char *format, ...) ; -+ -+extern volume_id_log_fn_t volume_id_log_fn; -+ -+struct volume_id; -+typedef int (*volume_id_probe_fn_t)(struct volume_id *id, uint64_t off, uint64_t size); -+typedef int (*all_probers_fn_t)(volume_id_probe_fn_t probe_fn, -+ struct volume_id *id, uint64_t off, uint64_t size, -+ void *data); -+ -+extern struct volume_id *volume_id_open_fd(int fd); -+extern void volume_id_close(struct volume_id *id); -+extern int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); -+extern const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type); -+extern void volume_id_all_probers(all_probers_fn_t all_probers_fn, -+ struct volume_id *id, uint64_t off, uint64_t size, -+ void *data); -+extern int volume_id_get_label(struct volume_id *id, const char **label); -+extern int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len); -+extern int volume_id_get_uuid(struct volume_id *id, const char **uuid); -+extern int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len); -+extern int volume_id_get_usage(struct volume_id *id, const char **usage); -+extern int volume_id_get_type(struct volume_id *id, const char **type); -+extern int volume_id_get_type_version(struct volume_id *id, const char **type_version); -+extern int volume_id_encode_string(const char *str, char *str_enc, size_t len); -+ -+/* -+ * Note: everything below will be made private or removed from -+ * a future version, and a new major release of libvolume_id -+ */ -+ -+extern struct volume_id *volume_id_open_node(const char *path); -+ -+#define VOLUME_ID_LABEL_SIZE 64 -+#define VOLUME_ID_UUID_SIZE 36 -+#define VOLUME_ID_FORMAT_SIZE 32 -+#define VOLUME_ID_PATH_MAX 256 -+#define VOLUME_ID_PARTITIONS_MAX 256 -+ -+enum volume_id_usage { -+ VOLUME_ID_UNUSED, -+ VOLUME_ID_UNPROBED, -+ VOLUME_ID_OTHER, -+ VOLUME_ID_FILESYSTEM, -+ VOLUME_ID_RAID, -+ VOLUME_ID_DISKLABEL, -+ VOLUME_ID_CRYPTO, -+}; -+ -+#include <util.h> -+ -+struct volume_id { -+ uint8_t label_raw[VOLUME_ID_LABEL_SIZE]; -+ size_t label_raw_len; -+ char label[VOLUME_ID_LABEL_SIZE+1]; -+ uint8_t uuid_raw[VOLUME_ID_UUID_SIZE]; -+ size_t uuid_raw_len; -+ char uuid[VOLUME_ID_UUID_SIZE+1]; -+ enum volume_id_usage usage_id; -+ char *usage; -+ char *type; -+ char type_version[VOLUME_ID_FORMAT_SIZE]; -+ -+ int fd; -+ uint8_t sbbuf[SB_BUFFER_SIZE]; -+ size_t sbbuf_len; -+ uint8_t seekbuf[SEEK_BUFFER_SIZE]; -+ uint64_t seekbuf_off; -+ size_t seekbuf_len; -+ int fd_close:1; -+}; -+ -+/* filesystems */ -+extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size); -+ -+/* special formats */ -+extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size); -+ -+/* raid */ -+extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size); -+ -+/* bios raid */ -+extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size); -+extern int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size); -+ -+#endif - -=== added file 'libvolume_id/vxfs.c' ---- grub-0.97.orig/libvolume_id/vxfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/vxfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,49 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+#define VXFS_SUPER_MAGIC 0xa501FCF5 -+ -+struct vxfs_super { -+ uint32_t vs_magic; -+ int32_t vs_version; -+} PACKED; -+ -+int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct vxfs_super *vxs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ vxs = (struct vxfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); -+ if (vxs == NULL) -+ return -1; -+ -+ if (vxs->vs_magic == cpu_to_le32(VXFS_SUPER_MAGIC)) { -+ sprintf(id->type_version, "%u", (unsigned int) vxs->vs_version); -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "vxfs"; -+ return 0; -+ } -+ -+ return -1; -+} - -=== added file 'libvolume_id/xfs.c' ---- grub-0.97.orig/libvolume_id/xfs.c 1970-01-01 00:00:00 +0000 -+++ grub-0.97/libvolume_id/xfs.c 2008-07-15 12:31:43 +0000 -@@ -0,0 +1,59 @@ -+/* -+ * volume_id - reads filesystem label and uuid -+ * -+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation version 2 of the License. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#ifdef HAVE_CONFIG_H -+# include <config.h> -+#endif -+ -+#include "volume_id.h" -+#include "util.h" -+#include "shared.h" -+ -+struct xfs_super_block { -+ uint8_t magic[4]; -+ uint32_t blocksize; -+ uint64_t dblocks; -+ uint64_t rblocks; -+ uint32_t dummy1[2]; -+ uint8_t uuid[16]; -+ uint32_t dummy2[15]; -+ uint8_t fname[12]; -+ uint32_t dummy3[2]; -+ uint64_t icount; -+ uint64_t ifree; -+ uint64_t fdblocks; -+} PACKED; -+ -+int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size) -+{ -+ struct xfs_super_block *xs; -+ -+ info("probing at offset 0x%llx", (unsigned long long) off); -+ -+ xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); -+ if (xs == NULL) -+ return -1; -+ -+ if (memcmp((char *)xs->magic, "XFSB", 4) != 0) -+ return -1; -+ -+ volume_id_set_label_raw(id, xs->fname, 12); -+ volume_id_set_label_string(id, xs->fname, 12); -+ volume_id_set_uuid(id, xs->uuid, 0, UUID_DCE); -+ -+ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -+ id->type = "xfs"; -+ -+ return 0; -+} - -=== modified file 'stage2/Makefile.am' ---- grub-0.97.orig/stage2/Makefile.am 2005-02-02 20:40:05 +0000 -+++ grub-0.97/stage2/Makefile.am 2008-07-09 17:23:44 +0000 -@@ -13,6 +13,10 @@ - # For <stage1.h>. - INCLUDES = -I$(top_srcdir)/stage1 - -+if UUID_SUPPORT -+INCLUDES += -I$(top_srcdir)/libvolume_id -+endif -+ - # The library for /sbin/grub. - noinst_LIBRARIES = libgrub.a - libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ -@@ -61,6 +65,12 @@ - PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 - START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 - -+if UUID_SUPPORT -+UUID_FLAGS = -DSUPPORT_UUID=1 -+else -+UUID_FLAGS = -+endif -+ - if NETBOOT_SUPPORT - NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1 - else -@@ -82,6 +92,8 @@ - STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ - $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) - -+STAGE2_COMPILE += $(UUID_FLAGS) -+ - STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 - STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 - -@@ -97,7 +109,12 @@ - - if NETBOOT_SUPPORT - pre_stage2_exec_LDADD = ../netboot/libdrivers.a --endif -+else -+if UUID_SUPPORT -+pre_stage2_exec_LDADD = ../libvolume_id/libvolume_id.a -+endif -+endif -+ - - if DISKLESS_SUPPORT - BUILT_SOURCES = stage2_size.h diskless_size.h - -=== modified file 'stage2/builtins.c' ---- grub-0.97.orig/stage2/builtins.c 2008-01-28 18:15:31 +0000 -+++ grub-0.97/stage2/builtins.c 2008-07-09 17:23:44 +0000 -@@ -49,6 +49,10 @@ - # include <md5.h> - #endif - -+#ifdef SUPPORT_UUID -+#include <volume_id.h> -+#endif -+ - /* The type of kernel loaded. */ - kernel_t kernel_type; - /* The boot device. */ -@@ -4790,6 +4794,168 @@ - "Probe VBE information. If the mode number MODE is specified, show only" - " the information about only the mode." - }; -+ -+ -+ -+#ifdef SUPPORT_UUID -+ -+struct uuid_callback_data -+{ -+ int found; /* 1 if uuid matches */ -+ char *uuid; /* uuid to look for */ -+}; -+ -+static void uuid_info_print(struct volume_id *id, const char *uuid) -+{ -+ const char *type; -+ int i; -+ -+ volume_id_get_type(id, &type); -+ grub_printf("(hd%d", current_drive - 0x80); -+ if ((current_partition & 0xFF0000) != 0xFF0000) -+ { -+ grub_printf (",%d", (current_partition >> 16) & 0xFF); -+ } -+ if ((current_partition & 0x00FF00) != 0x00FF00) -+ { -+ grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF)); -+ } -+ grub_printf(") %s",type); -+ for (i=0;i<6-strlen(type);i++) -+ { -+ grub_putchar(' '); -+ } -+ grub_printf(" %s\n",uuid); -+} -+ -+static int uuid_all_probers(volume_id_probe_fn_t probe_fn, -+ struct volume_id *id, -+ uint64_t off, -+ uint64_t size, -+ void *data) -+{ -+ struct uuid_callback_data *uc_data = (struct uuid_callback_data*)data; -+ -+ if (probe_fn(id, off, size) == 0) -+ { -+ const char *volume_uuid; -+ if (volume_id_get_uuid(id, &volume_uuid)) -+ { -+ if (!*(uc_data->uuid)) -+ { -+ uuid_info_print(id, volume_uuid); -+ } -+ else -+ { -+ if (strcmp(volume_uuid, uc_data->uuid) == 0) -+ { -+ grub_printf("Boot from "); -+ uuid_info_print(id, volume_uuid); -+ uc_data->found = 1; -+ return 1; -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+/* uuid find */ -+/* Search for the uuid arg in all of partitions. */ -+static int -+uuid_func(char *arg, int flag) -+{ -+ unsigned long drive; -+ unsigned long tmp_drive = saved_drive; -+ unsigned long tmp_partition = saved_partition; -+ struct uuid_callback_data uc_data; -+ -+ uc_data.uuid = arg; -+ uc_data.found = 0; -+ -+ /* Just hard disks and USB drives supported by BIOS */ -+ for (drive = 0x80; drive < 0x88; drive++) -+ { -+ unsigned long part = 0xFFFFFF; -+ unsigned long start, len, offset, ext_offset, gpt_offset; -+ int type, entry, gpt_count, gpt_size; -+ char *buf = (char *) RAW_ADDR(0x100000); -+ struct volume_id *vol_id = (struct volume_id *) RAW_ADDR (0x100000 + SECTOR_SIZE); -+ -+ current_drive = drive; -+ while (next_partition (drive, 0xFFFFFF, &part, &type, -+ &start, &len, &offset, &entry, -+ &ext_offset, &gpt_offset, -+ &gpt_count, &gpt_size, buf)) -+ { -+ if (type != PC_SLICE_TYPE_NONE -+ && ! IS_PC_SLICE_TYPE_BSD (type) -+ && ! IS_PC_SLICE_TYPE_EXTENDED (type)) -+ { -+ current_partition = part; -+ errnum = ERR_NONE; -+ /* Attempt to open device, conventional way */ -+ if (! open_device ()) -+ { -+ errnum = ERR_NONE; -+ /* Failed, like NTFS or FAT filesystems, so try the rootnoverify way */ -+ if (open_partition ()) -+ { -+ set_bootdev (0); -+ if (errnum) -+ { -+ /* Give up */ -+ errnum = ERR_NONE; -+ continue; -+ } -+ } -+ } -+ -+ /* And probe for uuid across all fs types */ -+ saved_drive = current_drive; -+ saved_partition = current_partition; -+ -+ grub_memset(vol_id, 0, sizeof(struct volume_id) ); -+ volume_id_all_probers(uuid_all_probers, vol_id, 0, len, (void*)&uc_data); -+ if (uc_data.found) -+ { -+ /* Success! */ -+ errnum = ERR_NONE; -+ return 0; -+ } -+ } -+ /* We want to ignore any error here. */ -+ errnum = ERR_NONE; -+ } -+ -+ /* next_partition always sets ERRNUM in the last call, so clear it. */ -+ errnum = ERR_NONE; -+ } -+ -+ saved_drive = tmp_drive; -+ saved_partition = tmp_partition; -+ current_drive = GRUB_INVALID_DRIVE; -+ current_partition = 0xFFFFFF; -+ errnum = ERR_FILE_NOT_FOUND; -+ -+ if (!*arg) -+ { -+ errnum = ERR_NONE; -+ return 0; -+ } -+ return 1; -+} -+ -+static struct builtin builtin_uuid = -+{ -+ "uuid", -+ uuid_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "uuid UUID", -+ "Set the current \"root device\" to the device with the uuid UUID," -+ " then attempt to mount it" -+}; -+#endif - - - /* The table of builtin commands. Sorted in dictionary order. */ -@@ -4879,6 +5045,9 @@ - &builtin_title, - &builtin_unhide, - &builtin_uppermem, -+#ifdef SUPPORT_UUID -+ &builtin_uuid, -+#endif - &builtin_vbeprobe, - 0 - }; - |