1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-11 09:18:07 +03:00

delete libvolume_id

This commit is contained in:
Kay Sievers 2009-05-12 13:28:01 +02:00
parent f07996885d
commit 3de63a356f
51 changed files with 6 additions and 6278 deletions

9
NEWS
View File

@ -2,10 +2,11 @@ udev 142
========
Bugfixes.
The program vol_id is removed from the repository and blkid from the
latest util-linux-ng package replaces it. Persisten disk links for
label and uuid depend on the util-linux-ng version of blkid now. Older
versions can not be used with udev.
The program vol_id and the library libvolume_id is removed from the
repository. Libvolume_id is merged with libblkid from the util-linux-ng
package. Persistent disk links for label and uuid depend on the
util-linux-ng version (2.15) of blkid now. Older versions of blkid
can not be used with udev.
Libudev allows to subscribe to udev events. To prevent unwanted messages
to be delivered, and waking up the subscribing process, a filter can be

View File

@ -21,14 +21,6 @@ AC_SUBST(LIBUDEV_LT_CURRENT)
AC_SUBST(LIBUDEV_LT_REVISION)
AC_SUBST(LIBUDEV_LT_AGE)
dnl /* libvolume_id version */
VOLID_LT_CURRENT=2
VOLID_LT_REVISION=0
VOLID_LT_AGE=1
AC_SUBST(VOLID_LT_CURRENT)
AC_SUBST(VOLID_LT_REVISION)
AC_SUBST(VOLID_LT_AGE)
AC_PATH_PROG([XSLTPROC], [xsltproc])
AC_CHECK_LIB(c, inotify_init,
@ -97,9 +89,6 @@ AC_CONFIG_FILES([
extras/rule_generator/Makefile
extras/scsi_id/Makefile
extras/usb_id/Makefile
extras/volume_id/Makefile
extras/volume_id/lib/Makefile
extras/volume_id/lib/libvolume_id.pc
])
AC_OUTPUT

View File

@ -11,5 +11,4 @@ SUBDIRS = \
fstab_import \
rule_generator \
scsi_id \
usb_id \
volume_id
usb_id

View File

@ -1,3 +0,0 @@
vol_id
*.8

View File

@ -1,4 +0,0 @@
include $(top_srcdir)/Makefile.am.inc
SUBDIRS = \
lib

View File

@ -1,2 +0,0 @@
libvolume_id.pc
libvolume_id.so*

View File

@ -1,74 +0,0 @@
include $(top_srcdir)/Makefile.am.inc
rootlibdir = $(exec_prefix)/$(libdir_name)
rootlib_LTLIBRARIES = \
libvolume_id.la
include_HEADERS =\
libvolume_id.h
libvolume_id_la_SOURCES =\
libvolume_id-private.h \
volume_id.c \
util.c \
md5.h \
md5.c \
ext.c \
fat.c \
hfs.c \
highpoint.c \
isw_raid.c \
lsi_raid.c \
via_raid.c \
silicon_raid.c \
nvidia_raid.c \
promise_raid.c \
adaptec_raid.c \
jmicron_raid.c \
ddf_raid.c \
iso9660.c \
jfs.c \
linux_raid.c \
linux_swap.c \
lvm.c \
ntfs.c \
reiserfs.c \
udf.c \
ufs.c \
xfs.c \
cramfs.c \
hpfs.c \
romfs.c \
sysv.c \
minix.c \
gfs.c \
luks.c \
ocfs.c \
vxfs.c \
squashfs.c \
netware.c \
oracleasm.c \
btrfs.c
libvolume_id_la_LDFLAGS = \
-version-info $(VOLID_LT_CURRENT):$(VOLID_LT_REVISION):$(VOLID_LT_AGE) \
-export-symbols $(top_srcdir)/extras/volume_id/lib/exported_symbols
# move devel files to $(prefix)$(libdir_name) if needed
install-data-hook:
rm $(DESTDIR)$(rootlibdir)/libvolume_id.la
if test "$(prefix)" != "$(exec_prefix)"; then \
mkdir -p $(DESTDIR)$(prefix)/$(libdir_name); \
mv $(DESTDIR)$(rootlibdir)/libvolume_id.a $(DESTDIR)$(prefix)/$(libdir_name)/; \
so_img_name=$$(readlink $(DESTDIR)$(rootlibdir)/libvolume_id.so); \
rm $(DESTDIR)$(rootlibdir)/libvolume_id.so; \
so_img_rel_target_prefix=$$(echo $(prefix)/$(libdir_name) | sed 's,\(^/\|\)[^/][^/]*,..,g'); \
ln -sf $$so_img_rel_target_prefix$(exec_prefix)/$(libdir_name)/$$so_img_name \
$(DESTDIR)$(prefix)/$(libdir_name)/libvolume_id.so; \
fi
EXTRA_DIST = \
exported_symbols
pkgconfigdir = $(prefix)/$(libdir_name)/pkgconfig
pkgconfig_DATA = libvolume_id.pc

View File

@ -1,116 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct adaptec_meta {
uint32_t b0idcode;
uint8_t lunsave[8];
uint16_t sdtype;
uint16_t ssavecyl;
uint8_t ssavehed;
uint8_t ssavesec;
uint8_t sb0flags;
uint8_t jbodEnable;
uint8_t lundsave;
uint8_t svpdirty;
uint16_t biosInfo;
uint16_t svwbskip;
uint16_t svwbcln;
uint16_t svwbmax;
uint16_t res3;
uint16_t svwbmin;
uint16_t res4;
uint16_t svrcacth;
uint16_t svwcacth;
uint16_t svwbdly;
uint8_t svsdtime;
uint8_t res5;
uint16_t firmval;
uint16_t firmbln;
uint32_t firmblk;
uint32_t fstrsvrb;
uint16_t svBlockStorageTid;
uint16_t svtid;
uint8_t svseccfl;
uint8_t res6;
uint8_t svhbanum;
uint8_t resver;
uint32_t drivemagic;
uint8_t reserved[20];
uint8_t testnum;
uint8_t testflags;
uint16_t maxErrorCount;
uint32_t count;
uint32_t startTime;
uint32_t interval;
uint8_t tstxt0;
uint8_t tstxt1;
uint8_t serNum[32];
uint8_t res8[102];
uint32_t fwTestMagic;
uint32_t fwTestSeqNum;
uint8_t fwTestRes[8];
uint8_t smagic[4];
uint32_t raidtbl;
uint16_t raidline;
uint8_t res9[0xF6];
} PACKED;
int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct adaptec_meta *ad;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
if (size < 0x10000)
return -1;
meta_off = ((size / 0x200)-1) * 0x200;
buf = volume_id_get_buffer(id, off + meta_off, 0x200);
if (buf == NULL)
return -1;
ad = (struct adaptec_meta *) buf;
if (memcmp(ad->smagic, "DPTM", 4) != 0)
return -1;
if (ad->b0idcode != be32_to_cpu(0x37FC4D1E))
return -1;
volume_id_set_usage(id, VOLUME_ID_RAID);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u", ad->resver);
id->type = "adaptec_raid_member";
return 0;
}

View File

@ -1,102 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <byteswap.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct btrfs_super_block {
uint8_t csum[32];
uint8_t fsid[16];
uint64_t bytenr;
uint64_t flags;
uint8_t magic[8];
uint64_t generation;
uint64_t root;
uint64_t chunk_root;
uint64_t log_root;
uint64_t log_root_transid;
uint64_t total_bytes;
uint64_t bytes_used;
uint64_t root_dir_objectid;
uint64_t num_devices;
uint32_t sectorsize;
uint32_t nodesize;
uint32_t leafsize;
uint32_t stripesize;
uint32_t sys_chunk_array_size;
uint64_t chunk_root_generation;
uint64_t compat_flags;
uint64_t compat_ro_flags;
uint64_t incompat_flags;
uint16_t csum_type;
uint8_t root_level;
uint8_t chunk_root_level;
uint8_t log_root_level;
struct btrfs_dev_item {
uint64_t devid;
uint64_t total_bytes;
uint64_t bytes_used;
uint32_t io_align;
uint32_t io_width;
uint32_t sector_size;
uint64_t type;
uint64_t generation;
uint64_t start_offset;
uint32_t dev_group;
uint8_t seek_speed;
uint8_t bandwidth;
uint8_t uuid[16];
uint8_t fsid[16];
} PACKED dev_item;
uint8_t label[256];
} PACKED;
int volume_id_probe_btrfs(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct btrfs_super_block *bfs;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
buf = volume_id_get_buffer(id, off + 0x10000, 0x200);
if (buf == NULL)
return -1;
bfs = (struct btrfs_super_block *)buf;
if (memcmp(bfs->magic, "_BHRfS_M", 8) != 0)
return -1;
volume_id_set_uuid(id, bfs->fsid, 0, UUID_DCE);
volume_id_set_uuid_sub(id, bfs->dev_item.uuid, 0, UUID_DCE);
volume_id_set_label_raw(id, bfs->label, 256);
volume_id_set_label_string(id, bfs->label, 256);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "btrfs";
return 0;
}

View File

@ -1,69 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct cramfs_super {
uint8_t magic[4];
uint32_t size;
uint32_t flags;
uint32_t future;
uint8_t signature[16];
struct cramfs_info {
uint32_t crc;
uint32_t edition;
uint32_t blocks;
uint32_t files;
} PACKED info;
uint8_t name[16];
} PACKED;
int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct cramfs_super *cs;
info("probing at offset 0x%" PRIx64 "\n", 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;
}

View File

@ -1,94 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2007 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <byteswap.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
/* http://www.snia.org/standards/home */
#define DDF_GUID_LENGTH 24
#define DDF_REV_LENGTH 8
struct ddf_header {
uint8_t signature[4];
uint32_t crc;
uint8_t guid[DDF_GUID_LENGTH];
uint8_t ddf_rev[DDF_REV_LENGTH];
} PACKED;
int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
uint64_t ddf_off;
const uint8_t *buf;
struct ddf_header *ddf;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
if (size < 0x30000)
return -1;
/* header at last sector */
ddf_off = ((size / 0x200)-1) * 0x200;
buf = volume_id_get_buffer(id, off + ddf_off, 0x200);
if (buf == NULL)
return -1;
ddf = (struct ddf_header *) buf;
if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0) {
info("header (little endian) found at %" PRIu64 "\n", (off + ddf_off));
goto found;
}
if (memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0) {
info("header (big endian) found at %" PRIu64 "\n", (off + ddf_off));
goto found;
}
/* adaptec non-standard header location */
ddf_off = ((size / 0x200)-257) * 0x200;
buf = volume_id_get_buffer(id, off + ddf_off, 0x200);
if (buf == NULL)
return -1;
ddf = (struct ddf_header *) buf;
if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0) {
info("header adaptec (little endian) found at %" PRIu64 "\n", (off + ddf_off));
goto found;
}
if (memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0) {
info("header adaptec (big endian) found at %" PRIu64 "\n", (off + ddf_off));
goto found;
}
return -1;
found:
volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING);
snprintf(id->type_version, DDF_REV_LENGTH + 1, "%s", ddf->ddf_rev);
volume_id_set_usage(id, VOLUME_ID_RAID);
id->type = "ddf_raid_member";
return 0;
}

View File

@ -1,17 +0,0 @@
volume_id_log_fn
volume_id_get_label
volume_id_get_label_raw
volume_id_get_uuid
volume_id_get_uuid_raw
volume_id_get_uuid_sub
volume_id_get_usage
volume_id_get_type
volume_id_get_type_version
volume_id_open_fd
volume_id_close
volume_id_probe_all
volume_id_probe_filesystem
volume_id_probe_raid
volume_id_all_probers
volume_id_get_prober_by_type
volume_id_encode_string

View File

@ -1,203 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2008 Theodore Ts'o <tytso@mit.edu>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.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];
uint8_t s_last_mounted[64];
uint32_t s_algorithm_usage_bitmap;
uint8_t s_prealloc_blocks;
uint8_t s_prealloc_dir_blocks;
uint16_t s_reserved_gdt_blocks;
uint8_t s_journal_uuid[16];
uint32_t s_journal_inum;
uint32_t s_journal_dev;
uint32_t s_last_orphan;
uint32_t s_hash_seed[4];
uint8_t s_def_hash_version;
uint8_t s_jnl_backup_type;
uint16_t s_reserved_word_pad;
uint32_t s_default_mount_opts;
uint32_t s_first_meta_bg;
uint32_t s_mkfs_time;
uint32_t s_jnl_blocks[17];
uint32_t s_blocks_count_hi;
uint32_t s_r_blocks_count_hi;
uint32_t s_free_blocks_hi;
uint16_t s_min_extra_isize;
uint16_t s_want_extra_isize;
uint32_t s_flags;
} PACKED;
#define EXT_SUPER_MAGIC 0xEF53
#define EXT2_FLAGS_TEST_FILESYS 0x0004
#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
EXT2_FEATURE_INCOMPAT_META_BG)
#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP
#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP
#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
EXT3_FEATURE_INCOMPAT_RECOVER| \
EXT2_FEATURE_INCOMPAT_META_BG)
#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~EXT3_FEATURE_INCOMPAT_SUPP
#define EXT_SUPERBLOCK_OFFSET 0x400
#define EXT3_MIN_BLOCK_SIZE 0x400
#define EXT3_MAX_BLOCK_SIZE 0x1000
int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size)
{
struct ext2_super_block *es;
size_t bsize;
uint32_t feature_compat;
uint32_t feature_ro_compat;
uint32_t feature_incompat;
uint32_t flags;
info("probing at offset 0x%" PRIx64 "\n", 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\n", bsize);
if (bsize < EXT3_MIN_BLOCK_SIZE || bsize > EXT3_MAX_BLOCK_SIZE) {
dbg("invalid ext blocksize\n");
return -1;
}
feature_compat = le32_to_cpu(es->s_feature_compat);
feature_ro_compat = le32_to_cpu(es->s_feature_ro_compat);
feature_incompat = le32_to_cpu(es->s_feature_incompat);
flags = le32_to_cpu(es->s_flags);
/* external journal device is jbd */
if ((feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) {
volume_id_set_usage(id, VOLUME_ID_OTHER);
id->type = "jbd";
goto found;
}
/* has journal */
if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) {
/* "use on development code" is ext4dev */
if ((flags & EXT2_FLAGS_TEST_FILESYS) != 0) {
id->type = "ext4dev";
goto found;
}
/* incompatible ext3 features is ext4 */
if ((feature_ro_compat & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) != 0 ||
(feature_incompat & EXT3_FEATURE_INCOMPAT_UNSUPPORTED) != 0) {
id->type = "ext4";
goto found;
}
id->type = "ext3";
goto found;
} else {
/* no incompatible ext2 feature is ext2 */
if ((feature_ro_compat & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) == 0 &&
(feature_incompat & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0) {
id->type = "ext2";
goto found;
}
}
return -1;
found:
volume_id_set_label_raw(id, es->s_volume_name, 16);
volume_id_set_label_string(id, es->s_volume_name, 16);
volume_id_set_uuid(id, es->s_uuid, 0, UUID_DCE);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u",
le32_to_cpu(es->s_rev_level), le16_to_cpu(es->s_minor_rev_level));
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
return 0;
}

View File

@ -1,509 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004-2007 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2007 Ryan Lortie <desrt@desrt.ca>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define FAT12_MAX 0xff5
#define FAT16_MAX 0xfff5
#define FAT_ATTR_VOLUME_ID 0x08
#define FAT_ATTR_DIR 0x10
#define FAT_ATTR_LONG_NAME 0x0f
#define FAT_ATTR_MASK 0x3f
#define FAT_ENTRY_FREE 0xe5
#define VFAT_LFN_SEQ_MASK 0x3f
#define VFAT_LFN_SEQ_LAST 0x40
#define VFAT_LFN_SEQ_MAX 20
#define VFAT_LFN_CHARS_PER_ENTRY (5 + 6 + 2)
#define VFAT_LOWERCASE_NAME 0x10
#define VFAT_LOWERCASE_EXT 0x08
struct vfat_super_block {
uint8_t boot_jump[3];
uint8_t sysid[8];
uint16_t sector_size;
uint8_t sectors_per_cluster;
uint16_t reserved;
uint8_t fats;
uint16_t dir_entries;
uint16_t sectors;
uint8_t media;
uint16_t fat_length;
uint16_t secs_track;
uint16_t heads;
uint32_t hidden;
uint32_t total_sect;
union {
struct fat_super_block {
uint8_t unknown[3];
uint8_t serno[4];
uint8_t label[11];
uint8_t magic[8];
uint8_t dummy2[192];
uint8_t pmagic[2];
} PACKED fat;
struct fat32_super_block {
uint32_t fat32_length;
uint16_t flags;
uint8_t version[2];
uint32_t root_cluster;
uint16_t fsinfo_sector;
uint16_t backup_boot;
uint16_t reserved2[6];
uint8_t unknown[3];
uint8_t serno[4];
uint8_t label[11];
uint8_t magic[8];
uint8_t dummy2[164];
uint8_t pmagic[2];
} PACKED fat32;
} PACKED type;
} PACKED;
struct fat32_fsinfo {
uint8_t signature1[4];
uint32_t reserved1[120];
uint8_t signature2[4];
uint32_t free_clusters;
uint32_t next_cluster;
uint32_t reserved2[4];
} PACKED;
struct vfat_dir_entry {
uint8_t name[11];
uint8_t attr;
uint8_t lowercase;
uint8_t fine_time_creat;
uint16_t time_creat;
uint16_t date_creat;
uint16_t date_acc;
uint16_t cluster_high;
uint16_t time_write;
uint16_t date_write;
uint16_t cluster_low;
uint32_t size;
} PACKED;
struct vfat_lfn_entry {
uint8_t seq;
uint16_t name0[5];
uint8_t attr;
uint8_t reserved;
uint8_t cksum;
uint16_t name1[6];
uint16_t cluster;
uint16_t name2[2];
} PACKED;
static uint8_t fat_lfn_checksum(const uint8_t name[11])
{
uint8_t cksum = 0;
int i;
/* http://en.wikipedia.org/wiki/File_Allocation_Table */
for (i = 0; i < 11; i++)
cksum = ((cksum & 1) ? 0x80 : 0) + (cksum >> 1) + name[i];
return cksum;
}
static size_t fat_read_lfn(uint8_t *filename, size_t fnsize,
struct vfat_dir_entry *dir,
struct vfat_dir_entry *entry)
{
uint8_t buffer[VFAT_LFN_SEQ_MAX * VFAT_LFN_CHARS_PER_ENTRY * 2];
uint8_t expected_seq = 1;
uint8_t cksum;
size_t len = 0;
size_t fnlen = 0;
cksum = fat_lfn_checksum(entry->name);
while (--entry >= dir) {
struct vfat_lfn_entry *lfn = (struct vfat_lfn_entry *) entry;
if (expected_seq > VFAT_LFN_SEQ_MAX)
break;
if ((lfn->attr & FAT_ATTR_MASK) != FAT_ATTR_LONG_NAME)
break;
if (lfn->cksum != cksum)
break;
if ((lfn->seq & VFAT_LFN_SEQ_MASK) != expected_seq++)
break;
if (lfn->cluster != 0)
break;
/* extra paranoia -- should never happen */
if (len + sizeof(lfn->name0) + sizeof(lfn->name1) +
sizeof(lfn->name2) > sizeof(buffer))
break;
memcpy (&buffer[len], lfn->name0, sizeof(lfn->name0));
len += sizeof(lfn->name0);
memcpy (&buffer[len], lfn->name1, sizeof(lfn->name1));
len += sizeof(lfn->name1);
memcpy (&buffer[len], lfn->name2, sizeof(lfn->name2));
len += sizeof(lfn->name2);
if (lfn->seq & VFAT_LFN_SEQ_LAST) {
fnlen = volume_id_set_unicode16(filename, fnsize, buffer, LE, len);
break;
}
}
return fnlen;
}
static size_t fat_read_filename(uint8_t *filename, size_t fnsize,
struct vfat_dir_entry *dir, struct vfat_dir_entry *entry)
{
size_t len;
int i;
/* check if maybe we have LFN entries */
len = fat_read_lfn(filename, fnsize, dir, entry);
if (len > 0)
goto out;
/* else, read the normal 8.3 name */
for (i = 0; i < 11; i++) {
if (entry->lowercase & ((i < 8) ? VFAT_LOWERCASE_NAME : VFAT_LOWERCASE_EXT))
filename[i] = tolower(entry->name[i]);
else
filename[i] = entry->name[i];
}
len = 11;
out:
filename[len] = '\0';
return len;
}
/* fills filename, returns string length */
static size_t get_fat_attr_volume_id(uint8_t *filename, size_t fnsize,
struct vfat_dir_entry *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\n");
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\n");
return fat_read_filename(filename, fnsize, dir, &dir[i]);
}
dbg("skip dir entry\n");
}
return 0;
}
int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size)
{
uint8_t filename[255 * 3];
struct vfat_super_block *vs;
struct vfat_dir_entry *dir;
struct fat32_fsinfo *fsinfo;
uint16_t sector_size;
uint16_t dir_entries;
uint32_t sect_count;
uint16_t reserved;
uint32_t fat_size;
uint32_t root_cluster;
uint32_t dir_size;
uint32_t cluster_count;
uint16_t fat_length;
uint32_t fat32_length;
uint64_t root_start;
uint32_t start_data_sect;
uint16_t root_dir_entries;
uint16_t fsinfo_sect;
uint8_t *buf;
uint32_t buf_size;
uint32_t next;
int maxloop;
size_t fnlen;
info("probing at offset 0x%" PRIx64 "\n", off);
buf = volume_id_get_buffer(id, off, 0x400);
if (buf == NULL)
return -1;
vs = (struct vfat_super_block *) buf;
if (memcmp(vs->sysid, "NTFS", 4) == 0)
return -1;
/* believe only that's fat, don't trust the version */
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;
/* check signature */
if (buf[510] != 0x55 || buf[511] != 0xaa)
return -1;
/* some old floppies don't have a magic, expect the boot jump address to match */
if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) &&
vs->boot_jump[0] != 0xe9)
return -1;
magic:
info("magic found\n");
/* reserverd sector count */
if (!vs->reserved)
return -1;
/* fat count */
if (!vs->fats)
return -1;
/* media check */
if (vs->media < 0xf8 && vs->media != 0xf0)
return -1;
/* cluster size check */
if (vs->sectors_per_cluster == 0 ||
(vs->sectors_per_cluster & (vs->sectors_per_cluster-1)))
return -1;
/* sector size check */
sector_size = le16_to_cpu(vs->sector_size);
if (sector_size == 0 || ((sector_size & (sector_size-1)) != 0))
return -1;
info("checks passed\n");
dbg("sector_size 0x%x\n", sector_size);
dbg("sectors_per_cluster 0x%x\n", vs->sectors_per_cluster);
dir_entries = le16_to_cpu(vs->dir_entries);
reserved = le16_to_cpu(vs->reserved);
dbg("reserved 0x%x\n", 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\n", sect_count);
fat_length = le16_to_cpu(vs->fat_length);
info("fat_length 0x%x\n", fat_length);
fat32_length = le32_to_cpu(vs->type.fat32.fat32_length);
info("fat32_length 0x%x\n", fat32_length);
if (fat_length)
fat_size = fat_length * vs->fats;
else if (fat32_length)
fat_size = fat32_length * vs->fats;
else
return -1;
info("fat_size 0x%x\n", fat_size);
dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
(sector_size-1)) / sector_size;
info("dir_size 0x%x\n", dir_size);
cluster_count = sect_count - (reserved + fat_size + dir_size);
cluster_count /= vs->sectors_per_cluster;
info("cluster_count 0x%x\n", 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%" PRIx64 "\n", root_start);
root_dir_entries = le16_to_cpu(vs->dir_entries);
dbg("expected entries 0x%x\n", 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;
fnlen = get_fat_attr_volume_id(filename, sizeof(filename), dir, root_dir_entries);
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
if (vs == NULL)
return -1;
if (fnlen > 0 && memcmp(filename, "NO NAME ", 11) != 0) {
volume_id_set_label_raw(id, filename, fnlen);
volume_id_set_label_string(id, filename, fnlen);
} 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, 0, UUID_DOS);
goto found;
fat32:
info("looking for FAT32\n");
/*
* FAT32 should have a valid signature in the fsinfo block,
* but also allow all bytes set to '\0', because some volumes
* do not set the signature at all.
*/
fsinfo_sect = le16_to_cpu(vs->type.fat32.fsinfo_sector);
buf = volume_id_get_buffer(id, off + (fsinfo_sect * sector_size), 0x200);
if (buf == NULL)
return -1;
fsinfo = (struct fat32_fsinfo *) buf;
info("signature1: 0x%02x%02x%02x%02x\n",
fsinfo->signature1[0], fsinfo->signature1[1],
fsinfo->signature1[2], fsinfo->signature1[3]);
info("signature2: 0x%02x%02x%02x%02x\n",
fsinfo->signature2[0], fsinfo->signature2[1],
fsinfo->signature2[2], fsinfo->signature2[3]);
if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0 &&
memcmp(fsinfo->signature1, "\x00\x00\x00\x00", 4) != 0)
return -1;
if (memcmp(fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0 &&
memcmp(fsinfo->signature2, "\x00\x00\x00\x00", 4) != 0)
return -1 ;
info("FAT32 signatures ok\n");
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
if (vs == NULL)
return -1;
strcpy(id->type_version, "FAT32");
/* FAT32 root dir is a cluster chain like any other directory */
buf_size = vs->sectors_per_cluster * sector_size;
root_cluster = le32_to_cpu(vs->type.fat32.root_cluster);
dbg("root dir cluster %u\n", 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\n", next);
next_sect_off = (next - 2) * vs->sectors_per_cluster;
next_off = (start_data_sect + next_sect_off) * sector_size;
dbg("cluster offset 0x%" PRIx64 "\n", 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\n", count);
fnlen = get_fat_attr_volume_id(filename, sizeof(filename), dir, count);
if (fnlen > 0)
break;
/* get FAT entry */
fat_entry_off = (reserved * sector_size) + (next * sizeof(uint32_t));
buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size);
if (buf == NULL)
goto found;
/* set next cluster */
next = le32_to_cpu(*((uint32_t *) buf)) & 0x0fffffff;
if (next < 2 || next >= 0x0ffffff0)
break;
}
if (maxloop == 0)
dbg("reached maximum follow count of root cluster chain, give up\n");
vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200);
if (vs == NULL)
return -1;
if (fnlen > 0 && memcmp(filename, "NO NAME ", 11) != 0) {
volume_id_set_label_raw(id, filename, fnlen);
volume_id_set_label_string(id, filename, fnlen);
} 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, 0, UUID_DOS);
found:
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "vfat";
/* we think this is fat, but we make sure no other signatures are found */
id->force_unique_result = 1;
return 0;
}

View File

@ -1,146 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2006 Red Hat, Inc. <redhat.com>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
/* Common gfs/gfs2 constants: */
#define GFS_MAGIC 0x01161970
#define GFS_DEFAULT_BSIZE 4096
#define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE)
#define GFS_METATYPE_SB 1
#define GFS_FORMAT_SB 100
#define GFS_LOCKNAME_LEN 64
/* gfs1 constants: */
#define GFS_FORMAT_FS 1309
#define GFS_FORMAT_MULTI 1401
/* gfs2 constants: */
#define GFS2_FORMAT_FS 1801
#define GFS2_FORMAT_MULTI 1900
struct gfs2_meta_header {
uint32_t mh_magic;
uint32_t mh_type;
uint64_t __pad0; /* Was generation number in gfs1 */
uint32_t mh_format;
uint32_t __pad1; /* Was incarnation number in gfs1 */
};
struct gfs2_inum {
uint64_t no_formal_ino;
uint64_t no_addr;
};
struct gfs2_sb {
struct gfs2_meta_header sb_header;
uint32_t sb_fs_format;
uint32_t sb_multihost_format;
uint32_t __pad0; /* Was superblock flags in gfs1 */
uint32_t sb_bsize;
uint32_t sb_bsize_shift;
uint32_t __pad1; /* Was journal segment size in gfs1 */
struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */
struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */
struct gfs2_inum sb_root_dir;
char sb_lockproto[GFS_LOCKNAME_LEN];
char sb_locktable[GFS_LOCKNAME_LEN];
struct gfs2_inum __pad3; /* Was quota inode in gfs1 */
struct gfs2_inum __pad4; /* Was licence inode in gfs1 */
uint8_t sb_uuid[16]; /* The UUID maybe 0 for backwards compat */
} PACKED;
static int uuid_non_zero(const uint8_t *p)
{
int i;
for (i = 0; i < 16; i++) {
if (p[i] != 0)
return 1;
}
return 0;
}
static int volume_id_probe_gfs_generic(struct volume_id *id, uint64_t off, int vers)
{
struct gfs2_sb *sbd;
info("probing at offset 0x%" PRIx64 "\n", off);
sbd = (struct gfs2_sb *)
volume_id_get_buffer(id, off + GFS_SUPERBLOCK_OFFSET, sizeof(struct gfs2_sb));
if (sbd == NULL)
return -1;
if (be32_to_cpu(sbd->sb_header.mh_magic) == GFS_MAGIC &&
be32_to_cpu(sbd->sb_header.mh_type) == GFS_METATYPE_SB) {
if (vers == 1) {
if (be32_to_cpu(sbd->sb_fs_format) != GFS_FORMAT_FS ||
be32_to_cpu(sbd->sb_multihost_format) != GFS_FORMAT_MULTI)
return -1; /* not gfs1 */
id->type = "gfs";
}
else if (vers == 2) {
if (be32_to_cpu(sbd->sb_fs_format) != GFS2_FORMAT_FS ||
be32_to_cpu(sbd->sb_multihost_format) != GFS2_FORMAT_MULTI)
return -1; /* not gfs2 */
id->type = "gfs2";
}
else
return -1;
if (strlen(sbd->sb_locktable)) {
uint8_t *label = (uint8_t *) sbd->sb_locktable;
volume_id_set_label_raw(id, label, GFS_LOCKNAME_LEN);
volume_id_set_label_string(id, label, GFS_LOCKNAME_LEN);
}
if (vers == 2 && uuid_non_zero(sbd->sb_uuid))
volume_id_set_uuid(id, sbd->sb_uuid, 0, UUID_DCE);
strcpy(id->type_version, "1");
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
return 0;
}
return -1;
}
int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size)
{
return volume_id_probe_gfs_generic(id, off, 1);
}
int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size)
{
return volume_id_probe_gfs_generic(id, off, 2);
}

View File

@ -1,325 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#include "md5.h"
struct hfs_finder_info{
uint32_t boot_folder;
uint32_t start_app;
uint32_t open_folder;
uint32_t os9_folder;
uint32_t reserved;
uint32_t osx_folder;
uint8_t id[8];
} PACKED;
static struct hfs_mdb {
uint8_t signature[2];
uint32_t cr_date;
uint32_t ls_Mod;
uint16_t atrb;
uint16_t nm_fls;
uint16_t vbm_st;
uint16_t alloc_ptr;
uint16_t nm_al_blks;
uint32_t al_blk_size;
uint32_t clp_size;
uint16_t al_bl_st;
uint32_t nxt_cnid;
uint16_t free_bks;
uint8_t label_len;
uint8_t label[27];
uint32_t vol_bkup;
uint16_t vol_seq_num;
uint32_t wr_cnt;
uint32_t xt_clump_size;
uint32_t ct_clump_size;
uint16_t num_root_dirs;
uint32_t file_count;
uint32_t dir_count;
struct hfs_finder_info finder_info;
uint8_t embed_sig[2];
uint16_t embed_startblock;
uint16_t embed_blockcount;
} PACKED *hfs;
struct hfsplus_bnode_descriptor {
uint32_t next;
uint32_t prev;
uint8_t type;
uint8_t height;
uint16_t num_recs;
uint16_t reserved;
} PACKED;
struct hfsplus_bheader_record {
uint16_t depth;
uint32_t root;
uint32_t leaf_count;
uint32_t leaf_head;
uint32_t leaf_tail;
uint16_t node_size;
} PACKED;
struct hfsplus_catalog_key {
uint16_t key_len;
uint32_t parent_id;
uint16_t unicode_len;
uint8_t unicode[255 * 2];
} PACKED;
struct hfsplus_extent {
uint32_t start_block;
uint32_t block_count;
} PACKED;
#define HFSPLUS_EXTENT_COUNT 8
struct hfsplus_fork {
uint64_t total_size;
uint32_t clump_size;
uint32_t total_blocks;
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
} PACKED;
static struct hfsplus_vol_header {
uint8_t signature[2];
uint16_t version;
uint32_t attributes;
uint32_t last_mount_vers;
uint32_t reserved;
uint32_t create_date;
uint32_t modify_date;
uint32_t backup_date;
uint32_t checked_date;
uint32_t file_count;
uint32_t folder_count;
uint32_t blocksize;
uint32_t total_blocks;
uint32_t free_blocks;
uint32_t next_alloc;
uint32_t rsrc_clump_sz;
uint32_t data_clump_sz;
uint32_t next_cnid;
uint32_t write_count;
uint64_t encodings_bmp;
struct hfs_finder_info finder_info;
struct hfsplus_fork alloc_file;
struct hfsplus_fork ext_file;
struct hfsplus_fork cat_file;
struct hfsplus_fork attr_file;
struct hfsplus_fork start_file;
} PACKED *hfsplus;
#define HFS_SUPERBLOCK_OFFSET 0x400
#define HFS_NODE_LEAF 0xff
#define HFSPLUS_POR_CNID 1
static void hfsid_set_uuid(struct volume_id *id, const uint8_t *hfs_id)
{
struct md5_ctx md5c;
static const uint8_t hash_init[16] = {
0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6,
0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
uint8_t uuid[16];
if (*((uint64_t *)hfs_id) == 0)
return;
md5_init(&md5c);
md5_update(&md5c, hash_init, 16);
md5_update(&md5c, hfs_id, 8);
md5_final(&md5c, uuid);
uuid[6] = 0x30 | (uuid[6] & 0x0f);
uuid[8] = 0x80 | (uuid[8] & 0x3f);
volume_id_set_uuid(id, uuid, 0, UUID_DCE);
}
int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size)
{
unsigned int blocksize;
unsigned int cat_block;
unsigned int ext_block_start;
unsigned int ext_block_count;
int ext;
unsigned int leaf_node_head;
unsigned int leaf_node_count;
unsigned int leaf_node_size;
unsigned int leaf_block;
uint64_t leaf_off;
unsigned int alloc_block_size;
unsigned int alloc_first_block;
unsigned int embed_first_block;
unsigned int record_count;
struct hfsplus_bnode_descriptor *descr;
struct hfsplus_bheader_record *bnode;
struct hfsplus_catalog_key *key;
unsigned int label_len;
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
const uint8_t *buf;
info("probing at offset 0x%" PRIx64 "\n", 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\n", alloc_block_size);
alloc_first_block = be16_to_cpu(hfs->al_bl_st);
dbg("alloc_first_block 0x%x\n", alloc_first_block);
embed_first_block = be16_to_cpu(hfs->embed_startblock);
dbg("embed_first_block 0x%x\n", embed_first_block);
off += (alloc_first_block * 512) +
(embed_first_block * alloc_block_size);
dbg("hfs wrapped hfs+ found at offset 0x%" PRIx64 "\n", off);
buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200);
if (buf == NULL)
return -1;
goto checkplus;
}
if (hfs->label_len > 0 && hfs->label_len < 28) {
volume_id_set_label_raw(id, hfs->label, hfs->label_len);
volume_id_set_label_string(id, hfs->label, hfs->label_len) ;
}
hfsid_set_uuid(id, hfs->finder_info.id);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "hfs";
return 0;
checkplus:
hfsplus = (struct hfsplus_vol_header *) buf;
if (memcmp(hfsplus->signature, "H+", 2) == 0)
goto hfsplus;
if (memcmp(hfsplus->signature, "HX", 2) == 0)
goto hfsplus;
return -1;
hfsplus:
hfsid_set_uuid(id, hfsplus->finder_info.id);
blocksize = be32_to_cpu(hfsplus->blocksize);
dbg("blocksize %u\n", blocksize);
memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
cat_block = be32_to_cpu(extents[0].start_block);
dbg("catalog start block 0x%x\n", 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\n", leaf_node_head);
leaf_node_size = be16_to_cpu(bnode->node_size);
dbg("leaf node size 0x%x\n", leaf_node_size);
leaf_node_count = be32_to_cpu(bnode->leaf_count);
dbg("leaf node count 0x%x\n", 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\n", 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\n", 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\n", descr->type);
record_count = be16_to_cpu(descr->num_recs);
dbg("number of records %u\n", 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\n", 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\n", 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;
}

View File

@ -1,100 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct hpt37x_meta {
uint8_t filler1[32];
uint32_t magic;
} PACKED;
struct hpt45x_meta {
uint32_t magic;
} PACKED;
#define HPT37X_CONFIG_OFF 0x1200
#define HPT37X_MAGIC_OK 0x5a7816f0
#define HPT37X_MAGIC_BAD 0x5a7816fd
#define HPT45X_MAGIC_OK 0x5a7816f3
#define HPT45X_MAGIC_BAD 0x5a7816fd
int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct hpt37x_meta *hpt;
uint32_t magic;
info("probing at offset 0x%" PRIx64 "\n", 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%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,116 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct hpfs_boot_block
{
uint8_t jmp[3];
uint8_t oem_id[8];
uint8_t bytes_per_sector[2];
uint8_t sectors_per_cluster;
uint8_t n_reserved_sectors[2];
uint8_t n_fats;
uint8_t n_rootdir_entries[2];
uint8_t n_sectors_s[2];
uint8_t media_byte;
uint16_t sectors_per_fat;
uint16_t sectors_per_track;
uint16_t heads_per_cyl;
uint32_t n_hidden_sectors;
uint32_t n_sectors_l;
uint8_t drive_number;
uint8_t mbz;
uint8_t sig_28h;
uint8_t vol_serno[4];
uint8_t vol_label[11];
uint8_t sig_hpfs[8];
uint8_t pad[448];
uint8_t magic[2];
} PACKED;
struct hpfs_super
{
uint8_t magic[4];
uint8_t magic1[4];
uint8_t version;
} PACKED;
struct hpfs_spare_super
{
uint8_t magic[4];
uint8_t magic1[4];
} PACKED;
#define HPFS_SUPERBLOCK_OFFSET 0x2000
#define HPFS_SUPERBLOCK_SPARE_OFFSET 0x2200
int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct hpfs_super *hs;
struct hpfs_spare_super *hss;
struct hpfs_boot_block *hbb;
uint8_t version;
info("probing at offset 0x%" PRIx64 "\n", off);
hs = (struct hpfs_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_OFFSET, 0x400);
if (hs == NULL)
return -1;
if (memcmp(hs->magic, "\x49\xe8\x95\xf9", 4) != 0)
return -1;
hss = (struct hpfs_spare_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_SPARE_OFFSET, 0x200);
if (hss == NULL)
return -1;
if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
return -1;
version = hs->version;
/* if boot block looks valid, read label and uuid from there */
hbb = (struct hpfs_boot_block *) volume_id_get_buffer(id, off, 0x200);
if (hbb == NULL)
return -1;
if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
hbb->sig_28h == 0x28) {
volume_id_set_label_raw(id, hbb->vol_label, 11);
volume_id_set_label_string(id, hbb->vol_label, 11);
volume_id_set_uuid(id, hbb->vol_serno, 0, UUID_DOS);
}
sprintf(id->type_version, "%u", version);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "hpfs";
return 0;
}

View File

@ -1,129 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define ISO_SUPERBLOCK_OFFSET 0x8000
#define ISO_SECTOR_SIZE 0x800
#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
#define ISO_VD_PRIMARY 0x1
#define ISO_VD_SUPPLEMENTARY 0x2
#define ISO_VD_END 0xff
#define ISO_VD_MAX 16
struct iso_volume_descriptor {
uint8_t type;
uint8_t id[5];
uint8_t version;
uint8_t flags;
uint8_t system_id[32];
uint8_t volume_id[32];
uint8_t unused[8];
uint8_t space_size[8];
uint8_t escape_sequences[8];
} PACKED;
struct high_sierra_volume_descriptor {
uint8_t foo[8];
uint8_t type;
uint8_t id[5];
uint8_t version;
} PACKED;
int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size)
{
uint8_t *buf;
struct iso_volume_descriptor *is;
struct high_sierra_volume_descriptor *hs;
info("probing at offset 0x%" PRIx64 "\n", 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->id, "CD001", 5) == 0) {
int vd_offset;
int i;
dbg("read label from PVD\n");
volume_id_set_label_raw(id, is->volume_id, 32);
volume_id_set_label_string(id, is->volume_id, 32);
dbg("looking for SVDs\n");
vd_offset = ISO_VD_OFFSET;
for (i = 0; i < ISO_VD_MAX; i++) {
uint8_t svd_label[64];
is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200);
if (is == NULL || is->type == ISO_VD_END)
break;
if (is->type != ISO_VD_SUPPLEMENTARY)
continue;
dbg("found SVD at offset 0x%" PRIx64 "\n", (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\n");
volume_id_set_unicode16(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\n");
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;
}

View File

@ -1,70 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct isw_meta {
uint8_t sig[32];
uint32_t check_sum;
uint32_t mpb_size;
uint32_t family_num;
uint32_t generation_num;
} PACKED;
#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. "
int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct isw_meta *isw;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,70 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct jfs_super_block {
uint8_t magic[4];
uint32_t version;
uint64_t size;
uint32_t bsize;
uint32_t dummy1;
uint32_t pbsize;
uint32_t dummy2[27];
uint8_t uuid[16];
uint8_t label[16];
uint8_t loguuid[16];
} PACKED;
#define JFS_SUPERBLOCK_OFFSET 0x8000
int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct jfs_super_block *js;
info("probing at offset 0x%" PRIx64 "\n", 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, 0, UUID_DCE);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "jfs";
return 0;
}

View File

@ -1,66 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct jmicron_meta {
int8_t signature[2];
uint8_t minor_version;
uint8_t major_version;
uint16_t checksum;
} PACKED;
int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct jmicron_meta *jm;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
if (size < 0x10000)
return -1;
meta_off = ((size / 0x200)-1) * 0x200;
buf = volume_id_get_buffer(id, off + meta_off, 0x200);
if (buf == NULL)
return -1;
jm = (struct jmicron_meta *) buf;
if (memcmp(jm->signature, "JM", 2) != 0)
return -1;
volume_id_set_usage(id, VOLUME_ID_RAID);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", jm->major_version, jm->minor_version);
id->type = "jmicron_raid_member";
return 0;
}

View File

@ -1,187 +0,0 @@
/*
* volume_id - reads volume label and uuid
*
* Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBVOLUME_ID_PRIVATE_H_
#define _LIBVOLUME_ID_PRIVATE_H_
#include <stddef.h>
#include <endian.h>
#include <stdint.h>
#include <inttypes.h>
#include <byteswap.h>
#include <syslog.h>
#include "libvolume_id.h"
#define ALLOWED_CHARS "#+-.:=@_"
#ifndef PACKED
#define PACKED __attribute__((packed))
#endif
static inline void __attribute__ ((format(printf, 1, 2)))
log_null(const char *format, ...) {}
#define err(format, arg...) volume_id_log_fn(LOG_ERR, __FILE__, __LINE__, format, ##arg)
#define info(format, arg...) volume_id_log_fn(LOG_INFO, __FILE__, __LINE__, format, ##arg)
#ifdef DEBUG
#define dbg(format, arg...) volume_id_log_fn(LOG_DEBUG, __FILE__, __LINE__, format, ##arg)
#else
#define dbg(format, arg...) log_null(format, ##arg)
#endif
#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 /* __BYTE_ORDER */
enum uuid_format {
UUID_STRING,
UUID_HEX_STRING,
UUID_DCE,
UUID_DOS,
UUID_64BIT_LE,
UUID_MD,
UUID_LVM,
};
enum endian {
LE = 0,
BE = 1
};
#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
/* 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
enum volume_id_usage {
VOLUME_ID_UNUSED,
VOLUME_ID_OTHER,
VOLUME_ID_FILESYSTEM,
VOLUME_ID_RAID,
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];
uint8_t uuid_sub_raw[VOLUME_ID_UUID_SIZE];
size_t uuid_sub_raw_len;
char uuid_sub[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 force_unique_result;
};
/* utils */
extern int volume_id_utf8_encoded_valid_unichar(const char *str);
extern size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count);
extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id);
extern void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count);
extern void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count);
extern void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count);
extern void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format);
extern void volume_id_set_uuid_sub(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format);
extern uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len);
extern void volume_id_free_buffer(struct volume_id *id);
/* filesystems */
extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_gfs(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_gfs2(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_btrfs(struct volume_id *id, uint64_t off, uint64_t size);
/* special formats */
extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size);
/* raid */
extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_oracleasm(struct volume_id *id, uint64_t off, uint64_t size);
/* bios raid */
extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_jmicron_raid(struct volume_id *id, uint64_t off, uint64_t size);
#endif

View File

@ -1,55 +0,0 @@
/*
* volume_id - reads volume label and uuid
*
* Copyright (C) 2005-2008 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIBVOLUME_ID_H_
#define _LIBVOLUME_ID_H_
#include <stdint.h>
#include <stddef.h>
struct volume_id;
typedef void (*volume_id_log_fn_t)(int priority, const char *file, int line, const char *format, ...)
__attribute__ ((format(printf, 4, 5)));
extern volume_id_log_fn_t volume_id_log_fn;
typedef int (*volume_id_probe_fn_t)(struct volume_id *id, uint64_t off, uint64_t size);
typedef int (*all_probers_fn_t)(volume_id_probe_fn_t probe_fn,
struct volume_id *id, uint64_t off, uint64_t size,
void *data);
extern struct volume_id *volume_id_open_fd(int fd);
extern void volume_id_close(struct volume_id *id);
extern int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size);
extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size);
extern const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type);
extern void volume_id_all_probers(all_probers_fn_t all_probers_fn,
struct volume_id *id, uint64_t off, uint64_t size,
void *data);
extern int volume_id_get_label(struct volume_id *id, const char **label);
extern int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len);
extern int volume_id_get_uuid(struct volume_id *id, const char **uuid);
extern int volume_id_get_uuid_sub(struct volume_id *id, const char **uuid);
extern int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len);
extern int volume_id_get_usage(struct volume_id *id, const char **usage);
extern int volume_id_get_type(struct volume_id *id, const char **type);
extern int volume_id_get_type_version(struct volume_id *id, const char **type_version);
extern int volume_id_encode_string(const char *str, char *str_enc, size_t len);
#endif

View File

@ -1,10 +0,0 @@
prefix=@prefix@
exec_prefix=@prefix@
libdir=@prefix@/@libdir_name@
includedir=@prefix@/include
Name: libvolume_id
Description: Library for reading metadata, label, uuid from various filesystems
Version: @VERSION@
Libs: -L${libdir} -lvolume_id
Cflags: -I${includedir}

View File

@ -1,181 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <byteswap.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct mdp0_super_block {
uint32_t md_magic;
uint32_t major_version;
uint32_t minor_version;
uint32_t patch_version;
uint32_t gvalid_words;
uint32_t set_uuid0;
uint32_t ctime;
uint32_t level;
uint32_t size;
uint32_t nr_disks;
uint32_t raid_disks;
uint32_t md_minor;
uint32_t not_persistent;
uint32_t set_uuid1;
uint32_t set_uuid2;
uint32_t set_uuid3;
} PACKED;
struct mdp1_super_block {
uint32_t magic;
uint32_t major_version;
uint32_t feature_map;
uint32_t pad0;
uint8_t set_uuid[16];
uint8_t set_name[32];
} PACKED;
#define MD_RESERVED_BYTES 0x10000
#define MD_SB_MAGIC 0xa92b4efc
static int volume_id_probe_linux_raid0(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct mdp0_super_block *mdp0;
union {
uint32_t ints[4];
uint8_t bytes[16];
} uuid;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
if (size < 0x10000)
return -1;
buf = volume_id_get_buffer(id, off, 0x800);
if (buf == NULL)
return -1;
mdp0 = (struct mdp0_super_block *) buf;
if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
uuid.ints[0] = bswap_32(mdp0->set_uuid0);
if (le32_to_cpu(mdp0->minor_version >= 90)) {
uuid.ints[1] = bswap_32(mdp0->set_uuid1);
uuid.ints[2] = bswap_32(mdp0->set_uuid2);
uuid.ints[3] = bswap_32(mdp0->set_uuid3);
} else {
uuid.ints[1] = 0;
uuid.ints[2] = 0;
uuid.ints[3] = 0;
}
volume_id_set_uuid(id, uuid.bytes, 0, UUID_MD);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u",
le32_to_cpu(mdp0->major_version),
le32_to_cpu(mdp0->minor_version),
le32_to_cpu(mdp0->patch_version));
} else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
uuid.ints[0] = mdp0->set_uuid0;
if (be32_to_cpu(mdp0->minor_version >= 90)) {
uuid.ints[1] = mdp0->set_uuid1;
uuid.ints[2] = mdp0->set_uuid2;
uuid.ints[3] = mdp0->set_uuid3;
} else {
uuid.ints[1] = 0;
uuid.ints[2] = 0;
uuid.ints[3] = 0;
}
volume_id_set_uuid(id, uuid.bytes, 0, UUID_MD);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u",
be32_to_cpu(mdp0->major_version),
be32_to_cpu(mdp0->minor_version),
be32_to_cpu(mdp0->patch_version));
} else
return -1;
volume_id_set_usage(id, VOLUME_ID_RAID);
id->type = "linux_raid_member";
return 0;
}
static int volume_id_probe_linux_raid1(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct mdp1_super_block *mdp1;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
buf = volume_id_get_buffer(id, off, 0x800);
if (buf == NULL)
return -1;
mdp1 = (struct mdp1_super_block *) buf;
if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC)
return -1;
if (le32_to_cpu(mdp1->major_version) != 1)
return -1;
volume_id_set_uuid(id, mdp1->set_uuid, 0, UUID_MD);
volume_id_set_label_raw(id, mdp1->set_name, 32);
volume_id_set_label_string(id, mdp1->set_name, 32);
volume_id_set_usage(id, VOLUME_ID_RAID);
id->type = "linux_raid_member";
return 0;
}
int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
uint64_t sboff;
if (size > MD_RESERVED_BYTES) {
/* version 0 at the end of the device */
sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
if (volume_id_probe_linux_raid0(id, off + sboff, size) == 0)
return 0;
/* version 1.0 at the end of the device */
sboff = (size & ~(0x1000 - 1)) - 0x2000;
if (volume_id_probe_linux_raid1(id, off + sboff, size) == 0) {
strcpy(id->type_version, "1.0");
return 0;
}
}
/* version 1.1 at the start of the device */
if (volume_id_probe_linux_raid1(id, off, size) == 0) {
strcpy(id->type_version, "1.1");
return 0;
}
/* version 1.2 at 4k offset from the start */
if (volume_id_probe_linux_raid1(id, off + 0x1000, size) == 0) {
strcpy(id->type_version, "1.2");
return 0;
}
return -1;
}

View File

@ -1,104 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct swap_header_v1_2 {
uint8_t bootbits[1024];
uint32_t version;
uint32_t last_page;
uint32_t nr_badpages;
uint8_t uuid[16];
uint8_t volume_name[16];
} PACKED;
#define LARGEST_PAGESIZE 0x10000
int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
unsigned int page;
struct swap_header_v1_2 *sw;
info("probing at offset 0x%" PRIx64 "\n", off);
/* eek, the swap signature is at the end of the PAGE_SIZE */
for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) {
buf = volume_id_get_buffer(id, off + page-10, 10);
if (buf == NULL)
return -1;
if (memcmp(buf, "SWAP-SPACE", 10) == 0) {
id->type = "swap";
strcpy(id->type_version, "1");
goto found;
}
if (memcmp(buf, "SWAPSPACE2", 10) == 0) {
id->type = "swap";
strcpy(id->type_version, "2");
goto found_label;
}
if (memcmp(buf, "S1SUSPEND", 9) == 0) {
id->type = "suspend";
strcpy(id->type_version, "s1suspend");
goto found_label;
}
if (memcmp(buf, "ULSUSPEND", 9) == 0) {
id->type = "suspend";
strcpy(id->type_version, "ulsuspend");
goto found_label;
}
if (memcmp(buf, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8) == 0) {
id->type = "suspend";
strcpy(id->type_version, "tuxonice");
goto found_label;
}
}
return -1;
found_label:
sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2));
if (sw != NULL) {
volume_id_set_label_raw(id, sw->volume_name, 16);
volume_id_set_label_string(id, sw->volume_name, 16);
volume_id_set_uuid(id, sw->uuid, 0, UUID_DCE);
}
found:
volume_id_set_usage(id, VOLUME_ID_OTHER);
/* we think this is swap, but we make sure no other signatures are found */
id->force_unique_result = 1;
return 0;
}

View File

@ -1,64 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct lsi_meta {
uint8_t sig[6];
} PACKED;
#define LSI_SIGNATURE "$XIDE$"
int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct lsi_meta *lsi;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,86 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 W. Michael Petullo <mike@flyn.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.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
#define LUKS_MAGIC_L 6
#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1)
#define UUID_STRING_L 40
static const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe};
struct luks_phdr {
uint8_t magic[LUKS_MAGIC_L];
uint16_t version;
uint8_t cipherName[LUKS_CIPHERNAME_L];
uint8_t cipherMode[LUKS_CIPHERMODE_L];
uint8_t hashSpec[LUKS_HASHSPEC_L];
uint32_t payloadOffset;
uint32_t keyBytes;
uint8_t mkDigest[LUKS_DIGESTSIZE];
uint8_t mkDigestSalt[LUKS_SALTSIZE];
uint32_t mkDigestIterations;
uint8_t uuid[UUID_STRING_L];
struct {
uint32_t active;
uint32_t passwordIterations;
uint8_t passwordSalt[LUKS_SALTSIZE];
uint32_t keyMaterialOffset;
uint32_t stripes;
} keyblock[LUKS_NUMKEYS];
};
int volume_id_probe_luks(struct volume_id *id, uint64_t off, uint64_t size)
{
struct luks_phdr *header;
header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE);
if (header == NULL)
return -1;
if (memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L))
return -1;
volume_id_set_usage(id, VOLUME_ID_CRYPTO);
volume_id_set_uuid(id, header->uuid, 36, UUID_HEX_STRING);
snprintf(id->type_version, sizeof(header->version), "%u", le16_to_cpu(header->version));
id->type = "crypto_LUKS";
return 0;
}

View File

@ -1,113 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.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;
struct lvm2_pv_header {
uint8_t id[32];
uint64_t devsize_xl;
} PACKED;
#define LVM1_SB_OFF 0x400
#define LVM1_MAGIC "HM"
int volume_id_probe_lvm1(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct lvm1_super_block *lvm;
info("probing at offset 0x%" PRIx64 "\n", 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, uint64_t size)
{
const uint8_t *buf;
unsigned int soff;
struct lvm2_super_block *lvm;
struct lvm2_pv_header *pvhdr;
dbg("probing at offset 0x%" PRIx64 "\n", 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:
dbg("found at offset 0x%x (pv hdr offset 0x%x)\n",
soff, cpu_to_le32(lvm->offset_xl));
soff += cpu_to_le32(lvm->offset_xl);
pvhdr = (struct lvm2_pv_header *) &buf[soff];
memcpy(id->type_version, lvm->type, 8);
volume_id_set_usage(id, VOLUME_ID_RAID);
volume_id_set_uuid(id, pvhdr->id, 0, UUID_LVM);
id->type = "LVM2_member";
return 0;
}

View File

@ -1,213 +0,0 @@
/*
* MD5 Message Digest Algorithm (RFC1321).
*
* Derived from cryptoapi implementation, originally based on the
* public domain implementation written by Colin Plumb in 1993.
*
* Copyright (c) Cryptoapi developers.
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <string.h>
#include <endian.h>
#include <byteswap.h>
#include "md5.h"
#if !defined __BYTE_ORDER || !(__BYTE_ORDER == __LITTLE_ENDIAN) && !(__BYTE_ORDER == __BIG_ENDIAN)
#error missing __BYTE_ORDER
#endif
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
#define MD5STEP(f, w, x, y, z, in, s) \
(w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
static void md5_transform(uint32_t *hash, uint32_t const *in)
{
uint32_t a, b, c, d;
a = hash[0];
b = hash[1];
c = hash[2];
d = hash[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
hash[0] += a;
hash[1] += b;
hash[2] += c;
hash[3] += d;
}
static inline void swab32_array(uint32_t *buf, unsigned int words)
{
unsigned int i;
for (i = 0; i < words; i++)
buf[i] = bswap_32(buf[i]);
}
static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words)
{
#if (__BYTE_ORDER == __BIG_ENDIAN)
swab32_array(buf, words);
#endif
}
static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words)
{
#if (__BYTE_ORDER == __BIG_ENDIAN)
swab32_array(buf, words);
#endif
}
static inline void md5_transform_helper(struct md5_ctx *ctx)
{
le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t));
md5_transform(ctx->hash, ctx->block);
}
void md5_init(struct md5_ctx *mctx)
{
mctx->hash[0] = 0x67452301;
mctx->hash[1] = 0xefcdab89;
mctx->hash[2] = 0x98badcfe;
mctx->hash[3] = 0x10325476;
mctx->byte_count = 0;
}
void md5_update(struct md5_ctx *mctx, const uint8_t *data, unsigned int len)
{
const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
mctx->byte_count += len;
if (avail > len) {
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
data, len);
return;
}
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail);
md5_transform_helper(mctx);
data += avail;
len -= avail;
while (len >= sizeof(mctx->block)) {
memcpy(mctx->block, data, sizeof(mctx->block));
md5_transform_helper(mctx);
data += sizeof(mctx->block);
len -= sizeof(mctx->block);
}
memcpy(mctx->block, data, len);
}
void md5_final(struct md5_ctx *mctx, uint8_t *out)
{
const unsigned int offset = mctx->byte_count & 0x3f;
char *p = (char *)mctx->block + offset;
int padding = 56 - (offset + 1);
*p++ = 0x80;
if (padding < 0) {
memset(p, 0x00, padding + sizeof (uint64_t));
md5_transform_helper(mctx);
p = (char *)mctx->block;
padding = 56;
}
memset(p, 0, padding);
mctx->block[14] = mctx->byte_count << 3;
mctx->block[15] = mctx->byte_count >> 29;
le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
sizeof(uint64_t)) / sizeof(uint32_t));
md5_transform(mctx->hash, mctx->block);
cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t));
memcpy(out, mctx->hash, sizeof(mctx->hash));
memset(mctx, 0, sizeof(*mctx));
}

View File

@ -1,30 +0,0 @@
/*
* MD5 Message Digest Algorithm (RFC1321).
*
* Derived from cryptoapi implementation, originally based on the
* public domain implementation written by Colin Plumb in 1993.
*
* Copyright (c) Cryptoapi developers.
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
*
* 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; either version 2 of the License, or (at your option)
* any later version.
*
*/
#define MD5_DIGEST_SIZE 16
#define MD5_HMAC_BLOCK_SIZE 64
#define MD5_BLOCK_WORDS 16
#define MD5_HASH_WORDS 4
struct md5_ctx {
uint32_t hash[MD5_HASH_WORDS];
uint32_t block[MD5_BLOCK_WORDS];
uint64_t byte_count;
};
extern void md5_init(struct md5_ctx *mctx);
extern void md5_update(struct md5_ctx *mctx, const uint8_t *data, unsigned int len);
extern void md5_final(struct md5_ctx *mctx, uint8_t *out);

View File

@ -1,122 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define MINIX_SUPERBLOCK_OFFSET 0x400
#define MINIX_SUPER_MAGIC 0x137F
#define MINIX_SUPER_MAGIC2 0x138F
#define MINIX2_SUPER_MAGIC 0x2468
#define MINIX2_SUPER_MAGIC2 0x2478
#define MINIX3_SUPER_MAGIC 0x4d5a
struct minix_super_block
{
uint16_t s_ninodes;
uint16_t s_nzones;
uint16_t s_imap_blocks;
uint16_t s_zmap_blocks;
uint16_t s_firstdatazone;
uint16_t s_log_zone_size;
uint32_t s_max_size;
uint16_t s_magic;
uint16_t s_state;
uint32_t s_zones;
} PACKED;
struct minix3_super_block {
uint32_t s_ninodes;
uint16_t s_pad0;
uint16_t s_imap_blocks;
uint16_t s_zmap_blocks;
uint16_t s_firstdatazone;
uint16_t s_log_zone_size;
uint16_t s_pad1;
uint32_t s_max_size;
uint32_t s_zones;
uint16_t s_magic;
uint16_t s_pad2;
uint16_t s_blocksize;
uint8_t s_disk_version;
} PACKED;
int volume_id_probe_minix(struct volume_id *id, uint64_t off, uint64_t size)
{
uint8_t *buf;
struct minix_super_block *ms;
struct minix3_super_block *m3s;
info("probing at offset 0x%" PRIx64 "\n", off);
buf = volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200);
if (buf == NULL)
return -1;
ms = (struct minix_super_block *) buf;
if (ms->s_magic == MINIX_SUPER_MAGIC ||
ms->s_magic == bswap_16(MINIX_SUPER_MAGIC)) {
strcpy(id->type_version, "1");
goto found;
}
if (ms->s_magic == MINIX_SUPER_MAGIC2 ||
ms->s_magic == bswap_16(MINIX_SUPER_MAGIC2)) {
strcpy(id->type_version, "1");
goto found;
}
if (ms->s_magic == MINIX2_SUPER_MAGIC ||
ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC)) {
strcpy(id->type_version, "2");
goto found;
}
if (ms->s_magic == MINIX2_SUPER_MAGIC2 ||
ms->s_magic == bswap_16(MINIX2_SUPER_MAGIC2)) {
strcpy(id->type_version, "2");
goto found;
}
m3s = (struct minix3_super_block *) buf;
if (m3s->s_magic == MINIX3_SUPER_MAGIC ||
m3s->s_magic == bswap_16(MINIX3_SUPER_MAGIC)) {
strcpy(id->type_version, "3");
goto found;
}
goto exit;
found:
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "minix";
return 0;
exit:
return -1;
}

View File

@ -1,108 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define NW_SUPERBLOCK_OFFSET 0x1000
struct netware_super_block {
uint8_t SBH_Signature[4];
uint16_t SBH_VersionMajor;
uint16_t SBH_VersionMinor;
uint16_t SBH_VersionMediaMajor;
uint16_t SBH_VersionMediaMinor;
uint32_t SBH_ItemsMoved;
uint8_t SBH_InternalID[16];
uint32_t SBH_PackedSize;
uint32_t SBH_Checksum;
uint32_t supersyncid;
int64_t superlocation[4];
uint32_t physSizeUsed;
uint32_t sizeUsed;
uint32_t superTimeStamp;
uint32_t reserved0[1];
int64_t SBH_LoggedPoolDataBlk;
int64_t SBH_PoolDataBlk;
uint8_t SBH_OldInternalID[16];
uint32_t SBH_PoolToLVStartUTC;
uint32_t SBH_PoolToLVEndUTC;
uint16_t SBH_VersionMediaMajorCreate;
uint16_t SBH_VersionMediaMinorCreate;
uint32_t SBH_BlocksMoved;
uint32_t SBH_TempBTSpBlk;
uint32_t SBH_TempFTSpBlk;
uint32_t SBH_TempFTSpBlk1;
uint32_t SBH_TempFTSpBlk2;
uint32_t nssMagicNumber;
uint32_t poolClassID;
uint32_t poolID;
uint32_t createTime;
int64_t SBH_LoggedVolumeDataBlk;
int64_t SBH_VolumeDataBlk;
int64_t SBH_SystemBeastBlkNum;
uint64_t totalblocks;
uint16_t SBH_Name[64];
uint8_t SBH_VolumeID[16];
uint8_t SBH_PoolID[16];
uint8_t SBH_PoolInternalID[16];
uint64_t SBH_Lsn;
uint32_t SBH_SS_Enabled;
uint32_t SBH_SS_CreateTime;
uint8_t SBH_SS_OriginalPoolID[16];
uint8_t SBH_SS_OriginalVolumeID[16];
uint8_t SBH_SS_Guid[16];
uint16_t SBH_SS_OriginalName[64];
uint32_t reserved2[64-(2+46)];
} PACKED;
int volume_id_probe_netware(struct volume_id *id, uint64_t off, uint64_t size)
{
struct netware_super_block *nw;
info("probing at offset 0x%" PRIx64 "\n", off);
nw = (struct netware_super_block *) volume_id_get_buffer(id, off + NW_SUPERBLOCK_OFFSET, 0x200);
if (nw == NULL)
return -1;
if (memcmp(nw->SBH_Signature, "SPB5", 4) != 0)
return -1;
volume_id_set_uuid(id, nw->SBH_PoolID, 0, UUID_DCE);
snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%02u",
le16_to_cpu(nw->SBH_VersionMediaMajor), le16_to_cpu(nw->SBH_VersionMediaMinor));
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "nss";
return 0;
}

View File

@ -1,203 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
static struct ntfs_super_block {
uint8_t jump[3];
uint8_t oem_id[8];
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t fats;
uint16_t root_entries;
uint16_t sectors;
uint8_t media_type;
uint16_t sectors_per_fat;
uint16_t sectors_per_track;
uint16_t heads;
uint32_t hidden_sectors;
uint32_t large_sectors;
uint16_t unused[2];
uint64_t number_of_sectors;
uint64_t mft_cluster_location;
uint64_t mft_mirror_cluster_location;
int8_t cluster_per_mft_record;
uint8_t reserved1[3];
int8_t cluster_per_index_record;
uint8_t reserved2[3];
uint8_t volume_serial[8];
uint16_t checksum;
} PACKED *ns;
static struct master_file_table_record {
uint8_t magic[4];
uint16_t usa_ofs;
uint16_t usa_count;
uint64_t lsn;
uint16_t sequence_number;
uint16_t link_count;
uint16_t attrs_offset;
uint16_t flags;
uint32_t bytes_in_use;
uint32_t bytes_allocated;
} PACKED *mftr;
static struct file_attribute {
uint32_t type;
uint32_t len;
uint8_t non_resident;
uint8_t name_len;
uint16_t name_offset;
uint16_t flags;
uint16_t instance;
uint32_t value_len;
uint16_t value_offset;
} PACKED *attr;
static struct volume_info {
uint64_t reserved;
uint8_t major_ver;
uint8_t minor_ver;
} PACKED *info;
#define MFT_RECORD_VOLUME 3
#define MFT_RECORD_ATTR_VOLUME_NAME 0x60
#define MFT_RECORD_ATTR_VOLUME_INFO 0x70
#define MFT_RECORD_ATTR_OBJECT_ID 0x40
#define MFT_RECORD_ATTR_END 0xffffffffu
int volume_id_probe_ntfs(struct volume_id *id, uint64_t off, uint64_t size)
{
uint8_t volume_serial[8];
unsigned int sector_size;
unsigned int cluster_size;
uint64_t mft_cluster;
uint64_t mft_off;
unsigned int mft_record_size;
unsigned int attr_type;
unsigned int attr_off;
unsigned int attr_len;
unsigned int val_off;
unsigned int val_len;
const uint8_t *buf;
const uint8_t *val;
info("probing at offset 0x%" PRIx64 "\n", 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;
memcpy(volume_serial, ns->volume_serial, sizeof(volume_serial));
sector_size = le16_to_cpu(ns->bytes_per_sector);
if (sector_size < 0x200)
return -1;
cluster_size = ns->sectors_per_cluster * sector_size;
mft_cluster = le64_to_cpu(ns->mft_cluster_location);
mft_off = mft_cluster * cluster_size;
if (ns->cluster_per_mft_record < 0)
/* size = -log2(mft_record_size); normally 1024 Bytes */
mft_record_size = 1 << -ns->cluster_per_mft_record;
else
mft_record_size = ns->cluster_per_mft_record * cluster_size;
dbg("sectorsize 0x%x\n", sector_size);
dbg("clustersize 0x%x\n", cluster_size);
dbg("mftcluster %" PRIu64 "\n", mft_cluster);
dbg("mftoffset 0x%" PRIx64 "\n", mft_off);
dbg("cluster per mft_record %i\n", ns->cluster_per_mft_record);
dbg("mft record size %i\n", mft_record_size);
buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size),
mft_record_size);
if (buf == NULL)
return -1;
mftr = (struct master_file_table_record*) buf;
dbg("mftr->magic '%c%c%c%c'\n", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]);
if (memcmp(mftr->magic, "FILE", 4) != 0)
return -1;
attr_off = le16_to_cpu(mftr->attrs_offset);
dbg("file $Volume's attributes are at offset %i\n", 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\n",
attr_type, attr_len, attr_off);
if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) {
dbg("found info, len %i\n", 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\n", val_len);
if (val_len > VOLUME_ID_LABEL_SIZE)
val_len = VOLUME_ID_LABEL_SIZE;
val = ((uint8_t *) attr) + val_off;
volume_id_set_label_raw(id, val, val_len);
volume_id_set_label_unicode16(id, val, LE, val_len);
}
}
volume_id_set_uuid(id, volume_serial, 0, UUID_64BIT_LE);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "ntfs";
/* we think this is ntfs, but we make sure no other signatures are found */
id->force_unique_result = 1;
return 0;
}

View File

@ -1,68 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct nvidia_meta {
uint8_t vendor[8];
uint32_t size;
uint32_t chksum;
uint16_t version;
} PACKED;
#define NVIDIA_SIGNATURE "NVIDIA"
int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct nvidia_meta *nv;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,198 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Andre Masella <andre@masella.no-ip.org>
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct ocfs1_super_block_header {
uint32_t minor_version;
uint32_t major_version;
uint8_t signature[128];
uint8_t mount_point[128];
uint64_t serial_num;
uint64_t device_size;
uint64_t start_off;
uint64_t bitmap_off;
uint64_t publ_off;
uint64_t vote_off;
uint64_t root_bitmap_off;
uint64_t data_start_off;
uint64_t root_bitmap_size;
uint64_t root_off;
uint64_t root_size;
uint64_t cluster_size;
uint64_t num_nodes;
uint64_t num_clusters;
uint64_t dir_node_size;
uint64_t file_node_size;
uint64_t internal_off;
uint64_t node_cfg_off;
uint64_t node_cfg_size;
uint64_t new_cfg_off;
uint32_t prot_bits;
int32_t excl_mount;
} PACKED;
struct ocfs1_super_block_label {
struct ocfs1_disk_lock {
uint32_t curr_master;
uint8_t file_lock;
uint8_t compat_pad[3];
uint64_t last_write_time;
uint64_t last_read_time;
uint32_t writer_node_num;
uint32_t reader_node_num;
uint64_t oin_node_map;
uint64_t dlock_seq_num;
} PACKED disk_lock;
uint8_t label[64];
uint16_t label_len;
uint8_t vol_id[16];
uint16_t vol_id_len;
uint8_t cluster_name[64];
uint16_t cluster_name_len;
} PACKED;
struct ocfs2_super_block {
uint8_t i_signature[8];
uint32_t i_generation;
int16_t i_suballoc_slot;
uint16_t i_suballoc_bit;
uint32_t i_reserved0;
uint32_t i_clusters;
uint32_t i_uid;
uint32_t i_gid;
uint64_t i_size;
uint16_t i_mode;
uint16_t i_links_count;
uint32_t i_flags;
uint64_t i_atime;
uint64_t i_ctime;
uint64_t i_mtime;
uint64_t i_dtime;
uint64_t i_blkno;
uint64_t i_last_eb_blk;
uint32_t i_fs_generation;
uint32_t i_atime_nsec;
uint32_t i_ctime_nsec;
uint32_t i_mtime_nsec;
uint64_t i_reserved1[9];
uint64_t i_pad1;
uint16_t s_major_rev_level;
uint16_t s_minor_rev_level;
uint16_t s_mnt_count;
int16_t s_max_mnt_count;
uint16_t s_state;
uint16_t s_errors;
uint32_t s_checkinterval;
uint64_t s_lastcheck;
uint32_t s_creator_os;
uint32_t s_feature_compat;
uint32_t s_feature_incompat;
uint32_t s_feature_ro_compat;
uint64_t s_root_blkno;
uint64_t s_system_dir_blkno;
uint32_t s_blocksize_bits;
uint32_t s_clustersize_bits;
uint16_t s_max_slots;
uint16_t s_reserved1;
uint32_t s_reserved2;
uint64_t s_first_cluster_group;
uint8_t s_label[64];
uint8_t s_uuid[16];
} PACKED;
int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct ocfs1_super_block_header *osh;
struct ocfs1_super_block_label *osl;
info("probing at offset 0x%" PRIx64 "\n", off);
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\n");
buf = volume_id_get_buffer(id, off + 0x200, 0x200);
if (buf == NULL)
return -1;
osl = (struct ocfs1_super_block_label *) buf;
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
if (osl->label_len <= 64) {
volume_id_set_label_raw(id, osl->label, 64);
volume_id_set_label_string(id, osl->label, 64);
}
if (osl->vol_id_len == 16)
volume_id_set_uuid(id, osl->vol_id, 0, UUID_DCE);
id->type = "ocfs";
return 0;
}
#define OCFS2_MAX_BLOCKSIZE 0x1000
#define OCFS2_SUPER_BLOCK_BLKNO 2
int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct ocfs2_super_block *os;
size_t blksize;
info("probing at offset 0x%" PRIx64 "\n", 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, 0, 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;
}

View File

@ -1,70 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct oracleasm_super_block {
uint8_t tag[8];
uint8_t id[24];
} PACKED;
#define ASM_SB_OFF 0x20
#define ASM_MAGIC "ORCLDISK"
/*
* Detect Oracle Automatic Storage Management (ASM).
* It can do mirroring, but don't consider it RAID in the sense
* that an ext3 filesystem could live inside. Thus, mark it 'other'.
* There also is a magic word 'ORCLCLRD'; like blkid(8), we ignore that.
*/
int volume_id_probe_oracleasm(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct oracleasm_super_block *oracleasm;
info("probing at offset 0x%" PRIx64 "\n", off);
buf = volume_id_get_buffer(id, off + ASM_SB_OFF, 0x800);
if (buf == NULL)
return -1;
oracleasm = (struct oracleasm_super_block *) buf;
if (memcmp(oracleasm->tag, ASM_MAGIC, 8) != 0)
return -1;
volume_id_set_usage(id, VOLUME_ID_OTHER);
volume_id_set_label_raw(id, oracleasm->id, 24);
volume_id_set_label_string(id, oracleasm->id, 24);
id->type = "oracleasm";
return 0;
}

View File

@ -1,74 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct promise_meta {
uint8_t sig[24];
} PACKED;
#define PDC_CONFIG_OFF 0x1200
#define PDC_SIGNATURE "Promise Technology, Inc."
int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
struct promise_meta *pdc;
unsigned int i;
static unsigned int sectors[] = {
63, 255, 256, 16, 399, 0
};
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,123 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2005 Tobias Klauser <tklauser@access.unizh.ch>
*
* 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, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct reiserfs_super_block {
uint32_t blocks_count;
uint32_t free_blocks;
uint32_t root_block;
uint32_t journal_block;
uint32_t journal_dev;
uint32_t orig_journal_size;
uint32_t dummy2[5];
uint16_t blocksize;
uint16_t dummy3[3];
uint8_t magic[12];
uint32_t dummy4[5];
uint8_t uuid[16];
uint8_t label[16];
} PACKED;
struct reiser4_super_block {
uint8_t magic[16];
uint16_t dummy[2];
uint8_t uuid[16];
uint8_t label[16];
uint64_t dummy2;
} PACKED;
#define REISERFS1_SUPERBLOCK_OFFSET 0x2000
#define REISERFS_SUPERBLOCK_OFFSET 0x10000
int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct reiserfs_super_block *rs;
struct reiser4_super_block *rs4;
uint8_t *buf;
info("probing at offset 0x%" PRIx64 "\n", 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, 0, UUID_DCE);
id->type = "reiser4";
goto found;
}
buf = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200);
if (buf == NULL)
return -1;
rs = (struct reiserfs_super_block *) buf;
if (memcmp(rs->magic, "ReIsErFs", 8) == 0) {
strcpy(id->type_version, "3.5");
id->type = "reiserfs";
goto found;
}
return -1;
found_label:
volume_id_set_label_raw(id, rs->label, 16);
volume_id_set_label_string(id, rs->label, 16);
volume_id_set_uuid(id, rs->uuid, 0, UUID_DCE);
found:
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
return 0;
}

View File

@ -1,65 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct romfs_super {
uint8_t magic[8];
uint32_t size;
uint32_t checksum;
uint8_t name[0];
} PACKED;
int volume_id_probe_romfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct romfs_super *rfs;
info("probing at offset 0x%" PRIx64 "\n", 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;
}

View File

@ -1,81 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct silicon_meta {
uint8_t unknown0[0x2E];
uint8_t ascii_version[0x36 - 0x2E];
uint8_t diskname[0x56 - 0x36];
uint8_t unknown1[0x60 - 0x56];
uint32_t magic;
uint32_t unknown1a[0x6C - 0x64];
uint32_t array_sectors_low;
uint32_t array_sectors_high;
uint8_t unknown2[0x78 - 0x74];
uint32_t thisdisk_sectors;
uint8_t unknown3[0x100 - 0x7C];
uint8_t unknown4[0x104 - 0x100];
uint16_t product_id;
uint16_t vendor_id;
uint16_t minor_ver;
uint16_t major_ver;
} PACKED;
#define SILICON_MAGIC 0x2F000000
int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct silicon_meta *sil;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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;
}

View File

@ -1,76 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define SQUASHFS_MAGIC 0x73717368
#define SQUASHFS_MAGIC_LZMA 0x71736873
struct squashfs_super {
uint32_t s_magic;
uint32_t inodes;
uint32_t bytes_used_2;
uint32_t uid_start_2;
uint32_t guid_start_2;
uint32_t inode_table_start_2;
uint32_t directory_table_start_2;
uint16_t s_major;
uint16_t s_minor;
} PACKED;
int volume_id_probe_squashfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct squashfs_super *sqs;
info("probing at offset 0x%" PRIx64 "\n", off);
sqs = (struct squashfs_super *) volume_id_get_buffer(id, off, 0x200);
if (sqs == NULL)
return -1;
if (sqs->s_magic == SQUASHFS_MAGIC || sqs->s_magic == SQUASHFS_MAGIC_LZMA) {
snprintf(id->type_version, sizeof(id->type_version), "%u.%u",
sqs->s_major, sqs->s_minor);
goto found;
}
if (sqs->s_magic == bswap_32(SQUASHFS_MAGIC) || sqs->s_magic == bswap_32(SQUASHFS_MAGIC_LZMA)) {
snprintf(id->type_version, sizeof(id->type_version), "%u.%u",
bswap_16(sqs->s_major), bswap_16(sqs->s_minor));
goto found;
}
return -1;
found:
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "squashfs";
return 0;
}

View File

@ -1,138 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define SYSV_NICINOD 100
#define SYSV_NICFREE 50
struct sysv_super
{
uint16_t s_isize;
uint16_t s_pad0;
uint32_t s_fsize;
uint16_t s_nfree;
uint16_t s_pad1;
uint32_t s_free[SYSV_NICFREE];
uint16_t s_ninode;
uint16_t s_pad2;
uint16_t s_inode[SYSV_NICINOD];
uint8_t s_flock;
uint8_t s_ilock;
uint8_t s_fmod;
uint8_t s_ronly;
uint32_t s_time;
uint16_t s_dinfo[4];
uint32_t s_tfree;
uint16_t s_tinode;
uint16_t s_pad3;
uint8_t s_fname[6];
uint8_t s_fpack[6];
uint32_t s_fill[12];
uint32_t s_state;
uint32_t s_magic;
uint32_t s_type;
} PACKED;
#define XENIX_NICINOD 100
#define XENIX_NICFREE 100
struct xenix_super {
uint16_t s_isize;
uint32_t s_fsize;
uint16_t s_nfree;
uint32_t s_free[XENIX_NICFREE];
uint16_t s_ninode;
uint16_t s_inode[XENIX_NICINOD];
uint8_t s_flock;
uint8_t s_ilock;
uint8_t s_fmod;
uint8_t s_ronly;
uint32_t s_time;
uint32_t s_tfree;
uint16_t s_tinode;
uint16_t s_dinfo[4];
uint8_t s_fname[6];
uint8_t s_fpack[6];
uint8_t s_clean;
uint8_t s_fill[371];
uint32_t s_magic;
uint32_t s_type;
} PACKED;
#define SYSV_SUPERBLOCK_BLOCK 0x01
#define SYSV_MAGIC 0xfd187e20
#define XENIX_SUPERBLOCK_BLOCK 0x18
#define XENIX_MAGIC 0x2b5544
#define SYSV_MAX_BLOCKSIZE 0x800
int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size)
{
struct sysv_super *vs;
struct xenix_super *xs;
unsigned int boff;
info("probing at offset 0x%" PRIx64 "\n", 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;
}

View File

@ -1,183 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct volume_descriptor {
struct descriptor_tag {
uint16_t id;
uint16_t version;
uint8_t checksum;
uint8_t reserved;
uint16_t serial;
uint16_t crc;
uint16_t crc_len;
uint32_t location;
} PACKED tag;
union {
struct anchor_descriptor {
uint32_t length;
uint32_t location;
} PACKED anchor;
struct primary_descriptor {
uint32_t seq_num;
uint32_t desc_num;
struct dstring {
uint8_t clen;
uint8_t c[31];
} PACKED ident;
} PACKED primary;
} PACKED type;
} PACKED;
struct volume_structure_descriptor {
uint8_t type;
uint8_t id[5];
uint8_t version;
} PACKED;
#define UDF_VSD_OFFSET 0x8000
int volume_id_probe_udf(struct volume_id *id, uint64_t off, uint64_t size)
{
struct volume_descriptor *vd;
struct volume_structure_descriptor *vsd;
unsigned int bs;
unsigned int b;
unsigned int type;
unsigned int count;
unsigned int loc;
unsigned int clen;
info("probing at offset 0x%" PRIx64 "\n", 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\n", 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\n",
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\n", 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\n", 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\n", 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;
}

View File

@ -1,227 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct ufs_super_block {
uint32_t fs_link;
uint32_t fs_rlink;
uint32_t fs_sblkno;
uint32_t fs_cblkno;
uint32_t fs_iblkno;
uint32_t fs_dblkno;
uint32_t fs_cgoffset;
uint32_t fs_cgmask;
uint32_t fs_time;
uint32_t fs_size;
uint32_t fs_dsize;
uint32_t fs_ncg;
uint32_t fs_bsize;
uint32_t fs_fsize;
uint32_t fs_frag;
uint32_t fs_minfree;
uint32_t fs_rotdelay;
uint32_t fs_rps;
uint32_t fs_bmask;
uint32_t fs_fmask;
uint32_t fs_bshift;
uint32_t fs_fshift;
uint32_t fs_maxcontig;
uint32_t fs_maxbpg;
uint32_t fs_fragshift;
uint32_t fs_fsbtodb;
uint32_t fs_sbsize;
uint32_t fs_csmask;
uint32_t fs_csshift;
uint32_t fs_nindir;
uint32_t fs_inopb;
uint32_t fs_nspf;
uint32_t fs_optim;
uint32_t fs_npsect_state;
uint32_t fs_interleave;
uint32_t fs_trackskew;
uint32_t fs_id[2];
uint32_t fs_csaddr;
uint32_t fs_cssize;
uint32_t fs_cgsize;
uint32_t fs_ntrak;
uint32_t fs_nsect;
uint32_t fs_spc;
uint32_t fs_ncyl;
uint32_t fs_cpg;
uint32_t fs_ipg;
uint32_t fs_fpg;
struct ufs_csum {
uint32_t cs_ndir;
uint32_t cs_nbfree;
uint32_t cs_nifree;
uint32_t cs_nffree;
} PACKED fs_cstotal;
int8_t fs_fmod;
int8_t fs_clean;
int8_t fs_ronly;
int8_t fs_flags;
union {
struct {
int8_t fs_fsmnt[512];
uint32_t fs_cgrotor;
uint32_t fs_csp[31];
uint32_t fs_maxcluster;
uint32_t fs_cpc;
uint16_t fs_opostbl[16][8];
} PACKED fs_u1;
struct {
int8_t fs_fsmnt[468];
uint8_t fs_volname[32];
uint64_t fs_swuid;
int32_t fs_pad;
uint32_t fs_cgrotor;
uint32_t fs_ocsp[28];
uint32_t fs_contigdirs;
uint32_t fs_csp;
uint32_t fs_maxcluster;
uint32_t fs_active;
int32_t fs_old_cpc;
int32_t fs_maxbsize;
int64_t fs_sparecon64[17];
int64_t fs_sblockloc;
struct ufs2_csum_total {
uint64_t cs_ndir;
uint64_t cs_nbfree;
uint64_t cs_nifree;
uint64_t cs_nffree;
uint64_t cs_numclusters;
uint64_t cs_spare[3];
} PACKED fs_cstotal;
struct ufs_timeval {
int32_t tv_sec;
int32_t tv_usec;
} PACKED fs_time;
int64_t fs_size;
int64_t fs_dsize;
uint64_t fs_csaddr;
int64_t fs_pendingblocks;
int32_t fs_pendinginodes;
} PACKED fs_u2;
} fs_u11;
union {
struct {
int32_t fs_sparecon[53];
int32_t fs_reclaim;
int32_t fs_sparecon2[1];
int32_t fs_state;
uint32_t fs_qbmask[2];
uint32_t fs_qfmask[2];
} PACKED fs_sun;
struct {
int32_t fs_sparecon[53];
int32_t fs_reclaim;
int32_t fs_sparecon2[1];
uint32_t fs_npsect;
uint32_t fs_qbmask[2];
uint32_t fs_qfmask[2];
} PACKED fs_sunx86;
struct {
int32_t fs_sparecon[50];
int32_t fs_contigsumsize;
int32_t fs_maxsymlinklen;
int32_t fs_inodefmt;
uint32_t fs_maxfilesize[2];
uint32_t fs_qbmask[2];
uint32_t fs_qfmask[2];
int32_t fs_state;
} PACKED fs_44;
} fs_u2;
int32_t fs_postblformat;
int32_t fs_nrpos;
int32_t fs_postbloff;
int32_t fs_rotbloff;
uint32_t fs_magic;
uint8_t fs_space[1];
} PACKED;
#define UFS_MAGIC 0x00011954
#define UFS2_MAGIC 0x19540119
#define UFS_MAGIC_FEA 0x00195612
#define UFS_MAGIC_LFN 0x00095014
int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size)
{
uint32_t magic;
int i;
struct ufs_super_block *ufs;
int offsets[] = {0, 8, 64, 256, -1};
info("probing at offset 0x%" PRIx64 "\n", 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\n", 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)\n", 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)\n", magic);
goto found;
}
}
return -1;
found:
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "ufs";
switch (magic) {
case UFS_MAGIC:
strcpy(id->type_version, "1");
break;
case UFS2_MAGIC:
strcpy(id->type_version, "2");
volume_id_set_label_raw(id, ufs->fs_u11.fs_u2.fs_volname, 32);
volume_id_set_label_string(id, ufs->fs_u11.fs_u2.fs_volname, 32);
break;
default:
break;
}
return 0;
}

View File

@ -1,449 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
/* count of characters used to encode one unicode char */
static int utf8_encoded_expected_len(const char *str)
{
unsigned char c = (unsigned char)str[0];
if (c < 0x80)
return 1;
if ((c & 0xe0) == 0xc0)
return 2;
if ((c & 0xf0) == 0xe0)
return 3;
if ((c & 0xf8) == 0xf0)
return 4;
if ((c & 0xfc) == 0xf8)
return 5;
if ((c & 0xfe) == 0xfc)
return 6;
return 0;
}
/* decode one unicode char */
static int utf8_encoded_to_unichar(const char *str)
{
int unichar;
int len;
int i;
len = utf8_encoded_expected_len(str);
switch (len) {
case 1:
return (int)str[0];
case 2:
unichar = str[0] & 0x1f;
break;
case 3:
unichar = (int)str[0] & 0x0f;
break;
case 4:
unichar = (int)str[0] & 0x07;
break;
case 5:
unichar = (int)str[0] & 0x03;
break;
case 6:
unichar = (int)str[0] & 0x01;
break;
default:
return -1;
}
for (i = 1; i < len; i++) {
if (((int)str[i] & 0xc0) != 0x80)
return -1;
unichar <<= 6;
unichar |= (int)str[i] & 0x3f;
}
return unichar;
}
/* expected size used to encode one unicode char */
static int utf8_unichar_to_encoded_len(int unichar)
{
if (unichar < 0x80)
return 1;
if (unichar < 0x800)
return 2;
if (unichar < 0x10000)
return 3;
if (unichar < 0x200000)
return 4;
if (unichar < 0x4000000)
return 5;
return 6;
}
/* check if unicode char has a valid numeric range */
static int utf8_unichar_valid_range(int unichar)
{
if (unichar > 0x10ffff)
return 0;
if ((unichar & 0xfffff800) == 0xd800)
return 0;
if ((unichar > 0xfdcf) && (unichar < 0xfdf0))
return 0;
if ((unichar & 0xffff) == 0xffff)
return 0;
return 1;
}
/* validate one encoded unicode char and return its length */
int volume_id_utf8_encoded_valid_unichar(const char *str)
{
int len;
int unichar;
int i;
len = utf8_encoded_expected_len(str);
if (len == 0)
return -1;
/* ascii is valid */
if (len == 1)
return 1;
/* check if expected encoded chars are available */
for (i = 0; i < len; i++)
if ((str[i] & 0x80) != 0x80)
return -1;
unichar = utf8_encoded_to_unichar(str);
/* check if encoded length matches encoded value */
if (utf8_unichar_to_encoded_len(unichar) != len)
return -1;
/* check if value has valid range */
if (!utf8_unichar_valid_range(unichar))
return -1;
return len;
}
size_t volume_id_set_unicode16(uint8_t *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count)
{
size_t i, j;
uint16_t c;
j = 0;
for (i = 0; i + 2 <= count; i += 2) {
if (endianess == LE)
c = (buf[i+1] << 8) | buf[i];
else
c = (buf[i] << 8) | buf[i+1];
if (c == 0) {
str[j] = '\0';
break;
} else if (c < 0x80) {
if (j+1 >= len)
break;
str[j++] = (uint8_t) c;
} else if (c < 0x800) {
if (j+2 >= len)
break;
str[j++] = (uint8_t) (0xc0 | (c >> 6));
str[j++] = (uint8_t) (0x80 | (c & 0x3f));
} else {
if (j+3 >= len)
break;
str[j++] = (uint8_t) (0xe0 | (c >> 12));
str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
str[j++] = (uint8_t) (0x80 | (c & 0x3f));
}
}
str[j] = '\0';
return j;
}
static char *usage_to_string(enum volume_id_usage usage_id)
{
switch (usage_id) {
case VOLUME_ID_FILESYSTEM:
return "filesystem";
case VOLUME_ID_OTHER:
return "other";
case VOLUME_ID_RAID:
return "raid";
case VOLUME_ID_CRYPTO:
return "crypto";
case VOLUME_ID_UNUSED:
return "unused";
}
return NULL;
}
void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id)
{
id->usage_id = usage_id;
id->usage = usage_to_string(usage_id);
}
void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count)
{
if (count > sizeof(id->label_raw))
count = sizeof(id->label_raw);
memcpy(id->label_raw, buf, count);
id->label_raw_len = count;
}
void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count)
{
size_t i;
if (count >= sizeof(id->label))
count = sizeof(id->label)-1;
memcpy(id->label, buf, count);
id->label[count] = '\0';
/* remove trailing whitespace */
i = strnlen(id->label, count);
while (i--) {
if (!isspace(id->label[i]))
break;
}
id->label[i+1] = '\0';
}
void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count)
{
if (count >= sizeof(id->label))
count = sizeof(id->label)-1;
volume_id_set_unicode16((uint8_t *)id->label, sizeof(id->label), buf, endianess, count);
}
static void set_uuid(const uint8_t *buf, size_t len, enum uuid_format format,
char *uuid, uint8_t *uuid_raw, size_t *uuid_raw_len)
{
unsigned int i;
unsigned int count = 0;
switch(format) {
case UUID_STRING:
count = len;
break;
case UUID_HEX_STRING:
count = len;
break;
case UUID_DOS:
count = 4;
break;
case UUID_64BIT_LE:
count = 8;
break;
case UUID_DCE:
count = 16;
break;
case UUID_MD:
count = 35;
break;
case UUID_LVM:
count = 32;
break;
}
memcpy(uuid_raw, buf, count);
*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(uuid, "%02X%02X-%02X%02X",
buf[3], buf[2], buf[1], buf[0]);
break;
case UUID_64BIT_LE:
sprintf(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_DCE:
sprintf(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_HEX_STRING:
/* translate A..F to a..f */
memcpy(uuid, buf, count);
for (i = 0; i < count; i++)
if (uuid[i] >= 'A' && uuid[i] <= 'F')
uuid[i] = (uuid[i] - 'A') + 'a';
uuid[count] = '\0';
break;
case UUID_STRING:
memcpy(uuid, buf, count);
uuid[count] = '\0';
break;
case UUID_MD:
sprintf(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_LVM:
sprintf(uuid,
"%c%c%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c%c%c",
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], buf[16], buf[17],
buf[18], buf[19], buf[20], buf[21],
buf[22], buf[23], buf[24], buf[25],
buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]);
break;
}
}
void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format)
{
if (len > sizeof(id->uuid_raw))
len = sizeof(id->uuid_raw);
set_uuid(buf, len, format, id->uuid, id->uuid_raw, &id->uuid_raw_len);
}
void volume_id_set_uuid_sub(struct volume_id *id, const uint8_t *buf, size_t len, enum uuid_format format)
{
if (len > sizeof(id->uuid_sub_raw))
len = sizeof(id->uuid_sub_raw);
set_uuid(buf, len, format, id->uuid_sub, id->uuid_sub_raw, &id->uuid_sub_raw_len);
}
uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len)
{
ssize_t buf_len;
info("get buffer off 0x%" PRIx64 "(%" PRIu64 "), len 0x%zx\n", off, 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\n");
return NULL;
}
}
/* check if we need to read */
if ((off + len) > id->sbbuf_len) {
info("read sbbuf len:0x%" PRIx64 "\n", (off + len));
if (lseek(id->fd, 0, SEEK_SET) < 0) {
dbg("lseek failed (%s)\n", strerror(errno));
return NULL;
}
buf_len = read(id->fd, id->sbbuf, off + len);
if (buf_len < 0) {
dbg("read failed (%s)\n", strerror(errno));
return NULL;
}
dbg("got 0x%zx (%zi) bytes\n", 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\n", len, buf_len);
return NULL;
}
}
return &(id->sbbuf[off]);
} else {
if (len > SEEK_BUFFER_SIZE) {
dbg("seek buffer too small %d\n", 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\n");
return NULL;
}
}
/* check if we need to read */
if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) {
info("read seekbuf off:0x%" PRIx64 " len:0x%zx\n", off, len);
if (lseek(id->fd, off, SEEK_SET) < 0) {
dbg("lseek failed (%s)\n", strerror(errno));
return NULL;
}
buf_len = read(id->fd, id->seekbuf, len);
if (buf_len < 0) {
dbg("read failed (%s)\n", strerror(errno));
return NULL;
}
dbg("got 0x%zx (%zi) bytes\n", 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\n", 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;
}
}

View File

@ -1,97 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
*
* Based on information taken from dmraid:
* Copyright (C) 2004-2006 Heinz Mauelshagen, Red Hat GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct via_meta {
uint16_t signature;
uint8_t version_number;
struct via_array {
uint16_t disk_bit_mask;
uint8_t disk_array_ex;
uint32_t capacity_low;
uint32_t capacity_high;
uint32_t serial_checksum;
} PACKED array;
uint32_t serial_checksum[8];
uint8_t checksum;
} PACKED;
#define VIA_SIGNATURE 0xAA55
/* 8 bit checksum on first 50 bytes of metadata. */
static uint8_t meta_checksum(struct via_meta *via)
{
uint8_t i = 50, sum = 0;
while (i--)
sum += ((uint8_t*) via)[i];
return sum == via->checksum;
}
int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
const uint8_t *buf;
uint64_t meta_off;
struct via_meta *via;
dbg("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, 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 > 2)
return -1;
if (!meta_checksum(via))
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;
}

View File

@ -1,592 +0,0 @@
/*
* volume_id - reads volume label and uuid
*
* Copyright (C) 2005-2007 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
struct prober {
volume_id_probe_fn_t prober;
const char *name[4];
};
static const struct prober prober_raid[] = {
{ volume_id_probe_linux_raid, { "linux_raid", } },
{ volume_id_probe_ddf_raid, { "ddf_raid", } },
{ volume_id_probe_intel_software_raid, { "isw_raid", } },
{ volume_id_probe_lsi_mega_raid, { "lsi_mega_raid", } },
{ volume_id_probe_via_raid, { "via_raid", } },
{ volume_id_probe_silicon_medley_raid, { "silicon_medley_raid", } },
{ volume_id_probe_nvidia_raid, { "nvidia_raid", } },
{ volume_id_probe_promise_fasttrack_raid, { "promise_fasttrack_raid", } },
{ volume_id_probe_highpoint_45x_raid, { "highpoint_raid", } },
{ volume_id_probe_adaptec_raid, { "adaptec_raid", } },
{ volume_id_probe_jmicron_raid, { "jmicron_raid", } },
{ volume_id_probe_lvm1, { "lvm1", } },
{ volume_id_probe_lvm2, { "lvm2", } },
{ volume_id_probe_highpoint_37x_raid, { "highpoint_raid", } },
};
static const struct prober prober_filesystem[] = {
{ volume_id_probe_vfat, { "vfat", } },
{ volume_id_probe_linux_swap, { "swap", } },
{ volume_id_probe_luks, { "luks", } },
{ volume_id_probe_xfs, { "xfs", } },
{ volume_id_probe_ext, { "ext2", "ext3", "jbd", } },
{ volume_id_probe_reiserfs, { "reiserfs", "reiser4", } },
{ volume_id_probe_jfs, { "jfs", } },
{ volume_id_probe_udf, { "udf", } },
{ volume_id_probe_iso9660, { "iso9660", } },
{ volume_id_probe_hfs_hfsplus, { "hfs", "hfsplus", } },
{ volume_id_probe_ufs, { "ufs", } },
{ volume_id_probe_ntfs, { "ntfs", } },
{ volume_id_probe_cramfs, { "cramfs", } },
{ volume_id_probe_romfs, { "romfs", } },
{ volume_id_probe_hpfs, { "hpfs", } },
{ volume_id_probe_sysv, { "sysv", "xenix", } },
{ volume_id_probe_minix, { "minix", } },
{ volume_id_probe_gfs, { "gfs", } },
{ volume_id_probe_gfs2, { "gfs2", } },
{ volume_id_probe_ocfs1, { "ocfs1", } },
{ volume_id_probe_ocfs2, { "ocfs2", } },
{ volume_id_probe_vxfs, { "vxfs", } },
{ volume_id_probe_squashfs, { "squashfs", } },
{ volume_id_probe_netware, { "netware", } },
{ volume_id_probe_oracleasm, { "oracleasm", } },
{ volume_id_probe_btrfs, { "btrfs", } },
};
/* the user can overwrite this log function */
static void default_log(int priority, const char *file, int line, const char *format, ...)
{
return;
}
volume_id_log_fn_t volume_id_log_fn = default_log;
/**
* volume_id_get_prober_by_type:
* @type: Type string.
*
* Lookup the probing function for a specific type.
*
* Returns: The probing function for the given type, #NULL otherwise.
**/
const volume_id_probe_fn_t *volume_id_get_prober_by_type(const char *type)
{
unsigned int p, n;
if (type == NULL)
return NULL;
for (p = 0; p < ARRAY_SIZE(prober_raid); p++)
for (n = 0; prober_raid[p].name[n] != NULL; n++)
if (strcmp(type, prober_raid[p].name[n]) == 0)
return &prober_raid[p].prober;
for (p = 0; p < ARRAY_SIZE(prober_filesystem); p++)
for (n = 0; prober_filesystem[p].name[n] != NULL; n++)
if (strcmp(type, prober_filesystem[p].name[n]) == 0)
return &prober_filesystem[p].prober;
return NULL;
}
/**
* volume_id_get_label:
* @id: Probing context.
* @label: Label string. Must not be freed by the caller.
*
* Get the label string after a successful probe. Unicode
* is translated to UTF-8.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_label(struct volume_id *id, const char **label)
{
if (id == NULL)
return 0;
if (label == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*label = id->label;
return 1;
}
/**
* volume_id_get_label_raw:
* @id: Probing context.
* @label: Label byte array. Must not be freed by the caller.
* @len: Length of raw label byte array.
*
* Get the raw label byte array after a successful probe. It may
* contain undecoded multibyte character streams.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_label_raw(struct volume_id *id, const uint8_t **label, size_t *len)
{
if (id == NULL)
return 0;
if (label == NULL)
return 0;
if (len == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*label = id->label_raw;
*len = id->label_raw_len;
return 1;
}
/**
* volume_id_get_uuid:
* @id: Probing context.
* @uuid: UUID string. Must not be freed by the caller.
*
* Get the raw UUID string after a successful probe.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_uuid(struct volume_id *id, const char **uuid)
{
if (id == NULL)
return 0;
if (uuid == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*uuid = id->uuid;
return 1;
}
/**
* volume_id_get_uuid_raw:
* @id: Probing context.
* @uuid: UUID byte array. Must not be freed by the caller.
* @len: Length of raw UUID byte array.
*
* Get the raw UUID byte array after a successful probe. It may
* contain unconverted endianes values.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_uuid_raw(struct volume_id *id, const uint8_t **uuid, size_t *len)
{
if (id == NULL)
return 0;
if (uuid == NULL)
return 0;
if (len == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*uuid = id->uuid_raw;
*len = id->uuid_raw_len;
return 1;
}
int volume_id_get_uuid_sub(struct volume_id *id, const char **uuid)
{
if (id == NULL)
return 0;
if (uuid == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*uuid = id->uuid_sub;
return 1;
}
/**
* volume_id_get_usage:
* @id: Probing context.
* @usage: Usage string. Must not be freed by the caller.
*
* Get the usage string after a successful probe.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_usage(struct volume_id *id, const char **usage)
{
if (id == NULL)
return 0;
if (usage == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*usage = id->usage;
return 1;
}
/**
* volume_id_get_type:
* @id: Probing context
* @type: Type string. Must not be freed by the caller.
*
* Get the type string after a successful probe.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_type(struct volume_id *id, const char **type)
{
if (id == NULL)
return 0;
if (type == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*type = id->type;
return 1;
}
/**
* volume_id_get_type_version:
* @id: Probing context.
* @type_version: Type version string. Must not be freed by the caller.
*
* Get the Type version string after a successful probe.
*
* Returns: 1 if the value was set, 0 otherwise.
**/
int volume_id_get_type_version(struct volume_id *id, const char **type_version)
{
if (id == NULL)
return 0;
if (type_version == NULL)
return 0;
if (id->usage_id == VOLUME_ID_UNUSED)
return 0;
*type_version = id->type_version;
return 1;
}
static int needs_encoding(const char c)
{
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
strchr(ALLOWED_CHARS, c))
return 0;
return 1;
}
/**
* volume_id_encode_string:
* @str: Input string to be encoded.
* @str_enc: Target string to store the encoded input.
* @len: Location to store the encoded string. The target string,
* which may be four times as long as the input string.
*
* Encode all potentially unsafe characters of a string to the
* corresponding hex value prefixed by '\x'.
*
* Returns: 1 if the entire string was copied, 0 otherwise.
**/
int volume_id_encode_string(const char *str, char *str_enc, size_t len)
{
size_t i, j;
if (str == NULL || str_enc == NULL || len == 0)
return 0;
str_enc[0] = '\0';
for (i = 0, j = 0; str[i] != '\0'; i++) {
int seqlen;
seqlen = volume_id_utf8_encoded_valid_unichar(&str[i]);
if (seqlen > 1) {
memcpy(&str_enc[j], &str[i], seqlen);
j += seqlen;
i += (seqlen-1);
} else if (str[i] == '\\' || needs_encoding(str[i])) {
sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
j += 4;
} else {
str_enc[j] = str[i];
j++;
}
if (j+3 >= len)
goto err;
}
str_enc[j] = '\0';
return 1;
err:
return 0;
}
/* run only once into a timeout for unreadable devices */
static int device_is_readable(struct volume_id *id, uint64_t off)
{
if (volume_id_get_buffer(id, off, 0x200) != NULL)
return 1;
return 0;
}
/**
* volume_id_probe_raid:
* @id: Probing context.
* @off: Probing offset relative to the start of the device.
* @size: Total size of the device.
*
* Probe device for all known raid signatures.
*
* Returns: 0 on successful probe, otherwise negative value.
**/
int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
unsigned int i;
if (id == NULL)
return -EINVAL;
if (!device_is_readable(id, off))
return -1;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
for (i = 0; i < ARRAY_SIZE(prober_raid); i++) {
if (prober_raid[i].prober(id, off, size) == 0) {
info("signature '%s' detected\n", id->type);
goto found;
}
}
return -1;
found:
/* If recognized, we free the allocated buffers */
volume_id_free_buffer(id);
return 0;
}
static void volume_id_reset_result(struct volume_id *id)
{
id->label_raw_len = 0;
id->label[0] = '\0';
id->uuid_raw_len = 0;
id->uuid[0] = '\0';
id->usage_id = VOLUME_ID_UNUSED;
id->usage = NULL;
id->type = NULL;
id->type_version[0] = '\0';
}
/**
* volume_id_probe_filesystem:
* @id: Probing context.
* @off: Probing offset relative to the start of the device.
* @size: Total size of the device.
*
* Probe device for all known filesystem signatures.
*
* Returns: 0 on successful probe, otherwise negative value.
**/
int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size)
{
unsigned int i;
if (id == NULL)
return -EINVAL;
if (!device_is_readable(id, off))
return -1;
info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
/*
* We probe for all known filesystems to find conflicting signatures. If
* we find multiple matching signatures and one of the detected filesystem
* types claims that it can not co-exist with any other filesystem type,
* we do not return a probing result.
*
* We can not afford to mount a volume with the wrong filesystem code and
* possibly corrupt it. Linux sytems have the problem of dozens of possible
* filesystem types, and volumes with left-over signatures from former
* filesystem types. Invalid signatures need to be removed from the volume
* to make the filesystem detection successful.
*
* We do not want to read that many bytes from probed floppies, skip volumes
* smaller than a usual floppy disk.
*/
if (size > 1440 * 1024) {
int found = 0;
int force_unique_result = 0;
int first_match = -1;
volume_id_reset_result(id);
for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) {
int match;
match = (prober_filesystem[i].prober(id, off, size) == 0);
if (match) {
info("signature '%s' %i detected\n", id->type, i);
if (id->force_unique_result)
force_unique_result = 1;
if (found > 0 && force_unique_result) {
info("conflicting signatures found, skip results\n");
return -1;
}
found++;
if (first_match < 0)
first_match = i;
}
}
if (found < 1)
return -1;
if (found == 1)
goto found;
if (found > 1) {
volume_id_reset_result(id);
info("re-read first match metadata %i\n", first_match);
if (prober_filesystem[first_match].prober(id, off, size) == 0)
goto found;
return -1;
}
}
/* return the first match */
volume_id_reset_result(id);
for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) {
if (prober_filesystem[i].prober(id, off, size) == 0) {
info("signature '%s' detected\n", id->type);
goto found;
}
}
return -1;
found:
/* If recognized, we free the allocated buffers */
volume_id_free_buffer(id);
return 0;
}
/**
* volume_id_probe_all:
* @id: Probing context.
* @off: Probing offset relative to the start of the device.
* @size: Total size of the device.
*
* Probe device for all known raid and filesystem signatures.
*
* Returns: 0 on successful probe, otherwise negative value.
**/
int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
{
if (id == NULL)
return -EINVAL;
if (!device_is_readable(id, off))
return -1;
/* probe for raid first, because fs probes may be successful on raid members */
if (volume_id_probe_raid(id, off, size) == 0)
return 0;
if (volume_id_probe_filesystem(id, off, size) == 0)
return 0;
return -1;
}
/**
* volume_id_probe_raid:
* @all_probers_fn: prober function to called for all known probing routines.
* @id: Context passed to prober function.
* @off: Offset value passed to prober function.
* @size: Size value passed to prober function.
* @data: Arbitrary data passed to the prober function.
*
* Run a custom function for all known probing routines.
**/
void volume_id_all_probers(all_probers_fn_t all_probers_fn,
struct volume_id *id, uint64_t off, uint64_t size,
void *data)
{
unsigned int i;
if (all_probers_fn == NULL)
return;
for (i = 0; i < ARRAY_SIZE(prober_raid); i++)
if (all_probers_fn(prober_raid[i].prober, id, off, size, data) != 0)
goto out;
for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++)
if (all_probers_fn(prober_filesystem[i].prober, id, off, size, data) != 0)
goto out;
out:
return;
}
/**
* volume_id_open_fd:
* @id: Probing context.
* @fd: Open file descriptor of device to read from.
*
* Create the context for probing.
*
* Returns: Probing context, or #NULL on failure.
**/
struct volume_id *volume_id_open_fd(int fd)
{
struct volume_id *id;
id = calloc(1, sizeof(struct volume_id));
if (id == NULL)
return NULL;
id->fd = fd;
return id;
}
/**
* volume_id_close:
* @id: Probing context.
*
* Release probing context and free all associated data.
*/
void volume_id_close(struct volume_id *id)
{
if (id == NULL)
return;
volume_id_free_buffer(id);
free(id);
}

View File

@ -1,59 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
#define VXFS_SUPER_MAGIC 0xa501FCF5
struct vxfs_super {
uint32_t vs_magic;
int32_t vs_version;
} PACKED;
int volume_id_probe_vxfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct vxfs_super *vxs;
info("probing at offset 0x%" PRIx64 "\n", 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;
}

View File

@ -1,70 +0,0 @@
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "libvolume_id-private.h"
struct xfs_super_block {
uint8_t magic[4];
uint32_t blocksize;
uint64_t dblocks;
uint64_t rblocks;
uint32_t dummy1[2];
uint8_t uuid[16];
uint32_t dummy2[15];
uint8_t fname[12];
uint32_t dummy3[2];
uint64_t icount;
uint64_t ifree;
uint64_t fdblocks;
} PACKED;
int volume_id_probe_xfs(struct volume_id *id, uint64_t off, uint64_t size)
{
struct xfs_super_block *xs;
info("probing at offset 0x%" PRIx64 "\n", 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, 0, UUID_DCE);
volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
id->type = "xfs";
return 0;
}