From 83cc6ab4760817509f1ed1ee429669e563f82caf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 27 Mar 2006 18:05:17 +0200 Subject: volume_id: rename subdirectory --- extras/volume_id/Makefile | 14 +- extras/volume_id/lib/Makefile | 124 ++++++++++ extras/volume_id/lib/cramfs.c | 64 +++++ extras/volume_id/lib/ext.c | 115 +++++++++ extras/volume_id/lib/fat.c | 349 +++++++++++++++++++++++++++ extras/volume_id/lib/hfs.c | 297 +++++++++++++++++++++++ extras/volume_id/lib/highpoint.c | 96 ++++++++ extras/volume_id/lib/hpfs.c | 56 +++++ extras/volume_id/lib/iso9660.c | 124 ++++++++++ extras/volume_id/lib/isw_raid.c | 66 +++++ extras/volume_id/lib/jfs.c | 65 +++++ extras/volume_id/lib/libvolume_id.h | 111 +++++++++ extras/volume_id/lib/linux_raid.c | 87 +++++++ extras/volume_id/lib/linux_swap.c | 76 ++++++ extras/volume_id/lib/lsi_raid.c | 60 +++++ extras/volume_id/lib/luks.c | 82 +++++++ extras/volume_id/lib/lvm.c | 97 ++++++++ extras/volume_id/lib/minix.c | 84 +++++++ extras/volume_id/lib/ntfs.c | 194 +++++++++++++++ extras/volume_id/lib/nvidia_raid.c | 64 +++++ extras/volume_id/lib/ocfs.c | 192 +++++++++++++++ extras/volume_id/lib/promise_raid.c | 70 ++++++ extras/volume_id/lib/reiserfs.c | 118 +++++++++ extras/volume_id/lib/romfs.c | 60 +++++ extras/volume_id/lib/silicon_raid.c | 77 ++++++ extras/volume_id/lib/squashfs.c | 52 ++++ extras/volume_id/lib/sysv.c | 133 ++++++++++ extras/volume_id/lib/udf.c | 178 ++++++++++++++ extras/volume_id/lib/ufs.c | 210 ++++++++++++++++ extras/volume_id/lib/util.c | 267 ++++++++++++++++++++ extras/volume_id/lib/util.h | 84 +++++++ extras/volume_id/lib/via_raid.c | 75 ++++++ extras/volume_id/lib/volume_id.c | 231 ++++++++++++++++++ extras/volume_id/lib/vxfs.c | 54 +++++ extras/volume_id/lib/xfs.c | 65 +++++ extras/volume_id/libvolume_id/Makefile | 124 ---------- extras/volume_id/libvolume_id/cramfs.c | 64 ----- extras/volume_id/libvolume_id/ext.c | 115 --------- extras/volume_id/libvolume_id/fat.c | 349 --------------------------- extras/volume_id/libvolume_id/hfs.c | 297 ----------------------- extras/volume_id/libvolume_id/highpoint.c | 96 -------- extras/volume_id/libvolume_id/hpfs.c | 56 ----- extras/volume_id/libvolume_id/iso9660.c | 124 ---------- extras/volume_id/libvolume_id/isw_raid.c | 66 ----- extras/volume_id/libvolume_id/jfs.c | 65 ----- extras/volume_id/libvolume_id/libvolume_id.h | 111 --------- extras/volume_id/libvolume_id/linux_raid.c | 87 ------- extras/volume_id/libvolume_id/linux_swap.c | 76 ------ extras/volume_id/libvolume_id/lsi_raid.c | 60 ----- extras/volume_id/libvolume_id/luks.c | 82 ------- extras/volume_id/libvolume_id/lvm.c | 97 -------- extras/volume_id/libvolume_id/minix.c | 84 ------- extras/volume_id/libvolume_id/ntfs.c | 194 --------------- extras/volume_id/libvolume_id/nvidia_raid.c | 64 ----- extras/volume_id/libvolume_id/ocfs.c | 192 --------------- extras/volume_id/libvolume_id/promise_raid.c | 70 ------ extras/volume_id/libvolume_id/reiserfs.c | 118 --------- extras/volume_id/libvolume_id/romfs.c | 60 ----- extras/volume_id/libvolume_id/silicon_raid.c | 77 ------ extras/volume_id/libvolume_id/squashfs.c | 52 ---- extras/volume_id/libvolume_id/sysv.c | 133 ---------- extras/volume_id/libvolume_id/udf.c | 178 -------------- extras/volume_id/libvolume_id/ufs.c | 210 ---------------- extras/volume_id/libvolume_id/util.c | 267 -------------------- extras/volume_id/libvolume_id/util.h | 84 ------- extras/volume_id/libvolume_id/via_raid.c | 75 ------ extras/volume_id/libvolume_id/volume_id.c | 231 ------------------ extras/volume_id/libvolume_id/vxfs.c | 54 ----- extras/volume_id/libvolume_id/xfs.c | 65 ----- extras/volume_id/vol_id.c | 2 +- 70 files changed, 4085 insertions(+), 4085 deletions(-) create mode 100644 extras/volume_id/lib/Makefile create mode 100644 extras/volume_id/lib/cramfs.c create mode 100644 extras/volume_id/lib/ext.c create mode 100644 extras/volume_id/lib/fat.c create mode 100644 extras/volume_id/lib/hfs.c create mode 100644 extras/volume_id/lib/highpoint.c create mode 100644 extras/volume_id/lib/hpfs.c create mode 100644 extras/volume_id/lib/iso9660.c create mode 100644 extras/volume_id/lib/isw_raid.c create mode 100644 extras/volume_id/lib/jfs.c create mode 100644 extras/volume_id/lib/libvolume_id.h create mode 100644 extras/volume_id/lib/linux_raid.c create mode 100644 extras/volume_id/lib/linux_swap.c create mode 100644 extras/volume_id/lib/lsi_raid.c create mode 100644 extras/volume_id/lib/luks.c create mode 100644 extras/volume_id/lib/lvm.c create mode 100644 extras/volume_id/lib/minix.c create mode 100644 extras/volume_id/lib/ntfs.c create mode 100644 extras/volume_id/lib/nvidia_raid.c create mode 100644 extras/volume_id/lib/ocfs.c create mode 100644 extras/volume_id/lib/promise_raid.c create mode 100644 extras/volume_id/lib/reiserfs.c create mode 100644 extras/volume_id/lib/romfs.c create mode 100644 extras/volume_id/lib/silicon_raid.c create mode 100644 extras/volume_id/lib/squashfs.c create mode 100644 extras/volume_id/lib/sysv.c create mode 100644 extras/volume_id/lib/udf.c create mode 100644 extras/volume_id/lib/ufs.c create mode 100644 extras/volume_id/lib/util.c create mode 100644 extras/volume_id/lib/util.h create mode 100644 extras/volume_id/lib/via_raid.c create mode 100644 extras/volume_id/lib/volume_id.c create mode 100644 extras/volume_id/lib/vxfs.c create mode 100644 extras/volume_id/lib/xfs.c delete mode 100644 extras/volume_id/libvolume_id/Makefile delete mode 100644 extras/volume_id/libvolume_id/cramfs.c delete mode 100644 extras/volume_id/libvolume_id/ext.c delete mode 100644 extras/volume_id/libvolume_id/fat.c delete mode 100644 extras/volume_id/libvolume_id/hfs.c delete mode 100644 extras/volume_id/libvolume_id/highpoint.c delete mode 100644 extras/volume_id/libvolume_id/hpfs.c delete mode 100644 extras/volume_id/libvolume_id/iso9660.c delete mode 100644 extras/volume_id/libvolume_id/isw_raid.c delete mode 100644 extras/volume_id/libvolume_id/jfs.c delete mode 100644 extras/volume_id/libvolume_id/libvolume_id.h delete mode 100644 extras/volume_id/libvolume_id/linux_raid.c delete mode 100644 extras/volume_id/libvolume_id/linux_swap.c delete mode 100644 extras/volume_id/libvolume_id/lsi_raid.c delete mode 100644 extras/volume_id/libvolume_id/luks.c delete mode 100644 extras/volume_id/libvolume_id/lvm.c delete mode 100644 extras/volume_id/libvolume_id/minix.c delete mode 100644 extras/volume_id/libvolume_id/ntfs.c delete mode 100644 extras/volume_id/libvolume_id/nvidia_raid.c delete mode 100644 extras/volume_id/libvolume_id/ocfs.c delete mode 100644 extras/volume_id/libvolume_id/promise_raid.c delete mode 100644 extras/volume_id/libvolume_id/reiserfs.c delete mode 100644 extras/volume_id/libvolume_id/romfs.c delete mode 100644 extras/volume_id/libvolume_id/silicon_raid.c delete mode 100644 extras/volume_id/libvolume_id/squashfs.c delete mode 100644 extras/volume_id/libvolume_id/sysv.c delete mode 100644 extras/volume_id/libvolume_id/udf.c delete mode 100644 extras/volume_id/libvolume_id/ufs.c delete mode 100644 extras/volume_id/libvolume_id/util.c delete mode 100644 extras/volume_id/libvolume_id/util.h delete mode 100644 extras/volume_id/libvolume_id/via_raid.c delete mode 100644 extras/volume_id/libvolume_id/volume_id.c delete mode 100644 extras/volume_id/libvolume_id/vxfs.c delete mode 100644 extras/volume_id/libvolume_id/xfs.c diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 88752b880e..78dfd867bc 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -31,12 +31,12 @@ all: $(PROG) $(MAN_PAGES) $(E) " CC " $@ $(Q) $(CC) -c $(CFLAGS) $< -o $@ -libvolume_id/libvolume_id.a: - $(Q) $(MAKE) -C libvolume_id +lib/libvolume_id.a: + $(Q) $(MAKE) -C lib -$(PROG): %: $(HEADERS) %.o libvolume_id/libvolume_id.a +$(PROG): %: $(HEADERS) %.o lib/libvolume_id.a $(E) " LD " $@ - $(Q) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) libvolume_id/libvolume_id.a $(LIB_OBJS) + $(Q) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) lib/libvolume_id.a $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(E) " STRIP " $@ $(Q) $(STRIPCMD) $@ @@ -51,17 +51,17 @@ endif clean: $(E) " CLEAN " $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) - $(Q) $(MAKE) -C libvolume_id clean + $(Q) $(MAKE) -C lib clean .PHONY: clean install-bin: all $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(sbindir)/$(PROG) - $(MAKE) -C libvolume_id install + $(MAKE) -C lib install .PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) - $(MAKE) -C libvolume_id uninstall + $(MAKE) -C lib uninstall .PHONY: uninstall-bin install-man: diff --git a/extras/volume_id/lib/Makefile b/extras/volume_id/lib/Makefile new file mode 100644 index 0000000000..6a12f0e67a --- /dev/null +++ b/extras/volume_id/lib/Makefile @@ -0,0 +1,124 @@ +# libvolume_id - read filesystem label/uuid +# +# Copyright (C) 2004-2006 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# +includedir = ${prefix}/usr/include +libdir = ${prefix}/lib +usrlibdir = ${prefix}/usr/lib + +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_LIB = ${INSTALL} -m 755 + +SHLIB_CUR = 0 +SHLIB_REV = 61 +SHLIB_AGE = 0 +SHLIB = libvolume_id.so.$(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE) + +OBJS= \ + ext.o \ + fat.o \ + hfs.o \ + highpoint.o \ + isw_raid.o \ + lsi_raid.o \ + via_raid.o \ + silicon_raid.o \ + nvidia_raid.o \ + promise_raid.o \ + iso9660.o \ + jfs.o \ + linux_raid.o \ + linux_swap.o \ + lvm.o \ + ntfs.o \ + reiserfs.o \ + udf.o \ + ufs.o \ + xfs.o \ + cramfs.o \ + hpfs.o \ + romfs.o \ + sysv.o \ + minix.o \ + luks.o \ + ocfs.o \ + vxfs.o \ + squashfs.o \ + volume_id.o \ + util.o + +HEADERS= \ + libvolume_id.h \ + util.h + +AR = $(CROSS)ar +RANLIB = $(CROSS)ranlib + +all: libvolume_id.a $(SHLIB) libvolume_id.pc +.PHONY: all +.DEFAULT: all + +%.o: %.c + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ + +.shlib: + $(Q) mkdir .shlib + +.shlib/%.o: %.c + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) -fPIC $< -o $@ + +libvolume_id.a: $(HEADERS) $(OBJS) + $(Q) rm -f $@ + $(E) " AR " $@ + $(Q) $(AR) cq $@ $(OBJS) + $(E) " RANLIB " $@ + $(Q) $(RANLIB) $@ + +$(SHLIB): $(HEADERS) .shlib $(addprefix .shlib/,$(OBJS)) + $(E) " CC " $@ + $(Q) $(CC) -shared $(CFLAGS) -o $@ -Wl,-soname,libvolume_id.so.$(SHLIB_CUR) $(addprefix .shlib/,$(OBJS)) + $(Q) ln -sf $@ libvolume_id.so.$(SHLIB_CUR) + $(Q) ln -sf $@ libvolume_id.so + +libvolume_id.pc: + $(E) " GENPC " $@ + $(Q) echo "prefix=${prefix}" > $@ + $(Q) echo "libdir=${libdir}" >> $@ + $(Q) echo "includedir=${includedir}" >> $@ + $(Q) echo "" >> $@ + $(Q) echo "Name: libvolume_id" >> $@ + $(Q) echo "Description: Filesystem label and uuid access" >> $@ + $(Q) echo "Version: $(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE)" >> $@ + $(Q) echo "Libs: -L\$${libdir} -lvolume_id" >> $@ + $(Q) echo "Cflags: -I\$${includedir}" >> $@ + +install: all + $(INSTALL_DATA) -D libvolume_id.h $(DESTDIR)$(includedir)/libvolume_id.h + $(INSTALL_LIB) -D libvolume_id.a $(DESTDIR)$(usrlibdir)/libvolume_id.a + $(INSTALL_LIB) -D $(SHLIB) $(DESTDIR)$(libdir)/$(SHLIB) + ln -sf $(DESTDIR)$(libdir)/$(SHLIB) $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) + ln -sf $(DESTDIR)$(libdir)/$(SHLIB) $(DESTDIR)$(usrlibdir)/libvolume_id.so + $(INSTALL_DATA) -D libvolume_id.pc $(DESTDIR)$(usrlibdir)/pkgconfig/libvolume_id.pc +.PHONY: install + +uninstall: + rm -f $(DESTDIR)$(includedir)/libvolume_id.h + rm -f $(DESTDIR)$(usrlibdir)/libvolume_id.a + rm -f $(DESTDIR)$(libdir)/$(SHLIB) + rm -f $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) + rm -f $(DESTDIR)$(libdir)/libvolume_id.so +.PHONY: uninstall + +clean: + $(E) " CLEAN " + $(Q) rm -f libvolume_id.a $(OBJS) + $(Q) rm -f $(SHLIB) libvolume_id.so.$(SHLIB_CUR) libvolume_id.so + $(Q) rm -rf .shlib + $(Q) rm -f libvolume_id.pc +.PHONY: clean + diff --git a/extras/volume_id/lib/cramfs.c b/extras/volume_id/lib/cramfs.c new file mode 100644 index 0000000000..beb34d5bc0 --- /dev/null +++ b/extras/volume_id/lib/cramfs.c @@ -0,0 +1,64 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct cramfs_super *cs; + + dbg("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(cs->magic, "\x45\x3d\xcd\x28", 4) == 0 || memcmp(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; +} diff --git a/extras/volume_id/lib/ext.c b/extras/volume_id/lib/ext.c new file mode 100644 index 0000000000..51c0011218 --- /dev/null +++ b/extras/volume_id/lib/ext.c @@ -0,0 +1,115 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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 0x00000004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 +#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) +{ + struct ext2_super_block *es; + size_t bsize; + + dbg("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, UUID_DCE); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", es->s_rev_level, es->s_minor_rev_level); + + /* check for external journal device */ + if ((le32_to_cpu(es->s_feature_incompat) & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { + volume_id_set_usage(id, VOLUME_ID_OTHER); + id->type = "jbd"; + return 0; + } + + /* check for ext2 / ext3 */ + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) + id->type = "ext3"; + else + id->type = "ext2"; + + return 0; +} diff --git a/extras/volume_id/lib/fat.c b/extras/volume_id/lib/fat.c new file mode 100644 index 0000000000..4840a2a23c --- /dev/null +++ b/extras/volume_id/lib/fat.c @@ -0,0 +1,349 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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 + +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 insfo_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 vfat_dir_entry { + uint8_t name[11]; + uint8_t attr; + uint16_t time_creat; + uint16_t date_creat; + uint16_t time_acc; + uint16_t date_acc; + uint16_t cluster_high; + uint16_t time_write; + uint16_t date_write; + uint16_t cluster_low; + uint32_t size; +} PACKED; + +static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + /* end marker */ + if (dir[i].name[0] == 0x00) { + dbg("end of dir"); + break; + } + + /* empty entry */ + if (dir[i].name[0] == FAT_ENTRY_FREE) + continue; + + /* long name */ + if ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME) + continue; + + if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { + /* labels do not have file data */ + if (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) + continue; + + dbg("found ATTR_VOLUME_ID id in root dir"); + return dir[i].name; + } + + dbg("skip dir entry"); + } + + return NULL; +} + +int volume_id_probe_vfat(struct volume_id *id, uint64_t off) +{ + struct vfat_super_block *vs; + struct vfat_dir_entry *dir; + 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; + uint8_t *buf; + uint32_t buf_size; + uint8_t *label = NULL; + uint32_t next; + int maxloop; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + /* believe only that's fat, don't trust the version + * the cluster_count will tell us + */ + if (memcmp(vs->sysid, "NTFS", 4) == 0) + return -1; + + if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0) + goto magic; + + if (memcmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "FAT16 ", 8) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0) + goto magic; + + if (memcmp(vs->type.fat.magic, "FAT12 ", 8) == 0) + goto magic; + + /* some old floppies don't have a magic, so we expect the boot code to match */ + + /* boot jump address check */ + 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 != 0x200 && sector_size != 0x400 && + sector_size != 0x800 && sector_size != 0x1000) + 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; + + dir = (struct vfat_dir_entry*) buf; + + label = get_attr_volume_id(dir, root_dir_entries); + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + if (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, label, 11); + volume_id_set_label_string(id, label, 11); + } else if (memcmp(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, UUID_DOS); + goto found; + +fat32: + 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; + + dir = (struct vfat_dir_entry*) buf; + count = buf_size / sizeof(struct vfat_dir_entry); + dbg("expected entries 0x%x", count); + + label = get_attr_volume_id(dir, count); + if (label) + 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 == 0) + 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 (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, label, 11); + volume_id_set_label_string(id, label, 11); + } else if (memcmp(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, UUID_DOS); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "vfat"; + + return 0; +} diff --git a/extras/volume_id/lib/hfs.c b/extras/volume_id/lib/hfs.c new file mode 100644 index 0000000000..a6e378dd28 --- /dev/null +++ b/extras/volume_id/lib/hfs.c @@ -0,0 +1,297 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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; + +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; + +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 + +int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off) +{ + 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; + + dbg("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(hfs->signature, "BD", 2) != 0) + goto checkplus; + + /* it may be just a hfs wrapper for hfs+ */ + if (memcmp(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) ; + } + + volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hfs"; + + return 0; + +checkplus: + hfsplus = (struct hfsplus_vol_header *) buf; + if (memcmp(hfsplus->signature, "H+", 2) == 0) + goto hfsplus; + if (memcmp(hfsplus->signature, "HX", 2) == 0) + goto hfsplus; + return -1; + +hfsplus: + volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS); + + 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; +} diff --git a/extras/volume_id/lib/highpoint.c b/extras/volume_id/lib/highpoint.c new file mode 100644 index 0000000000..deba540ad5 --- /dev/null +++ b/extras/volume_id/lib/highpoint.c @@ -0,0 +1,96 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + const uint8_t *buf; + struct hpt37x_meta *hpt; + uint32_t magic; + + dbg("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; +} diff --git a/extras/volume_id/lib/hpfs.c b/extras/volume_id/lib/hpfs.c new file mode 100644 index 0000000000..3e9589fcca --- /dev/null +++ b/extras/volume_id/lib/hpfs.c @@ -0,0 +1,56 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct hpfs_super *hs; + + dbg("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(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; +} diff --git a/extras/volume_id/lib/iso9660.c b/extras/volume_id/lib/iso9660.c new file mode 100644 index 0000000000..7b78a7e992 --- /dev/null +++ b/extras/volume_id/lib/iso9660.c @@ -0,0 +1,124 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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 vd_type; + uint8_t vd_id[5]; + uint8_t vd_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[4]; + uint8_t version; +} PACKED; + +int volume_id_probe_iso9660(struct volume_id *id, uint64_t off) +{ + uint8_t *buf; + struct iso_volume_descriptor *is; + struct high_sierra_volume_descriptor *hs; + + dbg("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(is->vd_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->vd_type == ISO_VD_END) + break; + if (is->vd_type != ISO_VD_SUPPLEMENTARY) + continue; + + dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset)); + if (memcmp(is->escape_sequences, "%/@", 3) == 0|| + memcmp(is->escape_sequences, "%/C", 3) == 0|| + memcmp(is->escape_sequences, "%/E", 3) == 0) { + dbg("Joliet extension found"); + volume_id_set_unicode16((char *)svd_label, sizeof(svd_label), is->volume_id, BE, 32); + if (memcmp(id->label, 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(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; +} diff --git a/extras/volume_id/lib/isw_raid.c b/extras/volume_id/lib/isw_raid.c new file mode 100644 index 0000000000..6465a31bf5 --- /dev/null +++ b/extras/volume_id/lib/isw_raid.c @@ -0,0 +1,66 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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; + + 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)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + isw = (struct isw_meta *) buf; + if (memcmp(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; +} diff --git a/extras/volume_id/lib/jfs.c b/extras/volume_id/lib/jfs.c new file mode 100644 index 0000000000..b230fb258c --- /dev/null +++ b/extras/volume_id/lib/jfs.c @@ -0,0 +1,65 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct jfs_super_block *js; + + dbg("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(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, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "jfs"; + + return 0; +} diff --git a/extras/volume_id/lib/libvolume_id.h b/extras/volume_id/lib/libvolume_id.h new file mode 100644 index 0000000000..7faf8d8af3 --- /dev/null +++ b/extras/volume_id/lib/libvolume_id.h @@ -0,0 +1,111 @@ +/* + * volume_id - reads volume label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#include + +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif + + +typedef void (*volume_id_log_fn)(int priority, const char *file, int line, const char *format, ...) + __attribute__ ((format(printf, 4, 5))); + +extern volume_id_log_fn volume_id_log; + +#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, +}; + +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; + size_t sbbuf_len; + uint8_t *seekbuf; + uint64_t seekbuf_off; + size_t seekbuf_len; + int fd_close:1; +}; + +extern struct volume_id *volume_id_open_fd(int fd); +extern struct volume_id *volume_id_open_node(const char *path); +extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); +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 void volume_id_close(struct volume_id *id); + +/* filesystems */ +extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ext(struct volume_id *id, uint64_t off); +extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off); +extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off); +extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off); +extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_minix(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); +extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off); +extern int volume_id_probe_udf(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off); + +/* special formats */ +extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off); +extern int volume_id_probe_luks(struct volume_id *id, uint64_t off); + +/* 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); +extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off); + +/* 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); +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); + +#endif diff --git a/extras/volume_id/lib/linux_raid.c b/extras/volume_id/lib/linux_raid.c new file mode 100644 index 0000000000..85e8d8109b --- /dev/null +++ b/extras/volume_id/lib/linux_raid.c @@ -0,0 +1,87 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct mdp_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 *mdp; + +#define MD_RESERVED_BYTES 0x10000 +#define MD_MAGIC 0xa92b4efc + +int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + const uint8_t *buf; + uint64_t sboff; + uint8_t uuid[16]; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; + buf = volume_id_get_buffer(id, off + sboff, 0x800); + if (buf == NULL) + return -1; + + mdp = (struct mdp_super_block *) buf; + + if (le32_to_cpu(mdp->md_magic) != MD_MAGIC) + return -1; + + memcpy(uuid, &mdp->set_uuid0, 4); + memcpy(&uuid[4], &mdp->set_uuid1, 12); + volume_id_set_uuid(id, uuid, UUID_DCE); + + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", + le32_to_cpu(mdp->major_version), + le32_to_cpu(mdp->minor_version), + le32_to_cpu(mdp->patch_version)); + + dbg("found raid signature"); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "linux_raid_member"; + + return 0; +} diff --git a/extras/volume_id/lib/linux_swap.c b/extras/volume_id/lib/linux_swap.c new file mode 100644 index 0000000000..0193648c9e --- /dev/null +++ b/extras/volume_id/lib/linux_swap.c @@ -0,0 +1,76 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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 *sw; + +#define LARGEST_PAGESIZE 0x4000 + +int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off) +{ + const uint8_t *buf; + unsigned int page; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + /* 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(buf, "SWAP-SPACE", 10) == 0) { + strcpy(id->type_version, "1"); + goto found; + } + + if (memcmp(buf, "SWAPSPACE2", 10) == 0) { + sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); + if (sw == NULL) + return -1; + strcpy(id->type_version, "2"); + 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, UUID_DCE); + goto found; + } + } + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_OTHER); + id->type = "swap"; + + return 0; +} diff --git a/extras/volume_id/lib/lsi_raid.c b/extras/volume_id/lib/lsi_raid.c new file mode 100644 index 0000000000..f1db4a6e50 --- /dev/null +++ b/extras/volume_id/lib/lsi_raid.c @@ -0,0 +1,60 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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; + + 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; + + lsi = (struct lsi_meta *) buf; + if (memcmp(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; +} diff --git a/extras/volume_id/lib/luks.c b/extras/volume_id/lib/luks.c new file mode 100644 index 0000000000..64de85ac21 --- /dev/null +++ b/extras/volume_id/lib/luks.c @@ -0,0 +1,82 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 W. Michael Petullo + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << 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 + +const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; +#define LUKS_MAGIC_L 6 +#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) +#define UUID_STRING_L 40 + +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) +{ + struct luks_phdr *header; + + header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); + if (header == NULL) + return -1; + + if (memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) + return -1; + + volume_id_set_usage(id, VOLUME_ID_CRYPTO); + volume_id_set_uuid(id, header->uuid, UUID_DCE_STRING); + + id->type = "crypto_LUKS"; + + return 0; +} diff --git a/extras/volume_id/lib/lvm.c b/extras/volume_id/lib/lvm.c new file mode 100644 index 0000000000..47d84b0968 --- /dev/null +++ b/extras/volume_id/lib/lvm.c @@ -0,0 +1,97 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + const uint8_t *buf; + struct lvm1_super_block *lvm; + + dbg("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(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) +{ + 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(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; +} diff --git a/extras/volume_id/lib/minix.c b/extras/volume_id/lib/minix.c new file mode 100644 index 0000000000..75e9c3acbd --- /dev/null +++ b/extras/volume_id/lib/minix.c @@ -0,0 +1,84 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +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; + +#define MINIX_SUPERBLOCK_OFFSET 0x400 + +int volume_id_probe_minix(struct volume_id *id, uint64_t off) +{ + struct minix_super_block *ms; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + ms = (struct minix_super_block *) volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); + if (ms == NULL) + return -1; + + if (le16_to_cpu(ms->s_magic) == 0x137f) { + strcpy(id->type_version, "1"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x1387) { + strcpy(id->type_version, "1"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x2468) { + strcpy(id->type_version, "2"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x2478) { + strcpy(id->type_version, "2"); + goto found; + } + + goto exit; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "minix"; + return 0; + +exit: + return -1; +} diff --git a/extras/volume_id/lib/ntfs.c b/extras/volume_id/lib/ntfs.c new file mode 100644 index 0000000000..23c64fc307 --- /dev/null +++ b/extras/volume_id/lib/ntfs.c @@ -0,0 +1,194 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +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; + +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; + +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; + +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 + +int volume_id_probe_ntfs(struct volume_id *id, uint64_t off) +{ + 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; + + dbg("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(ns->oem_id, "NTFS", 4) != 0) + return -1; + + volume_id_set_uuid(id, ns->volume_serial, UUID_NTFS); + + sector_size = le16_to_cpu(ns->bytes_per_sector); + 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) + goto found; + + 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(mftr->magic, "FILE", 4) != 0) + goto found; + + 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); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%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); + } + } + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "ntfs"; + + return 0; +} diff --git a/extras/volume_id/lib/nvidia_raid.c b/extras/volume_id/lib/nvidia_raid.c new file mode 100644 index 0000000000..10c1c714f7 --- /dev/null +++ b/extras/volume_id/lib/nvidia_raid.c @@ -0,0 +1,64 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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; + + 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)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + nv = (struct nvidia_meta *) buf; + if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", le16_to_cpu(nv->version)); + id->type = "nvidia_raid_member"; + + return 0; +} diff --git a/extras/volume_id/lib/ocfs.c b/extras/volume_id/lib/ocfs.c new file mode 100644 index 0000000000..b376ead833 --- /dev/null +++ b/extras/volume_id/lib/ocfs.c @@ -0,0 +1,192 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Andre Masella + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + const uint8_t *buf; + struct ocfs1_super_block_header *osh; + struct ocfs1_super_block_label *osl; + + buf = volume_id_get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + osh = (struct ocfs1_super_block_header *) buf; + if (memcmp(osh->signature, "OracleCFS", 9) != 0) + return -1; + snprintf(id->type_version, sizeof(id->type_version)-1, + "%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, 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) +{ + const uint8_t *buf; + struct ocfs2_super_block *os; + size_t blksize; + + dbg("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(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, UUID_DCE); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", os->s_major_rev_level, os->s_minor_rev_level); + id->type = "ocfs2"; + return 0; + } + return -1; +} diff --git a/extras/volume_id/lib/promise_raid.c b/extras/volume_id/lib/promise_raid.c new file mode 100644 index 0000000000..2a2ce1689e --- /dev/null +++ b/extras/volume_id/lib/promise_raid.c @@ -0,0 +1,70 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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 + }; + + dbg("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(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; +} diff --git a/extras/volume_id/lib/reiserfs.c b/extras/volume_id/lib/reiserfs.c new file mode 100644 index 0000000000..b5706f86e0 --- /dev/null +++ b/extras/volume_id/lib/reiserfs.c @@ -0,0 +1,118 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2005 Tobias Klauser + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct reiserfs_super_block *rs; + struct reiser4_super_block *rs4; + uint8_t *buf; + + dbg("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(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); + id->type = "reiserfs"; + goto found; + } + if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { + strcpy(id->type_version, "3.6"); + id->type = "reiserfs"; + goto found_label; + } + if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { + strcpy(id->type_version, "JR"); + id->type = "reiserfs"; + goto found_label; + } + + rs4 = (struct reiser4_super_block *) buf; + if (memcmp(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, 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(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, UUID_DCE); + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + + return 0; +} diff --git a/extras/volume_id/lib/romfs.c b/extras/volume_id/lib/romfs.c new file mode 100644 index 0000000000..8bb2a0018a --- /dev/null +++ b/extras/volume_id/lib/romfs.c @@ -0,0 +1,60 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct romfs_super *rfs; + + dbg("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(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; +} diff --git a/extras/volume_id/lib/silicon_raid.c b/extras/volume_id/lib/silicon_raid.c new file mode 100644 index 0000000000..017b023e27 --- /dev/null +++ b/extras/volume_id/lib/silicon_raid.c @@ -0,0 +1,77 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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; + + 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; + + sil = (struct silicon_meta *) buf; + if (le32_to_cpu(sil->magic) != SILICON_MAGIC) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", + le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); + id->type = "silicon_medley_raid_member"; + + return 0; +} diff --git a/extras/volume_id/lib/squashfs.c b/extras/volume_id/lib/squashfs.c new file mode 100644 index 0000000000..bdb1f16628 --- /dev/null +++ b/extras/volume_id/lib/squashfs.c @@ -0,0 +1,52 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2006 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +#define SQUASHFS_MAGIC 0x73717368 + +struct squashfs_super { + uint32_t s_magic; +} PACKED; + +int volume_id_probe_squashfs(struct volume_id *id, uint64_t off) +{ + struct squashfs_super *sqs; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + sqs = (struct squashfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); + if (sqs == NULL) + return -1; + + if (sqs->s_magic == SQUASHFS_MAGIC || sqs->s_magic == bswap_32(SQUASHFS_MAGIC)) { + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "squashfs"; + return 0; + } + + return -1; +} diff --git a/extras/volume_id/lib/sysv.c b/extras/volume_id/lib/sysv.c new file mode 100644 index 0000000000..52349c0623 --- /dev/null +++ b/extras/volume_id/lib/sysv.c @@ -0,0 +1,133 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct sysv_super *vs; + struct xenix_super *xs; + unsigned int boff; + + dbg("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; +} diff --git a/extras/volume_id/lib/udf.c b/extras/volume_id/lib/udf.c new file mode 100644 index 0000000000..d7497ec51b --- /dev/null +++ b/extras/volume_id/lib/udf.c @@ -0,0 +1,178 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + 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; + + dbg("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(vsd->id, "NSR02", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "NSR03", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "BEA01", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "BOOT2", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "CD001", 5) == 0) + goto blocksize; + if (memcmp(vsd->id, "CDW02", 5) == 0) + goto blocksize; + if (memcmp(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(vsd->id, "NSR02", 5) == 0) + goto anchor; + if (memcmp(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; +} diff --git a/extras/volume_id/lib/ufs.c b/extras/volume_id/lib/ufs.c new file mode 100644 index 0000000000..d3960b1bec --- /dev/null +++ b/extras/volume_id/lib/ufs.c @@ -0,0 +1,210 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + uint32_t magic; + int i; + struct ufs_super_block *ufs; + int offsets[] = {0, 8, 64, 256, -1}; + + dbg("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"; + + return 0; +} diff --git a/extras/volume_id/lib/util.c b/extras/volume_id/lib/util.c new file mode 100644 index 0000000000..cf5392cf9a --- /dev/null +++ b/extras/volume_id/lib/util.c @@ -0,0 +1,267 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +void volume_id_set_unicode16(char *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) +{ + unsigned int 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'; +} + +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) +{ + 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) +{ + unsigned int i; + + memcpy(id->label, buf, count); + + /* 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) +{ + volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); +} + +void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format) +{ + unsigned int i; + unsigned int count = 0; + + switch(format) { + case UUID_DOS: + count = 4; + break; + case UUID_NTFS: + case UUID_HFS: + count = 8; + break; + case UUID_DCE: + count = 16; + break; + case UUID_DCE_STRING: + count = 36; + 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: + switch(format) { + case UUID_DOS: + sprintf(id->uuid, "%02X%02X-%02X%02X", + buf[3], buf[2], buf[1], buf[0]); + break; + case UUID_NTFS: + sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", + buf[7], buf[6], buf[5], buf[4], + buf[3], buf[2], buf[1], buf[0]); + break; + case UUID_HFS: + sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + break; + case UUID_DCE: + sprintf(id->uuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], + buf[6], buf[7], + buf[8], buf[9], + buf[10], buf[11], buf[12], buf[13], buf[14],buf[15]); + break; + case UUID_DCE_STRING: + memcpy(id->uuid, buf, count); + id->uuid[count] = '\0'; + break; + } +} + +uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) +{ + ssize_t buf_len; + + dbg("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) { + if (id->sbbuf == NULL) { + id->sbbuf = malloc(SB_BUFFER_SIZE); + if (id->sbbuf == NULL) { + dbg("error malloc"); + return NULL; + } + } + + /* check if we need to read */ + if ((off + len) > id->sbbuf_len) { + dbg("read sbbuf len:0x%llx", (unsigned long long) (off + len)); + if (lseek(id->fd, 0, SEEK_SET) < 0) { + dbg("lseek failed (%s)", strerror(errno)); + return NULL; + } + buf_len = read(id->fd, id->sbbuf, off + len); + if (buf_len < 0) { + dbg("read failed (%s)", strerror(errno)); + return NULL; + } + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); + id->sbbuf_len = buf_len; + if ((size_t)buf_len < off + len) { + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); + return NULL; + } + } + + return &(id->sbbuf[off]); + } else { + if (len > SEEK_BUFFER_SIZE) { + dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); + return NULL; + } + + /* get seek buffer */ + if (id->seekbuf == NULL) { + id->seekbuf = malloc(SEEK_BUFFER_SIZE); + if (id->seekbuf == NULL) { + dbg("error malloc"); + return NULL; + } + } + + /* check if we need to read */ + if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { + dbg("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); + if (lseek(id->fd, off, SEEK_SET) < 0) { + dbg("lseek failed (%s)", strerror(errno)); + return NULL; + } + buf_len = read(id->fd, id->seekbuf, len); + if (buf_len < 0) { + dbg("read failed (%s)", strerror(errno)); + return NULL; + } + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); + id->seekbuf_off = off; + id->seekbuf_len = buf_len; + if ((size_t)buf_len < len) { + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); + return NULL; + } + } + + return &(id->seekbuf[off - id->seekbuf_off]); + } +} + +void volume_id_free_buffer(struct volume_id *id) +{ + if (id->sbbuf != NULL) { + free(id->sbbuf); + id->sbbuf = NULL; + id->sbbuf_len = 0; + } + if (id->seekbuf != NULL) { + free(id->seekbuf); + id->seekbuf = NULL; + id->seekbuf_len = 0; + } +} diff --git a/extras/volume_id/lib/util.h b/extras/volume_id/lib/util.h new file mode 100644 index 0000000000..1d1b53bb57 --- /dev/null +++ b/extras/volume_id/lib/util.h @@ -0,0 +1,84 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005-2006 Kay Sievers + * + * 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 +#endif + +#include +#include +#include + +#define err(format, arg...) volume_id_log(LOG_ERR, __FILE__, __LINE__, format, ##arg) +#define info(format, arg...) volume_id_log(LOG_INFO, __FILE__, __LINE__, format, ##arg) +#ifdef DEBUG +#define dbg(format, arg...) volume_id_log(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_DCE_STRING, + UUID_DCE, + UUID_DOS, + UUID_NTFS, + UUID_HFS, +}; + +enum endian { + LE = 0, + BE = 1 +}; + +extern void volume_id_set_unicode16(char *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, 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_ */ + diff --git a/extras/volume_id/lib/via_raid.c b/extras/volume_id/lib/via_raid.c new file mode 100644 index 0000000000..42cb098065 --- /dev/null +++ b/extras/volume_id/lib/via_raid.c @@ -0,0 +1,75 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +struct via_meta { + uint16_t signature; + uint8_t version_number; + struct via_array { + uint16_t disk_bits; + 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 + +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; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", via->version_number); + id->type = "via_raid_member"; + + return 0; +} diff --git a/extras/volume_id/lib/volume_id.c b/extras/volume_id/lib/volume_id.c new file mode 100644 index 0000000000..073ad79c77 --- /dev/null +++ b/extras/volume_id/lib/volume_id.c @@ -0,0 +1,231 @@ +/* + * volume_id - reads volume label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.h" + +/* 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 volume_id_log = default_log; + +int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + + /* probe for raid first, cause fs probes may be successful on raid members */ + if (size) { + if (volume_id_probe_linux_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_intel_software_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_lsi_mega_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_via_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_silicon_medley_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_nvidia_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_promise_fasttrack_raid(id, off, size) == 0) + goto found; + + if (volume_id_probe_highpoint_45x_raid(id, off, size) == 0) + goto found; + } + + if (volume_id_probe_lvm1(id, off) == 0) + goto found; + + if (volume_id_probe_lvm2(id, off) == 0) + goto found; + + if (volume_id_probe_highpoint_37x_raid(id, off) == 0) + goto found; + + return -1; + +found: + /* If recognized, we free the allocated buffers */ + volume_id_free_buffer(id); + return 0; +} + +int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + + if (volume_id_probe_luks(id, off) == 0) + goto found; + + /* signature in the first block, only small buffer needed */ + if (volume_id_probe_vfat(id, off) == 0) + goto found; + + if (volume_id_probe_xfs(id, off) == 0) + goto found; + + /* fill buffer with maximum */ + volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); + + if (volume_id_probe_linux_swap(id, off) == 0) + goto found; + + if (volume_id_probe_ext(id, off) == 0) + goto found; + + if (volume_id_probe_reiserfs(id, off) == 0) + goto found; + + if (volume_id_probe_jfs(id, off) == 0) + goto found; + + if (volume_id_probe_udf(id, off) == 0) + goto found; + + if (volume_id_probe_iso9660(id, off) == 0) + goto found; + + if (volume_id_probe_hfs_hfsplus(id, off) == 0) + goto found; + + if (volume_id_probe_ufs(id, off) == 0) + goto found; + + if (volume_id_probe_ntfs(id, off) == 0) + goto found; + + if (volume_id_probe_cramfs(id, off) == 0) + goto found; + + if (volume_id_probe_romfs(id, off) == 0) + goto found; + + if (volume_id_probe_hpfs(id, off) == 0) + goto found; + + if (volume_id_probe_sysv(id, off) == 0) + goto found; + + if (volume_id_probe_minix(id, off) == 0) + goto found; + + if (volume_id_probe_ocfs1(id, off) == 0) + goto found; + + if (volume_id_probe_ocfs2(id, off) == 0) + goto found; + + if (volume_id_probe_vxfs(id, off) == 0) + goto found; + + if (volume_id_probe_squashfs(id, off) == 0) + goto found; + + return -1; + +found: + /* If recognized, we free the allocated buffers */ + volume_id_free_buffer(id); + return 0; +} + +int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + + if (volume_id_probe_raid(id, off, size) == 0) + return 0; + + if (volume_id_probe_filesystem(id, off, size) == 0) + return 0; + + return -1; +} + +/* open volume by already open file descriptor */ +struct volume_id *volume_id_open_fd(int fd) +{ + struct volume_id *id; + + id = malloc(sizeof(struct volume_id)); + if (id == NULL) + return NULL; + memset(id, 0x00, sizeof(struct volume_id)); + + id->fd = fd; + + return id; +} + +/* open volume by device node */ +struct volume_id *volume_id_open_node(const char *path) +{ + struct volume_id *id; + int fd; + + fd = open(path, O_RDONLY); + if (fd < 0) { + dbg("unable to open '%s'", path); + return NULL; + } + + id = volume_id_open_fd(fd); + if (id == NULL) + return NULL; + + /* close fd on device close */ + id->fd_close = 1; + + return id; +} + +void volume_id_close(struct volume_id *id) +{ + if (id == NULL) + return; + + if (id->fd_close != 0) + close(id->fd); + + volume_id_free_buffer(id); + + free(id); +} diff --git a/extras/volume_id/lib/vxfs.c b/extras/volume_id/lib/vxfs.c new file mode 100644 index 0000000000..d10cc37762 --- /dev/null +++ b/extras/volume_id/lib/vxfs.c @@ -0,0 +1,54 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct vxfs_super *vxs; + + dbg("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)) { + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", (unsigned int) vxs->vs_version); + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "vxfs"; + return 0; + } + + return -1; +} diff --git a/extras/volume_id/lib/xfs.c b/extras/volume_id/lib/xfs.c new file mode 100644 index 0000000000..3d870c41e7 --- /dev/null +++ b/extras/volume_id/lib/xfs.c @@ -0,0 +1,65 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include "libvolume_id.h" +#include "util.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) +{ + struct xfs_super_block *xs; + + dbg("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(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, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "xfs"; + + return 0; +} diff --git a/extras/volume_id/libvolume_id/Makefile b/extras/volume_id/libvolume_id/Makefile deleted file mode 100644 index 6a12f0e67a..0000000000 --- a/extras/volume_id/libvolume_id/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -# libvolume_id - read filesystem label/uuid -# -# Copyright (C) 2004-2006 Kay Sievers -# -# Released under the GNU General Public License, version 2. -# -includedir = ${prefix}/usr/include -libdir = ${prefix}/lib -usrlibdir = ${prefix}/usr/lib - -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_LIB = ${INSTALL} -m 755 - -SHLIB_CUR = 0 -SHLIB_REV = 61 -SHLIB_AGE = 0 -SHLIB = libvolume_id.so.$(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE) - -OBJS= \ - ext.o \ - fat.o \ - hfs.o \ - highpoint.o \ - isw_raid.o \ - lsi_raid.o \ - via_raid.o \ - silicon_raid.o \ - nvidia_raid.o \ - promise_raid.o \ - iso9660.o \ - jfs.o \ - linux_raid.o \ - linux_swap.o \ - lvm.o \ - ntfs.o \ - reiserfs.o \ - udf.o \ - ufs.o \ - xfs.o \ - cramfs.o \ - hpfs.o \ - romfs.o \ - sysv.o \ - minix.o \ - luks.o \ - ocfs.o \ - vxfs.o \ - squashfs.o \ - volume_id.o \ - util.o - -HEADERS= \ - libvolume_id.h \ - util.h - -AR = $(CROSS)ar -RANLIB = $(CROSS)ranlib - -all: libvolume_id.a $(SHLIB) libvolume_id.pc -.PHONY: all -.DEFAULT: all - -%.o: %.c - $(E) " CC " $@ - $(Q) $(CC) -c $(CFLAGS) $< -o $@ - -.shlib: - $(Q) mkdir .shlib - -.shlib/%.o: %.c - $(E) " CC " $@ - $(Q) $(CC) -c $(CFLAGS) -fPIC $< -o $@ - -libvolume_id.a: $(HEADERS) $(OBJS) - $(Q) rm -f $@ - $(E) " AR " $@ - $(Q) $(AR) cq $@ $(OBJS) - $(E) " RANLIB " $@ - $(Q) $(RANLIB) $@ - -$(SHLIB): $(HEADERS) .shlib $(addprefix .shlib/,$(OBJS)) - $(E) " CC " $@ - $(Q) $(CC) -shared $(CFLAGS) -o $@ -Wl,-soname,libvolume_id.so.$(SHLIB_CUR) $(addprefix .shlib/,$(OBJS)) - $(Q) ln -sf $@ libvolume_id.so.$(SHLIB_CUR) - $(Q) ln -sf $@ libvolume_id.so - -libvolume_id.pc: - $(E) " GENPC " $@ - $(Q) echo "prefix=${prefix}" > $@ - $(Q) echo "libdir=${libdir}" >> $@ - $(Q) echo "includedir=${includedir}" >> $@ - $(Q) echo "" >> $@ - $(Q) echo "Name: libvolume_id" >> $@ - $(Q) echo "Description: Filesystem label and uuid access" >> $@ - $(Q) echo "Version: $(SHLIB_CUR).$(SHLIB_REV).$(SHLIB_AGE)" >> $@ - $(Q) echo "Libs: -L\$${libdir} -lvolume_id" >> $@ - $(Q) echo "Cflags: -I\$${includedir}" >> $@ - -install: all - $(INSTALL_DATA) -D libvolume_id.h $(DESTDIR)$(includedir)/libvolume_id.h - $(INSTALL_LIB) -D libvolume_id.a $(DESTDIR)$(usrlibdir)/libvolume_id.a - $(INSTALL_LIB) -D $(SHLIB) $(DESTDIR)$(libdir)/$(SHLIB) - ln -sf $(DESTDIR)$(libdir)/$(SHLIB) $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) - ln -sf $(DESTDIR)$(libdir)/$(SHLIB) $(DESTDIR)$(usrlibdir)/libvolume_id.so - $(INSTALL_DATA) -D libvolume_id.pc $(DESTDIR)$(usrlibdir)/pkgconfig/libvolume_id.pc -.PHONY: install - -uninstall: - rm -f $(DESTDIR)$(includedir)/libvolume_id.h - rm -f $(DESTDIR)$(usrlibdir)/libvolume_id.a - rm -f $(DESTDIR)$(libdir)/$(SHLIB) - rm -f $(DESTDIR)$(libdir)/libvolume_id.so.$(SHLIB_CUR) - rm -f $(DESTDIR)$(libdir)/libvolume_id.so -.PHONY: uninstall - -clean: - $(E) " CLEAN " - $(Q) rm -f libvolume_id.a $(OBJS) - $(Q) rm -f $(SHLIB) libvolume_id.so.$(SHLIB_CUR) libvolume_id.so - $(Q) rm -rf .shlib - $(Q) rm -f libvolume_id.pc -.PHONY: clean - diff --git a/extras/volume_id/libvolume_id/cramfs.c b/extras/volume_id/libvolume_id/cramfs.c deleted file mode 100644 index beb34d5bc0..0000000000 --- a/extras/volume_id/libvolume_id/cramfs.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct cramfs_super *cs; - - dbg("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(cs->magic, "\x45\x3d\xcd\x28", 4) == 0 || memcmp(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; -} diff --git a/extras/volume_id/libvolume_id/ext.c b/extras/volume_id/libvolume_id/ext.c deleted file mode 100644 index 51c0011218..0000000000 --- a/extras/volume_id/libvolume_id/ext.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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 0x00000004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 -#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) -{ - struct ext2_super_block *es; - size_t bsize; - - dbg("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, UUID_DCE); - snprintf(id->type_version, sizeof(id->type_version)-1, - "%u.%u", es->s_rev_level, es->s_minor_rev_level); - - /* check for external journal device */ - if ((le32_to_cpu(es->s_feature_incompat) & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { - volume_id_set_usage(id, VOLUME_ID_OTHER); - id->type = "jbd"; - return 0; - } - - /* check for ext2 / ext3 */ - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) - id->type = "ext3"; - else - id->type = "ext2"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/fat.c b/extras/volume_id/libvolume_id/fat.c deleted file mode 100644 index 4840a2a23c..0000000000 --- a/extras/volume_id/libvolume_id/fat.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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 - -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 insfo_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 vfat_dir_entry { - uint8_t name[11]; - uint8_t attr; - uint16_t time_creat; - uint16_t date_creat; - uint16_t time_acc; - uint16_t date_acc; - uint16_t cluster_high; - uint16_t time_write; - uint16_t date_write; - uint16_t cluster_low; - uint32_t size; -} PACKED; - -static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) { - /* end marker */ - if (dir[i].name[0] == 0x00) { - dbg("end of dir"); - break; - } - - /* empty entry */ - if (dir[i].name[0] == FAT_ENTRY_FREE) - continue; - - /* long name */ - if ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME) - continue; - - if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { - /* labels do not have file data */ - if (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) - continue; - - dbg("found ATTR_VOLUME_ID id in root dir"); - return dir[i].name; - } - - dbg("skip dir entry"); - } - - return NULL; -} - -int volume_id_probe_vfat(struct volume_id *id, uint64_t off) -{ - struct vfat_super_block *vs; - struct vfat_dir_entry *dir; - 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; - uint8_t *buf; - uint32_t buf_size; - uint8_t *label = NULL; - uint32_t next; - int maxloop; - - dbg("probing at offset 0x%llx", (unsigned long long) off); - - vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); - if (vs == NULL) - return -1; - - /* believe only that's fat, don't trust the version - * the cluster_count will tell us - */ - if (memcmp(vs->sysid, "NTFS", 4) == 0) - return -1; - - if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0) - goto magic; - - if (memcmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) - goto magic; - - if (memcmp(vs->type.fat.magic, "FAT16 ", 8) == 0) - goto magic; - - if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0) - goto magic; - - if (memcmp(vs->type.fat.magic, "FAT12 ", 8) == 0) - goto magic; - - /* some old floppies don't have a magic, so we expect the boot code to match */ - - /* boot jump address check */ - 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 != 0x200 && sector_size != 0x400 && - sector_size != 0x800 && sector_size != 0x1000) - 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; - - dir = (struct vfat_dir_entry*) buf; - - label = get_attr_volume_id(dir, root_dir_entries); - - vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); - if (vs == NULL) - return -1; - - if (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { - volume_id_set_label_raw(id, label, 11); - volume_id_set_label_string(id, label, 11); - } else if (memcmp(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, UUID_DOS); - goto found; - -fat32: - 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; - - dir = (struct vfat_dir_entry*) buf; - count = buf_size / sizeof(struct vfat_dir_entry); - dbg("expected entries 0x%x", count); - - label = get_attr_volume_id(dir, count); - if (label) - 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 == 0) - 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 (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { - volume_id_set_label_raw(id, label, 11); - volume_id_set_label_string(id, label, 11); - } else if (memcmp(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, UUID_DOS); - -found: - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "vfat"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/hfs.c b/extras/volume_id/libvolume_id/hfs.c deleted file mode 100644 index a6e378dd28..0000000000 --- a/extras/volume_id/libvolume_id/hfs.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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; - -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; - -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 - -int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off) -{ - 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; - - dbg("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(hfs->signature, "BD", 2) != 0) - goto checkplus; - - /* it may be just a hfs wrapper for hfs+ */ - if (memcmp(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) ; - } - - volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS); - - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "hfs"; - - return 0; - -checkplus: - hfsplus = (struct hfsplus_vol_header *) buf; - if (memcmp(hfsplus->signature, "H+", 2) == 0) - goto hfsplus; - if (memcmp(hfsplus->signature, "HX", 2) == 0) - goto hfsplus; - return -1; - -hfsplus: - volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS); - - 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; -} diff --git a/extras/volume_id/libvolume_id/highpoint.c b/extras/volume_id/libvolume_id/highpoint.c deleted file mode 100644 index deba540ad5..0000000000 --- a/extras/volume_id/libvolume_id/highpoint.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - const uint8_t *buf; - struct hpt37x_meta *hpt; - uint32_t magic; - - dbg("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; -} diff --git a/extras/volume_id/libvolume_id/hpfs.c b/extras/volume_id/libvolume_id/hpfs.c deleted file mode 100644 index 3e9589fcca..0000000000 --- a/extras/volume_id/libvolume_id/hpfs.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct hpfs_super *hs; - - dbg("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(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; -} diff --git a/extras/volume_id/libvolume_id/iso9660.c b/extras/volume_id/libvolume_id/iso9660.c deleted file mode 100644 index 7b78a7e992..0000000000 --- a/extras/volume_id/libvolume_id/iso9660.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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 vd_type; - uint8_t vd_id[5]; - uint8_t vd_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[4]; - uint8_t version; -} PACKED; - -int volume_id_probe_iso9660(struct volume_id *id, uint64_t off) -{ - uint8_t *buf; - struct iso_volume_descriptor *is; - struct high_sierra_volume_descriptor *hs; - - dbg("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(is->vd_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->vd_type == ISO_VD_END) - break; - if (is->vd_type != ISO_VD_SUPPLEMENTARY) - continue; - - dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset)); - if (memcmp(is->escape_sequences, "%/@", 3) == 0|| - memcmp(is->escape_sequences, "%/C", 3) == 0|| - memcmp(is->escape_sequences, "%/E", 3) == 0) { - dbg("Joliet extension found"); - volume_id_set_unicode16((char *)svd_label, sizeof(svd_label), is->volume_id, BE, 32); - if (memcmp(id->label, 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(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; -} diff --git a/extras/volume_id/libvolume_id/isw_raid.c b/extras/volume_id/libvolume_id/isw_raid.c deleted file mode 100644 index 6465a31bf5..0000000000 --- a/extras/volume_id/libvolume_id/isw_raid.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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; - - 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)-2) * 0x200; - buf = volume_id_get_buffer(id, off + meta_off, 0x200); - if (buf == NULL) - return -1; - - isw = (struct isw_meta *) buf; - if (memcmp(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; -} diff --git a/extras/volume_id/libvolume_id/jfs.c b/extras/volume_id/libvolume_id/jfs.c deleted file mode 100644 index b230fb258c..0000000000 --- a/extras/volume_id/libvolume_id/jfs.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct jfs_super_block *js; - - dbg("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(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, UUID_DCE); - - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "jfs"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/libvolume_id.h b/extras/volume_id/libvolume_id/libvolume_id.h deleted file mode 100644 index 7faf8d8af3..0000000000 --- a/extras/volume_id/libvolume_id/libvolume_id.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * volume_id - reads volume label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#include - -#ifndef PACKED -#define PACKED __attribute__((packed)) -#endif - - -typedef void (*volume_id_log_fn)(int priority, const char *file, int line, const char *format, ...) - __attribute__ ((format(printf, 4, 5))); - -extern volume_id_log_fn volume_id_log; - -#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, -}; - -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; - size_t sbbuf_len; - uint8_t *seekbuf; - uint64_t seekbuf_off; - size_t seekbuf_len; - int fd_close:1; -}; - -extern struct volume_id *volume_id_open_fd(int fd); -extern struct volume_id *volume_id_open_node(const char *path); -extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); -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 void volume_id_close(struct volume_id *id); - -/* filesystems */ -extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ext(struct volume_id *id, uint64_t off); -extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off); -extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off); -extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off); -extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_minix(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); -extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off); -extern int volume_id_probe_udf(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off); -extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off); - -/* special formats */ -extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off); -extern int volume_id_probe_luks(struct volume_id *id, uint64_t off); - -/* 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); -extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off); - -/* 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); -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); - -#endif diff --git a/extras/volume_id/libvolume_id/linux_raid.c b/extras/volume_id/libvolume_id/linux_raid.c deleted file mode 100644 index 85e8d8109b..0000000000 --- a/extras/volume_id/libvolume_id/linux_raid.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -struct mdp_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 *mdp; - -#define MD_RESERVED_BYTES 0x10000 -#define MD_MAGIC 0xa92b4efc - -int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) -{ - const uint8_t *buf; - uint64_t sboff; - uint8_t uuid[16]; - - dbg("probing at offset 0x%llx, size 0x%llx", - (unsigned long long) off, (unsigned long long) size); - - if (size < 0x10000) - return -1; - - sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; - buf = volume_id_get_buffer(id, off + sboff, 0x800); - if (buf == NULL) - return -1; - - mdp = (struct mdp_super_block *) buf; - - if (le32_to_cpu(mdp->md_magic) != MD_MAGIC) - return -1; - - memcpy(uuid, &mdp->set_uuid0, 4); - memcpy(&uuid[4], &mdp->set_uuid1, 12); - volume_id_set_uuid(id, uuid, UUID_DCE); - - snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", - le32_to_cpu(mdp->major_version), - le32_to_cpu(mdp->minor_version), - le32_to_cpu(mdp->patch_version)); - - dbg("found raid signature"); - volume_id_set_usage(id, VOLUME_ID_RAID); - id->type = "linux_raid_member"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/linux_swap.c b/extras/volume_id/libvolume_id/linux_swap.c deleted file mode 100644 index 0193648c9e..0000000000 --- a/extras/volume_id/libvolume_id/linux_swap.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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 *sw; - -#define LARGEST_PAGESIZE 0x4000 - -int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off) -{ - const uint8_t *buf; - unsigned int page; - - dbg("probing at offset 0x%llx", (unsigned long long) off); - - /* 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(buf, "SWAP-SPACE", 10) == 0) { - strcpy(id->type_version, "1"); - goto found; - } - - if (memcmp(buf, "SWAPSPACE2", 10) == 0) { - sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); - if (sw == NULL) - return -1; - strcpy(id->type_version, "2"); - 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, UUID_DCE); - goto found; - } - } - return -1; - -found: - volume_id_set_usage(id, VOLUME_ID_OTHER); - id->type = "swap"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/lsi_raid.c b/extras/volume_id/libvolume_id/lsi_raid.c deleted file mode 100644 index f1db4a6e50..0000000000 --- a/extras/volume_id/libvolume_id/lsi_raid.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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; - - 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; - - lsi = (struct lsi_meta *) buf; - if (memcmp(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; -} diff --git a/extras/volume_id/libvolume_id/luks.c b/extras/volume_id/libvolume_id/luks.c deleted file mode 100644 index 64de85ac21..0000000000 --- a/extras/volume_id/libvolume_id/luks.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 W. Michael Petullo - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -#define SECTOR_SHIFT 9 -#define SECTOR_SIZE (1 << 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 - -const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; -#define LUKS_MAGIC_L 6 -#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) -#define UUID_STRING_L 40 - -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) -{ - struct luks_phdr *header; - - header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); - if (header == NULL) - return -1; - - if (memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) - return -1; - - volume_id_set_usage(id, VOLUME_ID_CRYPTO); - volume_id_set_uuid(id, header->uuid, UUID_DCE_STRING); - - id->type = "crypto_LUKS"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/lvm.c b/extras/volume_id/libvolume_id/lvm.c deleted file mode 100644 index 47d84b0968..0000000000 --- a/extras/volume_id/libvolume_id/lvm.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - const uint8_t *buf; - struct lvm1_super_block *lvm; - - dbg("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(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) -{ - 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(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; -} diff --git a/extras/volume_id/libvolume_id/minix.c b/extras/volume_id/libvolume_id/minix.c deleted file mode 100644 index 75e9c3acbd..0000000000 --- a/extras/volume_id/libvolume_id/minix.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -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; - -#define MINIX_SUPERBLOCK_OFFSET 0x400 - -int volume_id_probe_minix(struct volume_id *id, uint64_t off) -{ - struct minix_super_block *ms; - - dbg("probing at offset 0x%llx", (unsigned long long) off); - - ms = (struct minix_super_block *) volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); - if (ms == NULL) - return -1; - - if (le16_to_cpu(ms->s_magic) == 0x137f) { - strcpy(id->type_version, "1"); - goto found; - } - - if (le16_to_cpu(ms->s_magic) == 0x1387) { - strcpy(id->type_version, "1"); - goto found; - } - - if (le16_to_cpu(ms->s_magic) == 0x2468) { - strcpy(id->type_version, "2"); - goto found; - } - - if (le16_to_cpu(ms->s_magic) == 0x2478) { - strcpy(id->type_version, "2"); - goto found; - } - - goto exit; - -found: - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "minix"; - return 0; - -exit: - return -1; -} diff --git a/extras/volume_id/libvolume_id/ntfs.c b/extras/volume_id/libvolume_id/ntfs.c deleted file mode 100644 index 23c64fc307..0000000000 --- a/extras/volume_id/libvolume_id/ntfs.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -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; - -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; - -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; - -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 - -int volume_id_probe_ntfs(struct volume_id *id, uint64_t off) -{ - 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; - - dbg("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(ns->oem_id, "NTFS", 4) != 0) - return -1; - - volume_id_set_uuid(id, ns->volume_serial, UUID_NTFS); - - sector_size = le16_to_cpu(ns->bytes_per_sector); - 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) - goto found; - - 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(mftr->magic, "FILE", 4) != 0) - goto found; - - 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); - snprintf(id->type_version, sizeof(id->type_version)-1, - "%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); - } - } - -found: - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "ntfs"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/nvidia_raid.c b/extras/volume_id/libvolume_id/nvidia_raid.c deleted file mode 100644 index 10c1c714f7..0000000000 --- a/extras/volume_id/libvolume_id/nvidia_raid.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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; - - 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)-2) * 0x200; - buf = volume_id_get_buffer(id, off + meta_off, 0x200); - if (buf == NULL) - return -1; - - nv = (struct nvidia_meta *) buf; - if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) - return -1; - - volume_id_set_usage(id, VOLUME_ID_RAID); - snprintf(id->type_version, sizeof(id->type_version)-1, "%u", le16_to_cpu(nv->version)); - id->type = "nvidia_raid_member"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/ocfs.c b/extras/volume_id/libvolume_id/ocfs.c deleted file mode 100644 index b376ead833..0000000000 --- a/extras/volume_id/libvolume_id/ocfs.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Andre Masella - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - const uint8_t *buf; - struct ocfs1_super_block_header *osh; - struct ocfs1_super_block_label *osl; - - buf = volume_id_get_buffer(id, off, 0x200); - if (buf == NULL) - return -1; - - osh = (struct ocfs1_super_block_header *) buf; - if (memcmp(osh->signature, "OracleCFS", 9) != 0) - return -1; - snprintf(id->type_version, sizeof(id->type_version)-1, - "%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, 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) -{ - const uint8_t *buf; - struct ocfs2_super_block *os; - size_t blksize; - - dbg("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(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, UUID_DCE); - snprintf(id->type_version, sizeof(id->type_version)-1, - "%u.%u", os->s_major_rev_level, os->s_minor_rev_level); - id->type = "ocfs2"; - return 0; - } - return -1; -} diff --git a/extras/volume_id/libvolume_id/promise_raid.c b/extras/volume_id/libvolume_id/promise_raid.c deleted file mode 100644 index 2a2ce1689e..0000000000 --- a/extras/volume_id/libvolume_id/promise_raid.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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 - }; - - dbg("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(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; -} diff --git a/extras/volume_id/libvolume_id/reiserfs.c b/extras/volume_id/libvolume_id/reiserfs.c deleted file mode 100644 index b5706f86e0..0000000000 --- a/extras/volume_id/libvolume_id/reiserfs.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2005 Tobias Klauser - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct reiserfs_super_block *rs; - struct reiser4_super_block *rs4; - uint8_t *buf; - - dbg("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(rs->magic, "ReIsErFs", 8) == 0) { - strcpy(id->type_version, "3.5"); - id->type = "reiserfs"; - goto found; - } - if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { - strcpy(id->type_version, "3.6"); - id->type = "reiserfs"; - goto found_label; - } - if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { - strcpy(id->type_version, "JR"); - id->type = "reiserfs"; - goto found_label; - } - - rs4 = (struct reiser4_super_block *) buf; - if (memcmp(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, 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(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, UUID_DCE); - -found: - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - - return 0; -} diff --git a/extras/volume_id/libvolume_id/romfs.c b/extras/volume_id/libvolume_id/romfs.c deleted file mode 100644 index 8bb2a0018a..0000000000 --- a/extras/volume_id/libvolume_id/romfs.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct romfs_super *rfs; - - dbg("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(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; -} diff --git a/extras/volume_id/libvolume_id/silicon_raid.c b/extras/volume_id/libvolume_id/silicon_raid.c deleted file mode 100644 index 017b023e27..0000000000 --- a/extras/volume_id/libvolume_id/silicon_raid.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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; - - 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; - - sil = (struct silicon_meta *) buf; - if (le32_to_cpu(sil->magic) != SILICON_MAGIC) - return -1; - - volume_id_set_usage(id, VOLUME_ID_RAID); - snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", - le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); - id->type = "silicon_medley_raid_member"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/squashfs.c b/extras/volume_id/libvolume_id/squashfs.c deleted file mode 100644 index bdb1f16628..0000000000 --- a/extras/volume_id/libvolume_id/squashfs.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2006 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -#define SQUASHFS_MAGIC 0x73717368 - -struct squashfs_super { - uint32_t s_magic; -} PACKED; - -int volume_id_probe_squashfs(struct volume_id *id, uint64_t off) -{ - struct squashfs_super *sqs; - - dbg("probing at offset 0x%llx", (unsigned long long) off); - - sqs = (struct squashfs_super *) volume_id_get_buffer(id, off + 0x200, 0x200); - if (sqs == NULL) - return -1; - - if (sqs->s_magic == SQUASHFS_MAGIC || sqs->s_magic == bswap_32(SQUASHFS_MAGIC)) { - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "squashfs"; - return 0; - } - - return -1; -} diff --git a/extras/volume_id/libvolume_id/sysv.c b/extras/volume_id/libvolume_id/sysv.c deleted file mode 100644 index 52349c0623..0000000000 --- a/extras/volume_id/libvolume_id/sysv.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct sysv_super *vs; - struct xenix_super *xs; - unsigned int boff; - - dbg("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; -} diff --git a/extras/volume_id/libvolume_id/udf.c b/extras/volume_id/libvolume_id/udf.c deleted file mode 100644 index d7497ec51b..0000000000 --- a/extras/volume_id/libvolume_id/udf.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - 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; - - dbg("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(vsd->id, "NSR02", 5) == 0) - goto blocksize; - if (memcmp(vsd->id, "NSR03", 5) == 0) - goto blocksize; - if (memcmp(vsd->id, "BEA01", 5) == 0) - goto blocksize; - if (memcmp(vsd->id, "BOOT2", 5) == 0) - goto blocksize; - if (memcmp(vsd->id, "CD001", 5) == 0) - goto blocksize; - if (memcmp(vsd->id, "CDW02", 5) == 0) - goto blocksize; - if (memcmp(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(vsd->id, "NSR02", 5) == 0) - goto anchor; - if (memcmp(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; -} diff --git a/extras/volume_id/libvolume_id/ufs.c b/extras/volume_id/libvolume_id/ufs.c deleted file mode 100644 index d3960b1bec..0000000000 --- a/extras/volume_id/libvolume_id/ufs.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - uint32_t magic; - int i; - struct ufs_super_block *ufs; - int offsets[] = {0, 8, 64, 256, -1}; - - dbg("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"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/util.c b/extras/volume_id/libvolume_id/util.c deleted file mode 100644 index cf5392cf9a..0000000000 --- a/extras/volume_id/libvolume_id/util.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -void volume_id_set_unicode16(char *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) -{ - unsigned int 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'; -} - -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) -{ - 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) -{ - unsigned int i; - - memcpy(id->label, buf, count); - - /* 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) -{ - volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); -} - -void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format) -{ - unsigned int i; - unsigned int count = 0; - - switch(format) { - case UUID_DOS: - count = 4; - break; - case UUID_NTFS: - case UUID_HFS: - count = 8; - break; - case UUID_DCE: - count = 16; - break; - case UUID_DCE_STRING: - count = 36; - 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: - switch(format) { - case UUID_DOS: - sprintf(id->uuid, "%02X%02X-%02X%02X", - buf[3], buf[2], buf[1], buf[0]); - break; - case UUID_NTFS: - sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", - buf[7], buf[6], buf[5], buf[4], - buf[3], buf[2], buf[1], buf[0]); - break; - case UUID_HFS: - sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); - break; - case UUID_DCE: - sprintf(id->uuid, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], - buf[6], buf[7], - buf[8], buf[9], - buf[10], buf[11], buf[12], buf[13], buf[14],buf[15]); - break; - case UUID_DCE_STRING: - memcpy(id->uuid, buf, count); - id->uuid[count] = '\0'; - break; - } -} - -uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) -{ - ssize_t buf_len; - - dbg("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) { - if (id->sbbuf == NULL) { - id->sbbuf = malloc(SB_BUFFER_SIZE); - if (id->sbbuf == NULL) { - dbg("error malloc"); - return NULL; - } - } - - /* check if we need to read */ - if ((off + len) > id->sbbuf_len) { - dbg("read sbbuf len:0x%llx", (unsigned long long) (off + len)); - if (lseek(id->fd, 0, SEEK_SET) < 0) { - dbg("lseek failed (%s)", strerror(errno)); - return NULL; - } - buf_len = read(id->fd, id->sbbuf, off + len); - if (buf_len < 0) { - dbg("read failed (%s)", strerror(errno)); - return NULL; - } - dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); - id->sbbuf_len = buf_len; - if ((size_t)buf_len < off + len) { - dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); - return NULL; - } - } - - return &(id->sbbuf[off]); - } else { - if (len > SEEK_BUFFER_SIZE) { - dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); - return NULL; - } - - /* get seek buffer */ - if (id->seekbuf == NULL) { - id->seekbuf = malloc(SEEK_BUFFER_SIZE); - if (id->seekbuf == NULL) { - dbg("error malloc"); - return NULL; - } - } - - /* check if we need to read */ - if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); - if (lseek(id->fd, off, SEEK_SET) < 0) { - dbg("lseek failed (%s)", strerror(errno)); - return NULL; - } - buf_len = read(id->fd, id->seekbuf, len); - if (buf_len < 0) { - dbg("read failed (%s)", strerror(errno)); - return NULL; - } - dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); - id->seekbuf_off = off; - id->seekbuf_len = buf_len; - if ((size_t)buf_len < len) { - dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); - return NULL; - } - } - - return &(id->seekbuf[off - id->seekbuf_off]); - } -} - -void volume_id_free_buffer(struct volume_id *id) -{ - if (id->sbbuf != NULL) { - free(id->sbbuf); - id->sbbuf = NULL; - id->sbbuf_len = 0; - } - if (id->seekbuf != NULL) { - free(id->seekbuf); - id->seekbuf = NULL; - id->seekbuf_len = 0; - } -} diff --git a/extras/volume_id/libvolume_id/util.h b/extras/volume_id/libvolume_id/util.h deleted file mode 100644 index 1d1b53bb57..0000000000 --- a/extras/volume_id/libvolume_id/util.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005-2006 Kay Sievers - * - * 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 -#endif - -#include -#include -#include - -#define err(format, arg...) volume_id_log(LOG_ERR, __FILE__, __LINE__, format, ##arg) -#define info(format, arg...) volume_id_log(LOG_INFO, __FILE__, __LINE__, format, ##arg) -#ifdef DEBUG -#define dbg(format, arg...) volume_id_log(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_DCE_STRING, - UUID_DCE, - UUID_DOS, - UUID_NTFS, - UUID_HFS, -}; - -enum endian { - LE = 0, - BE = 1 -}; - -extern void volume_id_set_unicode16(char *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, 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_ */ - diff --git a/extras/volume_id/libvolume_id/via_raid.c b/extras/volume_id/libvolume_id/via_raid.c deleted file mode 100644 index 42cb098065..0000000000 --- a/extras/volume_id/libvolume_id/via_raid.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -struct via_meta { - uint16_t signature; - uint8_t version_number; - struct via_array { - uint16_t disk_bits; - 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 - -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; - - volume_id_set_usage(id, VOLUME_ID_RAID); - snprintf(id->type_version, sizeof(id->type_version)-1, "%u", via->version_number); - id->type = "via_raid_member"; - - return 0; -} diff --git a/extras/volume_id/libvolume_id/volume_id.c b/extras/volume_id/libvolume_id/volume_id.c deleted file mode 100644 index 073ad79c77..0000000000 --- a/extras/volume_id/libvolume_id/volume_id.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * volume_id - reads volume label and uuid - * - * Copyright (C) 2005 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.h" - -/* 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 volume_id_log = default_log; - -int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) -{ - if (id == NULL) - return -EINVAL; - - /* probe for raid first, cause fs probes may be successful on raid members */ - if (size) { - if (volume_id_probe_linux_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_intel_software_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_lsi_mega_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_via_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_silicon_medley_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_nvidia_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_promise_fasttrack_raid(id, off, size) == 0) - goto found; - - if (volume_id_probe_highpoint_45x_raid(id, off, size) == 0) - goto found; - } - - if (volume_id_probe_lvm1(id, off) == 0) - goto found; - - if (volume_id_probe_lvm2(id, off) == 0) - goto found; - - if (volume_id_probe_highpoint_37x_raid(id, off) == 0) - goto found; - - return -1; - -found: - /* If recognized, we free the allocated buffers */ - volume_id_free_buffer(id); - return 0; -} - -int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) -{ - if (id == NULL) - return -EINVAL; - - if (volume_id_probe_luks(id, off) == 0) - goto found; - - /* signature in the first block, only small buffer needed */ - if (volume_id_probe_vfat(id, off) == 0) - goto found; - - if (volume_id_probe_xfs(id, off) == 0) - goto found; - - /* fill buffer with maximum */ - volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); - - if (volume_id_probe_linux_swap(id, off) == 0) - goto found; - - if (volume_id_probe_ext(id, off) == 0) - goto found; - - if (volume_id_probe_reiserfs(id, off) == 0) - goto found; - - if (volume_id_probe_jfs(id, off) == 0) - goto found; - - if (volume_id_probe_udf(id, off) == 0) - goto found; - - if (volume_id_probe_iso9660(id, off) == 0) - goto found; - - if (volume_id_probe_hfs_hfsplus(id, off) == 0) - goto found; - - if (volume_id_probe_ufs(id, off) == 0) - goto found; - - if (volume_id_probe_ntfs(id, off) == 0) - goto found; - - if (volume_id_probe_cramfs(id, off) == 0) - goto found; - - if (volume_id_probe_romfs(id, off) == 0) - goto found; - - if (volume_id_probe_hpfs(id, off) == 0) - goto found; - - if (volume_id_probe_sysv(id, off) == 0) - goto found; - - if (volume_id_probe_minix(id, off) == 0) - goto found; - - if (volume_id_probe_ocfs1(id, off) == 0) - goto found; - - if (volume_id_probe_ocfs2(id, off) == 0) - goto found; - - if (volume_id_probe_vxfs(id, off) == 0) - goto found; - - if (volume_id_probe_squashfs(id, off) == 0) - goto found; - - return -1; - -found: - /* If recognized, we free the allocated buffers */ - volume_id_free_buffer(id); - return 0; -} - -int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) -{ - if (id == NULL) - return -EINVAL; - - if (volume_id_probe_raid(id, off, size) == 0) - return 0; - - if (volume_id_probe_filesystem(id, off, size) == 0) - return 0; - - return -1; -} - -/* open volume by already open file descriptor */ -struct volume_id *volume_id_open_fd(int fd) -{ - struct volume_id *id; - - id = malloc(sizeof(struct volume_id)); - if (id == NULL) - return NULL; - memset(id, 0x00, sizeof(struct volume_id)); - - id->fd = fd; - - return id; -} - -/* open volume by device node */ -struct volume_id *volume_id_open_node(const char *path) -{ - struct volume_id *id; - int fd; - - fd = open(path, O_RDONLY); - if (fd < 0) { - dbg("unable to open '%s'", path); - return NULL; - } - - id = volume_id_open_fd(fd); - if (id == NULL) - return NULL; - - /* close fd on device close */ - id->fd_close = 1; - - return id; -} - -void volume_id_close(struct volume_id *id) -{ - if (id == NULL) - return; - - if (id->fd_close != 0) - close(id->fd); - - volume_id_free_buffer(id); - - free(id); -} diff --git a/extras/volume_id/libvolume_id/vxfs.c b/extras/volume_id/libvolume_id/vxfs.c deleted file mode 100644 index d10cc37762..0000000000 --- a/extras/volume_id/libvolume_id/vxfs.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct vxfs_super *vxs; - - dbg("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)) { - snprintf(id->type_version, sizeof(id->type_version)-1, "%u", (unsigned int) vxs->vs_version); - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "vxfs"; - return 0; - } - - return -1; -} diff --git a/extras/volume_id/libvolume_id/xfs.c b/extras/volume_id/libvolume_id/xfs.c deleted file mode 100644 index 3d870c41e7..0000000000 --- a/extras/volume_id/libvolume_id/xfs.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include "libvolume_id.h" -#include "util.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) -{ - struct xfs_super_block *xs; - - dbg("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(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, UUID_DCE); - - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "xfs"; - - return 0; -} diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index b086b3710c..3a7361a6ac 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -31,7 +31,7 @@ #include #include "../../udev.h" -#include "libvolume_id/libvolume_id.h" +#include "lib/libvolume_id.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) -- cgit v1.2.3-54-g00ecf